www.pudn.com > ExpBar_src.zip > cbbutton.c
/* * file : cbbutton.c * language : ANSI/ISO C * plattform : Win32 (Windows 98/Me/NT/2000/XP) * description : implements checkbox/radio button for xp-style explorer bar * * revision history: * ================= * * date: author: description: * -------------------------------------------------------------------------- * 02/17/2004 Ingo A. Kubbilun first published version 1.0 */ #include#include #include #define BUTTON_HSPACE 2 #define BUTTON_VSPACE1 6 #define BUTTON_VSPACE2 2 #define CHECK_HSPACE 4 #define RADIO_HSPACE 4 #define BUTTON_LEFT 0 #define BUTTON_RIGHT 1 #define BUTTON_CENTER 2 static BOOL APIENTRY GetLogFontEx ( HFONT hFont, PLOGFONT pLF, UINT *puDescent ) { HDC hDC = GetDC(NULL); HGDIOBJ hOldObj; TEXTMETRIC tm; memset(pLF,0,sizeof(LOGFONT)); if (!hDC) return FALSE; if (!hFont) { ReleaseDC(NULL,hDC); return FALSE; } hOldObj = SelectObject(hDC,hFont); if (!GetTextMetrics(hDC,&tm)) { SelectObject(hDC,hOldObj); ReleaseDC(NULL,hDC); return FALSE; } if (puDescent) *puDescent = tm.tmDescent; pLF->lfHeight = -tm.tmAscent; pLF->lfWeight = tm.tmWeight; pLF->lfItalic = tm.tmItalic; pLF->lfCharSet = tm.tmCharSet; pLF->lfQuality = DEFAULT_QUALITY; pLF->lfPitchAndFamily = tm.tmPitchAndFamily; GetTextFace(hDC,sizeof(pLF->lfFaceName),pLF->lfFaceName); SelectObject(hDC,hOldObj); ReleaseDC(NULL,hDC); return TRUE; } static void APIPRIVATE HandleClick ( HWND hwnd, PCBBUTTON pCBB ) { LONG lStyle = GetWindowLong(hwnd,GWL_STYLE); switch(lStyle & CBBS_TYPEMASK) { case CBBS_AUTOCHECKBOX: case CBBS_AUTORADIOBUTTON: pCBB->uButtonState ^= CBBST_CHECKED; InvalidateRect(hwnd,NULL,TRUE); break; case CBBS_AUTO3STATE: pCBB->uButtonState++; if (pCBB->uButtonState==3) pCBB->uButtonState = CBBST_UNCHECKED; InvalidateRect(hwnd,NULL,TRUE); break; } } static void APIPRIVATE GetHitTestRect ( HWND hwnd, PCBBUTTON pCBB, LPRECT lpRC ) { if (GetWindowLong(hwnd,GWL_STYLE) & CBBS_NOAUTOSIZE) GetClientRect(hwnd,lpRC); else { memcpy(lpRC,&pCBB->rcText,sizeof(RECT)); if (((pCBB->rcButton.right-pCBB->rcButton.left)>0) && ((pCBB->rcButton.bottom-pCBB->rcButton.top)>0)) { if (pCBB->rcButton.left < lpRC->left) lpRC->left = pCBB->rcButton.left; if (pCBB->rcButton.right > lpRC->right) lpRC->right = pCBB->rcButton.right; if (pCBB->rcButton.top < lpRC->top) lpRC->top = pCBB->rcButton.top; if (pCBB->rcButton.bottom > lpRC->bottom) lpRC->bottom = pCBB->rcButton.bottom; } } } static void APIPRIVATE CheckNeedRepaint ( HWND hwnd, PCBBUTTON pCBB ) { int iState = ITEMSTATE_COLD; RECT rcClient; POINT pt; if (!pCBB->bEnabled) iState = ITEMSTATE_DISABLED; else { GetHitTestRect(hwnd,pCBB,&rcClient); if (pCBB->bKeyDown) iState = ITEMSTATE_PRESSED; else { pt.x = pCBB->iMouseX; pt.y = pCBB->iMouseY; if (PtInRect(&rcClient,pt)) { if (pCBB->bLButtonDown) iState = ITEMSTATE_PRESSED; else iState = ITEMSTATE_HOT; } else if (GetCapture()==hwnd) iState = ITEMSTATE_HOT; } } if (pCBB->iState!=iState) { pCBB->iState = iState; InvalidateRect(hwnd,NULL,TRUE); } } // iRequiredWidth only used if !(lStyle & TLS_NOAUTOSIZE) !!! static BOOL APIENTRY GetItemSize ( HWND hwnd, PCBBUTTON pCBB, PSIZE pSI, int iRequiredWidth ) { SIZE siText,siSingleLine; TCHAR szText[256]; HDC hDC; HGDIOBJ hOldObj; RECT rcClient,rcText,rcClientOrig; LONG lStyle = GetWindowLong(hwnd,GWL_STYLE); LONG lExStyle = GetWindowLong(hwnd,GWL_EXSTYLE); UINT uDTStyle = 0L; int iTextWidth,iTextHeight,iDelta; int iPreTextWidth,iPreTextHeight; UINT uAlign; SIZE siTheme; BOOL bIsPushButton = FALSE; if (!pCBB) return FALSE; if (((lStyle & CBBS_TYPEMASK)==CBBS_PUSHBUTTON) || ((lStyle & CBBS_TYPEMASK)==CBBS_DEFPUSHBUTTON)) { uAlign = BUTTON_CENTER; bIsPushButton = TRUE; } else uAlign = BUTTON_LEFT; if (lStyle & CBBS_LEFT) uAlign = BUTTON_LEFT; else { if (lStyle & CBBS_RIGHT) uAlign = BUTTON_RIGHT; else if (lStyle & CBBS_CENTER) uAlign = BUTTON_CENTER; } if (lExStyle & WS_EX_RIGHT) { lStyle |= CBBS_LEFTTEXT; if (uAlign==BUTTON_LEFT) uAlign=BUTTON_RIGHT; else if (uAlign==BUTTON_RIGHT) uAlign=BUTTON_LEFT; } if (lStyle & CBBS_NOAUTOSIZE) { GetClientRect(hwnd,&rcClient); pSI->cx = rcClient.right; pSI->cy = rcClient.bottom; } else { if (iRequiredWidth==-1) GetClientRect(hwnd,&rcClient); else rcClient.right = iRequiredWidth; rcClient.left = rcClient.top = 0; rcClient.bottom = 32767; } memcpy(&rcClientOrig,&rcClient,sizeof(RECT)); memset(&pCBB->rcText,0,sizeof(RECT)); memset(&pCBB->rcButton,0,sizeof(RECT)); hDC = GetDC(hwnd); if (hDC) { if (bIsPushButton) hOldObj = SelectObject(hDC,pCBB->hFontNormal); else hOldObj = SelectObject(hDC,pCBB->hFontCheckedHot); szText[0]=0x00; GetWindowText(hwnd,szText,256); rcText.left = rcText.right = rcText.top = rcText.bottom = 0; uDTStyle = DT_SINGLELINE|DT_NOCLIP|DT_CALCRECT|DT_LEFT|DT_TOP; if (lExStyle & WS_EX_RTLREADING) uDTStyle |= DT_RTLREADING; siSingleLine.cy = DrawTextEx(hDC,szText,lstrlen(szText),&rcText,uDTStyle,NULL); siSingleLine.cx = rcText.right; // Calculate button and text dimensions switch(lStyle & CBBS_TYPEMASK) { case CBBS_PUSHBUTTON: case CBBS_DEFPUSHBUTTON: GetClientRect(hwnd,&rcClient); pSI->cx = rcClient.right; pSI->cy = rcClient.bottom; pCBB->rcButton.right = rcClient.right; pCBB->rcButton.bottom = rcClient.bottom; pCBB->rcText.left = BUTTON_HSPACE; pCBB->rcText.top = BUTTON_VSPACE1; pCBB->rcText.right = rcClient.right-(BUTTON_HSPACE<<1); pCBB->rcText.bottom = rcClient.bottom-(BUTTON_VSPACE1+BUTTON_VSPACE2); break; case CBBS_CHECKBOX: case CBBS_AUTOCHECKBOX: case CBBS_3STATE: case CBBS_AUTO3STATE: if (g_sEBI.bPreXP) { if (lStyle & CBBS_LEFTTEXT) // button right { pCBB->rcButton.right = rcClient.right; pCBB->rcButton.left = pCBB->rcButton.right-siSingleLine.cy; pCBB->rcButton.bottom = siSingleLine.cy; pCBB->rcText.bottom = rcClient.bottom; pCBB->rcText.right = pCBB->rcButton.left-CHECK_HSPACE; } else { pCBB->rcButton.right = siSingleLine.cy; pCBB->rcButton.bottom = siSingleLine.cy; pCBB->rcText.bottom = rcClient.bottom; pCBB->rcText.left = pCBB->rcButton.right+CHECK_HSPACE; pCBB->rcText.right = rcClient.right; } } else { siTheme.cx = siTheme.cy = 0; GetThemePartSize(pCBB->hTheme,hDC,BP_CHECKBOX,CBS_CHECKEDNORMAL,NULL,TS_DRAW,&siTheme); if (lStyle & CBBS_LEFTTEXT) // button right { pCBB->rcButton.right = rcClient.right; pCBB->rcButton.left = pCBB->rcButton.right-siTheme.cx; pCBB->rcButton.bottom = siTheme.cy; pCBB->rcText.bottom = rcClient.bottom; pCBB->rcText.right = pCBB->rcButton.left-CHECK_HSPACE; } else { pCBB->rcButton.right = siTheme.cx; pCBB->rcButton.bottom = siTheme.cy; pCBB->rcText.bottom = rcClient.bottom; pCBB->rcText.left = pCBB->rcButton.right+CHECK_HSPACE; pCBB->rcText.right = rcClient.right; } iDelta = siSingleLine.cy-siTheme.cy; if (iDelta) // >0: text>button, <0: button>text { if (iDelta<0) // button>text { pCBB->rcText.top = (-iDelta)>>1; } else { iDelta>>=1; pCBB->rcButton.top += iDelta; pCBB->rcButton.bottom += iDelta; } } } break; case CBBS_RADIOBUTTON: case CBBS_AUTORADIOBUTTON: if (g_sEBI.bPreXP) { if (lStyle & CBBS_LEFTTEXT) // button right { pCBB->rcButton.right = rcClient.right; pCBB->rcButton.left = pCBB->rcButton.right-siSingleLine.cy; pCBB->rcButton.bottom = siSingleLine.cy; pCBB->rcText.bottom = rcClient.bottom; pCBB->rcText.right = pCBB->rcButton.left-RADIO_HSPACE; } else { pCBB->rcButton.right = siSingleLine.cy; pCBB->rcButton.bottom = siSingleLine.cy; pCBB->rcText.bottom = rcClient.bottom; pCBB->rcText.left = pCBB->rcButton.right+RADIO_HSPACE; pCBB->rcText.right = rcClient.right; } } else { siTheme.cx = siTheme.cy = 0; GetThemePartSize(pCBB->hTheme,hDC,BP_RADIOBUTTON,RBS_CHECKEDNORMAL,NULL,TS_DRAW,&siTheme); if (lStyle & CBBS_LEFTTEXT) // button right { pCBB->rcButton.right = rcClient.right; pCBB->rcButton.left = pCBB->rcButton.right-siTheme.cx; pCBB->rcButton.bottom = siTheme.cy; pCBB->rcText.bottom = rcClient.bottom; pCBB->rcText.right = pCBB->rcButton.left-RADIO_HSPACE; } else { pCBB->rcButton.right = siTheme.cx; pCBB->rcButton.bottom = siTheme.cy; pCBB->rcText.bottom = rcClient.bottom; pCBB->rcText.left = pCBB->rcButton.right+RADIO_HSPACE; pCBB->rcText.right = rcClient.right; } iDelta = siSingleLine.cy-siTheme.cy; if (iDelta) // >0: text>button, <0: button>text { if (iDelta<0) // button>text { pCBB->rcText.top = (-iDelta)>>1; } else { iDelta>>=1; pCBB->rcButton.top += iDelta; pCBB->rcButton.bottom += iDelta; } } } break; default: SelectObject(hDC,hOldObj); ReleaseDC(hwnd,hDC); return FALSE; } rcText.left = 0; rcText.right = pCBB->rcText.right-pCBB->rcText.left; rcText.top = 0; rcText.bottom = 32767; if (lStyle & CBBS_FOCUSRECT) rcText.right -= 2; if (lStyle & CBBS_WORDBREAK) // multiline, use current control width { uDTStyle = DT_EXTERNALLEADING|DT_WORDBREAK; } else { if (lStyle & CBBS_END_ELLIPSIS) // singleline, use current control width { uDTStyle = DT_END_ELLIPSIS|DT_SINGLELINE; } else // singleline, ignore current control width { uDTStyle = DT_SINGLELINE|DT_NOCLIP; } } uDTStyle |= DT_CALCRECT|DT_LEFT|DT_TOP; if (lExStyle & WS_EX_RTLREADING) uDTStyle |= DT_RTLREADING; siText.cy = DrawTextEx(hDC,szText,lstrlen(szText),&rcText,uDTStyle,NULL); siText.cx = rcText.right; pCBB->bMultiLine = (siText.cy>=(siSingleLine.cy<<1)) ? TRUE : FALSE; iTextWidth = siText.cx; iTextHeight = siText.cy; if (lStyle & CBBS_FOCUSRECT) { iTextWidth += 2; iTextHeight += 2; } if (bIsPushButton) { iPreTextWidth = pCBB->rcText.right-pCBB->rcText.left; iPreTextHeight = pCBB->rcText.bottom-pCBB->rcText.top; if (iPreTextWidth>iTextWidth) { iDelta = iPreTextWidth-iTextWidth; switch(uAlign) { case BUTTON_LEFT: pCBB->rcText.right -= iDelta; break; case BUTTON_RIGHT: pCBB->rcText.left += iDelta; break; default: pCBB->rcText.left += (iDelta>>1); pCBB->rcText.right -= iDelta-(iDelta>>1); } } if (iPreTextHeight>iTextHeight) { iDelta = (iPreTextHeight-iTextHeight); pCBB->rcText.top += iDelta>>1; pCBB->rcText.bottom -= iDelta-(iDelta>>1); } else if (iPreTextHeight rcText.top -= iDelta>>1; pCBB->rcText.bottom += iDelta-(iDelta>>1); } } else { if (lStyle & CBBS_FOCUSRECT) { pCBB->rcText.top --; if (pCBB->rcText.top<0) { pCBB->rcText.top ++; pCBB->rcButton.top ++; pCBB->rcButton.bottom ++; } } pCBB->rcText.bottom = pCBB->rcText.top + iTextHeight; iPreTextWidth = pCBB->rcText.right-pCBB->rcText.left; if (iPreTextWidth>iTextWidth) { iDelta = iPreTextWidth-iTextWidth; switch(uAlign) { case BUTTON_LEFT: pCBB->rcText.right -= iDelta; break; case BUTTON_RIGHT: pCBB->rcText.left += iDelta; break; default: iDelta>>=1; pCBB->rcText.left += iDelta; pCBB->rcText.right -= iDelta; } } } SelectObject(hDC,hOldObj); ReleaseDC(hwnd,hDC); } if ((lStyle & CBBS_NOAUTOSIZE) || ((lStyle & CBBS_TYPEMASK)==CBBS_PUSHBUTTON) || ((lStyle & CBBS_TYPEMASK)==CBBS_DEFPUSHBUTTON)) return TRUE; // pSI füllen memcpy(&rcText,&pCBB->rcText,sizeof(RECT)); if (((pCBB->rcButton.right-pCBB->rcButton.left)>0) && ((pCBB->rcButton.bottom-pCBB->rcButton.top)>0)) { if (pCBB->rcButton.left < rcText.left) rcText.left = pCBB->rcButton.left; if (pCBB->rcButton.right > rcText.right) rcText.right = pCBB->rcButton.right; if (pCBB->rcButton.top < rcText.top) rcText.top = pCBB->rcButton.top; if (pCBB->rcButton.bottom > rcText.bottom) rcText.bottom = pCBB->rcButton.bottom; } pSI->cx = rcText.right/*-rcText.left*/; pSI->cy = rcText.bottom/*-rcText.top*/; return TRUE; } LRESULT CALLBACK CBButtonWndProc ( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { switch(uMsg) { case WM_GETORIGDIMENSIONS: { PCBBUTTON pCBB = (PCBBUTTON)GetWindowLong(hwnd,GWL_USERDATA); if (pCBB) { *((int*)wParam) = pCBB->iOrigWidth; *((int*)lParam) = pCBB->iOrigHeight; } else { *((int*)wParam) = 0; *((int*)lParam) = 0; } return 0L; } case WM_CREATE: { PCBBUTTON pCBB = (PCBBUTTON)malloc(sizeof(CBBUTTON)); LOGFONT lf; SIZE si; if (!pCBB) return -1L; memset(pCBB,0,sizeof(CBBUTTON)); { RECT rcClient; GetClientRect(hwnd,&rcClient); pCBB->iOrigWidth = rcClient.right; pCBB->iOrigHeight = rcClient.bottom; } pCBB->cbSize = sizeof(CBBUTTON); if (!g_sEBI.bPreXP) { pCBB->hTheme = OpenThemeData(hwnd,L"BUTTON"); if (!pCBB->hTheme) { free(pCBB); return -1L; } } pCBB->bEnabled = IsWindowEnabled(hwnd); pCBB->iMouseX = -1; pCBB->iMouseY = -1; pCBB->iState = pCBB->bEnabled ? ITEMSTATE_COLD : ITEMSTATE_DISABLED; if (GetLogFontEx((HFONT)GetStockObject(DEFAULT_GUI_FONT),&lf,&pCBB->uDescent)) { lf.lfWeight = FW_NORMAL; lf.lfItalic = FALSE; lf.lfUnderline = FALSE; pCBB->hFontNormal = CreateFontIndirect(&lf); lf.lfUnderline = TRUE; pCBB->hFontHot = CreateFontIndirect(&lf); lf.lfWeight = FW_BOLD; pCBB->hFontCheckedHot = CreateFontIndirect(&lf); lf.lfUnderline = FALSE; pCBB->hFontCheckedNormal = CreateFontIndirect(&lf); } SetWindowLong(hwnd,GWL_USERDATA,(LONG)pCBB); if (GetItemSize(hwnd,pCBB,&si,-1)) SetWindowPos(hwnd,NULL,0,0,si.cx,si.cy,SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOOWNERZORDER|SWP_NOZORDER); return 0L; } case WM_ENABLE: { PCBBUTTON pCBB = (PCBBUTTON)GetWindowLong(hwnd,GWL_USERDATA); if (!pCBB) return 0L; pCBB->bEnabled = wParam ? TRUE : FALSE; pCBB->iState = pCBB->bEnabled ? ITEMSTATE_COLD : ITEMSTATE_DISABLED; InvalidateRect(hwnd,NULL,TRUE); return 0L; } case WM_DESTROY: { PCBBUTTON pCBB = (PCBBUTTON)GetWindowLong(hwnd,GWL_USERDATA); if ((pCBB) && (pCBB->cbSize==sizeof(CBBUTTON))) { if (pCBB->hTheme) CloseThemeData(pCBB->hTheme); if (pCBB->hFontNormal) DeleteObject(pCBB->hFontNormal); if (pCBB->hFontHot) DeleteObject(pCBB->hFontHot); if (pCBB->hFontCheckedNormal) DeleteObject(pCBB->hFontCheckedNormal); if (pCBB->hFontCheckedHot) DeleteObject(pCBB->hFontCheckedHot); free(pCBB); SetWindowLong(hwnd,GWL_USERDATA,(LONG)0L); } break; } case WM_THEMECHANGED: { PCBBUTTON pCBB = (PCBBUTTON)GetWindowLong(hwnd,GWL_USERDATA); if (pCBB) { if (pCBB->hTheme) { CloseThemeData(pCBB->hTheme); pCBB->hTheme = NULL; } if (!g_sEBI.bPreXP) pCBB->hTheme = OpenThemeData(hwnd,L"BUTTON"); } return 0L; } case WM_SETFONT: { PCBBUTTON pCBB = (PCBBUTTON)GetWindowLong(hwnd,GWL_USERDATA); LOGFONT lf; SIZE si; if (!pCBB) return 0L; if (pCBB->hFontNormal) { DeleteObject(pCBB->hFontNormal); pCBB->hFontNormal = NULL; } if (pCBB->hFontHot) { DeleteObject(pCBB->hFontHot); pCBB->hFontHot = NULL; } if (pCBB->hFontCheckedNormal) { DeleteObject(pCBB->hFontCheckedNormal); pCBB->hFontCheckedNormal = NULL; } if (pCBB->hFontCheckedHot) { DeleteObject(pCBB->hFontCheckedHot); pCBB->hFontCheckedHot = NULL; } if (GetLogFontEx( wParam ? ((HFONT)wParam) : ((HFONT)GetStockObject(DEFAULT_GUI_FONT)),&lf,&pCBB->uDescent) ) { lf.lfWeight = FW_NORMAL; lf.lfItalic = FALSE; lf.lfUnderline = FALSE; pCBB->hFontNormal = CreateFontIndirect(&lf); lf.lfUnderline = TRUE; pCBB->hFontHot = CreateFontIndirect(&lf); lf.lfWeight = FW_BOLD; pCBB->hFontCheckedHot = CreateFontIndirect(&lf); lf.lfUnderline = FALSE; pCBB->hFontCheckedNormal = CreateFontIndirect(&lf); if (GetItemSize(hwnd,pCBB,&si,-1)) SetWindowPos(hwnd,NULL,0,0,si.cx,si.cy,SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOOWNERZORDER|SWP_NOZORDER); if (LOWORD(lParam)) InvalidateRect(hwnd,NULL,TRUE); } return 0L; } case CBBM_SETCURSOR: // wParam = HCURSOR(NULL=standard) { PCBBUTTON pCBB = (PCBBUTTON)GetWindowLong(hwnd,GWL_USERDATA); if (!pCBB) return FALSE; pCBB->hCursor = (HCURSOR)wParam; return TRUE; } case WM_NCHITTEST: { PCBBUTTON pCBB = (PCBBUTTON)GetWindowLong(hwnd,GWL_USERDATA); POINT pt; RECT rcClient; if (!pCBB) break; GetHitTestRect(hwnd,pCBB,&rcClient); pt.x = (int)((short)LOWORD(lParam)); pt.y = (int)((short)HIWORD(lParam)); ScreenToClient(hwnd,&pt); if (PtInRect(&rcClient,pt)) return HTCLIENT; else return HTNOWHERE; } case WM_SETCURSOR: { PCBBUTTON pCBB = (PCBBUTTON)GetWindowLong(hwnd,GWL_USERDATA); if (!pCBB) return FALSE; if (LOWORD(lParam)==HTCLIENT) SetCursor(pCBB->hCursor ? pCBB->hCursor : LoadCursor(NULL,IDC_ARROW)); else SetCursor(LoadCursor(NULL,IDC_ARROW)); return TRUE; } case WM_ERASEBKGND: return TRUE; case WM_SIZE: { PCBBUTTON pCBB = (PCBBUTTON)GetWindowLong(hwnd,GWL_USERDATA); SIZE si; if (!pCBB) return FALSE; GetItemSize(hwnd,pCBB,&si,-1); break; } case WM_CALCDIMENSIONS: // wParam = LPSIZE, lParam = width of control in px (-1 = get current width) { PCBBUTTON pCBBSave,pCBB = (PCBBUTTON)GetWindowLong(hwnd,GWL_USERDATA); BOOL bReturn; if (!pCBB) return FALSE; if (IsBadWritePtr((VOID *)wParam,sizeof(SIZE))) return FALSE; pCBBSave = (PCBBUTTON)malloc(sizeof(CBBUTTON)); if (!pCBBSave) return FALSE; memcpy(pCBBSave,pCBB,sizeof(CBBUTTON)); bReturn = GetItemSize(hwnd,pCBB,(PSIZE)wParam,(int)lParam); memcpy(pCBB,pCBBSave,sizeof(CBBUTTON)); return bReturn; } case WM_KEYDOWN: { PCBBUTTON pCBB = (PCBBUTTON)GetWindowLong(hwnd,GWL_USERDATA); if (!pCBB) return 0L; if ((wParam==VK_SPACE) && (pCBB->bFocus) && (pCBB->bEnabled) && (GetCapture()!=hwnd)) { pCBB->bKeyDown = TRUE; CheckNeedRepaint(hwnd,pCBB); } return 0L; } case WM_KEYUP: { PCBBUTTON pCBB = (PCBBUTTON)GetWindowLong(hwnd,GWL_USERDATA); if (!pCBB) return 0L; if ((wParam==VK_SPACE) && (pCBB->bFocus) && (pCBB->bEnabled) && (pCBB->bKeyDown)) { pCBB->bKeyDown = FALSE; CheckNeedRepaint(hwnd,pCBB); if (pCBB->bEnabled) { HandleClick(hwnd,pCBB); SendMessage(GetParent(hwnd), WM_COMMAND, MAKELONG( ((WORD)GetWindowLong(hwnd,GWL_ID)), ((WORD)CBBN_CLICKED) ), (LPARAM)hwnd); } } return 0L; } case WM_LBUTTONDBLCLK: { PCBBUTTON pCBB = (PCBBUTTON)GetWindowLong(hwnd,GWL_USERDATA); LONG lStyle = GetWindowLong(hwnd,GWL_STYLE); if (!pCBB) return 0L; if (!pCBB->bEnabled) return 0L; pCBB->iMouseX = (int)((short)LOWORD(lParam)); pCBB->iMouseY = (int)((short)HIWORD(lParam)); pCBB->bLButtonDown = TRUE; pCBB->bLButtonDblClk = TRUE; if ((!(lStyle & CBBS_NOSETFOCUSONCLICK)) && (pCBB->bEnabled)) SetFocus(hwnd); SetCapture(hwnd); CheckNeedRepaint(hwnd,pCBB); return 0L; } case WM_LBUTTONDOWN: { PCBBUTTON pCBB = (PCBBUTTON)GetWindowLong(hwnd,GWL_USERDATA); LONG lStyle = GetWindowLong(hwnd,GWL_STYLE); if (!pCBB) return 0L; if (!pCBB->bEnabled) return 0L; pCBB->iMouseX = (int)((short)LOWORD(lParam)); pCBB->iMouseY = (int)((short)HIWORD(lParam)); pCBB->bLButtonDown = TRUE; if ((!(lStyle & CBBS_NOSETFOCUSONCLICK)) && (pCBB->bEnabled)) SetFocus(hwnd); SetCapture(hwnd); CheckNeedRepaint(hwnd,pCBB); return 0L; } case WM_LBUTTONUP: { PCBBUTTON pCBB = (PCBBUTTON)GetWindowLong(hwnd,GWL_USERDATA); RECT rcClient; POINT pt; UINT uNotify; if (!pCBB) return 0L; if (!pCBB->bEnabled) return 0L; pCBB->iMouseX = (int)((short)LOWORD(lParam)); pCBB->iMouseY = (int)((short)HIWORD(lParam)); if (pCBB->bLButtonDown) { pCBB->bLButtonDown = FALSE; CheckNeedRepaint(hwnd,pCBB); pt.x = pCBB->iMouseX; pt.y = pCBB->iMouseY; GetClientRect(hwnd,&rcClient); if (PtInRect(&rcClient,pt)) { ReleaseCapture(); if (pCBB->bEnabled) { if (pCBB->bLButtonDblClk) { uNotify = CBBN_DOUBLECLICKED; pCBB->bLButtonDblClk = FALSE; } else uNotify = CBBN_CLICKED; HandleClick(hwnd,pCBB); SendMessage(GetParent(hwnd), WM_COMMAND, MAKELONG( ((WORD)GetWindowLong(hwnd,GWL_ID)), ((WORD)uNotify) ), (LPARAM)hwnd); } } else ReleaseCapture(); } return 0L; } case WM_MOUSELEAVE: { PCBBUTTON pCBB = (PCBBUTTON)GetWindowLong(hwnd,GWL_USERDATA); if (!pCBB) return 0L; pCBB->iMouseX = -1; pCBB->iMouseY = -1; pCBB->bTrackMouse = FALSE; CheckNeedRepaint(hwnd,pCBB); if (GetWindowLong(hwnd,GWL_STYLE) & CBBS_NOTIFY) { NMBCHOTITEM nmbchi; nmbchi.hdr.hwndFrom = hwnd; nmbchi.hdr.idFrom = GetWindowLong(hwnd,GWL_ID); nmbchi.hdr.code = CBBN_HOTITEMCHANGE; nmbchi.dwFlags = HICF_LEAVING; SendMessage(GetParent(hwnd),WM_NOTIFY,(WPARAM)nmbchi.hdr.idFrom,(LPARAM)&nmbchi); } return 0L; } case WM_MOUSEMOVE: { PCBBUTTON pCBB = (PCBBUTTON)GetWindowLong(hwnd,GWL_USERDATA); TRACKMOUSEEVENT tme; if (!pCBB) return 0L; if (!pCBB->bEnabled) return 0L; if (!pCBB->bTrackMouse) { pCBB->bTrackMouse = TRUE; tme.cbSize = sizeof(TRACKMOUSEEVENT); tme.dwFlags = TME_LEAVE; tme.dwHoverTime = 0; tme.hwndTrack = hwnd; TrackMouseEvent(&tme); if (GetWindowLong(hwnd,GWL_STYLE) & CBBS_NOTIFY) { NMBCHOTITEM nmbchi; nmbchi.hdr.hwndFrom = hwnd; nmbchi.hdr.idFrom = GetWindowLong(hwnd,GWL_ID); nmbchi.hdr.code = CBBN_HOTITEMCHANGE; nmbchi.dwFlags = HICF_ENTERING; SendMessage(GetParent(hwnd),WM_NOTIFY,(WPARAM)nmbchi.hdr.idFrom,(LPARAM)&nmbchi); } } pCBB->iMouseX = (int)((short)LOWORD(lParam)); pCBB->iMouseY = (int)((short)HIWORD(lParam)); CheckNeedRepaint(hwnd,pCBB); return 0L; } case WM_SETFOCUS: { PCBBUTTON pCBB = (PCBBUTTON)GetWindowLong(hwnd,GWL_USERDATA); LONG lStyle = GetWindowLong(hwnd,GWL_STYLE); if (!pCBB) break; pCBB->bFocus = TRUE; if (lStyle & CBBS_NOTIFY) { SendMessage(GetParent(hwnd), WM_COMMAND, MAKELONG( ((WORD)GetWindowLong(hwnd,GWL_ID)), ((WORD)CBBN_SETFOCUS) ), (LPARAM)hwnd); } InvalidateRect(hwnd,NULL,TRUE); return 0L; } case WM_KILLFOCUS: { PCBBUTTON pCBB = (PCBBUTTON)GetWindowLong(hwnd,GWL_USERDATA); LONG lStyle = GetWindowLong(hwnd,GWL_STYLE); if (!pCBB) break; pCBB->bFocus = FALSE; pCBB->bKeyDown = FALSE; if (lStyle & CBBS_NOTIFY) { SendMessage(GetParent(hwnd), WM_COMMAND, MAKELONG( ((WORD)GetWindowLong(hwnd,GWL_ID)), ((WORD)CBBN_KILLFOCUS) ), (LPARAM)hwnd); } InvalidateRect(hwnd,NULL,TRUE); return 0L; } case WM_CAPTURECHANGED: { PCBBUTTON pCBB = (PCBBUTTON)GetWindowLong(hwnd,GWL_USERDATA); if (!pCBB) return 0L; pCBB->bLButtonDown = FALSE; pCBB->bLButtonDblClk = FALSE; pCBB->bTrackMouse = FALSE; pCBB->iMouseX = -1; pCBB->iMouseY = -1; CheckNeedRepaint(hwnd,pCBB); return 0L; } case BM_GETCHECK: case CBBM_GETCHECK: { PCBBUTTON pCBB = (PCBBUTTON)GetWindowLong(hwnd,GWL_USERDATA); if (!pCBB) return 0L; return pCBB->uButtonState&0x3L; } case BM_SETCHECK: case CBBM_SETCHECK: { PCBBUTTON pCBB = (PCBBUTTON)GetWindowLong(hwnd,GWL_USERDATA); UINT uOldState; if (!pCBB) return 0L; uOldState = pCBB->uButtonState; pCBB->uButtonState = (((UINT)wParam)&0x3L)|(uOldState&~3); if (uOldState!=pCBB->uButtonState) InvalidateRect(hwnd,NULL,TRUE); return 0L; } case CBBM_GETSTATE: { PCBBUTTON pCBB = (PCBBUTTON)GetWindowLong(hwnd,GWL_USERDATA); UINT uState; if (!pCBB) return 0L; uState = pCBB->uButtonState; if (pCBB->iState==ITEMSTATE_PRESSED) uState |= CBBST_PUSHED; if (pCBB->bFocus) uState |= CBBST_FOCUS; return uState; } case CBBM_SETSTATE: { PCBBUTTON pCBB = (PCBBUTTON)GetWindowLong(hwnd,GWL_USERDATA); LONG lStyle = GetWindowLong(hwnd,GWL_STYLE); POINT pt; RECT rcClient; if (!pCBB) return 0L; if ((wParam) && (pCBB->iState!=ITEMSTATE_PRESSED)) { pCBB->iMouseX = 0; pCBB->iMouseY = 0; pCBB->bLButtonDown = TRUE; if ((!(lStyle & CBBS_NOSETFOCUSONCLICK)) && (pCBB->bEnabled)) SetFocus(hwnd); SetCapture(hwnd); CheckNeedRepaint(hwnd,pCBB); } else if ((!wParam) && (pCBB->iState==ITEMSTATE_PRESSED)) { pCBB->iMouseX = (int)((short)LOWORD(lParam)); pCBB->iMouseY = (int)((short)HIWORD(lParam)); if (pCBB->bLButtonDown) { pCBB->bLButtonDown = FALSE; CheckNeedRepaint(hwnd,pCBB); pt.x = 0; pt.y = 0; GetClientRect(hwnd,&rcClient); if (PtInRect(&rcClient,pt)) { ReleaseCapture(); if ((pCBB->bEnabled) && (pCBB->iState==ITEMSTATE_HOT)) { HandleClick(hwnd,pCBB); SendMessage(GetParent(hwnd), WM_COMMAND, MAKELONG( ((WORD)GetWindowLong(hwnd,GWL_ID)), ((WORD)CBBN_CLICKED) ), (LPARAM)hwnd); } } else ReleaseCapture(); } } return 0L; } case CBBM_SETSTYLE: { PCBBUTTON pCBB = (PCBBUTTON)GetWindowLong(hwnd,GWL_USERDATA); SIZE si; if (!pCBB) return 0L; SetWindowLong(hwnd,GWL_STYLE,(LONG)wParam); if (GetItemSize(hwnd,pCBB,&si,-1)) SetWindowPos(hwnd,NULL,0,0,si.cx,si.cy,SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOOWNERZORDER|SWP_NOZORDER); if (lParam) InvalidateRect(hwnd,NULL,TRUE); return 0L; } case CBBM_CLICK: { PCBBUTTON pCBB = (PCBBUTTON)GetWindowLong(hwnd,GWL_USERDATA); if (!pCBB) return 0L; HandleClick(hwnd,pCBB); SendMessage(GetParent(hwnd), WM_COMMAND, MAKELONG( ((WORD)GetWindowLong(hwnd,GWL_ID)), ((WORD)CBBN_CLICKED) ), (LPARAM)hwnd); return 0L; } case WM_PAINT: { PAINTSTRUCT ps; HDC hDC; POINT pt = {0,0}; hDC = BeginPaint(hwnd,&ps); if (hDC) { CBButtonPaintDC(hwnd,hDC,pt,TRUE,-1); EndPaint(hwnd,&ps); } return 0L; } case WM_PRINTCLIENT: { HDC hDC = (HDC)wParam; UINT uFlags = (UINT)lParam; POINT pt = {0,0}; if (hDC) { if (!((!IsWindowVisible(hwnd)) && (uFlags & PRF_CHECKVISIBLE))) CBButtonPaintDC(hwnd,hDC,pt,uFlags & PRF_ERASEBKGND ? TRUE : FALSE,-1); return TRUE; } return FALSE; } default: break; } return DefWindowProc(hwnd,uMsg,wParam,lParam); } void APIENTRY CBButtonPaintDC ( HWND hwnd, HDC hDC, POINT ptOffset, BOOL bPaintBackground, int iCtrlWidth ) { PCBBUTTON pCBB = (PCBBUTTON)GetWindowLong(hwnd,GWL_USERDATA); CBBUTTON CBBSave; LONG lStyle = GetWindowLong(hwnd,GWL_STYLE); LONG lExStyle = GetWindowLong(hwnd,GWL_EXSTYLE); UINT uDTStyle = 0L; UINT uAlign; BOOL bIsPushButton = FALSE; RECT rcClient; HBITMAP hOldBitmap,hBitmapMem; HDC hDCMem; HBRUSH hBackBrush; BOOL bDefaultButton; UINT uState,uPreState; int iOldMode,iOldColor; HFONT hOldFont; SIZE siText; RECT rcText; int iDelta,iTextWidthAvail; TCHAR szText[256]; if (pCBB) { if (iCtrlWidth!=-1) { SIZE si; memcpy(&CBBSave,pCBB,sizeof(CBBUTTON)); GetItemSize(hwnd,pCBB,&si,iCtrlWidth); rcClient.left = rcClient.top = 0; rcClient.right = si.cx; rcClient.bottom = si.cy; } else GetClientRect(hwnd,&rcClient); if (((lStyle & CBBS_TYPEMASK)==CBBS_PUSHBUTTON) || ((lStyle & CBBS_TYPEMASK)==CBBS_DEFPUSHBUTTON)) { uAlign = BUTTON_CENTER; bIsPushButton = TRUE; } else uAlign = BUTTON_LEFT; if (lStyle & CBBS_LEFT) uAlign = BUTTON_LEFT; else { if (lStyle & CBBS_RIGHT) uAlign = BUTTON_RIGHT; else if (lStyle & CBBS_CENTER) uAlign = BUTTON_CENTER; } if (lExStyle & WS_EX_RIGHT) { lStyle |= CBBS_LEFTTEXT; if (uAlign==BUTTON_LEFT) uAlign=BUTTON_RIGHT; else if (uAlign==BUTTON_RIGHT) uAlign=BUTTON_LEFT; } hDCMem = CreateCompatibleDC(hDC); hBitmapMem = CreateCompatibleBitmap(hDC,rcClient.right,rcClient.bottom); if ((hDCMem) && (hBitmapMem)) { hOldBitmap=SelectObject(hDCMem,hBitmapMem); if (bPaintBackground) { hBackBrush = (HBRUSH)SendMessage(GetParent(hwnd),WM_CTLCOLORBTN,(WPARAM)hDCMem,(LPARAM)hwnd); if (((ULONG)(hBackBrush))>1) FillRect(hDCMem,&rcClient,hBackBrush); } else BitBlt(hDCMem,0,0,rcClient.right,rcClient.bottom,hDC,ptOffset.x,ptOffset.y,SRCCOPY); /* hBackBrush = CreateSolidBrush(RGB(0xF0,0xE0,0xC0)); FillRect(hDCMem,&rcClient,hBackBrush); DeleteObject(hBackBrush);*/ switch(lStyle & CBBS_TYPEMASK) { case CBBS_PUSHBUTTON: case CBBS_DEFPUSHBUTTON: bDefaultButton = (lStyle & CBBS_TYPEMASK)==CBBS_DEFPUSHBUTTON ? TRUE : FALSE; if (pCBB->bFocus) bDefaultButton = TRUE; if (g_sEBI.bPreXP) { if (!pCBB->bEnabled) DrawFrameControl( hDCMem, &pCBB->rcButton, DFC_BUTTON, DFCS_BUTTONPUSH| (lStyle & CBBS_FLAT ? DFCS_FLAT : 0)| DFCS_INACTIVE ); else { memcpy(&rcText,&pCBB->rcButton,sizeof(RECT)); if (bDefaultButton) { HPEN hOldPen,hPen = CreatePen(PS_SOLID,0,GetSysColor(COLOR_3DDKSHADOW)); hOldPen = SelectObject(hDCMem,hPen); MoveToEx(hDCMem,rcText.left,rcText.top,NULL); LineTo(hDCMem,rcText.right-1,rcText.top); LineTo(hDCMem,rcText.right-1,rcText.bottom-1); LineTo(hDCMem,rcText.left,rcText.bottom-1); LineTo(hDCMem,rcText.left,rcText.top-1); SelectObject(hDCMem,hOldPen); rcText.left ++; rcText.right --; rcText.top ++; rcText.bottom --; } DrawFrameControl( hDCMem, &rcText, DFC_BUTTON, DFCS_BUTTONPUSH| (lStyle & CBBS_FLAT ? DFCS_FLAT : 0)| (pCBB->iState==ITEMSTATE_PRESSED ? DFCS_PUSHED : 0) ); } } else if (pCBB->hTheme) { switch(pCBB->iState) { case ITEMSTATE_DISABLED: uState = PBS_DISABLED; break; case ITEMSTATE_COLD: uState = bDefaultButton ? PBS_DEFAULTED : PBS_NORMAL; break; case ITEMSTATE_PRESSED: uState = PBS_PRESSED; break; case ITEMSTATE_HOT: uState = PBS_HOT; break; default: uState = PBS_NORMAL; break; } DrawThemeBackground(pCBB->hTheme, hDCMem, BP_PUSHBUTTON, uState, &pCBB->rcButton, NULL); } break; case CBBS_CHECKBOX: case CBBS_AUTOCHECKBOX: switch(pCBB->iState) { case ITEMSTATE_DISABLED: uPreState = DFCS_BUTTONCHECK|DFCS_INACTIVE; uState = pCBB->uButtonState==CBBST_CHECKED ? CBS_CHECKEDDISABLED : CBS_UNCHECKEDDISABLED; break; case ITEMSTATE_COLD: uPreState = DFCS_BUTTONCHECK; uState = pCBB->uButtonState==CBBST_CHECKED ? CBS_CHECKEDNORMAL : CBS_UNCHECKEDNORMAL; break; case ITEMSTATE_PRESSED: uPreState = DFCS_BUTTONCHECK|DFCS_PUSHED; uState = pCBB->uButtonState==CBBST_CHECKED ? CBS_CHECKEDPRESSED : CBS_UNCHECKEDPRESSED; break; case ITEMSTATE_HOT: uPreState = DFCS_BUTTONCHECK|DFCS_HOT; uState = pCBB->uButtonState==CBBST_CHECKED ? CBS_CHECKEDHOT : CBS_UNCHECKEDHOT; break; } if (pCBB->uButtonState==CBBST_CHECKED) uPreState |= DFCS_CHECKED; goto DoPaintCheck; case CBBS_3STATE: case CBBS_AUTO3STATE: switch(pCBB->iState) { case ITEMSTATE_DISABLED: uPreState = DFCS_BUTTON3STATE|DFCS_INACTIVE; uState = pCBB->uButtonState==CBBST_CHECKED ? CBS_CHECKEDDISABLED : (pCBB->uButtonState==CBBST_UNCHECKED ? CBS_UNCHECKEDDISABLED : CBS_MIXEDDISABLED); break; case ITEMSTATE_COLD: uPreState = DFCS_BUTTON3STATE; uState = pCBB->uButtonState==CBBST_CHECKED ? CBS_CHECKEDNORMAL : (pCBB->uButtonState==CBBST_UNCHECKED ? CBS_UNCHECKEDNORMAL : CBS_MIXEDNORMAL); break; case ITEMSTATE_PRESSED: uPreState = DFCS_BUTTON3STATE|DFCS_PUSHED; uState = pCBB->uButtonState==CBBST_CHECKED ? CBS_CHECKEDPRESSED : (pCBB->uButtonState==CBBST_UNCHECKED ? CBS_UNCHECKEDPRESSED : CBS_MIXEDPRESSED); break; case ITEMSTATE_HOT: uPreState = DFCS_BUTTON3STATE|DFCS_HOT; uState = pCBB->uButtonState==CBBST_CHECKED ? CBS_CHECKEDHOT : (pCBB->uButtonState==CBBST_UNCHECKED ? CBS_UNCHECKEDHOT : CBS_MIXEDHOT); break; } if (pCBB->uButtonState!=CBBST_UNCHECKED) uPreState |= DFCS_CHECKED; if (pCBB->uButtonState==CBBST_INDETERMINATE) uPreState |= DFCS_INACTIVE; DoPaintCheck: if (lStyle & CBBS_FLAT) uPreState |= DFCS_FLAT; if (g_sEBI.bPreXP) { DrawFrameControl( hDCMem, &pCBB->rcButton, DFC_BUTTON, uPreState ); } else { DrawThemeBackground(pCBB->hTheme, hDCMem, BP_CHECKBOX, uState, &pCBB->rcButton, NULL); } break; case CBBS_RADIOBUTTON: case CBBS_AUTORADIOBUTTON: switch(pCBB->iState) { case ITEMSTATE_DISABLED: uPreState = DFCS_BUTTONRADIO|DFCS_INACTIVE; uState = pCBB->uButtonState==CBBST_CHECKED ? RBS_CHECKEDDISABLED : RBS_UNCHECKEDDISABLED; break; case ITEMSTATE_COLD: uPreState = DFCS_BUTTONRADIO; uState = pCBB->uButtonState==CBBST_CHECKED ? RBS_CHECKEDNORMAL : RBS_UNCHECKEDNORMAL; break; case ITEMSTATE_PRESSED: uPreState = DFCS_BUTTONRADIO|DFCS_PUSHED; uState = pCBB->uButtonState==CBBST_CHECKED ? RBS_CHECKEDPRESSED : RBS_UNCHECKEDPRESSED; break; case ITEMSTATE_HOT: uPreState = DFCS_BUTTONRADIO|DFCS_HOT; uState = pCBB->uButtonState==CBBST_CHECKED ? RBS_CHECKEDHOT : RBS_UNCHECKEDHOT; break; } if (pCBB->uButtonState==CBBST_CHECKED) uPreState |= DFCS_CHECKED; if (lStyle & CBBS_FLAT) uPreState |= DFCS_FLAT; if (g_sEBI.bPreXP) { DrawFrameControl( hDCMem, &pCBB->rcButton, DFC_BUTTON, uPreState ); } else { DrawThemeBackground(pCBB->hTheme, hDCMem, BP_RADIOBUTTON, uState, &pCBB->rcButton, NULL); } break; } // Print text if (bIsPushButton) hOldFont=SelectObject(hDCMem,pCBB->hFontNormal); else if (pCBB->uButtonState!=CBBST_UNCHECKED) { if ((pCBB->iState==ITEMSTATE_HOT) || (pCBB->iState==ITEMSTATE_PRESSED)) hOldFont=SelectObject(hDCMem,pCBB->hFontCheckedHot); else hOldFont=SelectObject(hDCMem,pCBB->hFontCheckedNormal); } else { if ((pCBB->iState==ITEMSTATE_HOT) || (pCBB->iState==ITEMSTATE_PRESSED)) hOldFont=SelectObject(hDCMem,pCBB->hFontHot); else hOldFont=SelectObject(hDCMem,pCBB->hFontNormal); } iOldMode = SetBkMode(hDCMem,TRANSPARENT); if (pCBB->iState==ITEMSTATE_DISABLED) iOldColor = SetTextColor(hDCMem,GetSysColor(COLOR_GRAYTEXT)); else { if (bIsPushButton) iOldColor = SetTextColor(hDCMem,GetSysColor(COLOR_BTNTEXT)); else { if ((pCBB->iState==ITEMSTATE_HOT) || (pCBB->iState==ITEMSTATE_PRESSED)) iOldColor = SetTextColor(hDCMem,GetSysColor(COLOR_HOTLIGHT)); else iOldColor = SetTextColor(hDCMem,GetSysColor(COLOR_BTNTEXT)); } } szText[0]=0x00; GetWindowText(hwnd,szText,256); rcText.left = 0; rcText.right = pCBB->rcText.right-pCBB->rcText.left; rcText.top = 0; rcText.bottom = 32767; if (lStyle & CBBS_FOCUSRECT) rcText.right -= 2; if (lStyle & CBBS_WORDBREAK) // multiline, use current control width { uDTStyle = DT_EXTERNALLEADING|DT_WORDBREAK; } else { if (lStyle & CBBS_END_ELLIPSIS) // singleline, use current control width { uDTStyle = DT_END_ELLIPSIS|DT_SINGLELINE; } else // singleline, ignore current control width { uDTStyle = DT_SINGLELINE|DT_NOCLIP; } } uDTStyle |= DT_CALCRECT|DT_LEFT|DT_TOP; if (lExStyle & WS_EX_RTLREADING) uDTStyle |= DT_RTLREADING; siText.cy = DrawTextEx(hDCMem,szText,lstrlen(szText),&rcText,uDTStyle,NULL); siText.cx = rcText.right; if (lStyle & CBBS_FOCUSRECT) siText.cx += 2; uDTStyle &= ~(DT_CALCRECT|DT_LEFT|DT_NOCLIP); memcpy(&rcText,&pCBB->rcText,sizeof(RECT)); iTextWidthAvail = pCBB->rcText.right-pCBB->rcText.left; if (siText.cx >1; rcText.left += iDelta; rcText.right += iDelta; break; } } switch(uAlign) { case BUTTON_LEFT: uDTStyle |= DT_LEFT; break; case BUTTON_RIGHT: uDTStyle |= DT_RIGHT; break; case BUTTON_CENTER: uDTStyle |= DT_CENTER; break; } if (lStyle & CBBS_FOCUSRECT) { if (pCBB->bFocus) DrawFocusRect(hDCMem,&rcText); rcText.left ++; rcText.top ++; rcText.right --; rcText.bottom --; } /* if (bIsPushButton) { rcText.top += pCBB->uDescent; rcText.bottom += pCBB->uDescent; } */ DrawTextEx(hDCMem,szText,lstrlen(szText),&rcText,uDTStyle,NULL); SetBkMode(hDCMem,iOldMode); SetTextColor(hDCMem,iOldColor); BitBlt(hDC,ptOffset.x,ptOffset.y,rcClient.right,rcClient.bottom,hDCMem,0,0,SRCCOPY); SelectObject(hDCMem,hOldBitmap); } if (hBitmapMem) DeleteObject(hBitmapMem); if (hDCMem) DeleteDC(hDCMem); if (iCtrlWidth!=-1) memcpy(pCBB,&CBBSave,sizeof(CBBUTTON)); } }