I have created a custom button in mfc(VS 2013)DLL. It worked Fine. I have created a test dialog exe to test the dll. Then I added some code to simulate hover effect. Now when I run the Dialog exe, the button appears as wanted but when move the cursor on top of the button, the gradient changes but it throws an Debug Assertion.
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();
}
Code for hover 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();
}
}
Try
instead of
at the end of your function.