MessageBox needs an hWnd? lazarus / 67-Windows ---------------------------------------------------------------------- linuxbob · 2022-07-07 01:31 When I try to type in 'MessageBox' into a unit, the code prediction tells me I need to provide an hWnd. If I don't provide an hWnd, I get an error. The wiki doesn't refer to the hWnd parameter at all, nor does the appropriate Delphi reference. Coming from VB6, I never needed an hWnd there either. If an hWnd is required, which one should I pass? TIA. ---------------------------------------------------------------------- 440bx · 2022-07-07 01:34 Quote from: linuxbob on July 07, 2022, 03:31:40 amIf an hWnd is required, which one should I pass? Pass zero (0) as the hwnd. ---------------------------------------------------------------------- linuxbob · 2022-07-07 01:47 Cool, I'll give that a try. ---------------------------------------------------------------------- MarkMLl · 2022-07-07 07:24 What exactly are you trying to do (and on what platform)? There's a risk here that a suggestion from the IDE is leading you towards a low- level API rather than a more general routine to e.g. display a dialog(u)e. Also note that the- in fact any- wiki should not automatically be considered authoritative documentation. See e.g. https://lazarus- ccr.sourceforge.io/docs/lcl/ hence https://lazarus- ccr.sourceforge.io/docs/lcl/forms/tapplication.messagebox.html I'd suggest that even if not obvious, it is always prudent to give the compiler and IDE version in a question. For example, it might be that you have am IDE version where there are known to be deficiencies in some areas of the help subsystem. MarkMLl ---------------------------------------------------------------------- Zvoni · 2022-07-07 07:26 at a Guess, the hWnd is "representing" the Parent-Form of the Message- Box, but looking at Mark's link to TApplication.MessageBox i'm wondering where the hWnd is coming from.... ---------------------------------------------------------------------- MarkMLl · 2022-07-07 07:36 Quote from: Zvoni on July 07, 2022, 09:26:44 amat a Guess, the hWnd is "representing" the Parent-Form of the Message-Box, but looking at Mark's link to TApplication.MessageBox i'm wondering where the hWnd is coming from.... https://lazarus-ccr.sourceforge.io/docs/lcl/lclintf/messagebox.html ...which is also what Google turns up in preference to the TApplication method :-/ MarkMLl ---------------------------------------------------------------------- Zvoni · 2022-07-07 09:23 Quote from: MarkMLl on July 07, 2022, 09:36:11 amQuote from: Zvoni on July 07, 2022, 09:26:44 amat a Guess, the hWnd is "representing" the Parent-Form of the Message-Box, but looking at Mark's link to TApplication.MessageBox i'm wondering where the hWnd is coming from.... https://lazarus-ccr.sourceforge.io/docs/lcl/lclintf/messagebox.html ...which is also what Google turns up in preference to the TApplication method :-/ MarkMLl and there it is.... QuoteThe MessageBox function displays an modal dialog, with the given text, caption, icon and buttons. "Modal" implies a Parent ---------------------------------------------------------------------- BobDog · 2022-07-07 14:50 It has to be nil, it is a pointer. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i  function m sgbox(p:pointer;msg:pchar;title:pchar;L1:int32;L2:int32;milliseconds:i nt32):integer; cdecl external 'user32.dll' name 'MessageBoxTimeoutA'; beginwriteln(msgbox(nil,'Wait 3 seconds, or close the messagebox . . .','Hello',0,0,3000));end. ---------------------------------------------------------------------- rvk · 2022-07-07 15:21 Quote from: BobDog on July 07, 2022, 04:50:19 pmIt has to be nil, it is a pointer. Luckily a nil pointer is one that has the value 0  http://www.delphibasics.co.uk/RTL.asp?Name=Nil ---------------------------------------------------------------------- 440bx · 2022-07-07 15:44 Quote from: BobDog on July 07, 2022, 04:50:19 pmIt has to be nil, it is a pointer. It should _not_ be a pointer.  An HWND is not a pointer, it's a handle and, attempting to de-reference it will, more often than not, cause an access violation. You should correct that definition. ---------------------------------------------------------------------- Remy Lebeau · 2022-07-07 16:11 Quote from: 440bx on July 07, 2022, 05:44:21 pmIt should _not_ be a pointer.  An HWND is not a pointer, it's a handle 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 PCharThe L1 parameter should be UINT instead of Int32The L2 parameter should be WORD instead of Int32The milliseconds parameter should be DWORD instead of Int32The calling convention needs to be stdcall instead of cdecl So, a more appropriate example would look more like this: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i 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 · 2022-07-07 18:50 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  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i {$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; begin while 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 · 2022-07-08 00:30 Quote from: BobDog on July 07, 2022, 08:50:33 pmWin32 datatypes are not needed, no need for uses windows. 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 pmBut the function works fine as is in a simple format. 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 · 2022-07-12 11:47 Quote from: Remy Lebeau on July 08, 2022, 02:30:40 amIf 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. 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.