1

我正在处理与This Question完全相同的情况。

没有答案,而且问题太老了,所以我不能留下任何评论,看看 OP 是否找到了解决方案。

我现在才学习 p/invoke 的基础知识,至少还很难理解。

我一直在做相当多的搜索。我发现这个问题将我与这个问题/答案联系起来,但我仍然无法理解我需要做什么。

我想我正在寻求一种操作 WM_IME 命令的方法,或者至少在鼠标单击时禁用 WM_IME_ENDCOMPOSITION。

先感谢您

4

2 回答 2

1

没有 IME 专家,但您不能只覆盖“WndProc”而不传递“消息”,因为它会阻止其他应用程序/控件处理它吗?WndProc 捕获由操作系统生成的数百个“Windows 消息”,这些消息可以捕获给正在监听的“任何人”,一种方法是在条件合适时选择性地忽略该消息......

protected override void WndProc(ref Message m)
  {
    switch(m.Msg)
    {
      case WM_IME_ENDCOMPOSITION :
        // Gobble this up or ignore
        break;
      default:
        // Continue as normal
        base.WndProc (ref m);
        break;
    }
  }

例如,如果您正在处理一个控件,您可以覆盖控件的 WndProc,捕获鼠标按下事件(或 WM_MOUSEDOWN),设置一个变量以忽略 WM_IME_ENDCOMPOSITION,然后在鼠标向上重新启用该变量(或 WM_MOUSEUP )? 或者,您可以使用鼠标钩,但这可能有点矫枉过正......

于 2012-02-21T16:20:35.683 回答
0

我最终做了什么,因为 WM_IME_ENDCOMPOSITION 显然没有触发,我尝试禁用 mouseactivate winproc。

        private const int WM_MOUSEACTIVATE = 0x0021;
        private const int MA_NOACTIVATEANDEAT = 0x0004;

        protected override void WndProc(ref Message m)
        {
            if (mousestatus == 0)
            {
                if (m.Msg == WM_MOUSEACTIVATE)
                {
                    m.Result = (IntPtr)MA_NOACTIVATEANDEAT;
                    return;
                }
                base.WndProc(ref m);
            }
        }

然后将我所有的面板单击事件处理程序更改为鼠标悬停事件。因为应用程序的某些部分确实需要单击,所以我添加了一个 mousestatus 变量,这样只有当 mousestatus 为 0 时才会禁用鼠标单击。这是由鼠标位置定义的(与禁用鼠标单击一样,我将无法单击任何东西来启用它)。

    [System.Runtime.InteropServices.DllImport("user32.dll")]
    public static extern void mouse_event(int dwFlags, int dx, int dy, int cButtons, int dwExtraInfo);

    private void timer1_Tick(object sender, EventArgs e)
    {
        if ((Cursor.Position.X - Location.X) >= 904 && (Cursor.Position.X - Location.X) <= 963 && (Cursor.Position.Y - Location.Y) >= 145 && (Cursor.Position.Y - Location.Y) <= 167)
        {
            mousestatus = 1;

            mouse_event(MOUSEEVENTF_LEFTDOWN, Cursor.Position.X, Cursor.Position.Y, 0, 0);
            mouse_event(MOUSEEVENTF_LEFTUP, Cursor.Position.X, Cursor.Position.Y, 0, 0);


            timer4.Start();

        }
    }

我很确定点击会在定义 mousestatus=1 之前出现,所以为了确保点击了我需要的位置,我进行了虚拟鼠标点击。timer4 只是一个将 mousestatus 设置回 0 的计时器。

代码可能有点乱,我确信我可以使用一些快捷方式,但到目前为止,它可以满足我的需要。=D

于 2012-02-22T16:24:46.507 回答