cnblogs Post date: 2010-07-11 09:41

问题是这样的:

  我有个程序有个置顶的小提示窗口。然后,在使用ALT+TAB切换窗口时老是会不小心切换到这个提示窗口(和我的本意不符合的),很烦人。

如何解决:

  也就是说:如何让WinForm不会在ALT+TAB中出现?

  学过Win32窗口编程的都知道:Windows窗口的显示样式主要由创建窗口(CreateWindowEx)时dwExStyle和dwStyle两种样式决定。(WinForm最终还是用API创建窗口的)

  其中,dwExStyle中WS_EX_TOOLWINDOW正是我们需要的样式,它表示工具窗口,是不会在ALT+TAB中显示的。

如何更改dwExStyle样式呢?

  首先想到的是改变CreateWindowEx中的dwExStyle参数。具体而言,WinForm中有个属性CreateParams可以更改:

CreateParams.ExStyle = CreateParams.ExStyle | Win32Native.WS_EX_TOOLWINDOW;

  似乎,这条语句应该在WinForm创建前执行,但是有个问题是WinForm相关联的句柄创建的很早,即使你把这一句放到构造函数的最开始部分,结果也不能更改窗体样式。  还有没有其他办法呢?那只能在WinForm窗体创建后更改dwExStyle样式了。还好,API中有Get/SetWindowLong函数可以用来对已创建的窗口的相关信息进行更改。具体做法如下:

        [DllImport("user32.dll")]
        public static extern
            Int32 GetWindowLong(IntPtr hwnd, Int32 index);
        [DllImport("user32.dll")]
        public static extern
            Int32 SetWindowLong(IntPtr hwnd, Int32 index, Int32 newValue);
        public const int GWL_EXSTYLE = (-20);
        public static void AddWindowExStyle(IntPtr hwnd,Int32 val)
        {
            int oldValue = GetWindowLong(hwnd,GWL_EXSTYLE);
            if (oldValue == 0)
            {
                throw new System.ComponentModel.Win32Exception();
            }
            if (0 == SetWindowLong(hwnd, GWL_EXSTYLE, oldValue | val))
            {
                throw new System.ComponentModel.Win32Exception();
            }
        }
        public static int WS_EX_TOOLWINDOW = 0x00000080;
        //我把这个过程封装下:
        public static void SetFormToolWindowStyle(System.Windows.Forms.Form form)
        {
            AddWindowExStyle(form.Handle, WS_EX_TOOLWINDOW);
        }

  如此这般,对一个WinForm调用SetFormToolWindowStyle就行了。

需要注意的是:

  WS_EX_TOOLWINDOW和WS_EX_APPWINDOW(对应WinForm中ShowInTaskBar)是会冲突的。

  如果,这个窗口是APPWINDOW,那么还需要将ShowInTaskBar属性设为false.