Author Topic: How to use MessageBoxIndirect function  (Read 986 times)

0 Members and 1 Guest are viewing this topic.

KarenZ

  • Newbie
  • *
  • Posts: 46
How to use MessageBoxIndirect function
« on: March 17, 2018, 07:44:07 AM »
Hi

I would like to use the MessageBoxIndirect function,  is there an example program that I can use?

Also, what would be format for the Oxygen's  message box command  mbox?
And how to place in Yes and NO and Cancel buttons, title for this message box?

Thank you
Regards
Karen

Charles Pegge

  • Admin Support Member
  • *****
  • Posts: 3946
    • Oxygen Basic
Re: How to use MessageBoxIndirect function
« Reply #1 on: March 17, 2018, 10:06:46 AM »
Hi Karen,

Code: [Select]
'2018-03-17 T 17:02:18
'MessageBoxIndirect
'https://msdn.microsoft.com/en-us/library/windows/desktop/ms645402(v=vs.85).aspx
'%filename "t.exe"
'uses rtl64
uses corewin
'
typedef dword DWORD, UINT
typedef sys   HWND,HINSTANCE,DWORD_PTR,MSGBOXCALLBACK
typedef char *LPCTSTR
'
typedef struct {
  UINT           cbSize;
  HWND           hwndOwner;
  HINSTANCE      hInstance;
  LPCTSTR        lpszText;
  LPCTSTR        lpszCaption;
  DWORD          dwStyle;
  LPCTSTR        lpszIcon;
  DWORD_PTR      dwContextHelpId;
  MSGBOXCALLBACK lpfnMsgBoxCallback;
  DWORD          dwLanguageId;
} MSGBOXPARAMS, *PMSGBOXPARAMS;

MSGBOXPARAMS mbp

with mbp.
  cbSize=sizeof MSGBOXPARAMS
  hwndOwner=null 'hWnd
  hInstance=GetModuleHandle(null)
  lpszText="text"
  lpszCaption="caption"
  dwStyle=3 'Yes/No/Concel
  lpszIcon=null
  dwContextHelpId=null
  lpfnMsgBoxCallback=null
  dwLanguageId=0 'LANG_NEUTRAL
end with     '

int a
a=MessageBoxIndirect mbp
print a
'6 yes
'7 no
'2 cancel

MessageBox / MessageBoxW are a little easier!

MessageBox hWnd,"text","caption",3

mbox is a print primitive that accepts strings only.

KarenZ

  • Newbie
  • *
  • Posts: 46
Re: How to use MessageBoxIndirect function
« Reply #2 on: March 17, 2018, 01:09:47 PM »
Excellent
Many Thanks Charles

KarenZ

  • Newbie
  • *
  • Posts: 46
Re: How to use MessageBoxIndirect function
« Reply #3 on: March 17, 2018, 02:01:25 PM »
I had attempted to place in my own icon using the method shown in


http://forums.codeguru.com/showthread.php?137064-MessageBoxIndirect


Code: [Select]
MSGBOXPARAMS mbp

with mbp.
  cbSize=sizeof MSGBOXPARAMS
  hwndOwner=null 'hWnd
  hInstance=GetModuleHandle(null)
  lpszText="Good message"
  lpszCaption="Message"
  dwStyle=MB_OK OR MB_USERICON OR MB_TASKMODAL   '3 'Yes/No/Concel
  lpszIcon= null  ' MAKEINTRESOURCE(200)
  dwContextHelpId=null
  lpfnMsgBoxCallback=null
  dwLanguageId=0 'LANG_NEUTRAL
end with     '

but  there is a compilation error  " string operand required "  at the line
Code: [Select]
lpszIcon=  MAKEINTRESOURCE(200)

The icon at ID 200 was already done through a Res file
How do I incorporate my own icon into this messagebox ?



Mike Lobanovsky

  • Admin Support Member
  • *****
  • Posts: 1884
Re: How to use MessageBoxIndirect function
« Reply #4 on: March 17, 2018, 05:50:00 PM »
Hi Karen,

The simplest way to resolve you problem would be to declare the lpszIcon member in your MSGBOXPARAMS structure not as LPCTSTR which is a strongly typed string pointer, but rather as DWORD which is a generic numeric value. Then you will be able to assign your resource ID directly without casts or C macros: (MAKEINTRESOURCE(n) would just cast numeric n to a quasi string pointer with the higher order bytes zeroed out)

lpszIcon = 200


_____________________________________

Did you know? If you are able to intercept the normally concealed handle to a regular MessageBox dialog window, you can do almost anything you like with its visual appearance, behavior, and contents, e.g.:
  • pop up the MessageBox (or as it happens, Oxygen's Print) dialog in the middle of its owner window anywhere on your multiple monitors rather than in the center of your primary monitor (see FBSL Eclecta editor snapshot below)
  • use custom font faces and/or colors (idem)
  • make the message box auto destroy itself on an adjustable timeout and perform its default action if the user is too lazy to stir a finger to respond to the message (idem)
  • change the control sizes, placement, and contents to your liking (see FBSL Cold::Rocks compiler snapshot below)
  • delete the existing and/or add new controls and define their behaviors programmatically? (idem)
:D
Mike
(3.6GHz Intel Core i5 Quad w/ 16GB RAM, nVidia GTX 1060Ti w/ 6GB VRAM, Windows 7 Ultimate Sp1)

KarenZ

  • Newbie
  • *
  • Posts: 46
Re: How to use MessageBoxIndirect function
« Reply #5 on: March 17, 2018, 08:17:57 PM »
Thanks Mike, 

However, while compiling there is no error but there is no icon in the messagebox.

Code: [Select]
'MessageBoxIndirect_64.o2bas
'https://msdn.microsoft.com/en-us/library/windows/desktop/ms645402(v=vs.85).aspx
$ filename "MessageBoxIndirect_64.exe"
uses rtl64
uses corewin
'
typedef dword DWORD, UINT
typedef sys   HWND,HINSTANCE,DWORD_PTR,MSGBOXCALLBACK
typedef char *LPCTSTR
'
typedef struct {
  UINT           cbSize;
  HWND           hwndOwner;
  HINSTANCE      hInstance;
  LPCTSTR        lpszText;
  LPCTSTR        lpszCaption;
  DWORD          dwStyle;
  DWORD          lpszIcon;
  DWORD_PTR      dwContextHelpId;
  MSGBOXCALLBACK lpfnMsgBoxCallback;
  DWORD          dwLanguageId;
} MSGBOXPARAMS, *PMSGBOXPARAMS;




'=======================
' main

MSGBOXPARAMS mbp

with mbp.
  cbSize=sizeof MSGBOXPARAMS
  hwndOwner=null 'hWnd
  hInstance=GetModuleHandle(null)
  lpszText="Good message"
  lpszCaption="Message"
  dwStyle=MB_OK OR MB_USERICON OR MB_TASKMODAL   '3 'Yes/No/Concel
  lpszIcon=   200
  dwContextHelpId=null
  lpfnMsgBoxCallback=null
  dwLanguageId=0 'LANG_NEUTRAL
end with     '

int a
a=MessageBoxIndirect mbp
print a
'6 yes
'7 no
'2 cancel

Is that messagebox in FreeBasic ?  It is pretty cool.



Charles Pegge

  • Admin Support Member
  • *****
  • Posts: 3946
    • Oxygen Basic
Re: How to use MessageBoxIndirect function
« Reply #6 on: March 17, 2018, 08:19:51 PM »
Thanks Mike,

I would say use sys instead of dword to maintain member alignment in 64bit.

This is a good strategy for any other dual-typed members you may encounter. Then use  strptr explicitly when you intend to pass a string rather than a number.

Code: [Select]
typedef struct {
  UINT           cbSize;
  HWND           hwndOwner;
  HINSTANCE      hInstance;
  LPCTSTR        lpszText;
  LPCTSTR        lpszCaption;
  DWORD          dwStyle;
  sys            lpszIcon;
  DWORD_PTR      dwContextHelpId;
  MSGBOXCALLBACK lpfnMsgBoxCallback;
  DWORD          dwLanguageId;
} MSGBOXPARAMS, *PMSGBOXPARAMS;

KarenZ

  • Newbie
  • *
  • Posts: 46
Re: How to use MessageBoxIndirect function
« Reply #7 on: March 17, 2018, 08:33:10 PM »
Many Thanks Charles

The sys did the job

Mike Lobanovsky

  • Admin Support Member
  • *****
  • Posts: 1884
Re: How to use MessageBoxIndirect function
« Reply #8 on: March 18, 2018, 04:37:03 AM »
Charles,

Thanks for refining my suggestion!


Karen,

Glad you got your code running.

1/ The original O2 code posted in this thread had no indication what platform exactly it was going to be used on ('uses rtl64 remmed out), in which case Oxygen's JIT defaults to 32 bits where LPCTSTR would be exactly as wide as DWORD keeping the structure alignment correct.

Had I known you would be using it under 64 bits rather than O2 JIT, I would have suggested sys, which is in fact O2's alias to the MS system integer that's treated as 32 bits wide in x86 C code, or 64 bits wide, in x64 C. C pointers are always system integer wide.

Hence your failure to use my suggestion verbatim until Charles' comment arrived.

2/ That cool message box is in FBSL BASIC, the dialect used to create FBSL's Eclecta code editor, FMFD mini form designer, and Cold::Rocks static code compiler that form up the FBSL v3.5 development environment. FBSL supports three distinct but interoperating language syntaxes -- BASIC, ANSI C, and Intel-style assembly. :)
Mike
(3.6GHz Intel Core i5 Quad w/ 16GB RAM, nVidia GTX 1060Ti w/ 6GB VRAM, Windows 7 Ultimate Sp1)

Charles Pegge

  • Admin Support Member
  • *****
  • Posts: 3946
    • Oxygen Basic
Re: How to use MessageBoxIndirect function
« Reply #9 on: March 18, 2018, 07:02:35 AM »

In my next o2 update, it will no longer be necessary to change the type to sys, or cast the value. Just making the compiler a little smarter :)

KarenZ

  • Newbie
  • *
  • Posts: 46
Re: How to use MessageBoxIndirect function
« Reply #10 on: November 15, 2018, 02:03:48 PM »
Hi Charles

With the newer O2 updated compiler  of July 21, 2018,  I wasn't able to compile the following same program.
I got an error message "cbsize not defined"  .  Probably this is the result of the updated compiler.
Could you please help or advise on how to resolve this issue.

Thanks and regards
Karen

Code: [Select]
'MessageBoxIndirect_64.o2bas
'https://msdn.microsoft.com/en-us/library/windows/desktop/ms645402(v=vs.85).aspx
$ filename "MessageBoxIndirect_64.exe"
uses rtl64
uses corewin
'
typedef dword DWORD, UINT
typedef sys   HWND,HINSTANCE,DWORD_PTR,MSGBOXCALLBACK
typedef char *LPCTSTR
'
typedef struct {
  UINT           cbSize;
  HWND           hwndOwner;
  HINSTANCE      hInstance;
  LPCTSTR        lpszText;
  LPCTSTR        lpszCaption;
  DWORD          dwStyle;
  sys         lpszIcon;
  DWORD_PTR      dwContextHelpId;
  MSGBOXCALLBACK lpfnMsgBoxCallback;
  DWORD          dwLanguageId;
} MSGBOXPARAMS, *PMSGBOXPARAMS;




'=======================
' main

MSGBOXPARAMS mbp

with mbp.
  cbSize=sizeof MSGBOXPARAMS
  hwndOwner=null 'hWnd
  hInstance=GetModuleHandle(null)
  lpszText="Good message"
  lpszCaption="Message"
  dwStyle=MB_OK OR MB_USERICON OR MB_TASKMODAL   '3 'Yes/No/Concel
  lpszIcon=   200
  dwContextHelpId=null
  lpfnMsgBoxCallback=null
  dwLanguageId=0 'LANG_NEUTRAL
end with     '

int a
a=MessageBoxIndirect mbp
print a
'6 yes
'7 no
'2 cancel

Charles Pegge

  • Admin Support Member
  • *****
  • Posts: 3946
    • Oxygen Basic
Re: How to use MessageBoxIndirect function
« Reply #11 on: November 15, 2018, 02:51:53 PM »
Hi Karen,

There was a change of syntax, advocated by Mike, so that with members could be used on both the left side and the right side of an expression: The dot is prefixed to the members:

Code: [Select]
with mbp
  .cbSize=sizeof MSGBOXPARAMS
  .hwndOwner=null 'hWnd
  .hInstance=GetModuleHandle(null)
  .lpszText="Good message"
  .lpszCaption="Message"
  .dwStyle=MB_OK OR MB_USERICON OR MB_TASKMODAL   '3 'Yes/No/Concel
  .lpszIcon=   200
  .dwContextHelpId=null
  .lpfnMsgBoxCallback=null
  .dwLanguageId=0 'LANG_NEUTRAL
end with     '

KarenZ

  • Newbie
  • *
  • Posts: 46
Re: How to use MessageBoxIndirect function
« Reply #12 on: November 16, 2018, 06:49:41 AM »
Thanks Charles, that works perfectly!