![]() |
PickIconDialog
Hi,
Bei meinem ![]() ![]() Die Units SysUtils (RaiseLastOSError) Windows (Load und FreeLibrary, GetProcAddress) werden benötigt.
Delphi-Quellcode:
Hintergrund: Ab Windows 2000 (NT 5.0) ist der PickIconDialog Unicode, vorher war er ANSI. Daher wird bei NT-Systemen mit einer Major-Version von 5 oder höher der Code für Unicode ausgeführt, sonst der für ANSI. Des weiteren ist er bei älteren Systemen als nur per Index erreichbar, weshalb auf diesen zugegriffen wird, wenn GetProcAddress mit Namen fehlschlägt.
function PickIconDlg(hwndOwner: HWND; var lpstrFile: String;
var lpdwIconIndex: LongInt): Boolean; var Lib: THandle; PickIconDlgA: function(hwndOwner:HWND; lpstrFile: PAnsiChar; nMaxFile: DWORD; var lpdwIconIndex: LongInt): Longint; stdcall; PickIconDlgW: function(hwndOwner:HWND; lpstrFile: PWideChar; nMaxFile: DWORD; var lpdwIconIndex: LongInt): Longint; stdcall; WinVersion: DWord; WindowsMajorVersion: Byte; Unicode: Boolean; idx, Size: Integer; AnsiBuffer: AnsiString; WideBuffer: WideString; begin Lib := LoadLibrary('SHELL32'); if Lib <> 0 then try WinVersion := GetVersion; WindowsMajorVersion := Lo(WinVersion); Unicode := (WinVersion < $80000000) { NT-System } and (WindowsMajorVersion >= 5); { ab 2000 } idx := Length(lpstrFile); //size := Max(idx, MAX_PATH); if MAX_PATH > idx then size := MAX_PATH else size := idx; if Unicode then begin @PickIconDlgW := GetProcAddress(Lib, 'PickIconDlg'); if not Assigned(@PickIconDlgW) then @PickIconDlgW := GetProcAddress(Lib, Pointer(62)); if not Assigned(@PickIconDlgW) then RaiseLastOSError; WideBuffer := lpstrFile; SetLength(WideBuffer, size + 1); WideBuffer[idx+1] := #0; Result := PickIconDlgW(hwndOwner, PWideChar(WideBuffer), size, lpdwIconIndex) <> 0; if Result then lpstrFile := PWideChar(WideBuffer); end else begin @PickIconDlgA := GetProcAddress(Lib, Pointer(62)); if not Assigned(@PickIconDlgA) then RaiseLastOSError; AnsiBuffer := lpstrFile; SetLength(AnsiBuffer, size + 1); AnsiBuffer[idx+1] := #0; Result := PickIconDlgA(hwndOwner, PAnsiChar(AnsiBuffer), size, lpdwIconIndex) <> 0; if Result then lpstrFile := PAnsiChar(AnsiBuffer); end; finally if not FreeLibrary(Lib) then RaiseLastOSError; end else RaiseLastOSError; end; Mfg FAlter |
Re: PickIconDialog
die MSDN (*) schreibt, dass die Funktion erst ab Windows XP existiert.
Übrigens: Der letzte Rückgabewert geschrieben in lpdwIconIndex muss ein Integer sein laut Definition. Am besten wäre es, wenn die Funktion über LoadLibrary und so geladen wird. (*) Die MSDN konnte den Eintrag nicht finden. Ich habe daher im Cache von Google gesucht und gefunden: ![]() |
Re: PickIconDialog
Hi,
Zitat:
Delphi-Quellcode:
Daher verwendete man zuvor nur index. Natürlich erhält man da - und nicht ohne Grund - ne Meldung von wegen Platformunabhängigkeit. Eventuell sollte man daher die OS-Unterscheidung nur machen, wenn GetProcAdress nil zurückliefert bei 'PickIconDlg'. Dann müsste man LoadLibrary nehmen, damits nicht beim Programmstart ne hübsche Meldung gibt bei altem OS.
function ...
external 'SHELL32.DLL' name 'PickIconDlg'; Zitat:
Zitat:
Gute Nacht FAlter |
Re: PickIconDialog
Die Plattformunabhängigkeit bezieht sich auf Linux und Windows und hat nichts mit der Windows Version zu tun.
|
Re: PickIconDialog
Ich schätze, dass die MSDN WinXP als Minimum angibt, weil die Funktion davor als inoffiziel gilt.
|
Re: PickIconDialog
Hi,
Zitat:
Zitat:
[edit] Zitat:
[/edit] Mfg FAlter |
Re: PickIconDialog
Auf die Nummer 62 kannst du dich nur dann verlassen, wenn es in der MSDN so steht.
Da für ältere Windowsversionen wohl eh kein Update mehr kommt, wird das auch nicht geändert. Zu Abbrechen - überprüfe mal mit GetLastError, ob abgebrochen wurde. Oder den Parameter mit dem Bildindex - vielleicht ist dieser -1 ?. |
Re: PickIconDialog
Hi,
habe jetzt den LoadLibrary-Ansatz verfolgt. Bei neuem OS wird der Index nur verwendet, wenn GetProcAddress mit Angabe des Namen fehlschlägt. Im Gegensatz zu anderen Funktionen steht unter ms-help://borland.bds4/shellcc/platform/shell/reference/functions/pickicondlg.htm (PickIconDialog+F1) nicht da, dass GetLastError einen weiterbringt. Also keine Möglichkeit, einen Fehler zu erkennen. Existiert allerdings z. B. die Datei nicht, gibts ne MessageBox, und danach wird die SYSTEM32.DLL selbst angezeigt (und natürlich der zurückgegebene Dateiname wird zu <System32-Verzeichnis>\System32.dll). Eventuell gibt es ja außer Abbrechen gar keinen "Fehlerfall". Mfg FAlter |
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:04 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz