Adnan
Adnan

Reputation: 2996

Win32 API: App Freezes after opening dialog window

I am trying to open "Open File Dialog" of an already opened notepad app on a button click event with win32 API. Here is the code:

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);
}

This works fine and opens the "Open Dialog". But it freezes my app. If I try to move my app window with mouse, it hangs and shows "Not Responding" on title bar. I have also tried opening this dialog window in a separate thread, but no luck. How to solve this issue?

Upvotes: 1

Views: 1654

Answers (4)

David Heffernan
David Heffernan

Reputation: 612794

In the comments you state:

I want to open a file with win32 code without user intervention.

In that case your entire approach is wrong. Pass the name of the file to ShellExecuteEx, and let the system open the file.

As for why your current code blocks, that's simple enough. SendMessage is synchronous and only returns once the message has been processed. And the message processing completes when the modal file dialog is closed. But hacking away at Notepad in this manner is never the correct solution to a problem. Please refrain.

Upvotes: 2

Serge Rogatch
Serge Rogatch

Reputation: 15020

To prevent your program from hanging, you can use PostMessage instead of SendMessage:

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

You may want to further study the difference: What is the difference between Send Message and Post Message and how these relate to C# ,WPF and Pure windows programming?

Upvotes: 1

Elemental
Elemental

Reputation: 7466

In general there is a very big difference between SendMessage and PostMessage in the windows API.

SendMessage will run the associated callback (i.e. the thing supposed to receive the message) directly and return after the message has been completely processed. This is 'blocking' your app because notepad only returns from this call after the (modal) file dialog has returned.

PostMessage will add a message to the applications message queue and return immediately; at some later point the application (notepad) will process this message.

All of this said what you are doing is probably not a good idea - this kind of remote control of other applications raises some serious security concerns.

Upvotes: 0

xMRi
xMRi

Reputation: 15355

The code you show us looks like you want to control NOTEPAD: The reason why it blocks is simple. SendMessage send the WM_COMMAND message to NOTEPAD and waits until it is processed. Notpad itself receives the WM_COMMAND message and shows it file open dialog and waits for the user input.

This is all done inside the handling of the WM_COMMAND message and SendMessage will only return when this handling is done. So either the user aborts the dialog, or he selects a file and the file gets opened.

PS: Your question is not detailed enough what yo really want to do.

Upvotes: 2

Related Questions