| Autor |
Beitrag |
Steve1024
      
Beiträge: 141
Windows 2K, XP, 7 & Server 2003 - 2008; Linux (Ubuntu, Fedora)
D7, D05, D06, D09, DXE
|
Verfasst: Mi 15.06.11 22:02
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152:
| uses SysUtils, Classes, Forms, Messages, Controls, Windows;
type TExternalForm = class(TWinControl) private FExternalHWND: HWND; private FOldParent: HWND; FOldStyle, FOldExStyle: DWORD; FOldWndProc: Pointer; protected procedure CreateWnd; override; procedure DestroyWindowHandle; override; procedure SetParent(AParent: TWinControl); override; public constructor Create(AOwner: TComponent; AExternalHWND: HWND); reintroduce; procedure DefaultHandler(var Message); override; procedure SetBounds(ALeft, ATop, AWidth, AHeight: Integer); override; property ExternalHWND: HWND read FExternalHWND; end;
implementation
function OnEnumChildProc(hwWindow: HWND; lpParam: Integer): Bool; stdcall; var vOwner: TExternalForm; begin try vOwner := TExternalForm(Pointer(lpParam)); with TExternalForm.Create(vOwner, hwWindow) do begin Parent := vOwner; TabOrder := 0; end; except end; Result := TRUE; end;
constructor TExternalForm.Create(AOwner: TComponent; AExternalHWND: HWND); begin inherited Create(AOwner); FExternalHWND := AExternalHWND;
if (Windows.GetWindowLong(FExternalHWND, GWL_STYLE) AND WS_CLIPCHILDREN) <> 0 then ControlStyle := [csAcceptsControls, csDoubleClicks, csNoStdEvents] else ControlStyle := [csDoubleClicks, csNoStdEvents]; TabStop := (Windows.GetWindowLong(FExternalHWND, GWL_STYLE) AND WS_TABSTOP) <> 0; end;
procedure TExternalForm.CreateWnd; var vParams: TCreateParams; begin if FExternalHWND = 0 then raise Exception.Create('No external window found.');
FOldParent := Windows.GetParent(FExternalHWND); FOldWndProc := Pointer(GetWindowLong(WindowHandle, GWL_WNDPROC)); FOldStyle := Windows.GetWindowLong(FExternalHWND, GWL_STYLE); FOldExStyle := Windows.GetWindowLong(FExternalHWND, GWL_EXSTYLE);
CreateParams(vParams); Windows.SetParent(FExternalHWND, GetParentHandle); Windows.SetWindowLong(FExternalHWND, GWL_STYLE, ((FOldStyle OR vParams.Style OR WS_CHILD) AND NOT (WS_POPUP OR WS_CAPTION))); Windows.SetWindowLong(FExternalHWND, GWL_EXSTYLE, ((FOldExStyle OR vParams.ExStyle OR WS_EX_TOOLWINDOW)));
WindowHandle := FExternalHWND; DefWndProc := Pointer(GetWindowLong(WindowHandle, GWL_WNDPROC)); CreationControl := Self; SetWindowLong(WindowHandle, GWL_WNDPROC, Longint(@InitWndProc)); SendMessage(WindowHandle, WM_NULL, 0, 0);
if not Visible and IsWindowVisible(Handle) then ShowWindow(Handle, SW_HIDE);
EnumChildWindows(FExternalHWND, @OnEnumChildProc, NativeInt(Self)); end;
const OCM_BASE = $2000;
procedure TExternalForm.DefaultHandler(var Message); begin if HandleAllocated then with TMessage(Message) do begin if (Msg >= CN_BASE) and (Msg < CN_BASE + WM_USER) then Msg := Msg - (CN_BASE - OCM_BASE); if not (csAcceptsControls in ControlStyle) then begin Result := CallWindowProc(DefWndProc, Handle, Msg, WParam, LParam); exit; end; end;
inherited DefaultHandler(Message); end;
procedure TExternalForm.DestroyWindowHandle; begin inherited; SetWindowLong(WindowHandle, GWL_WNDPROC, Longint(DefWndProc)); WindowHandle := 0;
Windows.SetWindowLong(ExternalHWND, GWL_WNDPROC, Longint(FOldWndProc)); Windows.SetParent(ExternalHWND, FOldParent); Windows.SetWindowLong(ExternalHWND, GWL_STYLE, FOldStyle); Windows.SetWindowLong(ExternalHWND, GWL_EXSTYLE, FOldExStyle);
CallWindowProc(FOldWndProc, ExternalHWND, WM_SYSCOMMAND, SC_CLOSE , 0); DestroyWindow(ExternalHWND);
FExternalHWND := 0; end;
procedure TExternalForm.SetBounds(ALeft, ATop, AWidth, AHeight: Integer); begin inherited; SetWindowPos(FExternalHWND, 0, ALeft, ATop, AWidth, AHeight, SWP_NOZORDER OR SWP_NOACTIVATE ); end;
procedure TExternalForm.SetParent(AParent: TWinControl); var LRecreate: Boolean; begin LRecreate := HandleAllocated; if LRecreate then UpdateRecreatingFlag(True); try if (Parent = nil) and LRecreate then DestroyHandle; inherited; if Parent <> nil then Windows.SetParent(ExternalHWND, GetParentHandle); finally if LRecreate then UpdateRecreatingFlag(False); end; end; |
Guten Abend Liebe Community,
ich hab mal wieder ein Anliegen. Nachdem ich nun die letzten zwei Tage folgenden Code zusammengestellt habe, bin ich nun in der Lage jede x-beliebige Windows Fenster in mein Programm einzubinden. Sogar TAB finkioniert eins A.
Allerdings muss ich dabei folgendes festellen:
a) DestroyWindow funktioniert nicht mehr, ebenso CloseWindow etc
b) Viselle Themes werden nicht angewendet. Trotz XPMan usw. Wenn ich das Fenster nicht einbinde, bzw das Control freigebe, wird das Fenster so angezeigt wie es sollte
Ansonsten funktioniert das sehr gut. Notepad oder gar Cmd hab ich schon in ein GroupBox eingebunen.
Jetzt hätte ich aber noch gerne, dass es so aussieht wie es soll und dass DestroyWindow klappt.
Hat mir von euch bitte einer eine Idee zu Verbesserung?
Danke!
_________________ - posted with HTC HD2 -
Zuletzt bearbeitet von Steve1024 am Mo 20.06.11 14:48, insgesamt 1-mal bearbeitet
|
|
Steve1024 
      
Beiträge: 141
Windows 2K, XP, 7 & Server 2003 - 2008; Linux (Ubuntu, Fedora)
D7, D05, D06, D09, DXE
|
Verfasst: Fr 17.06.11 19:11
Weiss wirklich keiner Rat?
_________________ - posted with HTC HD2 -
|
|
trm
      
Beiträge: 491
Erhaltene Danke: 19
Windows 7x64
Delphi 7
|
Verfasst: Fr 17.06.11 20:33
Sendmessage sollte funktionieren.
SendMessage(hwnd, WM_SYSCOMMAND, SC_CLOSE, 0);
Tipp für Win x64: www.delphipraxis.net...-64bit-sc_close.html
Gruß Mathias 
_________________ In Erfurt gibt es eine Pension, in der es gemütlich ist, Google einfach nach Pension Fiege
|
|
Steve1024 
      
Beiträge: 141
Windows 2K, XP, 7 & Server 2003 - 2008; Linux (Ubuntu, Fedora)
D7, D05, D06, D09, DXE
|
Verfasst: Fr 17.06.11 22:10
Hallo Mathias,
danke für deinen Tipp. Zum Einen habe ich Win7 64bit und zum Anderen funktioniert leider gar nichts.
Weder SendMessage, PostMessage noch der bereits vorhandene Code CallWindowProc(FOldWndProc, ExternalHWND, WM_SYSCOMMAND, SC_CLOSE , 0);.
Ich kann das Fenster nicht schließen und/oder zerstören. Ich bekomme auch keinen Fehlercode zurück. Erst beim zweiten Aufruf bekomme ich die Meldung, dass das Handle ungültig sei, zurück. Das wäre ja, wenn der erste Aufruf so funktioniert hätte wie er soll, auch richtig. Das Fenster wird durch eine DLL aus meinem eignen Programm erzeugt und kann daher wohl weniger ein Berechtigungsproblem sein.
Im Moment habe ich zudem kein 32bit System um es da zu testen.
Dennoch: Unter 64bit sollte es doch auch gehen, oder nicht?
PS: Das Ding ist in XE entwickelt. Ich hoffe daher doch, dass das HWND 64bit kompatibel ist, oder?
PS*: Zu Guter Letzt noch die Frage bzgl der Themes... Warum werden die Controls immer Nativ dargestellt?
Danke für die Hilfe!
_________________ - posted with HTC HD2 -
|
|
trm
      
Beiträge: 491
Erhaltene Danke: 19
Windows 7x64
Delphi 7
|
Verfasst: Fr 17.06.11 22:19
Probier Dein Tool mal als Admin zu starten.
_________________ In Erfurt gibt es eine Pension, in der es gemütlich ist, Google einfach nach Pension Fiege
|
|
Steve1024 
      
Beiträge: 141
Windows 2K, XP, 7 & Server 2003 - 2008; Linux (Ubuntu, Fedora)
D7, D05, D06, D09, DXE
|
Verfasst: Fr 17.06.11 22:28
Bringt leider auch nichts. Es geht einfach nicht 
_________________ - posted with HTC HD2 -
|
|
Narses
      

Beiträge: 10183
Erhaltene Danke: 1256
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Sa 18.06.11 11:23
Moin!
Bitte ändere den Titel des Topics, da er wenig über das eigentlich Thema verrät. Hier der entsprechende Absatz aus den Richtlinien:
| 1.2 Beiträge: | | Bitte formuliere den Betreff Deiner Beiträge so, dass andere Mitglieder anhand dieser bereits das eigentliche Thema festmachen können. Beiträge wie etwa "Eine Anfängerfrage" oder "Weiß jemand, wie das geht?" lassen den Leser im Unklaren darüber, was das Thema der Diskussion ist.[...] |
Einfach oben bei Deinem ersten Beitrag auf  oder  klicken und den Titel ändern. Danke Dir!
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
Delphi-Laie
      
Beiträge: 1600
Erhaltene Danke: 232
Delphi 2 - RAD-Studio 10.1 Berlin
|
Verfasst: Sa 18.06.11 17:05
Steve1024 hat folgendes geschrieben : | | bin ich nun in der Lage jede x-beliebige Windows Fenster in mein Programm einzubinden. |
Wozu?
Ich fändes es hilfreich, wenn Du wenigstens kurz den Zweck Deines Programmes nennen/vorstellen könntest/würdest.
Steve1024 hat folgendes geschrieben : | | Sogar TAB finkioniert eins A. |
Dito: Wozu und außerdem noch: inwiefern?
|
|
Steve1024 
      
Beiträge: 141
Windows 2K, XP, 7 & Server 2003 - 2008; Linux (Ubuntu, Fedora)
D7, D05, D06, D09, DXE
|
Verfasst: Mo 20.06.11 15:19
Der Zweck ist eigentlich, PlugIns zu entwickeln.
Dabei sollen diese in der Lage sein ein Fenster zu erzeugen was ich dann mittels des HWND in meine Anwenung integriere (zB PageControl).
Dabei ist es wichtig, dass ein Tastatur-Begeisteter User (zB ich) mittels Tab von einem Control zum nächsten springen kann. In der Verganhenheit konnte ich zwar ein Fenster einbinden, aber die TAB Taste hat sich dann immer nur im lokalen Fenster bewegt und nicht auf dem ganzen Fenster Breich (zB TabControl etc).
Dennoch: Schöner Nebenerffekt aktuell ist zB, die CMD in ein Fenster von meiner Anwendung einbinden zu können.
Ich hoffe das war verständlich - und auch dass der Zweck nun klarer ist
Danke!
--- Moderiert von Narses: Beiträge zusammengefasst---
Achja: Hab das mit dem Fenster schließen und SC_Close nun hinbekommen. Bitte nicht fragen wie, denn ich weiss es nicht. Auf einmal ging es.
Auch mit dem Themes bin ich ein wenig weiter gekommen.
Allerdings reagieren die Steuerelemnte immer noch falsch auf Mausereignisse etc. Hat mir da noch einer einen Tipp?
Bis jetzt habe ich: ControlStyle := [csNeedsBorderPaint, csParentBackground] hinzugefügt. Damit geht es schon halb
Danke für die Hilfe!
_________________ - posted with HTC HD2 -
|
|
Steve1024 
      
Beiträge: 141
Windows 2K, XP, 7 & Server 2003 - 2008; Linux (Ubuntu, Fedora)
D7, D05, D06, D09, DXE
|
Verfasst: Mi 29.06.11 20:32
So... nun hab ich fast alles komplett.
Ich nun nur noch ein Problem: Wenn ich eine TForm einbinde, dann hab ich das Problem, dass ich jedes Control auswählen kann - auch TAB geht - aber, wenn ich direkt auf die Form klicke (nicht der Parent oder ein Child davon (zb. Edit); sondern die eigebunde Form bzw Controls die eigentlich nichts machen sollen (zB. Label)), dann spinnt alles.
Das ganze Fenster reagiert dann nicht mehr. Kein Minimieren, Maximieren, Schließen oder jegliche andere Eingabe. Wenn ich dann den Fokus auf eine andere Anwendung/anderes Fenster lege (durch klick) geht das Fenster wieder.
Hat von euch einer eine Idee warum das so ist?
Danke!
_________________ - posted with HTC HD2 -
|
|
|