窗口句柄有时为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
答案 0 :(得分:10)
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
到“某事”是对某事的托管引用,因此在传递给Native API时它们会在内部转换为IntPtr
。因此,从Native API的角度来看,out uint
相当于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;
答案 1 :(得分:1)
我认为错误cannot implicitly convert from uint to int
是指=
语句。字段this.ProcessID
为int
,但GetWindowThreadProcessId
返回uint
。
试试这个
this.ProcessID = unchecked((int)GetWindowThreadProcessId(windowHandle.ToInt32(),0))
答案 2 :(得分: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