// XListCtrlTestDlg.cpp : implementation file // #include "stdafx.h" #include "XListCtrlTest.h" #include "XListCtrlTestDlg.h" #include "about.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif /////////////////////////////////////////////////////////////////////////////// // CXListCtrlTestDlg dialog BEGIN_MESSAGE_MAP(CXListCtrlTestDlg, CDialog) //{{AFX_MSG_MAP(CXListCtrlTestDlg) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_WM_TIMER() ON_BN_CLICKED(IDC_BUTTON1, OnButton1) ON_WM_DESTROY() ON_NOTIFY(NM_CLICK, IDC_LIST, OnClick) ON_NOTIFY(NM_DBLCLK, IDC_LIST, OnDblClick) ON_NOTIFY(LVN_COLUMNCLICK, IDC_LIST, OnColumnClick) ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST, OnItemChanged) ON_BN_CLICKED(IDC_CLEAR, OnClear) ON_BN_CLICKED(IDC_BUTTON2, OnButton2) ON_BN_CLICKED(IDC_CHECK1, OnGridlines) //}}AFX_MSG_MAP ON_REGISTERED_MESSAGE(WM_XLISTCTRL_COMBO_SELECTION, OnComboSelection) ON_REGISTERED_MESSAGE(WM_XLISTCTRL_CHECKBOX_CLICKED, OnCheckbox) ON_REGISTERED_MESSAGE(WM_XLISTCTRL_EDIT_END, OnEditEnd) END_MESSAGE_MAP() /////////////////////////////////////////////////////////////////////////////// // ctor CXListCtrlTestDlg::CXListCtrlTestDlg(CWnd* pParent /*=NULL*/) : CDialog(CXListCtrlTestDlg::IDD, pParent) { //{{AFX_DATA_INIT(CXListCtrlTestDlg) m_bGridlines = FALSE; //}}AFX_DATA_INIT m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); m_bRunning = FALSE; m_bGridlines = TRUE; } /////////////////////////////////////////////////////////////////////////////// // DoDataExchange void CXListCtrlTestDlg::DoDataExchange(CDataExchange* pDX) { /////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// // // comment out the DDX_Control line to create CXListCtrl dynamically - // remember also to include lines in OnInitDialog to create CXListCtrl, // and remove the list control from IDD_LISTCTRLTEST_DIALOG in the rc file // /////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CXListCtrlTestDlg) DDX_Control(pDX, IDC_LOG, m_Log); DDX_Control(pDX, IDC_LIST, m_List); // comment out this line if creating dynamically DDX_Check(pDX, IDC_CHECK1, m_bGridlines); //}}AFX_DATA_MAP } /////////////////////////////////////////////////////////////////////////////// // OnInitDialog BOOL CXListCtrlTestDlg::OnInitDialog() { TRACE(_T("in CXListCtrlTestDlg::OnInitDialog\n")); CDialog::OnInitDialog(); // Add "About..." menu item to system menu. // IDM_ABOUTBOX must be in the system command range. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { CString strAboutMenu; strAboutMenu.LoadString(IDS_ABOUTBOX); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon /////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// // // include the following lines to create CXListCtrl dynamically - // remember also to comment out DDX line, and remove the list control // from IDD_LISTCTRLTEST_DIALOG in the rc file // /////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// #if 0 // ----------------------------------------------------------- DWORD dwStyle = LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | WS_CHILD | WS_VISIBLE | WS_GROUP | WS_TABSTOP; CRect rect, rectbutton; GetClientRect(&rect); GetDlgItem(IDC_BUTTON1)->GetClientRect(&rectbutton); rect.DeflateRect(5, 5); rect.top = rectbutton.bottom + 15; TRACE(" calling CreateEx\n"); // you may also use Create(), but I prefer WS_EX_CLIENTEDGE style VERIFY(m_List.CreateEx(WS_EX_CLIENTEDGE, _T("SysListView32"), _T(""), dwStyle, rect, this, IDC_LIST, NULL)); CFont *pFont = GetFont(); if (pFont) m_List.SetFont(pFont); #endif // ----------------------------------------------------------- // XListCtrl must have LVS_EX_FULLROWSELECT if combo or edit boxes are used DWORD dwExStyle = LVS_EX_FULLROWSELECT /*| LVS_EX_TRACKSELECT*/; // for hot tracking if (m_bGridlines) dwExStyle |= LVS_EX_GRIDLINES; m_List.SetExtendedStyle(dwExStyle); // call EnableToolTips to enable tooltip display m_List.EnableToolTips(TRUE); InitListCtrl(&m_List); return TRUE; // return TRUE unless you set the focus to a control } /////////////////////////////////////////////////////////////////////////////// // OnSysCommand void CXListCtrlTestDlg::OnSysCommand(UINT nID, LPARAM lParam) { if ((nID & 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlg; dlg.DoModal(); } else { CDialog::OnSysCommand(nID, lParam); } } /////////////////////////////////////////////////////////////////////////////// // OnPaint void CXListCtrlTestDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // device context for painting SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); // Center icon in client rectangle int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // Draw the icon dc.DrawIcon(x, y, m_hIcon); } else { CDialog::OnPaint(); } } /////////////////////////////////////////////////////////////////////////////// // OnQueryDragIcon HCURSOR CXListCtrlTestDlg::OnQueryDragIcon() { return (HCURSOR) m_hIcon; } /////////////////////////////////////////////////////////////////////////////// // OnTimer void CXListCtrlTestDlg::OnTimer(UINT nIDEvent) { static int nPct = 0; static int nItem = -1; static int nBlink = 0; if (nIDEvent == 1) { KillTimer(nIDEvent); m_List.SetProgress(1, 2); nPct = 0; SetTimer(2, 80, NULL); SetTimer(4, 400, NULL); } else if (nIDEvent == 2) { nPct += 10; m_List.UpdateProgress(1, 2, nPct); if (nPct >= 100) { KillTimer(nIDEvent); SetTimer(3, 2000, NULL); } } else if (nIDEvent == 3) { CString str; str = m_List.GetComboText(0, 2); KillTimer(nIDEvent); m_List.DeleteProgress(1, 2); SetTimer(1, 2000, NULL); } else if (nIDEvent == 4) { if (nItem != -1) { // remove previous color & bold from columns 1 and 5 m_List.SetItemText(nItem, 5, NULL, (COLORREF)-1, (COLORREF)-1); m_List.SetBold(nItem, 1, FALSE); } // blink item 3 if (nItem == 3) { nBlink++; if (nBlink >= 12) { nBlink = 0; nItem++; m_List.SetItemText(nItem, 5, NULL, RGB(255,255,255), RGB(255,0,0)); m_List.SetBold(nItem, 1, TRUE); } else { if (nBlink & 1) // blink every other time { m_List.SetItemText(nItem, 5, NULL, RGB(255,255,255), RGB(255,0,0)); m_List.SetBold(nItem, 1, TRUE); } } } else { nItem++; if (nItem >= 10) nItem = 0; m_List.SetItemText(nItem, 5, NULL, RGB(255,255,255), RGB(255,0,0)); m_List.SetBold(nItem, 1, TRUE); } } CDialog::OnTimer(nIDEvent); } /////////////////////////////////////////////////////////////////////////////// // OnButton1 void CXListCtrlTestDlg::OnButton1() { if (m_bRunning) { GetDlgItem(IDC_BUTTON1)->EnableWindow(FALSE); KillTimer(1); KillTimer(2); KillTimer(3); KillTimer(4); m_bRunning = FALSE; GetDlgItem(IDC_BUTTON1)->SetWindowText(_T("Start")); GetDlgItem(IDC_BUTTON1)->EnableWindow(TRUE); } else { GetDlgItem(IDC_BUTTON1)->EnableWindow(FALSE); FillListCtrl(&m_List); // show a disabled item m_List.SetEnabled(5, FALSE); m_List.SetItemText(5, 1, _T("This row is disabled")); #if 0 // ----------------------------------------------------------- // demonstrate handling of WM_SYSCOLORCHANGE int nElement = COLOR_WINDOW; COLORREF crWindow = ::GetSysColor(nElement); if (::SetSysColors(1, // number of elements &nElement, // array of elements &crWindow)) // array of RGB values { TRACE(_T("SetSysColors ok\n")); } else { TRACE(_T("SetSysColors failed\n")); } #endif // ----------------------------------------------------------- SetTimer(1, 1000, NULL); m_bRunning = TRUE; GetDlgItem(IDC_BUTTON1)->SetWindowText(_T("Stop")); GetDlgItem(IDC_BUTTON1)->EnableWindow(TRUE); } } /////////////////////////////////////////////////////////////////////////////// // OnButton2 - mark all subitems as unmodified void CXListCtrlTestDlg::OnButton2() { m_List.SetListModified(FALSE); for (int nItem = 0; nItem < m_List.GetItemCount(); nItem++) { for (int nSubItem = 0; nSubItem < m_List.GetColumns(); nSubItem++) { m_List.SetModified(nItem, nSubItem, FALSE); COLORREF crText, crBackground; m_List.GetItemColors(nItem, nSubItem, crText, crBackground); m_List.SetItemColors(nItem, nSubItem, RGB(0,0,0), crBackground); // is this a checkbox? if (m_List.GetItemCheckedState(nItem, nSubItem) != -1) { if (nSubItem == 0) m_List.SetItemText(nItem, nSubItem, _T(" ")); // erase * else m_List.SetItemText(nItem, nSubItem, _T("OK")); } } } m_List.RedrawWindow(); CString strCaption = _T(""); strCaption.LoadString(AFX_IDS_APP_TITLE); SetWindowText(strCaption); } /////////////////////////////////////////////////////////////////////////////// // OnClear - clear m_Log listbox void CXListCtrlTestDlg::OnClear() { m_Log.ResetContent(); } /////////////////////////////////////////////////////////////////////////////// // OnGridlines void CXListCtrlTestDlg::OnGridlines() { UpdateData(TRUE); DWORD dwExStyle = m_List.GetExtendedStyle(); if (m_bGridlines) dwExStyle |= LVS_EX_GRIDLINES; else dwExStyle &= ~LVS_EX_GRIDLINES; m_List.SetExtendedStyle(dwExStyle); } /////////////////////////////////////////////////////////////////////////////// // OnDestroy void CXListCtrlTestDlg::OnDestroy() { KillTimer(1); KillTimer(2); KillTimer(3); KillTimer(4); CDialog::OnDestroy(); } /////////////////////////////////////////////////////////////////////////////// // OnClick // // This method shows how to handle NM_CLICK messages from XListCtrl // void CXListCtrlTestDlg::OnClick(NMHDR* pNMHDR, LRESULT* pResult) { LPNMITEMACTIVATE pNMIA = reinterpret_cast(pNMHDR); int nItem = -1; int nSubItem = -1; if (pNMIA) { nItem = pNMIA->iItem; nSubItem = pNMIA->iSubItem; } if (nItem >= 0 && nSubItem >= 0) { CString strText = m_List.GetItemText(nItem, nSubItem); Log(_T("OnClick at (%d,%d): '%s'"), nItem, nSubItem, strText); } *pResult = 0; } /////////////////////////////////////////////////////////////////////////////// // OnDblClick // // This method shows how to handle NM_DBLCLK messages from XListCtrl // void CXListCtrlTestDlg::OnDblClick(NMHDR* pNMHDR, LRESULT* pResult) { LPNMITEMACTIVATE pNMIA = reinterpret_cast(pNMHDR); int nItem = -1; int nSubItem = -1; if (pNMIA) { nItem = pNMIA->iItem; nSubItem = pNMIA->iSubItem; } if (nItem >= 0 && nSubItem >= 0) { CString strText = m_List.GetItemText(nItem, nSubItem); Log(_T("OnDblClick at (%d,%d): '%s'"), nItem, nSubItem, strText); } *pResult = 0; } /////////////////////////////////////////////////////////////////////////////// // OnColumnClick // // This method shows how to handle LVN_COLUMNCLICK messages from XListCtrl // void CXListCtrlTestDlg::OnColumnClick(NMHDR* pNMHDR, LRESULT* pResult) { LPNMLISTVIEW pNMLV = reinterpret_cast(pNMHDR); int nItem = -1; int nSubItem = -1; if (pNMLV) { nItem = pNMLV->iItem; nSubItem = pNMLV->iSubItem; } Log(_T("OnColumnClick on column %d"), nSubItem); CString strCaption = _T(""); strCaption.LoadString(AFX_IDS_APP_TITLE); strCaption += _T(" *"); SetWindowText(strCaption); *pResult = 0; } /////////////////////////////////////////////////////////////////////////////// // OnItemChanged // // This method shows how to handle LVN_ITEMCHANGED messages from XListCtrl // void CXListCtrlTestDlg::OnItemChanged(NMHDR* pNMHDR, LRESULT* pResult) { LPNMLISTVIEW pNMLV = reinterpret_cast(pNMHDR); int nItem = -1; int nSubItem = -1; if (pNMLV) { nItem = pNMLV->iItem; nSubItem = pNMLV->iSubItem; } //TRACE(_T("in CXListCtrlTestDlg::OnItemChanged: %d, %d\n"), nItem, nSubItem); if (pNMLV && (pNMLV->uNewState == (UINT)(LVIS_FOCUSED|LVIS_SELECTED))) { CString strText = m_List.GetItemText(nItem, nSubItem); Log(_T("Selection changed to item %d"), nItem); } *pResult = 0; } /////////////////////////////////////////////////////////////////////////////// // OnEditEnd // // This method shows how to handle WM_XLISTCTRL_EDIT_END messages // from XListCtrl // LRESULT CXListCtrlTestDlg::OnEditEnd(WPARAM nItem, LPARAM nSubItem) { if (nItem >= 0 && nSubItem >= 0) { CString strText = m_List.GetItemText(nItem, nSubItem); Log(_T("OnEditEnd at (%d,%d): '%s'"), nItem, nSubItem, strText); COLORREF crText, crBackground; m_List.GetItemColors(nItem, nSubItem, crText, crBackground); if (m_List.GetModified(nItem, nSubItem)) { // subitem was modified - color it red m_List.SetItemText(nItem, nSubItem, strText, RGB(255,0,0), crBackground); CString strCaption = _T(""); strCaption.LoadString(AFX_IDS_APP_TITLE); strCaption += _T(" *"); SetWindowText(strCaption); } else { // subitem not modified - color it black - // note that once modified, a subitem will remain // marked as modified m_List.SetItemText(nItem, nSubItem, strText, RGB(0,0,0), crBackground); } } return 0; } /////////////////////////////////////////////////////////////////////////////// // OnComboSelection // // This method shows how to handle WM_XLISTCTRL_COMBO_SELECTION messages // from XListCtrl // LRESULT CXListCtrlTestDlg::OnComboSelection(WPARAM nItem, LPARAM nSubItem) { if (nItem >= 0 && nSubItem >= 0) { CString strText = m_List.GetItemText(nItem, nSubItem); Log(_T("OnComboSelection at (%d,%d): '%s'"), nItem, nSubItem, strText); COLORREF crText, crBackground; m_List.GetItemColors(nItem, nSubItem, crText, crBackground); if (m_List.GetModified(nItem, nSubItem)) { // subitem was modified - color it red m_List.SetItemText(nItem, nSubItem, strText, RGB(255,0,0), crBackground); CString strCaption = _T(""); strCaption.LoadString(AFX_IDS_APP_TITLE); strCaption += _T(" *"); SetWindowText(strCaption); } else { // subitem not modified - color it black - // note that once modified, a subitem will remain // marked as modified m_List.SetItemText(nItem, nSubItem, strText, RGB(0,0,0), crBackground); } } return 0; } /////////////////////////////////////////////////////////////////////////////// // OnCheckbox // // This method shows how to handle WM_XLISTCTRL_CHECKBOX_CLICKED messages // from XListCtrl // LRESULT CXListCtrlTestDlg::OnCheckbox(WPARAM nItem, LPARAM nSubItem) { if (nItem >= 0 && nSubItem >= 0) { Log(_T("OnCheckbox at (%d,%d)"), nItem, nSubItem); COLORREF crText, crBackground; m_List.GetItemColors(nItem, nSubItem, crText, crBackground); if (m_List.GetModified(nItem, nSubItem)) { // subitem was modified - color it red if (nSubItem == 0) m_List.SetItemText(nItem, nSubItem, _T("*"), RGB(255,0,0), crBackground); else m_List.SetItemText(nItem, nSubItem, _T("Error"), RGB(255,0,0), crBackground); CString strCaption = _T(""); strCaption.LoadString(AFX_IDS_APP_TITLE); strCaption += _T(" *"); SetWindowText(strCaption); } else { // subitem not modified - color it black - // note that once modified, a subitem will remain // marked as modified if (nSubItem == 0) m_List.SetItemText(nItem, nSubItem, _T(" "), RGB(0,0,0), crBackground); else m_List.SetItemText(nItem, nSubItem, _T("OK"), RGB(255,0,0), crBackground); } } return 0; } /////////////////////////////////////////////////////////////////////////////// // Log - log a message to the m_Log listbox void _cdecl CXListCtrlTestDlg::Log(LPCTSTR lpszFmt, ...) { ASSERT(lpszFmt); TCHAR buf[2000], fmt[2000]; va_list marker; // format string was passed as parameter _tcsncpy(fmt, lpszFmt, sizeof(fmt)/sizeof(TCHAR)-1); fmt[sizeof(fmt)/sizeof(TCHAR)-1] = _T('\0'); // combine output string and variables va_start(marker, lpszFmt); _vsntprintf(buf, (sizeof(buf)/sizeof(TCHAR))-1, fmt, marker); va_end(marker); buf[sizeof(buf)/sizeof(TCHAR)-1] = _T('\0'); CString strMsg(buf); // don't display \r or \n characters int i = 0; while ((i = strMsg.FindOneOf(_T("\r\n"))) != -1) strMsg.SetAt(i, _T(' ')); i = m_Log.AddString(strMsg); TRACE(_T("%s\n"), strMsg); // scroll into view if (i >= 0) { m_Log.SetTopIndex(i); } m_Log.SetCurSel(-1); }