mIRC Home    About    Download    Register    News    Help

Print Thread
#51928 30/09/03 03:13 AM
Joined: Dec 2002
Posts: 1,527
_
_D3m0n_ Offline OP
Hoopy frood
OP Offline
Hoopy frood
_
Joined: Dec 2002
Posts: 1,527
im wondering if there is a way for a dll or com to know whether or not mirc opens and closes a window inside itself? including in the close would be if i clicked the x to close things like inactive dcc sessions and such. the reason im asking is i need to be able to pass a command thru to mirc if i can be able to detect these childwindows closing and opening, and standard scripting isnt seeming to be too efficiant for my script. i know a small amount about dlls and very litle about com. any help would be very much appreciated.


D3m0nnet.com
Joined: Feb 2003
Posts: 3,432
S
Hoopy frood
Offline
Hoopy frood
S
Joined: Feb 2003
Posts: 3,432
I have never seen a DLL like that, but it would be welcommed if somone made one like it tho smile


if ($me != tired) { return } | else { echo -a Get a pot of coffee now $+($me,.) }
Joined: Dec 2002
Posts: 1,527
_
_D3m0n_ Offline OP
Hoopy frood
OP Offline
Hoopy frood
_
Joined: Dec 2002
Posts: 1,527
well id like a point in the right direction on making one, ive been looking and i think i need to find some way of finding out WS_CHILDWINDOW and then i need to be able to mak sure its not a dialog window as well... if i get any luck in it ill let u know. i need it to be able to process my treeview switchbar listings. be cause ON close isnt working properly on dcc windows. it fires my command at the termination of the session and not actually when i close the window. i am workin on a start to a dll but im still only learning it slowly thru the tutorials.


D3m0nnet.com
Joined: Dec 2002
Posts: 2,809
C
Hoopy frood
Offline
Hoopy frood
C
Joined: Dec 2002
Posts: 2,809
A dll can do it, but it's a real pain to do. I've never personally gotten it fully working although if I really played around with it I probably could.

Joined: Jun 2003
Posts: 195
N
Vogon poet
Offline
Vogon poet
N
Joined: Jun 2003
Posts: 195
have you tried subclassing the MDI window and catching WM_PARENTNOTIFY. You will recieve a WM_CREATE or WM_DESTROY along with the window handle of the child window. This only works for @windows as dialogs do not open inside the MDI (they are owned by the desktop) If you need to know what type of window is openeing (ie channel custom send get etc..) you can use GetClassName. I believe the current format is mIRC_WindowType. for example mIRC_Custom but im not too sure you can simply look in spy to get the names.

Note i meant this only works for windows not just @windows

Last edited by Narusegawa_Naru; 30/09/03 07:44 PM.

Have Fun smile
Joined: Dec 2002
Posts: 2,809
C
Hoopy frood
Offline
Hoopy frood
C
Joined: Dec 2002
Posts: 2,809
If he needs to check both dialogs and windows a CBT hook dll would be the way to go.

Joined: Dec 2002
Posts: 1,527
_
_D3m0n_ Offline OP
Hoopy frood
OP Offline
Hoopy frood
_
Joined: Dec 2002
Posts: 1,527
ive been doing quite a bit of reading and ty for your suggestion ..... in the tutorial im readingh it says something about superclassing the main mdi window and then it could cal the WM_CREATE message. ill keep working on ti and hopefully ill have some news to share.


D3m0nnet.com
Joined: Jun 2003
Posts: 195
N
Vogon poet
Offline
Vogon poet
N
Joined: Jun 2003
Posts: 195
codemaster is right a hook would be better in this case. I didnt mention it because a hook can not only just crash mirc but can lead to total system stability issues.

No superclassing wont help in this situation. superclassing is the process of creating a new window class based off of an old one. For exmaple you would use the GetClassInfoEx function to get the class info of lets say a BUTTON. replace the window procedure and name (as well as any other options you like) then call RegisterClassEx to register the new class. Once done you can use CreateWindow("YOUR_NEW_CLASS_NAME_HERE",other,args,...);

this is ok for windows that dont exist yet but mirc will still create its windows based off of the class it registered and not yours. If you dont mind maybe a few system crashes or other problems then i would say give the hook a shot just remember to follow the guidlines in the MSDN about returning the values back to other HookProcs.

To codemastr
Since the dialog is owned by the desktop and all dialogs share the same class how would you go about determining if the dialog was indeed opened by mirc and not say the video properties dialog? The only thing i can think of atm would be sending a signal with the dialog title to mirc since your script knows the dialogs title.

I suppose you could examine the process that created the dialog as well and compare it against mirc's process. I think this would be a bit more difficult considering you can have several instances of mirc running.

Last edited by Narusegawa_Naru; 01/10/03 12:00 AM.

Have Fun smile
Joined: Dec 2002
Posts: 1,527
_
_D3m0n_ Offline OP
Hoopy frood
OP Offline
Hoopy frood
_
Joined: Dec 2002
Posts: 1,527
actually no just the windows in the mdi under the spy is all i need to be able to access info for. and basically all i need to know is if it sends the create and close of the windows in the mdi.


D3m0nnet.com
Joined: Jun 2003
Posts: 195
N
Vogon poet
Offline
Vogon poet
N
Joined: Jun 2003
Posts: 195
in that case then i would suggest subclassing the MDI. Subclassing can lead to problems casueing mirc to crash but at least windows still lives. Sublassing is also a bit easier to do. You would simply create a dll function such as Mark or Init wich calls SetWindowLong with the GWL_WNDPROC constant. (note SetWindowLongPtr might be better if you think your dll will ever live on a 64bit version but i dont think that will happen soon).

Your window procedure may look a bit like this

LRESULT CALLBACK MyMDIProc(HWND hwnd,UINT msg,WPARAM wp,LPARAM lp)
{
switch(msg)
{
case WM_PARENTNOTIFY:
switch(LOWORD(wp)
{
case WM_CREATE:
//you can typecast lp to an HWND here (HWND)lp and get things such as the window text etc..
break;
case WM_DESTROY:
//same thing here.
break;
}
break;
}
return CallWindowProc(oldproc,hwnd,msg,wp,lp);
}

SetWindowLong will return the old window procedure. since theres only one MDI window and mirc is not threaded its ok to use a global WNDPROC (typecase the return result to a WNDPROC)

One thing to note a WndProc is a function called by windows not you (at least not firectly). Once you replace the wndproc windows will continue calling that procedure. If for example the use unloads the dll using /dll -u name then your proc is no longer valid however windows will still try to call it. This will crash mirc. You need to replace the old procedure when the dll unloads. Also if the window is closed (ie mirc is closed) your proc will receive the messages you cannot send that message back to mirc its no longer valid so you should replace the old procedure and then destroy the window yourself.

I know it sounds difficult but its not really. There are several good exmaples out there in fact you would be amazed at the number of mirc dll's that subclass some window.

Another hint to avoid problems finding the HWND of the MDI window i wouldnt use the ID value in spy with GetDlgItem. mIRC has been known to change her id's from build to build instead use the EnumChildWindows function and the GetClassName function. will will always be MDICLIENT


Have Fun smile
Joined: Dec 2002
Posts: 2,809
C
Hoopy frood
Offline
Hoopy frood
C
Joined: Dec 2002
Posts: 2,809
Subclassing can cause problems, but only if you don't do some trickery. The trickery is known as double loading. Basically, when your dll is unloaded mIRC is pretty much screwed, it will just crash. To prevent this, you do what is called double loading. Basically, in your DllMain entrypoint function you call LoadLibrary on your dll. This will increase the reference count. This means when mIRC calls FreeLibrary when it's done with your dll, it doesn't actually unload it, it just decreases the reference count from 2 to 1.

The replacing the old procedure is really a bad way to do it. Because consider this:

mIRC has MDIWnd uses func1
dll1 subclasses MDIWnd uses func2
dll2 subclasses MDIWnd uses func3

Now dll1 is unloaded, it sets the window function back to the func1. Now that means dll2 has been disabled since it will no longer receive messages. Now if dll2 is unloaded, it will change the function back to func2, which no longer exists since dll1 is unloaded therefore you get a crash. The solution is double loading and a state variable. In your DllMain exit-point handler you have, I think it's called PROCESS_DETACH or something like that. If you receive that, you set active = FALSE; or something like that. Then when you receive a PROCESS_ATTACH you just active = TRUE again, that way /dll -u still disables your dll but all the subclassing nonsense is avoided.

Another alternative (XP/2003 only) would be to use the new subclassing API which handles all that fun stuff for you. If I recall the function is called SubclassWindow which you can read more about in MSDN. Of course though that's only suitable if you're just making a modification for yourself since it only works on XP/2003.

Joined: Jun 2003
Posts: 195
N
Vogon poet
Offline
Vogon poet
N
Joined: Jun 2003
Posts: 195
double loading can solve the problem with crashing on unload however your dll still remains in memory unless you export a Remove or similar function and then handle that yourself.

If im not Mistaken isnt SubclassWindow a method of CWnd in MFC? Of course theres nothing saying you cant use MFC in your dll but most people tend to shy away from it i think its all personal taste.


Have Fun smile
Joined: Dec 2002
Posts: 2,809
C
Hoopy frood
Offline
Hoopy frood
C
Joined: Dec 2002
Posts: 2,809
Well yes it is, but God No! I'd die before I encourage someone to use MFC! Now that I'm at a PC that I actually have a copy of the MSDN on I can look up the function I was thinking of. The function is SetWindowSubclass.

Joined: Jun 2003
Posts: 195
N
Vogon poet
Offline
Vogon poet
N
Joined: Jun 2003
Posts: 195
lol well im sorta at odds with the MFC issue. MFC is just microsofts implementation of a good concept (namely OOP). I definately wouldnt recomend MFC to a new user but the only other alternative would be implement it yourself (or use someone elses who has). I have my own Window object that i use specificaly for this and other tasks but i think just for the scope of this dll subclassing the win32 way is probably the best.

I forgot to ask is this dll just for your own use or do you plan on releasing it? If its just for personal consumption then it really doesnt matter how you perform the job as long as it works. Otherwise you have to consider the others you may use your dll.


Have Fun smile
Joined: Dec 2002
Posts: 2,809
C
Hoopy frood
Offline
Hoopy frood
C
Joined: Dec 2002
Posts: 2,809
If you're interested in OOP in GUI try WTL (it's a beta library from MS). From what I hear, it's very stable, no MFC dlls to distribute, and it works similarly to the STL so the interface is familiar. I haven't heard anything bad about it.

Joined: Dec 2002
Posts: 1,527
_
_D3m0n_ Offline OP
Hoopy frood
OP Offline
Hoopy frood
_
Joined: Dec 2002
Posts: 1,527
its just for my own use ... im having issue making it work as i still dont know enough yet about dlls and c++ ive spent the last couple days reading up on everything u and codemastr are telling me. i tried your method and am now trying to figure out how to actually send the command alias i want it to pass in my mirc ..... basically ive made an alias that refresshes my list of open windows in the MDI in a treeview list. my problem with doing it in mirc scripting is it doesnt always send the alias on close of dcc windows. it sends it after the dcc has finished..... thats why i need to do it another way. im still new to this dll stuff but im hoping to learn enough to be able to make the dll function just to do this one thing. i dont ever plan on releasing it because the script is my own personal script. anything i share with anyone else never contains the treeview listing of windows. ive tried looking into codemastrs idea of it being able to be done differently in xp since thats what i do use.again im still at a very basic stage in this learning it. its probably more than im gonna be able to do immediatly but im going to keep taking stabs at it. i do have visual studio 2002 thats how im working with the cpp file and then how i plan to compile it. once i figure out a correct method. all of your help is greatly appreciated. I think in the past week ive read more tutorials than i can remember.


D3m0nnet.com
Joined: Jun 2003
Posts: 195
N
Vogon poet
Offline
Vogon poet
N
Joined: Jun 2003
Posts: 195
lol actually i dont think its too much to do. at least your learning something ne? anyhow to call the alias in mirc (/alias blah blah blah) your going to want to look into the filemapping/sendmessage support for mirc. Essentially you create a file in memory (not one on the disk) using CreateFileMapping The name MUST be mIRC. Then you call MapViewOfFile this will return a LPSTR that you can use to fill whatever you want mirc to do. for example to perform a command you would do something similar to

wsprintf(TheStrVar,"/echo -a hello");

then tell mirc to perform it

SendMessage(mWnd,WM_MCOMMAND,0,0);

I cant really remember what WM_MCOMMAND is defined as i think WM_USER+200 or something /help SendMessage will tell you tho. Dont forget to UnMapViewOfFile etc.. when you no longer need it. Best to handle creating/releasing in the LoadDll/UnloadDll functions If i get a few seconds i can try to whip up a small working sample and email you if you like.


Have Fun smile
Joined: Dec 2002
Posts: 1,527
_
_D3m0n_ Offline OP
Hoopy frood
OP Offline
Hoopy frood
_
Joined: Dec 2002
Posts: 1,527
that would be great if u could do that to give me some pointers, and yes i certainly am learning a ton of new things just by tryin to accomplish this. now for example when i have an alias i create in mirc then im going to have to send message something like
wsprintf(TheStrVar,"/servlistr"); //servlistr is the name of my alias in mirc

then from there i need to

SendMessage(mHwnd, WM_MCOMMAND, cMethod, 0L)

:: according to the helpfile from mirc. the one part im having slight trouble is in the filemapping part which ill read more on tomorro cause ive gotta sleep for work in the am. again ty very much for all your help.


D3m0nnet.com
Joined: Jun 2003
Posts: 195
N
Vogon poet
Offline
Vogon poet
N
Joined: Jun 2003
Posts: 195
not at all i love to help people. ya the sendmessage would actually be
SendMessage(mWnd,WM_MCOMMAND,0,0);

sure ill write one up and comment it heavy. mind you you may need to alter some things to fit your dll but im certain youll understand the important parts. just email me ay

Yamano_miyu@hotmail.com ill respond with it smile


Have Fun smile

Link Copied to Clipboard