C++ List Control如何实现类似.NET的Anchor/Dock自适应窗口缩放功能
Win32 C++ List Control 停靠适配窗口大小实现方案
实现原理
Win32 没有内置类似.NET的Anchor/Dock布局属性,需要手动响应对话框的WM_SIZE窗口尺寸变更消息,根据对话框的最新客户区尺寸,动态调整List Control的位置和大小即可实现同步适配效果。
修改后的完整实现代码
C++ 核心代码
#include <Windows.h> #include "resource.h" #pragma comment(linker, "\"/manifestdependency:type='win32' \ name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \ processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") #pragma comment(linker, "/SUBSYSTEM:WINDOWS") #include <CommCtrl.h> // LV_COLUMN and ListView_x INT_PTR CALLBACK DialogProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam) { wchar_t c0_txt[] = L"Dogzu"; switch (Message) { case WM_INITDIALOG: LVCOLUMNW col; col.mask = LVCF_TEXT | LVCF_WIDTH | LVIF_IMAGE; col.cx = 60; col.pszText = c0_txt; ListView_InsertColumn(GetDlgItem(hWnd, IDC_LIST1), 0, &col); return TRUE; case WM_SIZE: { // 窗口最小化时跳过处理 if (LOWORD(lParam) == 0 || HIWORD(lParam) == 0) return TRUE; HWND hList = GetDlgItem(hWnd, IDC_LIST1); if (hList) { // 保留初始布局的上下左右边距:左21、上25、右21、下28 int leftMargin = 21; int topMargin = 25; int rightMargin = 21; int bottomMargin = 28; int listWidth = LOWORD(lParam) - leftMargin - rightMargin; int listHeight = HIWORD(lParam) - topMargin - bottomMargin; // 调整List Control位置与大小 MoveWindow(hList, leftMargin, topMargin, listWidth, listHeight, TRUE); } return TRUE; } case WM_NCDESTROY: PostQuitMessage(0); return FALSE; case WM_COMMAND: switch (LOWORD(wParam)) { case IDOK: case IDCANCEL: DestroyWindow(hWnd); break; default: break; } break; default: return FALSE; } return TRUE; } int WINAPI WinMain( _In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nShowCmd ) { UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); HWND hWnd = CreateDialogParamW(hInstance, MAKEINTRESOURCEW(IDD_MAIN), nullptr, &DialogProc, 0); if (!hWnd) { MessageBoxW(nullptr, L"Dialog Creation Failed!", L"Error!", MB_ICONEXCLAMATION | MB_OK); return 0; } ShowWindow(hWnd, nShowCmd); UpdateWindow(hWnd); MSG msg; while (GetMessageW(&msg, nullptr, 0, 0)) { TranslateMessage(&msg); DispatchMessageW(&msg); } return msg.wParam; }
RC 资源代码
原资源代码无需修改,已配置WS_THICKFRAME属性支持窗口拖动缩放,保留原内容即可。
// Microsoft Visual C++ generated resource script. // #include "resource.h" #define APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 2 resource. // #include "winres.h" ///////////////////////////////////////////////////////////////////////////// #undef APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // English (United States) resources #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US #pragma code_page(1252) #ifdef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // TEXTINCLUDE // 1 TEXTINCLUDE BEGIN "resource.h\0" END 2 TEXTINCLUDE BEGIN "#include ""winres.h""\0" END 3 TEXTINCLUDE BEGIN "\r\n" "\0" END #endif // APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // DESIGNINFO // #ifdef APSTUDIO_INVOKED GUIDELINES DESIGNINFO BEGIN IDD_MAIN, DIALOG BEGIN LEFTMARGIN, 7 RIGHTMARGIN, 302 TOPMARGIN, 7 BOTTOMMARGIN, 169 END END #endif // APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // Dialog // IDD_MAIN DIALOGEX 0, 0, 309, 176 STYLE DS_SETFONT | DS_FIXEDSYS | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME CAPTION "Test" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN CONTROL "",IDC_LIST1,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,21,25,268,123 END ///////////////////////////////////////////////////////////////////////////// // // AFX_DIALOG_LAYOUT // IDD_MAIN AFX_DIALOG_LAYOUT BEGIN 0 END #endif // English (United States) resources ///////////////////////////////////////////////////////////////////////////// #ifndef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 3 resource. // ///////////////////////////////////////////////////////////////////////////// #endif // not APSTUDIO_INVOKED
效果说明
如果需要实现类似.NET的Dock.Fill效果(List Control完全铺满整个对话框客户区),只需将边距参数全部设置为0即可。
内容的提问来源于stack exchange,提问作者nop
相关产品推荐
相关产品推荐

