Recent

Author Topic: MessageBox needs an hWnd?  (Read 829 times)

linuxbob

  • New member
  • *
  • Posts: 8
MessageBox needs an hWnd?
« on: July 07, 2022, 03:31:40 am »
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

  • Hero Member
  • *****
  • Posts: 2935
Re: MessageBox needs an hWnd?
« Reply #1 on: July 07, 2022, 03:34:00 am »
If an hWnd is required, which one should I pass?
Pass zero (0) as the hwnd.
FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.

linuxbob

  • New member
  • *
  • Posts: 8
Re: MessageBox needs an hWnd?
« Reply #2 on: July 07, 2022, 03:47:56 am »
Cool, I'll give that a try.

MarkMLl

  • Hero Member
  • *****
  • Posts: 4778
Re: MessageBox needs an hWnd?
« Reply #3 on: July 07, 2022, 09:24:29 am »
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
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

Zvoni

  • Hero Member
  • *****
  • Posts: 1276
Re: MessageBox needs an hWnd?
« Reply #4 on: July 07, 2022, 09:26:44 am »
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....
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

MarkMLl

  • Hero Member
  • *****
  • Posts: 4778
Re: MessageBox needs an hWnd?
« Reply #5 on: July 07, 2022, 09:36:11 am »
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....

https://lazarus-ccr.sourceforge.io/docs/lcl/lclintf/messagebox.html

...which is also what Google turns up in preference to the TApplication method :-/

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

Zvoni

  • Hero Member
  • *****
  • Posts: 1276
Re: MessageBox needs an hWnd?
« Reply #6 on: July 07, 2022, 11:23:29 am »
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....

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....
Quote
The MessageBox function displays an modal dialog, with the given text, caption, icon and buttons.
"Modal" implies a Parent
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

BobDog

  • Sr. Member
  • ****
  • Posts: 299
Re: MessageBox needs an hWnd?
« Reply #7 on: July 07, 2022, 04:50:19 pm »

It has to be nil, it is a pointer.
Code: Pascal  [Select][+][-]
  1.  
  2. function msgbox(p:pointer;msg:pchar;title:pchar;L1:int32;L2:int32;milliseconds:int32):integer; cdecl external 'user32.dll' name 'MessageBoxTimeoutA';
  3.  
  4. begin
  5. writeln(msgbox(nil,'Wait 3 seconds, or close the messagebox . . .','Hello',0,0,3000));
  6. end.
  7.  

rvk

  • Hero Member
  • *****
  • Posts: 4836
Re: MessageBox needs an hWnd?
« Reply #8 on: July 07, 2022, 05:21:01 pm »
It 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

  • Hero Member
  • *****
  • Posts: 2935
Re: MessageBox needs an hWnd?
« Reply #9 on: July 07, 2022, 05:44:21 pm »
It 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.

FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 1129
    • Lebeau Software
Re: MessageBox needs an hWnd?
« Reply #10 on: July 07, 2022, 06:11:17 pm »
It 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 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  [Select][+][-]
  1. function MessageBoxTimeout(hWnd: HWND; const lpText, lpCaption: PAnsiChar; uType: UINT; wLanguageId: WORD; dwMilliseconds: DWORD): Integer; stdcall external 'user32.dll' name 'MessageBoxTimeoutA';
  2.  
  3. begin
  4.   WriteLn(MessageBoxTimeout(0{or an actual HWND}, 'Wait 3 seconds, or close the messagebox . . .', 'Hello', 0{MB_OK}, 0, 3000));
  5. end.
  6.  
« Last Edit: July 07, 2022, 06:15:01 pm by Remy Lebeau »
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

BobDog

  • Sr. Member
  • ****
  • Posts: 299
Re: MessageBox needs an hWnd?
« Reply #11 on: July 07, 2022, 08:50:33 pm »

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][+][-]
  1. {$macro on}
  2. {$define plus:=or}
  3.  
  4. function msgbox(p:pointer;msg:pchar;title:pchar;L1:int32;L2:int32;milliseconds:int32):integer; cdecl external 'user32.dll' name 'MessageBoxTimeoutA';
  5. const
  6. RETRYCANCEL    =$00000005;
  7. ICONINFORMATION=$00000040;
  8. var
  9. i:integer=0;
  10. j:integer=1;
  11. s,g:string;
  12.  
  13. begin
  14. while i<>2 do
  15. begin
  16. j:=j+1;
  17. Str(j,s);
  18. g:=concat('Wait ',s,' seconds or choose something . . .');
  19. i:=msgbox(nil,@g[1],'Messagebox Timed out',RETRYCANCEL plus ICONINFORMATION,0,1000*j);
  20. end;
  21. end.
  22.  




Remy Lebeau

  • Hero Member
  • *****
  • Posts: 1129
    • Lebeau Software
Re: MessageBox needs an hWnd?
« Reply #12 on: July 08, 2022, 02:30:40 am »
Win32 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.

But 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.
« Last Edit: July 08, 2022, 02:32:17 am by Remy Lebeau »
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

PascalDragon

  • Hero Member
  • *****
  • Posts: 4318
  • Compiler Developer
Re: MessageBox needs an hWnd?
« Reply #13 on: July 12, 2022, 01:47:15 pm »
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.

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. ;)

 

TinyPortal © 2005-2018