#include <windows.h>
#include <commctrl.h>
#include <stdio.h>
#include <stdlib.h>
#pragma comment(lib, "comctl32.lib")
// 防止重复定义
#ifdef NMLISTVIEW
#undef NMLISTVIEW
#endif
#ifdef LPNMLISTVIEW
#undef LPNMLISTVIEW
#endif
#ifdef LVN_BEGINDRAGCOLUMN
#undef LVN_BEGINDRAGCOLUMN
#endif
#ifdef HDS_DRAGDROP
#undef HDS_DRAGDROP
#endif
#ifdef HDM_SETEXTENDEDSTYLE
#undef HDM_SETEXTENDEDSTYLE
#endif
#ifdef LVS_EX_GRIDLINES
#undef LVS_EX_GRIDLINES
#endif
#ifdef LVS_EX_FULLROWSELECT
#undef LVS_EX_FULLROWSELECT
#endif
// 自定义常量和结构体定义
#define CUSTOM_IDD_MAIN_DIALOG 1000
#define CUSTOM_ID_LISTVIEW 1001
#define CUSTOM_ID_START_BUTTON 1002
#define CUSTOM_ID_CANCEL_BUTTON 1003
#define CUSTOM_HDS_DRAGDROP 0x0040
#define CUSTOM_LVN_BEGINDRAGCOLUMN (0xffff0000 | 20) // 自定义值
#define CUSTOM_HDM_SETEXTENDEDSTYLE (0x1200 + 22) // 自定义值
#define CUSTOM_LVS_EX_GRIDLINES 0x00000001
#define CUSTOM_LVS_EX_FULLROWSELECT 0x00000020
// 自定义NM_LISTVIEW结构
typedef struct _CUSTOM_NM_LISTVIEW {
NMHDR hdr;
int iItem;
int iSubItem;
UINT uNewState;
UINT uOldState;
UINT uChanged;
POINT ptAction;
LPARAM lParam;
} CUSTOM_NM_LISTVIEW, * LPCUSTOM_NM_LISTVIEW;
// 全局变量
HWND g_hListView = NULL;
// 函数声明
LRESULT CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
BOOL EnableListViewDragColumns();
void InitializeListView();
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
// 初始化通用控件
INITCOMMONCONTROLSEX icex;
icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
icex.dwICC = ICC_LISTVIEW_CLASSES;
InitCommonControlsEx(&icex);
// 注册自定义窗口类来替代对话框
WNDCLASSEX wc = { 0 };
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = DialogProc;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
wc.lpszClassName = L"CustomTableDialog";
RegisterClassEx(&wc);
// 创建主窗口
HWND hwnd = CreateWindowEx(
0, L"CustomTableDialog", L"表格对话框程序 - List Control版",
WS_OVERLAPPEDWINDOW & ~WS_THICKFRAME & ~WS_MAXIMIZEBOX,
CW_USEDEFAULT, CW_USEDEFAULT, 600, 450,
NULL, NULL, hInstance, NULL
);
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
// 消息循环
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int)msg.wParam;
}
// 窗口过程(替代对话框过程)
LRESULT CALLBACK DialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
static HWND hStartBtn = NULL;
static HWND hCancelBtn = NULL;
switch (uMsg)
{
case WM_CREATE:
{
// 创建List View控件
g_hListView = CreateWindow(WC_LISTVIEW, L"",
WS_CHILD | WS_VISIBLE | WS_BORDER | LVS_REPORT | LVS_EDITLABELS,
20, 20, 440, 220,
hwnd, (HMENU)CUSTOM_ID_LISTVIEW, GetModuleHandle(NULL), NULL);
// 设置扩展样式
ListView_SetExtendedListViewStyle(g_hListView,
CUSTOM_LVS_EX_GRIDLINES | CUSTOM_LVS_EX_FULLROWSELECT);
// 初始化列表视图
InitializeListView();
// 启用列拖拽功能
EnableListViewDragColumns();
// 创建开始按钮
hStartBtn = CreateWindow(L"BUTTON", L"开始",
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
150, 260, 80, 30,
hwnd, (HMENU)CUSTOM_ID_START_BUTTON, GetModuleHandle(NULL), NULL);
// 创建取消按钮
hCancelBtn = CreateWindow(L"BUTTON", L"取消",
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
270, 260, 80, 30,
hwnd, (HMENU)CUSTOM_ID_CANCEL_BUTTON, GetModuleHandle(NULL), NULL);
// 设置字体
HFONT hFont = CreateFont(14, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE,
DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
DEFAULT_PITCH | FF_DONTCARE, L"微软雅黑");
if (hFont)
{
SendMessage(hStartBtn, WM_SETFONT, (WPARAM)hFont, TRUE);
SendMessage(hCancelBtn, WM_SETFONT, (WPARAM)hFont, TRUE);
SendMessage(g_hListView, WM_SETFONT, (WPARAM)hFont, TRUE);
}
// 创建标题栏按钮
CreateWindow(L"BUTTON", L"确定",
WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON,
360, 260, 80, 30,
hwnd, (HMENU)IDOK, GetModuleHandle(NULL), NULL);
return 0;
}
case WM_COMMAND:
{
switch (LOWORD(wParam))
{
case CUSTOM_ID_START_BUTTON:
MessageBox(hwnd, L"点击了开始按钮!\n这是使用List Control实现的表格。",
L"提示", MB_OK | MB_ICONINFORMATION);
break;
case CUSTOM_ID_CANCEL_BUTTON:
MessageBox(hwnd, L"点击了取消按钮!\n可以关闭程序或执行其他操作。",
L"提示", MB_OK | MB_ICONINFORMATION);
break;
case IDOK:
case IDCANCEL:
DestroyWindow(hwnd);
return 0;
}
break;
}
case WM_NOTIFY:
{
LPNMHDR lpnmh = (LPNMHDR)lParam;
if (lpnmh->idFrom == CUSTOM_ID_LISTVIEW)
{
// 处理ListView通知
if (lpnmh->code == NM_CLICK)
{
// 处理点击事件
}
}
break;
}
case WM_SIZE:
{
// 窗口大小改变时调整控件大小
RECT rc;
GetClientRect(hwnd, &rc);
if (g_hListView)
{
MoveWindow(g_hListView, 20, 20, rc.right - 40, rc.bottom - 100, TRUE);
}
if (hStartBtn && hCancelBtn)
{
int btnY = rc.bottom - 60;
int centerX = (rc.right - 40) / 2;
MoveWindow(hStartBtn, centerX - 90, btnY, 80, 30, TRUE);
MoveWindow(hCancelBtn, centerX + 10, btnY, 80, 30, TRUE);
}
break;
}
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
// 初始化ListView - 使用安全的字符串处理
void InitializeListView()
{
if (!g_hListView) return;
// 清空现有列和数据
ListView_DeleteAllItems(g_hListView);
// 删除所有列
while (ListView_DeleteColumn(g_hListView, 0)) {}
// 添加列 - 使用动态分配避免const问题
const wchar_t* columnNames[] = {
L"列1", L"列2", L"列3", L"列4", L"列5"
};
for (int i = 0; i < 5; i++)
{
LVCOLUMN lvc = { 0 };
lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
lvc.fmt = LVCFMT_CENTER;
lvc.cx = 80;
lvc.pszText = const_cast<LPWSTR> (columnNames[i]); // 现在应该没问题了
lvc.iSubItem = i;
ListView_InsertColumn(g_hListView, i, &lvc);
}
// 添加数据
for (int row = 0; row < 4; row++)
{
// 插入第一项
LVITEM lvi = { 0 };
lvi.mask = LVIF_TEXT;
lvi.iItem = row;
lvi.iSubItem = 0;
wchar_t firstColText[32];
if (row == 0)
{
wcscpy_s(firstColText, L"1行1列");
}
else
{
swprintf_s(firstColText, L"%d行1列", row + 1);
}
lvi.pszText = firstColText;
ListView_InsertItem(g_hListView, &lvi);
// 添加其他列数据
for (int col = 1; col < 5; col++)
{
wchar_t buffer[32];
if (row == 0 && col == 0)
{
wcscpy_s(buffer, L"1行1列");
}
else
{
swprintf_s(buffer, L"%d行%d列", row + 1, col + 1);
}
ListView_SetItemText(g_hListView, row, col, buffer);
}
}
}
// 启用ListView列拖拽功能
BOOL EnableListViewDragColumns()
{
if (!g_hListView) return FALSE;
// 获取Header控件并设置扩展样式
HWND hHeader = ListView_GetHeader(g_hListView);
if (hHeader)
{
SendMessage(hHeader, CUSTOM_HDM_SETEXTENDEDSTYLE, 0, CUSTOM_HDS_DRAGDROP);
}
return TRUE;
}