static void PaintWorker(MButtonCtrl *ctl, HDC hdcPaint) { if (hdcPaint) { HDC hdcMem; HBITMAP hbmMem; HDC hOld; RECT rcClient; GetClientRect(ctl->hwnd, &rcClient); hdcMem = CreateCompatibleDC(hdcPaint); hbmMem = CreateCompatibleBitmap(hdcPaint, rcClient.right-rcClient.left, rcClient.bottom-rcClient.top); hOld = ( HDC )SelectObject(hdcMem, hbmMem); // If its a push button, check to see if it should stay pressed if (ctl->pushBtn && ctl->pbState) ctl->stateId = PBS_PRESSED; // Draw the flat button if (ctl->flatBtn) { if (ctl->hThemeToolbar) { int state = IsWindowEnabled(ctl->hwnd)?(ctl->stateId==PBS_NORMAL&&ctl->defbutton?PBS_DEFAULTED:ctl->stateId):PBS_DISABLED; if (isThemeBackgroundPartiallyTransparent(ctl->hThemeToolbar, TP_BUTTON, TBStateConvert2Flat(state))) { drawThemeParentBackground(ctl->hwnd, hdcMem, &rcClient); } drawThemeBackground(ctl->hThemeToolbar, hdcMem, TP_BUTTON, TBStateConvert2Flat(state), &rcClient, &rcClient); } else { HBRUSH hbr; if (ctl->stateId==PBS_PRESSED||ctl->stateId==PBS_HOT) hbr = GetSysColorBrush(COLOR_3DLIGHT); else { HWND hwndParent = GetParent(ctl->hwnd); HDC dc = GetDC(hwndParent); HBRUSH oldBrush = (HBRUSH)GetCurrentObject( dc, OBJ_BRUSH ); hbr = (HBRUSH)SendMessage(hwndParent, WM_CTLCOLORDLG, (WPARAM)dc, (LPARAM)hwndParent); SelectObject(dc,oldBrush); ReleaseDC(hwndParent,dc); } if (hbr) { FillRect(hdcMem, &rcClient, hbr); DeleteObject(hbr); } if (ctl->stateId==PBS_HOT||ctl->focus) { if (ctl->pbState) DrawEdge(hdcMem,&rcClient, EDGE_ETCHED,BF_RECT|BF_SOFT); else DrawEdge(hdcMem,&rcClient, BDR_RAISEDOUTER,BF_RECT|BF_SOFT|BF_FLAT); } else if (ctl->stateId==PBS_PRESSED) DrawEdge(hdcMem, &rcClient, BDR_SUNKENOUTER,BF_RECT|BF_SOFT); } } else { // Draw background/border if (ctl->hThemeButton) { int state = IsWindowEnabled(ctl->hwnd)?(ctl->stateId==PBS_NORMAL&&ctl->defbutton?PBS_DEFAULTED:ctl->stateId):PBS_DISABLED; if (isThemeBackgroundPartiallyTransparent(ctl->hThemeButton, BP_PUSHBUTTON, state)) { drawThemeParentBackground(ctl->hwnd, hdcMem, &rcClient); } drawThemeBackground(ctl->hThemeButton, hdcMem, BP_PUSHBUTTON, state, &rcClient, &rcClient); } else { UINT uState = DFCS_BUTTONPUSH|((ctl->stateId==PBS_HOT)?DFCS_HOT:0)|((ctl->stateId == PBS_PRESSED)?DFCS_PUSHED:0); if (ctl->defbutton&&ctl->stateId==PBS_NORMAL) uState |= DLGC_DEFPUSHBUTTON; DrawFrameControl(hdcMem, &rcClient, DFC_BUTTON, uState); } // Draw focus rectangle if button has focus if (ctl->focus) { RECT focusRect = rcClient; InflateRect(&focusRect, -3, -3); DrawFocusRect(hdcMem, &focusRect); } } // If we have an icon or a bitmap, ignore text and only draw the image on the button if (ctl->hIcon) { int ix = (rcClient.right-rcClient.left)/2 - (GetSystemMetrics(SM_CXSMICON)/2); int iy = (rcClient.bottom-rcClient.top)/2 - (GetSystemMetrics(SM_CYSMICON)/2); if (ctl->stateId == PBS_PRESSED) { ix++; iy++; } { HIMAGELIST hImageList; HICON hIconNew; hImageList = ImageList_Create(GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON), IsWinVerXPPlus()? ILC_COLOR32 | ILC_MASK : ILC_COLOR16 | ILC_MASK, 1, 0); ImageList_AddIcon(hImageList, ctl->hIcon); hIconNew = ImageList_GetIcon(hImageList, 0, ILD_NORMAL); DrawState(hdcMem,NULL,NULL,(LPARAM)hIconNew,0,ix,iy,GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON),IsWindowEnabled(ctl->hwnd)?DST_ICON|DSS_NORMAL:DST_ICON|DSS_DISABLED); ImageList_RemoveAll(hImageList); ImageList_Destroy(hImageList); DestroyIcon(hIconNew); } } else if (ctl->hBitmap) { BITMAP bminfo; int ix,iy; GetObject(ctl->hBitmap, sizeof(bminfo), &bminfo); ix = (rcClient.right-rcClient.left)/2 - (bminfo.bmWidth/2); iy = (rcClient.bottom-rcClient.top)/2 - (bminfo.bmHeight/2); if (ctl->stateId == PBS_PRESSED) { ix++; iy++; } DrawState(hdcMem,NULL,NULL,(LPARAM)ctl->hBitmap,0,ix,iy,bminfo.bmWidth,bminfo.bmHeight,IsWindowEnabled(ctl->hwnd)?DST_BITMAP:DST_BITMAP|DSS_DISABLED); } else if (GetWindowTextLength(ctl->hwnd)) { // Draw the text and optinally the arrow TCHAR szText[MAX_PATH]; SIZE sz; RECT rcText; HFONT hOldFont; CopyRect(&rcText, &rcClient); GetWindowText(ctl->hwnd, szText, SIZEOF(szText)); SetBkMode(hdcMem, TRANSPARENT); hOldFont = (HFONT)SelectObject(hdcMem, ctl->hFont); // XP w/themes doesn't used the glossy disabled text. Is it always using COLOR_GRAYTEXT? Seems so. SetTextColor(hdcMem, IsWindowEnabled(ctl->hwnd)||!ctl->hThemeButton?GetSysColor(COLOR_BTNTEXT):GetSysColor(COLOR_GRAYTEXT)); GetTextExtentPoint32(hdcMem, szText, lstrlen(szText), &sz); if (ctl->cHot) { SIZE szHot; GetTextExtentPoint32 (hdcMem, _T("&"), 1, &szHot); sz.cx -= szHot.cx; } if (ctl->arrow) { DrawState(hdcMem,NULL,NULL,(LPARAM)ctl->arrow,0,rcClient.right-rcClient.left-5-GetSystemMetrics(SM_CXSMICON)+(!ctl->hThemeButton&&ctl->stateId==PBS_PRESSED?1:0),(rcClient.bottom-rcClient.top)/2-GetSystemMetrics(SM_CYSMICON)/2+(!ctl->hThemeButton&&ctl->stateId==PBS_PRESSED?1:0),GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON),IsWindowEnabled(ctl->hwnd)?DST_ICON:DST_ICON|DSS_DISABLED); } SelectObject(hdcMem, ctl->hFont); DrawState(hdcMem,NULL,NULL,(LPARAM)szText,0,(rcText.right-rcText.left-sz.cx)/2+(!ctl->hThemeButton&&ctl->stateId==PBS_PRESSED?1:0),ctl->hThemeButton?(rcText.bottom-rcText.top-sz.cy)/2:(rcText.bottom-rcText.top-sz.cy)/2-(ctl->stateId==PBS_PRESSED?0:1),sz.cx,sz.cy,IsWindowEnabled(ctl->hwnd)||ctl->hThemeButton?DST_PREFIXTEXT|DSS_NORMAL:DST_PREFIXTEXT|DSS_DISABLED); SelectObject(hdcMem, hOldFont); } BitBlt(hdcPaint, 0, 0, rcClient.right-rcClient.left, rcClient.bottom-rcClient.top, hdcMem, 0, 0, SRCCOPY); SelectObject(hdcMem, hOld); DeleteObject(hbmMem); DeleteDC(hdcMem); } }
// ImageList_Destroy() the return value // refresh on WM_THEMECHANGED static HIMAGELIST CreateRadioImages(COLORREF clrBk, COLORREF clrText) { /* draw bitmap */ HDC hdcScreen = GetDC(NULL); if (hdcScreen == NULL) return NULL; HIMAGELIST himl = NULL; HDC hdc = CreateCompatibleDC(NULL); /* compatible to screen */ if (hdc != NULL) { SIZE size = { GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON) }; RECT rc; SetRect(&rc, 0, 0, 2 * size.cx, size.cy); HBITMAP hbm = CreateCompatibleBitmap(hdcScreen, rc.right, rc.bottom); if (hbm != NULL) { HBITMAP hbmPrev = (HBITMAP)SelectObject(hdc, hbm); if (hbmPrev != NULL) { /* error on select? */ HTHEME hTheme = OpenThemeData(NULL, L"Button"); SetRect(&rc, 0, 0, size.cx, size.cy); /* unchecked */ if (!DrawThemeBackground(hTheme, hdc, BP_RADIOBUTTON, RBS_UNCHECKEDNORMAL, &rc, NULL)) { /* checked */ OffsetRect(&rc, size.cx, 0); if (!DrawThemeBackground(hTheme, hdc, BP_RADIOBUTTON, RBS_CHECKEDNORMAL, &rc, NULL)) himl = ImageList_Create(size.cx, size.cy, ILC_COLOR32 | ILC_MASK, 3, 0); } CloseThemeData(hTheme); /* the classic way */ if (himl == NULL) { RECT rcRadio; HBRUSH hbrBk = CreateSolidBrush(clrBk); if (hbrBk != NULL) { FillRect(hdc, &rc, hbrBk); DeleteObject(hbrBk); HDC hdcMono = CreateCompatibleDC(hdc); if (hdcMono != NULL) { HBITMAP hbmMono = CreateBitmap(rc.right, rc.bottom, 1, 1, NULL); if (hbmMono != NULL) { HBITMAP hbmPrevMono = (HBITMAP)SelectObject(hdcMono, hbmMono); if (hbmPrevMono != NULL) { /* error on select? */ /* draws a black-and-white mask (see docs) * we need to colorize it using BitBlt with text and background color */ COLORREF clrPrevText = SetTextColor(hdc, clrText); COLORREF clrPrevBk = SetBkColor(hdc, clrBk); /* check mark is slightly smaller than icon size */ SetRect(&rcRadio, 0, 0, GetSystemMetrics(SM_CXMENUCHECK), GetSystemMetrics(SM_CYMENUCHECK)); if (rcRadio.right > size.cx) rcRadio.right = size.cx; if (rcRadio.bottom > size.cy) rcRadio.bottom = size.cy; SetRect(&rc, ((size.cx - rcRadio.right) / 2) + 1, ((size.cy - rcRadio.bottom) / 2) + 1, rcRadio.right + 1, rcRadio.bottom + 1); /* unchecked */ if (BitBlt(hdcMono, 0, 0, rcRadio.right, rcRadio.bottom, NULL, 0, 0, WHITENESS)) { /* white back */ if (DrawFrameControl(hdcMono, &rcRadio, DFC_BUTTON, DFCS_BUTTONRADIO | DFCS_FLAT)) { if (BitBlt(hdc, rc.left, rc.top, rcRadio.right, rcRadio.bottom, hdcMono, 0, 0, SRCCOPY | NOMIRRORBITMAP)) { /* checked */ OffsetRect(&rc, size.cx, 0); if (BitBlt(hdcMono, 0, 0, rcRadio.right, rcRadio.bottom, NULL, 0, 0, WHITENESS)) {/* white back */ if (DrawFrameControl(hdcMono, &rcRadio, DFC_BUTTON, DFCS_BUTTONRADIO | DFCS_FLAT | DFCS_CHECKED)) { if (BitBlt(hdc, rc.left, rc.top, rcRadio.right, rcRadio.bottom, hdcMono, 0, 0, SRCCOPY | NOMIRRORBITMAP)) himl = ImageList_Create(size.cx, size.cy, ILC_COLOR | ILC_MASK, 3, 0); } else BOX("second DrawFrameControl() failed"); } else BOX("second BitBlt() failed"); } else BOX("intermediate BitBlt() failed"); } else BOX("DrawFrameControl() failed"); } else BOX("first BitBlt() failed"); /* restore */ SetBkColor(hdc, clrPrevBk); SetTextColor(hdc, clrPrevText); SelectObject(hdcMono, hbmPrevMono); } else BOX("hbmPrevMono == NULL"); DeleteObject(hbmMono); } else BOX("hbmMono == NULL"); DeleteDC(hdcMono); } else BOX("hdcMono == NULL"); } } SelectObject(hdc, hbmPrev); /* create imagelist */ if (himl != NULL) { if (himl == NULL) BOX("img list create failed"); if (himl != NULL) if (ImageList_AddMasked(himl, hbm, clrBk) == -1) BOX("add failed"); } else BOX("Win9x: drawing code not reached"); } DeleteObject(hbm); } DeleteDC(hdc); } ReleaseDC(NULL, hdcScreen); return himl; }
LRESULT CALLBACK TabsCtrl::WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ) { PAINTSTRUCT ps; HDC hdc; TabsCtrl *p=(TabsCtrl *) GetWindowLong(hWnd, GWL_USERDATA); switch (message) { case WM_CREATE: { p=(TabsCtrl *) (((CREATESTRUCT *)lParam)->lpCreateParams); SetWindowLong(hWnd, GWL_USERDATA, (LONG) p ); p->tabScrollHWnd=CreateWindow(_T("SCROLLBAR"), NULL, /*SBS_TOPALIGN |*/ SBS_HORZ | WS_VISIBLE | WS_CHILD, 0, 0, CW_USEDEFAULT, CW_USEDEFAULT, hWnd, NULL, g_hInst, NULL); //dropdownWnd=DoCreateComboControl(hWnd); //ShowWindow(p->getListBoxHWnd(), SW_SHOW); break; } case CLEARMESS: {int result=MessageBox( p->getHWnd(), L"ќчистить лог?", L"ќчистить", MB_YESNO | MB_ICONWARNING); if (result==IDYES) Log::getInstance()->delet(); //if (result==IDYES) { // p->contact->messageList->clear(); // p->msgList->moveCursorEnd(); } break; case WM_PAINT: { hdc = BeginPaint(hWnd, &ps); /*if (p->makeTabLayout) { p->tabDoLayout(hdc); }*/ unsigned int activeTab=p->activeTab; for (unsigned int i=0; i < p->tabs.size(); i++) { if (i != activeTab) drawTab(hdc, p->xOffset, p->tabs[i], false); } int width=p->clientRect.right; HGDIOBJ old=SelectObject(hdc, GetStockObject(BLACK_PEN)); MoveToEx(hdc, 0, tabHeight-1, NULL); LineTo(hdc, width, tabHeight-1); SelectObject(hdc, old); if (activeTab >= 0 && activeTab < p->tabs.size() ) drawTab(hdc, p->xOffset, p->tabs[activeTab], true); RECT b={width-2*tabHeight, 0, width-tabHeight, tabHeight}; DrawFrameControl(hdc, &b, DFC_SCROLL, DFCS_SCROLLLEFT); b.left+=tabHeight; b.right+=tabHeight; DrawFrameControl(hdc, &b, DFC_SCROLL, DFCS_SCROLLRIGHT); EndPaint(hWnd, &ps); } break; case WM_KEYDOWN: smile_aktiv=40; if (wParam==VK_LEFT) PostMessage(hWnd, WM_COMMAND, TabsCtrl::PREVTAB, 0); if (wParam==VK_RIGHT) PostMessage(hWnd, WM_COMMAND, TabsCtrl::NEXTTAB, 0); break; case WM_LBUTTONDOWN: { smile_aktiv=40; int mouseX=GET_X_LPARAM(lParam); int mouseY=GET_Y_LPARAM(lParam); int width=p->clientRect.right; if (mouseY >= tabHeight) break; if (mouseX > width - tabHeight) { p->activeTab++; if (p->activeTab == p->tabs.size()) p->activeTab--; } else if (mouseX > width - 2*tabHeight) { if (p->activeTab != 0) p->activeTab--; } else for (unsigned int i=0; i < p->tabs.size(); i++) { TabInfoRef tab=p->tabs[i]; int tabX=p->xOffset+tab->tabXPos; if (mouseX < tabX) continue; if (mouseX > tabX+tab->tabWidth ) continue; p->activeTab=i; break; } InvalidateRect(p->getHWnd(), NULL, true); p->showActiveTab(); SHRGINFO shrg; shrg.cbSize = sizeof(shrg); shrg.hwndClient = hWnd; shrg.ptDown.x = LOWORD(lParam); shrg.ptDown.y = HIWORD(lParam); shrg.dwFlags = SHRG_RETURNCMD /*| SHRG_NOANIMATION*/; if (SHRecognizeGesture(&shrg) == GN_CONTEXTMENU) { p->processPopupMenu(false, LOWORD(lParam), HIWORD(lParam) ); } break; } case WM_COMMAND: { int cmd=LOWORD(wParam); if (cmd==TabsCtrl::CLOSETAB) { //close current tab int nextTab=p->activeTab; int delTab=nextTab; p->activeTab++; if (p->activeTab>=(int)p->tabs.size()) { nextTab--; p->activeTab=nextTab; } p->showActiveTab(); //hide before delete p->tabs.erase(p->tabs.begin()+delTab); p->activeTab=nextTab; p->tabDoLayout(); p->showActiveTab(); InvalidateRect(p->getHWnd(), NULL, true); } if (cmd==TabsCtrl::PREVTAB) { //go to prev tab // SetScrollInfo(p->tabScrollHWnd,SB_LEFT,0,0); if (p->activeTab > 0) { p->activeTab--; p->showActiveTab(); //hide before change p->tabDoLayout(); p->showActiveTab(); InvalidateRect(p->getHWnd(), NULL, true); } } if (cmd==TabsCtrl::NEXTTAB) { //go to next tab // SetScrollInfo(p->tabScrollHWnd,SB_RIGHT,0,0); if ((p->activeTab+1) < (int)p->tabs.size()) { p->activeTab++; p->showActiveTab(); //hide before change p->tabDoLayout(); p->showActiveTab(); InvalidateRect(p->getHWnd(), NULL, true); } } if (cmd==IDS_WINDOWS) { RECT rt; HWND parent=GetParent(p->getHWnd()); GetWindowRect(parent, &rt); RECT rb; SendMessage(g_hWndMenuBar, TB_GETRECT, IDS_WINDOWS, (LPARAM)&rb); p->processPopupMenu(true, rb.left, rt.bottom); } return 0; } case WM_MEASUREITEM: { LPMEASUREITEMSTRUCT mi=(LPMEASUREITEMSTRUCT)lParam; ODR * odr=(ODR *)(mi->itemData); mi->itemHeight=odr->getHeight(); mi->itemWidth=odr->getWidth(); return true; } case WM_DRAWITEM: { LPDRAWITEMSTRUCT di=(LPDRAWITEMSTRUCT) lParam; HBRUSH bgnd=CreateSolidBrush(GetBkColor(di->hDC)); FillRect(di->hDC, &(di->rcItem), bgnd); DeleteObject(bgnd); ODR * odr=(ODR *)(di->itemData); odr->draw(di->hDC, di->rcItem,0); return TRUE; } case WM_SIZE: { int height=GET_Y_LPARAM(lParam); int width=GET_X_LPARAM(lParam); SetRect(&(p->clientRect), 0, 0, width, height); p->updateChildsLayout(); break; } /*case WM_CTLCOLORSTATIC: case WM_CTLCOLORLISTBOX: case WM_CTLCOLOREDIT: { //HGDIOBJ brush= GetStockObject(GRAY_BRUSH); //HGDIOBJ pen= GetStockObject(WHITE_PEN); SetBkColor(hdc, 0x808080); SetTextColor(hdc, 0xffffff); //SelectObject((HDC)wParam, brush); //SelectObject((HDC)wParam, pen); return (BOOL) GetStockObject(GRAY_BRUSH); break; }*/ case WM_DESTROY: //TODO: Destroy all child data associated eith this window return 0; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; }
/* ================ ColorButton_DrawItem Draws the actual color button as as reponse to a WM_DRAWITEM message ================ */ void ColorButton_DrawItem ( HWND hWnd, LPDRAWITEMSTRUCT dis ) { assert ( dis ); HDC hDC = dis->hDC; UINT state = dis->itemState; RECT rDraw = dis->rcItem; RECT rArrow; // Draw outter edge UINT uFrameState = DFCS_BUTTONPUSH|DFCS_ADJUSTRECT; if (state & ODS_SELECTED) { uFrameState |= DFCS_PUSHED; } if (state & ODS_DISABLED) { uFrameState |= DFCS_INACTIVE; } DrawFrameControl ( hDC, &rDraw, DFC_BUTTON, uFrameState ); // Draw Focus if (state & ODS_SELECTED) { OffsetRect(&rDraw, 1,1); } if (state & ODS_FOCUS) { RECT rFocus = {rDraw.left, rDraw.top, rDraw.right - 1, rDraw.bottom}; DrawFocusRect ( hDC, &rFocus ); } InflateRect ( &rDraw, -GetSystemMetrics(SM_CXEDGE), -GetSystemMetrics(SM_CYEDGE) ); // Draw the arrow rArrow.left = rDraw.right - ARROW_SIZE_CX - GetSystemMetrics(SM_CXEDGE) /2; rArrow.right = rArrow.left + ARROW_SIZE_CX; rArrow.top = (rDraw.bottom + rDraw.top)/2 - ARROW_SIZE_CY / 2; rArrow.bottom = (rDraw.bottom + rDraw.top)/2 + ARROW_SIZE_CY / 2; ColorButton_DrawArrow ( hDC, &rArrow, (state & ODS_DISABLED) ? ::GetSysColor(COLOR_GRAYTEXT) : RGB(0,0,0) ); rDraw.right = rArrow.left - GetSystemMetrics(SM_CXEDGE)/2; // Draw separator DrawEdge ( hDC, &rDraw, EDGE_ETCHED, BF_RIGHT); rDraw.right -= (GetSystemMetrics(SM_CXEDGE) * 2) + 1 ; // Draw Color if ((state & ODS_DISABLED) == 0) { HBRUSH color = CreateSolidBrush ( (COLORREF)GetWindowLongPtr ( hWnd, GWL_USERDATA ) ); FillRect ( hDC, &rDraw, color ); FrameRect ( hDC, &rDraw, (HBRUSH)::GetStockObject(BLACK_BRUSH)); DeleteObject( color ); } }
/* * FIXME: * - Cache bitmaps, then just bitblt instead of calling DFC() (and * wasting precious CPU cycles) every time * - Center the buttons verticaly in the rect */ VOID UserDrawCaptionButton(HWND hWnd, LPRECT Rect, DWORD Style, DWORD ExStyle, HDC hDC, BOOL bDown, ULONG Type) { RECT TempRect; if (!(Style & WS_SYSMENU)) { return; } TempRect = *Rect; switch (Type) { case DFCS_CAPTIONMIN: { if (ExStyle & WS_EX_TOOLWINDOW) return; /* ToolWindows don't have min/max buttons */ if (Style & WS_SYSMENU) TempRect.right -= GetSystemMetrics(SM_CXSIZE) + 1; if (Style & (WS_MAXIMIZEBOX | WS_MINIMIZEBOX)) TempRect.right -= GetSystemMetrics(SM_CXSIZE) - 2; TempRect.left = TempRect.right - GetSystemMetrics(SM_CXSIZE) + 1; TempRect.bottom = TempRect.top + GetSystemMetrics(SM_CYSIZE) - 2; TempRect.top += 2; TempRect.right -= 1; DrawFrameControl(hDC, &TempRect, DFC_CAPTION, ((Style & WS_MINIMIZE) ? DFCS_CAPTIONRESTORE : DFCS_CAPTIONMIN) | (bDown ? DFCS_PUSHED : 0) | ((Style & WS_MINIMIZEBOX) ? 0 : DFCS_INACTIVE)); break; } case DFCS_CAPTIONMAX: { if (ExStyle & WS_EX_TOOLWINDOW) return; /* ToolWindows don't have min/max buttons */ if (Style & WS_SYSMENU) TempRect.right -= GetSystemMetrics(SM_CXSIZE) + 1; TempRect.left = TempRect.right - GetSystemMetrics(SM_CXSIZE) + 1; TempRect.bottom = TempRect.top + GetSystemMetrics(SM_CYSIZE) - 2; TempRect.top += 2; TempRect.right -= 1; DrawFrameControl(hDC, &TempRect, DFC_CAPTION, ((Style & WS_MAXIMIZE) ? DFCS_CAPTIONRESTORE : DFCS_CAPTIONMAX) | (bDown ? DFCS_PUSHED : 0) | ((Style & WS_MAXIMIZEBOX) ? 0 : DFCS_INACTIVE)); break; } case DFCS_CAPTIONCLOSE: { HMENU hSysMenu = GetSystemMenu(hWnd, FALSE); UINT MenuState = GetMenuState(hSysMenu, SC_CLOSE, MF_BYCOMMAND); /* in case of error MenuState==0xFFFFFFFF */ /* FIXME: A tool window has a smaller Close button */ if (ExStyle & WS_EX_TOOLWINDOW) { TempRect.left = TempRect.right - GetSystemMetrics(SM_CXSMSIZE); TempRect.bottom = TempRect.top + GetSystemMetrics(SM_CYSMSIZE) - 2; } else { TempRect.left = TempRect.right - GetSystemMetrics(SM_CXSIZE); TempRect.bottom = TempRect.top + GetSystemMetrics(SM_CYSIZE) - 2; } TempRect.top += 2; TempRect.right -= 2; DrawFrameControl(hDC, &TempRect, DFC_CAPTION, (DFCS_CAPTIONCLOSE | (bDown ? DFCS_PUSHED : 0) | ((!(MenuState & (MF_GRAYED|MF_DISABLED)) && !(GetClassLong(hWnd, GCL_STYLE) & CS_NOCLOSE)) ? 0 : DFCS_INACTIVE))); break; } } }
/* * FIXME: * - Drawing of WS_BORDER after scrollbars * - Correct drawing of size-box */ LRESULT DefWndNCPaint(HWND hWnd, HRGN hRgn, BOOL Active) { HDC hDC; DWORD Style, ExStyle; HWND Parent; RECT ClientRect, WindowRect, CurrentRect, TempRect; if (!IsWindowVisible(hWnd)) return 0; Style = GetWindowLongPtrW(hWnd, GWL_STYLE); TRACE("DefWndNCPaint: hWnd %p, hRgn %p, Active %s.\n", hWnd, hRgn, Active ? "TRUE" : "FALSE"); hDC = GetDCEx(hWnd, hRgn, DCX_WINDOW | DCX_INTERSECTRGN | DCX_USESTYLE | DCX_KEEPCLIPRGN); if (hDC == 0) { ERR("hDC is NULL!\n"); if (hRgn != HRGN_WINDOW) DeleteObject(hRgn); return 0; } Parent = GetParent(hWnd); ExStyle = GetWindowLongPtrW(hWnd, GWL_EXSTYLE); if (Active == -1) { if (ExStyle & WS_EX_MDICHILD) { Active = IsChild(GetForegroundWindow(), hWnd); if (Active) Active = (hWnd == (HWND)SendMessageW(Parent, WM_MDIGETACTIVE, 0, 0)); } else { Active = (GetForegroundWindow() == hWnd); } } GetWindowRect(hWnd, &WindowRect); GetClientRect(hWnd, &ClientRect); CurrentRect.top = CurrentRect.left = 0; CurrentRect.right = WindowRect.right - WindowRect.left; CurrentRect.bottom = WindowRect.bottom - WindowRect.top; /* Draw outer edge */ if (UserHasWindowEdge(Style, ExStyle)) { DrawEdge(hDC, &CurrentRect, EDGE_RAISED, BF_RECT | BF_ADJUST); } else if (ExStyle & WS_EX_STATICEDGE) { #if 0 DrawEdge(hDC, &CurrentRect, BDR_SUNKENINNER, BF_RECT | BF_ADJUST | BF_FLAT); #else SelectObject(hDC, GetSysColorBrush(COLOR_BTNSHADOW)); PatBlt(hDC, CurrentRect.left, CurrentRect.top, CurrentRect.right - CurrentRect.left, 1, PATCOPY); PatBlt(hDC, CurrentRect.left, CurrentRect.top, 1, CurrentRect.bottom - CurrentRect.top, PATCOPY); SelectObject(hDC, GetSysColorBrush(COLOR_BTNHIGHLIGHT)); PatBlt(hDC, CurrentRect.left, CurrentRect.bottom - 1, CurrentRect.right - CurrentRect.left, 1, PATCOPY); PatBlt(hDC, CurrentRect.right - 1, CurrentRect.top, 1, CurrentRect.bottom - CurrentRect.top, PATCOPY); InflateRect(&CurrentRect, -1, -1); #endif } /* Firstly the "thick" frame */ if ((Style & WS_THICKFRAME) && !(Style & WS_MINIMIZE)) { LONG Width = (GetSystemMetrics(SM_CXFRAME) - GetSystemMetrics(SM_CXDLGFRAME)) * GetSystemMetrics(SM_CXBORDER); LONG Height = (GetSystemMetrics(SM_CYFRAME) - GetSystemMetrics(SM_CYDLGFRAME)) * GetSystemMetrics(SM_CYBORDER); SelectObject(hDC, GetSysColorBrush(Active ? COLOR_ACTIVEBORDER : COLOR_INACTIVEBORDER)); /* Draw frame */ PatBlt(hDC, CurrentRect.left, CurrentRect.top, CurrentRect.right - CurrentRect.left, Height, PATCOPY); PatBlt(hDC, CurrentRect.left, CurrentRect.top, Width, CurrentRect.bottom - CurrentRect.top, PATCOPY); #ifdef __REACTOS__ PatBlt(hDC, CurrentRect.left, CurrentRect.bottom - 1, CurrentRect.right - CurrentRect.left, -Height, PATCOPY); PatBlt(hDC, CurrentRect.right - 1, CurrentRect.top, -Width, CurrentRect.bottom - CurrentRect.top, PATCOPY); #else PatBlt(hDC, CurrentRect.left, CurrentRect.bottom, CurrentRect.right - CurrentRect.left, -Height, PATCOPY); PatBlt(hDC, CurrentRect.right, CurrentRect.top, -Width, CurrentRect.bottom - CurrentRect.top, PATCOPY); #endif InflateRect(&CurrentRect, -Width, -Height); } /* Now the other bit of the frame */ if (Style & (WS_DLGFRAME | WS_BORDER) || ExStyle & WS_EX_DLGMODALFRAME) { DWORD Width = GetSystemMetrics(SM_CXBORDER); DWORD Height = GetSystemMetrics(SM_CYBORDER); SelectObject(hDC, GetSysColorBrush( (ExStyle & (WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE)) ? COLOR_3DFACE : (ExStyle & WS_EX_STATICEDGE) ? COLOR_WINDOWFRAME : (Style & (WS_DLGFRAME | WS_THICKFRAME)) ? COLOR_3DFACE : COLOR_WINDOWFRAME)); /* Draw frame */ PatBlt(hDC, CurrentRect.left, CurrentRect.top, CurrentRect.right - CurrentRect.left, Height, PATCOPY); PatBlt(hDC, CurrentRect.left, CurrentRect.top, Width, CurrentRect.bottom - CurrentRect.top, PATCOPY); #ifdef __REACTOS__ PatBlt(hDC, CurrentRect.left, CurrentRect.bottom - 1, CurrentRect.right - CurrentRect.left, -Height, PATCOPY); PatBlt(hDC, CurrentRect.right - 1, CurrentRect.top, -Width, CurrentRect.bottom - CurrentRect.top, PATCOPY); #else PatBlt(hDC, CurrentRect.left, CurrentRect.bottom, CurrentRect.right - CurrentRect.left, -Height, PATCOPY); PatBlt(hDC, CurrentRect.right, CurrentRect.top, -Width, CurrentRect.bottom - CurrentRect.top, PATCOPY); #endif InflateRect(&CurrentRect, -Width, -Height); } /* Draw caption */ if ((Style & WS_CAPTION) == WS_CAPTION) { DWORD CaptionFlags = DC_ICON | DC_TEXT | DC_BUTTONS; HPEN PreviousPen; BOOL Gradient = FALSE; if(SystemParametersInfoW(SPI_GETGRADIENTCAPTIONS, 0, &Gradient, 0) && Gradient) { CaptionFlags |= DC_GRADIENT; } TempRect = CurrentRect; if (Active) { CaptionFlags |= DC_ACTIVE; } if (ExStyle & WS_EX_TOOLWINDOW) { CaptionFlags |= DC_SMALLCAP; TempRect.bottom = TempRect.top + GetSystemMetrics(SM_CYSMCAPTION) - 1; CurrentRect.top += GetSystemMetrics(SM_CYSMCAPTION); } else { TempRect.bottom = TempRect.top + GetSystemMetrics(SM_CYCAPTION) - 1; CurrentRect.top += GetSystemMetrics(SM_CYCAPTION); } NtUserDrawCaption(hWnd, hDC, &TempRect, CaptionFlags); /* Draw buttons */ if (Style & WS_SYSMENU) { UserDrawCaptionButton(hWnd, &TempRect, Style, ExStyle, hDC, FALSE, DFCS_CAPTIONCLOSE); if ((Style & (WS_MAXIMIZEBOX | WS_MINIMIZEBOX)) && !(ExStyle & WS_EX_TOOLWINDOW)) { UserDrawCaptionButton(hWnd, &TempRect, Style, ExStyle, hDC, FALSE, DFCS_CAPTIONMIN); UserDrawCaptionButton(hWnd, &TempRect, Style, ExStyle, hDC, FALSE, DFCS_CAPTIONMAX); } } if(!(Style & WS_MINIMIZE)) { /* Line under caption */ PreviousPen = SelectObject(hDC, GetStockObject(DC_PEN)); SetDCPenColor(hDC, GetSysColor( ((ExStyle & (WS_EX_STATICEDGE | WS_EX_CLIENTEDGE | WS_EX_DLGMODALFRAME)) == WS_EX_STATICEDGE) ? COLOR_WINDOWFRAME : COLOR_3DFACE)); MoveToEx(hDC, TempRect.left, TempRect.bottom, NULL); LineTo(hDC, TempRect.right, TempRect.bottom); SelectObject(hDC, PreviousPen); } } if(!(Style & WS_MINIMIZE)) { HMENU menu = GetMenu(hWnd); /* Draw menu bar */ if (menu && !(Style & WS_CHILD)) { TempRect = CurrentRect; TempRect.bottom = TempRect.top + (UINT)NtUserxSetMenuBarHeight(menu, 0); CurrentRect.top += MenuDrawMenuBar(hDC, &TempRect, hWnd, FALSE); } if (ExStyle & WS_EX_CLIENTEDGE) { DrawEdge(hDC, &CurrentRect, EDGE_SUNKEN, BF_RECT | BF_ADJUST); } /* Draw the scrollbars */ if ((Style & WS_VSCROLL) && (Style & WS_HSCROLL) && IntIsScrollBarVisible(hWnd, OBJID_VSCROLL) && IntIsScrollBarVisible(hWnd, OBJID_HSCROLL)) { RECT ParentClientRect; TempRect = CurrentRect; if (ExStyle & WS_EX_LEFTSCROLLBAR) TempRect.right = TempRect.left + GetSystemMetrics(SM_CXVSCROLL); else TempRect.left = TempRect.right - GetSystemMetrics(SM_CXVSCROLL); TempRect.top = TempRect.bottom - GetSystemMetrics(SM_CYHSCROLL); FillRect(hDC, &TempRect, GetSysColorBrush(COLOR_BTNFACE)); /* FIXME: Correct drawing of size-box with WS_EX_LEFTSCROLLBAR */ if(Parent) GetClientRect(Parent, &ParentClientRect); if (HASSIZEGRIP(Style, ExStyle, GetWindowLongPtrW(Parent, GWL_STYLE), WindowRect, ParentClientRect)) { DrawFrameControl(hDC, &TempRect, DFC_SCROLL, DFCS_SCROLLSIZEGRIP); } IntDrawScrollBar(hWnd, hDC, SB_VERT); IntDrawScrollBar(hWnd, hDC, SB_HORZ); } else { if (Style & WS_VSCROLL && IntIsScrollBarVisible(hWnd, OBJID_VSCROLL)) IntDrawScrollBar(hWnd, hDC, SB_VERT); else if (Style & WS_HSCROLL && IntIsScrollBarVisible(hWnd, OBJID_HSCROLL)) IntDrawScrollBar(hWnd, hDC, SB_HORZ); } } ReleaseDC(hWnd, hDC); if (hRgn != HRGN_WINDOW) DeleteObject(hRgn); // We use DCX_KEEPCLIPRGN return 0; // For WM_NCPAINT message, return 0. }
/********************************************************************** * Push Button Functions */ static void PB_Paint( HWND hwnd, HDC hDC, UINT action ) { RECT rc, r; UINT dtFlags, uState; HPEN hOldPen; HBRUSH hOldBrush; INT oldBkMode; COLORREF oldTxtColor; HFONT hFont; LONG state = get_button_state( hwnd ); LONG style = GetWindowLongW( hwnd, GWL_STYLE ); BOOL pushedState = (state & BST_PUSHED); HWND parent; HRGN hrgn; GetClientRect( hwnd, &rc ); /* Send WM_CTLCOLOR to allow changing the font (the colors are fixed) */ if ((hFont = get_button_font( hwnd ))) SelectObject( hDC, hFont ); parent = GetParent(hwnd); if (!parent) parent = hwnd; SendMessageW( parent, WM_CTLCOLORBTN, (WPARAM)hDC, (LPARAM)hwnd ); hrgn = set_control_clipping( hDC, &rc ); hOldPen = SelectObject(hDC, SYSCOLOR_GetPen(COLOR_WINDOWFRAME)); hOldBrush = SelectObject(hDC,GetSysColorBrush(COLOR_BTNFACE)); oldBkMode = SetBkMode(hDC, TRANSPARENT); if (get_button_type(style) == BS_DEFPUSHBUTTON) { if (action != ODA_FOCUS) Rectangle(hDC, rc.left, rc.top, rc.right, rc.bottom); InflateRect( &rc, -1, -1 ); } /* completely skip the drawing if only focus has changed */ if (action == ODA_FOCUS) goto draw_focus; uState = DFCS_BUTTONPUSH; if (style & BS_FLAT) uState |= DFCS_MONO; else if (pushedState) { if (get_button_type(style) == BS_DEFPUSHBUTTON ) uState |= DFCS_FLAT; else uState |= DFCS_PUSHED; } if (state & (BST_CHECKED | BST_INDETERMINATE)) uState |= DFCS_CHECKED; DrawFrameControl( hDC, &rc, DFC_BUTTON, uState ); /* draw button label */ r = rc; dtFlags = BUTTON_CalcLabelRect(hwnd, hDC, &r); if (dtFlags == (UINT)-1L) goto cleanup; if (pushedState) OffsetRect(&r, 1, 1); oldTxtColor = SetTextColor( hDC, GetSysColor(COLOR_BTNTEXT) ); BUTTON_DrawLabel(hwnd, hDC, dtFlags, &r); SetTextColor( hDC, oldTxtColor ); draw_focus: if (action == ODA_FOCUS || (state & BST_FOCUS)) { InflateRect( &rc, -2, -2 ); DrawFocusRect( hDC, &rc ); } cleanup: SelectObject( hDC, hOldPen ); SelectObject( hDC, hOldBrush ); SetBkMode(hDC, oldBkMode); SelectClipRgn( hDC, hrgn ); if (hrgn) DeleteObject( hrgn ); }
static void CB_Paint( HWND hwnd, HDC hDC, UINT action ) { RECT rbox, rtext, client; HBRUSH hBrush; int delta; UINT dtFlags; HFONT hFont; LONG state = get_button_state( hwnd ); LONG style = GetWindowLongW( hwnd, GWL_STYLE ); HWND parent; HRGN hrgn; if (style & BS_PUSHLIKE) { PB_Paint( hwnd, hDC, action ); return; } GetClientRect(hwnd, &client); rbox = rtext = client; if ((hFont = get_button_font( hwnd ))) SelectObject( hDC, hFont ); parent = GetParent(hwnd); if (!parent) parent = hwnd; hBrush = (HBRUSH)SendMessageW(parent, WM_CTLCOLORSTATIC, (WPARAM)hDC, (LPARAM)hwnd); if (!hBrush) /* did the app forget to call defwindowproc ? */ hBrush = (HBRUSH)DefWindowProcW(parent, WM_CTLCOLORSTATIC, (WPARAM)hDC, (LPARAM)hwnd ); hrgn = set_control_clipping( hDC, &client ); if (style & BS_LEFTTEXT) { /* magic +4 is what CTL3D expects */ rtext.right -= checkBoxWidth + 4; rbox.left = rbox.right - checkBoxWidth; } else { rtext.left += checkBoxWidth + 4; rbox.right = checkBoxWidth; } /* Since WM_ERASEBKGND does nothing, first prepare background */ if (action == ODA_SELECT) FillRect( hDC, &rbox, hBrush ); if (action == ODA_DRAWENTIRE) FillRect( hDC, &client, hBrush ); /* Draw label */ client = rtext; dtFlags = BUTTON_CalcLabelRect(hwnd, hDC, &rtext); /* Only adjust rbox when rtext is valid */ if (dtFlags != (UINT)-1L) { rbox.top = rtext.top; rbox.bottom = rtext.bottom; } /* Draw the check-box bitmap */ if (action == ODA_DRAWENTIRE || action == ODA_SELECT) { UINT flags; if ((get_button_type(style) == BS_RADIOBUTTON) || (get_button_type(style) == BS_AUTORADIOBUTTON)) flags = DFCS_BUTTONRADIO; else if (state & BST_INDETERMINATE) flags = DFCS_BUTTON3STATE; else flags = DFCS_BUTTONCHECK; if (state & (BST_CHECKED | BST_INDETERMINATE)) flags |= DFCS_CHECKED; if (state & BST_PUSHED) flags |= DFCS_PUSHED; if (style & WS_DISABLED) flags |= DFCS_INACTIVE; /* rbox must have the correct height */ delta = rbox.bottom - rbox.top - checkBoxHeight; if (style & BS_TOP) { if (delta > 0) { rbox.bottom = rbox.top + checkBoxHeight; } else { rbox.top -= -delta/2 + 1; rbox.bottom = rbox.top + checkBoxHeight; } } else if (style & BS_BOTTOM) { if (delta > 0) { rbox.top = rbox.bottom - checkBoxHeight; } else { rbox.bottom += -delta/2 + 1; rbox.top = rbox.bottom - checkBoxHeight; } } else { /* Default */ if (delta > 0) { int ofs = (delta / 2); rbox.bottom -= ofs + 1; rbox.top = rbox.bottom - checkBoxHeight; } else if (delta < 0) { int ofs = (-delta / 2); rbox.top -= ofs + 1; rbox.bottom = rbox.top + checkBoxHeight; } } DrawFrameControl( hDC, &rbox, DFC_BUTTON, flags ); } if (dtFlags == (UINT)-1L) /* Noting to draw */ return; if (action == ODA_DRAWENTIRE) BUTTON_DrawLabel(hwnd, hDC, dtFlags, &rtext); /* ... and focus */ if (action == ODA_FOCUS || (state & BST_FOCUS)) { rtext.left--; rtext.right++; IntersectRect(&rtext, &rtext, &client); DrawFocusRect( hDC, &rtext ); } SelectClipRgn( hDC, hrgn ); if (hrgn) DeleteObject( hrgn ); }
/******************************************************************** * Function : SimLoop() * Purpose : Performs a single Simulation Loop iteration. Includes * drawing. ********************************************************************/ int SimLoop(void) { static int nFramesPerSecond = 0; static int nFramesSinceLastTick; static DWORD LastTicks = 0; DWORD Ticks; HDC hDC; HFONT hOldFont; char s[80]; int slen; DDSURFACEDESC ddsd; DDBLTFX BltFx; HRESULT ddreturn; /* Perform a single step in our world. */ if (StepWorld(bForwardKey, bBackKey, bLeftKey, bRightKey, nState, nGauge)) { if (lpPrimary->IsLost() == DDERR_SURFACELOST) lpPrimary->Restore(); /* Clear the backbuffer. */ #if CLEARBCKGRND BltFx.dwSize = sizeof(BltFx); BltFx.dwFillColor = 255; ddreturn = lpBackbuffer->Blt(NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &BltFx); #else ddreturn = DD_OK; #endif if (ddreturn == DD_OK) { /* While this is running, prepare * the drawing. */ if (PrepDrawWorld()) { /* Lock the surface. */ memset(&ddsd, 0, sizeof(DDSURFACEDESC)); ddsd.dwSize = sizeof(ddsd); ddreturn = lpBackbuffer->Lock(NULL, &ddsd, DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR, NULL); if (ddreturn == DD_OK) { DrawWorld((unsigned char *)ddsd.lpSurface, (int)ddsd.lPitch); int nX, nY; static unsigned char dummy; unsigned char ni; ni = 0; for (nY = 0; nY < 16; nY++) for (nX = 0; nX < 16; nX++) { /* Draw a small block at (nX * 3, nY * 3) */ ((unsigned char *)ddsd.lpSurface)[(nY * 3 * ddsd.lPitch) + (nX * 3)] = ni; ((unsigned char *)ddsd.lpSurface)[(nY * 3 * ddsd.lPitch) + (nX * 3 + 1)] = ni; ((unsigned char *)ddsd.lpSurface)[((nY * 3 + 1) * ddsd.lPitch) + (nX * 3)] = ni; ((unsigned char *)ddsd.lpSurface)[((nY * 3 + 1) * ddsd.lPitch) + (nX * 3 + 1)] = ni; ni++; } lpBackbuffer->Unlock(NULL); /* And now write Frames per second. */ /* Increment Frame counter. */ nFramesSinceLastTick++; /* Get system tick count. */ Ticks = GetTickCount(); /* Update fps value every second. */ if (Ticks > (LastTicks + 1000)) { nFramesPerSecond = nFramesSinceLastTick; nFramesSinceLastTick = 0; LastTicks = Ticks; } /* Get a DC to the buffer & write count. */ if (DD_OK == lpBackbuffer->GetDC(&hDC)) { SetBkMode(hDC, TRANSPARENT); hOldFont = SelectObject(hDC, AppFont); /* Build a string for display. */ slen = wsprintf(s, "FPS : %d", nFramesPerSecond); /* And draw the text. */ SetTextColor(hDC, RGB(0,0,0)); SIZE sz; GetTextExtentPoint32(hDC, s, slen, &sz); RECT rc; rc.top = 0; rc.left = 16 * 3; rc.right = 16 * 3 + sz.cx + 10; rc.bottom = sz.cy + 10; DrawFrameControl(hDC, &rc, DFC_BUTTON, DFCS_BUTTONPUSH); TextOut(hDC, 16*3 + 5, 5, s, slen); SelectObject(hDC, hOldFont); lpBackbuffer->ReleaseDC(hDC); } /* Perform required pageflipping to make the surface * we drawed visible. */ ddreturn = lpPrimary->Flip(NULL, DDFLIP_WAIT); if (ddreturn == DD_OK) { return 1; } } } } } return 0; }
LRESULT CALLBACK NotificationWnd::WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)\ { NotificationWnd *wnd = (NotificationWnd *)GetWindowLongPtr(hwnd, GWLP_USERDATA); if (WM_ERASEBKGND == message) { // do nothing, helps to avoid flicker return TRUE; } if (WM_TIMER == message && TIMEOUT_TIMER_ID == wParam) { if (wnd->notificationCb) wnd->notificationCb->RemoveNotification(wnd); else delete wnd; return 0; } if (WM_PAINT == message && wnd) { PAINTSTRUCT ps; HDC hdcWnd = BeginPaint(hwnd, &ps); ClientRect rect(hwnd); DoubleBuffer buffer(hwnd, rect); HDC hdc = buffer.GetDC(); HFONT oldfnt = SelectFont(hdc, wnd->font); RECT rTmp = rect.ToRECT(); DrawFrameControl(hdc, &rTmp, DFC_BUTTON, DFCS_BUTTONPUSH); if (wnd->highlight) { SetBkMode(hdc, OPAQUE); SetTextColor(hdc, GetSysColor(COLOR_HIGHLIGHTTEXT)); SetBkColor(hdc, GetSysColor(COLOR_HIGHLIGHT)); } else { SetBkMode(hdc, TRANSPARENT); SetTextColor(hdc, GetSysColor(COLOR_WINDOWTEXT)); } rect.Inflate(-PADDING, -PADDING); RectI rectMsg = rect; if (wnd->hasProgress) rectMsg.dy -= PROGRESS_HEIGHT + PADDING / 2; if (wnd->hasCancel) rectMsg.dx -= 20; ScopedMem<WCHAR> text(win::GetText(hwnd)); rTmp = rectMsg.ToRECT(); DrawText(hdc, text, -1, &rTmp, DT_SINGLELINE | DT_NOPREFIX); if (wnd->hasCancel) { rTmp = GetCancelRect(hwnd).ToRECT(); DrawFrameControl(hdc, &rTmp, DFC_CAPTION, DFCS_CAPTIONCLOSE | DFCS_FLAT); } if (wnd->hasProgress) { rect.dx = wnd->progressWidth; rect.y += rectMsg.dy + PADDING / 2; rect.dy = PROGRESS_HEIGHT; PaintRect(hdc, rect); rect.x += 2; rect.dx = (wnd->progressWidth - 3) * wnd->progress / 100; rect.y += 2; rect.dy -= 3; HBRUSH brush = GetStockBrush(BLACK_BRUSH); rTmp = rect.ToRECT(); FillRect(hdc, &rTmp, brush); DeleteObject(brush); } SelectFont(hdc, oldfnt); buffer.Flush(hdcWnd); EndPaint(hwnd, &ps); return 0; } if (WM_SETCURSOR == message && wnd->hasCancel) { PointI pt; if (GetCursorPosInHwnd(hwnd, pt) && GetCancelRect(hwnd).Contains(pt)) { SetCursor(LoadCursor(NULL, IDC_HAND)); return TRUE; } } if (WM_LBUTTONUP == message && wnd->hasCancel) { if (GetCancelRect(hwnd).Contains(PointI(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)))) { if (wnd->notificationCb) wnd->notificationCb->RemoveNotification(wnd); else delete wnd; return 0; } } return DefWindowProc(hwnd, message, wParam, lParam); }
static void PaintWorker(MButtonCtrl *ctl, HDC hdcPaint) { if (hdcPaint) { HDC hdcMem; HBITMAP hbmMem; HBITMAP hbmOld = 0; RECT rcClient; HFONT hOldFont = 0; int xOffset = 0; GetClientRect(ctl->hwnd, &rcClient); hdcMem = CreateCompatibleDC(hdcPaint); hbmMem = CreateCompatibleBitmap(hdcPaint, rcClient.right - rcClient.left, rcClient.bottom - rcClient.top); hbmOld = SelectObject(hdcMem, hbmMem); hOldFont = SelectObject(hdcMem, ctl->hFont); // If its a push button, check to see if it should stay pressed if (ctl->pushBtn && ctl->pbState) ctl->stateId = PBS_PRESSED; // Draw the flat button if (ctl->flatBtn) { if (ctl->hThemeToolbar && ctl->bThemed) { RECT rc = rcClient; int state = IsWindowEnabled(ctl->hwnd) ? (ctl->stateId == PBS_NORMAL && ctl->defbutton ? PBS_DEFAULTED : ctl->stateId) : PBS_DISABLED; SkinDrawBg(ctl->hwnd, hdcMem); if (MyIsThemeBackgroundPartiallyTransparent(ctl->hThemeToolbar, TP_BUTTON, TBStateConvert2Flat(state))) { MyDrawThemeParentBackground(ctl->hwnd, hdcMem, &rc); } MyDrawThemeBackground(ctl->hThemeToolbar, hdcMem, TP_BUTTON, TBStateConvert2Flat(state), &rc, &rc); } else { HBRUSH hbr; RECT rc = rcClient; if(ctl->buttonItem) { RECT rcParent; POINT pt; HWND hwndParent = pcli->hwndContactList; ImageItem *imgItem = ctl->stateId == PBS_HOT ? ctl->buttonItem->imgHover : (ctl->stateId == PBS_PRESSED ? ctl->buttonItem->imgPressed : ctl->buttonItem->imgNormal); LONG *glyphMetrics = ctl->stateId == PBS_HOT ? ctl->buttonItem->hoverGlyphMetrics : (ctl->stateId == PBS_PRESSED ? ctl->buttonItem->pressedGlyphMetrics : ctl->buttonItem->normalGlyphMetrics); //if(ctl->stateId == PBS_HOT && glyphMetrics[2] <= 1 && glyphMetrics[3] <= 1) // glyphMetrics = ctl->lastGlyphMetrics; GetWindowRect(ctl->hwnd, &rcParent); pt.x = rcParent.left; pt.y = rcParent.top; ScreenToClient(pcli->hwndContactList, &pt); BitBlt(hdcMem, 0, 0, rc.right, rc.bottom, g_CluiData.hdcBg, pt.x, pt.y, SRCCOPY); if(imgItem) DrawAlpha(hdcMem, &rc, 0, 0, 0, 0, 0, 0, 0, imgItem); if(g_glyphItem) { AlphaBlend(hdcMem, (rc.right - glyphMetrics[2]) / 2, (rc.bottom - glyphMetrics[3]) / 2, glyphMetrics[2], glyphMetrics[3], g_glyphItem->hdc, glyphMetrics[0], glyphMetrics[1], glyphMetrics[2], glyphMetrics[3], g_glyphItem->bf); //CopyMemory(ctl->lastGlyphMetrics, glyphMetrics, 4 * sizeof(LONG)); } } else if(ctl->bSkinned) { // skinned RECT rcParent; POINT pt; HWND hwndParent = pcli->hwndContactList; StatusItems_t *item; int item_id; GetWindowRect(ctl->hwnd, &rcParent); pt.x = rcParent.left; pt.y = rcParent.top; ScreenToClient(pcli->hwndContactList, &pt); if(HIWORD(ctl->bSkinned)) item_id = ctl->stateId == PBS_HOT ? ID_EXTBKTBBUTTONMOUSEOVER : (ctl->stateId == PBS_PRESSED ? ID_EXTBKTBBUTTONSPRESSED : ID_EXTBKTBBUTTONSNPRESSED); //GetItemByStatus(ctl->stateId == PBS_HOT ? ID_EXTBKBUTTONSMOUSEOVER : (ctl->stateId == PBS_PRESSED ? ID_EXTBKTBBUTTONSPRESSED : ID_EXTBKTBBUTTONSNPRESSED), &item); else item_id = ctl->stateId == PBS_HOT ? ID_EXTBKBUTTONSMOUSEOVER : (ctl->stateId == PBS_PRESSED ? ID_EXTBKBUTTONSPRESSED : ID_EXTBKBUTTONSNPRESSED); item = &StatusItems[item_id - ID_STATUS_OFFLINE]; //GetItemByStatus(ctl->stateId == PBS_PRESSED ? ID_EXTBKBUTTONSPRESSED : ID_EXTBKBUTTONSNPRESSED, &item); SetTextColor(hdcMem, item->TEXTCOLOR); if(item->IGNORED) { if(pt.y < 10 || g_CluiData.bWallpaperMode) //SkinDrawBg(ctl->hwnd, hdcMem); BitBlt(hdcMem, 0, 0, rc.right, rc.bottom, g_CluiData.hdcBg, pt.x, pt.y, SRCCOPY); else FillRect(hdcMem, &rc, GetSysColorBrush(COLOR_3DFACE)); } else { if(pt.y < 10 || g_CluiData.bWallpaperMode) //SkinDrawBg(ctl->hwnd, hdcMem); BitBlt(hdcMem, 0, 0, rc.right, rc.bottom, g_CluiData.hdcBg, pt.x, pt.y, SRCCOPY); else FillRect(hdcMem, &rc, GetSysColorBrush(COLOR_3DFACE)); rc.top += item->MARGIN_TOP; rc.bottom -= item->MARGIN_BOTTOM; rc.left += item->MARGIN_LEFT; rc.right -= item->MARGIN_RIGHT; DrawAlpha(hdcMem, &rc, item->COLOR, item->ALPHA, item->COLOR2, item->COLOR2_TRANSPARENT, item->GRADIENT, item->CORNER, item->BORDERSTYLE, item->imageItem); } } else { if (ctl->stateId == PBS_PRESSED || ctl->stateId == PBS_HOT) hbr = GetSysColorBrush(COLOR_3DFACE); else { HDC dc; HWND hwndParent; hwndParent = GetParent(ctl->hwnd); dc = GetDC(hwndParent); hbr = (HBRUSH) SendMessage(hwndParent, WM_CTLCOLORDLG, (WPARAM) dc, (LPARAM) hwndParent); ReleaseDC(hwndParent, dc); } if (hbr) { FillRect(hdcMem, &rc, hbr); DeleteObject(hbr); } } if(!ctl->bSkinned && ctl->buttonItem == 0) { if (ctl->stateId == PBS_HOT || ctl->focus) { if (ctl->pbState) DrawEdge(hdcMem, &rc, EDGE_ETCHED, BF_RECT | BF_SOFT); else DrawEdge(hdcMem, &rc, BDR_RAISEDOUTER, BF_RECT | BF_SOFT); } else if (ctl->stateId == PBS_PRESSED) DrawEdge(hdcMem, &rc, BDR_SUNKENOUTER, BF_RECT | BF_SOFT); } } } else { // Draw background/border if (ctl->hThemeButton && ctl->bThemed) { int state = IsWindowEnabled(ctl->hwnd) ? (ctl->stateId == PBS_NORMAL && ctl->defbutton ? PBS_DEFAULTED : ctl->stateId) : PBS_DISABLED; POINT pt; RECT rcParent; GetWindowRect(ctl->hwnd, &rcParent); pt.x = rcParent.left; pt.y = rcParent.top; ScreenToClient(pcli->hwndContactList, &pt); BitBlt(hdcMem, 0, 0, rcClient.right, rcClient.bottom, g_CluiData.hdcBg, pt.x, pt.y, SRCCOPY); if (MyIsThemeBackgroundPartiallyTransparent(ctl->hThemeButton, BP_PUSHBUTTON, state)) { MyDrawThemeParentBackground(ctl->hwnd, hdcMem, &rcClient); } MyDrawThemeBackground(ctl->hThemeButton, hdcMem, BP_PUSHBUTTON, state, &rcClient, &rcClient); } else { UINT uState = DFCS_BUTTONPUSH | ((ctl->stateId == PBS_HOT) ? DFCS_HOT : 0) | ((ctl->stateId == PBS_PRESSED) ? DFCS_PUSHED : 0); if (ctl->defbutton && ctl->stateId == PBS_NORMAL) uState |= DLGC_DEFPUSHBUTTON; DrawFrameControl(hdcMem, &rcClient, DFC_BUTTON, uState); } // Draw focus rectangle if button has focus if (ctl->focus) { RECT focusRect = rcClient; InflateRect(&focusRect, -3, -3); DrawFocusRect(hdcMem, &focusRect); } } // If we have an icon or a bitmap, ignore text and only draw the image on the button if (ctl->hIcon || ctl->hIconPrivate || ctl->iIcon) { int ix = (rcClient.right - rcClient.left) / 2 - (g_cxsmIcon / 2); int iy = (rcClient.bottom - rcClient.top) / 2 - (g_cxsmIcon / 2); HICON hIconNew = ctl->hIconPrivate != 0 ? ctl->hIconPrivate : ctl->hIcon; if (lstrlen(ctl->szText) == 0) { if (ctl->iIcon) ImageList_DrawEx(ctl->hIml, ctl->iIcon, hdcMem, ix, iy, g_cxsmIcon, g_cysmIcon, CLR_NONE, CLR_NONE, ILD_NORMAL); else DrawState(hdcMem, NULL, NULL, (LPARAM) hIconNew, 0, ix, iy, g_cxsmIcon, g_cysmIcon, IsWindowEnabled(ctl->hwnd) ? DST_ICON | DSS_NORMAL : DST_ICON | DSS_DISABLED); ctl->sLabel.cx = ctl->sLabel.cy = 0; } else { GetTextExtentPoint32(hdcMem, ctl->szText, lstrlen(ctl->szText), &ctl->sLabel); if(g_cxsmIcon + ctl->sLabel.cx + 8 > rcClient.right - rcClient.left) ctl->sLabel.cx = (rcClient.right - rcClient.left) - g_cxsmIcon - 8; else ctl->sLabel.cx += 4; ix = (rcClient.right - rcClient.left) / 2 - ((g_cxsmIcon + ctl->sLabel.cx) / 2); if (ctl->iIcon) ImageList_DrawEx(ctl->hIml, ctl->iIcon, hdcMem, ix, iy, g_cxsmIcon, g_cysmIcon, CLR_NONE, CLR_NONE, ILD_NORMAL); else DrawState(hdcMem, NULL, NULL, (LPARAM) hIconNew, 0, ix, iy, g_cxsmIcon, g_cysmIcon, IsWindowEnabled(ctl->hwnd) ? DST_ICON | DSS_NORMAL : DST_ICON | DSS_DISABLED); xOffset = ix + g_cxsmIcon + 4; } } else if (ctl->hBitmap) { BITMAP bminfo; int ix, iy; GetObject(ctl->hBitmap, sizeof(bminfo), &bminfo); ix = (rcClient.right - rcClient.left) / 2 - (bminfo.bmWidth / 2); iy = (rcClient.bottom - rcClient.top) / 2 - (bminfo.bmHeight / 2); if (ctl->stateId == PBS_PRESSED) { ix++; iy++; } DrawState(hdcMem, NULL, NULL, (LPARAM) ctl->hBitmap, 0, ix, iy, bminfo.bmWidth, bminfo.bmHeight, IsWindowEnabled(ctl->hwnd) ? DST_BITMAP : DST_BITMAP | DSS_DISABLED); } if (GetWindowTextLength(ctl->hwnd)) { // Draw the text and optinally the arrow RECT rcText; CopyRect(&rcText, &rcClient); SetBkMode(hdcMem, TRANSPARENT); // XP w/themes doesn't used the glossy disabled text. Is it always using COLOR_GRAYTEXT? Seems so. if(!ctl->bSkinned) SetTextColor(hdcMem, IsWindowEnabled(ctl->hwnd) || !ctl->hThemeButton ? GetSysColor(COLOR_BTNTEXT) : GetSysColor(COLOR_GRAYTEXT)); if (ctl->arrow) DrawState(hdcMem, NULL, NULL, (LPARAM) ctl->arrow, 0, rcClient.right - rcClient.left - 5 - g_cxsmIcon + (!ctl->hThemeButton && ctl->stateId == PBS_PRESSED ? 1 : 0), (rcClient.bottom - rcClient.top) / 2 - g_cysmIcon / 2 + (!ctl->hThemeButton && ctl->stateId == PBS_PRESSED ? 1 : 0), g_cxsmIcon, g_cysmIcon, IsWindowEnabled(ctl->hwnd) ? DST_ICON : DST_ICON | DSS_DISABLED); DrawState(hdcMem, NULL, NULL, (LPARAM) ctl->szText, 0, xOffset + (!ctl->hThemeButton && ctl->stateId == PBS_PRESSED ? 1 : 0), ctl->hThemeButton ? (rcText.bottom - rcText.top - ctl->sLabel.cy) / 2 + 1 : (rcText.bottom - rcText.top - ctl->sLabel.cy) / 2 + (ctl->stateId == PBS_PRESSED ? 1 : 0), ctl->sLabel.cx, ctl->sLabel.cy, IsWindowEnabled(ctl->hwnd) || ctl->hThemeButton ? DST_PREFIXTEXT | DSS_NORMAL : DST_PREFIXTEXT | DSS_DISABLED); } if (hOldFont) SelectObject(hdcMem, hOldFont); BitBlt(hdcPaint, 0, 0, rcClient.right - rcClient.left, rcClient.bottom - rcClient.top, hdcMem, 0, 0, SRCCOPY); SelectObject(hdcMem, hbmOld); DeleteObject(hbmMem); DeleteDC(hdcMem); DeleteObject(hbmOld); } }
void OnPaint(HWND hWnd) { HDC dialogDC; PAINTSTRUCT paint; RECT cRC, textRC; int i, xPos, yPos, CharCount; HFONT dcFont; HICON hIcon; HPEN hPen; COLORREF Color; // check if (nCols == 0 || nItems == 0) return; // begin painting dialogDC = BeginPaint(hWnd, &paint); if (dialogDC == NULL) return; // fill the client area GetClientRect(hWnd, &cRC); FillRect(dialogDC, &cRC, (HBRUSH)(COLOR_3DFACE + 1)); // if the selection index exceeded the display items, then // do display item shifting if (selectedWindow >= nItems) nShift = selectedWindow - nItems + 1; else nShift = 0; for (i = 0; i < nItems; ++i) { // get the icon to display hIcon = iconList[i + nShift]; // calculate the position where we start drawing xPos = DIALOG_MARGIN + CX_ITEM_SPACE * (i % nCols) + ITEM_MARGIN; yPos = DIALOG_MARGIN + CY_ITEM_SPACE * (i / nCols) + ITEM_MARGIN; // centering if (nItems < CoolSwitchColumns) { xPos += (itemsW - nItems * CX_ITEM_SPACE) / 2; } // if this position is selected, if (selectedWindow == i + nShift) { // create a solid pen Color = GetSysColor(COLOR_HIGHLIGHT); hPen = CreatePen(PS_SOLID, 1, Color); // draw a rectangle with using the pen SelectObject(dialogDC, hPen); SelectObject(dialogDC, GetStockObject(NULL_BRUSH)); Rectangle(dialogDC, xPos, yPos, xPos + CX_ITEM, yPos + CY_ITEM); Rectangle(dialogDC, xPos + 1, yPos + 1, xPos + CX_ITEM - 1, yPos + CY_ITEM - 1); // delete the pen DeleteObject(hPen); } // draw icon DrawIconEx(dialogDC, xPos + ICON_MARGIN, yPos + ICON_MARGIN, hIcon, CX_ICON, CY_ICON, 0, NULL, DI_NORMAL); } // set the text rectangle SetRect(&textRC, DIALOG_MARGIN, DIALOG_MARGIN + itemsH, totalW - DIALOG_MARGIN, totalH - DIALOG_MARGIN); // draw the sunken button around text DrawFrameControl(dialogDC, &textRC, DFC_BUTTON, DFCS_BUTTONPUSH | DFCS_PUSHED); // get text CharCount = GetWindowTextW(windowList[selectedWindow], windowText, _countof(windowText)); // draw text dcFont = SelectObject(dialogDC, dialogFont); SetTextColor(dialogDC, GetSysColor(COLOR_BTNTEXT)); SetBkMode(dialogDC, TRANSPARENT); DrawTextW(dialogDC, windowText, CharCount, &textRC, DT_CENTER | DT_VCENTER | DT_END_ELLIPSIS | DT_SINGLELINE); SelectObject(dialogDC, dcFont); // end painting EndPaint(hWnd, &paint); }
/** * name: PaintThemeButton * desc: Draws the none themed button * param: ctl - BTNCTRL structure for the button * hdcMem - device context to draw to * rcClient - rectangle of the whole button * return: nothing **/ static void __fastcall PaintButton(BTNCTRL *ctl, HDC hdcMem, LPRECT rcClient) { RECT rcText = { 0, 0, 0, 0 }; TCHAR szText[MAX_PATH] = { 0 }; WORD ccText; // Draw the flat button if (ctl->dwStyle & MBS_FLAT) { HBRUSH hbr = NULL; if (ctl->stateId == PBS_PRESSED || ctl->stateId == PBS_HOT) hbr = GetSysColorBrush(COLOR_3DLIGHT); else { HDC dc; HWND hwndParent; hwndParent = GetParent(ctl->hwnd); if (dc = GetDC(hwndParent)) { hbr = (HBRUSH)SendMessage(hwndParent, WM_CTLCOLORDLG, (WPARAM)dc, (LPARAM)hwndParent); ReleaseDC(hwndParent, dc); } } if (hbr) { FillRect(hdcMem, rcClient, hbr); DeleteObject(hbr); } if (ctl->stateId == PBS_HOT || ctl->bFocus) { if (ctl->pbState) DrawEdge(hdcMem, rcClient, EDGE_ETCHED, BF_RECT|BF_SOFT); else DrawEdge(hdcMem, rcClient, BDR_RAISEDOUTER, BF_RECT|BF_SOFT|BF_FLAT); } else if (ctl->stateId == PBS_PRESSED) DrawEdge(hdcMem, rcClient, BDR_SUNKENOUTER, BF_RECT|BF_SOFT); } else { UINT uState = DFCS_BUTTONPUSH|((ctl->stateId == PBS_HOT) ? DFCS_HOT : 0)|((ctl->stateId == PBS_PRESSED) ? DFCS_PUSHED : 0); if (ctl->defbutton&&ctl->stateId==PBS_NORMAL) uState |= DLGC_DEFPUSHBUTTON; DrawFrameControl(hdcMem, rcClient, DFC_BUTTON, uState); // Draw focus rectangle if button has focus if (ctl->bFocus) { RECT focusRect = *rcClient; InflateRect(&focusRect, -3, -3); DrawFocusRect(hdcMem, &focusRect); } } // calculate text rect { SIZE sizeText; HFONT hOldFont; ccText = GetWindowText(ctl->hwnd, szText, SIZEOF(szText)); if (ccText > 0) { hOldFont = (HFONT)SelectObject(hdcMem, ctl->hFont); GetTextExtentPoint32(hdcMem, szText, ccText, &sizeText); if (ctl->cHot) { SIZE sizeHot; GetTextExtentPoint32A(hdcMem, "&", 1, &sizeHot); sizeText.cx -= sizeHot.cx; } SelectObject(hdcMem, hOldFont); rcText.left = (ctl->hIcon) ? 0 : (rcClient->right - rcClient->left - sizeText.cx) / 2; rcText.top = (rcClient->bottom - rcClient->top - sizeText.cy) / 2; rcText.right = rcText.left + sizeText.cx; rcText.bottom = rcText.top + sizeText.cy; if (ctl->stateId == PBS_PRESSED) OffsetRect(&rcText, 1, 1); } } PaintIcon(ctl, hdcMem, &ccText, rcClient, &rcText); // draw text if (ccText > 0) { HFONT hOldFont; hOldFont = (HFONT)SelectObject(hdcMem, ctl->hFont); SetBkMode(hdcMem, TRANSPARENT); SetTextColor(hdcMem, IsWindowEnabled(ctl->hwnd) || !ctl->hThemeButton ? ctl->stateId == PBS_HOT ? GetSysColor(COLOR_HOTLIGHT) : GetSysColor(COLOR_BTNTEXT) : GetSysColor(COLOR_GRAYTEXT)); DrawState(hdcMem, NULL, NULL, (LPARAM)szText, 0, rcText.left, rcText.top, rcText.right - rcText.left, rcText.bottom - rcText.top, IsWindowEnabled(ctl->hwnd) || ctl->hThemeButton ? DST_PREFIXTEXT | DSS_NORMAL : DST_PREFIXTEXT | DSS_DISABLED); SelectObject(hdcMem, hOldFont); } }