GetWindowLong/SetWindowLong vs重写CreateParams?

Alv*_*ong 4 c# winforms

以前当我想创建一个点击式表单时,我很想使用平台调用来设置扩展窗口样式(GetWindowLong/ SetWindowLongin 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在明显的变化不需要任何平台调用.

所以我的几个问题:

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

Han*_*ant 9

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()才能使样式更改生效.