void CSearchDialog::UpdateListViewHeader() { HWND hHeader = ListView_GetHeader(GetDlgItem(m_hDlg,IDC_LISTVIEW_SEARCHRESULTS)); HDITEM hdItem; /* Remove the sort arrow from the column that was previously selected. */ if(m_iPreviousSelectedColumn != -1) { hdItem.mask = HDI_FORMAT; Header_GetItem(hHeader,m_iPreviousSelectedColumn,&hdItem); if(hdItem.fmt & HDF_SORTUP) { hdItem.fmt &= ~HDF_SORTUP; } else if(hdItem.fmt & HDF_SORTDOWN) { hdItem.fmt &= ~HDF_SORTDOWN; } Header_SetItem(hHeader,m_iPreviousSelectedColumn,&hdItem); } int iColumn = 0; for each(auto ci in m_sdps->m_Columns) { if(ci.SortMode == m_sdps->m_SortMode) { break; } iColumn++; } hdItem.mask = HDI_FORMAT; Header_GetItem(hHeader,iColumn,&hdItem); if(m_sdps->m_bSortAscending) { hdItem.fmt |= HDF_SORTUP; } else { hdItem.fmt |= HDF_SORTDOWN; } Header_SetItem(hHeader,iColumn,&hdItem); m_iPreviousSelectedColumn = iColumn; }
void CSysLogQuery::SetHeaderCheckbox(void) { BOOL fChecked = TRUE; for(int nItem = 0;nItem < ListView_GetItemCount(m_Syslog_query);nItem++) { if(!ListView_GetCheckState(m_Syslog_query,nItem)) { fChecked = FALSE; break; } } HWND header = ListView_GetHeader(m_Syslog_query); HDITEM hdi = {0}; hdi.mask = HDI_FORMAT; Header_GetItem(header,0,&hdi); if (fChecked) { hdi.fmt |= HDF_CHECKED; } else { hdi.fmt &= ~HDF_CHECKED; } Header_SetItem(header, 0, &hdi); }
void playlist_view::g_remove_sort() { bool b_sorted; unsigned idx; b_sorted = g_cache.active_get_playlist_sort(idx); if (b_sorted) { unsigned n, pcount = playlist_view::list_playlist.get_count(); for (n=0; n<pcount; n++) { playlist_view * p_playlist = playlist_view::list_playlist.get_item(n); if (p_playlist->wnd_header) { HDITEM hdi; memset(&hdi, 0, sizeof(hdi)); hdi.mask = HDI_FORMAT; Header_GetItem(p_playlist->wnd_header, idx, &hdi); /* FIX */ if (hdi.fmt & HDF_IMAGE) hdi.fmt ^= HDF_IMAGE; if (hdi.fmt & HDF_BITMAP_ON_RIGHT) hdi.fmt ^= HDF_BITMAP_ON_RIGHT; if (hdi.fmt & 0x0200) hdi.fmt ^= 0x0200; if (hdi.fmt & 0x0400) hdi.fmt ^= 0x0400; // hdi.fmt ^= HDF_IMAGE|HDF_BITMAP_ON_RIGHT|0x0200|0x0400; Header_SetItem(p_playlist->wnd_header, idx, &hdi); } } } }
//*********************************************************************** // apparently this only works for ComCtl version 6.0.0.0 // I would have to use a Manifest to specify that. // Linking a manifest requires adding a line to resource file: // CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "filename.manifest" //*********************************************************************** // http://www.gamedev.net/topic/569020-set-list-view-header-sort-arrow-c-win32/ BOOL CVListView::SetHeaderSortImage(int columnIndex, SHOW_ARROW showArrow) { HDITEM hdrItem = { 0 }; HWND hHeader = ListView_GetHeader(hwndVListView); if (hHeader) { hdrItem.mask = HDI_FORMAT; if ( Header_GetItem(hHeader, columnIndex, &hdrItem) ) { if (showArrow == SHOW_UP_ARROW) { hdrItem.fmt = (hdrItem.fmt & ~HDF_SORTDOWN) | HDF_SORTUP; } else if (showArrow == SHOW_DOWN_ARROW) { hdrItem.fmt = (hdrItem.fmt & ~HDF_SORTUP) | HDF_SORTDOWN; } else { hdrItem.fmt = hdrItem.fmt & ~(HDF_SORTDOWN | HDF_SORTUP); } return Header_SetItem(hHeader, columnIndex, &hdrItem); } } return FALSE; };
int TreeListGetHeaderWidth( __in PTREELIST_OBJECT Object ) { int i; int Count; int Width; HDITEM Item; RECT Rect; ASSERT(Object != NULL); Item.mask = HDI_WIDTH; Width = 0; Count = Header_GetItemCount(Object->hWndHeader); for(i = 0; i < Count; i++) { Header_GetItem(Object->hWndHeader, i, &Item); Width += Item.cxy; } // // N.B. Compare header's column total width with header's rect width // this require more evaluation. // GetClientRect(Object->hWndHeader, &Rect); Width = max(Rect.right - Rect.left, Width); return Width; }
LRESULT CpuFuncOnColumnClick( __in PDIALOG_OBJECT Object, __in NMLISTVIEW *lpNmlv ) { HWND hWndHeader; int nColumnCount; int i; HDITEM hdi; LISTVIEW_OBJECT *ListView; PCPU_FORM_CONTEXT Context; HWND hWndCtrl; HWND hWnd; Context = SdkGetContext(Object, CPU_FORM_CONTEXT); ListView = Context->ListView; if (ListView->SortOrder == SortOrderNone){ return 0; } if (ListView->LastClickedColumn == lpNmlv->iSubItem) { ListView->SortOrder = (LIST_SORT_ORDER)!ListView->SortOrder; } else { ListView->SortOrder = SortOrderAscendent; } hWnd = Object->hWnd; hWndCtrl = GetDlgItem(hWnd, IDC_LIST_FUNCTION); hWndHeader = ListView_GetHeader(hWndCtrl); ASSERT(hWndHeader); nColumnCount = Header_GetItemCount(hWndHeader); for (i = 0; i < nColumnCount; i++) { hdi.mask = HDI_FORMAT; Header_GetItem(hWndHeader, i, &hdi); if (i == lpNmlv->iSubItem) { hdi.fmt &= ~(HDF_SORTDOWN | HDF_SORTUP); if (ListView->SortOrder == SortOrderAscendent){ hdi.fmt |= HDF_SORTUP; } else { hdi.fmt |= HDF_SORTDOWN; } } else { hdi.fmt &= ~(HDF_SORTDOWN | HDF_SORTUP); } Header_SetItem(hWndHeader, i, &hdi); } ListView->LastClickedColumn = lpNmlv->iSubItem; ListView_SortItemsEx(hWndCtrl, CpuFuncSortCallback, (LPARAM)hWnd); return 0L; }
BOOL ListView_SortEx(HWND hListView, int iSortingColumn, int iSortedColumn) { HWND hHeader; HDITEM hColumn; BOOL bSortAsc; Sort sort; if ((GetWindowLongPtr(hListView, GWL_STYLE) & ~LVS_NOSORTHEADER) == 0) return TRUE; hHeader = ListView_GetHeader(hListView); SecureZeroMemory(&hColumn, sizeof(hColumn)); if ( (iSortedColumn != -1) && (iSortedColumn != iSortingColumn) ) { hColumn.mask = HDI_FORMAT | HDI_LPARAM; Header_GetItem(hHeader, iSortedColumn, &hColumn); hColumn.fmt &= ~HDF_SORTUP & ~HDF_SORTDOWN; hColumn.lParam = 0; // 0: deactivated, 1: false, 2: true. Header_SetItem(hHeader, iSortedColumn, &hColumn); } hColumn.mask = HDI_FORMAT | HDI_LPARAM; Header_GetItem(hHeader, iSortingColumn, &hColumn); bSortAsc = !(hColumn.lParam == 2); // 0: deactivated, 1: false, 2: true. hColumn.fmt &= (bSortAsc ? ~HDF_SORTDOWN : ~HDF_SORTUP ); hColumn.fmt |= (bSortAsc ? HDF_SORTUP : HDF_SORTDOWN); hColumn.lParam = (LPARAM)(bSortAsc ? 2 : 1); Header_SetItem(hHeader, iSortingColumn, &hColumn); /* Sort the list */ sort.bSortAsc = bSortAsc; sort.hList = hListView; sort.nClickedColumn = iSortingColumn; return ListView_SortItemsEx(hListView, SortListView, (LPARAM)&sort); }
LRESULT TreeListOnItemClick( __in PTREELIST_OBJECT Object, __in LPNMHDR lp ) { LPNMHEADER phdn; ULONG ColumnCount; ULONG Current, i; HDITEM hdi = {0}; if (!Object->hWndSort) { return 0; } phdn = (LPNMHEADER)lp; Current = phdn->iItem; if (Object->LastClickedColumn == Current) { Object->SortOrder = (LIST_SORT_ORDER)!Object->SortOrder; } else { Object->SortOrder = SortOrderAscendent; } ColumnCount = Header_GetItemCount(Object->hWndHeader); for (i = 0; i < ColumnCount; i++) { hdi.mask = HDI_FORMAT; Header_GetItem(Object->hWndHeader, i, &hdi); hdi.fmt &= ~(HDF_SORTDOWN | HDF_SORTUP); if (i == Current) { if (Object->SortOrder == SortOrderAscendent){ hdi.fmt |= HDF_SORTUP; } else { hdi.fmt |= HDF_SORTDOWN; } } Header_SetItem(Object->hWndHeader, i, &hdi); } Object->LastClickedColumn = Current; PostMessage(Object->hWndSort, WM_TREELIST_SORT, (WPARAM)Current, 0); return 0; }
void ListView::sort(int columnIndex, PFNLVCOMPARE compareItem) { // Update parameters of sorting. int oldSortColumnIndex = m_sortColumnIndex; m_sortColumnIndex = columnIndex; // make decision about order // positive value of m_sortAscending for ascending order // negative value of m_sortAscending for descending order if (oldSortColumnIndex == m_sortColumnIndex) { m_sortAscending = !m_sortAscending; } else { m_sortAscending = true; } m_compareItem = compareItem; // Update arrow in header. HWND hHeader = ListView_GetHeader(m_hwnd); if (hHeader != 0) { HDITEM hdrItem = { 0 }; hdrItem.mask = HDI_FORMAT; // delete all header icons if (Header_GetItem(hHeader, oldSortColumnIndex, &hdrItem)) { hdrItem.fmt = hdrItem.fmt & ~HDF_SORTUP & ~HDF_SORTDOWN; Header_SetItem(hHeader, oldSortColumnIndex, &hdrItem); } // add necessary header icon if (Header_GetItem(hHeader, m_sortColumnIndex, &hdrItem)) { hdrItem.fmt = hdrItem.fmt | (m_sortAscending ? HDF_SORTUP : HDF_SORTDOWN); Header_SetItem(hHeader, m_sortColumnIndex, &hdrItem); } } // Sort list of item. sort(); }
// CSysLogQuery 消息处理程序 BOOL CSysLogQuery::OnInitDialog() { CDialogEx::OnInitDialog(); // TODO: 在此添加额外的初始 CRect rect; m_Syslog_query.GetClientRect(&rect); m_Syslog_query.SetExtendedStyle(m_Syslog_query.GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_CHECKBOXES ); CImageList img_list; img_list.Create(1,25,ILC_COLORDDB | ILC_MASK,0,0); m_Syslog_query.SetImageList(&img_list,LVSIL_SMALL); m_Syslog_query.InsertColumn(0,NULL,LVCFMT_CENTER,40); //添加列标题 m_Syslog_query.InsertColumn(1, _T("操作时间"), LVCFMT_CENTER,(rect.Width()-40)/3-90, 1); m_Syslog_query.InsertColumn(2, _T("主机名"), LVCFMT_CENTER, (rect.Width()-40)/3-100, 2); m_Syslog_query.InsertColumn(3, _T("消息内容"), LVCFMT_CENTER, (rect.Width()-40)/3+180, 3); //m_Syslog_query.InsertColumn(4, _T("消息内容"), LVCFMT_CENTER, (rect.Width()-40)/4+150, 4); HWND header = ListView_GetHeader(m_Syslog_query); DWORD dwHeaderStyle = ::GetWindowLong(header, GWL_STYLE); dwHeaderStyle |= HDS_CHECKBOXES; ::SetWindowLong(header, GWL_STYLE, dwHeaderStyle); // Store the ID of the header control so we can handle its notification by ID int m_HeaderId = ::GetDlgCtrlID(header); // Now, we can update the format for the first header item, // which corresponds to the first column HDITEM hdi = { 0 }; hdi.mask = HDI_FORMAT; Header_GetItem(header, 0, &hdi); hdi.fmt |= HDF_CHECKBOX | HDF_FIXEDWIDTH; Header_SetItem(header, 0, &hdi); isCheckbox_log = FALSE; memset(check_log,0,256); i_checked_log = 0; page = 1; current_page = 0; return TRUE; // return TRUE unless you set the focus to a control // 异常: OCX 属性页应返回 FALSE }
// Set the UP / DOWN arrow image when a column header is clicked in the Favorite Games List void ListView_SetHeaderSortImage(HWND hLView, int nColIndex, bool bListViewAscending) { HWND hListViewHeader = ListView_GetHeader(hLView); BOOL isCommonControlVersion6 = IsCommCtrlVersion6(); int nColCount = Header_GetItemCount(hListViewHeader); for (int nIndex = 0; nIndex < nColCount; nIndex++) { HDITEM hi; // I only need to retrieve the format if i'm on windows xp. If not, then i need to retrieve the bitmap also. hi.mask = HDI_FORMAT | (isCommonControlVersion6 ? 0 : HDI_BITMAP); Header_GetItem(hListViewHeader, nIndex, &hi); // Set sort image to this column if(nIndex == nColIndex) { // Windows xp has a easier way to show the sort order in the header: i just have to set a flag and windows will do the drawing. No windows xp, no easy way. if (isCommonControlVersion6) { hi.fmt &= ~(HDF_SORTDOWN|HDF_SORTUP); hi.fmt |= bListViewAscending ? HDF_SORTUP : HDF_SORTDOWN; } else { UINT bitmapID = bListViewAscending ? IDB_UPARROW : IDB_DOWNARROW; // If there's a bitmap, let's delete it. if (hi.hbm) DeleteObject(hi.hbm); hi.fmt |= HDF_BITMAP|HDF_BITMAP_ON_RIGHT; hi.hbm = (HBITMAP)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(bitmapID), IMAGE_BITMAP, 0,0, LR_LOADMAP3DCOLORS); } } else { // Remove sort image (if exists) from other columns. if (isCommonControlVersion6) { hi.fmt &= ~(HDF_SORTDOWN|HDF_SORTUP); } else { // If there's a bitmap, let's delete it. if (hi.hbm) DeleteObject(hi.hbm); // Remove flags that tell windows to look for a bitmap. hi.mask &= ~HDI_BITMAP; hi.fmt &= ~(HDF_BITMAP|HDF_BITMAP_ON_RIGHT); } } Header_SetItem(hListViewHeader, nIndex, &hi); } }
void playlist_view::g_update_sort() { if (cfg_show_sort_arrows) { unsigned column; bool descending; bool b_sorted = g_cache.active_get_playlist_sort(column, &descending); if (b_sorted) { unsigned n, pcount = list_playlist.get_count(); for (n=0; n<pcount; n++) { playlist_view * p_playlist = playlist_view::list_playlist.get_item(n); if (p_playlist->wnd_header) { HDITEM hdi; memset(&hdi, 0, sizeof(hdi)); hdi.mask = HDI_FORMAT; Header_GetItem(p_playlist->wnd_header, column, &hdi); if (mmh::osversion::is_windows_xp_or_newer()) hdi.fmt |= HDF_STRING | (descending ? 0x0200 : 0x0400); else { if (!g_imagelist) create_image_list(); if (!Header_GetImageList(p_playlist->wnd_header)) Header_SetImageList(p_playlist->wnd_header, g_imagelist); hdi.mask |= HDI_IMAGE; hdi.fmt |= HDF_STRING|HDF_IMAGE|( (hdi.fmt & HDF_RIGHT ) ? 0 : HDF_BITMAP_ON_RIGHT); if (descending) { hdi.iImage = 0; } else { hdi.iImage = 1; } } Header_SetItem(p_playlist->wnd_header, column, &hdi); } } } } }
/** * Visually indicates the sort order of a header control item. * * \param hwnd A handle to the header control. * \param Index The index of the item. * \param Order The sort order of the item. */ VOID PhSetHeaderSortIcon( _In_ HWND hwnd, _In_ INT Index, _In_ PH_SORT_ORDER Order ) { ULONG count; ULONG i; count = Header_GetItemCount(hwnd); if (count == -1) return; for (i = 0; i < count; i++) { HDITEM item; item.mask = HDI_FORMAT; Header_GetItem(hwnd, i, &item); if (Order != NoSortOrder && i == Index) { if (Order == AscendingSortOrder) { item.fmt &= ~HDF_SORTDOWN; item.fmt |= HDF_SORTUP; } else if (Order == DescendingSortOrder) { item.fmt &= ~HDF_SORTUP; item.fmt |= HDF_SORTDOWN; } } else { item.fmt &= ~(HDF_SORTDOWN | HDF_SORTUP); } Header_SetItem(hwnd, i, &item); } }
VOID TreeListAutoExpand( HWND hwndHeader, LPNMTREEVIEW nhdr ) { RECT irc; LONG cx = 0, xleft = 0; HDITEM hdi; HTREEITEM citem = TreeView_GetChild(nhdr->hdr.hwndFrom, nhdr->itemNew.hItem); RtlSecureZeroMemory(&irc, sizeof(irc)); TreeView_GetItemRect(nhdr->hdr.hwndFrom, citem, &irc, TRUE); xleft = irc.left; while (citem) { RtlSecureZeroMemory(&irc, sizeof(irc)); TreeView_GetItemRect(nhdr->hdr.hwndFrom, citem, &irc, TRUE); if (irc.left < xleft) break; if (irc.right > cx) cx = irc.right; citem = TreeView_GetNextVisible(nhdr->hdr.hwndFrom, citem); } RtlSecureZeroMemory(&hdi, sizeof(hdi)); hdi.mask = HDI_WIDTH; Header_GetItem(hwndHeader, 0, &hdi); if (hdi.cxy < cx + 8) hdi.cxy = cx + 8; Header_SetItem(hwndHeader, 0, &hdi); }
void lvAddHeaderCheckbox(HWND lvTarget) { HWND header; DWORD dwHeaderStyle; INT iIndex; iIndex=LVFind(LV_FINDHWND,lvTarget); if (iIndex<0) ehError(); header = ListView_GetHeader(lvTarget); dwHeaderStyle = GetWindowLong(header, GWL_STYLE); dwHeaderStyle |= HDS_CHECKBOXES; SetWindowLong(header, GWL_STYLE, dwHeaderStyle); { // Now, we can update the format for the first header item, // which corresponds to the first column HDITEM hdi = { 0 }; hdi.mask = HDI_FORMAT; Header_GetItem(header, 0, &hdi); hdi.fmt |= HDF_CHECKBOX | HDF_FIXEDWIDTH; Header_SetItem(header, 0, &hdi); } //_arsLv[iIndex].hWndHeader=ListView_GetHeader(lvTarget);//GetWindow(objCalled->hWnd, GW_CHILD); //_arsLv[iIndex].idHeader=GetDlgCtrlID(_arsLv[iIndex].hWndHeader); }
LRESULT CpuThreadOnColumnClick( __in PDIALOG_OBJECT Object, __in NMLISTVIEW *lpNmlv ) { HWND hWndHeader; int nColumnCount; int i; HDITEM hdi; LISTVIEW_OBJECT *ListView; PCPU_FORM_CONTEXT Context; HWND hWndCtrl; HWND hWnd; BOOLEAN IsThreadSort; Context = SdkGetContext(Object, CPU_FORM_CONTEXT); ListView = Context->ListView; if (ListView->SortOrder == SortOrderNone){ return 0; } if (ListView->LastClickedColumn == lpNmlv->iSubItem) { ListView->SortOrder = (LIST_SORT_ORDER)!ListView->SortOrder; } else { ListView->SortOrder = SortOrderAscendent; } hWnd = Object->hWnd; hWndCtrl = lpNmlv->hdr.hwndFrom; IsThreadSort = (lpNmlv->hdr.idFrom == IDC_LIST_CPU_THREAD_THREAD) ? TRUE : FALSE; hWndHeader = ListView_GetHeader(hWndCtrl); ASSERT(hWndHeader); nColumnCount = Header_GetItemCount(hWndHeader); for (i = 0; i < nColumnCount; i++) { hdi.mask = HDI_FORMAT; Header_GetItem(hWndHeader, i, &hdi); if (i == lpNmlv->iSubItem) { hdi.fmt &= ~(HDF_SORTDOWN | HDF_SORTUP); if (ListView->SortOrder == SortOrderAscendent){ hdi.fmt |= HDF_SORTUP; } else { hdi.fmt |= HDF_SORTDOWN; } } else { hdi.fmt &= ~(HDF_SORTDOWN | HDF_SORTUP); } Header_SetItem(hWndHeader, i, &hdi); } ListView->LastClickedColumn = lpNmlv->iSubItem; if (IsThreadSort) { ListView_SortItemsEx(hWndCtrl, CpuThreadSortThreadCallback, (LPARAM)hWnd); } else { ListView_SortItemsEx(hWndCtrl, CpuThreadSortPcCallback, (LPARAM)hWnd); } return 0L; }
LRESULT ClbWndProc( IN HWND hWnd, IN UINT message, IN WPARAM wParam, IN LPARAM lParam ) /*++ Routine Description: This function is the window procedure for the Clb custom control. Arguments: Standard window procedure parameters. Return Value: LRESULT - dependent on the supplied message. --*/ { BOOL Success; LPCLB_INFO ClbInfo; if( message == WM_NCCREATE ) { LONG Long; // // Save the original styles. // Long = SetWindowLong( hWnd, GWL_USERDATA, (( LPCREATESTRUCT ) lParam )->style ); DbgAssert( Long == 0 ); // // Get rid of any styles that are uninteresting to the Clb. // SetWindowLong( hWnd, GWL_STYLE, (( LPCREATESTRUCT ) lParam )->style & CLBS_CLB ); return TRUE; } if( message == WM_CREATE ) { // // Assert that there is no prior per window information associated // with this Clb. // DbgAssert( RestoreClbInfo( hWnd ) == NULL ); // // Restore the original styles. // (( LPCREATESTRUCT ) lParam )->style = GetWindowLong( hWnd, GWL_USERDATA ); // // Allocate a CLB_INFO object for this Clb and initialize the Clb // relevant fields. // ClbInfo = AllocateObject( CLB_INFO, 1 ); DbgPointerAssert( ClbInfo ); // // Set the number of columns to zero so that remainder of creation // understands the state of the Clb. // ClbInfo->Columns = 0; // // Create the header portion of the Clb. // Success = CreateHeader( hWnd, ClbInfo, ( LPCREATESTRUCT ) lParam ); DbgAssert( Success ); // // Create the list box portion of the Clb. // Success = CreateListBox( hWnd, ClbInfo, ( LPCREATESTRUCT ) lParam ); DbgAssert( Success ); // // Adjust the column number, widths based on the heading text. // Success = AdjustClbHeadings( hWnd, ClbInfo, (( LPCREATESTRUCT ) lParam )->lpszName ); DbgAssert( Success ); // // Everything was succesfully created so set the Clb's signature // and save it away as part of the per window data. // SetSignature( ClbInfo ); SaveClbInfo( ClbInfo ); return 0; } // // Get the ClbInfo object for this Clb and make sure that its already // been created i.e. WM_CREATE was already executed and thereby initialized // and saved a ClbInfo object. // ClbInfo = RestoreClbInfo( hWnd ); if( ClbInfo != NULL ) { // // Validate that this really is a ClbInfo object. // DbgAssert( CheckSignature( ClbInfo )); switch( message ) { case WM_DESTROY: { // // Delete the font used in the list box. // Success = DeleteObject( ClbInfo->hFontListBox ); DbgAssert( Success ); // // Delete the array of right habd edges. // Success = FreeObject( ClbInfo->Right ); DbgAssert( Success ); // // Delete the CLB_INFO object for this window. // Success = FreeObject( ClbInfo ); DbgAssert( Success ); SaveClbInfo ( ClbInfo ); return 0; } case WM_PAINT: { PAINTSTRUCT ps; RECT Rect; POINT Points[ 2 ]; HDC hDC; HPEN hPen; hDC = BeginPaint( hWnd, &ps ); DbgAssert( hDC == ps.hdc ); Success = GetClientRect( hWnd, &Rect ); DbgAssert( Success ); Points[ 0 ].x = 0; Points[ 0 ].y = ClbInfo->HeaderHeight + 1; Points[ 1 ].x = Rect.right - Rect.left; Points[ 1 ].y = ClbInfo->HeaderHeight + 1; hPen = GetStockObject( BLACK_PEN ); DbgHandleAssert( hPen ); hPen = SelectObject( hDC, hPen ); Success = Polyline( hDC, Points, NumberOfEntries( Points )); DbgAssert( Success ); hPen = SelectObject( hDC, hPen ); Success = DeleteObject( hPen ); DbgAssert( Success ); Success = EndPaint( hWnd, &ps ); DbgAssert( Success ); return 0; } case WM_COMMAND: switch( LOWORD( wParam )) { case ID_LISTBOX: switch( HIWORD( wParam )) { case LBN_DBLCLK: case LBN_KILLFOCUS: case LBN_SELCHANGE: { // // These messages come to ClbWndProc because it is the parent // of the list box, but they are really intended for the parent // of the Clb. // HWND hWndParent; // // Forward the message to the Clb's parent if it has a parent. // hWndParent = GetParent( hWnd ); DbgHandleAssert( hWndParent ); if( hWndParent != NULL ) { // // Replace the control id and handle with the Clb's. // LOWORD( wParam ) = GetDlgCtrlID( hWnd ); DbgAssert( LOWORD( wParam ) != 0 ); lParam = ( LPARAM ) hWnd; // // Forward the message... // return SendMessage( hWndParent, message, wParam, lParam ); } } } break; } break; // // Forward to listbox. // case LB_GETCURSEL: case LB_SETCURSEL: case LB_FINDSTRING: case LB_GETITEMDATA: case LB_RESETCONTENT: case WM_CHAR: case WM_GETDLGCODE: case WM_KILLFOCUS: return SendMessage( ClbInfo->hWndListBox, message, wParam, lParam ); case WM_SETFOCUS: { SetFocus( ClbInfo->hWndListBox ); return 0; } case WM_COMPAREITEM: { // // This message comes to ClbWndProc because it is the parent // of the list box, but is really intended for the parent // of the Clb. // HWND hWndParent; // // Forward the message to the Clb's parent if it has a parent. // hWndParent = GetParent( hWnd ); DbgHandleAssert( hWndParent ); if( hWndParent != NULL ) { int ControlId; LPCOMPAREITEMSTRUCT lpcis; lpcis = ( LPCOMPAREITEMSTRUCT ) lParam; ControlId = GetDlgCtrlID( hWnd ); DbgAssert( ControlId != 0 ); // // Modify the COMPAREITEMSTRUCT so that it refers to the Clb. // lpcis->CtlID = ControlId; lpcis->hwndItem = hWnd; // // Forward the message... // return SendMessage( hWndParent, message, ( WPARAM ) ControlId, lParam ); } break; } case WM_DELETEITEM: { LPDELETEITEMSTRUCT lpditms; LPCLB_ROW ClbRow; DWORD i; DbgAssert( wParam == ID_LISTBOX ); // // Retrieve the pointer to the DELETEITEMSTRUCT. // lpditms = ( LPDELETEITEMSTRUCT ) lParam; DbgAssert(( lpditms->CtlType == ODT_LISTBOX ) &&( lpditms->CtlID == ID_LISTBOX )); // // If there is no data, just return. // if( lpditms->itemData == 0 ) { return TRUE; } // // Retrieve the CLB_ROW object for this row. // ClbRow = ( LPCLB_ROW ) lpditms->itemData; // // For each column delete the string. // for( i = 0; i < ClbInfo->Columns; i++ ) { // // Strings were copied with _tcsdup so they must be // freed with free( ). // free( ClbRow->Strings[ i ].String ); } // // Free the CLB_STRING object. // Success = FreeObject( ClbRow->Strings ); DbgAssert( Success ); // // Free the CLB_ROW object. // Success = FreeObject( ClbRow ); DbgAssert( Success ); return TRUE; } case WM_DRAWITEM: { LPDRAWITEMSTRUCT lpdis; BOOL DrawFocus; DbgAssert( wParam == ID_LISTBOX ); // // Retrieve the pointer to the DRAWITEMSTRUCT. // lpdis = ( LPDRAWITEMSTRUCT ) lParam; DbgAssert(( lpdis->CtlType == ODT_LISTBOX ) &&( lpdis->CtlID == ID_LISTBOX )); // // If there is no data, just return. // if( lpdis->itemData == 0 ) { return TRUE; } if( lpdis->itemAction & ( ODA_DRAWENTIRE | ODA_SELECT )) { DWORD i; LPCLB_ROW ClbRow; COLORREF TextColor; COLORREF BkColor; // // Retrieve the CLB_ROW object for this row. // ClbRow = ( LPCLB_ROW ) lpdis->itemData; // // If the item is selected, set the selection colors. // if( lpdis->itemState & ODS_SELECTED ) { BkColor = COLOR_HIGHLIGHT; TextColor = COLOR_HIGHLIGHTTEXT; } else { BkColor = COLOR_WINDOW; TextColor = COLOR_WINDOWTEXT; } BkColor = GetSysColor( BkColor ); TextColor = GetSysColor( TextColor ); BkColor = SetBkColor( lpdis->hDC, BkColor ); DbgAssert( BkColor != CLR_INVALID ); TextColor = SetTextColor( lpdis->hDC, TextColor ); DbgAssert( TextColor != CLR_INVALID ); // // For each column display the text. // for( i = 0; i < ClbInfo->Columns; i++ ) { RECT ClipOpaqueRect; int x; int Left; UINT GdiErr; // // Depending on the format, adjust the alignment reference // point (x) and the clipping rectangles left edge so that // there are five pixels between each column. // switch( ClbRow->Strings[ i ].Format ) { case CLB_LEFT: if( i == 0 ) { x = 2; } else { x = ClbInfo->Right[ i - 1 ] + 2; } Left = x - 2; break; case CLB_RIGHT: if( i == 0 ) { Left = 0; } else { Left = ClbInfo->Right[ i - 1 ]; } x = ClbInfo->Right[ i ] - 3; break; default: DbgAssert( FALSE ); } // // Set the format for this column. // GdiErr = SetTextAlign( lpdis->hDC, ClbRow->Strings[ i ].Format | TA_TOP ); DbgAssert( GdiErr != GDI_ERROR ); // // Clip each string to its column width less two pixels // (for asthetics). // Success = SetRect( &ClipOpaqueRect, Left, lpdis->rcItem.top, ClbInfo->Right[ i ], lpdis->rcItem.bottom ); DbgAssert( Success ); Success = ExtTextOut( lpdis->hDC, x, lpdis->rcItem.top, ETO_CLIPPED | ETO_OPAQUE, &ClipOpaqueRect, ClbRow->Strings[ i ].String, ClbRow->Strings[ i ].Length, NULL ); DbgAssert( Success ); // // If the item has the focus, draw the focus rectangle. // DrawFocus = lpdis->itemState & ODS_FOCUS; } } else { // // If the Clb has the focus, display a focus rectangle // around the selected item. // DrawFocus = lpdis->itemAction & ODA_FOCUS; } // // If needed, toggle the focus rectangle. // if( DrawFocus ) { Success = DrawFocusRect( lpdis->hDC, &lpdis->rcItem ); DbgAssert( Success ); } return TRUE; } case WM_NOTIFY: { HD_NOTIFY * lpNot; HD_ITEM *pHDI; lpNot = (HD_NOTIFY *)lParam; pHDI = lpNot->pitem; switch( lpNot->hdr.code) { static DRAW_ERASE_LINE DrawEraseLine; static HPEN hPen; static HDC hDCClientListBox; HD_ITEM hdi; UINT iRight; UINT i; RECT ClientRectHeader; case HDN_BEGINTRACK: { RECT ClientRectListBox; // // Get thd HDC for the list box. // hDCClientListBox = GetDC( ClbInfo->hWndListBox ); DbgHandleAssert( hDCClientListBox ); // // Create the pen used to display the drag position and // select it into the in list box client area DC. Also set // the ROP2 code so that drawing with the pen twice in the // same place will erase it. This is what allows the // line to drag. // hPen = CreatePen( PS_DOT, 1, RGB( 255, 255, 255 )); DbgHandleAssert( hPen ); hPen = SelectObject( hDCClientListBox, hPen ); SetROP2( hDCClientListBox, R2_XORPEN ); // // Set up the DRAW_ERASE_LINE structure so that the drag line is // drawn from the top to the bottom of the list box at the // current drag position. // Success = GetClientRect( ClbInfo->hWndListBox, &ClientRectListBox ); DbgAssert( Success ); // // Draw the initial drag line from the top to the bottom // of the list box equivalent with the header edge grabbed // by the user. // DrawEraseLine.Draw.Src.x = ClbInfo->Right[ pHDI->cxy ]; DrawEraseLine.Draw.Src.y = 0; DrawEraseLine.Draw.Dst.x = ClbInfo->Right[ pHDI->cxy ]; DrawEraseLine.Draw.Dst.y = ClientRectListBox.bottom - ClientRectListBox.top; Success = DrawLine( hDCClientListBox, &DrawEraseLine ); DbgAssert( Success ); return 0; } case HDN_TRACK: { //DWORD Columns; // // Get new drag position. // iRight = 0; hdi.mask = HDI_WIDTH; for( i = 0; i < ClbInfo->Columns - 1; i++ ) { if (i != (UINT)lpNot->iItem) { Header_GetItem(ClbInfo->hWndHeader, i, &hdi); } else { hdi.cxy = pHDI->cxy; } iRight += hdi.cxy; ClbInfo->Right[i] = iRight; } GetClientRect( ClbInfo->hWndHeader, &ClientRectHeader ); ClbInfo->Right[i] = ClientRectHeader.right; // // Erase the old line and draw the new one at the new // drag position. // Success = RedrawVerticalLine( hDCClientListBox, ClbInfo->Right[lpNot->iItem], &DrawEraseLine ); DbgAssert( Success ); return 0; } case HDN_ENDTRACK: // // Replace the old pen and delete the one created // during HBN_BEGINDRAG. // hPen = SelectObject( hDCClientListBox, hPen ); Success = DeleteObject( hPen ); DbgAssert( Success ); // // Release the DC for the list box. // Success = ReleaseDC( ClbInfo->hWndListBox, hDCClientListBox ); DbgAssert( Success ); Success = RedrawWindow( hWnd, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_UPDATENOW | RDW_ALLCHILDREN ); DbgAssert( Success ); return 0; } break; } case WM_SETTEXT: // // Adjust the column number and widths based on the heading text. // Success = AdjustClbHeadings( hWnd, ClbInfo, ( LPCWSTR ) lParam ); DbgAssert( Success ); return Success; case WM_SIZE: { HDWP hDWP; LONG Width; LONG Height; LONG Style; LONG VScrollWidth; Width = LOWORD( lParam ); Height = HIWORD( lParam ); hDWP = BeginDeferWindowPos( 2 ); DbgHandleAssert( hDWP ); // // Retrieve the list box's styles. // Style = GetWindowLong( ClbInfo->hWndListBox, GWL_STYLE ); // // If the list box has a vertical scroll bar compute its // width so that the header window's width can be adjusted // appropriately. // VScrollWidth = ( Style & WS_VSCROLL ) ? GetSystemMetrics( SM_CXVSCROLL ) + ( GetSystemMetrics( SM_CXBORDER ) * 2 ) : 0; // // Size the header window to the width of the Clb and its // default / original height. // hDWP = DeferWindowPos( hDWP, ClbInfo->hWndHeader, NULL, 0, 0, Width - VScrollWidth, ClbInfo->HeaderHeight, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER ); DbgHandleAssert( hDWP ); // // If the list box has a vertical scroll bar, bump the width // and height by two so that its border overwrites the Clb // border. This eliminates a double border (and a gap) between // the right and bottom edges of the scroll bar and the Clb. // if( Style & WS_VSCROLL ) { Height += 2; Width += 2; } // // Size the list box so that it is the size of the Clb less // the height of the header window less the height of the // border. // hDWP = DeferWindowPos( hDWP, ClbInfo->hWndListBox, NULL, 0, 0, Width, Height - ClbInfo->HeaderHeight - 3, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER ); DbgHandleAssert( hDWP ); Success = EndDeferWindowPos( hDWP ); DbgAssert( Success ); break; } } } return DefWindowProc( hWnd, message, wParam, lParam ); }
LRESULT FilterOnColumnClick( IN HWND hWnd, IN NMLISTVIEW *lpNmlv ) { HWND hWndList; HWND hWndHeader; int ColumnCount; int i; HDITEM hdi; LISTVIEW_OBJECT *Object; PDIALOG_OBJECT Dialog; PFILTER_CONTEXT Context; Dialog = (PDIALOG_OBJECT)SdkGetObject(hWnd); Context = SdkGetContext(Dialog, FILTER_CONTEXT); Object = Context->ListObject; ASSERT(Object != NULL); if (Object->SortOrder == SortOrderNone){ return 0; } if (Object->LastClickedColumn == lpNmlv->iSubItem) { Object->SortOrder = (LIST_SORT_ORDER)!Object->SortOrder; } else { Object->SortOrder = SortOrderAscendent; } hWndList = GetDlgItem(hWnd, IDC_LIST_FILTER); hWndHeader = ListView_GetHeader(hWndList); ASSERT(hWndHeader); ColumnCount = Header_GetItemCount(hWndHeader); for (i = 0; i < ColumnCount; i++) { hdi.mask = HDI_FORMAT; Header_GetItem(hWndHeader, i, &hdi); if (i == lpNmlv->iSubItem) { hdi.fmt &= ~(HDF_SORTDOWN | HDF_SORTUP); if (Object->SortOrder == SortOrderAscendent){ hdi.fmt |= HDF_SORTUP; } else { hdi.fmt |= HDF_SORTDOWN; } } else { hdi.fmt &= ~(HDF_SORTDOWN | HDF_SORTUP); } Header_SetItem(hWndHeader, i, &hdi); } Object->LastClickedColumn = lpNmlv->iSubItem; Object->hWnd = lpNmlv->hdr.hwndFrom; Object->CtrlId = lpNmlv->hdr.idFrom; ListView_SortItemsEx(hWndList, FilterSortCallback, (LPARAM)Object); return 0L; }
void SearchResults::rebuild() { EnterCriticalSection(&lock); static char colNames[colCount][32] = { "Name", "Date", "Size", "Game name", "Lineup", "Length", "Mode" }; int colPos[colCount]; getColPos(colPos); int colOrder[colCount]; int numOrder = 0; for (int i = 0; i < colCount; i++) if (colPos[cfg.colOrder[i]] >= 0) colOrder[numOrder++] = colPos[cfg.colOrder[i]]; Dictionary<uint32> selected; for (int sel = ListView_GetNextItem(hWnd, -1, LVNI_SELECTED); sel >= 0; sel = ListView_GetNextItem(hWnd, sel, LVNI_SELECTED)) selected.set(items[sel].path, 1); int scrollPosX = GetScrollPos(hWnd, SB_HORZ); int scrollPosY = GetScrollPos(hWnd, SB_VERT); if (items.length() > 0) { RECT rc; ListView_GetItemRect(hWnd, 0, &rc, LVIR_BOUNDS); scrollPosY *= rc.bottom - rc.top; } setRedraw(false); clear(); clearColumns(); for (int i = 0; i < colCount; i++) if (colPos[i] >= 0) insertColumn(colPos[i], colNames[i]); if (colPos[colName] >= 0) setColumnUTF8(colPos[colName], true); ListView_SetColumnOrderArray(hWnd, numOrder, colOrder); int colSort = (cfg.colSort[0] & 0x80000000 ? ~cfg.colSort[0] : cfg.colSort[0]); if (colSort >= 0 && colSort < colCount && colPos[colSort] >= 0 && items.length() > 0) { HBITMAP image = NULL; if (cfg.colSort[0] & 0x80000000) image = getApp()->getImageLibrary()->getBitmap("SortUp"); else image = getApp()->getImageLibrary()->getBitmap("SortDown"); if (image) { HWND hHeader = ListView_GetHeader(hWnd); HDITEM hdi; memset(&hdi, 0, sizeof hdi); hdi.mask = HDI_FORMAT; Header_GetItem(hHeader, colSort, &hdi); hdi.mask |= HDI_BITMAP; hdi.fmt |= HDF_BITMAP | HDF_BITMAP_ON_RIGHT; hdi.hbm = image; Header_SetItem(hHeader, colSort, &hdi); } } items.sort(compItems); for (int i = 0; i < items.length(); i++) addItem(i, false); for (int i = 0; i < items.length(); i++) if (selected.has(items[i].path)) ListView_SetItemState(hWnd, i, LVIS_SELECTED, LVIS_SELECTED); for (int i = 0; i < colCount; i++) if (colPos[i] >= 0) setColumnWidth(colPos[i], cfg.colWidth[i]); setRedraw(true); ListView_Scroll(hWnd, scrollPosX, scrollPosY); LeaveCriticalSection(&lock); }
VOID TreeListUpdateColumn( __in PTREELIST_OBJECT Object ) { HDITEM hdi; LONG i; Object->HeaderWidth = 0; for(i = 0; i < Object->ColumnCount; i++) { hdi.mask = HDI_WIDTH | HDI_LPARAM | HDI_FORMAT; Header_GetItem(Object->hWndHeader, i, &hdi); Object->Column[i].Width = hdi.cxy; if(i == 0) { //Object->Column[i].Rect.left = 2; Object->Column[i].Rect.left = 0; } else { //Object->Column[i].Rect.left = Object->Column[i - 1].Rect.right + 2; Object->Column[i].Rect.left = Object->Column[i - 1].Rect.right; } Object->Column[i].Rect.right = Object->Column[i].Rect.left + //Object->Column[i].Width - 2; Object->Column[i].Width; switch(hdi.fmt & HDF_JUSTIFYMASK) { case HDF_RIGHT: Object->Column[i].Align = DT_RIGHT; break; case HDF_CENTER: Object->Column[i].Align = DT_CENTER; break; case HDF_LEFT: Object->Column[i].Align = DT_LEFT; break; default: Object->Column[i].Align = DT_LEFT; } Object->HeaderWidth += Object->Column[i].Width; } // // Adjust right column width according to header's bounding rect // /*GetWindowRect(Object->hWndHeader, &rc); Delta = rc.right - rc.left - Object->HeaderWidth; if (Delta > 0) { i -= 1; Object->Column[i].Width += Delta; Object->HeaderWidth += Delta; hdi.mask = HDI_WIDTH; hdi.cxy = Object->Column[i].Width; Header_SetItem(Object->hWndHeader, i, &hdi); }*/ }
VOID WINAPI HashVerifySortColumn( PHASHVERIFYCONTEXT phvctx, LPNMLISTVIEW plv ) { if (phvctx->status != CLEANUP_COMPLETED) return; // Sorting is available only after the worker is done // Capture the current selection/focus state HashVerifyReadStates(phvctx); if (phvctx->sort.iColumn != plv->iSubItem) { // Change to a new column phvctx->sort.iColumn = plv->iSubItem; phvctx->sort.bReverse = FALSE; qsort_s_uptr(phvctx->index, phvctx->cTotal, sizeof(PHVITEM), HashVerifySortCompare, phvctx); } else if (phvctx->sort.bReverse) { // Clicking a column thrice in a row reverts to the original file order phvctx->sort.iColumn = -1; phvctx->sort.bReverse = FALSE; // We do need to validate phvctx->index to handle the edge case where // the list is really non-empty, but we are treating it as empty because // we could not allocate an index (qsort_s uses the given length while // SLBuildIndex uses the actual length); this is, admittedly, a very // extreme edge case, as it crops up only in an OOM situation where the // user tries to click-sort an empty list view! if (phvctx->index) SLBuildIndex(phvctx->hList, phvctx->index); } else { // Clicking a column twice in a row reverses the order; since we are // just reversing the order of an already-sorted column, we can just // naively flip the index if (phvctx->index) { PHVITEM pItemTemp; PPHVITEM ppItemLow = phvctx->index; PPHVITEM ppItemHigh = phvctx->index + phvctx->cTotal - 1; while (ppItemHigh > ppItemLow) { pItemTemp = *ppItemLow; *ppItemLow = *ppItemHigh; *ppItemHigh = pItemTemp; ++ppItemLow; --ppItemHigh; } } phvctx->sort.bReverse = TRUE; } // Restore the selection/focus state HashVerifySetStates(phvctx); // Update the UI { HWND hWndHeader = ListView_GetHeader(phvctx->hWndList); INT i; HDITEM hdi; hdi.mask = HDI_FORMAT; for (i = HV_COL_FIRST; i <= HV_COL_LAST; ++i) { Header_GetItem(hWndHeader, i, &hdi); hdi.fmt &= ~(HDF_SORTDOWN | HDF_SORTUP); if (phvctx->sort.iColumn == i) hdi.fmt |= (phvctx->sort.bReverse) ? HDF_SORTDOWN : HDF_SORTUP; Header_SetItem(hWndHeader, i, &hdi); } // Invalidate all items ListView_RedrawItems(phvctx->hWndList, 0, phvctx->cTotal); // Set a light gray background on the sorted column ListView_SetSelectedColumn( phvctx->hWndList, (phvctx->sort.iColumn != HV_COL_STATUS) ? phvctx->sort.iColumn : -1 ); // Unfortunately, the list does not automatically repaint all of the // areas affected by SetSelectedColumn, so it is necessary to force a // repaint of the list view's visible areas in order to avoid artifacts InvalidateRect(phvctx->hWndList, NULL, FALSE); } }
void DoGetRepStuff(HWND hwnd, LPINSERTITEM pfr) { HD_ITEM hi; int ret; HD_ITEM FAR* pitem; HGLOBAL hglb; int iAlloc; hi.mask = pfr->mask; hi.cxy = pfr->cxy; if (pfr->Nullpitem) pitem = NULL; else pitem = &hi; hi.cchTextMax = pfr->cchTextMax; // hi.cchTextMax = MAX_PSZTEXT; hi.fmt = pfr->fmt; hi.lParam = pfr->lParam; if (hi.cchTextMax == 0) iAlloc = MAX_PSZTEXT; else iAlloc = hi.cchTextMax; if (pfr->NullpszText) hi.pszText = NULL; // can this be done ?? else { hglb = GlobalAlloc(GPTR, iAlloc); hi.pszText = (LPSTR) GlobalLock(hglb); // _fstrcpy(hi.pszText, pfr->pszText); } if (pfr->NullHwd) ret = Header_GetItem(NULL, pfr->index, pitem); else ret = Header_GetItem(pfr->hwnd, pfr->index, pitem); wsprintf(szDbgMsg, "%d = Header_GetItem(index = %d, \n\ mask = %x )", ret, pfr->index, hi.mask); MyDebugMsg(DM_TRACE, "%s", (LPCSTR) szDbgMsg); SetDlgItemInt(hwnd, IDC_INSERTRET, ret, TRUE) ; if (ret) { SetDlgItemInt(hwnd, IDC_INSERTCXY, hi.cxy, TRUE); SetDlgItemInt(hwnd, IDC_INSERTCCHTEXTMAX, hi.cchTextMax, TRUE); wsprintf(szTemp, szLongFilter, hi.lParam); SetDlgItemText(hwnd, IDC_INSERTLPARAM, szTemp); SetDlgItemText(hwnd, IDC_INSERTTEXT, hi.pszText); wsprintf(szTemp, "%04hx", hi.mask); SetDlgItemText(hwnd, IDC_INSERTMASK, szTemp); CheckDlgButton(hwnd, IDC_INSERTHDRIGHT, hi.fmt & HDF_RIGHT); CheckDlgButton(hwnd, IDC_INSERTHDLEFT, hi.fmt & HDF_LEFT); CheckDlgButton(hwnd, IDC_INSERTHDCENTER, hi.fmt & HDF_CENTER); CheckDlgButton(hwnd, IDC_INSERTHDJUSTIFYMASK, hi.fmt & HDF_JUSTIFYMASK); CheckDlgButton(hwnd, IDC_INSERTHDOWNERDRAW, hi.fmt & HDF_OWNERDRAW); CheckDlgButton(hwnd, IDC_INSERTHDSTRING, hi.fmt & HDF_STRING); CheckDlgButton(hwnd, IDC_INSERTHDBITMAP, hi.fmt & HDF_BITMAP); wsprintf(szTemp, szLongFilter, (DWORD) hi.hbm); SetDlgItemText(hwnd, IDC_INSERTHBM, szTemp); wsprintf(szTemp, "%04x", hi.fmt); // SetDlgItemInt(hwnd, IDC_INSERTFMT, hi.fmt, TRUE); SetDlgItemText(hwnd, IDC_INSERTFMT, szTemp); } if (!pfr->NullpszText) { GlobalUnlock(hglb); GlobalFree(hglb); } /**** wsprintf(szTemp, szLongFilter, hwndFind) ; SetDlgItemText(hwnd, ID_INSERTRET, szTemp) ; **/ }
static LRESULT CALLBACK MainWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { PMAIN_WND_INFO Info; LRESULT Ret = 0; /* Get the window context */ Info = (PMAIN_WND_INFO)GetWindowLongPtr(hwnd, GWLP_USERDATA); if (Info == NULL && msg != WM_CREATE) { goto HandleDefaultMessage; } switch(msg) { case WM_CREATE: { Info = (PMAIN_WND_INFO)(((LPCREATESTRUCT)lParam)->lpCreateParams); /* Initialize the main window context */ Info->hMainWnd = hwnd; Info->SelectedItem = NO_ITEM_SELECTED; SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)Info); if (!InitMainWnd(Info)) return -1; /* Fill the list-view before showing the main window */ RefreshServiceList(Info); /* Show the window */ ShowWindow(hwnd, Info->nCmdShow); SetFocus(Info->hListView); } break; case WM_SIZE: { MainWndResize(Info, LOWORD(lParam), HIWORD(lParam)); } break; case WM_NOTIFY: { LPNMHDR pnmhdr = (LPNMHDR)lParam; switch (pnmhdr->code) { case NM_DBLCLK: { POINT pt; RECT rect; GetCursorPos(&pt); GetWindowRect(Info->hListView, &rect); if (PtInRect(&rect, pt)) { SendMessage(hwnd, WM_COMMAND, //ID_PROP, MAKEWPARAM((WORD)ID_PROP, (WORD)0), 0); } //OpenPropSheet(Info); } break; case NM_RETURN: { SendMessage(hwnd, WM_COMMAND, //ID_PROP, MAKEWPARAM((WORD)ID_PROP, (WORD)0), 0); } break; case LVN_COLUMNCLICK: { LPNMLISTVIEW pnmv = (LPNMLISTVIEW) lParam; HDITEM hdi; /* get pending sort direction for clicked column */ hdi.mask = HDI_LPARAM; (void)Header_GetItem(Info->hHeader, pnmv->iSubItem, &hdi); /* get new sort parameters */ Info->SortSelection = pnmv->iSubItem; Info->SortDirection = hdi.lParam; /* set new sort direction and save */ hdi.lParam = (hdi.lParam == ORD_ASCENDING) ? ORD_DESCENDING : ORD_ASCENDING; (void)Header_SetItem(Info->hHeader, pnmv->iSubItem, &hdi); (void)ListView_SortItemsEx(Info->hListView, CompareFunc, (LPARAM)Info); } break; case LVN_ITEMCHANGED: { LPNMLISTVIEW pnmv = (LPNMLISTVIEW) lParam; if (pnmv->uNewState != 0) { ListViewSelectionChanged(Info, pnmv); SetMenuAndButtonStates(Info); } } break; case TTN_GETDISPINFO: { LPTOOLTIPTEXT lpttt; UINT idButton; lpttt = (LPTOOLTIPTEXT)lParam; /* Specify the resource identifier of the descriptive * text for the given button. */ idButton = (UINT)lpttt->hdr.idFrom; switch (idButton) { case ID_PROP: lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_PROP); break; case ID_REFRESH: lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_REFRESH); break; case ID_EXPORT: lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_EXPORT); break; case ID_CREATE: lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_CREATE); break; case ID_DELETE: lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_DELETE); break; case ID_START: lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_START); break; case ID_STOP: lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_STOP); break; case ID_PAUSE: lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_PAUSE); break; case ID_RESTART: lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_RESTART); break; } } break; } } break; case WM_CONTEXTMENU: { POINT pt; RECT lvRect; INT xPos = GET_X_LPARAM(lParam); INT yPos = GET_Y_LPARAM(lParam); GetCursorPos(&pt); /* display popup when cursor is in the list view */ GetWindowRect(Info->hListView, &lvRect); if (PtInRect(&lvRect, pt)) { TrackPopupMenuEx(GetSubMenu(Info->hShortcutMenu, 0), TPM_RIGHTBUTTON, xPos, yPos, Info->hMainWnd, NULL); } } break; case WM_COMMAND: { MainWndCommand(Info, LOWORD(wParam), (HWND)lParam); goto HandleDefaultMessage; } case WM_MENUSELECT: { if (Info->hStatus != NULL) { if (!MainWndMenuHint(Info, LOWORD(wParam), MainMenuHintTable, sizeof(MainMenuHintTable) / sizeof(MainMenuHintTable[0]), IDS_HINT_BLANK)) { MainWndMenuHint(Info, LOWORD(wParam), SystemMenuHintTable, sizeof(SystemMenuHintTable) / sizeof(SystemMenuHintTable[0]), IDS_HINT_BLANK); } } } break; case WM_ENTERMENULOOP: { Info->bInMenuLoop = TRUE; UpdateMainStatusBar(Info); break; } case WM_EXITMENULOOP: { Info->bInMenuLoop = FALSE; UpdateMainStatusBar(Info); break; } case WM_CLOSE: { HeapFree(ProcessHeap, 0, Info->pAllServices); DestroyMenu(Info->hShortcutMenu); DestroyWindow(hwnd); } break; case WM_DESTROY: { HeapFree(ProcessHeap, 0, Info); SetWindowLongPtr(hwnd, GWLP_USERDATA, 0); PostQuitMessage(0); } break; default: { HandleDefaultMessage: Ret = DefWindowProc(hwnd, msg, wParam, lParam); } break; } return Ret; }
static BOOL ListView_Sort(HWND hListView, int iSortingColumn, int iSortedColumn) { if ( (GetWindowLongPtr(hListView, GWL_STYLE) & ~LVS_NOSORTHEADER) && (iSortingColumn >= 0) ) { BOOL bSortAscending; SORT_INFO SortInfo; HWND hHeader = ListView_GetHeader(hListView); HDITEM hColumn = {0}; /* If we are sorting according to another column, uninitialize the old one */ if ( (iSortedColumn >= 0) && (iSortingColumn != iSortedColumn) ) { hColumn.mask = HDI_FORMAT; Header_GetItem(hHeader, iSortedColumn, &hColumn); hColumn.fmt &= ~(HDF_SORTUP | HDF_SORTDOWN); Header_SetItem(hHeader, iSortedColumn, &hColumn); } /* Get the sorting state of the new column */ hColumn.mask = HDI_FORMAT; Header_GetItem(hHeader, iSortingColumn, &hColumn); /* * Check whether we are sorting the list because the user clicked * on a column, or because we are refreshing the list: * * iSortedColumn >= 0 - User clicked on a column; holds the * old sorting column index. * iSortedColumn < 0 - List being refreshed. */ if (iSortedColumn >= 0) { /* Invert the sorting direction */ bSortAscending = ((hColumn.fmt & HDF_SORTUP) == 0); } else { /* * If the sorting state of the column is uninitialized, * initialize it by default to ascending sorting. */ if ((hColumn.fmt & (HDF_SORTUP | HDF_SORTDOWN)) == 0) hColumn.fmt |= HDF_SORTUP; /* Keep the same sorting direction */ bSortAscending = ((hColumn.fmt & HDF_SORTUP) != 0); } /* Set the new column sorting state */ hColumn.fmt &= ~(bSortAscending ? HDF_SORTDOWN : HDF_SORTUP ); hColumn.fmt |= (bSortAscending ? HDF_SORTUP : HDF_SORTDOWN); Header_SetItem(hHeader, iSortingColumn, &hColumn); /* Sort the list */ SortInfo.iSortingColumn = iSortingColumn; SortInfo.bSortAscending = bSortAscending; return ListView_SortItems(hListView, CompareFunc, (LPARAM)&SortInfo); } else return TRUE; }