VOID NcAreaDrawButton( _Inout_ PEDIT_CONTEXT Context, _In_ RECT ButtonRect ) { HDC hdc; HDC bufferDc; HBITMAP bufferBitmap; HBITMAP oldBufferBitmap; RECT bufferRect = { 0, 0, ButtonRect.right - ButtonRect.left, ButtonRect.bottom - ButtonRect.top }; if (!(hdc = GetWindowDC(Context->WindowHandle))) return; bufferDc = CreateCompatibleDC(hdc); bufferBitmap = CreateCompatibleBitmap(hdc, bufferRect.right, bufferRect.bottom); oldBufferBitmap = SelectObject(bufferDc, bufferBitmap); if (Context->Pushed) { FillRect(bufferDc, &bufferRect, Context->BrushPushed); //FrameRect(bufferDc, &bufferRect, CreateSolidBrush(RGB(0xff, 0, 0))); } else if (Context->Hot) { FillRect(bufferDc, &bufferRect, Context->BrushHot); //FrameRect(bufferDc, &bufferRect, CreateSolidBrush(RGB(38, 160, 218))); } else { FillRect(bufferDc, &bufferRect, Context->BrushNormal); } // Draw the image centered within the rect. if (SearchboxText->Length > 0) { ImageList_Draw( Context->ImageList, 0, bufferDc, bufferRect.left + ((bufferRect.right - bufferRect.left) - Context->ImageWidth) / 2, bufferRect.top + ((bufferRect.bottom - bufferRect.top) - Context->ImageHeight) / 2, ILD_NORMAL | ILD_TRANSPARENT ); } else { ImageList_Draw( Context->ImageList, 1, bufferDc, bufferRect.left + ((bufferRect.right - bufferRect.left) - Context->ImageWidth + 2) / 2, // (ImageWidth + 2) offset left by two bufferRect.top + ((bufferRect.bottom - bufferRect.top) - (Context->ImageHeight - 2)) / 2, // (ImageHeight - 2) offset top by one ILD_NORMAL | ILD_TRANSPARENT ); } BitBlt(hdc, ButtonRect.left, ButtonRect.top, ButtonRect.right, ButtonRect.bottom, bufferDc, 0, 0, SRCCOPY); SelectObject(bufferDc, oldBufferBitmap); DeleteObject(bufferBitmap); DeleteDC(bufferDc); ReleaseDC(Context->WindowHandle, hdc); }
INT_PTR TffdshowPageDec::msgProc(UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_COMMAND: switch (LOWORD(wParam)) { case IDC_CBX_PRESETS: if (HIWORD(wParam) == CBN_SELCHANGE) { char_t presetName[256], actPresetName[256]; GetDlgItemText(m_hwnd, IDC_CBX_PRESETS, presetName, 255); deciD->getActivePresetName(actPresetName, 255); if (stricmp(presetName, actPresetName) != 0) { selectPreset(presetName); } return TRUE; } break; } break; case WM_FFONNEWFILTERS: { for (ThtiPages::const_iterator hp = filterPages.begin(); hp != filterPages.end(); hp++) for (TconfPages::const_iterator i = (*hp)->begin(); i != (*hp)->end(); i++) { ((TconfPageDec*)(*i))->onNewFilter(); } return TRUE; } case WM_NOTIFY: { NMHDR *nmhdr = LPNMHDR(lParam); if (nmhdr->hwndFrom == htv && nmhdr->idFrom == IDC_TV_TREE) switch (nmhdr->code) { case TVN_GETINFOTIP: { if (!cfgGet(IDFF_showHints)) { return FALSE; } NMTVGETINFOTIP *nmtvit = LPNMTVGETINFOTIP(lParam); TconfPageBase *page = hti2page(nmtvit->hItem); char_t tipS[1024] = _l(""); if (deciD->getFilterTipEx(page->filterID, page->filterPageID, tipS, 1023) != S_OK) { page->getTip(tipS, 1023); } if (tipS[0] == '\0') { return FALSE; } memset(nmtvit->pszText, 0, nmtvit->cchTextMax); ff_strncpy(nmtvit->pszText, tipS, nmtvit->cchTextMax - 1); return TRUE; } case NM_CUSTOMDRAW: { NMTVCUSTOMDRAW *tvcd = LPNMTVCUSTOMDRAW(lParam); int rcDy = tvcd->nmcd.rc.bottom - tvcd->nmcd.rc.top; if (tvcd->nmcd.dwDrawStage == CDDS_PREPAINT) { setDlgResult(CDRF_NOTIFYITEMDRAW); return TRUE; } else if (tvcd->nmcd.dwDrawStage == CDDS_ITEMPREPAINT) { TconfPageBase *page = ((ThtiPage*)tvcd->nmcd.lItemlParam)->getPage(); if (page->getInter() == -1 && page->getOrder() == -1) { return FALSE; } setDlgResult(CDRF_NOTIFYPOSTPAINT); return TRUE; } else if (tvcd->nmcd.dwDrawStage == CDDS_ITEMPOSTPAINT) { RECT &tr = tvcd->nmcd.rc; if (tr.right > tr.left && tr.bottom > tr.top) { RECT rr; TreeView_GetItemRect(htv, HTREEITEM(tvcd->nmcd.dwItemSpec), &rr, true); rr.left -= 24; TconfPageBase *page = ((ThtiPage*)tvcd->nmcd.lItemlParam)->getPage(); if (page->getInter() != -1) { ImageList_Draw(hil, page->getInter() ? ilChecked : ilClear, tvcd->nmcd.hdc, tr.left + 8 + rr.left, tr.top + (rcDy - 16) / 2, ILD_TRANSPARENT); } if (isIn(page->getOrder(), deciD->getMinOrder2(), deciD->getMaxOrder2()) && (tvcd->nmcd.uItemState & CDIS_SELECTED)) { int img; HTREEITEM hti = page->hti; HTREEITEM htiPrev = TreeView_GetPrevVisible(htv, hti), htiNext = TreeView_GetNextVisible(htv, hti); int order = page->getOrder(), orderPrev = hti2page(htiPrev)->getOrder(), orderNext = hti2page(htiNext)->getOrder(); if (order == deciD->getMinOrder2()) { img = ilArrowD; } else if (order == deciD->getMaxOrder2()) { img = ilArrowU; } else { img = ilArrowUD; } ImageList_DrawEx(hil, img, tvcd->nmcd.hdc, tr.left + 2 + rr.left, tr.top + (rcDy - 16) / 2, 5, 16, CLR_DEFAULT, CLR_DEFAULT, ILD_TRANSPARENT); } } return TRUE; } return FALSE; } case NM_CLICK: { POINT ps; GetCursorPos(&ps); ScreenToClient(htv, &ps); TVHITTESTINFO tvhti; tvhti.pt = ps; HTREEITEM hti = TreeView_HitTest(htv, &tvhti); if (!hti) { return FALSE; } RECT rr; TreeView_GetItemRect(htv, hti, &rr, TRUE); RECT r; TreeView_GetItemRect(htv, hti, &r, FALSE); ps.x -= rr.left - 24; int iconTop = ((r.bottom - r.top) - 16) / 2; ps.y -= r.top; if (ps.x >= 8 && ps.x <= 16 + 8 && ps.y >= iconTop + 2 && ps.y <= iconTop + 13) { if (invInter(hti2page(hti), &r)) { return TRUE; } } else if (ps.x >= 2 && ps.x <= 7 && TreeView_GetSelection(htv) == tvhti.hItem) { int center = (r.bottom - r.top) / 2; if (ps.y > center - 6 && ps.y < center - 1 && page->getOrder() > deciD->getMinOrder2()) { swap(-1); return TRUE; } else if (ps.y > center + 1 && ps.y < center + 6 && page->getOrder() < deciD->getMaxOrder2()) { swap(1); return TRUE; } } return FALSE; } case TVN_BEGINDRAG: { NMTREEVIEW *nmtv = LPNMTREEVIEW(lParam); dragpage = hti2page(nmtv->itemNew.hItem); int order = dragpage->getOrder(); TreeView_SelectItem(htv, nmtv->itemNew.hItem); if (isIn(order, deciD->getMinOrder2(), deciD->getMaxOrder2())) { SetCapture(m_hwnd); } else { dragpage = NULL; } break; } } break; } case WM_MOUSEMOVE: if (dragpage) { TVHITTESTINFO tvhti; tvhti.pt.x = LOWORD(lParam) - tvx; tvhti.pt.y = HIWORD(lParam) - tvy; if (HTREEITEM htiTarget = TreeView_HitTest(htv, &tvhti)) { //TreeView_SelectDropTarget(htv,htiTarget); TconfPageBase *targetpage = hti2page(htiTarget); if (isIn(targetpage->getOrder(), deciD->getMinOrder2(), deciD->getMaxOrder2())) { swap(dragpage, targetpage); } } return TRUE; } break; case WM_LBUTTONUP: if (dragpage) { dragpage = NULL; ReleaseCapture(); return TRUE; } break; } return TffdshowPageBase::msgProc(uMsg, wParam, lParam); }
void Picker_HandleDrawItem(HWND hWnd, LPDRAWITEMSTRUCT lpDrawItemStruct) { struct PickerInfo *pPickerInfo; HDC hDC = lpDrawItemStruct->hDC; RECT rcItem = lpDrawItemStruct->rcItem; UINT uiFlags = ILD_TRANSPARENT; HIMAGELIST hImageList; int nItem = lpDrawItemStruct->itemID; COLORREF clrTextSave = 0; COLORREF clrBkSave = 0; COLORREF clrImage = GetSysColor(COLOR_WINDOW); static TCHAR szBuff[MAX_PATH]; BOOL bFocus = (GetFocus() == hWnd); LPCTSTR pszText; UINT nStateImageMask; BOOL bSelected; LV_COLUMN lvc; LV_ITEM lvi; RECT rcAllLabels; RECT rcLabel; RECT rcIcon; int offset; SIZE size; int i, j; int nColumn; int nColumnMax = 0; int *order; BOOL bDrawAsChild; int indent_space; BOOL bColorChild = FALSE; BOOL bParentFound = FALSE; int nParent; HBITMAP hBackground = GetBackgroundBitmap(); MYBITMAPINFO *pbmDesc = GetBackgroundInfo(); pPickerInfo = GetPickerInfo(hWnd); order = malloc(pPickerInfo->nColumnCount * sizeof(*order)); if (!order) return; nColumnMax = Picker_GetNumColumns(hWnd); if (GetUseOldControl()) { pPickerInfo->pCallbacks->pfnGetColumnOrder(order); } else { /* Get the Column Order and save it */ ListView_GetColumnOrderArray(hWnd, nColumnMax, order); /* Disallow moving column 0 */ if (order[0] != 0) { for (i = 0; i < nColumnMax; i++) { if (order[i] == 0) { order[i] = order[0]; order[0] = 0; } } ListView_SetColumnOrderArray(hWnd, nColumnMax, order); } } /* Labels are offset by a certain amount */ /* This offset is related to the width of a space character */ GetTextExtentPoint32(hDC, " ", 1 , &size); offset = size.cx; lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE | LVIF_PARAM; lvi.iItem = nItem; lvi.iSubItem = order[0]; lvi.pszText = szBuff; lvi.cchTextMax = sizeof(szBuff) / sizeof(szBuff[0]); lvi.stateMask = 0xFFFF; /* get all state flags */ ListView_GetItem(hWnd, &lvi); bSelected = ((lvi.state & LVIS_DROPHILITED) || ( (lvi.state & LVIS_SELECTED) && ((bFocus) || (GetWindowLong(hWnd, GWL_STYLE) & LVS_SHOWSELALWAYS)))); /* figure out if we indent and draw grayed */ if (pPickerInfo->pCallbacks->pfnFindItemParent) nParent = pPickerInfo->pCallbacks->pfnFindItemParent(hWnd, lvi.lParam); else nParent = -1; bDrawAsChild = (pPickerInfo->pCallbacks->pfnGetViewMode() == VIEW_GROUPED && (nParent >= 0)); /* only indent if parent is also in this view */ if ((nParent >= 0) && bDrawAsChild) { for (i = 0; i < ListView_GetItemCount(hWnd); i++) { lvi.mask = LVIF_PARAM; lvi.iItem = i; ListView_GetItem(hWnd, &lvi); if (lvi.lParam == nParent) { bParentFound = TRUE; break; } } } if (pPickerInfo->pCallbacks->pfnGetOffsetChildren && pPickerInfo->pCallbacks->pfnGetOffsetChildren()) { if (!bParentFound && bDrawAsChild) { /*Reset it, as no Parent is there*/ bDrawAsChild = FALSE; bColorChild = TRUE; } else { nParent = -1; bParentFound = FALSE; } } ListView_GetItemRect(hWnd, nItem, &rcAllLabels, LVIR_BOUNDS); ListView_GetItemRect(hWnd, nItem, &rcLabel, LVIR_LABEL); rcAllLabels.left = rcLabel.left; if (hBackground != NULL) { RECT rcClient; HRGN rgnBitmap; RECT rcTmpBmp = rcItem; RECT rcFirstItem; HPALETTE hPAL; HDC htempDC; HBITMAP oldBitmap; htempDC = CreateCompatibleDC(hDC); oldBitmap = SelectObject(htempDC, hBackground); GetClientRect(hWnd, &rcClient); rcTmpBmp.right = rcClient.right; /* We also need to check whether it is the last item The update region has to be extended to the bottom if it is */ if (nItem == ListView_GetItemCount(hWnd) - 1) rcTmpBmp.bottom = rcClient.bottom; rgnBitmap = CreateRectRgnIndirect(&rcTmpBmp); SelectClipRgn(hDC, rgnBitmap); DeleteObject(rgnBitmap); hPAL = GetBackgroundPalette(); if (hPAL == NULL) hPAL = CreateHalftonePalette(hDC); if (GetDeviceCaps(htempDC, RASTERCAPS) & RC_PALETTE && hPAL != NULL) { SelectPalette(htempDC, hPAL, FALSE); RealizePalette(htempDC); } ListView_GetItemRect(hWnd, 0, &rcFirstItem, LVIR_BOUNDS); for (i = rcFirstItem.left; i < rcClient.right; i += pbmDesc->bmWidth) for (j = rcFirstItem.top; j < rcClient.bottom; j += pbmDesc->bmHeight) BitBlt(hDC, i, j, pbmDesc->bmWidth, pbmDesc->bmHeight, htempDC, 0, 0, SRCCOPY); SelectObject(htempDC, oldBitmap); DeleteDC(htempDC); if (GetBackgroundPalette() == NULL) { DeleteObject(hPAL); hPAL = NULL; } } indent_space = 0; if (bDrawAsChild) { RECT rect; ListView_GetItemRect(hWnd, nItem, &rect, LVIR_ICON); /* indent width of icon + the space between the icon and text * so left of clone icon starts at text of parent */ indent_space = rect.right - rect.left + offset; } rcAllLabels.left += indent_space; if (bSelected) { HBRUSH hBrush; HBRUSH hOldBrush; if (bFocus) { clrTextSave = SetTextColor(hDC, GetSysColor(COLOR_HIGHLIGHTTEXT)); clrBkSave = SetBkColor(hDC, GetSysColor(COLOR_HIGHLIGHT)); hBrush = CreateSolidBrush(GetSysColor(COLOR_HIGHLIGHT)); } else { clrTextSave = SetTextColor(hDC, GetSysColor(COLOR_BTNTEXT)); clrBkSave = SetBkColor(hDC, GetSysColor(COLOR_BTNFACE)); hBrush = CreateSolidBrush(GetSysColor(COLOR_BTNFACE)); } hOldBrush = SelectObject(hDC, hBrush); FillRect(hDC, &rcAllLabels, hBrush); SelectObject(hDC, hOldBrush); DeleteObject(hBrush); } else { if (hBackground == NULL) { HBRUSH hBrush; hBrush = CreateSolidBrush(GetSysColor(COLOR_WINDOW)); FillRect(hDC, &rcAllLabels, hBrush); DeleteObject(hBrush); } if (pPickerInfo->pCallbacks->pfnGetOffsetChildren && pPickerInfo->pCallbacks->pfnGetOffsetChildren()) { if (bDrawAsChild || bColorChild) clrTextSave = SetTextColor(hDC, GetListCloneColor()); else clrTextSave = SetTextColor(hDC, GetListFontColor()); } else { if (bDrawAsChild) clrTextSave = SetTextColor(hDC, GetListCloneColor()); else clrTextSave = SetTextColor(hDC, GetListFontColor()); } clrBkSave = SetBkColor(hDC, GetSysColor(COLOR_WINDOW)); } if (lvi.state & LVIS_CUT) { clrImage = GetSysColor(COLOR_WINDOW); uiFlags |= ILD_BLEND50; } else if (bSelected) { if (bFocus) clrImage = GetSysColor(COLOR_HIGHLIGHT); else clrImage = GetSysColor(COLOR_BTNFACE); uiFlags |= ILD_BLEND50; } nStateImageMask = lvi.state & LVIS_STATEIMAGEMASK; if (nStateImageMask) { int nImage = (nStateImageMask >> 12) - 1; hImageList = ListView_GetImageList(hWnd, LVSIL_STATE); if (hImageList) ImageList_Draw(hImageList, nImage, hDC, rcItem.left, rcItem.top, ILD_TRANSPARENT); } ListView_GetItemRect(hWnd, nItem, &rcIcon, LVIR_ICON); rcIcon.left += indent_space; ListView_GetItemRect(hWnd, nItem, &rcItem, LVIR_LABEL); hImageList = ListView_GetImageList(hWnd, LVSIL_SMALL); if (hImageList) { UINT nOvlImageMask = lvi.state & LVIS_OVERLAYMASK; if (rcIcon.left + 16 + indent_space < rcItem.right) { ImageList_DrawEx(hImageList, lvi.iImage, hDC, rcIcon.left, rcIcon.top, 16, 16, GetSysColor(COLOR_WINDOW), clrImage, uiFlags | nOvlImageMask); } } ListView_GetItemRect(hWnd, nItem, &rcItem, LVIR_LABEL); pszText = MakeShortString(hDC, szBuff, rcItem.right - rcItem.left, 2*offset + indent_space); rcLabel = rcItem; rcLabel.left += offset + indent_space; rcLabel.right -= offset; DrawText(hDC, pszText, -1, &rcLabel, DT_LEFT | DT_SINGLELINE | DT_NOPREFIX | DT_VCENTER); for (nColumn = 1; nColumn < nColumnMax; nColumn++) { int nRetLen; UINT nJustify; LV_ITEM lvItem; lvc.mask = LVCF_FMT | LVCF_WIDTH; ListView_GetColumn(hWnd, order[nColumn], &lvc); lvItem.mask = LVIF_TEXT; lvItem.iItem = nItem; lvItem.iSubItem = order[nColumn]; lvItem.pszText = szBuff; lvItem.cchTextMax = sizeof(szBuff) / sizeof(szBuff[0]); if (ListView_GetItem(hWnd, &lvItem) == FALSE) continue; rcItem.left = rcItem.right; rcItem.right += lvc.cx; nRetLen = strlen(szBuff); if (nRetLen == 0) continue; pszText = MakeShortString(hDC, szBuff, rcItem.right - rcItem.left, 2 * offset); nJustify = DT_LEFT; if (pszText == szBuff) { switch (lvc.fmt & LVCFMT_JUSTIFYMASK) { case LVCFMT_RIGHT: nJustify = DT_RIGHT; break; case LVCFMT_CENTER: nJustify = DT_CENTER; break; default: break; } } rcLabel = rcItem; rcLabel.left += offset; rcLabel.right -= offset; DrawText(hDC, pszText, -1, &rcLabel, nJustify | DT_SINGLELINE | DT_NOPREFIX | DT_VCENTER); } if (lvi.state & LVIS_FOCUSED && bFocus) DrawFocusRect(hDC, &rcAllLabels); SetTextColor(hDC, clrTextSave); SetBkColor(hDC, clrBkSave); free(order); }
void TabBarPlus::drawItem(DRAWITEMSTRUCT *pDrawItemStruct) { RECT rect = pDrawItemStruct->rcItem; int nTab = pDrawItemStruct->itemID; if (nTab < 0) { ::MessageBox(NULL, TEXT("nTab < 0"), TEXT(""), MB_OK); //return ::CallWindowProc(_tabBarDefaultProc, hwnd, Message, wParam, lParam); } bool isSelected = (nTab == ::SendMessage(_hSelf, TCM_GETCURSEL, 0, 0)); TCHAR label[MAX_PATH]; TCITEM tci; tci.mask = TCIF_TEXT|TCIF_IMAGE; tci.pszText = label; tci.cchTextMax = MAX_PATH-1; if (!::SendMessage(_hSelf, TCM_GETITEM, nTab, reinterpret_cast<LPARAM>(&tci))) { ::MessageBox(NULL, TEXT("! TCM_GETITEM"), TEXT(""), MB_OK); //return ::CallWindowProc(_tabBarDefaultProc, hwnd, Message, wParam, lParam); } HDC hDC = pDrawItemStruct->hDC; int nSavedDC = ::SaveDC(hDC); ::SetBkMode(hDC, TRANSPARENT); HBRUSH hBrush = ::CreateSolidBrush(::GetSysColor(COLOR_BTNFACE)); ::FillRect(hDC, &rect, hBrush); ::DeleteObject((HGDIOBJ)hBrush); if (isSelected) { if (_drawTopBar) { RECT barRect = rect; if (_isVertical) { barRect.right = barRect.left + 6; rect.left += 2; } else { barRect.bottom = barRect.top + 6; rect.top += 2; } if (::SendMessage(_hParent, NPPM_INTERNAL_ISFOCUSEDTAB, 0, (LPARAM)_hSelf)) hBrush = ::CreateSolidBrush(_activeTopBarFocusedColour); // #FAAA3C else hBrush = ::CreateSolidBrush(_activeTopBarUnfocusedColour); // #FAD296 ::FillRect(hDC, &barRect, hBrush); ::DeleteObject((HGDIOBJ)hBrush); } } else { if (_drawInactiveTab) { RECT barRect = rect; hBrush = ::CreateSolidBrush(_inactiveBgColour); ::FillRect(hDC, &barRect, hBrush); ::DeleteObject((HGDIOBJ)hBrush); } } if (_drawTabCloseButton) { RECT closeButtonRect = _closeButtonZone.getButtonRectFrom(rect); if (isSelected) { if (!_isVertical) { //closeButtonRect.top += 2; closeButtonRect.left -= 2; } } else { if (_isVertical) closeButtonRect.left += 2; } // 3 status for each inactive tab and selected tab close item : // normal / hover / pushed int idCloseImg; if (_isCloseHover && (_currentHoverTabItem == nTab) && (_whichCloseClickDown == -1)) // hover idCloseImg = IDR_CLOSETAB_HOVER; else if (_isCloseHover && (_currentHoverTabItem == nTab) && (_whichCloseClickDown == _currentHoverTabItem)) // pushed idCloseImg = IDR_CLOSETAB_PUSH; else idCloseImg = isSelected?IDR_CLOSETAB:IDR_CLOSETAB_INACT; HDC hdcMemory; hdcMemory = ::CreateCompatibleDC(hDC); HBITMAP hBmp = ::LoadBitmap(_hInst, MAKEINTRESOURCE(idCloseImg)); BITMAP bmp; ::GetObject(hBmp, sizeof(bmp), &bmp); if (_isVertical) rect.top = closeButtonRect.top + bmp.bmHeight; else rect.right = closeButtonRect.left; ::SelectObject(hdcMemory, hBmp); ::BitBlt(hDC, closeButtonRect.left, closeButtonRect.top, bmp.bmWidth, bmp.bmHeight, hdcMemory, 0, 0, SRCCOPY); ::DeleteDC(hdcMemory); ::DeleteObject(hBmp); } // Draw image HIMAGELIST hImgLst = (HIMAGELIST)::SendMessage(_hSelf, TCM_GETIMAGELIST, 0, 0); SIZE charPixel; ::GetTextExtentPoint(hDC, TEXT(" "), 1, &charPixel); int spaceUnit = charPixel.cx; if (hImgLst && tci.iImage >= 0) { IMAGEINFO info; int yPos = 0, xPos = 0; int marge = 0; ImageList_GetImageInfo(hImgLst, tci.iImage, &info); RECT & imageRect = info.rcImage; if (_isVertical) xPos = (rect.left + (rect.right - rect.left)/2 + 2) - (imageRect.right - imageRect.left)/2; else yPos = (rect.top + (rect.bottom - rect.top)/2 + (isSelected?0:2)) - (imageRect.bottom - imageRect.top)/2; if (isSelected) marge = spaceUnit*2; else marge = spaceUnit; if (_isVertical) { rect.bottom -= imageRect.bottom - imageRect.top; ImageList_Draw(hImgLst, tci.iImage, hDC, xPos, rect.bottom - marge, isSelected?ILD_TRANSPARENT:ILD_SELECTED); rect.bottom += marge; } else { rect.left += marge; ImageList_Draw(hImgLst, tci.iImage, hDC, rect.left, yPos, isSelected?ILD_TRANSPARENT:ILD_SELECTED); rect.left += imageRect.right - imageRect.left; } } bool isStandardSize = (::SendMessage(_hParent, NPPM_INTERNAL_ISTABBARREDUCED, 0, 0) == TRUE); if (isStandardSize) { if (_isVertical) SelectObject(hDC, _hVerticalFont); else SelectObject(hDC, _hFont); } else { if (_isVertical) SelectObject(hDC, _hVerticalLargeFont); else SelectObject(hDC, _hLargeFont); } int Flags = DT_SINGLELINE; if (_drawTabCloseButton) { Flags |= DT_LEFT; } else { if (!_isVertical) Flags |= DT_CENTER; } // the following uses pixel values the fix alignments issues with DrawText // and font's that are rotated 90 degrees if (isSelected) { //COLORREF selectedColor = RGB(0, 0, 255); ::SetTextColor(hDC, _activeTextColour); if (_isVertical) { rect.bottom -= 2; rect.left += ::GetSystemMetrics(SM_CXEDGE) + 4; rect.top += (_drawTabCloseButton)?spaceUnit:0; Flags |= DT_BOTTOM; } else { rect.top -= ::GetSystemMetrics(SM_CYEDGE); rect.top += 3; rect.left += _drawTabCloseButton?spaceUnit:0; Flags |= DT_VCENTER; } } else { ::SetTextColor(hDC, _inactiveTextColour); if (_isVertical) { rect.top += 2; rect.bottom += 4; rect.left += ::GetSystemMetrics(SM_CXEDGE) + 2; } else { rect.left += (_drawTabCloseButton)?spaceUnit:0; } Flags |= DT_BOTTOM; } ::DrawText(hDC, label, lstrlen(label), &rect, Flags); ::RestoreDC(hDC, nSavedDC); }
// --------------------------------------------------------------------------- // ChildWndProc // --------------------------------------------------------------------------- // Description: Main window procedure. // Arguments: // HWND [in] Window handle. // UINT [in] Message identifier. // WPARAM [in] Depends on message. // LPARAM [in] Depends on message. // Returns: // LPARAM Depends on message. LPARAM CALLBACK ChildWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { HDC hdc=NULL, hmemDC=NULL; PAINTSTRUCT ps; HBRUSH hbrBkGnd=NULL; RECT rect; // Call the appropriate message handler switch(uMsg) { case WM_PAINT: { // Get the Display Context so we have someplace to blit. hdc = BeginPaint( hWnd, &ps ); // Create a compatible DC. hmemDC = CreateCompatibleDC( hdc ); GetClientRect( hWnd, &rect ); // Create a bitmap big enough for our client rectangle. HBITMAP hmemBMP = CreateCompatibleBitmap( hdc, rect.right - rect.left, rect.bottom - rect.top ); // Select the bitmap into the off-screen DC. HGDIOBJ hobjOld = SelectObject( hmemDC, hmemBMP ); // Erase the background. hbrBkGnd = CreateSolidBrush( GetSysColor(COLOR_3DFACE) ); FillRect( hmemDC, &rect, hbrBkGnd ); DeleteObject( hbrBkGnd ); // Draw into memory DC ImageList_Draw( g_hListBmp, 0, hmemDC, 0, 0, INDEXTOOVERLAYMASK(g_iBmp) ); if( g_iBmp%6 == 2 ) { ImageList_Draw( g_hListBmp, WEYESNAR, hmemDC, 0, 0, 0 ); } if( g_iBmp%6 == 5 ) { ImageList_Draw( g_hListBmp, WEYESCLO, hmemDC, 0, 0, 0 ); } // Blit to window DC StretchBlt( hdc, 0, 0, rect.right, rect.bottom, hmemDC, 0, 0, rect.right, rect.bottom, SRCCOPY ); // Replace the previous GDI object to the DC SelectObject( hmemDC, hobjOld ); // Done with off-screen bitmap and DC. DeleteObject( hmemBMP ); DeleteDC( hmemDC ); DeleteDC( hdc ); // Clean up and get outta here EndPaint( hWnd, &ps ); } break; case WM_DESTROY: // Delete Mouth Bitmaps ImageList_Destroy( g_hListBmp ); break; } // Call the default message handler return DefWindowProc(hWnd, uMsg, wParam, lParam); }
void TabBarPlus::drawItem(DRAWITEMSTRUCT *pDrawItemStruct) { RECT rect = pDrawItemStruct->rcItem; int nTab = pDrawItemStruct->itemID; if (nTab < 0) { ::MessageBox(NULL, TEXT("nTab < 0"), TEXT(""), MB_OK); } bool isSelected = (nTab == ::SendMessage(_hSelf, TCM_GETCURSEL, 0, 0)); TCHAR label[MAX_PATH]; TCITEM tci; tci.mask = TCIF_TEXT|TCIF_IMAGE; tci.pszText = label; tci.cchTextMax = MAX_PATH-1; if (!::SendMessage(_hSelf, TCM_GETITEM, nTab, reinterpret_cast<LPARAM>(&tci))) { ::MessageBox(NULL, TEXT("! TCM_GETITEM"), TEXT(""), MB_OK); } HDC hDC = pDrawItemStruct->hDC; int nSavedDC = ::SaveDC(hDC); ::SetBkMode(hDC, TRANSPARENT); HBRUSH hBrush = ::CreateSolidBrush(::GetSysColor(COLOR_BTNFACE)); ::FillRect(hDC, &rect, hBrush); ::DeleteObject((HGDIOBJ)hBrush); // equalize drawing areas of active and inactive tabs int paddingDynamicTwoX = NppParameters::getInstance()->_dpiManager.scaleX(2); int paddingDynamicTwoY = NppParameters::getInstance()->_dpiManager.scaleY(2); if (isSelected) { // the drawing area of the active tab extends on all borders by default rect.top += ::GetSystemMetrics(SM_CYEDGE); rect.bottom -= ::GetSystemMetrics(SM_CYEDGE); rect.left += ::GetSystemMetrics(SM_CXEDGE); rect.right -= ::GetSystemMetrics(SM_CXEDGE); // the active tab is also slightly higher by default (use this to shift the tab cotent up bx two pixels if tobBar is not drawn) if (_isVertical) { rect.left += _drawTopBar ? paddingDynamicTwoX : 0; rect.right -= _drawTopBar ? 0 : paddingDynamicTwoX; } else { rect.top += _drawTopBar ? paddingDynamicTwoY : 0; rect.bottom -= _drawTopBar ? 0 : paddingDynamicTwoY; } } else { if (_isVertical) { rect.left += paddingDynamicTwoX; rect.right += paddingDynamicTwoX; rect.top -= paddingDynamicTwoY; rect.bottom += paddingDynamicTwoY; } else { rect.left -= paddingDynamicTwoX; rect.right += paddingDynamicTwoX; rect.top += paddingDynamicTwoY; rect.bottom += paddingDynamicTwoY; } } // the active tab's text with TCS_BUTTONS is lower than normal and gets clipped if (::GetWindowLongPtr(_hSelf, GWL_STYLE) & TCS_BUTTONS) { if (_isVertical) { rect.left -= 2; } else { rect.top -= 2; } } // draw highlights on tabs (top bar for active tab / darkened background for inactive tab) RECT barRect = rect; if (isSelected) { if (_drawTopBar) { int topBarHeight = NppParameters::getInstance()->_dpiManager.scaleX(4); if (_isVertical) { barRect.left -= NppParameters::getInstance()->_dpiManager.scaleX(2); barRect.right = barRect.left + topBarHeight; } else { barRect.top -= NppParameters::getInstance()->_dpiManager.scaleY(2); barRect.bottom = barRect.top + topBarHeight; } if (::SendMessage(_hParent, NPPM_INTERNAL_ISFOCUSEDTAB, 0, reinterpret_cast<LPARAM>(_hSelf))) hBrush = ::CreateSolidBrush(_activeTopBarFocusedColour); // #FAAA3C else hBrush = ::CreateSolidBrush(_activeTopBarUnfocusedColour); // #FAD296 ::FillRect(hDC, &barRect, hBrush); ::DeleteObject((HGDIOBJ)hBrush); } } else { if (_drawInactiveTab) { hBrush = ::CreateSolidBrush(_inactiveBgColour); ::FillRect(hDC, &barRect, hBrush); ::DeleteObject((HGDIOBJ)hBrush); } } // draw close button if (_drawTabCloseButton) { // 3 status for each inactive tab and selected tab close item : // normal / hover / pushed int idCloseImg; if (_isCloseHover && (_currentHoverTabItem == nTab) && (_whichCloseClickDown == -1)) // hover idCloseImg = IDR_CLOSETAB_HOVER; else if (_isCloseHover && (_currentHoverTabItem == nTab) && (_whichCloseClickDown == _currentHoverTabItem)) // pushed idCloseImg = IDR_CLOSETAB_PUSH; else idCloseImg = isSelected?IDR_CLOSETAB:IDR_CLOSETAB_INACT; HDC hdcMemory; hdcMemory = ::CreateCompatibleDC(hDC); HBITMAP hBmp = ::LoadBitmap(_hInst, MAKEINTRESOURCE(idCloseImg)); BITMAP bmp; ::GetObject(hBmp, sizeof(bmp), &bmp); int bmDpiDynamicalWidth = NppParameters::getInstance()->_dpiManager.scaleX(bmp.bmWidth); int bmDpiDynamicalHeight = NppParameters::getInstance()->_dpiManager.scaleY(bmp.bmHeight); RECT buttonRect = _closeButtonZone.getButtonRectFrom(rect, _isVertical); ::SelectObject(hdcMemory, hBmp); ::StretchBlt(hDC, buttonRect.left, buttonRect.top, bmDpiDynamicalWidth, bmDpiDynamicalHeight, hdcMemory, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY); ::DeleteDC(hdcMemory); ::DeleteObject(hBmp); } // draw image HIMAGELIST hImgLst = (HIMAGELIST)::SendMessage(_hSelf, TCM_GETIMAGELIST, 0, 0); if (hImgLst && tci.iImage >= 0) { IMAGEINFO info; ImageList_GetImageInfo(hImgLst, tci.iImage, &info); RECT& imageRect = info.rcImage; int fromBorder; int xPos, yPos; if (_isVertical) { fromBorder = (rect.right - rect.left - (imageRect.right - imageRect.left) + 1) / 2; xPos = rect.left + fromBorder; yPos = rect.bottom - fromBorder - (imageRect.bottom - imageRect.top); rect.bottom -= fromBorder + (imageRect.bottom - imageRect.top); } else { fromBorder = (rect.bottom - rect.top - (imageRect.bottom - imageRect.top) + 1) / 2; yPos = rect.top + fromBorder; xPos = rect.left + fromBorder; rect.left += fromBorder + (imageRect.right - imageRect.left); } ImageList_Draw(hImgLst, tci.iImage, hDC, xPos, yPos, isSelected ? ILD_TRANSPARENT : ILD_SELECTED); } // draw text bool isStandardSize = (::SendMessage(_hParent, NPPM_INTERNAL_ISTABBARREDUCED, 0, 0) == TRUE); if (isStandardSize) { if (_isVertical) SelectObject(hDC, _hVerticalFont); else SelectObject(hDC, _hFont); } else { if (_isVertical) SelectObject(hDC, _hVerticalLargeFont); else SelectObject(hDC, _hLargeFont); } SIZE charPixel; ::GetTextExtentPoint(hDC, TEXT(" "), 1, &charPixel); int spaceUnit = charPixel.cx; TEXTMETRIC textMetrics; GetTextMetrics(hDC, &textMetrics); int textHeight = textMetrics.tmHeight; int textDescent = textMetrics.tmDescent; int Flags = DT_SINGLELINE | DT_NOPREFIX; // This code will read in one character at a time and remove every first ampersand (&). // ex. If input "test && test &&& test &&&&" then output will be "test & test && test &&&". // Tab's caption must be encoded like this because otherwise tab control would make tab too small or too big for the text. TCHAR decodedLabel[MAX_PATH]; const TCHAR* in = label; TCHAR* out = decodedLabel; while (*in != 0) if (*in == '&') while (*(++in) == '&') *out++ = *in; else *out++ = *in++; *out = '\0'; if (_isVertical) { // center text horizontally (rotated text is positioned as if it were unrotated, therefore manual positioning is necessary) Flags |= DT_LEFT; Flags |= DT_BOTTOM; rect.left += (rect.right - rect.left - textHeight) / 2; rect.bottom += textHeight; // ignoring the descent when centering (text elements below the base line) is more pleasing to the eye rect.left += textDescent / 2; rect.right += textDescent / 2; // 1 space distance to save icon rect.bottom -= spaceUnit; } else { // center text vertically Flags |= DT_LEFT; Flags |= DT_VCENTER; // ignoring the descent when centering (text elements below the base line) is more pleasing to the eye rect.top += textDescent / 2; rect.bottom += textDescent / 2; // 1 space distance to save icon rect.left += spaceUnit; } ::SetTextColor(hDC, isSelected ? _activeTextColour : _inactiveTextColour); ::DrawText(hDC, decodedLabel, lstrlen(decodedLabel), &rect, Flags); ::RestoreDC(hDC, nSavedDC); }
void DrawStartPage(WindowInfo& win, HDC hdc, FileHistory& fileHistory, COLORREF colorRange[2]) { HPEN penBorder = CreatePen(PS_SOLID, DOCLIST_SEPARATOR_DY, WIN_COL_BLACK); HPEN penThumbBorder = CreatePen(PS_SOLID, DOCLIST_THUMBNAIL_BORDER_W, WIN_COL_BLACK); HPEN penLinkLine = CreatePen(PS_SOLID, 1, COL_BLUE_LINK); ScopedFont fontSumatraTxt(GetSimpleFont(hdc, L"MS Shell Dlg", 24)); ScopedFont fontLeftTxt(GetSimpleFont(hdc, L"MS Shell Dlg", 14)); HGDIOBJ origFont = SelectObject(hdc, fontSumatraTxt); /* Just to remember the orig font */ ClientRect rc(win.hwndCanvas); FillRect(hdc, &rc.ToRECT(), gBrushLogoBg); SelectObject(hdc, gBrushLogoBg); SelectObject(hdc, penBorder); bool isRtl = IsUIRightToLeft(); /* render title */ RectI titleBox = RectI(PointI(0, 0), CalcSumatraVersionSize(hdc)); titleBox.x = rc.dx - titleBox.dx - 3; DrawSumatraVersion(hdc, titleBox); PaintLine(hdc, RectI(0, titleBox.dy, rc.dx, 0)); /* render recent files list */ SelectObject(hdc, penThumbBorder); SetBkMode(hdc, TRANSPARENT); SetTextColor(hdc, WIN_COL_BLACK); rc.y += titleBox.dy; rc.dy -= titleBox.dy; FillRect(hdc, &rc.ToRECT(), gBrushAboutBg); rc.dy -= DOCLIST_BOTTOM_BOX_DY; Vec<DisplayState *> list; fileHistory.GetFrequencyOrder(list); int width = limitValue((rc.dx - DOCLIST_MARGIN_LEFT - DOCLIST_MARGIN_RIGHT + DOCLIST_MARGIN_BETWEEN_X) / (THUMBNAIL_DX + DOCLIST_MARGIN_BETWEEN_X), 1, DOCLIST_MAX_THUMBNAILS_X); int height = min((rc.dy - DOCLIST_MARGIN_TOP - DOCLIST_MARGIN_BOTTOM + DOCLIST_MARGIN_BETWEEN_Y) / (THUMBNAIL_DY + DOCLIST_MARGIN_BETWEEN_Y), FILE_HISTORY_MAX_FREQUENT / width); PointI offset(rc.x + DOCLIST_MARGIN_LEFT + (rc.dx - width * THUMBNAIL_DX - (width - 1) * DOCLIST_MARGIN_BETWEEN_X - DOCLIST_MARGIN_LEFT - DOCLIST_MARGIN_RIGHT) / 2, rc.y + DOCLIST_MARGIN_TOP); if (offset.x < ABOUT_INNER_PADDING) offset.x = ABOUT_INNER_PADDING; else if (list.Count() == 0) offset.x = DOCLIST_MARGIN_LEFT; SelectObject(hdc, fontSumatraTxt); SIZE txtSize; const WCHAR *txt = _TR("Frequently Read"); GetTextExtentPoint32(hdc, txt, (int)str::Len(txt), &txtSize); RectI headerRect(offset.x, rc.y + (DOCLIST_MARGIN_TOP - txtSize.cy) / 2, txtSize.cx, txtSize.cy); if (isRtl) headerRect.x = rc.dx - offset.x - headerRect.dx; DrawText(hdc, txt, -1, &headerRect.ToRECT(), (isRtl ? DT_RTLREADING : DT_LEFT) | DT_NOPREFIX); SelectObject(hdc, fontLeftTxt); SelectObject(hdc, GetStockBrush(NULL_BRUSH)); win.staticLinks.Reset(); for (int h = 0; h < height; h++) { for (int w = 0; w < width; w++) { if (h * width + w >= (int)list.Count()) { // display the "Open a document" link right below the last row height = w > 0 ? h + 1 : h; break; } DisplayState *state = list.At(h * width + w); RectI page(offset.x + w * (int)(THUMBNAIL_DX + DOCLIST_MARGIN_BETWEEN_X * win.uiDPIFactor), offset.y + h * (int)(THUMBNAIL_DY + DOCLIST_MARGIN_BETWEEN_Y * win.uiDPIFactor), THUMBNAIL_DX, THUMBNAIL_DY); if (isRtl) page.x = rc.dx - page.x - page.dx; bool loadOk = true; if (!state->thumbnail) loadOk = LoadThumbnail(*state); if (loadOk && state->thumbnail) { SizeI thumbSize = state->thumbnail->Size(); if (thumbSize.dx != THUMBNAIL_DX || thumbSize.dy != THUMBNAIL_DY) { page.dy = thumbSize.dy * THUMBNAIL_DX / thumbSize.dx; page.y += THUMBNAIL_DY - page.dy; } HRGN clip = CreateRoundRectRgn(page.x, page.y, page.x + page.dx, page.y + page.dy, 10, 10); SelectClipRgn(hdc, clip); RenderedBitmap *clone = state->thumbnail->Clone(); UpdateBitmapColorRange(clone->GetBitmap(), colorRange); clone->StretchDIBits(hdc, page); SelectClipRgn(hdc, NULL); DeleteObject(clip); delete clone; } RoundRect(hdc, page.x, page.y, page.x + page.dx, page.y + page.dy, 10, 10); int iconSpace = (int)(20 * win.uiDPIFactor); RectI rect(page.x + iconSpace, page.y + page.dy + 3, page.dx - iconSpace, iconSpace); if (isRtl) rect.x -= iconSpace; DrawText(hdc, path::GetBaseName(state->filePath), -1, &rect.ToRECT(), DT_SINGLELINE | DT_END_ELLIPSIS | DT_NOPREFIX | (isRtl ? DT_RIGHT : DT_LEFT)); SHFILEINFO sfi; HIMAGELIST himl = (HIMAGELIST)SHGetFileInfo(state->filePath, 0, &sfi, sizeof(sfi), SHGFI_SYSICONINDEX | SHGFI_SMALLICON | SHGFI_USEFILEATTRIBUTES); ImageList_Draw(himl, sfi.iIcon, hdc, isRtl ? page.x + page.dx - (int)(16 * win.uiDPIFactor) : page.x, rect.y, ILD_TRANSPARENT); win.staticLinks.Append(StaticLinkInfo(rect.Union(page), state->filePath, state->filePath)); } } /* render bottom links */ rc.y += DOCLIST_MARGIN_TOP + height * THUMBNAIL_DY + (height - 1) * DOCLIST_MARGIN_BETWEEN_Y + DOCLIST_MARGIN_BOTTOM; rc.dy = DOCLIST_BOTTOM_BOX_DY; SetTextColor(hdc, COL_BLUE_LINK); SelectObject(hdc, penLinkLine); HIMAGELIST himl = (HIMAGELIST)SendMessage(win.hwndToolbar, TB_GETIMAGELIST, 0, 0); RectI rectIcon(offset.x, rc.y, 0, 0); ImageList_GetIconSize(himl, &rectIcon.dx, &rectIcon.dy); rectIcon.y += (rc.dy - rectIcon.dy) / 2; if (isRtl) rectIcon.x = rc.dx - offset.x - rectIcon.dx; ImageList_Draw(himl, 0 /* index of Open icon */, hdc, rectIcon.x, rectIcon.y, ILD_NORMAL); txt = _TR("Open a document..."); GetTextExtentPoint32(hdc, txt, (int)str::Len(txt), &txtSize); RectI rect(offset.x + rectIcon.dx + 3, rc.y + (rc.dy - txtSize.cy) / 2, txtSize.cx, txtSize.cy); if (isRtl) rect.x = rectIcon.x - rect.dx - 3; DrawText(hdc, txt, -1, &rect.ToRECT(), isRtl ? DT_RTLREADING : DT_LEFT); PaintLine(hdc, RectI(rect.x, rect.y + rect.dy, rect.dx, 0)); // make the click target larger rect = rect.Union(rectIcon); rect.Inflate(10, 10); win.staticLinks.Append(StaticLinkInfo(rect, SLINK_OPEN_FILE)); rect = DrawBottomRightLink(win.hwndCanvas, hdc, _TR("Hide frequently read")); win.staticLinks.Append(StaticLinkInfo(rect, SLINK_LIST_HIDE)); SelectObject(hdc, origFont); DeleteObject(penBorder); DeleteObject(penThumbBorder); DeleteObject(penLinkLine); }
void DockingCont::drawTabItem(DRAWITEMSTRUCT *pDrawItemStruct) { TCITEM tcItem = {0}; RECT rc = pDrawItemStruct->rcItem; int nTab = pDrawItemStruct->itemID; bool isSelected = (nTab == getActiveTb()); // get current selected item tcItem.mask = TCIF_PARAM; ::SendMessage(_hContTab, TCM_GETITEM, nTab, (LPARAM)&tcItem); if (!tcItem.lParam) return; TCHAR* text = ((tTbData*)tcItem.lParam)->pszName; int length = lstrlen(((tTbData*)tcItem.lParam)->pszName); // get drawing context HDC hDc = pDrawItemStruct->hDC; int nSavedDC = ::SaveDC(hDc); // For some bizarre reason the rcItem you get extends above the actual // drawing area. We have to workaround this "feature". rc.top += ::GetSystemMetrics(SM_CYEDGE); ::SetBkMode(hDc, TRANSPARENT); HBRUSH hBrush = ::CreateSolidBrush(::GetSysColor(COLOR_BTNFACE)); ::FillRect(hDc, &rc, hBrush); ::DeleteObject((HGDIOBJ)hBrush); // draw orange bar if ((_bDrawOgLine == TRUE) && (isSelected)) { RECT barRect = rc; barRect.top += rc.bottom - 4; hBrush = ::CreateSolidBrush(RGB(250, 170, 60)); ::FillRect(hDc, &barRect, hBrush); ::DeleteObject((HGDIOBJ)hBrush); } // draw icon if enabled if (((tTbData*)tcItem.lParam)->uMask & DWS_ICONTAB) { HIMAGELIST hImageList = (HIMAGELIST)::SendMessage(_hParent, DMM_GETIMAGELIST, 0, 0); int iPosImage = ::SendMessage(_hParent, DMM_GETICONPOS, 0, (LPARAM)((tTbData*)tcItem.lParam)->hClient); if ((hImageList != NULL) && (iPosImage >= 0)) { // Get height of image so we IMAGEINFO info = {0}; RECT & imageRect = info.rcImage; ImageList_GetImageInfo(hImageList, iPosImage, &info); ImageList_Draw(hImageList, iPosImage, hDc, rc.left + 3, 2, ILD_NORMAL); if (isSelected == true) { rc.left += imageRect.right - imageRect.left + 5; } } } if (isSelected == true) { COLORREF _unselectedColor = RGB(0, 0, 0); ::SetTextColor(hDc, _unselectedColor); // draw text rc.top -= ::GetSystemMetrics(SM_CYEDGE); ::SelectObject(hDc, _hFont); ::DrawText(hDc, text, length, &rc, DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX); } ::RestoreDC(hDc, nSavedDC); }