Einzelnen Beitrag anzeigen

MathiasSimmack
(Gast)

n/a Beiträge
 
#6

Den Dialog anzeigen

  Alt 27. Jun 2002, 10:12
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);
  Mit Zitat antworten Zitat