Bereiche für Child Windows begrenzen



  • Mmacher schrieb:

    abrissbirne schrieb:

    Danke für die aussagkräftige Antwort. Gibt es denn eine andere Möglichkeit?

    Nein, automatisch geht das nicht.
    Ja, indem Du selbst beim Verschieben des Fensters kontrollierend eingreifst.

    Bearbeite die Nachricht WM_GETMINMAXINFO oder WM_SIZING ab, diese wird gesendet, wenn die Fenstergröße geändert oder verschoben wird.
    So kannst Du also die Lage und die Größe des Fensters beeinflußen bevor das Fenster neugezeichnet wird.

    Am elegantesten geht das m.E. mit WM_GETMINMAXINFO, denn da übernimmt Windows danach automatisch das nötige MoveWindow() 😉

    HTH,
    Martin

    Danke, dass hört sich doch gut an. Bin noch nicht so vertaut mit der ganzen Fenstergeschichte. Werde mir WM_GETMINMAXINFO mal genauer ansehen.

    Thx



  • Ok, ich steig da noch nicht so ganz durch obwohl ich ein paar Codezeilen wie

    case WM_GETMINMAXINFO: { 
    
         // Minimale Fensterabmessungen 
         ((LPMINMAXINFO)lParam)->ptMinTrackSize.x = 640; 
         ((LPMINMAXINFO)lParam)->ptMinTrackSize.y = 480; 
    
         // Maximale Fensterabmessungen 
         ((LPMINMAXINFO)lParam)->ptMaxTrackSize.x = 1280; 
         ((LPMINMAXINFO)lParam)->ptMaxTrackSize.y = 1024; 
    
    } break;
    

    finden konnte.

    Ich habe das Fenster um das es sich dreht nicht seibst erstellt (CreateWnd()) sondern mir über FindWindow() das Handle auf das Fenster geben lassen. Wie kann ich nun über die Windows Messages diesem Fenster eine gewisse Positionierung über die Msg WM_GETMINMAXINFO übergeben?

    Danke



  • abrissbirne schrieb:

    Ich habe das Fenster um das es sich dreht nicht seibst erstellt (CreateWnd()) sondern mir über FindWindow() das Handle auf das Fenster geben lassen.

    Häh? Handelt es sich möglicherweise um ein Fenster eines anderen Prozesses? Oder wurde es von Deiner Applikation erzeugt?

    Ich gehe des weiteren davon aus, Du redest von einem Fenster, welches vom User ganz gewöhnlich mit der Maus in der Größe verändert und/oder in der Position verschoben werden kann. Also kein Fenster im Sinne von z.B. Controls in einem Dialog o.ä.



  • Mmacher schrieb:

    Häh? Handelt es sich möglicherweise um ein Fenster eines anderen Prozesses? Oder wurde es von Deiner Applikation erzeugt?

    Ich gehe des weiteren davon aus, Du redest von einem Fenster, welches vom User ganz gewöhnlich mit der Maus in der Größe verändert und/oder in der Position verschoben werden kann. Also kein Fenster im Sinne von z.B. Controls in einem Dialog o.ä.

    Alles richtig. Das Fenster stammt von einem anderen Prozess. Ich habe mir das Handle auf dieses Fenster ausgelesen. Der User kann dieses in der Tat in der Größe verändern. Ist es möglich das ich nun mit dem bekannten Handle Einfluss auf dieses Fenster nehmen kann? Sprich den Bereich in dem das Fenster verschoben werden kann, oder die maximale Größe.

    Danke



  • Möglicherweise das entsprechende Fenster subclasen und folgende Nachrichten behandeln: WM_MOVE, WM_MOVING, WM_SIZE, WM_SIZING



  • ....... schrieb:

    Möglicherweise das entsprechende Fenster subclasen und folgende Nachrichten behandeln: WM_MOVE, WM_MOVING, WM_SIZE, WM_SIZING

    Ich arbeite mich gerade in die WinAPI Programmierung ein. Was brauche ich denn zum subclasen (und was ist das überhaupt? Hast du ein Codebeispiel?). Um die Nachrichten an ein Fenster abzugreifen brauche ich doch den Klassennamen, das Handle auf das Fenster sowie dessen Titel. Ist das korrekt? Wenn ich nun das Handle und den Titel habe, kann ich dann an den Klassennamen herankommen um sich dann eine Nachrichenverarbeitungsroutine zu basteln?


  • Mod

    Ich muss anzweifeln, dass Du Google benutzt hast:
    http://www.google.de/search?hl=de&num=50&newwindow=1&q=msdn+subclassing&meta=
    liefert 2 Artikel, die perfekt diese Sache erklären.

    Ansonsten siehe MSDN über die Trivia von Fensterprozeduren:
    http://msdn.microsoft.com/en-us/library/ms633569(VS.85).aspx



  • abrissbirne schrieb:

    Ich arbeite mich gerade in die WinAPI Programmierung ein.

    Junge, junge, voller Tatendrang, nicht schlecht.

    Abgesehen davon, daß Grundlagen über Fenster enorm wichtig für das Verständnis ist:
    Du hast hier immer noch nicht für uns klar genug Dein wahres Problem geäußert. Ich meine was genau möchtest Du erreichen?
    Vielleicht kannst Du ein für uns nachvollziehbares Praxisbeispiel beschreiben?

    Denn nicht selten führen völlig andere Lösungswege zum gewünschten Ziel.
    Z.B. ein unsichtbares zweites Desktop mit eingeschränkter Größe, ohne in fremde Programme (Prozesse) reinpfuschen zu müssen?

    Martin



  • Martin Richter schrieb:

    Ich muss anzweifeln, dass Du Google benutzt hast:
    http://www.google.de/search?hl=de&num=50&newwindow=1&q=msdn+subclassing&meta=
    liefert 2 Artikel, die perfekt diese Sache erklären.

    Ansonsten siehe MSDN über die Trivia von Fensterprozeduren:
    http://msdn.microsoft.com/en-us/library/ms633569(VS.85).aspx

    Da muss ich dir recht geben. Meine Frage zielte eher auf einen anderen Lösungsweg ab, da ich mich mit subclassing noch nie beschäftigt habe. Wenn subclassing aber eine gute und saubere Lösung ist, werde ich mich auch damit beschäftigen müssen.

    Mmacher schrieb:

    abrissbirne schrieb:

    Ich arbeite mich gerade in die WinAPI Programmierung ein.

    Junge, junge, voller Tatendrang, nicht schlecht.

    Abgesehen davon, daß Grundlagen über Fenster enorm wichtig für das Verständnis ist:
    Du hast hier immer noch nicht für uns klar genug Dein wahres Problem geäußert. Ich meine was genau möchtest Du erreichen?
    Vielleicht kannst Du ein für uns nachvollziehbares Praxisbeispiel beschreiben?

    Denn nicht selten führen völlig andere Lösungswege zum gewünschten Ziel.
    Z.B. ein unsichtbares zweites Desktop mit eingeschränkter Größe, ohne in fremde Programme (Prozesse) reinpfuschen zu müssen?

    Martin

    Ok mein Problem konkret.
    Ich habe eine kleine LabVIEW Applikation. Die Darstellungsarten von LV sind enorm bei gerigem Programmieraufwand. Nun habe ich eine Toplevel Applikation. Dort werden Diagramme von irgendwelchen Daten dargestellt. Jetzt möchte ich die geladenen Diagramme (eingenständige Fenster) als Childwindows des Toplevel Fensters deklarieren. Das konnte ich auch über FindWindow() und SetParent() realisieren. Nun möchte ich aber den Bereich in dem die Childwindows bewegt werden können einschränken (nicht über die Menüleister drüber hinaus ...). Ich habe bereits ein kleines C-Programm erstellt, mit dem ich die Windows Nachrichten an Fenster abgefangen und weiterverarbeitet habe. Also rein in C kann ich den Bereich eingrenzen. Jetzt muss ich irgendie versuchen mit dem Fenster Handle des LV Fensters das gleiche hinzubekommen und das ganze als DLL bereitstellen. Ich hoffe ich konnte die Problemstellung gut beschreiben.

    Danke


  • Mod

    Ich kenne LabView nicht aber irgendwie finde ich Deine Ansätze komisch.
    Wieso musst Du FindWindow benutzen?
    Wieso musst Du SetParent benutzen, kannst Du ein Fenster nicht wahlfrei erzeugen mit Labview wo Du willst?
    Subclassing hilft Dir genau hier. Du bekommst in Deiner WndProc alle Nachrichten undkannst selber entscheiden, ob Du diese weiterleitest oder was Du damit machst.



  • Martin Richter schrieb:

    Ich kenne LabView nicht aber irgendwie finde ich Deine Ansätze komisch.
    Wieso musst Du FindWindow benutzen?
    Wieso musst Du SetParent benutzen, kannst Du ein Fenster nicht wahlfrei erzeugen mit Labview wo Du willst?
    Subclassing hilft Dir genau hier. Du bekommst in Deiner WndProc alle Nachrichten undkannst selber entscheiden, ob Du diese weiterleitest oder was Du damit machst.

    Ich kann Fenster mit LV erzeugen, aber eben keine mit Abhängigkeiten (Child-Parten-Windows). Außerdem gibt es soetwas wie ein Fenster-Nachrichten nicht. Das heißt ich bekomme nicht mit wenn ein LV Fenster bewegt wird. Wenn du sagst das subclassing die Methode für mich ist, werde ich mich damit beschäftigen. Allerdings interessiert mich der Ansatz mit dem zweiten Desktop auch. Kann ich damit eine Client-Area bestimmen?
    Danke


  • Mod

    Und wie erzeugst Du bitte ein Fenster?
    Übergibst Du kein Parent Handle? Erzeugt LabView immer ein Popup Window? Kann ich mir nicht vorstellen.

    Zum zweiten Desktop kann ich nichts sagen weil ich das in diesem Zusammenhang nicht verstehe.
    Zudem finde ich solche Ansätze hanebüchen.



  • Martin Richter schrieb:

    Und wie erzeugst Du bitte ein Fenster?
    Übergibst Du kein Parent Handle?

    Nein. Sonst würde ich wohl kaum solche Klimmzüge machen.



  • Nun, ich versuche Deine Beschreibung nachvollzuziehen, bin da schon konfus, was genau Du meinst 😕

    Ich kenne LabView noch grob von der Demonstration auf einer Messe, aber das hilft mir auch nicht weiter.
    Aber der Reihe nach:

    abrissbirne schrieb:

    Ich habe eine kleine LabVIEW Applikation. Die Darstellungsarten von LV sind enorm bei gerigem Programmieraufwand.

    "LabView" ist Applikation Nr. 1 (oder auch Prozess Nr. 1) -> also nennen wir es App1

    abrissbirne schrieb:

    Nun habe ich eine Toplevel Applikation. Dort werden Diagramme von irgendwelchen Daten dargestellt. Jetzt möchte ich die geladenen Diagramme (eingenständige Fenster) als Childwindows des Toplevel Fensters deklarieren. Das konnte ich auch über FindWindow() und SetParent() realisieren.

    "Eine Toplevel Applikation" -> App2
    "Diagramme mit irgendwelchen Daten" -> Childfenster von App2, d.h. von App2 mit CreateWindow() erzeugt -> CFApp2

    abrissbirne schrieb:

    Das konnte ich auch über FindWindow() und SetParent() realisieren.

    Ich fürchte, schon jetzt habe ich ein Interpretationsproblem, denn FindWindow() und SetParent() macht bei eigenen, selbst generierten Fenstern (App2 erzeugt CF2) nun nicht wirklich Sinn.
    Oder meinst Du die "Diagramme von irgendwelchen Daten" sind das Childfenster von App1 (LabView), also CFApp1 ?

    abrissbirne schrieb:

    Nun möchte ich aber den Bereich in dem die Childwindows bewegt werden können einschränken (nicht über die Menüleister drüber hinaus ...).

    Welchen Bereich als Grenzen meinst Du?
    Den Fensterbereich (Client- bzw. Ausgabebereich) von App1 oder den von App2 ?

    abrissbirne schrieb:

    Ich habe bereits ein kleines C-Programm erstellt, mit dem ich die Windows Nachrichten an Fenster abgefangen und weiterverarbeitet habe. Also rein in C kann ich den Bereich eingrenzen.

    Ist hier noch von der gleichen "Toplevel Applikation" (also App2 ) die Rede?

    abrissbirne schrieb:

    Jetzt muss ich irgendie versuchen mit dem Fenster Handle des LV Fensters das gleiche hinzubekommen und das ganze als DLL bereitstellen.

    ???

    Meine Phantasie meint, Du möchtest wahrscheinlich ein Fenster mit den Diagrammen von LabView in Deine Applikation App2 so einverleiben, als ob es ein selbst erzeugtes Childfenster von App2 wäre? Und App1 soll von der Bildfläche verschwinden (ggf. in die Taskleiste minimiert) ?

    Martin



  • Mmacher schrieb:

    Nun, ich versuche Deine Beschreibung nachvollzuziehen, bin da schon konfus, was genau Du meinst 😕

    Ich kenne LabView noch grob von der Demonstration auf einer Messe, aber das hilft mir auch nicht weiter.
    Aber der Reihe nach:

    abrissbirne schrieb:

    Ich habe eine kleine LabVIEW Applikation. Die Darstellungsarten von LV sind enorm bei gerigem Programmieraufwand.

    "LabView" ist Applikation Nr. 1 (oder auch Prozess Nr. 1) -> also nennen wir es App1

    Nein, dass ist noch keine Applikation. LV stellt nur die Runtime-Engine dar.

    Mmacher schrieb:

    abrissbirne schrieb:

    Nun habe ich eine Toplevel Applikation. Dort werden Diagramme von irgendwelchen Daten dargestellt. Jetzt möchte ich die geladenen Diagramme (eingenständige Fenster) als Childwindows des Toplevel Fensters deklarieren. Das konnte ich auch über FindWindow() und SetParent() realisieren.

    "Eine Toplevel Applikation" -> App2
    "Diagramme mit irgendwelchen Daten" -> Childfenster von App2, d.h. von App2 mit CreateWindow() erzeugt -> CFApp2

    Toplevel Applikation -> App1
    Diagramme mit irgendwelchen Daten -> Childfenster von App1, aber nicht mit CreateWindow erzeugt. Und da ist mein Problem. Wenn man mit LV arbeitet, hat man zu jedem neuen Programmcode direkt ein Fenster dabei. Das Fenster (nennt sich in LV Frontpanel) ist direkt an den Programmcode (Blockdiagramm) gekoppelt. Man kann das Fenster Anzeigen oder aber auch nicht (dann wird der Code als Funktion benutzt, die aufgerufen werden kann). Ich erstelle quasi kein Fenster selbst, dass übernimmt direkt LabVIEW für mich. Ich zeige es eben nur an, oder aber auch nicht.

    Mmacher schrieb:

    abrissbirne schrieb:

    Das konnte ich auch über FindWindow() und SetParent() realisieren.

    Ich fürchte, schon jetzt habe ich ein Interpretationsproblem, denn FindWindow() und SetParent() macht bei eigenen, selbst generierten Fenstern (App2 erzeugt CF2) nun nicht wirklich Sinn.
    Oder meinst Du die "Diagramme von irgendwelchen Daten" sind das Childfenster von App1 (LabView), also CFApp1 ?

    Da ich keine Fenster duch CreateWindow selbst erzeuge geht es leider nicht anders. Die Diagramm sind Childfenster von App1 Alles was ich von den Fenstern habe ist der Titel und das Handle, aber kein Klassenname.

    Mmacher schrieb:

    abrissbirne schrieb:

    Nun möchte ich aber den Bereich in dem die Childwindows bewegt werden können einschränken (nicht über die Menüleister drüber hinaus ...).

    Welchen Bereich als Grenzen meinst Du?
    Den Fensterbereich (Client- bzw. Ausgabebereich) von App1 oder den von App2 ?

    Von App1, App2 gibt es nicht.

    Mmacher schrieb:

    abrissbirne schrieb:

    Ich habe bereits ein kleines C-Programm erstellt, mit dem ich die Windows Nachrichten an Fenster abgefangen und weiterverarbeitet habe. Also rein in C kann ich den Bereich eingrenzen.

    Ist hier noch von der gleichen "Toplevel Applikation" (also App2 ) die Rede?

    Nein, das war nur eine Übung für mich um mit den WM vertraut zu werden.

    Mmacher schrieb:

    abrissbirne schrieb:

    Jetzt muss ich irgendie versuchen mit dem Fenster Handle des LV Fensters das gleiche hinzubekommen und das ganze als DLL bereitstellen.

    ???

    Meine Phantasie meint, Du möchtest wahrscheinlich ein Fenster mit den Diagrammen von LabView in Deine Applikation App2 so einverleiben, als ob es ein selbst erzeugtes Childfenster von App2 wäre? Und App1 soll von der Bildfläche verschwinden (ggf. in die Taskleiste minimiert) ?

    Martin

    So ähnlich. Die Diagramme solle Childfenster von App1 werden und App1 ggf. in der Taskleiste minimiert werden können.



  • Oje, ich bin da schon fast am Aufgeben...

    Bevor ich da weiter rate, erstmal eine grundsätzliche Frage:
    Ist denn die besagte "Toplevel Applikation" noch Bestandteil von LabView oder ist das DEINE in C/C++ selbstgeschriebene Applikation (eine separat gestartete .EXE)?

    Übrigens: Eine Applikation ist ein gestarteter Prozeß, das hat nicht unbedingt etwas mit einer Ausgabe mit Fenster zu tun.
    Insofern vermute ich hier ein Mißverständnis deinerseits, und LabView mit der Runtime-Engine ist nach meiner Vorstellung immernoch "App1".

    Hier reden wir mit klar definierten Begriffen von Microsoft, was "Applikation", "Prozeß", "Child-Window", "Parent" usw. betrifft. Nur so ist es überhaupt möglich mit anderen z.B. hier im Forum zu kommunizieren, was eigentlich gemeint ist.

    Mein jetzige Bestandsaufnahme von Deiner Situation sieht mittlerweile so aus:
    App1: LabView Runtime-Engine
    App2: Toplevel-Window oder "LabView Frontpanel", als Tochter-Prozeß (oder GUI-Thread) von App1 aufgerufen
    App3: Deine C/C++-Applikation um das Fenster von App2 zu manipulieren.

    Stark vereinfacht kann man sagen, guck mal in den Task-Switch (mit Alt+Tab), oder alternativ in den Task-Manager:
    Welche Prozesse (also Applikationen) laufen da gerade?



  • Ich möchte hier einen Zwischenbericht abgeben.
    Bin der Sache schon näher gekommen. Ich arbeite momentan mit Hook-Funktionen. Auf diese Weise kann ich Fensternachrichten eines anderen Prozesses abfangen. Hier mein Code:

    #include "stdafx.h"
    
    HHOOK hWndProc;
    
    BOOL APIENTRY DllMain( HMODULE hModule,
                           DWORD  ul_reason_for_call,
                           LPVOID lpReserved
    					 )
    {
    	switch (ul_reason_for_call)
    	{
    	case DLL_PROCESS_ATTACH:
    		hWndProc = NULL;
    		break;
    
    	case DLL_THREAD_ATTACH:
    	case DLL_THREAD_DETACH:
    	case DLL_PROCESS_DETACH:
    		if(hWndProc != NULL)
    			UnhookWindowsHookEx(hWndProc);
    		break;
    	}
    	return TRUE;
    }
    
    // Funktionsprototypen
    extern "C" __declspec(dllexport) int CatchWindowMessage(HWND *ptargetWnd);
    LRESULT WINAPI WndProc(int nCode, WPARAM wParam, LPARAM lParam);
    
    extern "C" __declspec(dllexport) int CatchWindowMessage(HWND *ptargetWnd)
    {
    	DWORD targetThread = GetWindowThreadProcessId(ptargetWnd, NULL);
    	hWndProc = SetWindowsHookEx(WH_GETMESSAGE, &WndProc, NULL, targetThread);
    	return 0;
    }
    
    /**************************************************************** 
      Hook procedure 
     ****************************************************************/ 
    
    LRESULT WINAPI WndProc(int nCode, WPARAM wParam, LPARAM lParam) 
    {
    	MSG *msg = (MSG*)lParam;
    	if (nCode < 0)  // do not process message 
            return CallNextHookEx(hWndProc, nCode, wParam, lParam); 
    
        switch (nCode) 
        { 
            case HC_ACTION:
    			switch(msg->message)
    			{
    				case WM_RBUTTONDOWN:
    					MessageBox(NULL, "Right mouse button down", "WM Info", MB_OK);
    					break;
    
    				case WM_MOUSEMOVE:
    					// Wird hineingesprungen [X]
    					break;
    				case WM_MOVING:
    					MessageBox(NULL, "Wnd moved", "WM Info", MB_OK);
    			}
                break; 
    
            default: 
                break;
        } 
    
        return CallNextHookEx(hWndProc, nCode, wParam, lParam); 
    }
    

    Einen Mouseklick, sowie das Maus über das Fenster hinwegbewegen bekomme ich als Message abgefangen. Aber die Nachricht WM_MOVING komischerweise nicht. Hat jemand eine Erklärung? In der Onlinehilfe steht leider nicht welche NAchrichten mit der Hook-Funktion abgefangen werden können.

    Danke 🙂


Anmelden zum Antworten