In Titelleiste von einem Fenster zeichnen / schreiben
-
Hallo,
Ich möchte mit der WinApi unter MASM32 in meiner Titelleiste zeichnen.
Dafür benutze ich in der WindowProc folgenden Code:WndProc proc hWin :DWORD, uMsg :DWORD, wParam :DWORD, lParam :DWORD LOCAL WDC:DWORD .if uMsg == WM_DESTROY invoke PostQuitMessage,NULL mov eax, 0 ret .elseif uMsg == WM_LBUTTONDOWN .elseif uMsg == WM_KEYDOWN .elseif uMsg == WM_PAINT .elseif uMsg == WM_NCPAINT invoke GetWindowDC, hWin mov WDC, eax ;unser Gesamtes Fenster ist in WDC gespeichert invoke Rectangle,WDC, 4,10,100,100 invoke ReleaseDC,hWin, WDC .endif invoke DefWindowProc,hWin,uMsg,wParam,lParam ret WndProc endp
Da die meisten hier mit C/C++ Arbeiten sollte der Code nicht ganz fremd sein...
Warum ich den Code als Antwort auf NCPaint schreibe liegt daran das er dort,
(und nur dort) halbwegs funktioniert.
Jedoch auch erst wenn mein Fenster von einem anderen überdeckt wurde, bis dahin
erstrahlt mein Rahmen in schönem weißWenn ich den Code bei WM_PAINT unterbringe wird grundsätzlich
nur im Clientbereich gezeichnet und nicht in der Titelleiste.1. Fehlt mir der Aufruf einer Funktion, damit mein Fenster gleich "richtig"
dargestellt wird? Wie schon geschrieben ist mein Fenster erst nach dem
überlappen durch ein anderes so wie es sein sollte.
ShowWindow() und UpdateWindow() werden nach der Erstellung bereits aufgerufen.2. Im Beispiel aus dem Buch wird auf den Klick auf einen Menüpunkt in der
Titelleiste gezeichnet. Das geht bei mir garnicht, da außerhalb von NCPAINT nur
auf dem Clientbereich gezeichnet wird. Vielleicht hat hier auch noch jemand
einen Rat.Die Funktion GetWindowDC() liefert mir ja den Gerätecontext des gesamten
Fensters zurück.Danke und Gruß,
Nicky
-
Der Sinn der Titelleiste ist, dass Windows sie malt und nicht du. Wenn du das doof findest blende die Titelleiste aus und male deine eigene.
Du kannst zwar im Prinzip selbst in der Titelleiste rummalen, aber Windows wird dir pseudozufällig wieder drübermalen, woraus Flackern oder halb gemalter Text resultiert, was du wahrscheinlich nie ganz weg kriegst.
-
Wenn Windows die Titelleiste zeichnet, schickt es an das Fenster die Nachricht WM_NCPAINT. behandele diese Nachricht in deiner Wndproc und ruf da deine Z1eichenroutinen auf.
@nwp3: Diese Erfahrungen habe ich bisher nicht gemacht. Aber ich habe so was auch nur mal als Spielerei zum Ausprobieren gemacht und nicht produktiv angewendet.
-
_Luckie schrieb:
Wenn Windows die Titelleiste zeichnet, schickt es an das Fenster die Nachricht WM_NCPAINT. behandele diese Nachricht in deiner Wndproc und ruf da deine Z1eichenroutinen auf.
Und gib dann 0 zurück und rufe nicht mehr DefWindowProc auf.
-
Der Sinn der Titelleiste ist, dass Windows sie malt und nicht du. Wenn du das doof findest blende die Titelleiste aus und male deine eigene.
@nwp3:
Sorry, aber warum jemand in der Titelleiste malen will oder nicht, das sei doch ihn selber überlassen... Zumindest finde ich deinen Beitrag einfach nur unpassend, denn Dein Beitrag führt nicht ansatzweise zu einer Lösung des Problems bzw der eigentlichen Frage! (zumindest ist das meine persönliche Meinung, ohne dich irgendwie angreifen zu wollen)@supernicky:
Ich bin mir gerade nich ganz sicher; aber um den Bereich der Titelleiste zu erhalten, müsste das dann nicht in etwa wie folgt sein?// Code ist einfach so geschrieben - ohne zu testen... HWND hDC = GetDC(hWnd); RECT rc; rc.left = 0; rc.top = 0; rc.right = 800; // Fensterbreite rc.bottom = r.top - GetSystemMetrics(SM_CYCAPTION); DrawCaption(hWnd,hDC,rc,DC_GRADIENT|DC_TEXT|DC_ACTIVE|DC_ICON);
Zumindest könnte man so auch u.a. mit DrawCaption() die Titelleiste (Icon+Text+Gradient) an jeder Stelle im Fenster zeichnen.
-
Hi nicky,
hier findest Du ein paar Ideen/Hinweise/Beispiele:
http://masm32.com/board/index.php?topic=245.0
http://www.catch22.net/tuts/custom-titlebar
-
Hallo nochmal,
@nwp3
Ich statte meine Programme nicht mit solchen Spielerein aus.. ich versuche nur den C-Code aus den Büchern mit MASM umzusetzen.@alle anderen
Ich werde mein Programm mal auf WinXP testen, ich glaube gelesen zu haben das dies wohl mit Windows AERO zu tun hat.
Da mein Programm nach einmaligem überlappen durch ein anderes Fenster jedoch "richtig" funktioniert (und aussieht),
wollte ich mal fragen welche Funktion beim Überdecken von Windows aufgerufen wird?
Vielleicht kann ich diese Funktion nach WM_CREATE selbst aufrufen damit mein Programm den weißen Rahmen
am Anfang nicht mehr anzeigt.InvalidateRect() hab ich schon versucht. Leider kein Erfolg.
Trotzdem Danke
Nicky
-
Mit Spielereien meint ihr eine Titelleiste?
Solche Spielereien wie eine Titelleiste zu malen willst du nicht, aber in der Titelleiste malen ist ok. Das verstehe ich nicht.Bei InvalidateRect steht, dass das nur die Client-Area neu malt und die Titelleiste gehört nicht dazu. Versuch mal RedrawWindow mit der RDW_FRAME-Flag.