mIRC Homepage
Posted By: TheXenocide Menu DLL Help - 22/10/03 07:17 AM
I'm working on a DLL for a project and i've run into a problem trying to set mIRCs menubar. It seems that everytime i try to set the menubar mIRC closes immediately. I've tried using the SetMenu() API and the SendMessage(WM_MDISETMENU,...) command and they both react the same. I know that it is possible there is a dll called menuedit that does it. I've done some debugging and I can't seem to find a window message to capture from mIRCs WndProc to stop this from happening. Also: the same exact code works when setting the menubar to a picture window. please help frown
Posted By: legolas558 Re: Menu DLL Help - 28/10/03 07:50 PM
Are you sure that menuedit sets a new menu bar? Perhaps it edits the runtime menu resource handle and then refreshes it to the app...this would prevent the HANDLE from changing and is a good hack to prevent any WM_DESTROY in the mIRC's WndProc...
Posted By: Narusegawa_Naru Re: Menu DLL Help - 28/10/03 08:35 PM
depending on what your wanting to do using the existing menu may indeed be the easiest method. however if for example you wish to alter the menu using ownerdraw it may be faster to simply create your own menu. Note however that the SetMenu api replaces the windows menu but does not destroy the old menu. An application should retrieve the old menu using GetMenu then call DestroyMenu on that handle. this will prevent memory leaks. I dont think that SetMenu will automatically set the new window menu in the new menubar. the window menu is the menubar item that houses the list of currently opened mdi windows (note that unless a particular window is made to open on the desktop it will be an MDI window and is a child of the MDI client window NOT the mirc main window). I think you will be required to send the WM_MDISETMENU message anyway (unless you dont plan on allowing the display of mdi windows). This message is not sent to the frame window (the mWnd in a dll call) but instead is sent to the mdi window. Alternatively this message can also replace the whole menubar as well. Using this message the application MUST call the DrawMenuBar function to disply the new changes. The menu is part of the non-client area of the window and is not subject to change with WM_PAINT or WM_ERASEBKGND. as far as i know WM_NCPAINT wont redraw the menu either so an explicit call is a must. as for preventing the WM_DESTROY message from being sent i dont see how using the original menu's handle prevents this. in fact im sure it wont. Also i dont think this is your problem anyway perhaps if you posted some of the offending code i may be able to assist you further. Im afraid ill be moving to houston this thursday (in 2 days) and i wont be back on for some time so if you read this late dont think that my long wait is at all an unwillingness to help im simply not here lol.
Posted By: TheXenocide Re: Menu DLL Help - 29/10/03 05:47 AM
Thank you both for your replies smile

First, yes i'm sure that menuedit.dll replaced mIRCs menubar. there were functions to modify mIRCs existing menubar, but there are problems if you try to delete the commands menu (and i would imagine, the newly added favorites menu) because mIRC will automatically update those items on the HMENU that was ORIGINALLY mIRCs menubar, so "GrimZ" added another function that would replace mIRCs menu.

I over-ride mRICs WndProc, so I catch the WM_DESTROY message and return mIRC to it's original state and resend the WM_DESTROY message to mIRCs WndProc, thus removing the potential for undestroyed menus and such.

Naru: yes i am creating owner drawn menus, and thank you for the tip on WM_SETMDIMENU, I forgot that I was sending it to the frame window, rather than the MDI client window frown I think that that may help, also: i know that I must use the DrawMenuBar command with that message smile.

If i can't get the code to work in the next couple of days (while you are moving) then I will post some code or e-mail some to you or something, that way you can see what's up smile.

Once again, thank you very much
Posted By: Narusegawa_Naru Re: Menu DLL Help - 29/10/03 02:38 PM
most likely the problem is in catching the WM_DESTROY. instead catch the WM_CLOSE perform the unsubclass there then PostMessage it to the original proc. using SendMessage causes your dll to wait for a return value and after sending WM_DESTROY back to mirc its no longer valid. If you replace the menu its usually safe to destroy the old handle as mirc will recieve the new handle in any menu messages sent to the procedure. i dont think mirc stores the handle globaly as the menu is most likely a resource. more likely it retrieves its handle through GetMenu when altering it such as adding items to command etc.

on newer versions of windows memory leaks can be freed upon termination of the process and/or thread wich caused the leak in the first place. this is not always true however and i would suggest destroying the old handle after replacing it. if for some reason mirc actually is storing the handle globally this could indeed cause a crash if you free it but i dont think thats the case. at any rate trial and error is most likely the best solution.
Posted By: TheXenocide Re: Menu DLL Help - 29/10/03 11:51 PM
Sorry, at the time that I was writing my reply, I did not have the source handy (nor do I now :tongue:), but I am indeed catching the WM_CLOSE message instead of WM_DESTROY and using PostMessage after restoring mIRCs original WndProc, lol. That's simple stuff that you think of when coding, but not necessarily when typing a reply laugh.

At any rate, the reason I was thinking that mIRC stored the HMENU locally is because in GrimZ's menuedit.dll he states (in the docs) that he had to replace mIRCs original menu to stop mIRC from trying to redraw the commands menu . What i've now done (which i should have done in the first place) is used "depends.exe" on menuedit.dll and determined that it uses GetClass* RegisterClass and UnregisterClass (or whatever that API really is) and other such functions. I'm not entirely sure what this means, but i know that mIRC uses a resource based menu and that the mIRC Frame has the resource menu as it's "default" menu, which may be one of the things causing the problems, any suggestions? when i go home i'll post a full list of the APIs it uses from GDI32.

I think that there may be something involved with that smile, anyway, i g2g, thank you so much for your help, I hope you might be able to think of something i couldn't when i show you the list of APIs it uses.
Posted By: TheXenocide Re: Menu DLL Help - 31/10/03 04:59 AM
Ok, first off, when i said GDI32 i meant User32 :tongue:.

Next: I did A LOT of trial and error and dif debugging and I determined that the error was NOT caused by mIRC or the SetMenu function. I tried for about an hour to figure out exactly what was going wrong but I had no luck, so I decided to completely rewrite it.

Good news is: It works wonderfully, When I rewrote it, I made it a lot less complicated (by removing a lot of the features :'(, but oh well, I can add them later) which in the end turned to be for the better.

Anyway, thank you so much Naru, you've been a great help and I will be sure to mention you in the credits/thanks section when I release something. I read in Grimz's docs,

Quote:
Naru - You're the elitest chick I've ever known ... where the hell did you go? =(


and if this is the same Naru, then it is definately true :tongue:. I hope that I might be able to help you some day, or that we might be able to work together some time (i always enjoy coding with someone who's good :tongue: it's so much better then constantly helping n00bs although, i guess someone has to do it :tongue:, someone did it for me smile ).
Posted By: Narusegawa_Naru Re: Menu DLL Help - 31/10/03 06:49 PM
lol ya often times a complete recode (i call them wipes) seems to magically fix alot of things. whenever i code anything my ultimate goal is speed so i find myself continuosly optimizing code (usually on the asm level). often times i introduce problems myself (i am my own worste enemy). Yes I am the same naru GrimZ was speaking of. I dont mind helping new coders i quite enjoy it but i agree it would be nice to collaborate on a project or two with someone who already has at least some basic knowledge.

Many of the function your using (menu api) are located in user32.dll wich is why you see the dependancy for it. You may want to look into the application exescope (i think its shareware). It offers a few options that depends doesnt and is pretty clean and easy to follow.
Posted By: TheXenocide Re: Menu DLL Help - 04/11/03 05:18 PM
I'll check that out. I knew that the menu functions were in user32, but using depends you can see exactly which user32 APIs he was using and then determine the need for them (some of which I still can't figure out why he used :tongue:).

At any rate, I too am always trying to optimize code, i do not, however, know enough ASM to actually code in it :tongue:, i guess it's too old school for me frown but oh well. Perhaps some day i'll get to learn it.

Perhaps you might help me with a new problem, i haven't done any debuggin yet (because i was up coding it till like 3:00am,) but i have run into the following problem: while docking toolbars into mIRCs "Application Frame" and Resizing the "MDICLIENT" window, everything appears to work just fine, all the windows dock, etc. but when I maximize the MDI's child window (the status window for example) it seems that the child window has the correct X, Y, and Width, but it's height causes it to go below mIRCs Frames boundaries... i have to check some of my wath just to double check it, but I don't think it's my math. Have any ideas?

btw, thanks so much for the help :tongue:
Posted By: Narusegawa_Naru Re: Menu DLL Help - 04/11/03 09:46 PM
well not to be contridictory but ya its probably your math lol.

remember that the MDI client window may or may not be at 0,0. the toolbar and switchbar are child controls of the frame window. essentially what you do is adjust the mdi pos wich seems like you have then adjust its height based on its height - the height of the new child control (the docked window). for example if the child window is 100 tall you move the MDI down 100 ans shorten its height by 100. the best solution i would recommend would be to use the DeferWindowPos api. you can position and size multiple windows at once (namely the child window and the MDI)

also note that other dll's (ktools is a prime example) also handles sizing the mdi and the 2 dll's wont play nice togethor. if its just for you then i sposse it doesnt matter much.

another method you could use would be to get the client rect of the frame window then subtract the sum of the height of each control (toolbar switchbar and the child window) then use that as your new cy value in SetWindowPos (or DeferWindowPos). also note that if you use these function do not use the HWND_TOPMOST parameter. depending on wich windows version your using setting this with an MDI client window cna cause some drawing issues (cant remember why but you can see it on MSDN)
Posted By: TheXenocide Re: Menu DLL Help - 05/11/03 05:33 AM
lol, thank you. I knew how to do all of the docking :tongue: but thanks for trying to help anyway. No... my math was quite correct... if i didn't forget a single + sign :tongue:, it's always something smile. i accidently had something like "iHeight = 'Something'" instead of "iHeight += ..." lol, but i've got all of that worked out, lol. just one last bug to work out (which i think i know whats up) and it'll be complete, a docking dll that allows 32 docked windows (not that anybody would need 32 :tongue:) a custom docked toolbar (that doesn't count as any of the 32), with some other new features, such as allowing you to have it dock the side windows first instead of the top windows, and allowing you to choose when the custom toolbar will be docked (before ALL windows [including the switchbar and toolbar], after toolbar/switchbar but before the other 32 possibly docked windows, or after ALL windows [including the 32 possibly docked ones]).

I suppose it's safe to let everyone know that this DLL is for a full script that Voice of Power, db2k, and myself are working on, called "Paragon" which will support all sorts of great new features. The dll that I am writing for it is to allow some of the features in our script to do things that haven't been done before, but theres also some stuff that has been done and I've added them for the following reasons:
1) Theres no sense in using a 40k dll for 2 functions.
2) Theres no sense in distributing 15 dlls with a script.
3) Theres no sense in loading 15 dlls which will have have their own memory overhead, and possibly cause conflicts with eachother and with overridden window procedures.
4) Things have been done, but not the way i wanted them :tongue:
5) Looking at the code of others, i've noticed that nobody seems to focus on efficiency anymore.

Next, some features in the dll:
1) Replacing mIRCs menu bar with a custom one which supports Owner Drawn popups.
2) Docking multiple windows on any side (top left bottom right) including the other toolbar features mentioned earlier :tongue:
3) Basic icon/titlebar functions
4) Basic icon counting function
5) Common Dialog Color and Font Select Dialogs (I May add open and save stuff too)
6) A function to detect when a dialog control has lost focus
7) And i'm sure there'll be more

Finally, It will be released for public use shortly after our script has been released. There is currently no release date.

I had a question for you naru: could you point me toward the APIs I should look into for placing an icon in the system tray? By all means i don't want the code written for me, but if you can tell me where/how to start poking around so that i might learn that would be much appreciated. Thanks for the ExeScope thing too, I think i'll stick to depends.exe for now, but i'll keep ExeScope around in case i need some of the other features it offers, i just like the way depends displays dependency and import/export information a little better. Wow, this was a long post wink
Posted By: Narusegawa_Naru Re: Menu DLL Help - 05/11/03 04:20 PM
yup fill a NOTIFYICONDATA data struct and use the Shell_NotifyIcon(NIM_ADD,&that_struct_var);
Posted By: TheXenocide Re: Menu DLL Help - 06/11/03 04:16 AM
thank you much :tongue:, if I were to use an owner drawn menu associated with a tray icon, what should I use as a device context for drawing the menu items? I haven't looked into the function yet (I'm on the wrong comp for that, as always :tongue:) but would i have to use TrackPopupMenu/Ex? I suppose that is something i'll find out when i look into it tho :tongue:... anyway, thanks so much for the help, saves me a lot of time peeking through the help file for dif macros/apis.
Posted By: TheXenocide Re: Menu DLL Help - 06/11/03 05:36 PM
that was signifigantly easier than I thought it would be :tongue:, thanks for the help.
Posted By: TheXenocide Re: Menu DLL Help - 08/11/03 02:43 AM
Ok, now i have another good question for you. How can i catch media key buttons from a multimedia keyboard? I tried using RegisterHotKey with the VK_MEDIA* constants, but it doesn't seem to work. I have a program that reads the keys and sends messages to windows media player (and other media players), but I can't figure out how to utilize them frown
Posted By: Narusegawa_Naru Re: Menu DLL Help - 11/11/03 06:46 AM
oops sorry didnt see the additonally post. try using the following.

* launches your browser to its default home page
keybd_event(VK_BROWSER_HOME,0,0,0);
keybd_event(VK_BROWSER_HOME,0,KEYEVENTF_KEYUP,0);

* launches media player (or whatever the default player is)
keybd_event(VK_LAUNCH_MEDIA_SELECT ,0,0,0);
keybd_eventVK_LAUNCH_MEDIA_SELECT ,0,KEYEVENTF_KEYUP,0);
© mIRC Discussion Forums