使用GetWindowLongPtr+GWL_STYLE无法获取全部窗口样式问题
问题:GetWindowLongPtr()无法获取EDIT窗口的WS_BORDER样式
我尝试用GetWindowLongPtr()获取窗口的完整样式,但遇到问题——该函数返回的结果里没有WS_BORDER样式。
创建EDIT窗口时,我明确指定了WS_CHILD | WS_VISIBLE | WS_BORDER | ES_LEFT样式,代码片段如下:
HWND input = CreateWindow( L"EDIT", L"", WS_CHILD | WS_VISIBLE | WS_BORDER | ES_LEFT, 300, 100, 100, 20, hwnd, NULL, GetModuleHandle(NULL), NULL ); LONG_PTR style = GetWindowLongPtr(input, GWL_STYLE);
调试时发现获取到的style值是0x50000000,只包含WS_CHILD、WS_VISIBLE和ES_LEFT三种样式。我怀疑系统没把WS_BORDER存在窗口样式的内存区域,而是存到了其他地方。
完整测试用例:
#include <windows.h> int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, wchar_t* pCmdLine, int nCmdShow) { WNDCLASSW wc = {}; wc.lpfnWndProc = DefWindowProc; wc.hInstance = hInstance; wc.lpszClassName = L"Window"; RegisterClassW(&wc); HWND hwnd = CreateWindow( L"Window", L"Test", WS_OVERLAPPEDWINDOW, // Size and pos CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL ); HWND input = CreateWindow( L"EDIT", L"", WS_CHILD | WS_VISIBLE | WS_BORDER | ES_LEFT, 100, 220, 100, 20, hwnd, NULL, hInstance, NULL ); ShowWindow(hwnd, nCmdShow); LONG_PTR style = GetWindowLongPtr(input, GWL_STYLE); MSG msg = {}; while(GetMessage(&msg, NULL, 0, 0) > 0) { TranslateMessage(&msg); DispatchMessage(&msg); } return 0; }
解答
这是EDIT控件的特殊行为——系统会将WS_BORDER样式转换为ES_BORDER样式(编辑控件的扩展样式),因此直接通过GWL_STYLE无法获取到WS_BORDER,需要使用GetWindowLongPtr()搭配GWL_EXSTYLE参数来检查ES_BORDER。
验证步骤:
- 获取控件的扩展样式:
LONG_PTR exStyle = GetWindowLongPtr(input, GWL_EXSTYLE);
- 判断
ES_BORDER是否存在:
if (exStyle & ES_BORDER) { // 边框样式已生效 }
本质原因是,对于EDIT这类标准系统控件,内部会对传入的基础样式做映射处理,将WS_BORDER转换为扩展样式中的ES_BORDER,以此实现控件的边框渲染逻辑。你指定的WS_BORDER实际上已经生效,只是存储位置从基础样式转移到了扩展样式区域。
另外,也可以通过计算窗口非客户区大小验证边框是否存在:调用GetWindowRect()获取窗口整体矩形,调用GetClientRect()获取客户区矩形,两者的尺寸差即为边框的宽度。
内容的提问来源于stack exchange,提问作者Daloo
相关产品推荐
相关产品推荐

