Fenster Sichtbarkeit: Ein schlechter Scherz!?



  • Hallo alle zusammen!

    Das geht an alle WinAPI Cracks!

    Ich habe ein schlimmes Fensterproblem:

    Ich habe mehrere groupboxes (child des Hauptfensters), denen ich jeweils eine subclass proc spendiert habe. Diese haben wieder einige child windows, die wiederum ihre eigenen subclass procs haben.

    Nun treten folgende Probleme auf (sorry, der folgende Satz wird etwas kompliziert):
    - 1) Wenn ich innerhalb einer subclass proc eines der childs einer groupbox (und zwar genau in der Abarbeitung von WM_COMMAND) ein anderes Fenster, dass ebenfalls child einer anderen subklassierten oder derselben groupbox ist, mit ShowWindow(hWindow, SW_HIDE) verstecke, ist es noch immer sichtbar! Wenn ich z.B. einen Button so verstecke, ist er zwar noch sicht- aber nicht mehr klickbar. ShowWindow() gibt ja zurück, ob das Fenster vorher sichtbar war, sagt mir aber ebenfalls, dass es eigentlich korrekt versteckt sein müsste. Wenn ich ein anderes Fenster (wie z.B. den Windows Rechner) darüber bewege, sind die betreffenden Fenster weg, so wie es eigentlich sein sollte.
    - 2) Wenn ich ein solches Fenster mit z.B. MoveWindow() bewege, ist es an seiner neuen UND seiner alten Position zu sehen.

    Da scheint also irgendwas mit WM_PAINT nicht zu stimmen, übrigens bringen da auch RedrawWindow(), InvalidateRect(), UpdateWindow() o.ä. nichts.

    Bevor ich es vergesse:
    - a) Mit dem Messaging gibt es keine Probleme (d.h. die Messages WM_LBUTTONDOWN, WM_COMMAND usw. werden wie erwartet an die subclass Prozeduren gesendet).
    - b) Ich rufe in jeder subclass proc am Ende die richtige (?) alte Proc auf.
    - c) Ich hab die subclass der Groupbox vor den Subclasses der childs der groupbox zugewiesen.

    Wäre cool, wenn jemand einen Vorschlag hätte. 🙂



  • Also ich hätte da jetzt gesagt, du rufst entweder die original WndProc am Ende nicht richtig auf (falls du WM_PAINT nicht selber abfängst) oder du reagierst auf WM_PAINT falsch 🙄
    Zeig doch mal ein wenig Code 😉



  • Hi, klar kann ich Code posten.

    Nur vorweg:

    Also ich hätte da jetzt gesagt, du rufst entweder die original WndProc am Ende nicht richtig auf (falls du WM_PAINT nicht selber abfängst) oder du reagierst auf WM_PAINT falsch

    Weder sende ich WM_PAINT irgendwie selbst (ich rufe jedoch ab- und zu mal RedrawWindow() auf), noch verarbeite ich diese Message.

    Mir scheint eher die Sache mit den alten Prozeduren als Erklärung plausibler, hoffe, du kannst in diesem Code einen Fehler erkennen:

    // in einer Init-Funktion:
    	hGR_Info = GROUPBOX(" Materials ", 5, 356, 190, 204, hMainHwnd);
    
    	pFOldInfo = (WNDPROC) SetWindowLong(hGR_Info, GWL_WNDPROC, DWORD 
              (hGR_InfoProc));
    
    	SetProp(hGR_Info, "OldProc", (HANDLE) pFOldInfo);
    
    	// dann die Subclass Proc dieser Groupbox:
    	LRESULT hGR_InfoProc(HWND Hwnd, UINT Message, WPARAM WParam, LPARAM 
                LParam)	{
    
    	     WNDPROC pFOld = (WNDPROC) GetProp(Hwnd, "OldProc");
    
    	     switch (Message)
    
    		{  case WM_COMMAND:
    
    		      {	fprintf(Protokoll, "Hallo");	}
    
    			break;
    
    		   default: break;	}
    
    	   return CallWindowProc(pFOld, Hwnd, Message, WParam, LParam);	}
    
        // dann noch die Klasse, die ein subklassiertes child der Groupbox kapselt:
          // im Konstruktor dieser Klasse:	
    
    	this->hMain = CreateWindow("STATIC", NULL, WS_CHILD | SS_NOTIFY, 
              nPosX, nPosY, CW_USEDEFAULT, CW_USEDEFAULT, hParent, NULL, hGlHinst, 
              NULL);
    
    	this->pFOldProc = (WNDPROC) SetWindowLong(this->hMain, GWL_WNDPROC, 
              DWORD (SubclassProc));
    
    	SetProp(this->hMain, "this", (HANDLE) this);
    	SetProp(this->hMain, "OldProc", (HANDLE) this->pFOldProc);
    
      // dies ist die statische subclass proc von hMain:
    	LRESULT CALLBACK CButtonGroup::SubclassProc(HWND hParentHandle, UINT 
               nMessage, WPARAM WParam, LPARAM LParam)	{
    
                 WNDPROC pFOld	= (WNDPROC) GetProp(hParentHandle, "OldProc");
    
    	    switch (nMessage)
    
    		{  case WM_COMMAND:	
    
    		   {// Wenn ich hier ShowWindow() o. MoveWindow() aufrufe,
    		    // sind die Fenster dennoch noch an ihrer (alten) Pos.
    		    // sichtbar
    		    return 0; }	// auch keine Änderung, wenn ich
    				// return 0 weglasse!
    
    		    break;
    
    		default: break;	}
    
    	return CallWindowProc(pFOld, hParentHandle, nMessage, WParam, LParam);	}
    

    Man sieht hier hoffentlich in etwa das Schema des Programmes: In einer Init-Funktion erzeuge ich die Groupbox, dann weise ich die neue Subclass Proc zu, die alte speichere ich und übergebe sie dem Fenster als Property (was eigentlich bisher immer funktioniert hat, auch wenn ich die Variable selbst in der subclass verwende, ist das Problem noch immer da).
    Irgendwann später in den Init-Funktionen erzeuge ich die childs dieser Groupbox, u.a. auch ein erweitertes selbstdefiniertes Kontrollelement, das ein Hauptfenster hat, das wiederum subklassiert ist.
    ⚠ Diese subclass proc ist wie das Hauptfenster dieses Controls auch als static-Funtkion in einer Klasse gekapselt. Wenn ich innerhalb dieser subclass, und ganz genau während der Behandlung von WM_COMMAND ein Fenster verstecke oder verschiebe (das ein beliebiges child eines subklassierten Fensters ist), wird es nicht versteckt bzw. ist noch an der alten Position sichtbar 😕 , das
    return 0 am Ende von WM_COMMAND spielt dabei keine Rolle.

    Hoffe jemand kann das schnell überblicken und mir sagen, was ich falsch gemacht habe, danke! :p



  • Werden deine SubclassProcs denn richtig aufgerufen?
    Evtl. (denke zwar eher nicht 🙄 ) hilft dir das hier weiter: http://www.winapi.net/index.php?inhalt=s27



  • Hat mir leider auch nicht weiter geholfen, trotzdem danke für die Mühe! 👍 Werde das Problem schon irgendwie lösen und dann posten, was das Problem war, falls andere Programmierer auch mal darauf stoßen sollten. 😉


Log in to reply