Stretch Bitmap


  • Mod



  • Ehrlicherweise muss ich sagen, dass ich bei Ownerdraw nicht verstehe, ob man eine Klasse von CButton ableiten muss, und dann den neuen Button per Hand mittels Create ins Dialogfeld einbauen muss, und die Messageshändler ebenfalls per "Hand" einrichten muss. Und eine Frage zu Subclassing: Kann man eine Subklasse für mehrere Steuerelemente verwenden ? Wenn es darum geht Hintergrundbilder zu zeichnen, woher weiss eine Instanz der Subklasse, für welches Steuerelement sie zeichnen soll ? Wie ist das bei Ownerdraw ? Fällt mir ein, dass man das über den Konstruktor erreichen kann .... Sorry ...



  • Du musst nichts ableiten, einfach Ownerdraw im Editor auf true setzen (oder bei dem Button direkt das Flag BS_OWNERDRAW), in BEGIN_MESSAGE_MAP ON_WM_DRAWITEM einfügen und es wird beim Dialog OnDrawItem aufgerufen.

    void MyDlg::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct)
    {
    	if(nIDCtl == /*ID des Buttons*/)
    	{
    		CWnd* wnd = GetDlgItem(nIDCtl);
            // Das Bitmap muss natürlich zuvor, in OnInitDialog bspw., mit BM_SETIMAGE gesetzt worden sein
    		HBITMAP bitmap = reinterpret_cast<HBITMAP>(wnd->SendMessage(BM_GETIMAGE, IMAGE_BITMAP, 0)); 
    		BITMAP bmInfo = { };
    		GetObject(bitmap, sizeof(BITMAP), &bmInfo);
    		HDC hdcMem = CreateCompatibleDC(lpDrawItemStruct->hDC);
    		HGDIOBJ oldbm = SelectObject(hdcMem, bitmap);
    
    		StretchBlt(lpDrawItemStruct->hDC,
    			lpDrawItemStruct->rcItem.left,
    			lpDrawItemStruct->rcItem.top,
    			lpDrawItemStruct->rcItem.right-lpDrawItemStruct->rcItem.left,
    			lpDrawItemStruct->rcItem.bottom-lpDrawItemStruct->rcItem.top,
    			hdcMem,
    			0, 0, bmInfo.bmWidth, bmInfo.bmHeight,
    			SRCCOPY);
    		SelectObject(hdcMem, oldbm);
    		DeleteDC(hdcMem);
    
            // Optional ein Focus-Rect, gelöscht wird es in diesem Fall mit dem Bitmap selber, wenn das Bitmap
            // kleiner dargestellt wird, könnte es mit FrameRect gelöscht werden
    		if(lpDrawItemStruct->itemState & ODS_FOCUS)
    			DrawFocusRect(lpDrawItemStruct->hDC, &lpDrawItemStruct->rcItem);
    	//	else
    	//		FrameRect(lpDrawItemStruct->hDC, &lpDrawItemStruct->rcItem, GetSysColorBrush(COLOR_3DFACE));
    	}
    	else
    	{
    		CDialog::OnDrawItem(nIDCtl, lpDrawItemStruct);
    	}
    

    Das ist natürlich die einfachste Variante (vor allem ohne Returnwertüberprüfung), die noch beliebig erweitert werden kann. Schon jetzt sollte der Code aber in eine eigene Funktion gepackt werden. Dann kann diese Funktion eben auch für verschiedene Buttons mit unterschiedlichen Bitmaps aufgerufen werden.



  • Danke yahendrik, da fällt mir ein Stein vom Herzen ! Danke Euch !!! Tschüss ...



  • So und nun doch noch was, das mit ownerdraw mit Stretch hat gut funktioniert, jetzt kam ich auf die Idee, um mein Bitmap einen "Bilderrahmen" zu zeichnen, bei CDC gibt es die Member Rectangle, das löscht aber das Bitmap. Weiss jemand Rat ? Gegoogelt habe ich schon, vielleicht zu wenig, jaja ich nerve eben ...



  • Entweder einen transparenten Pinsel verwenden, DrawEdge oder 4 mal LineTo aufrufen.



  • DrawEdge zeichnet nur einen ganz dünnen Rahmen, der sollte 20 Pixel breit sein , und ein hölzernes Aussehen haben, zuviel verlangt ?



  • Ist wohl eher eine Sache eines Paint-Programms, da suche ich gerade ( zur Vervollständigung meines Wissens ) wisst Ihr welche ? Kostenlose ?



  • Paint.net sollte reichen



  • Also nochmals Danke !!!


Log in to reply