:Start of EnumChildWindows
![]() | ![]() |
|---|
If you are viewing this script in your browser you can save it as a VDS 5.x source file (*.dsc) to run it.
# # DragonSphere Software's Home Page # # All Source Files for this demo ############################################################################### # # # This demo shows how to use GadgetX'es CallBack functions by using the # # EnumChildWindows API function # # # ############################################################################### Option Decimalsep,. Title Window Info If @Greater(@Name(@Sysinfo(DSVER)),4) External gadgetx.dll,@Sysinfo(DSVER) #DEFINE COMMAND,GADGETX,DEFINE,SET,CALL,FREEDLL,PRINTDIALOG,StopCB,SetCallback #DEFINE FUNCTION,GADGETX,LOADDLL,GET,ADDROF,SPACE,CALL,GetCallback Else Warn This demo requires VDS 5.x Stop End Define Variable,Handle,user32 Set user32,@LoadDLL(user32.dll) # Define Command # Syntax: Define Command,, , , ,
Define Command,EnumWindows_Done,user32,EnumWindows,EnumWindows,Pointer|lpEnumFunc,DWORD|lParam Define Command,EnumChildWindows_Done,user32,EnumChildWindows,EnumChildWindows,Handle|hWndParent,Pointer|lpEnumChildFunc,DWORD|lParam Define Function,Handle,user32,GetParent,GetParent,Handle|hWndParent Define Variable,String,MyEvent Define Variable,Handle,ParentHwnd Define Variable,Pointer,EnumWinProc Define Variable,Pointer,EnumChildWinProc Define Variable,QWORD,LstCount Define Variable,BYTE,cnt Define Variable,String,CBParams Define Variable,String,CBParamsChild Define Variable,String,Item Define Variable,String,Title Define Variable,String,Class Define Variable,String,Text Rem Describe to Gadget what Parameters are supposed to be passed to our fuction rem by the external DLL and give Gadget a user defined VDS event name that will rem be trigered each time the external function calls our Callback function Define CallBack,0,Integer,EnumWindowsProc,Handle,Integer Define CallBack,1,Integer,EnumChildWins,Handle,Integer Rem Get the memory address of 1 of the 5 callback functions inside of Gadget. rem they are numbered similar to VDS List but the Callback ID's start at 0,1,2,3,4 rem Gadget EnumWinProc,@Gadget(AddrOf,CallBack,0) Set EnumChildWinProc,@AddrOf(CallBack,1) Rem Initialize all String variables... Set MyEvent,@Space(256) Set CBParams,@Space(256) Set CBParamsChild,@Space(256) Set Item,@Space(256) Set Title,@Space(256) Set Class,@Space(256) Set Text,@Space(256) :Main DIALOG CREATE,Test Callback,-1,0,599,266 REM *** Modified by Dialog Designer on 12/4/2003 - 09:20 *** DIALOG ADD,TEXT,TEXT1,12,48,,,Click the button to get a list of all child Windows. If @Greater(@Name(@Sysinfo(DSVER)),4) DIALOG ADD,TABLE,TABLE1,36,24,556,156,Handle|Class|Title/Parent Else DIALOG ADD,LIST,TABLE1,36,24,556,156 End DIALOG ADD,BUTTON,BUTTON1,208,108,64,24,Get List DIALOG ADD,BUTTON,BUTTON2,208,400,64,24,Close DIALOG ADD,BUTTON,WinInfo,208,256,64,24,&Info DIALOG ADD,STATUS,STATUS1,Click Get List... DIALOG SHOW rem %%Stat_hwnd = @winexists(~STATUS1) Rem Make a temp list to hold the CallBack parameters. List create,1 List create,2 :evloop Rem Ok be warned if you use a Timer event then expect this rem to be very slow. rem If you need to use a Timer then use FireEvent Timer wait event Set MyEvent,@Event() if @Get(MyEvent) goto @Get(MyEvent) End goto evloop :TIMER If @Equal(%%CheckChildEnumWindows,1) DIALOG CURSOR,WAIT End goto evloop :BUTTON1BUTTON Gosub QUITCOMMANDS %%CheckChildEnumWindows = 1 Rem Make sure the List box is cleared. List Clear,TABLE1 List Clear,2 Set LstCount,0 Rem Kick off the EnumWindows function. Passing it the memory address of our Callback function. Rem Note: If you want the function to run Asyncronously then you must call it as a VDS command. rem This is because Gadget calls the function from a seperate thread when called as a VDS rem command. rem I did this so that Gadget's callback functions will work like other languages. rem Gadget EnumWindows,EnumWinProc,0 REM @winexists(Project: mpgadget) Call EnumChildWindows,#TfMain,EnumChildWinProc,0 goto evloop :EnumWindows_Done %%CheckEnumWindows = 0 DIALOG CURSOR DIALOG SET,TEXT1,Wow that took a bit of work but I am finished now. Dialog Set,STATUS1,There are @Get(LstCount) windows open on your PC dang your busy call ya later... goto evloop :EnumChildWindows_Done DIALOG CURSOR %%CheckChildEnumWindows = 0 Dialog Set,STATUS1,There are @Get(LstCount) child windows for Test Callback... goto evloop :WinInfoBUTTON Set Item,@Item(TABLE1) If @Null(@Get(Item)) Set Item,@Item(TABLE1,0) End %%OldFsep = @fsep() Option FieldSep,@Tab() Parse "%%Hwnd;%%Class;%%Titletxt",@Get(Item) if @Greater(@Pos(->,%%Hwnd),0) Rem This is a child window %%Hwnd = @SubStr(%%Hwnd,3,@len(%%Hwnd)) %%Status = @WinPos(%%Hwnd,S) If @Equal(%%Status,1) %%Status = Normal ElsIf @Equal(%%Status,2) %%Status = Iconized ElsIf @Equal(%%Status,3) %%Status = Maximized End If @Equal(%%Class,##32770) If @Equal(#@WinClass(@Call(GetParent,%%Hwnd)),##32770) Rem Use Title text for both child and parent Info Handle: %%Hwnd@CR()Title: %%Titletxt@CR()Parent Title: @WinText(@Call(GetParent,%%Hwnd))@CR()Status: %%Status@CR()Top: @WinPos(%%Hwnd,T)@CR()Left: @WinPos(%%Hwnd,L)@CR()Width: @WinPos(%%Hwnd,W)@CR()Height: @WinPos(%%Hwnd,H) Else Rem Else just use the child's title text Info Handle: %%Hwnd@CR()Title: %%Titletxt@CR()Parent: #@WinClass(@Call(GetParent,%%Hwnd))@CR()Status: %%Status@CR()Top: @WinPos(%%Hwnd,T)@CR()Left: @WinPos(%%Hwnd,L)@CR()Width: @WinPos(%%Hwnd,W)@CR()Height: @WinPos(%%Hwnd,H) End Else If @Equal(#@WinClass(@Call(GetParent,%%Hwnd)),##32770) Rem Use Title text for parent Info Handle: %%Hwnd@CR()Class: %%Class@CR()Parent Title: @WinText(@Call(GetParent,%%Hwnd))@CR()Status: %%Status@CR()Top: @WinPos(%%Hwnd,T)@CR()Left: @WinPos(%%Hwnd,L)@CR()Width: @WinPos(%%Hwnd,W)@CR()Height: @WinPos(%%Hwnd,H) Else Rem Else use the child and Parent class Info Handle: %%Hwnd@CR()Class: %%Class@CR()Parent: #@WinClass(@Call(GetParent,%%Hwnd))@CR()Status: %%Status@CR()Top: @WinPos(%%Hwnd,T)@CR()Left: @WinPos(%%Hwnd,L)@CR()Width: @WinPos(%%Hwnd,W)@CR()Height: @WinPos(%%Hwnd,H) End End Else Rem This is a Top level window %%Status = @WinPos(%%Hwnd,S) If @Equal(%%Status,1) %%Status = Normal ElsIf @Equal(%%Status,2) %%Status = Iconized ElsIf @Equal(%%Status,3) %%Status = Maximized End If @Equal(%%Class,##32770) Info Handle: %%Hwnd@CR()Title: %%Titletxt@CR()Status: %%Status@CR()Top: @WinPos(%%Hwnd,T)@CR()Left: @WinPos(%%Hwnd,L)@CR()Width: @WinPos(%%Hwnd,W)@CR()Height: @WinPos(%%Hwnd,H) Else Info Handle: %%Hwnd@CR()Class: %%Class@CR()Status: %%Status@CR()Top: @WinPos(%%Hwnd,T)@CR()Left: @WinPos(%%Hwnd,L)@CR()Width: @WinPos(%%Hwnd,W)@CR()Height: @WinPos(%%Hwnd,H) End End End Option FieldSep,%%OldFsep goto evloop :EnumWindowsProc Rem This sub-routine is the event that Gadget trigered due to the EnumWindows API rem function calling one of Gadget's callback routines. Rem Ok here is the strange part of this. Because Gadget can only emulate rem Callback functions due to the fact that rem 1) You cannot build functions with VDS source code. rem 2) You cannot get the memory address of a VDS sub-routine. rem We have to emulate them with some generic functions that I put in Gadget. rem In this case EnumWindows requires a return value of '1' to enumerate all the window rem handles on the PC. Rem @Gadget(GetCallback, ) returns all parameters passed to the callback as a VDS List rem Gadget will sit and wait until you collect the value with the GetCallback function. rem If you never collect the value then when you exit the VDS script it will generate and ERROR. rem This is due to the thread that is left open because the callback is waiting for the signal rem to set the return value and finish processing. Set CBParams,@Get(GetCallback,0) rem If @Null(@Gadget(CBParams)) Rem Just a redundant check to make sure Gadget is returning information rem Define CallBack,Return,0,0 rem Info This should not have been called @CR()@Item(2,@pred(@count(2))) If @Get(CBParams) rem Info @Gadget(CBParams)@CR() Rem Clear List 1 List clear,1 Rem Assign the Parameters that was passed to Gadget's CallBack function rem to list 1. List Assign,1,@Get(CBParams) REM Info @Text(1)@CR() REM Gadget CBParams,NULL Rem Place in a loop to get each parameter in turn Set cnt,0 Repeat Set Item,@Item(1,@Get(cnt)) if @Greater(@Pos(@chr(37),@Get(Item)),0) Rem Make sure the Item that we are getting is the Window Handle and not rem our second parameter which in this case we don't care about. rem Normally the second parameter you would be able to set so you can tell rem your CallBack function when to stop but because we are remotely controlling rem our CallBack function we don't need this. Rem Get the Window's Title bar text rem Gadget Title,@WinText(@Gadget(Item)) Set Title,@WinText(@Get(Item)) Set Class,#@WinClass(@Get(Item)) Set ParentHwnd,@Get(Item) if @Greater(@len(@Get(Title)),0) Rem If the Window has a title bar or some kind of text then display the text Set Text,@Get(Item)@Tab()@Get(Class)@Tab()@Get(Title) Else Rem If the window does not have any text then just display "No Title" Set Text,@Get(Item)@Tab()@Get(Class)@Tab()No Title End End Until @Greater(@Get(cnt,++),@count(1)) Rem Add the Window info to our list box. if @Greater(@Match(2,@Get(Text)),-1) Else List ADD,2,@Get(Text) List ADD,TABLE1,@Get(Text) Dialog Set,STATUS1,There are @Get(LstCount,++) windows open on your PC... End List Seek,2,0 Call EnumChildWindows,ParentHwnd,EnumChildWinProc,0 %%CheckEnumChildWindows = 1 rem SetCallBack Return,0,1 End Goto Evloop :EnumChildWins rem %E = @event() Rem This sub-routine is the event that Gadget trigered due to the EnumChildWindows API rem function calling one of Gadget's callback routines. Rem Ok here is the strange part of this. Because Gadget can only emulate rem Callback functions due to the fact that rem 1) You cannot build functions with VDS source code. rem 2) You cannot get the memory address of a VDS sub-routine. rem We have to emulate them with some generic functions that I put in Gadget. rem In this case EnumChildWindows requires a return value of '1' to enumerate all the rem child window handles on the current window. Rem @Gadget(GetCallback, ) returns all parameters passed to the callback as a VDS List rem Gadget will sit and wait until you collect the value with the GetCallback function. rem If you never collect the value then when you exit the VDS script it will generate and ERROR. rem This is due to the thread that is left open because the callback is waiting for the signal rem to set the return value and finish processing. Set CBParamsChild,@GetCallback(1) If @Null(@Get(CBParamsChild)) Rem Just a redundant check to make sure Gadget is returning information rem if there was no return then just return 0 to the child callback rem Define CallBack,Return,1,0 rem This is here to clear the parent EnumWindows callback rem Define CallBack,Return,0,1 rem Info This could have been called @CR()@Item(2,@pred(@count(2))) Else Rem Clear List 1 List clear,1 Rem Assign the Parameters that was passed to Gadget's CallBack function rem to list 1. List Assign,1,@Get(CBParamsChild) REM Gadget CBParams,NULL Rem Place in a loop to get each parameter in turn Set cnt,0 Repeat Set Item,@Item(1,@Get(cnt)) if @Greater(@Pos(@chr(37),@Get(Item)),0) Rem Make sure the parameter that we are getting is the Child Window Handle and not rem our second parameter which in this case we don't care about. rem Normally the second parameter you would be able to set so you can tell rem your CallBack function when to stop but because we are remotely controlling rem our CallBack function we don't need this. Rem Get the Window's Title bar text rem Gadget Title,@WinText(@Gadget(Item)) Set Title,@Call(GetParent,@Get(Item)) Set Class,#@WinClass(@Get(Item)) if @Get(Title) Rem If the Window has a title bar or some kind of text then display the text Set Text,"->"@Get(Item)@Tab()@Get(Class)@Tab()@Get(Title) Else Rem If the window does not have any text then just display "No Title" Set Text,"->"@Get(Item)@Tab()@Get(Class)@Tab()No Title End End Until @Greater(@Get(cnt,++),@count(1)) Rem Add the Window info to our list box. if @Greater(@Match(2,@Get(Text)),-1) else List ADD,TABLE1,@Get(Text) List ADD,2,@Get(Text) Dialog Set,STATUS1,There are @Get(LstCount,++) windows open on your PC... rem Info @Text(2) end List Seek,2,0 Rem Set the CallBack return value. End rem Info Wait here for a sec. SetCallBack Return,1,1 Goto Evloop :QUITCOMMANDS if @Equal(%%CheckEnumChildWindows,1) %E = SetCallBack Return,1,0 repeat wait 0.1 %E = @Event() IF @Equal(%E,EnumChildWindows_Done) Info EnumChildwindows is done End Until @Equal(%E,EnumChildWindows_Done) End REM Info Stoping everything Rem Added this to clear the memory addresses and close the callback handles. StopCB Rem After you stop all CallBacks you have to re-establish their memory addresses rem and callback handles. rem Gadget EnumWinProc,@Gadget(AddrOf,CallBack,0) Set EnumChildWinProc,@AddrOf(CallBack,1) Exit :parentwin if @Equal(%%CheckEnumWindows,1) SetCallBack Return,0,0 repeat wait 0.1 %E = @Event() IF @Equal(%E,EnumWindows_Done) Info Enumwindows is done End Until @Equal(%E,EnumWindows_Done) End Exit :BUTTON2BUTTON :CLOSE DIALOG CURSOR Rem Just incase the Callbacks are hung release them... Gosub QUITCOMMANDS Rem Clear your list... List clear,TABLE1 List clear,1 List close,1 List clear,2 List close,2 Rem Free user32.dll FreeDLL user32 Stop
© Copyright DragonSphere Software 2000-2005
Terms and Conditions