GetWindowLong / SetWindowLong vs overriding CreateParams?

本文关键字:CreateParams overriding vs SetWindowLong GetWindowLong | 更新日期: 2023-09-27 17:49:21

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

刚才我想使它不可见的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呢?

GetWindowLong / SetWindowLong vs overriding CreateParams?

在Windows上有什么功能上的不同吗?

是的,非常喜欢。重写CreateParams确保样式标志在使用CreateWindowEx()调用创建窗口时具有所需的值。调用SetWindowLong()会延迟,它要求首先创建窗口,因为您需要Handle属性。将它与GWL_STYLE和GWL_EXSTYLE一起使用是有风险的,旧的Windows版本对此很不习惯。如此之多,以至于Winforms不这样做,它实际上重新创建窗口,这样它就可以将新的样式标志传递给CreateWindowEx()。请注意RecreateHandle()方法,它在属性被更改时使用,该属性是底层的样式标志。Winforms也有支持Windows 98的负担。

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

不确定,实际上你必须尝试。但很明显,你有一个很好的"可能",当你依靠pinvoke时,你的几率为零。

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

我想是惯性吧。settwindowslong()已经有25年的历史了,CreateParams只有10年的历史,仍然很晦涩。

先问下一个问题:不,我从来没有见过一个全面的列表,说明在每个Windows版本的窗口生命周期中,哪些样式标志可以安全地更改为哪个预定义的窗口类。很确定这样的列表不存在,或者可以信任,需要反复试验。请注意,可能需要使用SWP_FRAMECHANGED方法调用SetWindowsPos()来使样式更改生效。