[Solved] SendMessage (Win32) for BMX-NG?

BlitzMax Forums/Brucey's Modules/[Solved] SendMessage (Win32) for BMX-NG?

RustyKristi(Posted 2016) [#1]
Hi, is there a way to make this work with NG?

Extern "win32"
	Function ExtractIconA%(hWnd%,File$z,Index%)
	Function GetActiveWindow%()
	Function SendMessage:Int(hWnd:Int,MSG:Int,wParam:Int,lParam:Int) = "SendMessageA@16"
End Extern


I have used Pub.win32 for import to get rid of those conflict issues but now I'm getting "stray@" errors..

Thanks


col(Posted 2016) [#2]
If you are compiling for x64 then hWnd, wParam and lParam would be a Byte Ptr ( 8 bytes each ). This would then make the external definition "SendMessageA@28".

edit - Just for the record GetActiveWindow and SendMessageA are also defined in Pub.Win32 which may be the cause of the conflict too.


RustyKristi(Posted 2016) [#3]
Thanks col. How about if x86 only?


RustyKristi(Posted 2016) [#4]
What I'm really trying to accomplish is to get a window icon and I just found Yahfree's guide here. Any idea how this works for NG?

http://www.blitzbasic.com/Community/posts.php?topic=72899


col(Posted 2016) [#5]
How about if x86 only?

In x86 the Byte Ptr would be 4 bytes giving you the @16 again, so depending on your build architecture the size will automatically change as is needed.

Any idea how this works for NG

As it turns out the ExtractIconA is also defined too ( in pub.mod/win32.mod/shell32.bmx ) so that whole Extern...EndExtern block can be removed.
The ExtractIcon function returns an OS handle, which in NG land would be a Byte Ptr...
Without testing I imagine something along the lines of this should be in the right direction
Function SetIcon(iconname$, TheWindow:Byte Ptr)	
	Local icon:Byte Ptr = ExtractIconA(TheWindow,iconname,0)
	Local WM_SETICON:UInt = $80
	Local ICON_SMALL:UInt = 0
	Local ICON_BIG:UInt = 1
	sendmessagea(TheWindow, WM_SETICON, Byte Ptr(ICON_BIG), icon)
End Function



col(Posted 2016) [#6]
If you really want to use SendMessage as opposed to SendMessageA then you can use

Global SendMessage:Byte Ptr(hWnd:Byte Ptr,iMsg:UInt,wParam:Byte Ptr,lParam:Byte Ptr) = SendMessageA

Function.....
[...]
SendMessage( TheWindow, WM_SETICON, Byte Ptr(ICON_BIG), icon )
EndFunction



col(Posted 2016) [#7]
Oh just in case you're be confused by the name of Win32 and 32 on the end of the file names etc... Win32 is the name of the C Api for Windows and has nothing to do with 32bit or 64bit processors, it may have done years ago when 16bit was about but its all the same name now and deals with all intel architectures in one go.


RustyKristi(Posted 2016) [#8]
Thanks. Ah yes, already knew that win32 thing way back ;-).

I followed it with the ExtractIcon function, is this correct?
Extern "win32"
	Global SendMessage:Byte Ptr(hWnd:Byte Ptr,iMsg:UInt,wParam:Byte Ptr,lParam:Byte Ptr) = "SendMessageA"
	Global ExtractIcon:Byte Ptr(hWnd:Byte Ptr,File$z,Index:Byte Ptr) = "ExtractIconA"
	
End Extern



I'm now getting this error(s):

 'SendMessageA' redeclared as different kind of symbol



col(Posted 2016) [#9]
You're almost there, remove the extern block as you're not defining anything thats external ( youre just creating a function pointer that will point to an existing already defined function, even though that function is external it doesn't matter here, as the 'Max compiler knows about it now and has a definition for it ) , and also remove the quotes around the original function name so that the function pointer points directly to the existing function, then use the "Win32" convention on the end of the new function pointer for __stdcall convention...

Global SendMessage:Byte Ptr(hWnd:Byte Ptr,iMsg:UInt,wParam:Byte Ptr,lParam:Byte Ptr)"Win32" = SendMessageA
Global ExtractIcon:Byte Ptr(hWnd:Byte Ptr,File$z,Index:Uint)"Win32" = ExtractIconA


That should be about it :p

Oh yeah, you have the last parameter of the ExtractIcon as a Byte Ptr, it should be an UInt ;-)


RustyKristi(Posted 2016) [#10]
Thanks, almost there..

Global SendMessage:Byte Ptr(hWnd:Byte Ptr,iMsg:UInt,wParam:Byte Ptr,lParam:Byte Ptr)"Win32" = SendMessageA
Global ExtractIcon:Byte Ptr(hWnd:Byte Ptr,File$z,Index:Uint)"Win32" = ExtractIconA
Global GetActiveWindow:Byte Ptr()"Win32" = GetActiveWindow


It now builds ok but I'm getting some invalid exception pointing to GetActiveWindow in debug mode

SetIcon is this:

Function SetIcon(iconname$z, TheWindow:Byte Ptr)	
	Local icon:Byte Ptr=ExtractIconA(TheWindow,iconname,0)
	Local WM_SETICON = $80
	Local ICON_SMALL = 0
	Local ICON_BIG = 1
	Sendmessage(TheWindow, WM_SETICON, ICON_BIG, icon)
End Function



AppFile as stated here: https://en.wikibooks.org/wiki/BlitzMax/Modules/BASIC/BlitzMax_runtime#AppFile

Graphics 800,600,0,2
SetIcon(AppFile,GetActiveWindow())


Following the tutorial link, I already got the embedded icon ".o" file as the application icon, just the window icon only I'm having issues with.


col(Posted 2016) [#11]
There's a problem with you redefining GetActiveWindow as GetActiveWindow, possible a compiler error, but either way its unnecessary as they are the same name. If you remove that one then the EAV should be gone.


RustyKristi(Posted 2016) [#12]
Ok got it. If I remove that part I'm getting this error instead..

Attempt to call uninitialized function pointer



col(Posted 2016) [#13]
Hmm, I'm using the latest from the repo and just built in debug/release for x86 and x64 and this works ok...

Complete code...

Strict

Graphics 800,600
Print Int(GetActiveWindow())



you should get any non zero value returned and displayed in the console/editor. GetActiveWindow should be defined in 'mod/pub.mod/win32.mod/user32.bmx'. It may be worth checking that it is indeed in there and/or rebuild all modules.


RustyKristi(Posted 2016) [#14]
Awesome Dave! Thanks! it works now :D My mistake on redefining GetActiveWindow X-P


Brucey(Posted 2016) [#15]
If you find Windows API things that are not declared in Pub.Win32, we could always add them there... (since ideally they would all be there anyway).

Presumably the implementation is fairly incomplete because
1) the win32 api is quite large
2) whomever decided to have a pub.win32 was too lazy to do it properly

;-)


col(Posted 2016) [#16]
@RustiKristi
Glad you got it sorted and working :-)

@Brucey
Too lazy ? :D Have you seen the size of the windows api headers? Last time I counted them ;-) there were over a million lines of code ( yes folks! just the headers! ), on top of which there is now win8 and win10. I doubt any sane person would want to do them all :p


RustyKristi(Posted 2016) [#17]
oh i see. yeah now I'm curious with MonkeyX. Does it have the same setup wit win32 headers? :S


col(Posted 2016) [#18]
I personally don't use MonkeyX/2 as its priorities seem to be in a different direction to what Brucey is doing with NG.

I'm sure others know more about it though. Maybe even ask on the MonkeyX forums?