mIRC Home    About    Download    Register    News    Help

Print Thread
#137961 22/12/05 06:18 PM
Joined: Dec 2002
Posts: 230
G
greeny Offline OP
Fjord artisan
OP Offline
Fjord artisan
G
Joined: Dec 2002
Posts: 230
Hi there.

I'm using a docking DLL, which works just fine when I disable the "confirm on exit" option in mIRC.

Even with this option enabled, the DLL still works fine if I normally close mIRC and press the "yes" button in the confirmation dialog.

However, when I press the "no" button, the docking will be really messed up.

I traced this back to the WM_CLOSE message, which is sent even before you confirmed the exit. So basically, the DLL issues the commands that are meant for "unloading" the DLL even though mIRC is still running (i.e. you pressed "no" in the confirmation dialog).

So, my question is, is there a simple solution for this problem? Like a message I can use instead of WM_CLOSE, that triggers when mIRC is REALLY closed?

Thanks for your help.

#137962 23/12/05 12:12 AM
Joined: Jan 2003
Posts: 2,523
Q
Hoopy frood
Offline
Hoopy frood
Q
Joined: Jan 2003
Posts: 2,523
Sounds like you want WM_DESTROY


/.timerQ 1 0 echo /.timerQ 1 0 $timer(Q).com
#137963 23/12/05 09:14 AM
Joined: Dec 2002
Posts: 230
G
greeny Offline OP
Fjord artisan
OP Offline
Fjord artisan
G
Joined: Dec 2002
Posts: 230
Yup, sounds like I want it, unfortunately, that message is never sent wink

#137964 23/12/05 02:23 PM
Joined: Jan 2003
Posts: 249
C
Fjord artisan
Offline
Fjord artisan
C
Joined: Jan 2003
Posts: 249
it is sent and in fact it's there that you should unsubclass mIRC before it closes and clean everything you need to clean.

#137965 23/12/05 03:28 PM
Joined: Jun 2003
Posts: 195
N
Vogon poet
Offline
Vogon poet
N
Joined: Jun 2003
Posts: 195
technically youll want to un subclass in the WM_NCDESTROY. typically if youve reserved any memory. Dont forget to PostMessage the destroy and return 0 from your wndproc. (so your out of your proc when the dll unloads and mIRC can see the destroy)

#137966 17/01/06 07:43 AM
Joined: Dec 2002
Posts: 580
N
Fjord artisan
Offline
Fjord artisan
N
Joined: Dec 2002
Posts: 580
Let me save everyone a whole lot of time searching MSDN for info on the proper way to subclass windows using Win32 API calls... Download my DLL at SuperTemplate 1.1. Actually you only need one c++ file in my DLL Template, safe-subclass.cpp (will most likely be posted separately on mircscripts.org soon)... BTW, If handled properly, it doesn't matter what message is used to unsubclass... And if you use "safe-subclassing.cpp" it wont matter which you use either.

Basically, Any DLLs created using this subclassing process, can subclass the same window at the same time, AND neither needs to know about the other to unsubclass. This means it doesn't matter what order the DLLs are unsubclassed (unloaded) or what message they use to unsubclass...

And yes, either WM_DESTROY (Destroy Window Message) or WM_QUIT (Hwnd should be eliminated) can be used to unsubclass when the window is closed.

#137967 17/01/06 04:14 PM
Joined: Jun 2003
Posts: 195
N
Vogon poet
Offline
Vogon poet
N
Joined: Jun 2003
Posts: 195
I wouldnt use WM_QUIT to unsubclass. If mIRC was the subclassed window and the user clicked "No" to the confirm dialog then your subclass will be removed even tho mIRC wasnt actually closed. mIRC uses WM_QUIT to display the confirm on close dialog.

Im curious as to how your controlling other dll's (that arent using your patch) in the unsubclass. You will still end up with a broken chain because dll's not using your file will simply unsubclass w/o calling a safe routine. My last attempt used api hijacking to control SetWindowLong but still required that all the dll's loaded be compiled with my lib. i.e it had a msg manager and added subclassed windows to a tree when the dll called SetWindowLong.

#137968 17/01/06 04:38 PM
Joined: Dec 2002
Posts: 580
N
Fjord artisan
Offline
Fjord artisan
N
Joined: Dec 2002
Posts: 580
Wrong... As your original post stated, mirc asks to confirm exit when a WM_CLOSE messsage is sent, WM_QUIT is the LAST message a window ever receives.

But you are correct that WM_QUIT should not be used (I just looked it up), WM_DESTORY is the proper place to unsubclass...

WM_CLOSE
WM_DESTROY
WM_QUIT

BTW, you are correct, there isn't a realisticly possible way to control "unsafe" dll's, Only DLL's that use my "safe-subclass.cpp" (or equivilant) file will be compatibile. IMHO, it should be part of the Win32 API... wink


NaquadaBomb
www.mirc-dll.com
#137969 17/01/06 05:11 PM
Joined: Dec 2002
Posts: 580
N
Fjord artisan
Offline
Fjord artisan
N
Joined: Dec 2002
Posts: 580
BTW, despite what Microsoft says here...

Quote:

The WM_QUIT message is not associated with a window and wherefore will never be received through a window's window procedure. It is retrieved only by the GetMessage or PeekMessage functions.

I tested this when I was writing safe-subclass.cpp, and it appears that WM_QUIT is received in subclassed windows procedures.


NaquadaBomb
www.mirc-dll.com
#137970 08/03/06 12:10 AM
Joined: Dec 2002
Posts: 230
G
greeny Offline OP
Fjord artisan
OP Offline
Fjord artisan
G
Joined: Dec 2002
Posts: 230
I still can't get this to work. Could it be that mIRC unloads the DLL upon exit before the WM_DESTROY message is received?

I'm really not doing anything fancy with the DLL... I'm just catching the WM_SIZE message so I know when the mIRC window is resized.

I tested this with ShowMessage(), on WM_CLOSE a dialog pops up, but when I replace it with WM_DESTROY or WM_QUIT, nothing happens...

#137971 18/03/06 01:30 AM
Joined: Dec 2002
Posts: 580
N
Fjord artisan
Offline
Fjord artisan
N
Joined: Dec 2002
Posts: 580
I guess it is possible. If when using confirm on exit, a yes answer is given (still processing WM_CLOSE message), before the message completes, the DLL's are unload... This would not be good. mIRC should unload DLL's in WM_DESTROY or WM_QUIT. Only one person can tell you if that's the case though... wink


NaquadaBomb
www.mirc-dll.com
#137972 21/03/06 10:23 PM
Joined: Dec 2002
Posts: 580
N
Fjord artisan
Offline
Fjord artisan
N
Joined: Dec 2002
Posts: 580
Quote:
I still can't get this to work. Could it be that mIRC unloads the DLL upon exit before the WM_DESTROY message is received?


Using thread hooks I have determined that this is "probably" what does happen. That's a problem, here's why...

Say a DLL is subclassing the mIRC app, on WM_CLOSE it does nothing. Now the DLL is unloaded... The return value of WM_CLOSE is going to return to the subclassed callback, which is no longer in memory, regardless of what WND_PROC was changed to.

To prevent problems, unsubclassing must be completed when WM_CLOSE is received, then return 0L to the current WM_CLOSE message and PostMessage(WM_CLOSE) again so that the subclassed procedure is out of the chain when WM_CLOSE is processed by mIRC.

Now the problem is "Confirm on Exit"... WM_CLOSE can either finish closing or be canceled. If we unsubclass in WM_CLOSE before knowing this, and exit is canceled, mIRC will continue to run but now be unsubclassed.


NaquadaBomb
www.mirc-dll.com
#137973 21/03/06 11:03 PM
Joined: Dec 2002
Posts: 580
N
Fjord artisan
Offline
Fjord artisan
N
Joined: Dec 2002
Posts: 580
Here is what I saw hooking WM_CLOSE. I have excluded the WM_DESTROY messages of controls for simplicity.

Canceled
WM_CLOSE: 1376684 16 0 0 mIRC mIRC
WM_CREATE: 1180678 1 1225544 0 #32770
WM_DESTROY: 1180678 2 0 0 #32770 Confirm Exit
WM_CLOSE_RETURN mIRC 1376684

Close Confirmed
WM_CLOSE: 1376684 16 0 0 mIRC mIRC
WM_CREATE: 1246214 1 1225544 0 #32770
WM_DESTROY: 1246214 2 0 0 #32770
(NO RETURN)

It then appears that WM_DESTROY is sent out to all(?) mIRC children. The "confirm on exit's" dialog and controls receive WM_DESTORY first. Then any controls the DLL created receive WM_DESTROY. Here is where output stops, either because the DLL was unloaded or because mIRC will no longer process WM_MCOMMAND.


NaquadaBomb
www.mirc-dll.com

Link Copied to Clipboard