Altes Systemtray Problem :(



  • Hallo,

    ich habe mal wieder das alte Systemtry Problem. Soviel ich gesehen
    habe, ist es noch nicht richtig gelösst.
    Ich starte einen Dialog minimiert und erzeuge das Systemtray Icon.
    Nach 1 Sekunde hide ich den Dialog, sodass er nicht mehr in der
    Taskleiste erscheint, dafür aber im Systemtray.
    Nun kann ich den Dialog über Abfrage des Systemtrays wiederherholen.
    Soweit so gut, wurde hier ja schon zu oft erklärt.
    Nun habe ich aber einen transparenten Dialog, der in OnPaint speziell
    gezeichnet wird. Bei einem Wiederherstellen wird lustigerweise kein
    OnPaint aufgerufen. Ein OnEraseBkgnd Event brachte auch nicht den Erfolg,
    hat aber nach dem Maximieren immerhin schon mal reagiert.
    Der Dialog ist zwar ausgeschnitten, hat aber statt Farbe nur Grau im Bild.
    Es fehlen also die Bilddaten auf dem Ausschnitt.
    Lasse ich den Dialog zur Seite Raus und ziehe ihn wieder zurück ist an der
    Stelle die Farbe wieder da. Überlappe ich ein anderes Fenster ist die Farbe
    wieder da, ebenso alle weiteren minimize und maximize funktionieren.
    Das ganze passiert nicht, wenn ich im OnInit den SW_MINIMIZE weglasse und
    den Dialog kurzzeitig anzeigen lasse.

    Hier Teile meines Codes, natürlich nur die wichtigen Teile:

    void CSampleDlg::OnPaint() 
    {
    
    	// device context for painting
    	CPaintDC dc(this); 
    	//Create a memory DC
    	HDC hMemDC = ::CreateCompatibleDC(NULL);
    	//Select the bitmap in the memory dc.
    	SelectObject(hMemDC, m_hBitmap);
    	//Copy the memory dc into the screen dc
    	::BitBlt(dc.m_hDC, 0, 0, m_Bitmap.bmWidth, m_Bitmap.bmHeight, hMemDC, 0, 0, SRCCOPY);
    	//Delete the memory DC and the bitmap
    	::DeleteDC(hMemDC);
    	CDialog::OnPaint();
    }
    
    void CSampleDlg::OnClose()
    {
    	// TODO: Fügen Sie hier Ihren Meldungsbehandlungscode ein, und/oder benutzen Sie den Standard.
    	DeleteObject(m_hBitmap);	//not really need but what the heck.
    	CDialog::OnClose();
    }
    
    void CSampleDlg::OnLButtonDown(UINT nFlags, CPoint point)
    {
    	// TODO: Add your message handler code here and/or call default
    	PostMessage( WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM( point.x, point.y));
    	CDialog::OnLButtonDown(nFlags, point);
    }
    
    void CSampleDlg::OnSize(UINT nType, int cx, int cy)
    {
    
    	// Load the image
    	m_hBitmap = (HBITMAP)LoadBitmap(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDB_Style));
    	//Get information about the bitmap..
    	GetObject(m_hBitmap, sizeof(m_Bitmap), &m_Bitmap);	// Get info about the bitmap 
    	// Put the bitmap into a memory device context
    	CPaintDC dc(this);
    	//get a memory dc object
    	CDC dcMem;
    	//create a compatible dc
    	dcMem.CreateCompatibleDC(&dc);	// Select the bitmap into the in-memory DC
    	//Select the bitmap into the dc
    	CBitmap* pOldBitmap = dcMem.SelectObject(CBitmap::FromHandle(m_hBitmap));
    	//Create a couple of region objects.
    	CRgn crRgn, crRgnTmp;
    	//create an empty region
    	crRgn.CreateRectRgn(0, 0, 0, 0);
    	//Create a region from a bitmap with transparency colour of Purple
    	COLORREF crTransparent = TRANSPARENTCOLOR;	
    	int iX = 0;
    
    	for (int iY = 0; iY < m_Bitmap.bmHeight; iY++)
    	{
    		do
    		{
    			//skip over transparent pixels at start of lines.
    			while (iX <= m_Bitmap.bmWidth && dcMem.GetPixel(iX, iY) == crTransparent)
    				iX++;
    			//remember this pixel
    			int iLeftX = iX;
    			//now find first non transparent pixel
    			while (iX <= m_Bitmap.bmWidth && dcMem.GetPixel(iX, iY) != crTransparent)
    				++iX;
    			//create a temp region on this info
    			crRgnTmp.CreateRectRgn(iLeftX, iY, iX, iY+1);
    			//combine into main region.
    			crRgn.CombineRgn(&crRgn, &crRgnTmp, RGN_OR);
    			//delete the temp region for next pass (otherwise you'll get an ASSERT)
    			crRgnTmp.DeleteObject();
    		}while(iX < m_Bitmap.bmWidth);
    		iX = 0;
    	}
    	//Centre it on current desktop
    	SetWindowRgn(crRgn, TRUE);
    	iX = (GetSystemMetrics(SM_CXSCREEN)) / 2 - (m_Bitmap.bmWidth / 2);
    	iY = (GetSystemMetrics(SM_CYSCREEN)) / 2 - (m_Bitmap.bmHeight / 2);
    	//SetWindowPos(&wndTopMost, iX, iY, m_Bitmap.bmWidth, m_Bitmap.bmHeight, NULL); 
    	SetWindowPos(NULL, iX, iY, m_Bitmap.bmWidth, m_Bitmap.bmHeight, NULL); 
    
    	// Free resources.
    	dcMem.SelectObject(pOldBitmap);	// Put the original bitmap back (prevents memory leaks)
    	dcMem.DeleteDC();
    	crRgn.DeleteObject();
    }
    


  • Achja, schon gelösst.
    Ich musste im OnEraseBkgrond den Status bRetValue zwischenspeichern.
    Etwa so:

    BOOL CSampleDlg::OnEraseBkgnd(CDC* pDC)
    {
    	BOOL bRetValue = CDialog::OnEraseBkgnd(pDC);
    	// device context for painting
    	CPaintDC dc(this); 
    	//Create a memory DC
    	HDC hMemDC = ::CreateCompatibleDC(NULL);
    	//Select the bitmap in the memory dc.
    	SelectObject(hMemDC, m_hBitmap);
    	//Copy the memory dc into the screen dc
    	::BitBlt(dc.m_hDC, 0, 0, m_Bitmap.bmWidth, m_Bitmap.bmHeight, hMemDC, 0, 0, SRCCOPY);
    	//Delete the memory DC and the bitmap
    	::DeleteDC(hMemDC);
    
    	return bRetValue;
    }
    

Anmelden zum Antworten