Thema: Delphi Paint-Messages abfangen

Einzelnen Beitrag anzeigen

teebee

Registriert seit: 17. Jan 2003
Ort: Köln
460 Beiträge
 
Delphi 6 Professional
 
#10

Re: Paint-Messages abfangen

  Alt 26. Sep 2005, 13:21
Das ganze ist ja schön und gut, hat aber einen kleinen Haken: Wenn man den Dialog im Explorer-Style haben möchte, kommt in der Hook-Procedure kein WM_CTLCOLORDLG an. Windows erzeugt dann nämlich den neuen Dialog als Child eines unsichtbaren Standard-Dialogs und die DialogProcedure des Standard-Dialogs bekommt die Nachricht. Man muss also irgendwie in die DialogProc des unsichtbaren Parents der neuen DialogBox gelangen, was nur auf sehr schmutzige Art geht:
Delphi-Quellcode:
// Hier merken wir uns die Adresse der alten DialogProc des Parents unseres Dialogs
Var oldDlgProc: Pointer;

// Diese DialogProc bearbeitet WM_CTLCOLORDLG
Function DialogProc(hdlg: HWND; uiMsg: UINT; wParam: WPARAM; lParam:LPARAM): UINT; stdcall;
Begin
 case uiMsg of
  WM_CTLCOLORDLG:
   Result := GetStockObject(WHITE_BRUSH); // zu Demozwecken
 else
  Result := CallWindowProc(oldDlgProc,hdlg,uiMsg,wParam,lParam);
 end;
End;

// Das ist unsere eigentliche Hook-DialogProcedure
Function OpenFileNameHook(hdlg: HWND; uiMsg: UINT; wParam: WPARAM; lParam:LPARAM): UINT; stdcall;
Var ofnParent: Integer;
Begin
 Result := 0;
 Case uiMsg of
  WM_NOTIFY: Begin
              Result := 0;
              If ((POFNOTIFY(lparam)^.hdr.code)=CDN_INITDONE) then Begin
               // wir merken uns den Parent
               ofnParent := GetParent(hdlg);
               // und holen uns die Adresse der ParentDialogProc
               oldDlgProc := Pointer(GetWindowLong(ofnparent,DWL_DLGPROC));
               // und setzen die ParentDialogProc auf die obere Proc
               SetWindowLong(ofnParent,DWL_DLGPROC,Integer(@DialogProc));
               Result := 1;
              End;
             End;
 End;
End;

procedure TForm1.Button1Click(Sender: TObject);
Var ofn: TOpenFileName;
begin
 // rudimentäres Befüllen der Struktur zu Demozwecken
 ZeroMemory(@ofn,sizeof(ofn));
 ofn.lStructSize := sizeof(ofn);
 ofn.lpstrInitialDir := 'C:\';
 ofn.Flags := OFN_ENABLEHOOK or OFN_EXPLORER; // wir wollen den Explorer-Style
 ofn.lpfnHook := @OpenFileNameHook;
 GetOpenFileName(ofn);
end;
Zugegeben, sieht schmutzig aus, aber geht...

Gruß, teebee
  Mit Zitat antworten Zitat