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; }