最近因为项目需要,要做一个浮动的小窗口,在不能获取焦点的前提下,窗口中的按钮依然能够使用。
实现这一功能查找到了两种方式:
第一种是浮动窗口只能是一个单独的程序,需要窗口时,先打开程序获取窗口句柄,在进行操作。
第二种是浮动窗口作为主程序的子窗口,将浮动窗口做成Form,new对象即可。
第一种方式的实现,相信大家在网上已经看到很多了。就是下边这段代码:
1 private const int WS_EX_TOOLWINDOW = 0x00000080; 2 private const int WS_EX_NOACTIVATE = 0x08000000; 3 protected override CreateParams CreateParams 4 { 5 get 6 { 7 CreateParams cp = base.CreateParams; 8 cp.ExStyle |= (WS_EX_NOACTIVATE | WS_EX_TOOLWINDOW); 9 cp.Parent = IntPtr.Zero; // Keep this line only if you used UserControl 10 return cp; 11 //return base.CreateParams; 12 } 13 }
最好将窗口的Topmost 属性设置为True ,作为最顶层窗口。
第二种方式的实现,也是在网上找了好久发现的,直接贴代码:
1 [System.Runtime.InteropServices.DllImport("user32.dll")] 2 private extern static IntPtr SetActiveWindow(IntPtr handle); 3 private const int WM_ACTIVATE = 0x006; 4 private const int WM_ACTIVATEAPP = 0x01C; 5 private const int WM_NCACTIVATE = 0x086; 6 private const int WA_INACTIVE = 0; 7 private const int WM_MOUSEACTIVATE = 0x21; 8 private const int MA_NOACTIVATE = 3; 9 protected override void WndProc(ref Message m) 10 { 11 if (m.Msg == WM_MOUSEACTIVATE) 12 { 13 m.Result = new IntPtr(MA_NOACTIVATE); 14 return; 15 } 16 else if (m.Msg == WM_NCACTIVATE) 17 { 18 19 if (((int)m.WParam & 0xFFFF) != WA_INACTIVE) 20 { 21 if (m.LParam != IntPtr.Zero) 22 SetActiveWindow(m.LParam); 23 else 24 SetActiveWindow(IntPtr.Zero); 25 return; 26 } 27 28 } 29 base.WndProc(ref m); 30 }
这种方式是截获了
WM_MOUSEACTIVATE
windows消息,并返回
MA_NOACTIVATE