簡體   English   中英

MFC自定義按鈕控件

[英]MFC Custom Button control

我在mfc(VS 2013)DLL中創建了一個自定義按鈕。 工作正常。 我創建了一個測試對話框exe來測試dll。 然后,我添加了一些代碼來模擬懸停效果。 現在,當我運行Dialog exe時,該按鈕會根據需要顯示,但是將光標移到該按鈕的頂部時,漸變會發生變化,但會引發Debug斷言。

void CBootstrapButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{

    dc = CDC::FromHandle(lpDrawItemStruct->hDC);//Get device context object

    m_bIsFocused = (lpDrawItemStruct->itemState & ODS_FOCUS);
    m_bIsDisabled = (lpDrawItemStruct->itemState & ODS_DISABLED);
    m_bIsPressed = (lpDrawItemStruct->itemState & ODS_SELECTED);

    //Preparing the Region to Draw

    CRect btnRect = lpDrawItemStruct->rcItem;
    int iCX = lpDrawItemStruct->rcItem.right;
    int iCY = lpDrawItemStruct->rcItem.bottom;

    CRgn Rgn1;//<-this is where I am getting assertion error
    Rgn1.CreateRoundRectRgn(0, 0, lpDrawItemStruct->rcItem.right, lpDrawItemStruct->rcItem.bottom, 10, 10);
    dc->SelectClipRgn(&Rgn1);

    MemDC.CreateCompatibleDC(dc);
    pDC = &MemDC;

    Bmp.CreateCompatibleBitmap(dc, iCX, iCY);
    OldBitmap = MemDC.SelectObject(&Bmp);

    border = RGB(219, 219, 219);//Button Border color

    /******* Some Color Logic*******/

    //Applying Border
    pDC->RoundRect(0, 0, lpDrawItemStruct->rcItem.right, lpDrawItemStruct->rcItem.bottom, 10, 10);
    pDC->FillSolidRect(&lpDrawItemStruct->rcItem, border);

    if (m_bIsFocused)
    {
        pDC->DrawFocusRect(&lpDrawItemStruct->rcItem);
    }

    //Applying Gradients
    CRgn Rgn2;
    Rgn2.CreateRoundRectRgn(1, 1, lpDrawItemStruct->rcItem.right - 1, lpDrawItemStruct->rcItem.bottom - 1, 10, 10);
    pDC->SelectClipRgn(&Rgn2);

    RECT rect = lpDrawItemStruct->rcItem;

    for (int i = 0; i<rect.bottom; i++)  
    {
        int r, g, b;
        r = r1 + (i * (r2 - r1) / rect.bottom);
        g = g1 + (i * (g2 - g1) / rect.bottom);
        b = b1 + (i * (b2 - b1) / rect.bottom);
        pDC->FillSolidRect(0, i, rect.right, 1, RGB(r, g, b));
    }

    //Start Drawing Text
    CString strText;
    GetWindowText(strText);
    int iOldMode = pDC->SetBkMode(TRANSPARENT);

    COLORREF crOldColor;

    //Setting Text Color
    if (btnStyle==BTN_DEFAULT)
    {
        crOldColor = pDC->SetTextColor(RGB(0, 0, 0));
    }
    else
    {
        crOldColor = pDC->SetTextColor(RGB(255, 255, 255));
    }


    //Setting Font for Text (Default Font Name=Open Sans,Default Font Size=24)
    //TODO Font Size according to Button Size.
    CFont font;
    font.CreateFont(
        24,                        // nHeight//Font Size
        0,                         // nWidth
        0,                         // nEscapement
        0,                         // nOrientation
        FW_NORMAL,                 // nWeight
        FALSE,                     // bItalic
        FALSE,                     // bUnderline
        0,                         // cStrikeOut
        ANSI_CHARSET,              // nCharSet
        OUT_DEFAULT_PRECIS,        // nOutPrecision
        CLIP_DEFAULT_PRECIS,       // nClipPrecision
        DEFAULT_QUALITY,           // nQuality
        DEFAULT_PITCH | FF_SWISS,  // nPitchAndFamily
        _T("Open Sans"));

    CFont* def_font = pDC->SelectObject(&font);

    //Draw Text
    pDC->DrawText(strText, &lpDrawItemStruct->rcItem, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
    dc->BitBlt(0, 0, iCX, iCY, pDC, 0, 0, SRCCOPY);

    pDC->SetTextColor(crOldColor);
    pDC->SetBkMode(iOldMode);
    pDC->SelectObject(OldBitmap);
    pDC->SelectObject(def_font);
    //End Drawing Text

    //Cleaning up
    pDC->DeleteDC();
    dc->SelectClipRgn(NULL);
    dc->Detach();
}

懸停效果代碼

void CBootstrapButton::OnMouseMove(UINT nFlags, CPoint point)
{
    CWnd* wndUnderMouse = NULL;
    CWnd* wndActive = this;
    TRACKMOUSEEVENT csTME;

    CButton::OnMouseMove(nFlags, point);

    ClientToScreen(&point);
    wndUnderMouse = WindowFromPoint(point);

    if (nFlags & MK_LBUTTON && m_bMouseOnButton == FALSE) return;

    wndActive = GetActiveWindow();

    if (wndUnderMouse && wndUnderMouse->m_hWnd == m_hWnd && wndActive)
    {
        if (!m_bMouseOnButton)
        {
            m_bMouseOnButton = TRUE;

            Invalidate();

            csTME.cbSize = sizeof(csTME);
            csTME.dwFlags = TME_LEAVE;
            csTME.hwndTrack = m_hWnd;
            ::_TrackMouseEvent(&csTME);
        } // if
    }
    else CancelHover();
} 

void CBootstrapButton::CancelHover()
{
    if (m_bMouseOnButton)
    {
        m_bMouseOnButton = FALSE;
        Invalidate();
    }
}

嘗試

this->ReleaseDC(dc);

代替

dc->Detach();

在您的功能結束時。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM