Um nun endlich unsere eigene Eigenschaftenseite anzeigen zu können, ziehen wir die Funktion "AddPages" heran, bei der wir zwei neue Variablen benötigen. Die eine Variable ist ein
Handle auf die erzeugte Seite, die zweite ist eine Struktur, die wir zum Erzeugen der Seite benötigen. Mal ein bisschen Microsoft-Code:
Code:
typedef struct _PROPSHEETPAGE {
DWORD dwSize; // Größe der Struktur
DWORD dwFlags; // Flags
HINSTANCE hInstance; // Instanz
union {
LPCSTR pszTemplate; // Dialog-ID
LPCDLGTEMPLATE pResource;
};
union {
HICON hIcon;
LPCSTR pszIcon;
};
LPCSTR pszTitle; // Titel
DLGPROC pfnDlgProc; // Dialog-Funktion
LPARAM lParam;
LPFNPSPCALLBACK pfnCallback;
UINT *pcRefParent;
#if (_WIN32_IE >= 0x0500)
LPCTSTR pszHeaderTitle;
LPCTSTR pszHeaderSubTitle;
#endif
#if (_WIN32_WINNT >= 0x0501)
HANDLE hActCtx;
#endif
}
Nun interessiert uns nicht alles davon, wir brauchen nur:
Code:
var
aPSP : TPropSheetPage;
begin
fillchar(aPSP, sizeof(TPropSheetPage),#0);
aPSP.dwSize := sizeof(TPropSheetPage);
aPSP.dwFlags := PSP_USETITLE;
aPSP.hInstance := hInstance;
aPSP.pszTemplate := MakeIntResource(IDD_PROPDLG);
aPSP.pszTitle := 'Beispielseite'; // Titel der Seite
aPSP.pfnDlgProc := @propdlgproc; // Dialogfunktion
aPSP.pfnCallback := nil;
aPSP.lParam := 0;
end;
Jetzt können wir die Seite erstellen lassen, wozu wir die Funktion "CreatePropertySheetPage" benutzen:
Code:
var
hPage : HPropSheetPage;
begin
...
hPage := CreatePropertySheetPage(aPSP);
if(hPage <> nil) then
if(lpfnAddPage(hPage,lParam) = FALSE) then
DestroyPropertySheetPage(hPage);
end;
Die Dialog-Funktion
Unser Dialog benutzt eine typische Nachrichtenfunktion, in der wir Einfluss auf die Anzeige nehmen können. Diese Funktion ist
NonVCL-Entwicklern sicher bekannt - andernfalls empfehle ich einen Blick in Luckies "
NonVCL-Tutorials", wobei die Themen Dialogressourcen und Listbox besonders interessant sind, da wir beides in unserem Beispiel benötigen.
Schauen wir uns also mal an, wie die Dateinamen aus dem String-Array in unsere Listbox kommen.
Code:
WM_INITDIALOG:
begin
if(length(szOpenedTextfile) > 0) then
for i := 0 to length(szOpenedTextFile) - 1 do
begin
ZeroMemory(@buffer,sizeof(buffer));
lstrcpy(buffer,pchar(szOpenedTextfile[i]));
SendDlgItemMessage(hDlg,IDC_LISTBOX,
LB_ADDSTRING,0,integer(@buffer));
end;
end;
Nichts weltbewegendes, denke ich. - Fehlt noch der Klick auf den Button: hier müssen wir herausfinden, ob und welche Dateien alles markiert sind, und dann übergeben wir sie einfach an "ShellExecute":
Code:
WM_COMMAND:
if(HIWORD(wp) = BN_CLICKED) then
case LOWORD(wp) of
IDC_OPENBTN:
begin
// Anzahl der Einträge bestimmen
items := SendDlgItemMessage(hDlg,IDC_LISTBOX,
LB_GETCOUNT,0,0);
// ausgewählte Einträge auslesen
for i := 0 to items do
if(SendDlgItemMessage(hDlg,IDC_LISTBOX,LB_GETSEL,i,0) > 0) then
begin
ZeroMemory(@buffer,sizeof(buffer));
SendDlgItemMessage(hDlg,IDC_LISTBOX,LB_GETTEXT,i,integer(@buffer));
// und via "ShellExecute" starten
ShellExecute(0,nil,buffer,nil,nil,SW_SHOWNORMAL);
end;
end;
end;
Wer mit diesem Code nichts anfangen kann, sollte wirklich einen Blick in die erwähnten Tutorials werfen. Aber ich glaube, in so einem Fall ist eine Shell-Erweiterung vielleicht ein zu hartes Projekt als Einstieg.
Noch ein Wort zu "ShellExecute": Wie man sehen kann, verwende ich als zweiten Parameter
nil. Ich überlasse also dem System die Entscheidung, was mit den Textdateien passiert. In den meisten Fällen sollte die Standardaktion aber "open" sein, was den Start eines Texteditors und die Anzeige der Datei bedeutet. Es wäre aber auch denkbar, dass die Standardaktion auf Drucken eingestellt ist ... was auch immer ... Also, Obacht!
Änderungen übernehmen
Schauen wir uns noch eine Eigenschaft unserer "Property Sheet" an, die in dem Fall zwar weniger wichtig ist, die aber ihr möglicherweise brauchen werdet: den "Übernehmen"-Button. Der ist normalerweise deaktiviert, aber durch irgendwelche Änderungen wird er aktiviert.
Soll die eigene Shell-Erweiterung auf den Klick dieses Buttons reagieren und irgendwelche Aktionen ausführen, dann ist dazu die Nachricht "WM_NOTIFY" abzufangen:
Code:
WM_NOTIFY:
if(PNMHDR(lp).code = PSN_APPLY) then
MessageBox(0,'Übernehmen-Button geklickt','Information',
MB_ICONINFORMATION or MB_OK);