In Library Messages empfangen [gelöst]
-
- Beiträge: 462
- Registriert: Mi 30. Jul 2008, 13:11
- OS, Lazarus, FPC: WinXP SP3 (L 0.9.28.2 FPC 2.2.4)
- CPU-Target: 32Bit
- Kontaktdaten:
In Library Messages empfangen [gelöst]
Kontext: eine Library unter Windows (DLL), Plattformunabhängigkeit ist in diesem Fall nicht von Bedeutung
Wenn ich mich nicht irre, muss eine Klasse, die (funktionierende) Message-Methoden haben will, auch ein Window-Handle haben, also Nachfahre von TWinControl sein. Nach http://bugs.freepascal.org/view.php?id=7182 scheint aber genau das in Librarys nicht verwendbar. Nun frage ich mich, ob es nicht doch einen Weg gibt, dass man in einer Librarys an Windows-Messages herankommen kann. Bevor ich drauf gekommen bin, dass man Messages mit Message-Methoden empfangen kann, hatte ich glaube mal was von Hooks gelesen. Wenn ich mich recht erinnere, kann ich damit eine Prozedur angeben, in der ich jede Message überprüfen kann, bevor sie an das zum Handle gehörige window ausgeliefert wird. Dazu müsste ich natürlich auch erstmal ein window-Handle haben. Wie komme ich in einer Library an ein Window-Handle? Welche Ideen habt ihr noch? Welche ist die erfolgversprechendste Spur, der ich mich widmen sollte?
Wenn ich mich nicht irre, muss eine Klasse, die (funktionierende) Message-Methoden haben will, auch ein Window-Handle haben, also Nachfahre von TWinControl sein. Nach http://bugs.freepascal.org/view.php?id=7182 scheint aber genau das in Librarys nicht verwendbar. Nun frage ich mich, ob es nicht doch einen Weg gibt, dass man in einer Librarys an Windows-Messages herankommen kann. Bevor ich drauf gekommen bin, dass man Messages mit Message-Methoden empfangen kann, hatte ich glaube mal was von Hooks gelesen. Wenn ich mich recht erinnere, kann ich damit eine Prozedur angeben, in der ich jede Message überprüfen kann, bevor sie an das zum Handle gehörige window ausgeliefert wird. Dazu müsste ich natürlich auch erstmal ein window-Handle haben. Wie komme ich in einer Library an ein Window-Handle? Welche Ideen habt ihr noch? Welche ist die erfolgversprechendste Spur, der ich mich widmen sollte?
Zuletzt geändert von RSE am Mo 7. Dez 2009, 22:00, insgesamt 2-mal geändert.
Seit er seinen neuen Computer hat, löst er alle Probleme, die er vorher nicht hatte!
-
- Beiträge: 3444
- Registriert: Mo 11. Sep 2006, 10:24
- OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
- CPU-Target: X32 / X64 / ARMv5
- Wohnort: Krefeld
Re: In Library Windows-Messages empfangen
AFAIK, kann man zu diesem Zweck "hidden Windows" erzeugen, die niemals sichtbar sind aber Messages empfangen können. Vermutlich tut man das am besten direkt über die entsprechende Windows API und nicht über die LCL.
Ich würde diese Art Kommunikations-Funktionen auf jeden Fall in eine spezielle Unit auslagern, da sie nicht auf Linux portierbar sind.
Möglicherweise ist so etwas aber auch in den Funktionen für Thread-Kommunikation bereits enthalten.
-Michael
Ich würde diese Art Kommunikations-Funktionen auf jeden Fall in eine spezielle Unit auslagern, da sie nicht auf Linux portierbar sind.
Möglicherweise ist so etwas aber auch in den Funktionen für Thread-Kommunikation bereits enthalten.
-Michael
-
- Beiträge: 462
- Registriert: Mi 30. Jul 2008, 13:11
- OS, Lazarus, FPC: WinXP SP3 (L 0.9.28.2 FPC 2.2.4)
- CPU-Target: 32Bit
- Kontaktdaten:
Re: In Library Windows-Messages empfangen
Wie gesagt spielt Plattformunabhängigkeit dabei keine Rolle, weil ich in dieser Library eine DirectShow-Anbindung realisieren möchte. DirectShow ist das Multimediaframework von Windows. Die ganze Library soll also nur für Windows sein, allerdings soll das Library-Interface plattformunabhängig bleiben, damit ich später auch Anbindungen für GStreamer (für Linux) und Quicktime (MacOS) bauen kann.
Ich werde mich jetzt mal damit beschäftigen und melde mich wieder, wenn ich die nächsten Problemchen, die schon in Sicht sind, formulieren kann
Gibt es auf anderen Betriebssystemen eigentlich auch Window-Handles wie in Windows? Gibt es auch Messages? Gibt es eine Seite, auf der man sich belesen kann, wo Plattformabhänigkeit beginnt (bzgl. Handles und Messages und sowas, natürlich keine API-Aufrufe, das ist klar)?
Ich werde mich jetzt mal damit beschäftigen und melde mich wieder, wenn ich die nächsten Problemchen, die schon in Sicht sind, formulieren kann

Gibt es auf anderen Betriebssystemen eigentlich auch Window-Handles wie in Windows? Gibt es auch Messages? Gibt es eine Seite, auf der man sich belesen kann, wo Plattformabhänigkeit beginnt (bzgl. Handles und Messages und sowas, natürlich keine API-Aufrufe, das ist klar)?
Seit er seinen neuen Computer hat, löst er alle Probleme, die er vorher nicht hatte!
-
- Beiträge: 3444
- Registriert: Mo 11. Sep 2006, 10:24
- OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
- CPU-Target: X32 / X64 / ARMv5
- Wohnort: Krefeld
Re: In Library Windows-Messages empfangen
Bei Linux ist das Thema komplexer, weil das System, in dem deine Anwendung läuft ja nicht nur aus Linux (dem Kernel) besteht, sondern Du vermutlich ja auch ein Darstellungs-System (X), ein Windowing-System (KDE, Gnome) und eine Widget-System (GTK) verwendest, die alle eigene Interfaces haben. Mindestens der Kernel und KDE stellen Messaging zur Verfügung. Beim Kernel z.B. "Signals", "System V Messages" und "Pipes", oft wird aber auch TCP/IP Rechner-intern verwendet, was (im Gegensatz zu Windows-internem TCP/IP) sehr performant ist. Bei KDE/GNOME und GTK etc. kenne ich mich nicht aus.
-Michael
-Michael
-
- Beiträge: 462
- Registriert: Mi 30. Jul 2008, 13:11
- OS, Lazarus, FPC: WinXP SP3 (L 0.9.28.2 FPC 2.2.4)
- CPU-Target: 32Bit
- Kontaktdaten:
Re: In Library Windows-Messages empfangen
WOW Also so ´ne Art Schichtenarchitektur, unterste Schicht ist der Kernel, dann X, dann ein Windowing System (Gnome oder KDE) und dann das Widget-Set (GTK, GTK2, QT). MacOS ist ja soweit ich weiß auch ein Linux-Derivat, so dass es dann genau die gleiche Architektur hat, nur als Widgetset dann Carbon oder Cocoa.
Nun will ja Lazarus genau davon abstrahieren, aber genau diese Funktionen sind wahrscheinlich eben nicht kompatibel mit den Bibliotheken, wenn ich das richtig sehe. Woran erkenne ich denn, wenn ich auf eine Plattformabhängige Eigenschaft zugreife? Ist THandle schon plattformabhängig? Das nächste Problem wird sein, ein Videofenster "einzufangen" und in meine Form zu integrieren. Dazu würde ich am liebsten irgendwie in der Biliothek das Fenster so an das Interface übergeben, dass es plattformunabhängig von der GUI in Empfang genommen werden kann. Sicherlich keine allzu einfache Aufgabe, vor allem wenn man nicht weiß, welche (Windowing-)Funktionen denn nun in Librarys sicher und plattformübergreifend verwendbar sind.
Nun will ja Lazarus genau davon abstrahieren, aber genau diese Funktionen sind wahrscheinlich eben nicht kompatibel mit den Bibliotheken, wenn ich das richtig sehe. Woran erkenne ich denn, wenn ich auf eine Plattformabhängige Eigenschaft zugreife? Ist THandle schon plattformabhängig? Das nächste Problem wird sein, ein Videofenster "einzufangen" und in meine Form zu integrieren. Dazu würde ich am liebsten irgendwie in der Biliothek das Fenster so an das Interface übergeben, dass es plattformunabhängig von der GUI in Empfang genommen werden kann. Sicherlich keine allzu einfache Aufgabe, vor allem wenn man nicht weiß, welche (Windowing-)Funktionen denn nun in Librarys sicher und plattformübergreifend verwendbar sind.
Seit er seinen neuen Computer hat, löst er alle Probleme, die er vorher nicht hatte!
-
- Beiträge: 462
- Registriert: Mi 30. Jul 2008, 13:11
- OS, Lazarus, FPC: WinXP SP3 (L 0.9.28.2 FPC 2.2.4)
- CPU-Target: 32Bit
- Kontaktdaten:
Re: In Library Messages empfangen und Windows zurückgeben
Also ich hab jetzt ein bissl gesucht und gefunden, dass man mit dem WinAPI-Aufruf CreateWindow (http://msdn.microsoft.com/en-us/library ... 85%29.aspx) ein Fenster erstellen kann. In meinem Fall bietet sich wohl Static oder Message an (http://msdn.microsoft.com/en-us/library ... spx#system). Wie finde ich die verwendete Windows-Version heraus, um zwischen Static und Message zu entscheiden? Mit der Einbindung der Unit Windows kann man CreateWindow verwenden, aber ich weiß nicht so recht, was ich da übergeben soll...
Nach weiterer Suche bin ich auf AllocateHWND gestoßen, dass es in Delphi genau für meinen Zweck gibt. Leider ist es in Lazarus offenbar nicht implementiert.
Wie komme ich an so ein Fenster, um Messages empfangen zu können?
Nach weiterer Suche bin ich auf AllocateHWND gestoßen, dass es in Delphi genau für meinen Zweck gibt. Leider ist es in Lazarus offenbar nicht implementiert.
Wie komme ich an so ein Fenster, um Messages empfangen zu können?
Seit er seinen neuen Computer hat, löst er alle Probleme, die er vorher nicht hatte!
-
- Beiträge: 462
- Registriert: Mi 30. Jul 2008, 13:11
- OS, Lazarus, FPC: WinXP SP3 (L 0.9.28.2 FPC 2.2.4)
- CPU-Target: 32Bit
- Kontaktdaten:
Re: In Library Messages empfangen und Windows zurückgeben
Ich werd mir wohl das Handle vom MainWindow übergeben lassen und einen Hook setzen. Dann kann ich DirectShow die Messages an das MainWindow schicken lassen und sie mit dem Hook abfangen. Das ist zwar echt keine schöne Lösung, aber bei der weiß ich, wie ich es zu implementieren hab. Für Hilfe bei der Erzeugung eines Windows direkt in der Library bin ich natürlich immer dankbar und werde es dann umbauen, wenn mir die Umsetzung gelingt.
Seit er seinen neuen Computer hat, löst er alle Probleme, die er vorher nicht hatte!
-
- Beiträge: 3444
- Registriert: Mo 11. Sep 2006, 10:24
- OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
- CPU-Target: X32 / X64 / ARMv5
- Wohnort: Krefeld
Re: In Library Messages empfangen und Windows zurückgeben
MacOS basiert auf BSD und das ist wie Linux ein Unix-Derivat.
X ist eine Applikation, die neben den anderen Applikationen läuft und Grafik-Darstellungs-Aufträge von ihnen erhält. Dabei werden keine Fenster verwaltet. X wird über TCP/IP angesprochen und muss nicht auf demselben Rechner laufen wie die Anwenderprogramme. Es gibt auch X-Server-Programme, die auf Windows-Rechnern laufen.
Das Windowing -System ist ein permanent laufendes Programm und organisiert die die Window-Darstellung für die Anwender-Programme.
Das Widget-System ist (wenn ich das richtig sehe) eine Library, also Unterprogramm-Sammlung.
-Michael
X ist eine Applikation, die neben den anderen Applikationen läuft und Grafik-Darstellungs-Aufträge von ihnen erhält. Dabei werden keine Fenster verwaltet. X wird über TCP/IP angesprochen und muss nicht auf demselben Rechner laufen wie die Anwenderprogramme. Es gibt auch X-Server-Programme, die auf Windows-Rechnern laufen.
Das Windowing -System ist ein permanent laufendes Programm und organisiert die die Window-Darstellung für die Anwender-Programme.
Das Widget-System ist (wenn ich das richtig sehe) eine Library, also Unterprogramm-Sammlung.
-Michael
-
- Beiträge: 3444
- Registriert: Mo 11. Sep 2006, 10:24
- OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
- CPU-Target: X32 / X64 / ARMv5
- Wohnort: Krefeld
Re: In Library Messages empfangen und Windows zurückgeben
Für private Zwecke kannst Du den Code für AllocateHWND aus der Delphi-VCL klauen. Das sind doch vermutlich nur ein paar Zeilen.RSE hat geschrieben:Nach weiterer Suche bin ich auf AllocateHWND gestoßen, dass es in Delphi genau für meinen Zweck gibt. Leider ist es in Lazarus offenbar nicht implementiert.
Wie komme ich an so ein Fenster, um Messages empfangen zu können?
-Michael
-
- Beiträge: 462
- Registriert: Mi 30. Jul 2008, 13:11
- OS, Lazarus, FPC: WinXP SP3 (L 0.9.28.2 FPC 2.2.4)
- CPU-Target: 32Bit
- Kontaktdaten:
Re: In Library Messages empfangen und Windows zurückgeben
Hm, so wie es ist klauen wohl eher nich, aber wenn ich es verstehe, kann ich ja ähnliches selbst proggen, allerdings hab ich die VCL-Sources nicht verfügbar. Falls du sie verfügbar hast, wäre ich dir äußerst verbunden, wenn du sie mir zukommen lassen könntest. Falls es hier öffentlich im Forum zu rechtlichen Probs führe könnte, dann vielleicht per PM, aber es geht ja nicht um ein Klauen der Implementation, sondern um die Diskussion eines Beispiels. Sorry, aber ich komm da ohne Hilfe echt nicht weiter. Nach Message und Window lässt sich echt besch... googeln!mschnell hat geschrieben:Für private Zwecke kannst Du den Code für AllocateHWND aus der Delphi-VCL klauen.
Ich habe jetzt aber noch ein paar Infos, womit ich mir folgendes zusammengebastelt habe, was zumindest der Compiler erst einmal nicht anmeckert (Ich hab keine Ahnung, ob die Werte, die ich da übergebe tatsächlich so übergeben werden sollen):
Code: Alles auswählen
var
HWindow: HWND;
begin
HWindow := CreateWindow(PChar('Static'),PChar(''),WS_DISABLED,0,0,0,0,0,0,HINSTANCE,nil);
Seit er seinen neuen Computer hat, löst er alle Probleme, die er vorher nicht hatte!
-
- Beiträge: 2013
- Registriert: Do 16. Okt 2008, 10:22
- OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
- CPU-Target: x86,x64,ARM
Re: In Library Messages empfangen und Windows zurückgeben
WindowProcedure wird in RegisterClass() als lpfnWndProc in der WNDCLASS Struktur übergeben oder mit SetWindowLong() mit GWL_WNDPROC gesetzt. MSEgui Beispiel: lib/common/kernel/i386-win32/mseguiintf.pas gui_init() Funktion.RSE hat geschrieben: In der Doku im MSDN steht "Before returning, CreateWindow sends a WM_CREATE message to the window procedure.", allerdings wird mit CreateWindow gar keine solche Procedure übergeben! Wie soll ich diese Message empfangen? Wie gebe ich eine WindowProcedure an? Offenbar steckt das alles irgendwie in der Klasse "Static" drin, die ich irgendwie vorher wohl noch ableiten muss oder so, um meinen eigenen Message-Handler zu schreiben...
http://mseide-msegui.svn.sourceforge.ne ... 386-win32/
Martin
-
- Beiträge: 3444
- Registriert: Mo 11. Sep 2006, 10:24
- OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
- CPU-Target: X32 / X64 / ARMv5
- Wohnort: Krefeld
Re: In Library Messages empfangen und Windows zurückgeben
In meinen (nicht ganz aktuellen) LCL- und FPC- Sourcen gibt es durchaus eine (oder mehrere) Implementierung von AllocateHWND. Such 'mal nach AllocateHWND in allen *.pas, *.pp und *.inc - Dateien !RSE hat geschrieben:Nach weiterer Suche bin ich auf AllocateHWND gestoßen, dass es in Delphi genau für meinen Zweck gibt. Leider ist es in Lazarus offenbar nicht implementiert.
-Michael
-
- Beiträge: 462
- Registriert: Mi 30. Jul 2008, 13:11
- OS, Lazarus, FPC: WinXP SP3 (L 0.9.28.2 FPC 2.2.4)
- CPU-Target: 32Bit
- Kontaktdaten:
Re: In Library Messages empfangen und Windows zurückgeben
Sorry, hab die letzten Tage leider nix machen können, uns ist das Aquarium kaputt gegangen. Zum Glück nur gerissen und nicht geplatzt, so haben wir das Wasser noch ablassen können. Wir hatten sogar noch ein leeres kleines 80l-Becken für die Fische rumstehen. Ich hoffe ihr hattet einen erfreulicheren Nikolaustag...
Ich hab mir jetzt was zusammengebastelt, das allem Anschein nach funktioniert. Die Sourcen von mse sind mir allerdings ein bissl zu schwierig gewesen, ich hab mich größtenteils an http://www.delphipraxis.net/post1107527.html orientiert. Hier das Ergebnis:
Falls es noch Verbesserungsvorschläge gibt, dann immer her damit! 
Ich hab mir jetzt was zusammengebastelt, das allem Anschein nach funktioniert. Die Sourcen von mse sind mir allerdings ein bissl zu schwierig gewesen, ich hab mich größtenteils an http://www.delphipraxis.net/post1107527.html orientiert. Hier das Ergebnis:
Code: Alles auswählen
program project1;
...
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Windows;
...
var
MyHandle: HWND;
MyClass: TWndClass;
function MyWndProc(Handle:HWND; MyMsg:UINT; _MyWParam:WPARAM; MyLParam:LPARAM): LRESULT; stdcall;
begin
case MyMsg of
WM_GETMINMAXINFO: Result := 0; // maximized Size
WM_NCCREATE: Result := 1;
WM_CREATE: Result := 0;
WM_NCCALCSIZE: Result := 0; // Resize
WM_NCDESTROY: Result := 0;
WM_DESTROY: Result := 0;
else // die behandelten Messages treten alle auf, weitere nicht
Result := 0;
end;
end;
begin
MyClass.lpfnWndProc := @MyWndProc;
MyClass.lpszClassName := PChar('TMyClass');
MyClass.hInstance := HInstance;
if RegisterClass(MyClass) = 0 then
Exit;
try
MyHandle := CreateWindow(PChar('TMyClass'),PChar(''),WS_DISABLED,0,0,0,0,0,0,HInstance,nil);
if MyHandle = 0 then
Exit;
DestroyWindow(MyHandle);
finally
UnregisterClass(PChar('TMyClass'),HInstance);
end;
end.

Seit er seinen neuen Computer hat, löst er alle Probleme, die er vorher nicht hatte!
-
- Beiträge: 462
- Registriert: Mi 30. Jul 2008, 13:11
- OS, Lazarus, FPC: WinXP SP3 (L 0.9.28.2 FPC 2.2.4)
- CPU-Target: 32Bit
- Kontaktdaten:
Re: In Library Messages empfangen und Windows zurückgeben
Hm, das ist ja fast genau so wie bei mir implementiert, scheint wohl nicht ganz falsch zu sein :-p Danke!
Ich habe meine Implementierung entsprechend angepasst:
Ich kenne zwar nicht den genauen Grund, warum WS_EX_TOOLWINDOW und WS_POPUP verwendet werden soll, aber die Lazarus-Entwickler wissen schon, was sie tun.
Vielen Dank an alle Helfer!
Ich habe meine Implementierung entsprechend angepasst:
Code: Alles auswählen
program project1;
...
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Windows;
...
var
MyHandle: HWND;
MyClass: TWndClass;
function MyWndProc(Handle:HWND; MyMsg:UINT; _MyWParam:WPARAM; MyLParam:LPARAM): LRESULT; stdcall;
//var
// MyInstance: TMyInstance;
begin
// MyInstance := TTMyInstance(GetWindowLongPtr(HWindow,GWL_USERDATA)); // Ist für die Integration in Klassen sehr hilfreich <<<<< hier
case MyMsg of
WM_NCCREATE: Result := 1;
WM_NCCALCSIZE: Result := 0; // Resize
WM_CREATE: Result := 0;
WM_SIZE: Result := 0; // <<<<< hier
WM_MOVE: Result := 0; // <<<<< hier
WM_GETMINMAXINFO: Result := 0; // maximized Size <<<<< tritt jetzt nicht mehr auf, dafür alle anderen in dieser Reihenfolge
WM_DESTROY: Result := 0;
WM_NCDESTROY: Result := 0;
else // weitere Messages treten nicht auf
Result := 0;
end;
end;
begin
Pointer(MyClass.lpfnWndProc) := @MyWndProc; // <<<<< hier
MyClass.lpszClassName := PChar('TMyClass');
MyClass.hInstance := HInstance;
if RegisterClass(MyClass) = 0 then
Exit;
try
MyHandle := CreateWindowEx(WS_EX_TOOLWINDOW,PChar('TMyClass'),PChar(''),WS_POPUP,0,0,0,0,0,0,HInstance,nil); // <<<<< hier
if MyHandle = 0 then
Exit;
// SetWindowLongPtr(MsgWinHandle,GWL_USERDATA,PtrInt(Self)); // Ist für die Integration in Klassen sehr hilfreich <<<<< hier
DestroyWindow(MyHandle);
finally
UnregisterClass(PChar('TMyClass'),HInstance);
end;
end.
Vielen Dank an alle Helfer!
Seit er seinen neuen Computer hat, löst er alle Probleme, die er vorher nicht hatte!