Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. SendMessage for Interprocess communication stops working

SendMessage for Interprocess communication stops working

Scheduled Pinned Locked Moved C / C++ / MFC
c++visual-studiodebugging
10 Posts 4 Posters 1 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • F Offline
    F Offline
    ForNow
    wrote on last edited by
    #1

    Hi, I have been using SendMessage for interprocess communication. The Sender Is The Parent console C program. The receiver is a MFC Windows program All of the sudden it stopped working I am sure that the windows handle is valid as after The MainFrame is created a (running under the VS debugger) I observe the m_hWnd of the Mainframe. it is the same value returned by the FindWindow (to reterive the windows handle) I orignally a WM_USER + X and later tried RegisterWindowMessage The MFC message map (ON_MESSAGE) has message either a #define WM_USER + x or UINT returned from the RegisterWindowMessage and member handling the message is LRESULT Wparam, Lparam

    M L L 3 Replies Last reply
    0
    • F ForNow

      Hi, I have been using SendMessage for interprocess communication. The Sender Is The Parent console C program. The receiver is a MFC Windows program All of the sudden it stopped working I am sure that the windows handle is valid as after The MainFrame is created a (running under the VS debugger) I observe the m_hWnd of the Mainframe. it is the same value returned by the FindWindow (to reterive the windows handle) I orignally a WM_USER + X and later tried RegisterWindowMessage The MFC message map (ON_MESSAGE) has message either a #define WM_USER + x or UINT returned from the RegisterWindowMessage and member handling the message is LRESULT Wparam, Lparam

      M Offline
      M Offline
      Midi_Mick
      wrote on last edited by
      #2

      The issue with SendMessage is that it blocks the calling process until a response is received. Therefore, if something goes wrong in the receiver, the caller tends to hang. So in your situation, my first checks would involve seeing what, if anything, the Mainframe is doing with the message that was sent. Put a breakpoint in the Mainframe's message pump where it catches your registered message, and take it from there. If, by chance, it is not catching your registered message, then there is something amiss with the registration process.

      Cheers, Mick ------------------------------------------------ It doesn't matter how often or hard you fall on your arse, eventually you'll roll over and land on your feet.

      F 1 Reply Last reply
      0
      • M Midi_Mick

        The issue with SendMessage is that it blocks the calling process until a response is received. Therefore, if something goes wrong in the receiver, the caller tends to hang. So in your situation, my first checks would involve seeing what, if anything, the Mainframe is doing with the message that was sent. Put a breakpoint in the Mainframe's message pump where it catches your registered message, and take it from there. If, by chance, it is not catching your registered message, then there is something amiss with the registration process.

        Cheers, Mick ------------------------------------------------ It doesn't matter how often or hard you fall on your arse, eventually you'll roll over and land on your feet.

        F Offline
        F Offline
        ForNow
        wrote on last edited by
        #3

        There is no message pump (Maybe under the covers) As it's a message map I can only break at the handling procedure which isn't reached

        M 1 Reply Last reply
        0
        • F ForNow

          There is no message pump (Maybe under the covers) As it's a message map I can only break at the handling procedure which isn't reached

          M Offline
          M Offline
          Midi_Mick
          wrote on last edited by
          #4

          Then that tends to indicate an issue with the message registration. Go back (temporarily) to using a WM_USER message, and if that works, then you'll have to look deeper into the way the RegisterMessage is being called. It's been quite a few years since I've done anything with custom windows message, but I have a vague recollection that there is a "gotcha" in there that got me for a while. Can't remember what it was, though, sorry.

          Cheers, Mick ------------------------------------------------ It doesn't matter how often or hard you fall on your arse, eventually you'll roll over and land on your feet.

          1 Reply Last reply
          0
          • F ForNow

            Hi, I have been using SendMessage for interprocess communication. The Sender Is The Parent console C program. The receiver is a MFC Windows program All of the sudden it stopped working I am sure that the windows handle is valid as after The MainFrame is created a (running under the VS debugger) I observe the m_hWnd of the Mainframe. it is the same value returned by the FindWindow (to reterive the windows handle) I orignally a WM_USER + X and later tried RegisterWindowMessage The MFC message map (ON_MESSAGE) has message either a #define WM_USER + x or UINT returned from the RegisterWindowMessage and member handling the message is LRESULT Wparam, Lparam

            L Offline
            L Offline
            Lost User
            wrote on last edited by
            #5

            Hi,

            ForNow wrote:

            I have been using SendMessage for interprocess communication.

            When you ask for help you should always mention the operating system. Read the article section about deadlocks and make sure that you understand the dangers of using SendMessage for IPC. Also note that moving forward... all software engineers are encouraged to use the recommended/supported Microsoft Interprocess Communication mechanisms.

            ForNow wrote:

            and later tried RegisterWindowMessage

            Are you checking that the return value of RegisterWindowMessage is not zero? Why did you ask for help but did not give the results of GetLastError()? I recommend avoiding RegisterWindowMessage. Keep in mind that you can only obtain 16,384 RegisterWindowMessage unique identifiers. After that... there are no more system resources for globally unique messages. Let's imagine that you are writing software to control an oil refinery system. Maybe you are writing defense department mission critical software. Perhaps an airplane requires your Windows component for operation. Imagine if your writing the radar system for an ship out in the sea. Maybe in these scenarios the operating system is mission critical and should never go down. In these scenarios it is important to avoid RegisterWindowMessage on these systems. Likewise system builders of mission critical software should perform accounting on all software utilizing RegisterWindowMessage.

            ForNow wrote:

            I orignally a WM_USER + X

            Here you chose the wrong message integer range for IPC. Read this: WM_USER = Used to define private messages for use by private window classes Some possible solutions: 1.) Re-write your IPC and avoid the window message system. 2.) Check if your window message was filtered-out via UIPI. If so, utilize the ChangeWindowMessageFilterEx function to

            F 1 Reply Last reply
            0
            • F ForNow

              Hi, I have been using SendMessage for interprocess communication. The Sender Is The Parent console C program. The receiver is a MFC Windows program All of the sudden it stopped working I am sure that the windows handle is valid as after The MainFrame is created a (running under the VS debugger) I observe the m_hWnd of the Mainframe. it is the same value returned by the FindWindow (to reterive the windows handle) I orignally a WM_USER + X and later tried RegisterWindowMessage The MFC message map (ON_MESSAGE) has message either a #define WM_USER + x or UINT returned from the RegisterWindowMessage and member handling the message is LRESULT Wparam, Lparam

              L Offline
              L Offline
              leon de boer
              wrote on last edited by
              #6

              Lets first discuss the general Windows cases. Basic rule never use SendMessage between any windows that you don't directly know the message arrangements use PostMessage instead. The other trap with SendMessage is it is easy to go circular (happens a lot when playing around with scrollbar code :-)). Make sure the send message handling doesn't send a messsage back to the caller which then sends off another message and around and around it goes. I also have a scary feeling you have a different thread on the console app given the title Interprocess. If that is true you can not blindly use SendMessage, it crosses a thread boundary and it will deadlock .... Guaranteed if done raw. It is sort of covered in the Microsoft discussion of SendMessage when they talk about the data marshalling and playing around with SendMessageTimeout. The easier solution is just don't use it, PostMessage is there and has no issues. If you need a response back you post back another message so you setup a ping/pong message system using PostMessage, saves a lot of effort and heartache. In the directory watcher code I did for you that is why I used PostMessage in the thread not SendMessage. Use SendMessage there and it will Deadlock randomly.

              // Post off message back to application window.
              PostMessage(watchData->AppWindow, watchData->MsgId, watchData->CmdId, (LPARAM)msgToApp);

              Randor in his post is correct if you want to tow the "Microsoft line", so I guess look at is what you are coding a critical system. Historically most have always used WM_USER and I have never seen a clash because there is really only you, Windows and your framework that post messages around inside your application and you can see it in testing and debugging on your machine. This isn't a bug that would suddenly appear in the field or such, it was always more a problem if you had two or more programmers and they both selected the same message number you got some funny things happen. Anyhow if you are going to stick to messages perhaps move up to WM_APP messages (It came in with Windows 95) because that range is designed to do exactly what you are doing and will be one more bit of safety. None of these message ranges go inside/outside your applications so it's only stuff within your application you have to worry about. AFAIK windows itself puts no messages into the WM_USER range these days because of the data marshal requirements and I believe it has been like that since Win95. Even the classic old ones like LB_ADDSTRING got moved into the standard wind

              F 1 Reply Last reply
              0
              • L Lost User

                Hi,

                ForNow wrote:

                I have been using SendMessage for interprocess communication.

                When you ask for help you should always mention the operating system. Read the article section about deadlocks and make sure that you understand the dangers of using SendMessage for IPC. Also note that moving forward... all software engineers are encouraged to use the recommended/supported Microsoft Interprocess Communication mechanisms.

                ForNow wrote:

                and later tried RegisterWindowMessage

                Are you checking that the return value of RegisterWindowMessage is not zero? Why did you ask for help but did not give the results of GetLastError()? I recommend avoiding RegisterWindowMessage. Keep in mind that you can only obtain 16,384 RegisterWindowMessage unique identifiers. After that... there are no more system resources for globally unique messages. Let's imagine that you are writing software to control an oil refinery system. Maybe you are writing defense department mission critical software. Perhaps an airplane requires your Windows component for operation. Imagine if your writing the radar system for an ship out in the sea. Maybe in these scenarios the operating system is mission critical and should never go down. In these scenarios it is important to avoid RegisterWindowMessage on these systems. Likewise system builders of mission critical software should perform accounting on all software utilizing RegisterWindowMessage.

                ForNow wrote:

                I orignally a WM_USER + X

                Here you chose the wrong message integer range for IPC. Read this: WM_USER = Used to define private messages for use by private window classes Some possible solutions: 1.) Re-write your IPC and avoid the window message system. 2.) Check if your window message was filtered-out via UIPI. If so, utilize the ChangeWindowMessageFilterEx function to

                F Offline
                F Offline
                ForNow
                wrote on last edited by
                #7

                Thanks so much for your reply I have a couple questions first in order to use the Hammer and mind you I only need to use SendMessage in the console app ONCE for the LRESULT is the windows handle of the the modeless dialog box which I will PostMessage from the console app to the windows app to say data is ready The Data is in shared storage I would have to create a message pump via GetMessage,TranslateMessage,DispatchMessage per yourself How to post a thread message to a console application[^] Second What Makes SendMessage with WM_COPYDATA message so special that it is Sanctioned By MicroSoft

                L 1 Reply Last reply
                0
                • L leon de boer

                  Lets first discuss the general Windows cases. Basic rule never use SendMessage between any windows that you don't directly know the message arrangements use PostMessage instead. The other trap with SendMessage is it is easy to go circular (happens a lot when playing around with scrollbar code :-)). Make sure the send message handling doesn't send a messsage back to the caller which then sends off another message and around and around it goes. I also have a scary feeling you have a different thread on the console app given the title Interprocess. If that is true you can not blindly use SendMessage, it crosses a thread boundary and it will deadlock .... Guaranteed if done raw. It is sort of covered in the Microsoft discussion of SendMessage when they talk about the data marshalling and playing around with SendMessageTimeout. The easier solution is just don't use it, PostMessage is there and has no issues. If you need a response back you post back another message so you setup a ping/pong message system using PostMessage, saves a lot of effort and heartache. In the directory watcher code I did for you that is why I used PostMessage in the thread not SendMessage. Use SendMessage there and it will Deadlock randomly.

                  // Post off message back to application window.
                  PostMessage(watchData->AppWindow, watchData->MsgId, watchData->CmdId, (LPARAM)msgToApp);

                  Randor in his post is correct if you want to tow the "Microsoft line", so I guess look at is what you are coding a critical system. Historically most have always used WM_USER and I have never seen a clash because there is really only you, Windows and your framework that post messages around inside your application and you can see it in testing and debugging on your machine. This isn't a bug that would suddenly appear in the field or such, it was always more a problem if you had two or more programmers and they both selected the same message number you got some funny things happen. Anyhow if you are going to stick to messages perhaps move up to WM_APP messages (It came in with Windows 95) because that range is designed to do exactly what you are doing and will be one more bit of safety. None of these message ranges go inside/outside your applications so it's only stuff within your application you have to worry about. AFAIK windows itself puts no messages into the WM_USER range these days because of the data marshal requirements and I believe it has been like that since Win95. Even the classic old ones like LB_ADDSTRING got moved into the standard wind

                  F Offline
                  F Offline
                  ForNow
                  wrote on last edited by
                  #8

                  thanks But PostMessage Windows -> console wont work because the console app doesn't have a message queue. I know the GetMessage,TranslateMessage,DispatchMessage creates one. Or Rather the GetMessage I have a question about the Message Structure Since the console app doesn't a windows the Hwnd is NULL What about the last parameter of the message structure the Point parameter what would its value be in the console application

                  L 1 Reply Last reply
                  0
                  • F ForNow

                    Thanks so much for your reply I have a couple questions first in order to use the Hammer and mind you I only need to use SendMessage in the console app ONCE for the LRESULT is the windows handle of the the modeless dialog box which I will PostMessage from the console app to the windows app to say data is ready The Data is in shared storage I would have to create a message pump via GetMessage,TranslateMessage,DispatchMessage per yourself How to post a thread message to a console application[^] Second What Makes SendMessage with WM_COPYDATA message so special that it is Sanctioned By MicroSoft

                    L Offline
                    L Offline
                    Lost User
                    wrote on last edited by
                    #9

                    ForNow wrote:

                    I would have to create a message pump via GetMessage,TranslateMessage,DispatchMessage

                    Hi, Calling the PostMessage function exported from user32.dll results in a NtUserPostMessage system call. This alone should be enough to promote the thread to a gui thread via KiConvertToGuiThread. Note that things are changing as security features are being added to the Microsoft Windows platform. You would need to make sure that PROCESS_CREATION_MITIGATION_POLICY_WIN32K_SYSTEM_CALL_DISABLE_ALWAYS_ON is not defined. This security feature disables win32k system calls for a process/thread.

                    ForNow wrote:

                    Second What Makes SendMessage with WM_COPYDATA message so special that it is Sanctioned By MicroSoft

                    You are essentially asking: 1.) Why does User Interface Privilege Isolation exist? 2.) Why is the old message model (for inter-process communication) being deprecated ? Basically the answer is: For a future with better secure computing platform and secure internet connectivity. Recent hacking attacks described in the media (i.e. democratic national convention) could have potentially been mitigated by defining PROCESS_CREATION_MITIGATION_POLICY_WIN32K_SYSTEM_CALL_DISABLE_ALWAYS_ON on browser/e-mail rendering threads. Essentially a 'system call' attack surface reduction. Always use a modern up-to-date browser. I recommend Microsoft Edge or Google Chrome. Chromium Win32k system call lockdown[^] Security enhancements for Microsoft Edge[^] Hopefully one day software companies will be required to adhere to an international standard for secure computing. We are still in the wild-west early stages of computing.

                    1 Reply Last reply
                    0
                    • F ForNow

                      thanks But PostMessage Windows -> console wont work because the console app doesn't have a message queue. I know the GetMessage,TranslateMessage,DispatchMessage creates one. Or Rather the GetMessage I have a question about the Message Structure Since the console app doesn't a windows the Hwnd is NULL What about the last parameter of the message structure the Point parameter what would its value be in the console application

                      L Offline
                      L Offline
                      leon de boer
                      wrote on last edited by
                      #10

                      Okay lets first deal with your misconceptions Windows console windows do have a window handle it just has a special function to get it because it isn't present by default because you start with main not winmain and main has no position for it on it's parameters which are arguments. GetConsoleWindow function (Windows)[^] You can also directly pull the message handler if you want to just provide your own that looks like this

                      WNDPROC ConsoleWindow = NULL;

                      static LRESULT CALLBACK MyWndProc(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam) {

                      // Process your message here
                      
                      if (ConsoleWindow)
                      	return CallWindowProc(ConsoleWindow, Wnd, Msg, wParam, lParam);   // Call back old handler
                      return(0);
                      

                      }

                      // Usually first thing in main
                      HWND hWnd = GetConsoleWindow();
                      ConsoleWindow = (WNDPROC)SetWindowLong(hWnd, GWL_WNDPROC, (LONG)MyWndProc);

                      However since Win95 we tend not to do that anymore because there is a much easier way with a special class called Message-Only Windows. There are even a couple of articles on using them in the code project archives but it's just like any normal window just it has no visible parts. The 3rd alternative is you make a normal windows program and create a console window from the launch using AllocConsole. AllocConsole function (Windows)[^] Lots of science and maths guys do this so they can dump data out onto the console window while running there graphics. You do not have to have a graphics window however you can simply use the stdin and stdout ... here is the simplest sample. Compile it as a standard windows GUI project. So again in this sample you have a standard message queue available and a console window.

                      #include
                      #include

                      int APIENTRY WinMain(HINSTANCE hInstance,
                      HINSTANCE hPrevInstance,
                      LPSTR lpCmdLine,
                      int nCmdShow)
                      {
                      DWORD charsRead = 0;
                      TCHAR keyBuffer[100];

                      AllocConsole();
                      
                      HANDLE myConsoleHandle = GetStdHandle(STD\_OUTPUT\_HANDLE);
                      DWORD cCharsWritten;
                      TCHAR\* str = TEXT("Hello I am the console\\r\\n");
                      WriteConsole(myConsoleHandle, st
                      
                      1 Reply Last reply
                      0
                      Reply
                      • Reply as topic
                      Log in to reply
                      • Oldest to Newest
                      • Newest to Oldest
                      • Most Votes


                      • Login

                      • Don't have an account? Register

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • World
                      • Users
                      • Groups