当我尝试从C#中的User32.dll,SetWindowLong调用函数时,什么都没有发生。我知道为什么,但是我不知道该如何“修复”。
这是一段代码。
[DllImport("user32.dll")]
public static extern long GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("user32.dll")]
public static extern long SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
const int WS_EX_TOPMOST = 0x00000008;
const int GWL_EXSTYLE = -20;
public static bool IsWindowTopMost(int id)
{
return (GetWindowLong(GetHWNDById(id), GWL_EXSTYLE) & WS_EX_TOPMOST) == WS_EX_TOPMOST;
}
public static void SetAlwaysOnTop(int id)
{
IntPtr hWnd = GetHWNDById(id);
long actuallyStyle = GetWindowLong(hWnd, GWL_EXSTYLE) | WS_EX_TOPMOST;
SetWindowLong(hWnd, GWL_EXSTYLE, (int)actuallyStyle));
}
IsWindowTopMost可以正常工作,但SetAlwaysOnTop不能。快速检查代码后,我发现了一些有趣的东西。 GetWindowLong之后的变量“ actuallyStyle”等于4295295232,或操作4295295240之后。这是问题所在,函数SetWindowLong将dwNewLong接受为整数。当我在SetWindowLong的定义中长时间更改int时,pinvoke会引发错误,因为“函数和目标函数不匹配”。
如何解决?
最佳答案
始终将窗口置于顶部的正确方法是使用SetWindowPos function。问题很可能是SetWindowLong
只是设置了一个变量,但是SetWindowPos
实际上通知窗口管理器进行所需的重绘,因此请改用它。
现在关于问题标题,必须同时将SetWindowLong
和GetWindowLong
声明为int
,而不是long
。
这有两个原因。首先,C和C#之间的区别。整个Windows API文档均以C术语where long means 32 bits signed integer定义,但是C#威胁long
为64位有符号整数,因此会出现错误。使用64位的函数在API文档中声明为long long
。
造成这种差异的另一个原因是历史的。这两个函数都是在Windows的16位时代创建的,其中int
是16位,而long
是32位。 int
类型后来被扩展,但long
保持原样。名称未更改以保持兼容性。
关于c# - User32 SetWindowLong接受int代替long,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34577624/