Zeichenbreich in rect-Struktur



  • Hallo!

    Also wenn ich außerhalb der WM_PAINT-Message etwas male, oder irgendwelche Buttons erstelle, dann muss ich den Buttons irgendwelche Koordinaten zuordnen!

    Wenn ich jetzt meinen Windowsstyle veränder, dann ist oben die Adresszeile manchmal breiter und manchmal dünner, das hat zur Folge, dass mein Hintergrundbild nach unten oder oben "verschoben" wird, aber meine Buttons noch dort bleiben, wo sie vorher waren, weil sie sich an rect-koordinaten orientieren. Diese rect-Koordinaten hab ich mit der Funktion GetClientRect(); bekommen ...

    Gibt es auch eine Funktion, die mir die Koordinaten nur vom zeichenbereich zurück gibt und dabei die Breite der Titelleiste und der Menuleiste ignoriert?



  • Guten Morgen!

    Ich hab mir etwas überlegt *g*, ich könnte auch "einfach" eine eigene Titelleiste zeichen, nur dazu kann ich leider hier in der Suche wenig finden ...



  • Normalerweise arbeitest du doch immer mit Client-Koodinaten - von daher verstehe ich dein Problem gerade nicht so ganz...



  • Ja, warte mal, ich werds dir mal an Hand eines(zweier) Screenshots erklären!

    schau genau auf den Würfel im Zusammenspiel mit seinem Hintergrund:
    http://www.sro.at/bildupload/images/verschoben.jpg
    oben, sowie unten

    Der "Fehler" ist zwar nur minmal, aber trotzdem "nervig"!



  • Und das mit dem roten Kreuzchen ist ein Control? Oder zeichnest du das auch selber rein? Und wo und wie zeichnest du den Hintergrund?



  • Das mit dem roten Kreuzchen ist ein Bitmap (ein "leerer" Würfel), je nachdem was man würfelt, so verändert sich auch das Bitmap, es bleibt aber an der selben stelle ...

    Den Hintergrund zeichne ich so:

    wndclass.hbrBackground = CreatePatternBrush((HBITMAP) LoadImage(hInstance, "Bitmaps/Kniffel-nHG4.bmp", IMAGE_BITMAP, 0, 0, 
    		    LR_DEFAULTSIZE | LR_LOADFROMFILE | LR_CREATEDIBSECTION))
    

    Also als Brush ... Und der passt sich genau an die Größe der Titelleiste + Menüleiste an, also "geht runter" bzw. "hoch", ganz im Gegensatz zu meinen Controls, oder Bitmaps, die bleiben fest an ihrem Ort, egal wie groß die Titel- + Menüleiste sind -> Verschiebungen ...



  • Top_se schrieb:

    Das mit dem roten Kreuzchen ist ein Bitmap (ein "leerer" Würfel), je nachdem was man würfelt, so verändert sich auch das Bitmap, es bleibt aber an der selben stelle ...
    [...] passt sich genau an die Größe der Titelleiste + Menüleiste an, also "geht runter" bzw. "hoch", ganz im Gegensatz zu meinen Controls, oder Bitmaps, die bleiben fest an ihrem Ort, egal wie groß die Titel- + Menüleiste sind -> Verschiebungen ...

    Und wo und wie zeichnest du die Kreuzchen bzw. wie erstellst du die Controls (falls du dafür ein eigenes Control verwendest)



  • Also die Kreuzchen erstelle ich in einer ZeichenMessage einfach mit BitBlt:

    SelectObject (hdcMem, hBtmWue0) ;
    												BitBlt (hdc, x, y,   40, 40, hdcMem, 0, 0, SRCCOPY) ;
    												break;
    

    und meine Controls in der WM_CREATE z.b. so:

    CreateWindow("BUTTON", "wuerfeln", 
    				 WS_CHILD|WS_VISIBLE,
    				 53, 401, 130, 40,
    				 hwnd, (HMENU)ID_wuerfeln, hInstance, 0);
    


  • Und sowohl die Controls als auch die Kreuzchen sitzen falsch, oder nur letztere? Wie holst du dir dein hdc?



  • Ähm, naja, was nun genau falsch gezeichnet wird ist eine schwere Frage, zumindest harmonieren sie nicht miteinander *g*, sprich das eine (der Hintergrund) verschieb sich je nach Größe der Titelleiste, und die Controls und Bitmaps bleiben fest an ihren Orten sitzen, egal wie groß die Titelleiste ist!

    Also nochmal genau zu deiner Frage: Beide werden "falsch" gezeichnet, es gibt keinen Unterschied zwischen den Kreuzchen(Bitmaps) und den Controls ...

    Mein hdc des Fenster, auf dem ich die Controls und Bitmaps zeichne bekomme ich wie gewohnt:

    hdc = GetWindowDC(hwnd);		 
    hdcMem = CreateCompatibleDC(hdc) ;
    

    oder ist da etwas Falsches dran?



  • Nimm statt GetWindowDC GetDC, damit bekommst du ein Handle auf den DC deiner Client-Area 🙂
    Bzw. eigentlich solltest du auf das tatsächliche Fenster nur in WM_PAINT zeichnen (in deinen MemoryDC kannst du das überall tun). Am besten einmal in den MemoryDC und diesen dann einfach in WM_PAINT immer in dein Fenster blitten...



  • Hey, danke!

    Ich habe die WM_PAINT-Message bisher verschmäht, weil ich diese nicht direkt manuell aufrufen kann ... Da war mir meine eigenen PM_MALEN-Message lieber 😃

    Ich hab zwar noch ein kleines Problemchen, aber ich glaube ich das kann ich selbst lösen, also zumindest versuch ich das erstmal selbst!

    Mercy!



  • Top_se schrieb:

    Ich habe die WM_PAINT-Message bisher verschmäht, weil ich diese nicht direkt manuell aufrufen kann

    stimmt nicht
    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/pantdraw_4zef.asp



  • Lol, welche Zufall, genau vor ca. 2 mins hab ich mir diese MSDN-Page angeschaut und komisch geguckt 😃
    Naja, ich werde das in zukünftigen programmen besser machen, aber jetzt möchte ich nichtmehr meinen ganzen Code umkrempeln ...
    Ach ja, und mit der Funktion kann ich aber meiner Paintmessage keine Parameter übergeben ...

    Ähm, ich hatte aber eigentl. einen anderen Grund, warum ich auf die MSDN-Page gegangen bin, ich hatte nach einer Funktion gesucht, die mir alle Controls "aktualisiert", also wenn man z.b. eine Bitmap drüber zeichenet, dann verschienden die Controls ja und erst, wenn man wieder mit der Maus drüber fährt werden sie wieder "sichtbar", gibts da eine Funktion, oder soll ich jedes Control einfach irgendwie ansprechen, z.b. bei nem Button einen Häkchen setzen und gleich wieder weg machen *g*!?



  • So, also ich habe das Problem jetzt irgendwie ganz komisch gelöst *g*

    Also ich habe halt wie gesagt eine PM_MALEN-Message und wenn ich diese mit dem wParam 4 aufrufe, dann komme ich zu dieser Abzweigung:

    if (LOWORD(wParam) == 4)
    	{
    	hBtmHG = (HBITMAP) LoadImage(hInstance, REG_getHGPfad(), IMAGE_BITMAP, 0,
                      0, LR_DEFAULTSIZE | LR_LOADFROMFILE | LR_  CREATEDIBSECTION);
          SelectObject (hdcMem, hBtmHG) ;
    	BitBlt(hdc,0,0,540,607,hdcMem, 0, 0, SRCCOPY);					
    
    	//Fensterrect.bottom = 1000;
    	//Fensterrect.left = 0;
    	//Fensterrect.right = 1000;
    	//Fensterrect.top = 0;
    	//InvalidateRect(hwnd, &Fensterrect, TRUE);
    	//UpdateWindow(hwnd);
    	};
    

    hier wird halt mein Hintergrund gemalt!

    Wenn ich das jetzt so ^^ machen würde dann sieht meine Oberfläche so aus:
    http://www.sro.at/bildupload/images/HG-drueber.jpg
    also das Hintergrundbild liegt über meinen Controls.

    Wenn ich den Abzweig so hier machen würde:

    if (LOWORD(wParam) == 4)
    	{
    	hBtmHG = (HBITMAP) LoadImage(hInstance, REG_getHGPfad(), IMAGE_BITMAP, 0,
                      0, LR_DEFAULTSIZE | LR_LOADFROMFILE | LR_  CREATEDIBSECTION);
          SelectObject (hdcMem, hBtmHG) ;
    	BitBlt(hdc,0,0,540,607,hdcMem, 0, 0, SRCCOPY);					
    
    	Fensterrect.bottom = 1000;
    	Fensterrect.left = 0;
    	Fensterrect.right = 1000;
    	Fensterrect.top = 0;
    	InvalidateRect(hwnd, &Fensterrect, TRUE);
    	UpdateWindow(hwnd);
    	};
    

    Dann würde meine Oberfläche so aussehen:
    http://www.sro.at/bildupload/images/HG-weg.jpg
    also mein Hintergrundbild wird von InvalideRect halt "zerstört", aber meine Controls sind zu sehen ...

    Aber jetzt kommts, wenn ich jetzt zusätzlich noch die WM_PAINT-Message (wird ja mit UpdateWindow(hwnd) hervorgerufen) so umlenke, dass sie mir wieder meine PM_MALEN mit dem wParam 4 aufruft, also so:

    case WM_PAINT :
    			{
    				SendMessage(hwnd,PM_MALEN,4,0);				
    			};
    

    Dann sieht meine Oberfläche klasse aus, also so:
    http://www.sro.at/bildupload/images/gut.jpg

    ABer dann komm ich ja sozusagen in eine "Endlosschleife, weil meine PM_MALEN ja dann ständig eine WM_PAINT-Message schickt und andersrum ...
    Aber das wirkt sich irgendwie nicht auf meine CPU-Auslastung aus ...
    Kann mir das einer von euch erklären, würde mich freuen!



  • Du musst Windows irgendwo sagen, dass dein Fensterinhalt wieder gültig ist (ValidateRect) - normalerweise macht man dies mittels Begin-/EndPaint bei WM_PAINT. Also zeiche lieber alle in WM_PAINT und leite lieber PM_MALEN dorthin mit InvalidateRect um - deinen Parameter von dort kannst du ja z.B. in einer static Variable speichern...



  • So, der Osterstress hat sich ein wenig gelegt, jetzt habe ich wieder Zeit für andere Dinge ...

    Also dankeschön für deine Antwort!
    Jetzt habe ich nurnoch das Problem, dass unter meinen mit TextOut()-erstellten Texten so ein doofer weißer Hintergrund ist! Ich dachte eigentl. dass man das mit einem Brush beheben kann, und habe es auch so probiert:

    hBrush = CreatePatternBrush(hBtmHG);
    	SelectObject(hdc, hBrush);
    	SelectObject(hdcMem, hBrush);				
    
    	MoveToEx(hdc,460,158,NULL);
    	LineTo(  hdc,505,158);
    
    	wsprintf(szNachricht,"Summe1:");
    	TextOut(hdc,280,164,szNachricht,7);
    	wsprintf(szPunkte,"%3d",Summe0);
    	TextOut(hdc,472,164,szPunkte,3);				
    	wsprintf(szNachricht,"Bonus (63/35 bzw 85/50):");
          TextOut(hdc,280,184,szNachricht,24);
    	wsprintf(szPunkte,"%3d",Bonus);
    	TextOut(hdc,472,184,szPunkte,3);
          . 
          .
          .
    

    Dabei ist hBtmHG das Handel zu meinem Hintergrundbitmap!

    Aber der Hintergrund der Text bleibt immernoch weiß, dies sieht man auch an den Screenshots von oben, die ich da gezeigt habe ...

    Danke!


Log in to reply