Forum > Windows

MessageBox needs an hWnd?

<< < (3/3)

Remy Lebeau:

--- Quote from: 440bx on July 07, 2022, 05:44:21 pm ---It should _not_ be a pointer.  An HWND is not a pointer, it's a handle

--- End quote ---

Indeed, though technically a HANDLE/HWND is actually a pointer in the POV of the Win32 API.  But FPC (and Delphi) has the THandle type to represent OS handles.  But I agree, the declaration needs to be fixed, the parameter should be a HWND/THandle instead of a Pointer.

Also, just about everything else about the declaration is wrong and should be fixed:


* The msg and title parameters should be PAnsiChar instead of PChar
* The L1 parameter should be UINT instead of Int32
* The L2 parameter should be WORD instead of Int32
* The milliseconds parameter should be DWORD instead of Int32
* The calling convention needs to be stdcall instead of cdecl
So, a more appropriate example would look more like this:


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---function MessageBoxTimeout(hWnd: HWND; const lpText, lpCaption: PAnsiChar; uType: UINT; wLanguageId: WORD; dwMilliseconds: DWORD): Integer; stdcall external 'user32.dll' name 'MessageBoxTimeoutA'; begin  WriteLn(MessageBoxTimeout(0{or an actual HWND}, 'Wait 3 seconds, or close the messagebox . . .', 'Hello', 0{MB_OK}, 0, 3000));end. 

BobDog:

Win32 datatypes are not needed, no need for uses windows.
C suggests
int MessageBoxTimeoutA(IN HWND hWnd, IN LPCSTR lpText,
    IN LPCSTR lpCaption, IN UINT uType,
    IN WORD wLanguageId, IN DWORD dwMilliseconds);

But the function works fine as is in a simple format.

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---{$macro on}{$define plus:=or} function msgbox(p:pointer;msg:pchar;title:pchar;L1:int32;L2:int32;milliseconds:int32):integer; cdecl external 'user32.dll' name 'MessageBoxTimeoutA';constRETRYCANCEL    =$00000005;ICONINFORMATION=$00000040;vari:integer=0;j:integer=1;s,g:string; beginwhile i<>2 dobeginj:=j+1;Str(j,s);g:=concat('Wait ',s,' seconds or choose something . . .');i:=msgbox(nil,@g[1],'Messagebox Timed out',RETRYCANCEL plus ICONINFORMATION,0,1000*j);end;end. 


Remy Lebeau:

--- Quote from: BobDog on July 07, 2022, 08:50:33 pm ---Win32 datatypes are not needed, no need for uses windows.

--- End quote ---

They are not required, no.  But they do make things easier and consistent.

But, you DO need to match the correct data type sizes at least (ie sizeof(WORD) <> sizeof(Int32)!), and especially the correct calling convention (very important!), or else bad things will happen, whether you notice them right away or not.


--- Quote from: BobDog on July 07, 2022, 08:50:33 pm ---But the function works fine as is in a simple format.

--- End quote ---

It doesn't work correctly if you use the wrong calling convention, for instance (as this example is doing).

If you compile for 32bit, then all Win32 APIs (except for wsprintf(A/W)) use the stdcall calling convention, NOT cdecl, despite what MS's documentation suggests (since MS doesn't usually display the calling convention used, it is implied instead). So, don't mismatch them!  In the example provided, stack corruption WILL occur when the program tries to clean up the call stack a second time AFTER MessageBoxTimeoutA() has already cleaned up the call stack upon its exit.

If you compile for 64bit, then this issue is moot since there is only 1 calling convention defined by the Windows 64bit ABI, which the compiler handles for you, so the cdecl/stdcall keywords are ignored in code.

PascalDragon:

--- Quote from: Remy Lebeau on July 08, 2022, 02:30:40 am ---If you compile for 64bit, then this issue is moot since there is only 1 calling convention defined by the Windows 64bit ABI, which the compiler handles for you, so the cdecl/stdcall keywords are ignored in code.

--- End quote ---

They are not ignored, they are mapped to the default calling convention for - in this case - Windows. For non-Windows they would be mapped to the SysV ABI calling convention. And then there's also vectorcall as well as sysv_abi_default and ms_abi_default. ;)

Navigation

[0] Message Index

[*] Previous page

Go to full version