GetWindowLong / SetWindowLong vs重写CreateParams?

时间:2012-12-21 08:02:26

标签: c# winforms

以前,当我想创建点击型表单时,我tempted to use platform invokes to set the extended window styles GetWindowLong / SetWindowLong中的user32.dll / CreateParams

刚才我想让它对Alt + Tab窗口列表不可见,我发现an example覆盖GetWindowLong来设置扩展窗口样式而不是使用SetWindowong / { {1}}。

现在我有了这个:

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 appears on msdn并且有一个操作窗口样式的示例。那么为什么StackOverflow上的一些在线“示例”和答案会告诉人们使用GetWindowLong / SetWindowLong

1 个答案:

答案 0 :(得分:8)

  

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