External Windows

BlitzPlus Forums/BlitzPlus Programming/External Windows

MattVonFat(Posted 2004) [#1]
Hi, ive seen a post on this before i think but i couldn't find it so maybe i didnt...anyway...is there anyway to control external windows, like if i have another app open say (as its the first that came to mind) Notepad. Is there anyway to close it using blitz or even write into it?

Thanks if you can help


soja(Posted 2004) [#2]
Yes, but you have to use WinAPI (not so hard). There are a number of functions that will let you do a number of things. What do you need specifically?


MattVonFat(Posted 2004) [#3]
Well i was just inquiring at the mo for the future, but thanks for the info!

Matt


MattVonFat(Posted 2004) [#4]
Um this may sound stupid what is WinAPI?


soja(Posted 2004) [#5]
Windows Application Programming Interface. Essentially a bunch of DLLs from Microsoft in windows\system(32) that provide functions for programming with Windows. See documentation on msdn.microsoft.com.


MattVonFat(Posted 2004) [#6]
ok thanks


MattVonFat(Posted 2004) [#7]
Ok i found one to get the window handle "FindWindowEx" but i dont know how i would get it to work in my program.

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/WinUI/WindowsUserInterface/Windowing/Windows/WindowReference/WindowFunctions/FindWindowEx.asp


soja(Posted 2004) [#8]
First you need to write a declaration (.decls) for it. See "Specs and Utils -> Userlibs Specifications".

At the bottom of the MSDN page, look at the Import Library (user32.lib) -- so this function is found in user32.dll.

1) Type in a plain text file:
.lib "user32.dll"


Now look at the function declaration, at the top. Let's break it apart, bit by bit. The first part of it (HWND) specifies that it returns a handle to a window (which to Blitz, is just an Int) so put in the name of the function for Blitz, and an Int return value:
FindWindowEx%(...

And then it takes 4 parameters. The two HWNDs are Ints to Blitz, and the two LPCTSTRs are pointers to character arrays in C, which would be Strings to Blitz. So we specify those parameters like so:
FindWindowEx%(hwndParent%, hwndChildAfter%, lpszClass$, lpszWindow$)...

The parameter names can really be anything you want, but I just made them the same as what's on MSDN. Also, notice the descriptions for the arguments on MSDN. They're all marked as IN which means the arguments are only used as you pass them in. Sometimes they might be marked OUT or IN\OUT, which means they could be used to return values to you, and you would probably have to pass a custom type instance or a bank (basically, a memory block). Also, if you want to pass NULL, the parameter must be declared as % and you must pass 0.

Finally, just write the name of the function exported from the DLL, like so:
FindWindowEx%(hwndParent%, hwndChildAfter%, lpszClass$, lpszWindow$):"FindWindowEx"

and then save that file with a .decls extension and put it in the userlibs folder.

You might also want to take note of the supprted versions of Windows for the function.

Now to use it in a program, you can just type:
hwnd% = FindWindowEx(0, 0, "CLASSNAME", "TITLE")


This will search all the windows (and child windows) on the desktop for one that matches the CLASSNAME window class, and TITLE in the title bar. Note that you could also change the 4th parameter from $ to %, and pass 0 instead to match anything.

In order to get the window classname, try downloading Greatis' WinDowse. It will tell you a ton of stuff about the windows on your desktop.

Well, that's the basics of it. Make sure you do error handling and such. Try it out, you'll probably have questions. Hope it makes sense for you though. =)


MattVonFat(Posted 2004) [#9]
Thanks, it makes perfect sense! I'll try it out now.


MattVonFat(Posted 2004) [#10]
I just had a go but it says user lib function not found.

Have i done something wrong?


VIP3R(Posted 2004) [#11]
-


MattVonFat(Posted 2004) [#12]
I still get "user lib function not found". I put it in the user32.decls which also has other functions and they work fine. I tried a different one that i found and also put it in user32.decls but that doesn't work either. When i tried the beep function, that seemed to work ok.


soja(Posted 2004) [#13]
Oh, I see. The actual exported function name is FindWindowExA. Tack that A onto the end there and see how that works.

I found this out by looking at the actual exported functions of the DLL with dumpbin. (You can also do it with PEView.)


MattVonFat(Posted 2004) [#14]
Thanks for all your help, its now working!

Thanks again to everyone!


soja(Posted 2004) [#15]
Not a problem. Would you mind posting your declarations and bb function call? Does it still say "user lib function not found"?

If so, make sure that these two lines:
.lib "user32.dll"
FindWindowEx%(hwndParent%, hwndChildAfter%, lpszClass$, lpszWindow$):"FindWindowExA"

...are in a .decls file which is found in the userlibs folder. Remember, it doesn't matter what you call the .decls file as long as it is plain text, there is only one '.lib "user32.dll"' line, and it's in the userlibs folder.

Then, just put this line:
hwnd% = FindWindowEx(0, 0, "CLASSNAME", "TITLE")
Notify hwnd
into a program and run it. It should return 0, but you can try it with an actual classname and title (found from WinDowse) and it should work.

If you don't see where your problem is, we'll help you figure it out.


MattVonFat(Posted 2004) [#16]
lol, I spoke too soon. The handle i get from Blitz is different to the one i get on WinDowse. WinDowse has letters in the handle for media player, while when i change the variable type for the blitz one, i get a strange symbol. Also when i use DestroyWindow (API) with the handle i get from blitz, nothing happens to Media Player.


Eikon(Posted 2004) [#17]
Stay away from DestroyWindow, use PostMessage with the WM_CLOSE (16) flag to kill it.


soja(Posted 2004) [#18]
do you mean the class? or the actual windows handle?


MattVonFat(Posted 2004) [#19]
a% = FindWindowExA(0, 0, "WMPlayerApp", "Windows Media Player")


When i print a it has a number in it but when i looked at the handle in WinDowse it showed a number with a B in it.


soja(Posted 2004) [#20]
B is a number is hexadecimal (base 16, 0-9,A-F... F=15 in decimal)

I've been comparing the two -- I'm not sure what handle WinDowse is displaying. I'm not sure I would trust it (since I can't figure it out). Try this:
w=CreateWindow("hi",100,100,100,100,0,3)
Print GetForegroundWindow()
Print FindWindowEx(0, 0, "BLITZMAX_WINDOW_CLASS", "hi")
Print QueryObject(w,1)
WaitKey()

See how they all display the same number? I don't know what WinDowse is displaying... I've never used it to get a window handle. (Also not that window handles will probably change each time you create/destroy the window.)

GetForegroundWindow is defined under .lib "user32.dll" as:
GetForegroundWindow%():"GetForegroundWindow"


MattVonFat(Posted 2004) [#21]
Thanks, it seems to be working ok now. Not only that i've also learnt about making decls for the WinAPI, so this has been a good learning experience.

Thanks again