3

我正在创建一个简单的 C# 应用程序来监视服务器上的销售应用程序,如果任何消息框出现特定的窗口名称以关闭窗口并继续该过程。供应商有随机出现的信息消息框,它会挂起应用程序,直到单击 X 或 OK 按钮。出现了两种类型的消息框,一种在使用我的应用程序时可以正常关闭,而另一种则没有。它们看起来都非常相似,只是其中一个嵌入了 sql 文本作为消息的一部分。FindWindow 找到了这两个消息框,它只是在 SendMessage 运行时它不会关闭第二种类型的消息框,即使它看到它也是如此。我也尝试过 PostMessage 并且遇到了同样的问题。

这就是我所拥有的:

    private const int WM_CLOSE = 0x10;

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    public static extern int SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);

    IntPtr ErrorPopUp = FindWindow(null, WindowToClose.Trim());
                        if (ErrorPopUp != IntPtr.Zero) {
                            try {
                                Thread.Sleep(200);
                                SendMessage(ErrorPopUp, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
                                _WMExceptionDal.LogErrorMsg(_WMException);

                            } catch (Exception ex) {
                                _WMException.txt_iferror = "Unable to close the popup window";
                                _WMException.txt_sqlerrtext = ex.ToString();
                                _WMExceptionDal.LogErrorMsg(_WMException);
                            }
                        }

其他方法的任何建议,或者如果我做错了什么,为什么某些消息框会被 WM_CLOSE 关闭,为什么有些不会我真的很感激。

4

1 回答 1

1

答案比您想象的要简单:您收到的错误弹出窗口有一个“确定”按钮,而窗口标题栏区域没有“关闭”按钮。

它们非常非常原始:window proc 的消息处理仅限于对话框按钮后面的功能:

SendMessage(ErrorPopUp, WM_COMMAND, IDOK, IntPtr.Zero);

如果您发送它WM_CLOSE,则没有人在家:该窗口的消息处理程序中没有任何内容可以响应该消息。是的,曾经有一段时间我认为所有的窗口也会响应WM_CLOSE消息。

对响应来自其他线程的“关闭”消息的对话框窗口也有限制,但我认为这不是这里发生的情况。(但是,如果对话框在标题栏中确实有一个“x”按钮来关闭它,并且它没有响应您的WM_CLOSE消息,这是最可能的解释)。

无论哪种方式,您都在向它发送错误消息:创建对话框是为了响应按钮上列出的用户输入,这些是您发送的消息 -WM_COMMAND带有消息标识符:

private const int WM_COMMAND = 0x111;
private const int dlgOK = 0x1; private const int dlgCANCEL = 0x2; private const int dlgABORT = 0x3; private const int dlgRETRY = 0x4; private const int dlgIGNORE = 0x5; private const int dlgYES = 0x6; private const int dlgNO = 0x7;

问题“哪个标识符?” 通常是无关紧要的——你知道这里是“好的”——但是GetDlgItem()如果你需要询问,User32 函数会检查存在哪些对话框函数。

另外:注意带有“取消”按钮的对话框 - 对话框中有取消功能的实现,可以启用窗口菜单并在标题栏中为您提供关闭“x”按钮,其中一些实现响应WM_CLOSE消息(他们也应该回复 WM_SYSCOMMAND, SC_CLOSE);但是您不明智地依赖WM_COMMAND, dlgCANCEL.

于 2016-02-01T21:59:17.477 回答