Wann ist Dialogfenster sichtbar?

fujitsufan

Erfahrenes Mitglied
Hallo zusammen,

wieder ein Problem.
Ich zeichne einen Kreis, auch ausgefüllt. Funktioniert prächtig.
Es sei denn, dass ich die Funktion welche den Kreis auf den Dialog zeichnet im Dialog-Setup aufgerufen wird.

Ich kann diese Funktion manuell per Button-Click aufrufen. Zu diesem Zeitpunkt ist das Dialogfenster sichtbar und alles wird gut.

C++:
void TElementBeschriftungDialog::PaintClock()
{
    int iTest = 0;
 
    DWORD penColor = RGB_GRAY39;
    DWORD bgColor = RGB_CYAN4;
    RECT rDialog, rClock;
    POINT pPoint, pCenterClock;
    HDC hDC;
    LONG lwidth = 0.0, lHight = 0.0;
    LONG dX = 0.0, dY = 50.0, dR = 150.0;
   
    //hDC = GetWindowDC(this->hDlg);
    hDC = GetDC(this->hDlg);
 
 
 
    HBRUSH backGroundBrush = CreateSolidBrush(bgColor);
    HPEN pen = CreatePen(0, 2, penColor);
 
    GetWindowRect(this->hDlg, &rDialog);
    lwidth = rDialog.right - rDialog.left, lHight = rDialog.bottom - rDialog.top;
 
    pPoint.x = rDialog.left, pPoint.y = rDialog.top;
    ScreenToClient(hDlg, &pPoint);
 
    pCenterClock.x = pPoint.x + lwidth / 2 + dX;
    pCenterClock.y = pPoint.y + lHight / 2 + dY;
 
    rClock.left = pCenterClock.x - dR / 2, rClock.right = pCenterClock.x + dR / 2;
    rClock.top = pCenterClock.y - dR / 2, rClock.bottom = pCenterClock.y + dR / 2;
 
 
    SelectObject(hDC, backGroundBrush);
    SelectObject(hDC, pen);
 
   
    Ellipse(hDC, rClock.left, rClock.top, rClock.right, rClock.bottom);
   
   
 
    DeleteObject(backGroundBrush);
    DeleteObject(pen);
 
}

Wie kann ich eine Windows Message abfangen, die mir signalisiert, dass das Dialogfenster sichtbar ist?
Mist folgender Funktion geht's nicht. "WM_INITDIALOG" scheint die falsche Message zu sein.
Diese kommt viel zu früh.

C++:
BOOL FAR TElementBeschriftungDialog::MsgProc(HWND hWndDlg, UINT Message, WPARAM wParam, LPARAM lParam)
{
   
 
    // select text in ctrl that has the focus
    if (Message == WM_INITDIALOG)
    {
        //this->_hDlg = hWndDlg;
    }
 
    BOOL ret = TDialog::MsgProc(hWndDlg, Message, wParam, lParam);
 
    return ret;
}

Viele Grüße.
fujitsufan
 

MCoder

Erfahrenes Mitglied
Hallo,

gezeichnet wird grundsätzlich immer bei einer WM_PAINT-Message. Nur so wird sichergestellt, dass die Zeichnung auch sichtbar ist, wenn das Fenster sichtbar ist. WM_PAINT wird auch aufgerufen, wenn das Fenster z.B. mal verdeckt war, damit die Zeichnung aktualisiert werden kann.

Gruß
MCoder
 

fujitsufan

Erfahrenes Mitglied
Hallo MCoder,

dachte ich auch erstmals.
Die Message kommt bei mir noch nicht an in der .......

C++:
BOOL FAR TElementBeschriftungDialog::MsgProc(HWND hWndDlg, UINT Message, WPARAM wParam, LPARAM lParam)
{
   
    switch (Message)
    {
    case WM_INITDIALOG:
        //this->_hDlg = hWndDlg;
        break;
    case WM_PAINT:
        InitPaint();
        PaintClock();
        break;
    }
   
 
    BOOL ret = TDialog::MsgProc(hWndDlg, Message, wParam, lParam);
 
    return ret;
}

......an

Muss mal nachschauen warum dies so ist.

Trotzdem vielen Dank!
fujitsufan
 

Endurion

Erfahrenes Mitglied
Wie erkennst du, ob WM_PAINT kommt? Hast du einen Breakpoint gesetzt?

Wenn du WM_PAINT behandelst, musst du dich an ein paar Regeln handeln:

1)
Benutze BeginPaint/EndPaint; sonst weiß Windows nicht, welche Teile vom Fenster jetzt neu gezeichnet wurden, und versucht, das Fenster immer wieder zu zeichen.
2)
Wenn du in einer DialogProc eine Nachricht behandelst, solltest du TRUE zurückgeben (und die Nachricht damit nicht an die Basis-DialogProc weiterreichen)

Unabhängig davon hast du da noch ein paar Resource-Leaks im Code:

1) Ein HDC, der per GetDC erfragt wird, muss mit ReleaseDC freigegeben werden
2) Du musst den HDC wieder in den Ausgangszustand zurückversetzen. Alle Objekte, die du per SelectObject an den HDC ent-bindest müssen wieder daran gebunden werden.

Das müsste reichen:

Code:
// Hier die alten gebundenen Objekte speichern
HBRUSH oldBrush = SelectObject( hDC, backGroundBrush );
HPEN oldPen = SelectObject( hDC, pen );

Ellipse(hDC, rClock.left, rClock.top, rClock.right, rClock.bottom);   

DeleteObject( backGroundBrush );
DeleteObject( pen );

// alte Objekte wieder neu binden
SelectObject( hDC, oldBrush );
SelectObject( hDC, oldPen );

// HDC freigeben
ReleaseDC( hDC );
 

Neue Beiträge