我希望在C#中创建一个无法接受焦点的表单,即当我单击表单上的按钮时,焦点不会从当前具有焦点的应用程序中被盗。
有关此示例,请参阅Windows屏幕键盘。请注意,单击某个按钮时,焦点不会从您当前使用的应用程序中获取。
如何实现此行为?
更新
事实证明它就像覆盖CreateParams
属性并将WS_EX_NOACTIVATE
添加到扩展窗口样式一样简单。谢谢你指出我正确的方向!
不幸的是,这会产生不良的副作用,因为它会影响表单移动,即您仍然可以在屏幕上拖放表单,但拖动时不会显示窗口的边框,因此很难精确定位它。
如果有人知道如何解决这个问题,我们将不胜感激。
答案 0 :(得分:9)
禁用鼠标激活:
class NonFocusableForm : Form
{
protected override void DefWndProc(ref Message m)
{
const int WM_MOUSEACTIVATE = 0x21;
const int MA_NOACTIVATE = 0x0003;
switch(m.Msg)
{
case WM_MOUSEACTIVATE:
m.Result = (IntPtr)MA_NOACTIVATE;
return;
}
base.DefWndProc(ref m);
}
}
在没有激活的情况下显示表单(对于无边框形式的唯一一种方式):
[DllImport("user32.dll")]
public static extern bool ShowWindow(IntPtr handle, int flags);
NativeMethods.ShowWindow(form.Handle, 8);
执行此操作的标准方法(似乎它不适用于所有表单样式):
protected override bool ShowWithoutActivation
{
get { return true; }
}
如果还有其他激活表单的方法,可以用类似的方式抑制它们。
答案 1 :(得分:0)
这是我使用的“ NoFocusForm”:
public class NoFocusForm : Form
{
/// From MSDN <see cref="https://docs.microsoft.com/en-us/windows/win32/winmsg/extended-window-styles"/>
/// A top-level window created with this style does not become the
/// foreground window when the user clicks it. The system does not
/// bring this window to the foreground when the user minimizes or
/// closes the foreground window. The window should not be activated
/// through programmatic access or via keyboard navigation by accessible
/// technology, such as Narrator. To activate the window, use the
/// SetActiveWindow or SetForegroundWindow function. The window does not
/// appear on the taskbar by default. To force the window to appear on
/// the taskbar, use the WS_EX_APPWINDOW style.
private const int WS_EX_NOACTIVATE = 0x08000000;
public NoFocusForm()
{
// my other initiate stuff
}
/// <summary>
/// Prevent form from getting focus
/// </summary>
protected override CreateParams CreateParams
{
get
{
var createParams = base.CreateParams;
createParams.ExStyle |= WS_EX_NOACTIVATE;
return createParams;
}
}
}