1

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?

Adnan
  • 2,986
  • 7
  • 43
  • 63
  • Isn't the Open File Dialog supposed to be a modal dialog? – CinCout Aug 13 '15 at 06:39
  • I am new to win32 API. Do you want to say that there is a better way of opening Open Dialog? – Adnan Aug 13 '15 at 06:45
  • After opening Open Dialog, I want to open a file with win32 code without user intervention. But, since app freezes after showing Open Dialog, the next piece of code doesn't execute. – Adnan Aug 13 '15 at 06:55
  • What are you trying. Do want to control NOTEPAD? – xMRi Aug 13 '15 at 07:14
  • Stop hacking, start developing solid code. Module 1: Introduce yourself to [UI Automation](https://msdn.microsoft.com/en-us/library/windows/desktop/ee684009.aspx). – IInspectable Aug 13 '15 at 11:42

4 Answers4

2

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.

xMRi
  • 14,982
  • 3
  • 26
  • 59
2

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.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • Notepad file opening is just an example. I am trying to do something different. PostMessage worked for me. – Adnan Aug 13 '15 at 07:46
  • 2
    Whatever you are doing, that is surely not the solution. – David Heffernan Aug 13 '15 at 07:48
  • OK please guide me then on doing it in right way. I am trying to open a config file in a 3rd party app that is already running. – Adnan Aug 13 '15 at 07:55
  • It's really not constructive to do it this way. You asked how to open a file in Notepad. Now you want to do something else. You won't tell us anything about the 3rd party app and we have to fight to get details. We have many such questions here every day and askers rarely want to use the official automation approaches and for reasons unknown to me seem hell bent on hacking away in the manner you are doing. You've already accepted an answer here which tells us that you are content with what you are doing. That's fine. – David Heffernan Aug 13 '15 at 07:57
  • I apologize for that. But I was not allowed to disclose that 3rd party app. Notepad was the similar example for me. That's why I used it for an example. Apparently using PostMessage instead of ShowMessge solved my issue. That's why I accepted that answer. Thanks for your suggestion anyways. – Adnan Aug 13 '15 at 08:02
  • It always goes this way. It's as is you didn't read the bit where I wrote "official automation". Don't you even wonder what that refers to? – David Heffernan Aug 13 '15 at 08:04
1

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?

Community
  • 1
  • 1
Serge Rogatch
  • 13,865
  • 7
  • 86
  • 158
0

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.

Elemental
  • 7,365
  • 2
  • 28
  • 33
  • I don't see, how this introduces any sort of security issues, with UIPI in place. This does, however, create a support nightmare. After all, you're taking a dependency on undocumented behavior, that can change without prior notice. – IInspectable Aug 14 '15 at 11:40