User32 SetWindowLong 接受 int 而不是 long
User32 SetWindowLong accepts int instead long
当我尝试在 C# SetWindowLong 中从 User32.dll 调用函数时,没有任何反应。我知道为什么,但我不知道如何 "repair" 这个。
这是一段代码。
[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,OR 运算后为 4295295240。这就是问题所在,函数 SetWindowLong 接受一个 Integer 作为 dwNewLong。当我在 SetWindowLong 的定义中将 int 更改为 long 时,pinvoke 会抛出错误,因为 "unmatched function and target function".
它是如何传播的?
将 window 置于最前面的正确方法是使用 SetWindowPos function。问题很可能是 SetWindowLong
只是设置了一个变量,但 SetWindowPos
实际上通知了 window 管理器进行所需的重绘,因此请改用它。
现在关于问题标题,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# SetWindowLong 中从 User32.dll 调用函数时,没有任何反应。我知道为什么,但我不知道如何 "repair" 这个。 这是一段代码。
[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,OR 运算后为 4295295240。这就是问题所在,函数 SetWindowLong 接受一个 Integer 作为 dwNewLong。当我在 SetWindowLong 的定义中将 int 更改为 long 时,pinvoke 会抛出错误,因为 "unmatched function and target function".
它是如何传播的?
将 window 置于最前面的正确方法是使用 SetWindowPos function。问题很可能是 SetWindowLong
只是设置了一个变量,但 SetWindowPos
实际上通知了 window 管理器进行所需的重绘,因此请改用它。
现在关于问题标题,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
保持原样。名称未更改以保持兼容性。