2015-06-22 2 views
1

Я создал пользовательскую кнопку в mfc (VS 2013) DLL. Он работал отлично. Я создал тестовый диалог exe для проверки DLL. Затем я добавил код для моделирования эффекта зависания. Теперь, когда я запускаю Dialog exe, кнопка появляется по желанию, но при перемещении курсора вверху кнопки, градиент меняется, но он выдает подтверждение отладки.MFC Custom Button control

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

Код для парения Effect

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(); 
    } 
} 
+1

где именно происходит утверждение отладки, в котором строка вашего кода? – Robson

+1

Каков точный текст утверждения? – rrirower

+0

Когда я нажимаю break, курсоры указывают на функцию attachHDC в wingdi.cpp – Antony

ответ

0

Попробуйте

this->ReleaseDC(dc); 

вместо

dc->Detach(); 

в конце вашей функции.

+0

По-прежнему та же проблема. – Antony