web-dev-qa-db-ja.com

IntPtrをintに変換する方法

タイプ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_

12
E Mett

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);

intIntPtrは交換しないでください。それらは、32ビットでのみほぼ同等です(サイズは同じ)。 64ビットでは、IntPtrlongとほぼ同等です(サイズは同じ)

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と同等です。

説明:重要なのは、パラメーターの「長さ」が正しいことです。 intuintは、呼び出されたAPIと同じです。また、32ビットのIntPtrも同じです。

一部のタイプ(boolcharなど)には、マーシャラーによる特別な処理があることに注意してください。

intIntPtrに変換しないでください。 IntPtrとして保管し、幸せに暮らしてください。 IntPtrでサポートされていない数学演算を作成する必要がある場合は、longを使用します(64ビットなので、Windows 128になるまで、何の問題 :-) )。

IntPtr p = ...
long l = (long)p;
p = (IntPtr)l;
10
xanatos

エラーcannot implicitly convert from uint to int=ステートメントを参照していると思います。フィールドthis.ProcessIDintですが、GetWindowThreadProcessIduintを返します。

これを試して

this.ProcessID = unchecked((int)GetWindowThreadProcessId(windowHandle.ToInt32(),0))
1
RomanHotsiy

次の場合はいつでも、「算術演算でオーバーフローが発生しました」と表示されていました。

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
0
DanielV