Declaring Win32 stuff for Bmax?
BlitzMax Forums/BlitzMax Beginners Area/Declaring Win32 stuff for Bmax?
| ||
I'm converting some old BPlus code to BMax, and can't understand why some of my User32, Kernel32, etc DECLS won't work when converted to BMax's format, but some do. If it was all not working, I would at least know where the problem was. For example, BPlus GetWindowThreadProcessId%(hwnd%,processid*):"GetWindowThreadProcessId" GetClassName%(hwnd%,classname*,max%):"GetClassNameA" BMax Function GetWindowThreadProcessId(hWnd:Int,ID:Byte Ptr) Function GetClassName(hWnd:Int,clString:Byte Ptr,nMaxCount:Int) = "GetClassNameA" GetWindowThreadProcess works fine, but GetClassName doesn't work, either with or without the "GetClassNameA". It's not an isolated function either, there are quite a lot that I can't define. 1) What am I doing wrong? 2) Can I save myself the trouble? Has anyone made a complete ( or near complete ) list of these declarations for Max? |
| ||
Pub.Win32 contains a few of them, but those ones you can do with:Extern "Win32" Function GetWindowThreadProcessId(hWnd:Int,ID:Byte Ptr) = "GetWindowThreadProcessId@8" Function GetClassName(hWnd:Int,clString:Byte Ptr,nMaxCount:Int) = "GetClassNameA@12" End Extern |
| ||
Ok, thanks, so it works with @12 appended, but why do I need that, what is it, and where do I find it for other functions I need? Also why does GetWindowThreadProcessId work perfectly without the need for the @8 but GetClassName doesn't work without the @12? Pub.Win32 doesn't contain much of what I need, and Birdie's TWin32 mod is no longer distributed in the samples, it would seem. |
| ||
the @12 is the size of the returned value, you can get this information by using a command prompt and navigate to the lib directory in your BMax folder. Then type nm libname.a > name.txt This will export the full names of the functions to a text file (specified by the last portion) e.g. nm libuser32.a > user32.txt |
| ||
Ok, that makes sense, thanks for the tip. I'm struggling now with Win32 stuff that wants to be passed a C Struct. It was my understanding that you could use BlitzMax types as surrogate C Structs if you generated an Int Ptr to the first field in the type. But this doesn't work : Extern "win32" Function GetVersionExA(lpOSVer:Byte Ptr) = "GetVersionExA@4" End Extern Type OSVersionInfoEx Field dwOSVersionInfoSize: Long Field dwMajorVersion:Long Field dwMinorVersion:Long Field dwBuildNumber:Long Field dwPlatformId:Long Field szCSDVersion:Byte[128] Field wServicePackMajor: Int Field wServicePackMinor: Int Field wSuiteMask: Int Field wProductType: Byte Field wReserved: Byte End Type Function GetOSVersion() Local VersionInfo:OSVersionInfoEx=New OSVersionInfoEx VersionInfo.dwOSVersionInfoSize=182 GetVersionExA(Int Ptr(Varptr(VersionInfo.dwOSVersionInfoSize))) DebugLog VersionInfo.dwOSVersionInfoSize DebugLog VersionInfo.dwMajorVersion DebugLog VersionInfo.dwMinorVersion DebugLog VersionInfo.dwBuildNumber DebugLog VersionInfo.dwPlatformID DebugLog String.FromCString(VersionInfo.szCSDVersion) DebugLog VersionInfo.wServicePackMajor DebugLog VersionInfo.wServicePackMinor DebugLog VersionInfo.wSuiteMask DebugLog VersionInfo.wProductType DebugLog VersionInfo.wReserved End Function EDIT: Fixed a few silly errors made when typing into the code box. Should have just copied and pasted really. EDIT2: Ok, I now know that SizeOf is returning an incorrect value, so I hardcoded the data buffer size. I'm still getting an error, and it's error 122, ERROR_INSUFFICIENT_BUFFER - The data area passed to a system call is too small. But I can make it absolutely huge and I still get the same problem. EDIT3: Tried it with Banks and MemAlloc() too, and I *still* get the same error code. I used the MSDN page as a reference for copying the Struct to a type. http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sysinfo/base/getversionex.asp |
| ||
the @12 is the size of the returned value Was that a typo Perturbatio, I thought the number is the combined size of the parameters the function receives. |
| ||
I can spot that at least Field szCSDVersion:Byte[128] should be Field szCSDVersion:Byte ptr The dll allocates the memory for that string. You have to free your .FromCString thing yourself though, so you should put it in a variable. read more at: http://www.blitzbasic.com/Community/posts.php?topic=53269 |
| ||
Changing the Byte Array to a Byte Pointer makes no difference. It still returns the same error code. I'm a little unclear on the freeing of the FromCString's. If all I have is a Byte Pointer, I have no idea how to free memory it points to. Just MemFree? When do I need to free them and when can I let them pass? For example, do I need to free it myself with this sort of thing as well? GetWindowText(HWND,CharBuffer,255) WindowName=String.FromCString(CharBuffer) Presumably not since I have a proper variable for this, and not a pointer. |
| ||
Sorry - you are right. I took the time to look it up, and the memory block is in the struct. Now I'll have to sort it out to make up. |
| ||
No problem. I figured it out with a TBank. Apparently making the bank too big also returns the error that the bank is too small (!!) and I had my data types muddled. My Longs should have been Ints and my Ints should have been shorts. All working fine now though. It appears not to be possible to do it with Blitz Types at all, since Blitz doesn't allocate memory for arrays within types in one contiguous block. IMO, it needs to be sorted ( or at least to have an alternative struct which can't contain functions and methods ) because it's hard to take BMax seriously as a general purpose language when you have to work so hard to work with anything outside of Max. Even PureBasic allocates Struct's in one block of memory, specifically so that you can work easily with the WinAPI. |