c# - WS_EX_NOACTIVATE 和 WinForms 的两个问题

标签 c# .net winforms user-interface winapi

在我的一些应用程序中,我使用 WS_EX_NOACTIVATE extended window style value (例如,创建虚拟键盘或用于另一个程序中托管的表单)。该值会阻止表单获得焦点。

这是我的操作方法:

protected override CreateParams CreateParams
{
    get
    {
        CreateParams p = base.CreateParams;

        p.ExStyle |= Win32.WS_EX_NOACTIVATE;

        return p;
    }
}

它工作得很好,但我注意到这个解决方案有两个问题:

  1. 用户无法通过按“Tab”在控件之间移动
  2. 当用户拖动表单时,我们看不到位移(移动过程中表单不会重绘)

那么,是否有可能解决这些问题,或者至少实现一些替代方案?也许 WS_EX_NOACTIVATE 不是最好的解决方案?

非常感谢!

最佳答案

以下是我针对每个问题找到的解决方案:


问题#1:

protected override bool ProcessKeyPreview(ref Message m)
{
    if (m.Msg == Win32.WM_KEYDOWN && (Keys)m.WParam == Keys.Tab)
    {
        if (Control.ModifierKeys == Keys.Shift)
        {
            this.SelectNextControl(ActiveControl, false, true, true, true);  // Bring focus to previous control
        }
        else
        {
            this.SelectNextControl(ActiveControl, true, true, true, true);  // Bring focus to next control
        }
    }

    return base.ProcessKeyPreview(ref m);
}

问题#2:您必须拦截从系统收到的适当消息(WM_SIZINGWM_MOVING)并使用以下命令设置表单的位置SetWindowPos() - 这将迫使它移动!

在您的表单类中:

public const int WM_SIZING = 0x0214;
public const int WM_MOVING = 0x0216;

[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
    public int Left;
    public int Top;
    public int Right;
    public int Bottom;
}

[DllImport("user32.dll", SetLastError = true)]
private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInstertAfter, int x, int y, int cx, int cy, uint flags);

protected override void WndProc(ref Message m)
{
    if (m.Msg == WM_SIZING || m.Msg == WM_MOVING)
    {
        RECT rect = (RECT)Marshal.PtrToStructure(m.LParam, typeof(RECT));
        SetWindowPos(this.Handle, IntPtr.Zero, rect.Left, rect.Top, rect.Right - rect.Left, rect.Bottom - rect.Top, 0);
    }
    else
    {
        base.WndProc(ref m);
    }
}

关于c# - WS_EX_NOACTIVATE 和 WinForms 的两个问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28873729/

相关文章:

c# - 简单的 LINQ to SQL 嵌套选择

c# - 内存占用最少的集合?

c++ - 在 winform 中使用 DrawImage

c# - 如果 TextBox 为空或已经为 0,如何禁止用户在 TextBox 上插入 0?

c# - 给定邮政编码(或坐标)和半径,如何获得邮政编码 (GB) 列表?

c# - ? x : y, 是什么意思呢?

c# - 对于 "actionSheetAlert", (action) 之后是什么 =>

c# - 提取字符串的第二部分

winforms - 连接的 USB 设备的分类

c# - ASP.NET Core 3.0 中 ExpressionHelper 的替代品?