Einzelnen Beitrag anzeigen

NicoDE
(Gast)

n/a Beiträge
 
#2

Re: Problem mit ShellMessageBox

  Alt 22. Mär 2004, 22:40
Zitat von MathiasSimmack:
Ich mache irgendwas falsch. Aber was?
Liegt nur daran, dass es nicht gerade einfach ist, mit Delphi Language variante Parameter (...) umzusetzen.

Delphi-Quellcode:
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.
Gruss Nico

[edit] BASM Optimierungen [/edit]
[edit] Anpassungen D2-D6 [/edit]
[edit] Unicode-Anpassung [/edit]
  Mit Zitat antworten Zitat