Michael Aivaliotis Posted January 30, 2013 Report Share Posted January 30, 2013 How can my LabVIEW EXE application handle the windows WM_Close message correctly? I have tried the Windows Messaging Queue library without any resolution to this problem. The behavior I'm seeing is that my application window closes but the app remains running as can be seen by looking at the process list in Windows Task Manager. The images below don't show it but I've added the Quit LabVIEW function to exit the app. So far I've tried: Creating a loop that monitors the windows message queue: Application Instance Closed? Event: Panel Close? Event: I've read this thread but it didn't seem to address the issue head-on. Or I didn't see what the resolution was. Any help is appreciated. Thanks. Quote Link to comment
Darin Posted January 31, 2013 Report Share Posted January 31, 2013 The simple answer is that the 'correct' way to handle this message is indeed with the Application Instance Close? event. I can pump this message directly to a LV executable and it fires the event every time (so far). There is a bit of a goof in your top image, the code for WM_CLOSE is 0x10 or 16, either change the radix of your Case Structure (yes) or change the value. Unless for some reason you have registered and are looking for WM_ENABLE. Is this an intermittent problem? By that I especially mean does it happen to some executables all of the time, all executables some of the time, or some executables some of the time? And how exactly are you triggering the shutdown that fails to kill the process? Perhaps it is not sending the message you expect. Of course while testing I notice several Chrome processes running on my machine with the browser closed so perhaps it is not so uncommon. 1 Quote Link to comment
Michael Aivaliotis Posted January 31, 2013 Author Report Share Posted January 31, 2013 The simple answer is that the 'correct' way to handle this message is indeed with the Application Instance Close? event. I can pump this message directly to a LV executable and it fires the event every time (so far). The Application Instance Close? event doesn't work. If you can attach an example that works, that would be nice, but my tests show it not working. You're correct in catching my bug. Nice to have a second set of eyes . That was the problem. After I fixed that it worked as expected. So the updated diagram for anyone else needing this: Quote Link to comment
Darin Posted February 1, 2013 Report Share Posted February 1, 2013 Here is a barebones example. You can build the exe from the project, or run the included one called CloseMe.exe. You can run Pump WM_CLOSE.vi to send that message to the running executable, if the popup appears then the Event Fired. Test WM_CLOSE.zip Quote Link to comment
Michael Aivaliotis Posted February 1, 2013 Author Report Share Posted February 1, 2013 Awesome thanks. I think I figured out why Application Instance Close? wasn't working for me. So the WM_CLOSE message requires a handle to a window name. My executable had a custom window name. I was using this as the window name. So the window was closing fine but the event was not firing and the app remained in memory. In your example, if you set the VI title name to CloseMe, instead of the default CloseMe.vi, then it won't work. So the message gets sent to the window instead of the app, which is also called CloseMe.exe. Now I just have to make sure that my window title doesn't match my exe name. Quote Link to comment
Ton Plomp Posted February 1, 2013 Report Share Posted February 1, 2013 The Application Instance Close? event doesn't work. If you can attach an example that works, that would be nice, but my tests show it not working. Michael, could you explain 'Does not work'. What do you expect from this event? It should get triggered when Windows wants to close an application (I get this event when I shut down my computer). Since you Discard the event your application is ignoring this event, and you should close your app yourself. Ton Quote Link to comment
Rolf Kalbermatter Posted February 1, 2013 Report Share Posted February 1, 2013 Ton definitely has pointed out one potential pitfal in your code. The Panel:Close? event always works for me. if you tell LabVIEW to discard it you have to make sure that your state machine then goes into a clean-up state, that eventually closes the front panel explicitly and then also terminates the state machine loop. If your front panel is the top level VI too, the code after the VI:Close method won't be executed in an executable as the LabVIEW runtime engine will be shutdown immediately after the last window is gone, but it helps when the application is run in the development environment. I have personally only used the Application:Close? event in deamon like applications that do not show a front panel by default. The proper operation when a user requests to shutdown the machine is that Windows sends a WM_CLOSE message to every application window, which will result into a Panel:Close? event in the LabVIEW VI, and then a WM_QUIT to the main instance which will trigger the Application:Close? event. But if you handle all the Panel:Close? events properly there should be no panel (hidden or not) left over at the time the Application:Close? event will trigger. On the other hand adding both Panel:Close? and Application:Close? to the state machine handling and going into a proper VI terminate state when you chose to discard that event, wouldn't hurt either. Quote Link to comment
Ton Plomp Posted February 1, 2013 Report Share Posted February 1, 2013 If I have an application that has lengthy processes (>10 seconds), or when it's unlikely that I regurarly (agian at least every 10 seconds) hit the main event loop, then I have a dedicated 'Terminate' event loop, that's monitoring both the Application:Close? and Panel:Close? events and will signal an abort to these lengthy processes to stop prematurely. Ton Quote Link to comment
Darin Posted February 1, 2013 Report Share Posted February 1, 2013 So the WM_CLOSE message requires a handle to a window name. My executable had a custom window name. I was using this as the window name. So the window was closing fine but the event was not firing and the app remained in memory. In your example, if you set the VI title name to CloseMe, instead of the default CloseMe.vi, then it won't work. So the message gets sent to the window instead of the app, which is also called CloseMe.exe. Now I just have to make sure that my window title doesn't match my exe name. Should have been an obvious assumption on my part that you were changing the name. If you remember the funny business with the 'HideRootWindow' ini key and multiple entries in the taskbar, this issue is almost certainly related to that. At any rate, an executable appears multiple times in the windows list. The name of the first entry (numerical order) is the window title. The other two entries have the name of the executable without the extension. The proper handle happens to be the second one in the list. When you change the window title to match the name of the executable without the extension 'CloseMe' in this case, then FindWindow will now return the handle to the first window instead of the second. Now you are pumping messages to the wrong one and havoc ensues. Change the title to 'Change Me' and still use 'ChangeMe' to find the Handle and you are all set. My personal naming convention combined with the very small number of times I have pumped messages to executables has kept me safe from this behavior. When naming files I leave out spaces, but in the window titles I use them. I'd rather be lucky than good. Quote Link to comment
Michael Aivaliotis Posted February 1, 2013 Author Report Share Posted February 1, 2013 Thanks Darin for the response. Ya, figures I'd run into a corner case. All is good now. Quote Link to comment
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.