none
Problem Using Postmessage(hwnd,WM_COMMAND....) In .NET 4.0 C# App RRS feed

  • Question

  •  I use the following code to send a WM_COMMAND message to a menu item

    of a 32bit Native C++ app running in XP compatibilty mode in Win7(64bit) :

     

    using System.Runtime.InteropServices;

     

    [DllImport("user32.dll", CharSet = CharSet.Auto)]

    public static extern int PostMessage(IntPtr hwnd, int msg, int wparam, int lparam);

    ...

    PostMessage(APP.MainWindowHandle, WM_COMMAND, command_id, 0);

     

    It works well in the main window of the app, but fails to activate a menu item

    in another area of the same app. Just fails to work with no exception thrown.

    The same code works well when compiled/executed in C# .NET3.5 running in XP(32bit).

    Does anyone have any ideas, pointers, ideas as to what I'm doing wrong?

    I'm a bit perplexed since the function does work in one area of the code

    but not the other and also works well as I mentioned in XP .NET 3.5.

    Any suggestions will be greatly appreciated.

    Thanks,

    Tom Fisher

    Saturday, May 8, 2010 4:06 PM

Answers

  • Good news! I tried sending the HWND of the toolbar along with
    the WM_COMAND message and it works now!

    PostMessage(hwnd, WM_COMMAND, (uint)set_my_recent_folder, ToolbarWindow32_hwnd);

    Interesting that Win7(x64) requires it and XP(32bit) doesn't.

    THANKS again for your help and interest.

    Tom Fisher

    • Marked as answer by SamAgain Friday, May 14, 2010 6:43 AM
    Tuesday, May 11, 2010 5:53 PM

All replies

  •   I use the following code to send a WM_COMMAND message to a menu item

    of a 32bit Native C++ app running in XP compatibilty mode in Win7(64bit) :

     

    using

    System.Runtime.InteropServices;

    [DllImport("user32.dll", CharSet = CharSet.Auto)]

    public static extern int PostMessage(IntPtr hwnd, int msg, int wparam, int lparam);

    ...

    PostMessage(APP.MainWindowHandle, WM_COMMAND, command_id, 0);

     

    It works well in the main window of the app, but fails to activate a menu item

    in another area of the same app. Just fails to work with no exception noted.

    The same code works well when compiled/executed in C# .NET3.5 running in XP(32bit).

    Does anyone have any hints, pointers, ideas as to what I'm doing wrong?

    I'm a bit perplexed since the function does work in one area of the code

    but not the other and also works well as I mentioned in XP .NET 3.5.

    Any suggestions will be greatly appreciated.

    Thanks,

    Tom Fisher

     

     

    • Merged by SamAgain Friday, May 14, 2010 6:44 AM
    Saturday, May 8, 2010 1:20 AM
  • Are you certain that you're getting/using the correct window HANDLE? Use Spy++ to verify that the message is being sent, and sent to the correct window.

    My suspicion is that the problem lies in how you're obtaining the handle.

    Saturday, May 8, 2010 7:00 PM
  •   Thanks for the reply. That is what I suspected so I double checked the handle/control ID  that I'm

    getting using WinSpector. Even tried the other handles in the dlg box with no luck.

    As I say, the function works fine when I run the same code in XP(32bit) .NET 3.5

    It also works fine when called to execute a different menu item in Win 7(64bit) .NET 4.0.

    The item that I'm trying to activate is in a folder selection dialog box(class #32770). Using Winspector

    to filter WM_COMMAND messages shows Code 0 Control ID: 41060 HWND: 0x004b0550 when I click

    the item. It is one of five selection items located in a ToolbarWindow32 class. It is not a Button class.

     As I say, any ideas will be greatly appreciated. 

    Tom Fisher

    Saturday, May 8, 2010 10:08 PM
  • Give UI Automation a try:  http://msdn.microsoft.com/en-us/library/ms747327.aspx
    MCP
    Sunday, May 9, 2010 7:52 AM
  • It sounds like the command ID changed between XP and Win7 for that common dialog. Have you spied on it under both OSes?
    Sunday, May 9, 2010 11:40 AM
  •   Using Winspector, I get the same command ID in both Win 7 and XP.

    VERY FRUSTRATING!!

    Sunday, May 9, 2010 12:01 PM
  • I don't have Windows 7 (my beta recently expired and I have not purchased a copy yet), so I can't dig into this myself. Can you post a dump from WinSpector of you clicking on the toolbar item that you want to simulate. Make sure the dump includes messages from all the windows in the dialog (i.e. dialog + all children), and for each HWND in the dump, give me a quick description of what that handle refers to (i.e. 004E5623 Dialog window, 004F512A Toolbar, etc.).

    I'm wondering if there is message reflection happening in the newer version of the dialog, and maybe you need to target your message to a different window. Of course this could happen internally and not be visible in the message dump, but it's worth a look.

    Sunday, May 9, 2010 12:21 PM
  •   Thanks again. I wish that I was more proficent with WinSpector as I'm not quite sure how to produce and collect what you need. Could you be more specific?

    When I look at the WM_COMMAND message params received by the parent dlg window when I actually click on the item versus those sent by my code

    I don't see any difference. Of course the obvious difference is that one works and the other doesn't ! One difference that I do note is that when I use

    Postmessage to activate a menu item in the main window of the code, it works. Spying this sequence shows two identical WM_COMMAND messages

    received but no return result noted. The sequence to the dlg window always shows a zero return to the WM_COMMAND message.

     

    Sunday, May 9, 2010 8:16 PM
  • I'm not familier with WinSpector because I use Spy++. In Spy, you choose a window to log messages from, on that dialog are some options like "Include child windows", "All windows in process", etc. If you target the top-level dialog window and select "Include child windows", Spy logs all messages (they can be filtered, but I would be interested in all messages, not just WM_COMMAND as I would look for reflected messages) sent/posted to the target window and all of its child windows.

    As for a description of HWND values, that you would have to provide manually by looking at all the HWND values logged and finding out what they belong to (hunting with the window finder tool).

    Monday, May 10, 2010 2:50 PM
  •   I only have the express versions of C++ and C# which don't seem to include spyxx.exe.

    Does anyone know where I might download it?

     

    Monday, May 10, 2010 6:17 PM
  • I've heard that WinSpector is a better tool than Spy++. If my memory serves me correctly, when I last evaluated it, I found that it failed to work in a 64-bit environment and therefore was useless to me. You might try harder at getting to know the tool (a Windows message spy is one of the most valuable tools a developer can have when working with Windows apps). Because Spy++ is a "componant of Visual Studio", it's not legally redistributable.

    If you absolutely cannot produce results from WinSpector, you can email me and we'll try a different approach. My email is my name at msn dot com. Please use this forum thread's subject line in the subject of the email.

    Monday, May 10, 2010 9:19 PM
  • Hi Tom,

    Redeclare your postmessage function like this:

    [DllImport("user32.dll")]
    static public extern bool PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
    And be sure that your main window's thread is not being blocked. Since the thread will handle the message you posted asynchronously. When you use the PostMessage method, just like use it in Win32. It's the same.
    Hope this helpful to you! If you have any further quetions, please feel free to let me know.
    Please mark the right answer at right time.
    Bset Regards,
    Tracy
    Tuesday, May 11, 2010 9:38 AM
  • After doing some poking around, I came up with this solution:

    using System;
    using System.Collections.Generic;
    using System.Runtime.InteropServices;
    using System.Text;
    
    class Program
    {
      static void Main()
      {
        // Get the Open dialog
        // Enumerate the child windows, building a list of ToolbarWindow32 windows
        IntPtr hWndDialog = FindWindow("#32770", "Open");
        if (hWndDialog != IntPtr.Zero)
          EnumChildWindows(hWndDialog, EnumProc, hWndDialog);
      }
    
      static bool EnumProc(IntPtr hWndToolbar, IntPtr hWndDialog)
      {
        // Get the window's class name
        StringBuilder name = new StringBuilder(1024);
        GetClassName(hWndToolbar, name, name.Capacity);
    
        // If it's a ToolbarWindow32 window
        // Post the command message once for each toolbar window
        // One of them will turn out to be the correct one
        if (String.Compare(name.ToString(), "ToolbarWindow32") == 0)
          PostMessage(hWndDialog, 0x0111, (IntPtr)41060, hWndToolbar);
    
        return true;
      }
    
      [DllImport("user32.dll", EntryPoint = "FindWindowW", CharSet=CharSet.Unicode)]
      static extern IntPtr FindWindow(string className, string windowName);
    
      [return: MarshalAs(UnmanagedType.Bool)]
      delegate bool EnumChildProc(IntPtr hwnd, IntPtr lParam);
    
      [DllImport("user32.dll")]
      static extern int EnumChildWindows(IntPtr hwndParent, EnumChildProc enumProc, IntPtr lParam);
    
      [DllImport("user32.dll", EntryPoint = "GetClassNameW", CharSet=CharSet.Unicode)]
      static extern int GetClassName(IntPtr hwnd, StringBuilder buffer, int bufferLen);
    
      [DllImport("user32.dll")]
      static extern int PostMessage(IntPtr hwnd, int message, IntPtr wParam, IntPtr lParam);
    
    }
    
    • Edited by Tergiver Tuesday, May 11, 2010 5:35 PM removed the list and just PostMessage directly from EnumChildWindows
    Tuesday, May 11, 2010 5:28 PM
  • Good news! I tried sending the HWND of the toolbar along with
    the WM_COMAND message and it works now!

    PostMessage(hwnd, WM_COMMAND, (uint)set_my_recent_folder, ToolbarWindow32_hwnd);

    Interesting that Win7(x64) requires it and XP(32bit) doesn't.

    THANKS again for your help and interest.

    Tom Fisher

    • Marked as answer by SamAgain Friday, May 14, 2010 6:43 AM
    Tuesday, May 11, 2010 5:53 PM
  • Thanks, I wasn't able to succeed at this at win7.

    Thursday, September 6, 2012 9:08 PM