タイプint
のウィンドウハンドルとタイプIntPtr
のウィンドウハンドル
int
の例:
_ [DllImport("user32.dll")]
static extern uint GetWindowThreadProcessId(int hWnd, int ProcessId);
_
IntPtr
の例:
_ [DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, int wParam, StringBuilder lParam);
_
変換やキャストができないようです。
this.ProcessID = GetWindowThreadProcessId(windowHandle.ToInt32(),0)
を試すと、エラーが発生します_cannot implicitly convert from uint to int
_
SendMessage
署名は
static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
またはこれ
static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, StringBuilder lParam);
int
とIntPtr
は交換しないでください。それらは、32ビットでのみほぼ同等です(サイズは同じ)。 64ビットでは、IntPtr
はlong
とほぼ同等です(サイズは同じ)
GetWindowThreadProcessId
署名は
static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
または
static extern uint GetWindowThreadProcessId(IntPtr hWnd, IntPtr ProcessId);
この場合、ref
またはout
から「何か」へのマネージ参照は何かへの参照であるため、ネイティブAPIに渡されると、内部でIntPtr
に変換されます。そう out uint
は、ネイティブAPIの観点からは、IntPtr
と同等です。
説明:重要なのは、パラメーターの「長さ」が正しいことです。 int
とuint
は、呼び出されたAPIと同じです。また、32ビットのIntPtr
も同じです。
一部のタイプ(bool
やchar
など)には、マーシャラーによる特別な処理があることに注意してください。
int
をIntPtr
に変換しないでください。 IntPtr
として保管し、幸せに暮らしてください。 IntPtr
でサポートされていない数学演算を作成する必要がある場合は、long
を使用します(64ビットなので、Windows 128になるまで、何の問題 :-) )。
IntPtr p = ...
long l = (long)p;
p = (IntPtr)l;
エラーcannot implicitly convert from uint to int
は=
ステートメントを参照していると思います。フィールドthis.ProcessID
はint
ですが、GetWindowThreadProcessId
はuint
を返します。
これを試して
this.ProcessID = unchecked((int)GetWindowThreadProcessId(windowHandle.ToInt32(),0))
次の場合はいつでも、「算術演算でオーバーフローが発生しました」と表示されていました。
IntPtr handler = OpenSCManager(null, null, SC_MANAGER_CREATE_SERVICE);
if (handler.ToInt32() == 0) //throws Exception
その代わりに:
IntPtr handler = OpenSCManager(null, null, SC_MANAGER_CREATE_SERVICE);
if (handler == IntPtr.Zero) //OK