![]() |
Paint-Messages abfangen
hi ihr alle ;),
hab mal ne frage: undzwar wie kann ich die paint-messages von dialogen abfangen? (weiß nicht ob ich das so richtig ausgedrück habe^^) also ich will eigentlich das design von zB einem OpenDialog verändern.... deshalb müsste ich irgendwie an diese "drankommen". müsste irgendwie auf die form der dialoge zugreifen können. hat jemand ne idee wie ich das anstellen kann? :gruebel: MfG |
Re: Paint-Messages abfangen
Ja man kann diese Nachrichten abfangen aber die GDI ist nicht multithreadfähig.
Man kann aber mit einem ![]() ![]() |
Re: Paint-Messages abfangen
hm,
hört sich sehr kompliziert an :? irgendwie finde ich nicht so recht nen ansatz. kann mir jemand dabei helfen? also sagen wir einfach mal ich möchte die farbe von einem OpenDialog ändern. Wie mache ich das dann? :gruebel: MfG |
Re: Paint-Messages abfangen
Du nimmst das Handle vom Dialog und schickst an dieses eine entsprechende Nachricht. Welche das ist weiß ich jetzt aus dem Kopf nicht, aber das sollte sich ja innerhalb von 10 Minuten in der OH finden lassen.
|
Re: Paint-Messages abfangen
Gut gemeint, aber leider Quatsch. Man schickt dem Dialog zu diesem Behufe keine Nachricht, sondern man verarbeitet eine bestimmte Nachricht. Ich versuche nachher schnell was hinzuhacken.
|
Re: Paint-Messages abfangen
Delphi-Quellcode:
function OFNHookProc(Wnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): UINT; stdcall;
var col: COLORREF; brush: HBRUSH; begin Writeln('OFNHookProc'); brush := GetProp(Wnd, 'brush'); case Msg of WM_CTLCOLORDLG: begin Writeln('WM_CTLCOLORDLG'); col := RGB($ff, 0, 0); SetBkColor(wParam, col); SetBkMode(wParam, TRANSPARENT); if(brush <> 0)then DeleteObject(brush); brush := CreateSolidBrush(col); SetProp(Wnd, 'brush', brush); Result := brush; end; WM_CLOSE: begin if(brush <> 0) then DeleteObject(brush); end; else Result := ord(False); end; end; var ofn: tagOFNA; Buffer: array[0..MAX_PATH] of Char; begin AllocConsole(); ZeroMemory(@ofn, sizeof(ofn)); ofn.lStructSize := sizeof(ofn); ofn.hWndOwner := GetDesktopWindow(); ofn.hInstance := hInstance; ofn.lpstrFilter := 'Textfiles'#0'*.txt'#0'Rich Text Documents'#0'*.rtf'#0#0; ofn.lpstrFile := @Buffer; ofn.nMaxFile := sizeof(Buffer) div sizeof(Char); ofn.Flags := OFN_ENABLEHOOK or OFN_FILEMUSTEXIST or OFN_PATHMUSTEXIST; ofn.lpfnHook := @OFNHookProc; GetOpenFileName(ofn); end. |
Re: Paint-Messages abfangen
hui, also danke erstmal, aber kann damit leider nichts anfangen :(
was ist denn "tagOFNA;"? kann mit der OH die zugehörige unit nicht finden :roll: |
Re: Paint-Messages abfangen
Zitat:
Delphi-Quellcode:
var
OldWndProc: TFNWndProc; NewWndProc: TFNWndProc; ParentHWnd: HWND; // ------------------------------------------------------------------------------------------------- function ParentOpenDialogWndProc(hWnd: HWND; uMsg: UINT; wParam: WPARAM; lParam: LPARAM) : LRESULT; stdcall; begin if uMsg = WM_PAINT then begin // Hier dein Source Code end; CallWindowProc(OldWndProc, hWnd, uMsg, wParam, lParam); end; // ------------------------------------------------------------------------------------------------- procedure TForm1.OpenDialog1Show(Sender: TObject); begin NewWndProc := @ParentOpenDialogWndProc; ParentHWnd := GetParent(OpenDialog1.Handle); OldWndProc := TFNWndProc(SetWindowLong(ParentHWnd, GWL_WNDPROC, Longint(NewWndProc))); end; // ------------------------------------------------------------------------------------------------- procedure TForm1.OpenDialog1Close(Sender: TObject); begin SetWindowLong(ParentHWnd, GWL_WNDPROC, Longint(OldWndProc)); end; // ------------------------------------------------------------------------------------------------- |
Re: Paint-Messages abfangen
Zitat:
Das von mir gepostete Ding ist fast komplett. Da fehlt lediglich der Anfang (program Bla; uses Windows, Messages, CommDlg;). |
Re: Paint-Messages abfangen
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:
Zugegeben, sieht schmutzig aus, aber geht...
// 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; Gruß, teebee |
Re: Paint-Messages abfangen
Stimmt. Hatte ich leider nicht getestet :stupid: :oops:
|
Re: Paint-Messages abfangen
hm also irgendwie weiß ich net so recht....das will alles nicht so.
bei den ersten beiden lösungen seh ich neben der form immmer eine leere eingabeaufforderung. und die von teebee reagiert irgendwie garnicht so recht. weiß net was ich falsch mache :gruebel: ursprünglich dachte ich auch an sowas wie TForm. also dass ich über die klasse TForm irgendwie den Dialog ändern kann wie ich will.. nur wenn das so kompliziert ist, muss ich das wohl leider sein lassen :? gibts da ncihts einfacheres? das mit der farbe ändern war ja nur ein beispiel. das ist eins von vielen sachen die ich vor hatte. ich wollte dann zB das Editfeld usw durch andere komponenten ersetzen oder so. schriftart ändern uswusw... geht das überhaupt? :gruebel: |
Re: Paint-Messages abfangen
Zitat:
|
Re: Paint-Messages abfangen
hab ich mir schon überlegt, aber wie zB mache ich rechts die graue spalte wo Desktop, Eigene Dateien, usw drinne steht?
aber eigetnlich soll der alles können, was der von windows auch kann... ist das net zu umständlich sowas selber zu machen? |
Re: Paint-Messages abfangen
Zitat:
Dann lösche AllocConsole() und es ist weg ... keine Eingabeaufforderung mehr, toll?! :roll: Zitat:
|
Re: Paint-Messages abfangen
ja schön dass nun keine eingabeaufforderung mehr da ist :D aber funzt trotzdem net.
aber is jetzt egal. dann bau ich mir halt eben selbst einen und poste ihn danach mal hier. könnt mir ja dann sagen, ob man das auch mit euren methoden hätte machen können^^ ;) trotzdem nochmal danke! MfG |
Re: Paint-Messages abfangen
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:
Soviel zu "aber funzt trotzdem net" ... |
Re: Paint-Messages abfangen
:gruebel: Ich weiss nicht so recht, wo das Problem ist. Meine Lösung kannst Du einfach in ein Projekt pasten, Formular mit einem Button, OnClick-Event verbinden, fertig. Dann kannst Du von da aus schrittweise Erweiterungen vornehmen. Wie Olli schon gesagt hat, nicht vergessen, CommDlg einzubinden.
Gruß, teebee |
Re: Paint-Messages abfangen
Liste der Anhänge anzeigen (Anzahl: 1)
okay...das wundert mich nun echt. hab das genauso wies im anhang is geht aber net, wenn ichs neu kompiliere... :(
im übringen möchte ich einen "neuen" (oder wie auch immer man das ausdrücken will ;)) OpenDialog. Dieser hier ist mir in einem etwas zu alten Style. Geht das auch? |
Re: Paint-Messages abfangen
Der 'neue' Style heisst Explorer-Style, siehe mein erstes Posting.
Gruß, teebee |
Re: Paint-Messages abfangen
Ah okay. dann probier ichs nochmal so. :)
war mir nicht bewusst, dass das der Explorer Style is :roll: |
Re: Paint-Messages abfangen
Zitat:
EDIT: Übrigens kann es noch Probleme beim Setzen der Struktirgröße geben - NT 4.0 erwartet da eine bestimmte, wobei sizeof() dann nicht mehr funzt. |
Re: Paint-Messages abfangen
Habe gerade festgestellt, dass mein Beispiel ab einschl. Delphi 6 nicht problemlos funktioniert. Ab da wird nämlich eine OPENFILENAME-Strukur verwendet, die zusätzliche Felder beinhaltet (für Windows 2000 aufwärts), u. a. ein Flag zum Ein- und Ausschalten der Places-Bar. Setzt man jetzt die Strukturgröße mit
Delphi-Quellcode:
erkennt Windows, dass man die neue Struktur verwendet und wertet dieses Flag aus, allerdings muss man dann auch unbedingt
ofn.lStructSize := sizeof(ofn);
Delphi-Quellcode:
setzen, damit der Dialog überhaupt erzeugt wird.
ofn.nMaxFile := MAX_PATH; // Länge des Filename-Buffers
Setzt man die Strukturgröße auf
Delphi-Quellcode:
ist Windows nicht so empfindlich und der Dialog wird auch bei nMaxFile := 0 erzeugt, aber es gibt eben auch keine Places-Bar.
ofn.lStructSize := OPENFILENAME_SIZE_VERSION_400; // die Konstante hat den Wert 76
Gruß, teebee |
Re: Paint-Messages abfangen
Zitat:
|
Re: Paint-Messages abfangen
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:53 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