Win32开发:我的SysLink控件为何显示为纯文本?
问题:Win32 LINK控件显示带
<a>标签的纯文本,无法渲染可点击链接 我使用Win32 API、C++和Visual Studio,尝试在窗口中添加可点击的URL。按照微软官方示例实现时,链接却显示为带有<a>标签的纯文本。官方示例将链接放在标题栏中,但使用了WS_CHILD样式导致其隐藏,因此我改用WS_CAPTION样式使其显示。我遗漏了什么?该控件是否仅适用于对话框?
相关代码如下:
wWinMain():
INITCOMMONCONTROLSEX icex; icex.dwSize = sizeof(INITCOMMONCONTROLSEX); icex.dwICC = ICC_LINK_CLASS; InitCommonControlsEx(&icex);
MyRegisterClass2():
WNDCLASSEXW wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = WndProc2; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = NULL; wcex.hCursor = LoadCursor(nullptr, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); wcex.lpszMenuName = NULL; wcex.lpszClassName = WC_LINK; wcex.hIconSm = NULL; return RegisterClassExW(&wcex);
InitInstance():
hWndMain = CreateWindowW( szWindowClass, szTitle, WS_OVERLAPPED | WS_MINIMIZEBOX | WS_SYSMENU, xPos, yPos, windowWidth, windowHeight, nullptr, nullptr, hInstance, nullptr );
RECT rectLink = { 30, 30, 300, 40 }; hWndLink = CreateWindowEx( 0, WC_LINK, L"link: <A HREF=\"https://www.google.com\">click</A>", WS_VISIBLE | WS_CHILD | WS_TABSTOP | WS_CAPTION, rectLink.left, rectLink.top, rectLink.right, rectLink.bottom, hWndMain, NULL, hInstance, NULL); if (!hWndLink) { return FALSE; } ShowWindow(hWndMain, nCmdShow); ShowWindow(hWndLink, nCmdShow); UpdateWindow(hWndMain); UpdateWindow(hWndLink);
WndProc2():
LRESULT CALLBACK WndProc2(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_PAINT: { PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &ps); EndPaint(hWnd, &ps); } break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; }
问题根源及修正方案
1. 不要手动注册WC_LINK窗口类
WC_LINK是系统预定义的链接控件类,无需你调用RegisterClassExW自定义注册。你写的WndProc2会覆盖系统控件的默认消息处理逻辑,导致控件无法解析<a>标签渲染链接。直接删除MyRegisterClass2()函数即可。
2. 移除错误的WS_CAPTION样式
链接控件是子控件,WS_CAPTION是顶级窗口的标题栏样式,给子控件添加该样式会导致显示异常,完全没必要。
3. 修正控件尺寸计算
CreateWindowEx的宽度和高度参数是控件的实际宽高,你直接传入rectLink.right和rectLink.bottom是错误的,需要计算为rectLink.right - rectLink.left和rectLink.bottom - rectLink.top。
4. 处理链接点击通知
在主窗口的WndProc中添加WM_NOTIFY消息处理,捕获链接的NM_CLICK通知以打开URL:
// 先定义控件ID,比如在头文件中添加: #define IDC_MY_LINK 1001 // 主窗口WndProc修改: LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_NOTIFY: { NMHDR* pNMHDR = (NMHDR*)lParam; if (pNMHDR->idFrom == IDC_MY_LINK && pNMHDR->code == NM_CLICK) { ShellExecuteW(hWnd, L"open", L"https://www.google.com", NULL, NULL, SW_SHOWNORMAL); } break; } case WM_PAINT: { PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &ps); EndPaint(hWnd, &ps); } break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; }
同时修改链接控件的创建代码,指定控件ID:
hWndLink = CreateWindowEx( 0, WC_LINK, L"<A HREF=\"https://www.google.com\">click here</A>", WS_VISIBLE | WS_CHILD | WS_TABSTOP, rectLink.left, rectLink.top, rectLink.right - rectLink.left, rectLink.bottom - rectLink.top, hWndMain, (HMENU)IDC_MY_LINK, // 指定控件ID hInstance, NULL);
补充说明
- LINK控件既可以用于对话框,也可以用于普通窗口,只要正确创建即可。
- 你代码中
InitCommonControlsEx初始化ICC_LINK_CLASS的部分是正确的,保留即可。
内容的提问来源于stack exchange,提问作者user22157294
相关产品推荐
相关产品推荐

