Auf transparentem Fenster zeichnen



  • Hallo.

    Mein Ziel ist es ein Popup-Fenster zu erstellen, dass transparent ist und auf dem ich "zeichnen" kann.

    Das Popup-Fenster erstelle ich so:

    hwnd = CreateWindowEx(
    		0,
    		szClassName,                  // "Testwindow"
    		"Test...",					// Titel
    		WS_SYSMENU|WS_POPUP,		  // Window-Long / Style
    		50,	   				    // position x (default: CW_USEDEFAULT)
    		200,	   				   // position y (default: CW_USEDEFAULT)
    		WINDOW_WIDTH,				 // Breite
    		WINDOW_HEIGHT,				// Höhe
    		HWND_DESKTOP,				 // Kind vom Desktop
    		NULL,						 // Kein Menü
    		hThisInstance,	   		 // Program Instance handler
    		NULL
    	);
    

    Ich zeichne so (in WindowProcedure):

    if (message == WM_PAINT) {
    		PAINTSTRUCT ps;
    		brush = CreateSolidBrush(col);
    		HDC dc;
    		dc = NULL;
    		dc = BeginPaint(hwnd, &ps);
    		SelectObject(dc, brush);
    		FillRect(dc, &ColorRect, brush);
    		EndPaint(hwnd, &ps);
    	}
    

    Das klappt auch. Allerdings soll das Fenster nun transparent sein, so dass nur das gezeichnete Rechteck zu sehen ist.

    Das habe ich so versucht:

    SetWindowLong(hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_LAYERED);
    

    Nun ist allerdings das ganze Fenster transparent, wobei ja das Rechteck sichtbar sein sollte.

    Wie stelle ich das an?

    Wer den kompletten Code sehen will:
    main.cpp - main.h

    Vielen Dank für Hilfe und Tipps!


  • Mod

    Ich verstehe jetzt nicht was sichtbar sein soll und was transparent.

    Evtl. ist ja SetLayeredWindowsAttribut was Du suchst.
    http://msdn.microsoft.com/en-us/library/ms633540(VS.85).aspx

    Du kannst dort eine entsprechende Farbe definieren, die als Transparent gilt...



  • Danke! Mit LWA_COLORKEY funktioniert es.

    Zum Verständnis:
    Das Hauptfenster (grauer Hintergrund) sollte transparent sein.
    Das gezeichnete Rechteck sollte sichtbar sein.

    Noch eine andere Frage:
    Wie ist es möglich ein GUI-Programm zu erstellen ohne dass es einen Eintrag in der Taskbar hat?

    // Edit:
    WS_EX_TOOLWINDOW ist die Lösung. Ich dachte zuerst das könnte ich nicht mit WS_POPUP kombinieren, aber klappt doch.

    Danke für die Hilfe,
    Thomas



  • Mit Shell_NotifyIcon kannst du übrigens ein Icon im Systray anzeigen lassen und Menüs einblenden etc.

    Du schreibst

    Das Hauptfenster (grauer Hintergrund) sollte transparent sein.

    , das Rechteck jedoch sichtbar. Das heißt für mich, dass du Teile des Fensters wirklich ausblenden möchtest und nicht transparent über andere Fenster zeichnen lassen möchtest.
    Für so etwas kannst du ja mal bei Codeproject vorbeischauen. Die einzige Funktion die du aus diesem Projekt brauchst, ist CreateRgnFromFile. Das Fenster kann somit beliebige Formen (abhängig vom übergebenen Bitmap) annehmen.



  • Problem ist allerdings, dass sich der anzuzeigende Bereich immer ändert, so dass mir ein fixes Bild nichts bringt.

    Aber ich habe nun auch eine andere Möglichkeit gefunden den Hintergrund transparent zu bekommen:

    wincl.hbrBackground = (HBRUSH) GetStockObject(NULL_BRUSH);
    

    Funktioniert gut, denn so kann ich SetLayeredWindowAttributes(hwnd, 0, ..., LWA_ALPHA); immer noch dazu nutzen um die Alpha-Transparenz der Applikation zu verändern.

    Allerdings habe ich nun ein neues Problem.
    Ich zeichne so auf das Fenster:

    if (message == WM_PAINT) {
    		Recht rect;
    		rect.top = 0;
    		rect.bottom = 120;                // Höhe
    		PAINTSTRUCT ps;
    		HDC dc = BeginPaint(hwnd, &ps);
    		SelectObject(dc, brush);
    		for (int i=0; i<3; i++) {
    			rect.left = i*30;             // Das nächte Rechteck ist 30 Pixel weiter rechts
    			rect.right = rect.left + 20;  // Breite von 20 Pixeln
    
    			FillRect(dc, &rect, brush);   // Rechteck zeichnen
    		}
    		EndPaint(hwnd, &ps);
    	}
    

    Das erzeugt 3 Rechtecke. Leider ist der Zwischenraum dazwischen nicht transparent, sondern einfach schwarz.

    Ich habe bereits ps.fErase = true; und SetBkColor(dc, TRANSPARENT); probiert. Funktioniert leider beides nicht.

    Wäre nochmals sehr dankbar für Hilfe. 🙂



  • versuch mal SetBkMode statt SetBkColor


Anmelden zum Antworten