Управление пользовательской кнопкой MFC

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

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

1

Решение

Пытаться

this->ReleaseDC(dc);

вместо

dc->Detach();

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

0

Другие решения