タイトル : Re^7: VB2010 internetsetoption 投稿日 : 2015/04/17(Fri) 10:50 投稿者 : 魔界の仮面弁士
> Private Declare Function InternetOpen Lib "wininet.dll" Alias _ > "InternetOpenA" (ByVal sAgent As String, ByVal lAccessType As Integer, _ > ByVal sProxyName As String, ByVal sProxyBypass As String, _ > ByVal lFlags As Integer) As Integer Win9x 系が淘汰された現在では、あえて A系を選択する必要性は薄いと思います。 VBA なら Ansi Function の方が楽ですが、.NET なら Unicode Function の方が良いですよ。 > Private Declare Auto Function InternetSetOption Lib "wininet.dll" _ > (ByVal hInternet As Integer, ByVal dwOption As Integer, _ > ByVal lpBuffer As Integer, ByVal lpdwBufferLength As Integer) As Boolean 以下一般論。 h で始まる引数名は、ハンドル型の引数を意味します。 → 一般的には、ByVal IntPtr とします。なお、対象オブジェクトによっては、 さらにカプセル化したクラスが使われることもあります。 (例:Microsoft.Win32.SafeHandles 名前空間) dw で始まる引数名は、DWORD 型の引数を意味します。 → 本来の型は ByVal UInteger です。ただし ByVal Integer もよく使われます。 lp で始まる引数名は、LONG POINTER な引数を意味します。 → 「ByRef 値型」「ByVal 参照型」「ByVal IntPtr」などが使われます。 LPRECT なら ByRef RECT構造体、などのように。 LPVOID の場合、複数のデータ型が渡される可能性があるため、 VB.NET ではオーバーロードで対応することが多いです。 上記を踏まえたうえで、元の API 定義を見てみると https://msdn.microsoft.com/en-us/library/windows/desktop/aa385114/ となっています。 まず第 4 引数。ここには第 3 引数のデータ長(文字数またはバイト数)が入ります。 データ型は DWORD 。なので、ByVal dwBufferLength As Integer/UInteger が適切です。 しかし提示された宣言は、ByVal lpdwBufferLength As Integer になっていますよね。 引数名が動作に影響を与えるわけではありませんが、lpdw の接頭辞だと、 ByRef UInteger を連想してしまいます。(定義としては間違っていないのですが) 次に第 3 引数。ここには第 2 引数に指定したオプション値によって 異なる値が渡されるわけですが、今回のタイムアウト設定の場合は、 DWORD のポインタが渡されることになります。 つまり、★ByVal Integer にするのは誤り★で、 ByRef UInteger/Integer にするべきでしょう。 ByVal IntPtr でも間違いでは無いですが、それが冗長なことは先述の通り。 第 2 引数。ここは ByVal UInteger / Integer なので問題なし。 オプション定数群を Enum にして、ByVal 列挙型としてみるのも良いですね。 第 1 引数。ByVal Integer は正しくありません。 x86 ビルドの場合は限定的に利用可能ではありますが、本来は ByVal IntPtr です。 戻り値。これは As Boolean のままで OK です。より明確にするために、 As <MarshalAs(UnmanagedType.Bool)> Boolean と書くこともあります。 …というか、今まで VB6 では動いていたんですよね。その時は、それぞれの引数を どのように定義し、そこにどんな型の変数を渡していたのでしょうか? (特に第3引数) > Public Const INTERNET_OPTION_CONNECT_TIMEOUT As Integer = 2 '接続タイムアウト こっちは「As」付きで、 > Private Const USER_AGENT = "WININET" 'ユーザーエージェント名 こっちは「As」なしなのが気にかかります。まぁ良いですけど。 > Private hOpen As Integer ' オープンハンドル > Private hConnect As Integer ' コネクトハンドル ハンドルは IntPtr で統一しましょう。 > dim timeout as integer ……小文字? ここは実際のコードとは違うのですね。 > timeoutの値を1000にするとInternetSetOptionはFalseを返し、 > 99999にするとTrueを返します。 ByVal / ByRef の時点で間違っていましたので、その動作はおそらく偶然です。 パソコンを何度か再起動すると、また違う動作になってしまう可能性すらあるでしょう。 |