GetWindowLong / SetWindowLong 与重写 CreateParams 的区别?

6

以前我想创建一个可点击的表单时,曾经考虑使用平台调用来设置扩展窗口样式user32.dll中的GetWindowLong / SetWindowLong)。

现在我想让它在Alt+Tab窗口列表中不可见,并找到了一个示例重写CreateParams而不是使用GetWindowLong/SetWindowong来设置扩展窗口样式。

现在我的代码是这样的:

protected override CreateParams CreateParams
{
    get
    {
        CreateParams cp = base.CreateParams;
        cp.ExStyle |= 0x80000 /* WS_EX_LAYERED */ | 0x20 /* WS_EX_TRANSPARENT */ | 0x80/* WS_EX_TOOLWINDOW */;
        return cp;
    }
}

现在看起来不需要任何平台调用。

所以我的一些问题:

  1. 在Windows上会有任何功能上的区别吗?(只是说我现在甚至没有XP机可以尝试。)
  2. 现在我没有平台调用,我的程序是否可以在Linux / Mac上的Mono上运行?(如果我现在可以尝试,我就不会在这里问你了。)
  3. Control.CreateParams 在msdn上出现并且有一个操作窗口样式的示例。那么为什么有些在线“示例”和StackOverflow的答案告诉人们使用GetWindowLong/SetWindowLong
1个回答

10

在Windows上会有功能差异吗?

非常有。覆盖CreateParams可以确保窗口在使用CreateWindowEx()调用创建时具有所需的样式标志值。Pinvoking SetWindowLong()是晚期调用,需要先创建窗口,因为您需要Handle属性。对于GWL_STYLE和GWL_EXSTYLE使用它是有风险的,旧版本的Windows对此很挑剔。Winforms实际上会重新创建窗口,以便可以将新的样式标志传递给CreateWindowEx(),请注意RecreateHandle()方法,当底层是样式标志的属性更改时使用它。 Winforms确实要承担支持Windows 98的负担。

我的程序能在Linux/Mac的Mono上运行吗?

不确定,你实际上必须尝试一下。但显然你有一个好的“或许”,如果你依赖pinvoke则几乎没有机会。

在StackOverflow上告诉人们使用GetWindowLong/SetWindowLong吗?

我想是出于惯性。SetWindowsLong()已经存在了25年以上,CreateParams是10年前才出现的,而且仍然相当晦涩。

预测下一个问题:否,我从未见过关于每个Windows版本在窗口生命周期的什么时间可以安全地更改哪个预定义窗口类的哪些样式标志以及可以更改哪些样式标志的全面列表。相当确定这样的清单不存在,或者不能信任,需要试错。请注意,可能需要使用SWP_FRAMECHANGED调用SetWindowsPos()才能使样式更改生效。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接