Un handle de fenêtre, parfois de type int
et d'autres heures de type IntPtr
int
exemple:
[DllImport("user32.dll")]
static extern uint GetWindowThreadProcessId(int hWnd, int ProcessId);
IntPtr
exemple:
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, int wParam, StringBuilder lParam);
Je ne semble pas être capable de convertir/casting de l'un à l'autre.
Quand j'essaie this.ProcessID = GetWindowThreadProcessId(windowHandle.ToInt32(),0)
je reçois une erreur cannot implicitly convert from uint to int
La signature SendMessage
est
static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
ou ca
static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, StringBuilder lParam);
N'échangez pas int
et IntPtr
. Ils sont presque équivalents seulement à 32 bits (de taille égale). À 64 bits, une IntPtr
est presque équivalente à une long
(taille égale)
La signature GetWindowThreadProcessId
est
static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
ou
static extern uint GetWindowThreadProcessId(IntPtr hWnd, IntPtr ProcessId);
Dans ce cas, une ref
ou une out
à "quelque chose" sont des références gérées à quelque chose, elles sont donc converties en interne en IntPtr
lorsqu'elles sont passées à l'API native. Donc, out uint
est, du point de vue de l'API native, équivalent à IntPtr
.
Explication: l’important est que la "longueur" des paramètres soit la bonne. int
et uint
sont égaux pour l'API appelée. Et une IntPtr
32 bits est la même chose.
Notez que certains types (comme bool
et char
) ont un traitement spécial par le marshaler.
Vous ne devriez jamais convertir une int
en une IntPtr
. Gardez-le comme une IntPtr
et vivez heureux. Si vous devez effectuer des opérations mathématiques non supportées par IntPtr
, utilisez long
(c'est 64 bits, donc jusqu'à ce que nous ayons Windows 128 , il n'y aura pas de problème :-)).
IntPtr p = ...
long l = (long)p;
p = (IntPtr)l;
Je pense que l'erreur cannot implicitly convert from uint to int
fait référence à l'instruction =
. Le champ this.ProcessID
est int
, mais GetWindowThreadProcessId
renvoie uint
.
Essaye ça
this.ProcessID = unchecked((int)GetWindowThreadProcessId(windowHandle.ToInt32(),0))
J'obtenais "Une opération arithmétique aboutissait à un débordement", chaque fois que j'étais:
IntPtr handler = OpenSCManager(null, null, SC_MANAGER_CREATE_SERVICE);
if (handler.ToInt32() == 0) //throws Exception
au lieu de:
IntPtr handler = OpenSCManager(null, null, SC_MANAGER_CREATE_SERVICE);
if (handler == IntPtr.Zero) //OK