2013-08-11 9 views
9

gestire una finestra a volte di tipo int e altre volte di tipo IntPtrCome convertire IntPtr a int

int esempio:

[DllImport("user32.dll")] 
    static extern uint GetWindowThreadProcessId(int hWnd, int ProcessId);  

IntPtr esempio:

[DllImport("user32.dll", CharSet = CharSet.Auto)] 
    static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, int wParam, StringBuilder lParam); 

non lo faccio sembra essere in grado di convertire/cast da uno all'altro.

Quando provo this.ProcessID = GetWindowThreadProcessId(windowHandle.ToInt32(),0) ottengo un errore cannot implicitly convert from uint to int

+7

'WindowHandle.ToInt32() 'funzionerà. –

+0

@Henk holterman Ho modificato la domanda, ma non compila ancora –

+2

Non devi modificare le parti chiave di una domanda, aggiungi una sezione successiva. –

risposta

10

La firma SendMessage è

static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam); 

o questo

static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, StringBuilder lParam); 

Non scambiare int e IntPtr. Sono quasi equivalenti solo a 32 bit (di dimensioni uguali). A 64 bit un IntPtr è quasi equivalente a un long (pari dimensioni)

La firma GetWindowThreadProcessId è

static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId); 

o

static extern uint GetWindowThreadProcessId(IntPtr hWnd, IntPtr ProcessId); 

In questo caso, un ref o un out a " qualcosa "sono gestiti riferimenti a qualcosa, quindi vengono convertiti internamente in IntPtr quando vengono passati all'API nativa. Quindi out uint è, dal punto di vista dell'API nativa, equivalente a IntPtr.

Spiegazione: l'importante è che la "lunghezza" dei parametri sia quella corretta. int e uint sono uguali per l'API chiamata. E un 3223 IntPtr è lo stesso.

Si noti che alcuni tipi (come bool e char) hanno una gestione speciale da parte del gestore di marshalling.

Non si dovrebbe MAI convertire un int in un IntPtr. Keep it come IntPtr e vivi felice. Se devi eseguire alcune operazioni matematiche non supportate da IntPtr, utilizza long (è 64 bit, quindi finché non avremo Windows 128, non ci saranno problemi :-)).

IntPtr p = ... 
long l = (long)p; 
p = (IntPtr)l; 
1

Penso che l'errore si riferisce a cannot implicitly convert from uint to int= dichiarazione. Il campo this.ProcessID è int, ma GetWindowThreadProcessId restituisce uint.

Prova questa

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