VOID TreeListUpdateTooltips( HWND hwndTreeList ) { HWND TreeControl = (HWND)GetWindowLongPtr(hwndTreeList, TL_TREECONTROL_SLOT), ToolTips = (HWND)GetWindowLongPtr(hwndTreeList, TL_TOOLTIPS_SLOT), Header = (HWND)GetWindowLongPtr(hwndTreeList, TL_HEADERCONTROL_SLOT); PTL_SUBITEMS subitems; HTREEITEM item = TreeView_GetRoot(TreeControl); RECT rc, subrc; TOOLINFO tool; ULONG i = 0, c; LONG cx; TVITEMEX itemex; RtlSecureZeroMemory(&rc, sizeof(rc)); Header_GetItemRect(Header, 0, &rc); cx = rc.right; c = (ULONG)SendMessage(ToolTips, TTM_GETTOOLCOUNT, 0, 0); RtlSecureZeroMemory(&tool, sizeof(tool)); tool.cbSize = sizeof(tool); while (SendMessage(ToolTips, TTM_ENUMTOOLS, i, (LPARAM)&tool) && (i < c)) { if (!TreeView_GetItemRect(TreeControl, (HTREEITEM)(tool.uId - tool.lParam), &rc, FALSE)) { SendMessage(ToolTips, TTM_DELTOOL, 0, (LPARAM)&tool); continue; } i++; } while (item) { if (TreeView_GetItemRect(TreeControl, item, &rc, TRUE)) { RtlSecureZeroMemory(&itemex, sizeof(itemex)); itemex.hItem = item; itemex.mask = TVIF_HANDLE | TVIF_PARAM; TreeView_GetItem(TreeControl, &itemex); if (rc.right > cx) rc.right = cx; AddTooltipItemSub(TreeControl, ToolTips, (UINT_PTR)item, 0, &rc); if (itemex.lParam) { subitems = (PTL_SUBITEMS)itemex.lParam; for (i = 0; i < subitems->Count; i++) { if (!Header_GetItemRect(Header, i + 1, &subrc)) break; subrc.top = rc.top; subrc.bottom = rc.bottom; AddTooltipItemSub(TreeControl, ToolTips, i + 1 + (UINT_PTR)item, i + 1, &subrc); } } } item = TreeView_GetNextVisible(TreeControl, item); } }
LRESULT TreeListOnTrack( __in PTREELIST_OBJECT Object, __in LPNMHDR lp ) { LPNMHEADER phdn; RECT Rect; LONG x; LONG y; phdn = (LPNMHEADER)lp; Header_GetItemRect(Object->hWndHeader, phdn->iItem, &Rect); x = Rect.left + phdn->pitem->cxy; y = Rect.bottom - Rect.top; if (Object->SplitbarLeft != -1) { TreeListDrawVerticalLine(Object, Object->SplitbarLeft); TreeListDrawVerticalLine(Object, x); Object->SplitbarLeft = x; } return 0; }
void MyListView_AddItemWithIcon(HWND hListView, TCHAR *ItemText, int ColumnIndex, int RowIndex, void *pData, int iIcon) { LV_ITEM ListViewItem; int ColumnWidth; int ItemWidth; HWND hHeader; hHeader = ListView_GetHeader(hListView); if (ColumnIndex == (Header_GetItemCount(hHeader)-1)) { RECT itemRect; RECT headerRect; // get rect of last column in header Header_GetItemRect(hHeader, (Header_GetItemCount(hHeader)-1), &itemRect); GetClientRect(hHeader,&headerRect); ItemWidth= headerRect.right - itemRect.left; } else { ItemWidth = ListView_GetStringWidth(hListView, ItemText) + (GetSystemMetrics(SM_CXEDGE)<<1)+(4<<1); } ColumnWidth = ListView_GetColumnWidth(hListView,ColumnIndex); ListViewItem.mask = LVIF_TEXT; if (iIcon!=-1) { ListViewItem.mask |= LVIF_IMAGE; ListViewItem.iImage = iIcon; } ListViewItem.iItem = RowIndex; ListViewItem.iSubItem = ColumnIndex; ListViewItem.pszText = ItemText; if (ColumnIndex == 0) { ListViewItem.mask |= LVIF_PARAM; ListViewItem.lParam = (LPARAM)pData; ListView_InsertItem(hListView, &ListViewItem); } else { ListView_SetItem(hListView, &ListViewItem); } if (ItemWidth>ColumnWidth) ListView_SetColumnWidth(hListView, ColumnIndex, ItemWidth); }
BOOL CXTPHeaderCtrl::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) { if (m_arFrozenCols.GetCount()) { CPoint pt; ::GetCursorPos(&pt); CPoint ptClient = pt; ScreenToClient(&ptClient); HDHITTESTINFO hti; ::ZeroMemory(&hti, sizeof(hti)); hti.pt.x = ptClient.x; hti.pt.y = ptClient.y; int nIndex = (int)::SendMessage(GetSafeHwnd(), HDM_HITTEST, 0L, (LPARAM)&hti); if (nIndex > -1) { // if we are over one of the frozen columns, we can stop if (IsColFrozen(nIndex)) { ::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW)); return TRUE; } else { // determine if the current index is adjacent to a frozen column index. // if columns are resized by dragging to the right, test for the frozen column on the left. // if columns are resized by dragging to the left, test for the frozen column on the right. int iAdjIndex = nIndex + (m_bRTL ? 1 : -1); if ((iAdjIndex > -1) && IsColFrozen(iAdjIndex)) { CRect r; Header_GetItemRect(m_hWnd, nIndex, &r); int nMidPoint = (r.left + (r.Width()/2)); // if columns resize to the right and the point is the right half of the header item... if (!m_bRTL && (ptClient.x <= nMidPoint)) { ::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW)); return TRUE; } // if columns resize to the left and the point is the left half of the header item... else if (m_bRTL && (ptClient.x >= nMidPoint)) { ::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW)); return TRUE; } } } } } return CHeaderCtrl::OnSetCursor(pWnd, nHitTest, message); }
BOOL GridView::GetItemRect(ULONG column, ULONG line, RECT *rect) { // get the current position of the column header Header_GetItemRect(m_hWndHeader, column, rect); // wo rect->top = (line - m_nVScrollPos) * m_nLineHeight + m_nHeaderHeight; rect->bottom = rect->top + m_nLineHeight; return TRUE; }
VOID TreeListHandleHeaderNotify( HWND hwndBox, HWND hwndTree, HWND hwndHeader ) { LONG cx, i, c, headerheight; RECT hr, ir; SCROLLINFO scroll; RtlSecureZeroMemory(&hr, sizeof(hr)); GetWindowRect(hwndHeader, &hr); headerheight = hr.bottom - hr.top; cx = 0; c = Header_GetItemCount(hwndHeader); for (i = 0; i < c; i++) { Header_GetItemRect(hwndHeader, i, &hr); if (hr.right > cx) cx = hr.right; } GetClientRect(hwndBox, &hr); if (cx > hr.right) { RtlSecureZeroMemory(&scroll, sizeof(scroll)); scroll.cbSize = sizeof(scroll); scroll.fMask = SIF_ALL; GetScrollInfo(hwndBox, SB_HORZ, &scroll); GetClientRect(hwndHeader, &ir); if ((ir.right > cx) && (scroll.nPos + (int)scroll.nPage == scroll.nMax)) { SetWindowPos(hwndHeader, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOZORDER); SetWindowPos(hwndTree, 0, 0, headerheight, hr.right, hr.bottom - headerheight, SWP_NOZORDER); scroll.nPos = 0; } scroll.nMax = cx; scroll.nPage = hr.right; SetScrollInfo(hwndBox, SB_HORZ, &scroll, TRUE); GetClientRect(hwndBox, &hr); GetWindowRect(hwndTree, &ir); ir.right -= ir.left; SetWindowPos(hwndTree, 0, 0, 0, ir.right, hr.bottom - headerheight, SWP_NOMOVE | SWP_NOZORDER); SetWindowPos(hwndHeader, 0, 0, 0, cx, headerheight, SWP_NOMOVE | SWP_NOZORDER); } else { ShowScrollBar(hwndBox, SB_HORZ, FALSE); GetClientRect(hwndBox, &hr); SetWindowPos(hwndHeader, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOZORDER); SetWindowPos(hwndTree, 0, 0, headerheight, hr.right, hr.bottom - headerheight, SWP_NOZORDER); } RedrawWindow(hwndTree, NULL, NULL, RDW_INVALIDATE | RDW_NOERASE); }
int CXTPHeaderCtrl::GetFrozenColWidth() { int iFrozenWidth = 0; for (POSITION pos = m_arFrozenCols.GetHeadPosition(); pos; m_arFrozenCols.GetNext(pos)) { int iCol = m_arFrozenCols.GetAt(pos); CRect r; Header_GetItemRect(m_hWnd, iCol, &r); iFrozenWidth += r.Width(); } return iFrozenWidth; }
static BOOL ListViewContextMenu(HWND hwndPicker, LPARAM lParam) { struct PickerInfo *pPickerInfo; POINT pt, headerPt; int i = 0, nViewID = 0, nColumn = -1; HWND hwndHeader; RECT rcCol; pPickerInfo = GetPickerInfo(hwndPicker); // Extract the point out of the lparam pt.x = GET_X_LPARAM(lParam); pt.y = GET_Y_LPARAM(lParam); if (pt.x < 0 && pt.y < 0) GetCursorPos(&pt); // Figure out which header column was clicked, if at all nViewID = Picker_GetViewID(hwndPicker); if ((nViewID == VIEW_REPORT) || (nViewID == VIEW_GROUPED)) { hwndHeader = ListView_GetHeader(hwndPicker); headerPt = pt; ScreenToClient(hwndHeader, &headerPt); for (i = 0; Header_GetItemRect(hwndHeader, i, &rcCol); i++) { if (PtInRect(&rcCol, headerPt)) { nColumn = i; break; } } } if (nColumn >= 0) { // A column header was clicked if (pPickerInfo->pCallbacks->pfnOnHeaderContextMenu) pPickerInfo->pCallbacks->pfnOnHeaderContextMenu(pt, nColumn); } else { // The body was clicked if (pPickerInfo->pCallbacks->pfnOnBodyContextMenu) pPickerInfo->pCallbacks->pfnOnBodyContextMenu(pt); } return TRUE; }
// // MouseToItem // // Return the line+column information from the specified mouse coordinates // GVRow *GridView::MouseToItem(int mx, int my, ULONG *pline, ULONG *pcol, ULONG *puPortion, RECT *prect, GVITEM **gvitem) { RECT rect; ULONG line = 0, col = 0, portion = GHT_NONE; GetActiveClientRect(&rect); // clip mouse to edge of window if(mx < rect.left) mx = rect.left; if(my < rect.top) my = rect.top; if(my >= rect.bottom) my = rect.bottom - 1; if(mx >= rect.right) mx = rect.right - 1; // take the head-control into account my -= m_nHeaderHeight; mx += m_nHScrollPos; // work out the visual line-number line = my / m_nLineHeight + m_nVScrollPos; if(line >= m_gvData.VisibleRows()) line = m_gvData.VisibleRows()-1; if(gvitem) *gvitem = 0; GVRow *rowptr = m_gvData.GetRow(line); // check each column to see which was clicked in for(UINT i = 0; rowptr && i < m_nNumColumns; i++) { RECT rect; ULONG lidx = Header_OrderToIndex(m_hWndHeader, i); Header_GetItemRect(m_hWndHeader, lidx, &rect); // have we clicked in this item? perform a hittest to see what // part of the item was clicked (i.e. tree/icon/text etc) if(mx >= rect.left && mx < rect.right) { int treepos = rect.left;//0; int iconpos = rect.left;//0; if(prect) SetRect(prect, rect.left, line * m_nLineHeight + m_nHeaderHeight, rect.right, (line +1) * m_nLineHeight + m_nHeaderHeight - 1); // if this is column#0 then it contains the tree-hierarchy graphics if(lidx == 0) { treepos += rowptr->TreeIndent() * LEVEL_WIDTH; iconpos = treepos + LEVEL_WIDTH; if(rowptr->HasChildren() == false) treepos += LEVEL_WIDTH; } // clicked somewhere in the tree? if(mx < treepos) { portion = GHT_TREELINE; } else if(mx >= treepos && mx < iconpos) { portion = GHT_TREEBUTTON; } // clicked on the icon? else if(mx >= iconpos && mx < iconpos + 16) { portion = GHT_ICON; } // otherwise it's on the item itself else { portion = GHT_TEXT; } if(gvitem) *gvitem = &rowptr->items[lidx]; col = lidx; break; } } if(pcol) *pcol = col; if(puPortion) *puPortion = portion; if(pline) *pline = line; return rowptr; }
LRESULT CALLBACK TreeListHookProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { HWND BaseWindow = GetParent(hwnd); WNDPROC OriginalTreeProc = (WNDPROC)GetWindowLongPtr(BaseWindow, TL_TREEWNDPROC_SLOT); LPNMTTDISPINFO hdr; LPTSTR privateBuffer; TVITEMEX itemex; RECT rc, hr; PTL_SUBITEMS subitems; TOOLINFO tool; HDC dc; switch (uMsg) { case WM_NOTIFY: hdr = (LPNMTTDISPINFO)lParam; if (hdr->hdr.hwndFrom == (HWND)GetWindowLongPtr(BaseWindow, TL_TOOLTIPS_SLOT)) { switch (hdr->hdr.code) { case TTN_SHOW: RtlSecureZeroMemory(&tool, sizeof(tool)); tool.cbSize = sizeof(tool); tool.uId = hdr->hdr.idFrom; tool.hwnd = hwnd; SendMessage(hdr->hdr.hwndFrom, TTM_GETTOOLINFO, 0, (LPARAM)&tool); if (TreeView_GetItemRect(hwnd, (HTREEITEM)(hdr->hdr.idFrom - tool.lParam), &rc, TRUE)) { if (tool.lParam > 0) { Header_GetItemRect((HWND)GetWindowLongPtr(BaseWindow, TL_HEADERCONTROL_SLOT), tool.lParam, &hr); rc.left = hr.left; rc.right = hr.right; } rc.left += 3; rc.top += 1; ClientToScreen(hwnd, (LPPOINT)&rc); SendMessage(hdr->hdr.hwndFrom, TTM_ADJUSTRECT, TRUE, (LPARAM)&rc); SetWindowPos(hdr->hdr.hwndFrom, 0, rc.left, rc.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW); return TRUE; } break; case TTN_GETDISPINFO: if (!Header_GetItemRect((HWND)GetWindowLongPtr(BaseWindow, TL_HEADERCONTROL_SLOT), hdr->lParam, &hr)) break; if (!TreeView_GetItemRect(hwnd, (HTREEITEM)(hdr->hdr.idFrom - hdr->lParam), &rc, TRUE)) break; if ((hdr->lParam == 0) && (rc.right < hr.right - 1)) // is tooltip from the first column? break; privateBuffer = (LPTSTR)GetWindowLongPtr(BaseWindow, TL_TOOLTIPSBUFFER_SLOT); RtlSecureZeroMemory(&itemex, sizeof(itemex)); RtlSecureZeroMemory(privateBuffer, TL_SIZEOF_PRIVATEBUFFER); itemex.mask = TVIF_TEXT | TVIF_HANDLE | TVIF_PARAM; itemex.cchTextMax = MAX_PATH; itemex.pszText = privateBuffer; itemex.hItem = (HTREEITEM)(hdr->hdr.idFrom - hdr->lParam); TreeView_GetItem(hwnd, &itemex); if ((hdr->lParam > 0) && (itemex.lParam != 0)) { subitems = (PTL_SUBITEMS)itemex.lParam; rc.left = hr.left + 3; rc.right = hr.right - 3; dc = GetDC(hwnd); SelectObject(dc, (HGDIOBJ)SendMessage(hwnd, WM_GETFONT, 0, 0)); DrawText(dc, subitems->Text[hdr->lParam - 1], -1, &rc, DT_VCENTER | DT_SINGLELINE | DT_CALCRECT); ReleaseDC(hwnd, dc); if (rc.right < hr.right - 2) break; _strncpy(privateBuffer, MAX_PATH, subitems->Text[hdr->lParam - 1], MAX_PATH); } hdr->lpszText = privateBuffer; break; } } break; case WM_PAINT: TreeListUpdateTooltips(BaseWindow); break; } return OriginalTreeProc(hwnd, uMsg, wParam, lParam); }
LRESULT TreeListCustomDraw( HWND hwndHeader, LPNMTVCUSTOMDRAW pdraw ) { TCHAR textbuf[MAX_PATH]; TVITEMEX item; HBRUSH brush; HPEN pen; RECT hr, ir, subr; SIZE tsz; LONG i, c, cx; PTL_SUBITEMS subitem; HGDIOBJ prev; if ((pdraw->nmcd.dwDrawStage & CDDS_ITEM) == 0) return CDRF_NOTIFYITEMDRAW; RtlSecureZeroMemory(&item, sizeof(item)); RtlSecureZeroMemory(&textbuf, sizeof(textbuf)); item.mask = TVIF_TEXT | TVIF_HANDLE | TVIF_PARAM | TVIF_CHILDREN | TVIF_STATE; item.hItem = (HTREEITEM)pdraw->nmcd.dwItemSpec; item.cchTextMax = (sizeof(textbuf) / sizeof(TCHAR)) - 1; item.pszText = textbuf; TreeView_GetItem(pdraw->nmcd.hdr.hwndFrom, &item); subitem = (PTL_SUBITEMS)item.lParam; RtlSecureZeroMemory(&hr, sizeof(hr)); TreeView_GetItemRect(pdraw->nmcd.hdr.hwndFrom, (HTREEITEM)pdraw->nmcd.dwItemSpec, &ir, TRUE); //FillRect(pdraw->nmcd.hdc, &pdraw->nmcd.rc, GetSysColorBrush(COLOR_WINDOW)); if (item.cChildren == 1) { RtlSecureZeroMemory(&tsz, sizeof(tsz)); if (GetThemePartSize(tl_theme, pdraw->nmcd.hdc, TVP_GLYPH, GLPS_CLOSED, NULL, TS_TRUE, &tsz) != S_OK) { tsz.cx = 8; tsz.cy = 8; } subr.top = ir.top + (((ir.bottom - ir.top) - tsz.cy) / 2); subr.bottom = subr.top + tsz.cy; subr.left = ir.left - tsz.cx - 3; subr.right = ir.left - 3; if ((item.state & TVIS_EXPANDED) == 0) i = GLPS_CLOSED; else i = GLPS_OPENED; DrawThemeBackground(tl_theme, pdraw->nmcd.hdc, TVP_GLYPH, i, &subr, NULL); } cx = 0; c = Header_GetItemCount(hwndHeader); for (i = 0; i < c; i++) { RtlSecureZeroMemory(&hr, sizeof(hr)); Header_GetItemRect(hwndHeader, i, &hr); if (hr.right > cx) cx = hr.right; } if ((subitem) && ((pdraw->nmcd.uItemState & CDIS_FOCUS)) == 0) { if (subitem->ColorFlags & TLF_BGCOLOR_SET) { pdraw->clrTextBk = subitem->BgColor; SetBkColor(pdraw->nmcd.hdc, subitem->BgColor); } if (subitem->ColorFlags & TLF_FONTCOLOR_SET) { pdraw->clrText = subitem->FontColor; SetTextColor(pdraw->nmcd.hdc, subitem->FontColor); } } brush = CreateSolidBrush(pdraw->clrTextBk); subr.top = ir.top; subr.bottom = ir.bottom - 1; subr.left = ir.left; subr.right = cx; FillRect(pdraw->nmcd.hdc, &subr, brush); DeleteObject(brush); Header_GetItemRect(hwndHeader, 0, &hr); subr.right = hr.right - 3; subr.left += 3; DrawText(pdraw->nmcd.hdc, textbuf, -1, &subr, DT_END_ELLIPSIS | DT_VCENTER | DT_SINGLELINE); ir.right = cx; pen = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_MENUBAR)); prev = SelectObject(pdraw->nmcd.hdc, pen); for (i = 0; i < c; i++) { RtlSecureZeroMemory(&hr, sizeof(hr)); Header_GetItemRect(hwndHeader, i, &hr); if ((i > 0) && subitem) if (i <= (LONG)subitem->Count) if (subitem->Text[i - 1]) { subr.top = ir.top; subr.bottom = ir.bottom; subr.left = hr.left + 3; subr.right = hr.right - 3; DrawText(pdraw->nmcd.hdc, subitem->Text[i - 1], -1, &subr, DT_END_ELLIPSIS | DT_VCENTER | DT_SINGLELINE); } MoveToEx(pdraw->nmcd.hdc, hr.left, ir.bottom - 1, NULL); LineTo(pdraw->nmcd.hdc, hr.right - 1, ir.bottom - 1); LineTo(pdraw->nmcd.hdc, hr.right - 1, ir.top - 1); } SelectObject(pdraw->nmcd.hdc, prev); DeleteObject(pen); if ((pdraw->nmcd.uItemState & CDIS_FOCUS) != 0) DrawFocusRect(pdraw->nmcd.hdc, &ir); return CDRF_SKIPDEFAULT; }
void CXTPSkinObjectHeader::OnDraw(CDC* pDC) { CXTPClientRect rcClient(this); CRect rcBackground(rcClient); CXTPBufferDC dc(*pDC, rcClient); BOOL bFilterBar = (GetStyle() & HDS_FILTERBAR) && XTPSystemVersion()->GetComCtlVersion() >= MAKELONG(80, 5); CRect rcFilter(0, 0, 0, 0); dc.FillSolidRect(rcClient, GetColor(COLOR_3DFACE)); if (bFilterBar) { INT cyFilter = (rcClient.Height() - 1)/2; rcFilter = rcClient; rcClient.bottom = rcClient.top + cyFilter; rcFilter.top = rcClient.bottom; DefWindowProc(WM_PAINT, (WPARAM)dc.GetSafeHdc(), 0); } CXTPSkinManagerClass* pClass = GetSkinClass(); CXTPFontDC fontDC(&dc, GetFont()); dc.SetTextColor(GetColor(COLOR_BTNTEXT)); dc.SetBkMode(TRANSPARENT); CHeaderCtrl* pHeaderCtrl = (CHeaderCtrl*)this; int iItemCount = pHeaderCtrl->GetItemCount(); // Draw each header item for (int iItem = 0; iItem < iItemCount; ++iItem) { int nIndex = Header_OrderToIndex(m_hWnd, iItem); // initialize draw item structure. CRect rcItem(0, 0, 0, 0); Header_GetItemRect(m_hWnd, nIndex, &rcItem); if ((rcItem.right < rcClient.left) || (rcItem.left > rcClient.right)) continue; if (bFilterBar) { rcItem.bottom = rcFilter.top; } int nState = HIS_NORMAL; if (nIndex == m_nHotItem) { nState = m_bLBtnDown ? HIS_PRESSED : HIS_HOT; } rcBackground.left = max(rcBackground.left, rcItem.right); pClass->DrawThemeBackground(&dc, HP_HEADERITEM, nState, &rcItem); DrawItemEntry(&dc, nIndex, rcItem, nState); } if (rcBackground.left < rcBackground.right) pClass->DrawThemeBackground(&dc, 0, 0, &rcBackground); }