#include <Windows.h>#include <Windowsx.h>#include <CommCtrl.h>#include "resource.h"#ifdef _UNICODE#if defined _M_IX86#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")#elif defined _M_X64#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"")#else#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")#endif#endif// 向指定列表的指定位置添加指定列元素VOID InsertColumn(HWND hList, int nIndex, int nWidth = 0, LPCWSTR lpText = L"", int nFmt = LVCFMT_CENTER){ // 需要定义一个添加列必须用到的结构体,并[初始化其第一个字段 mask],表示哪一些字段是有效的 LV_COLUMN lvColumn = { LVCF_FMT | LVCF_TEXT | LVCF_WIDTH }; // 将用户传入的参数设置到结构体的指定字段中,对于添加的第一列数据,无论指定 // 什么对齐方式,始终都是左对齐的,如果希望全部居中,可以先添加一个空列。 lvColumn.fmt = nFmt; lvColumn.cx = nWidth; lvColumn.pszText = (LPWSTR)lpText; // 通过宏 ListView_InsertColumn 添加列 ListView_InsertColumn(hList, nIndex, &lvColumn);}// 向指定的列表中指定的行添加相应内容VOID InsertItem(HWND hList, int nRow, LPCWSTR lpName, LPCWSTR lpAge, LPCWSTR lpSchool){ // 初始化一个结构体,并设置第一个成员为想要应用的字段类型 LV_ITEM lvItem = { LVIF_TEXT }; // 设置当前需要添加到的是哪一个位置 lvItem.iItem = nRow; lvItem.iSubItem = 0; lvItem.pszText = (LPWSTR)L""; // 想要设置一行中字段的信息,必须要先添加一行 ListView_InsertItem(hList, &lvItem); // 在单独的使用宏 ListView_SetItemText 设置每一行中每一列的内容 ListView_SetItemText(hList, nRow, 1, (LPWSTR)lpName); ListView_SetItemText(hList, nRow, 2, (LPWSTR)lpAge); ListView_SetItemText(hList, nRow, 3, (LPWSTR)lpSchool);}// 对话框的回调函数,消息处理了返回 TRUE,没有处理返回 FALSEINT_PTR CALLBACK DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam){ switch (uMsg) { // 当用户点击了关闭按钮时产生的消息,对话框要求必须使用 EndDialog 退出 case WM_CLOSE: { EndDialog(hDlg, 0); break; } // 对话框的初始化消息是 WM_INITDIALOG,常用于进行控件的初始化 case WM_INITDIALOG: { // 获取到列表控件的句柄 HWND hList = GetDlgItem(hDlg, IDC_LIST1); // 为列表添加扩展风格,支持更多操作 ListView_SetExtendedListViewStyle(hList, LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES); // 对于列表控件的报表风格,想要添加内容,最少需要有一列数据,所以先添加列 InsertColumn(hList, 0); InsertColumn(hList, 1, 120, L"姓名", LVCFMT_CENTER); InsertColumn(hList, 2, 50, L"年龄", LVCFMT_CENTER); InsertColumn(hList, 3, 250, L"学校", LVCFMT_CENTER); // 在添加了列之后,添加每一行的信息 InsertItem(hList, 0, L"小明", L"18", L"北京大学"); InsertItem(hList, 1, L"小红", L"17", L"清华大学"); InsertItem(hList, 2, L"小刚", L"19", L"野鸡大学"); break; } // 列表控件是一个通用控件,需要通过 WM_NOTIFY 进行相应 case WM_NOTIFY: { // WM_NOTIFY 的附加参数 lParam 指向的是结构体 NMHDR,保存了更多内容 auto pNmhdr = (LPNMHDR)lParam; // 判断当前的消息是不是由列表控件产生的 if (pNmhdr->idFrom == IDC_LIST1) { // 如果当前是列表控件,那么 lParam 指向的实际上是 NMLISTVIEW auto pNmListView = (LPNMLISTVIEW)lParam; // 筛选行为,只有在鼠标左键点击的时候才相应,弹出点击的内容 if (pNmhdr->code == NM_CLICK && pNmListView->iItem != -1) { WCHAR lpBuffer[0x100]{}; ListView_GetItemText(pNmhdr->hwndFrom, pNmListView->iItem, pNmListView->iSubItem, lpBuffer, 0x100); MessageBox(hDlg, lpBuffer, lpBuffer, MB_OK); } // 筛选行为,只有在鼠标右键点击的时候才相应,弹出点击的内容 if (pNmhdr->code == NM_RCLICK && pNmListView->iItem != -1) { // 1. 获取当前光标的位置,获取的是相对屏幕的,不用转换 POINT Point{}; GetCursorPos(&Point); // 2. 找到菜单资源 HMENU hMenu = LoadMenu(GetModuleHandle(NULL), MAKEINTRESOURCE(IDR_MENU1)); HMENU hSubMenu = GetSubMenu(hMenu, 0); // 3. 弹出菜单 TrackPopupMenu(hSubMenu, TPM_LEFTALIGN, Point.x, Point.y, 0, hDlg, NULL); } } break; } default: { return FALSE; } } return TRUE;}int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){ // 1. 是实例句柄,用于标识资源所在的位置 // 2. 资源的ID,大多数时候会使用 MAKEINTRESOURCE 进行转换 // 3. 对话框的父窗口,NULL 表示桌面 // 4. 回调函数,用于响应对话框产生的所有消息 DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, DlgProc); return 0;}
