[WINAPI] Transparentes Fenster / Rahmen

Programmiersprachen, APIs, Bibliotheken, Open Source Engines, Debugging, Quellcode Fehler und alles was mit praktischer Programmierung zu tun hat.
Antworten
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

[WINAPI] Transparentes Fenster / Rahmen

Beitrag von BeRsErKeR »

Hallo,

ich möchte ein Programm schreiben welches Rahmen um bestimmte Controls (Buttons, Fenster, Labels, etc -> HWND) von anderen Programmen zeichnet. Das ganze wird eine Art Spy++ falls das wer kennt. Ich muss notgedrungen direkt mit der WINAPI arbeiten, also keine externen Libs und auch nicht MFC oder ähnliches. Zur Verfügung steht mir dabei auch nur die Express Version vom Visual Studio 2008. Programmieren möchte ich mit C/C++.

Ziel ist es mit der Maus über Controls eines anderen Programm zu fahren und wenn ein Control unter der Maus ist einen Rahmen um dieses zeichnen und einen Dialog anzeigen (oder einen Tooltip) der die Control-ID und ein paar andere Infos anzeigt.

Wie ich an die Fenster-Handles rankomme weiß ich. Auch wie ich die Informationen auslese usw. Die Frage ist nun wie kann ich das mit dem Rahme realisieren. Ich weiß z.B. von Tools wie SnagIt usw. dass es möglich ist.

Meine Ideen:

1. In den Prozess des Zielprogramms einklinken, z.B. mit GetWindowThreadProcessId + OpenProcess + CreateRemoteThread usw. Und dort die WindowProc durch eine eigene überschreiben und Zusatzfunktionen für das Rahmenzeichnen einbauen.
2. Ein "transparentes" Fenster nutzen, welches den Rahmen zeichnet.


Zu 1.: Erstens würde ich nur ungern in fremde Prozesse eingreifen und zweitens besitze ich nicht die nötigen Zugriffsrechte um z.B. einen Remote Thread im Prozess zu erstellen. Auch das Setzen von SeDebugPrivilege brachte keinen Erfolg.

Zu 2.: Hier sehe ich das Problem darin, dass ich das Fenster immer im Vordergrund halten muss und dahinterliegende Anwendungen nicht mehr bedienbar sind. Bzw. ich wüsste nicht wie ich Messages, die ich nicht abfangen muss bzw. abgefangen habe an darunterliegende Anwendungen weitergeben kann.


Ich würde gern wissen wie soetwas gemacht werden könnte, vom Prinzip her.

Darüber dass man solche Tools nicht schreiben sollte müssen wir nicht diskutieren. Es ist nötig und wird nur von mir genutzt und soll halt eine Art erweitertes Spy++ sein um mir eine Menge Arbeit zu ersparen.
Ohne Input kein Output.
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: [WINAPI] Transparentes Fenster / Rahmen

Beitrag von dot »

Evtl. reicht es dir, den Rahmen einfach direkt auf den Bildschirm (CreateDC(TEXT("DISPLAY"), nullptr, nullptr, nullptr)) zu malen!?
Ansonsten solltest du mit GetDC() bzw GetWindowDC() aber auch einfach an einen entsprechenden DC für das jeweilige Fenster kommen und kannst dann den Rahmen reinmalen...
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: [WINAPI] Transparentes Fenster / Rahmen

Beitrag von BeRsErKeR »

dot hat geschrieben:Evtl. reicht es dir, den Rahmen einfach direkt auf den Bildschirm (CreateDC(TEXT("DISPLAY"), nullptr, nullptr, nullptr)) zu malen!?
Ansonsten solltest du mit GetDC() bzw GetWindowDC() aber auch einfach an einen entsprechenden DC für das jeweilige Fenster kommen und kannst dann den Rahmen reinmalen...
Zur ersten Idee: Werd ich mal testen.

Zur zweiten Idee: Ich weiß nicht inwiefern ich von außen da zugreifen kann. Informationen auslesen, ja, aber Controls neu zeichnen etc? Bezweifle ich doch stark. Ich hatte es mal über GetDC() versucht und manuell was reingemalt. Das wurde aber nicht angezeigt. Ich kann ja z.B. auch keine WM_PAINT-Nachrichten abfangen bzw. verarbeiten. Kann aber sein, dass ich was vergessen habe.

Ich hatte InvalidateRect, UpdateWindow, BeginPaint/EndPaint, usw in allen möglichen Kombinationen getestet. Angezeigt wurde nichts. Mir wär es allerdings auch lieber nicht direkt im anderen Programm rumzumalen. Wenn mein Programm dann mal abschmiert etc. bleibt der Rahmen dann da oder ähnliches.

Danke erstmal für die Antwort. Morgen probier ich mal noch etwas weiter.
Ohne Input kein Output.
Andre
Establishment
Beiträge: 186
Registriert: 21.12.2011, 20:33

Re: [WINAPI] Transparentes Fenster / Rahmen

Beitrag von Andre »

Vielleicht sind Layered Windows was du brauchst. Ich habe mich mal ein wenig zurück erinnert, und sogar die Seite gefunden, auf der ein ähnliches Problem angegangen wurde.
Dort geht es zwar darum, wie man Schatten unter ein Fenster bekommt, aber Transparent müssen die auch sein. Außerdem soll man "durch sie durch" klicken können.
http://www.codeproject.com/KB/dialog/FrameShadow.aspx

Ich habe mich auch schnell in den Sourcecode einlesen können:
Transparenz bekommt dein Fenster mit dem WS_EX_LAYERED flag. Wie das genau geht musst du dir aber noch selber raussuchen ;)
Um um das Fenster hindurchklicken zu können setzt du einfach das WS_EX_TRANSPARENT flag.
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: [WINAPI] Transparentes Fenster / Rahmen

Beitrag von BeRsErKeR »

Vielen Dank das klingt sehr vielversprechend. Ein Problem habe ich allerdings noch. Ich muss irgendwie die WM_MOUSEMOVE-Message abfangen. Am besten für das Fenster, dass ich untersuchen will, allerdings komm ich da nicht an die WindowProc ran. Ich hab nun versucht das ganze über das DesktopWindow zu machen. Da kann ich die WindowProc überschreiben und die Nachricht abfangen. Allerdings geht das halt nur wenn sich kein anderes Fenster über dem Desktop befindet und genau das möchte ich ja.

Eine weitere Möglichkeit wäre ein transparentes Fenster (nicht WS_EX_TRANSPARENT!) über den gesamten Desktop was immer im Vordergrund bleibt und die Nachricht verarbeitet. Die Frage ist dann aber wie ich dann rausbekomme über welchem Control sich die Maus im Zielfenster (darunterliegend) befindet.

Hat da jemand eine Idee?
Ohne Input kein Output.
Andre
Establishment
Beiträge: 186
Registriert: 21.12.2011, 20:33

Re: [WINAPI] Transparentes Fenster / Rahmen

Beitrag von Andre »

Was möchtest du denn mit der WM_MOUSEMOVE anstellen? Kannst du das nicht auch per GetCursorPos() in deiner Hauptschleife abfragen?
(Auch wenn das natürlich etwas unschön ist, es funktioniert aber ;) )
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: [WINAPI] Transparentes Fenster / Rahmen

Beitrag von BeRsErKeR »

Ich habs über eine globale HookProc gelöst. Dafür muss ich zwar eine Extra-DLL anlegen aber das ist kein Beinbruch. Dadurch kann ich Messages abfangen, bevor sie an das Programm gehen. Prinzipiell hackt man sich damit zwar auch in den Prozessraum des Programms aber man muss nicht direkt mit irgendwelchen programminternen Prozessen/Threads rumspielen.

Bislang klappt schonmal alles ganz gut. Ich habe nun allerdings den Weg eingeschlagen kein transparentes Fenster zu nutzen, sondern zeichne die Rahmen direkt ins Zielprogramm. Vorher hatte ich es mit GetDC(NULL) probiert was auch ging, allerdings ist das dann nicht der DC des Desktopwindows, sondern des primären Displays und da kann man irgendwie nicht wirklich InvalidateRect usw für nutzen wenn man Rahmen wieder verschwinden lassen will, bzw. man kann nur den gesamten Screen neu zeichnen und das flackert.

Jedenfalls zeichne ich nun direkt einen Rahmen über das jeweilige Fenster unter dem Cursor. Das Problem ist nun, dass der Rahmen wieder weg muss, wenn ein anderes Fenster unterm Cursor ist oder gar kein Fenster (Desktop). Vom Prinzip her kein Problem, nur brachten weder RedrawWindow, noch InvalidateRect, noch UpdateWindow (bzw. Kombinationen aus diesen) einen Erfolg. Manchmal klappt es kurz für einige Fenster, meistens bleibt der Rahmen oder wenigstens Teile davon erhalten. Selbst wenn ich das gesamte Applikationsfenster neuzeichne (RedrawWindow) und das Flag RDW_ALLCHILDREN setze (und auch RDW_UPDATENOW, RDW_ERASENOW, RDW_INVALIDATE und/oder RDW_ERASE) bleiben teilweise Rahmen vorhanden.

In vielen Foren hab ich gelesen, dass es so gehen sollte und scheinbar oft auch funktioniert. Aber irgendwie scheint es bei mir nicht so recht zu klappen. Ich sehe aber gerade, dass RDW_FRAME mein Problem lösen könnte. Das werde ich mal ausprobieren. Der Rahmen ist in der Regel über den Fenster-Rahmen gezeichnet und bei Buttons etc funktioniert es schon problemlos.

Andre hat geschrieben:Was möchtest du denn mit der WM_MOUSEMOVE anstellen? Kannst du das nicht auch per GetCursorPos() in deiner Hauptschleife abfragen?
(Auch wenn das natürlich etwas unschön ist, es funktioniert aber ;) )
Naja dafür muss ich ja eine Art von Polling nutzen (von mir aus mit Hilfe eines Timers), weil sonst weiß ich nicht wirklich wann sich die Maus bewegt. Da find ich das mit der HookProc schon besser. Letztlich nutze ich sogar GetCursorPos, aber lasse das Event halt durch die WM_MOUSEMOVE-Message des Zielfensters auslösen. Hooks werd ich eh noch brauchen, weil ich z.B. auch auf das Minimieren oder Verschieben des Zielfensters reagieren muss (Rahmen ausblenden oder mitverschieben).
Ohne Input kein Output.
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: [WINAPI] Transparentes Fenster / Rahmen

Beitrag von dot »

Warum kannst du nicht einfach GetDC(Zielfenster) machen und dann dort reinmalen?
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: [WINAPI] Transparentes Fenster / Rahmen

Beitrag von BeRsErKeR »

dot hat geschrieben:Warum kannst du nicht einfach GetDC(Zielfenster) machen und dann dort reinmalen?
Das mache ich doch. Nur kann man über den DC nicht wirklich gezeichnete Dinge einfach so wieder löschen. Ein FillRect oder ähnliches kommt nicht in Frage, denn der Inhalt soll ja so sein, wie er vom eigentlichen Programm gezeichnet wurde. Der eigentliche Weg geht über InvalidateRect, aber das klappt halt auch nicht.

Das Zeichnen des Rahmens ist wie gesagt kein Problem und auch nicht die Positionierung oder das Abfangen der Mausevents.

Es geht wirklich nur darum, den gezeichneten Rahmen wieder zu löschen und zwar nur diesen. Ich möchte nicht alle Childs des Hauptfensters neuzeichnen, wenn der Rahmen eines bestimmten Controls weg soll.
Ohne Input kein Output.
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: [WINAPI] Transparentes Fenster / Rahmen

Beitrag von dot »

BeRsErKeR hat geschrieben:
dot hat geschrieben:Warum kannst du nicht einfach GetDC(Zielfenster) machen und dann dort reinmalen?
Das mache ich doch. Nur kann man über den DC nicht wirklich gezeichnete Dinge einfach so wieder löschen. Ein FillRect oder ähnliches kommt nicht in Frage, denn der Inhalt soll ja so sein, wie er vom eigentlichen Programm gezeichnet wurde. Der eigentliche Weg geht über InvalidateRect, aber das klappt halt auch nicht.
Aber dafür solltest du keine Hooks oder sonstwas brauchen!? Oder brauchst du die nur zum Abfangen der Mausbewegung?
Was mich eben verwirrt ist, dass du von GetDC(NULL) sprichst, was dir aber schon das Desktop Window gibt. Wenn du das Display willst, musst du CreateDC() verwenden und ich meinte GetDC(Handle_zum_Parent_des_Fensters_wo_ein_Rahmen_drum_herum_soll).
Sendest du InvalidateRect() direkt an das jeweilige Fenster oder suchst du dir erst dessen top-level Parent (GetAncestor(hWnd, GA_ROOT))? Ich würds mal an letzteren senden ;)
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: [WINAPI] Transparentes Fenster / Rahmen

Beitrag von BeRsErKeR »

dot hat geschrieben:
BeRsErKeR hat geschrieben:
dot hat geschrieben:Warum kannst du nicht einfach GetDC(Zielfenster) machen und dann dort reinmalen?
Das mache ich doch. Nur kann man über den DC nicht wirklich gezeichnete Dinge einfach so wieder löschen. Ein FillRect oder ähnliches kommt nicht in Frage, denn der Inhalt soll ja so sein, wie er vom eigentlichen Programm gezeichnet wurde. Der eigentliche Weg geht über InvalidateRect, aber das klappt halt auch nicht.
Aber dafür solltest du keine Hooks oder sonstwas brauchen!? Oder brauchst du die nur zum Abfangen der Mausbewegung?
Die Hooks nutze ich um festzustellen, wann sich die Maus über dem Zielfenster bewegt, wann das Fenster minimiert wird oder wann es verschoben wird. Die Hooks generieren einfach nur Event-Messages und senden sie an mein Programm, woraufhin dieses dann eine entsprechende Funktion ausführt (z.B. Zeichnen des Rahmens). Innerhalb der MouseHook muss ich nicht mal die Mausposition abfangen, es dient eher als Event-Erfassung.

dot hat geschrieben:Was mich eben verwirrt ist, dass du von GetDC(NULL) sprichst, was dir aber schon das Desktop Window gibt. Wenn du das Display willst, musst du CreateDC() verwenden und ich meinte GetDC(Handle_zum_Parent_des_Fensters_wo_ein_Rahmen_drum_herum_soll).
Ich hatte es mal mit GetDC(NULL) versucht und dieses gibt eben nicht den DC für das Desktop Window zurück, wie es GetDC(GetDesktopWindow()) tun würde. Das sind 2 paar Schuhe. GetDC(NULL) gibt den DC des primären Displays zurück, sodass man über alles malen kann. Über das Desktop Window zu malen würde eh nicht viel bringen, da dieses ja hinter den anderen Fenstern liegt. Die Variante war mir aber zu krass und vorallem kann man wie gesagt nicht wirklich ein InvalidateRect auf das primäre Display machen. ChangeDisplaySettings(0, 0) ging dafür zwar, allerdings halt nur für den gesamten Screen und das will ich nicht machen um einen kleinen Rahmen irgendwo zu löschen. Flackert halt wie sau.

dot hat geschrieben:Sendest du InvalidateRect() direkt an das jeweilige Fenster oder suchst du dir erst dessen top-level Parent (GetAncestor(hWnd, GA_ROOT))? Ich würds mal an letzteren senden ;)
Ich hatte beides versucht auch in Kombination und mit der verschärften Variante (GetAncestor(hWnd, GA_ROOTOWNER)). Es hatte nicht viel gebracht.


Ich habe es nun aber hinbekommen mit RedrawWindow, indem ich RDW_FRAME und RDW_ALLCHILDREN hinzugenommen habe (nun sind quasi alle Flags aktiv). Das funktioniert auch wie es sein sollte.


Ich habe nun allerdings noch eine Frage, die nicht unbedingt was mit dem Zeichnen zu tun hat.

Und zwar liegen die ganzen Dialoge der Zielanwendung als Resourcen vor, die in etlichen verschiedenen DLLs eingebettet sind. Mein "Spy" soll nun rausfinden, aus welcher DLL ein bestimmtes Control ist (bzw. die zugrundeliegende Resource). Ist das irgendwie möglich?

Ich hab mir bislang die ProcessID des Controls geholt und alle Module des Prozesses aufgelistet (EnumProcessModules). Da sind allerdings alle DLLs drin, vermutlich weil es halt nur einen Prozess gibt oder ähnliches. Nun hatte ich die Idee rauszufinden welche Resource vom Control bzw. des Eltern-Dialogs verwendet wird und darüber eventuell das ModuleHandle rauszukriegen. Zur Not würde ich auch alle geladenen Module nach der Resource (FindResource) durchsuchen, was natürlich unschön wäre aber es ist halt notwendig.

Ich hab leider noch keine Möglichkeit gefunden, die Resource rauszufinden und habe fast die Befürchtung, dass man das nicht rausbekommt. Hat da jemand eine Idee?
Ohne Input kein Output.
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: [WINAPI] Transparentes Fenster / Rahmen

Beitrag von BeRsErKeR »

Mein Ansatz war nun:

1. Den Eltern-Dialog ermitteln
2. Alle Module des Prozesses des Zielfensters ermitteln
3. Die Resource in jedem Modul suchen:
  • Name: MAKEINTRESOURCE(GetDlgCtrlID(<Eltern-Dialog>))
  • Type: MAKEINTRESOURCE(5) bzw. RT_DIALOG
4. Bei einem Fund den Namen des Moduls zurückgeben
5. Bei keinem Fund den Namen des ersten Moduls zurückgeben (Hauptprogramm -> .exe)


Es scheitert allerdings an 3., die Resource wird nicht gefunden. Ich vermute dass der Resourcenname wohl nicht ganz so einfach erstellt werden kann.
Ohne Input kein Output.
Helmut
Establishment
Beiträge: 237
Registriert: 11.07.2002, 15:49
Wohnort: Bonn
Kontaktdaten:

Re: [WINAPI] Transparentes Fenster / Rahmen

Beitrag von Helmut »

BeRsErKeR hat geschrieben:Ich hatte es mal mit GetDC(NULL) versucht und dieses gibt eben nicht den DC für das Desktop Window zurück, wie es GetDC(GetDesktopWindow()) tun würde. Das sind 2 paar Schuhe. GetDC(NULL) gibt den DC des primären Displays zurück, sodass man über alles malen kann. Über das Desktop Window zu malen würde eh nicht viel bringen, da dieses ja hinter den anderen Fenstern liegt. Die Variante war mir aber zu krass und vorallem kann man wie gesagt nicht wirklich ein InvalidateRect auf das primäre Display machen. ChangeDisplaySettings(0, 0) ging dafür zwar, allerdings halt nur für den gesamten Screen und das will ich nicht machen um einen kleinen Rahmen irgendwo zu löschen. Flackert halt wie sau.
Normalerweise entfernt man den Rahmen, indem man ihn nochmal zeichnet. Dadurch, dass die Windows-Rahmenfunktion jedes zweite Pixel einfach bitweise xort hebt sich das ganze aus. Problematisch wird es nur, wenn sich das Zielfenster zwischenzeitig selber neuzeichnet, aber das ist zu verkraften.
Das mit der Mausposition löst zumindest Spy++ so, indem es den Benutzer zwingt bei der Fensterauswahl die Maustaste zu drücken. Mit SetCapture() bekommt man dann auch außerhalb des eigenen Fensters Mausnachrichten.
Löwe
Beiträge: 15
Registriert: 29.09.2003, 21:17

Re: [WINAPI] Transparentes Fenster / Rahmen

Beitrag von Löwe »

Hm, ich versteh nicht wirklich, was das alles jetzte mit "Transparenten fenstern/Rahmen" zu tun hat. Aber wenn es dir darum geht, ein Fenster Transparent zu machen, befass dich mal damit:

Code: Alles auswählen

HMODULE hDLL;
PSLWA pSetLayeredWindowAttributes;
float wnd_alpha = 80.0;

hDLL = LoadLibrary("user32");
pSetLayeredWindowAttributes = (PSLWA) GetProcAddress(hDLL,"SetLayeredWindowAttributes");

SetWindowLong (hWnd, GWL_EXSTYLE, GetWindowLong(hWnd, GWL_EXSTYLE) | WS_EX_LAYERED ) ;
// Fensterhintergrund sollte weiß sein ;) (255,255,255)
pSetLayeredWindowAttributes(hWnd, RGB(255,255,255), (int)((255.0 / 100.0) * wnd_alpha), LWA_COLORKEY);
Sorry, ist nur eben schnell aus nem uralten code kopiert. Kann jetzt auf die schnelle auch keine Detailfragen dazu benatworten. Hatte es im BCB 4 geschrieben. Das Fenster (weiße Hinterdrundfarbe) wird halt durchsichtig gemacht, und zeigt (in meinem Fall) danach aber noch Text (in Form von TLable-Objekten (BCB halt) an an, die auf dem fenster liegen.

vllt Hilfts ja weiter
jumphigh
Beiträge: 19
Registriert: 30.06.2004, 13:41
Kontaktdaten:

Re: [WINAPI] Transparentes Fenster / Rahmen

Beitrag von jumphigh »

Wenn du nicht selber mit dem ROP-Code R2_XORPEN manuell einen Rahmen malen willst, würde ich doch ganz einfach "DrawFocusRect" empfehlen. Ohne Mouse-Hook kommt man aus, wenn man die Maus einfängt (SetCapture). Dann erhältst du weiterhin alle WM_MOUSEMOVE, auch wenn sich der Zeiger außerhalb deines Fenster befindet. Mittels WindowFromPoint und GetWindowDC sollte der Rahmen kein Problem mehr sein: Beim Wechsel von einem Fenster ins andere einfach DrawFocusRect im alten Fenster noch einmal aufrufen zum Löschen und im neuen ebenfalls zum neu Markieren.

Mit dem Maus-Haken wird es etwas schwieriger, da du mittels IPC (z.B. PostMessage an dein eigenes Fenster) die Daten (HWND z.B.) aus dem jeweiligen Prozess in dein eigenes Programm schaffen musst. Natürlich verschluckt dein Haken nicht die Fensternachrichten, sondern gibt sie an die nächsten Haken weiter. Für einen Haken benötigt man anders als bei OpenProcess keine weiteren Rechte, allenfalls kann man ab Vista nicht mit niedriger Integritätsstufe auf Fenster mit höherer Stufe (z.B. "elevated" Admin) zugreifen.

MfG
Andreas
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: [WINAPI] Transparentes Fenster / Rahmen

Beitrag von BeRsErKeR »

Löwe hat geschrieben:Hm, ich versteh nicht wirklich, was das alles jetzte mit "Transparenten fenstern/Rahmen" zu tun hat. Aber wenn es dir darum geht, ein Fenster Transparent zu machen, befass dich mal damit:
Naja darum gings halt am Anfang und ich wollte keinen neuen Thread erstellen für die neuen Probleme. Danke aber für die Hinweise (auch an Helmut). Das läuft aber wie gesagt.

jumphigh hat geschrieben:Ohne Mouse-Hook kommt man aus, wenn man die Maus einfängt (SetCapture). Dann erhältst du weiterhin alle WM_MOUSEMOVE, auch wenn sich der Zeiger außerhalb deines Fenster befindet.
Kann man dann das Zielprogramm noch vernünftig bedienen? Weil das wäre schon wichtig. Kann mir irgendwie nicht vorstellen, dass ein SetCapture für mein eigenes Fenster dann noch Button-Klicks, etc im Zielfenster ermöglicht.



Wie schon gesagt, ist mein derzeitiges Problem ein anderes. Und zwar die DLL, die die Control-Resource enthält, über das Window-Handle ausfindig zu machen und/oder den Control-Namen (nicht Titel), wie er z.B. in Designern gesetzt werden kann, über das Window-Handle zu kriegen. Prinzipiell geht das, aber halt nur mit Zugriff auf den Remote-Process und den hab ich nicht. Von daher wird es wohl nicht gehen.
Ohne Input kein Output.
jumphigh
Beiträge: 19
Registriert: 30.06.2004, 13:41
Kontaktdaten:

Re: [WINAPI] Transparentes Fenster / Rahmen

Beitrag von jumphigh »

Kann man dann das Zielprogramm noch vernünftig bedienen? Weil das wäre schon wichtig. Kann mir irgendwie nicht vorstellen, dass ein SetCapture für mein eigenes Fenster dann noch Button-Klicks, etc im Zielfenster ermöglicht.
Ich komme ehrlich gesagt nicht mehr mit! Es ging dir darum, wie man ein fremdes Fenster kennzeichnet bzw. ausliest, wenn man mit der Maus darüber fährt. Dafür habe ich dir ein VS-2010-Projekt angehangen. Ziehe einfach das Zielkreuz auf ein Fenster. Funktioniert wie der Spy. Während des Einfangens der Maus kommen alle Mausnachrichten an dein Fenster, das fremde Fenster erhält keine mehr.
Wie schon gesagt, ist mein derzeitiges Problem ein anderes. Und zwar die DLL, die die Control-Resource enthält, über das Window-Handle ausfindig zu machen und/oder den Control-Namen (nicht Titel), wie er z.B. in Designern gesetzt werden kann, über das Window-Handle zu kriegen. Prinzipiell geht das, aber halt nur mit Zugriff auf den Remote-Process und den hab ich nicht. Von daher wird es wohl nicht gehen.
Ich glaube, du verstehst da was falsch! Die Designer setzen als Control-Namen i.d.R. eine symbolische Konstante, die einfach eine Zahl abstrahiert. Für Win32-Dialoge kann man diese Zahl zumeist via GetDlgCtrlID ermitteln, aber den symbolischen Namen aus einer IDE erhält man dadurch natürlich nicht. Es ist unter Windows prinzipiell nicht möglich, ein Fenster zu identifizieren, wenn dieses nicht selber Vorkehrungen wie eine eindeutige WindowClass oder einen eindeutigen Titel trifft.

MfG
Andreas
Dateianhänge
WindowTracker.zip
Window-Tracking findet in WindowTrackerDlg.cpp -> CWindowTrackerDlg::OnMouseMove statt.
(1.94 MiB) 233-mal heruntergeladen
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: [WINAPI] Transparentes Fenster / Rahmen

Beitrag von BeRsErKeR »

jumphigh hat geschrieben:
Kann man dann das Zielprogramm noch vernünftig bedienen? Weil das wäre schon wichtig. Kann mir irgendwie nicht vorstellen, dass ein SetCapture für mein eigenes Fenster dann noch Button-Klicks, etc im Zielfenster ermöglicht.
Ich komme ehrlich gesagt nicht mehr mit! Es ging dir darum, wie man ein fremdes Fenster kennzeichnet bzw. ausliest, wenn man mit der Maus darüber fährt. Dafür habe ich dir ein VS-2010-Projekt angehangen. Ziehe einfach das Zielkreuz auf ein Fenster. Funktioniert wie der Spy. Während des Einfangens der Maus kommen alle Mausnachrichten an dein Fenster, das fremde Fenster erhält keine mehr.
Nun ja prinzipiell möchte ich eine Art Spy. Allerdings soll man während der Spy aktiv ist das Zielprogramm weiter bedienen können. Ich muss mit dem Tool Oberflächen untersuchen und will halt nicht nach jedem untersuchten Control, den Spy ausschalten oder deaktivieren. Ich muss im Zielprogramm andere Tabs/Dialoge/etc öffnen usw. Daher wäre es toll, wenn das Zielprogramm bedienbar bleibt. Mit MouseHooks ging das eigentlich ganz gut.

jumphigh hat geschrieben:
Wie schon gesagt, ist mein derzeitiges Problem ein anderes. Und zwar die DLL, die die Control-Resource enthält, über das Window-Handle ausfindig zu machen und/oder den Control-Namen (nicht Titel), wie er z.B. in Designern gesetzt werden kann, über das Window-Handle zu kriegen. Prinzipiell geht das, aber halt nur mit Zugriff auf den Remote-Process und den hab ich nicht. Von daher wird es wohl nicht gehen.
Ich glaube, du verstehst da was falsch! Die Designer setzen als Control-Namen i.d.R. eine symbolische Konstante, die einfach eine Zahl abstrahiert. Für Win32-Dialoge kann man diese Zahl zumeist via GetDlgCtrlID ermitteln, aber den symbolischen Namen aus einer IDE erhält man dadurch natürlich nicht. Es ist unter Windows prinzipiell nicht möglich, ein Fenster zu identifizieren, wenn dieses nicht selber Vorkehrungen wie eine eindeutige WindowClass oder einen eindeutigen Titel trifft.
Ja diese Vermutung hatte ich auch und habe die letzte Woche auch Gewissheit erlangt. Die IDs bringen einem halt auch herzlich wenig, da sie halt nicht eindeutig sind (bzw. nur in einem Dialog). Ich kannte mich bis vorgestern leider noch nicht so recht mit den .NET Forms aus und dachte, dass der Controlname vielleicht mit im Control abgelegt wird.

Allerdings bin ich mir recht sicher, dass man damals mit dem Visual Studio 6.0 Exe-Files, die MFC-Dialoge enthielten, mit dem Resource-Editor öffnen konnte und dann auch die Resourcen wie Dialoge, Icons, StringTables, etc gesehen hat. Wenn das immer noch irgendwie möglich ist, könnte man eventuell direkt die DLLs auslesen. Wobei ich von der Zuordnung her dann wohl auch nicht weiter komme.

Danke jedenfalls für die Hinweise. Ich hab allerdings aufgegeben.
Ohne Input kein Output.
Antworten