6

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

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

所以我的几个问题:

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

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

于 2012-12-21T12:20:58.430 回答