Win32 API:应用程序在打开对话框窗口

时间:2015-08-13 06:33:24

标签: c++ winapi

我正在尝试使用win32 API在按钮单击事件上打开已打开的记事本应用程序的“打开文件对话框”。这是代码:

void onButonClicked()
{

    HWND hWnd = ::FindWindow(NULL, L"Untitled - Notepad");

    HMENU hWndMenu = ::GetMenu(hWnd);
    HMENU hWndSubMenu = ::GetSubMenu(hWndMenu, 0);
    SendMessage(hWnd, WM_COMMAND, GetMenuItemID(hWndSubMenu, 1), 0);
}

这很好用并打开“打开对话框”。但它冻结了我的应用程序。如果我尝试使用鼠标移动我的应用程序窗口,它会挂起并在标题栏上显示“无响应”。我也尝试在一个单独的线程中打开这个对话框窗口,但没有运气。如何解决这个问题?

4 个答案:

答案 0 :(得分:2)

您向我们展示的代码看起来像您要控制NOTEPAD: 它阻塞的原因很简单。 SendMessage将WM_COMMAND消息发送到NOTEPAD并等待直到它被处理。 Notpad本身接收WM_COMMAND消息并显示文件打开对话框并等待用户输入。

这一切都是在处理WM_COMMAND消息时完成的,而SendMessage只会在完成此处理时返回。因此,要么用户中止对话框,要么选择文件并打开文件。

PS:你的问题不够详细,你真正想做什么。

答案 1 :(得分:2)

在评论中说明:

  

我想用win32代码打开一个文件而无需用户干预。

在这种情况下,你的整个方法都是错误的。将文件名传递给ShellExecuteEx,让系统打开文件。

至于为什么你当前的代码阻塞,这很简单。 SendMessage是同步的,只有在处理完消息后才会返回。当模态文件对话框关闭时,消息处理完成。但是以这种方式破坏记事本永远不是解决问题的正确方法。请不要。

答案 2 :(得分:1)

为防止程序被挂起,您可以使用PostMessage代替SendMessage

PostMessage(hWnd, WM_COMMAND, GetMenuItemID(hWndSubMenu, 1), 0);

您可能希望进一步研究差异:What is the difference between Send Message and Post Message and how these relate to C# ,WPF and Pure windows programming?

答案 3 :(得分:0)

一般来说,Windows API中SendMessage和PostMessage之间存在很大差异。

SendMessage将直接运行相关的回调(即应该接收消息的东西),并在消息完全处理后返回。这是“阻止”您的应用程序,因为记事本仅在(模态)文件对话框返回后才从此调用返回。

PostMessage将向应用程序消息队列添加消息并立即返回;稍后,应用程序(记事本)将处理此消息。

所有这些都说明你所做的可能不是一个好主意 - 这种对其他应用程序的远程控制引起了一些严重的安全问题。

相关问题