program ShMsgBox;
uses
Windows, ShellAPI;
type
{$IFDEF UNICODE}
LPCTSTR = PWideChar;
{$ELSE}
LPCTSTR = PAnsiChar;
{$ENDIF}
////////////////////////////////////////////////////////////////////////////////
//
// ShellMessageBox
//
// ( [url]http://search.microsoft.com/?View=msdn&qu=ShellMessageBox[/url] )
//
// Notes:
// Maximum used ressource string length is 80 chars
// ShellMessageBox adds MB_SETFOREGROUND to fuStyle
//
function ShellMessageBox(Inst: HINST; Wnd: HWND; Msg, Title: LPCTSTR;
Style: UINT;
const Arguments:
array of LPCTSTR): Integer;
stdcall;
type
TFNShellMessageBoxA =
function(hInst: HINST; hWnd: HWND; pszMsg: LPCSTR;
pszTitle: LPCSTR; fuStyle: UINT
{...}): Integer;
cdecl;
TFNShellMessageBoxW =
function(hInst: HINST; hWnd: HWND; pszMsg: LPCWSTR;
pszTitle: LPCWSTR; fuStyle: UINT
{...}): Integer;
cdecl;
TFNShellMessageBox =
function(hInst: HINST; hWnd: HWND; pszMsg: LPCTSTR;
pszTitle: LPCTSTR; fuStyle: UINT
{...}): Integer;
cdecl;
const
ShellMessageBoxProcNameA = '
ShellMessageBoxA';
ShellMessageBoxProcNameW = '
ShellMessageBoxW';
ShellMessageBoxProcOrdA = PAnsiChar(183);
ShellMessageBoxProcOrdW = PAnsiChar(182);
{$IFDEF UNICODE}
ShellMessageBoxProcName = ShellMessageBoxProcNameW;
ShellMessageBoxProcOrd = ShellMessageBoxProcOrdW;
{$ELSE}
ShellMessageBoxProcName = ShellMessageBoxProcNameA;
ShellMessageBoxProcOrd = ShellMessageBoxProcOrdA;
{$ENDIF}
var
ShellModule: HMODULE;
FNShellMessageBox: TFNShellMessageBox;
begin
Result := 0;
ShellModule := LoadLibrary(shell32);
if (ShellModule <> 0)
then
try
FNShellMessageBox := TFNShellMessageBox(
GetProcAddress(ShellModule, ShellMessageBoxProcName));
if not Assigned(FNShellMessageBox)
then
FNShellMessageBox := TFNShellMessageBox(
GetProcAddress(ShellModule, ShellMessageBoxProcOrd));
if Assigned(FNShellMessageBox)
then
begin
asm
push ebx
// save EBX
mov ecx,[Arguments-$04]
// High(Arguments)
mov ebx,ecx
// offset to last argument
shl ebx,$02
// (High * SizeOf)
inc ecx
// Length(Arguments)
jz @@call
// no arguments?
mov edx,[Arguments]
// first argument
add edx,ebx
// last argument
@@loop: push dword ptr [edx]
// push argument
sub edx,$04
// next argument
loop @@loop
// until ecx = 0
@@call: push dword ptr [Style]
// push params
push dword ptr [Title]
// ...
push dword ptr [Msg]
push dword ptr [Wnd]
push dword ptr [Inst]
call FNShellMessageBox
// call function
add esp,$18
// cleanup stack (params)
add esp,ebx
// cleanup stack (arguments)
mov [Result],eax
// return value into Result
pop ebx
// restore EBX
end;
end;
finally
FreeLibrary(ShellModule);
end;
end;
////////////////////////////////////////////////////////////////////////////////
// Sample
begin
ShellMessageBox(0, 0,
'
function %2(%4: %3; %6: %5; %8, %10: %7; %12: %11 {...}): %1;',
'
ShellMessageBox', MB_OK
or MB_DEFBUTTON1
or MB_ICONINFORMATION,
['
Integer', '
ShellMessageBox', '
HINST', '
hInst', '
HWND', '
hWnd',
'
LPCTSTR', '
pszMsg', '
LPCTSTR', '
pszTitle', '
UINT', '
fuStyle']);
end.