#include <Windows.h>
#include <CommCtrl.h>
#include <windowsx.h>
#include "resource.h"
/**
通用控件 需要捕获notify消息
WM_NOTIFY 消息
当事件发生或控件需要一些信息时,由公共控件发送到其父窗口。
参数
wParam
发送消息的公共控件的标识符。 不保证此标识符是唯一的。
应用程序应使用 NMHDR 结构的 hwndFrom 或 idFrom 成员 (作为 lParam 参数传递) 来标识控件。
lParam
指向包含通知代码和其他信息的 NMHDR 结构的指针。 对于某些通知消息,此参数指向将 NMHDR
结构作为其第一个成员的较大结构。扩展:获取更详细的列表通知信息 LVM_GETITEMTEXTW
当通知码是LVN_xxx(列表专属)时,lParam可强转为NMLISTVIEW结构体(包含项索引、列索引、状态等):
typedef struct tagNMLISTVIEW {NMHDR hdr; // 基础NMHDR结构体int iItem; // 项索引(-1表示无)int iSubItem; // 列索引UINT uNewState; // 新状态UINT uOldState; // 旧状态UINT uChanged; // 变化的状态类型POINT ptAction; // 操作的坐标LPARAM lParam; // 项关联的自定义数据
} NMLISTVIEW, *LPNMLISTVIEW;
*/
void CenterWindow(HWND hWnd);
void SetWindowG(HWND hwnd, int width, int height);
INT_PTR CALLBACK Dlgproc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);BOOL InsertColum(HWND hwnd,int nIDDlgItem,int nColum,LPWSTR columName, int columWidth);
BOOL InsertItem(HWND hwnd, int nIDDlgItem, int nRow);
BOOL SetListItemText(HWND hwnd, int nIDDlgItem, int nRow, int nColumn, LPWSTR columnName);int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{DialogBoxW(hInstance, MAKEINTRESOURCEW(IDD_DIALOG1), NULL, Dlgproc);return 0;
}INT_PTR CALLBACK Dlgproc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam
)
{switch (uMsg){case WM_INITDIALOG:{SetWindowG(hwnd, 800, 530);ListView_SetExtendedListViewStyle(GetDlgItem(hwnd,IDC_LIST1),LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES);InsertColum(hwnd, IDC_LIST1, 0, (LPWSTR)L"", 0);InsertColum(hwnd, IDC_LIST1, 1, (LPWSTR)L"映像名称", 80);InsertColum(hwnd, IDC_LIST1, 2, (LPWSTR)L"用户名", 120);InsertColum(hwnd, IDC_LIST1, 3, (LPWSTR)L"CPU", 120);InsertColum(hwnd, IDC_LIST1, 4, (LPWSTR)L"描述", 120);//插入一行InsertItem(hwnd, IDC_LIST1, 0);SetListItemText(hwnd, IDC_LIST1, 0,0,(LPWSTR)L"");SetListItemText(hwnd, IDC_LIST1, 0, 1, (LPWSTR)L"11");SetListItemText(hwnd, IDC_LIST1, 0, 2, (LPWSTR)L"22");SetListItemText(hwnd, IDC_LIST1, 0, 3, (LPWSTR)L"33");InsertItem(hwnd, IDC_LIST1, 1);SetListItemText(hwnd, IDC_LIST1, 1, 0, (LPWSTR)L"");SetListItemText(hwnd, IDC_LIST1, 1, 1, (LPWSTR)L"1111");SetListItemText(hwnd, IDC_LIST1, 1, 2, (LPWSTR)L"2222");SetListItemText(hwnd, IDC_LIST1, 1, 3, (LPWSTR)L"3333");//LVITEMW lvitem = { LVIF_TEXT,0 };////lvitem.iItem = 0;//lvitem.pszText = (LPWSTR)L"123.EXE";//SendDlgItemMessageW(hwnd, IDC_LIST1, LVM_INSERTITEM,0, (LONG)&lvitem);/*lvitem.iSubItem = 1;lvitem.pszText = (LPWSTR)L"3333123.EXE";SendDlgItemMessageW(hwnd, IDC_LIST1, LVM_SETITEMTEXTW, 0, (LONG)&lvitem);lvitem.iSubItem = 2;lvitem.pszText = (LPWSTR)L"7777123.EXE";SendDlgItemMessageW(hwnd, IDC_LIST1, LVM_SETITEMTEXTW, 0, (LONG)&lvitem);*/break;}case WM_NOTIFY:{/**WM_NOTIFY的lParam并非控件句柄,而是指向NMHDR结构体的指针(包含通知源、通知类型等核心信息),你直接用(HWND)lParam判断控件句柄会导致逻辑完全错误。typedef struct tagNMHDR {HWND hwndFrom; // 发送通知的控件句柄(对应IDC_LIST1)UINT idFrom; // 发送通知的控件ID(IDC_LIST1)UINT code; // 具体的通知码(如列表控件的LVN_ITEMCHANGED、NM_CLICK等)} NMHDR, *LPNMHDR;如果消息来源是list控件,那么lparam 指向的是一个完整的结构体指针*/// 第一步:取出NMHDR结构体指针(核心)LPNMHDR pNmhdr = (LPNMHDR)lParam;// 第二步:判断通知是否来自IDC_LIST1/*if (pNmhdr->hwndFrom == GetDlgItem(hwnd, IDC_LIST1)) {*/NMLISTVIEW* lNmlistView = (NMLISTVIEW*)lParam;if (wParam == IDC_LIST1 && lNmlistView->iItem != -1) {// 第三步:根据不同通知码处理具体逻辑switch (pNmhdr->code) {// 示例1:列表项被点击case NM_CLICK:{//MessageBoxW(hwnd, L"列表控件被点击", L"提示", MB_OK);WCHAR buff[100] = { 0 };LVITEMW lvitem = { 0 };lvitem.iSubItem = lNmlistView->iSubItem;lvitem.pszText = buff;lvitem.cchTextMax = 100;SendDlgItemMessageW(hwnd, wParam, LVM_GETITEMTEXTW, lNmlistView->iItem, (LPARAM)&lvitem);MessageBoxW(hwnd, lvitem.pszText, L"提示", MB_OK);break;}case NM_RCLICK: {POINT point = {0};GetCursorPos(&point);HMENU hMenu = LoadMenuW(GetModuleHandleW(0), MAKEINTRESOURCE(IDR_MENU1));HMENU hSubMenu = GetSubMenu(hMenu,0);TrackPopupMenu(hSubMenu, TPM_LEFTALIGN,point.x, point.y,0,hwnd,NULL);break;}default:break;}}break;}case WM_HSCROLL:{break;}case WM_VSCROLL:{break;}case WM_CLOSE:EndDialog(hwnd, 0);break;default:return FALSE;break;}return TRUE;}// 居中函数
void CenterWindow(HWND hWnd)
{RECT rc;GetWindowRect(hWnd, &rc);int width = rc.right - rc.left;int height = rc.bottom - rc.top;int screenWidth = GetSystemMetrics(SM_CXSCREEN);int screenHeight = GetSystemMetrics(SM_CYSCREEN);SetWindowPos(hWnd, NULL,(screenWidth - width) / 2,(screenHeight - height) / 2,0, 0, SWP_NOZORDER | SWP_NOSIZE);
}
void SetWindowG(HWND hwnd, int width, int height)
{// DPI自适应UINT dpi = GetDpiForWindow(hwnd);int baseWidth = width;int baseHeight = height;int scaledWidth = MulDiv(baseWidth, dpi, 96);int scaledHeight = MulDiv(baseHeight, dpi, 96);SetWindowPos(hwnd, NULL, 0, 0, scaledWidth, scaledHeight,SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE);// 居中显示CenterWindow(hwnd);
}BOOL InsertColum(HWND hwnd, int nIDDlgItem, int nColum, LPWSTR columName,int columWidth)
{LVCOLUMNW lvColum = {LVCF_FMT | LVCF_WIDTH | LVCF_TEXT};lvColum.fmt = LVCFMT_CENTER;lvColum.cx = columWidth;lvColum.pszText = columName;SendDlgItemMessageW(hwnd, nIDDlgItem, LVM_INSERTCOLUMN, nColum, (LONG)&lvColum);return TRUE;
}
BOOL InsertItem(HWND hwnd, int nIDDlgItem, int nRow)
{LVITEMW lvitem = { LVIF_TEXT,nRow };//lvitem.iItem = 0;lvitem.pszText = (LPWSTR)L"";SendDlgItemMessageW(hwnd, nIDDlgItem, LVM_INSERTITEM, nRow, (LONG)&lvitem);return TRUE;
}
BOOL SetListItemText(HWND hwnd, int nIDDlgItem, int nRow, int nColumn, LPWSTR columnName)
{LVITEMW lvitem = { LVIF_TEXT,nRow,nColumn };//lvitem.iSubItem = nColumn;lvitem.pszText = columnName;SendDlgItemMessageW(hwnd, nIDDlgItem, LVM_SETITEMTEXTW, nRow, (LONG)&lvitem);return TRUE;}