我一直在慢慢学习 Win32 API,并被这个难住了:
当我在 Windows 7 上以“经典外观”和“Windows 7 Aero Glass”外观运行它时,一切正常,甚至在控件上有 Aero 外观,它们看起来很正常。当我在我的 XP 机器上再次使用“经典外观”运行它时,一切看起来都不错,但是当我在 XP 上使用“Windows XP 主题”运行它时,我得到的就是上面的内容。
遵循 Microsoft 在http://msdn.microsoft.com/en-us/library/bb773175%28VS.85%29.aspx上的视觉样式指南,我需要做 3 件事:
1. 链接到 ComCtl32.lib 并调用 InitCommonControls。
检查,这样做,我将 comctl32 添加到我的链接器设置中。
2. 将名为 YourApp.exe.manifest 的文件添加到具有 XML 清单格式的源代码树中。
检查,这样做了。我有一个正在使用的版本,但为了安全起见,我尝试了他们网站上建议的版本,我什至将它重命名为 start 指定以涵盖所有基础。(是的,我知道给它我的应用程序的名称......)
3. 将清单添加到应用程序的资源文件中,如下所示:
检查,这样做了。我将他们建议的指定行添加到我的 rc 文件中。
因此,在所有情况下,一切正常,Windows XP 风格主题除外。
我唯一认为剩下的就是我没有响应 WM_PAINT 消息,但我将它传递给默认窗口 proc,以允许 Windows 在这方面做它的事情。(我看不出这是否行不通,它在其他任何地方都行不通。)
我看到了与这篇文章类似的帖子,它说使用 InitCommonControlsEx,也这样做了,但无济于事。
我难住了。
#include <windows.h>
#include <windowsx.h>
#include <commctrl.h>
#include <uxtheme.h>
#include <iostream>
using namespace std;
#define IDC_MAIN_BUTTON_1 101 // Button identifier
#define IDC_MAIN_BUTTON_2 102 // Button identifier
#define IDC_MAIN_BUTTON_3 103 // Button identifier
#define IDC_MAIN_BUTTON_4 104 // Button identifier
HWND hWndButton1;
HWND hWndButton2;
HWND hWndButton3;
HWND hWndButton4;
MSG msg;
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK MyWndProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass,
DWORD_PTR dwRefData);
int WINAPI WinMain (HINSTANCE hInstance,
HINSTANCE hPrevInst,
LPSTR lpCmdLine,
int ShowCmd) {
INITCOMMONCONTROLSEX icc;
// Initialize common controls.
icc.dwSize = sizeof(icc);
icc.dwICC = ICC_WIN95_CLASSES |
ICC_COOL_CLASSES |
ICC_INTERNET_CLASSES |
ICC_LINK_CLASS |
ICC_STANDARD_CLASSES |
ICC_USEREX_CLASSES;
InitCommonControlsEx(&icc);
WNDCLASSEXW wClass;
ZeroMemory(&wClass,sizeof(WNDCLASSEXW));
wClass.cbSize = sizeof(WNDCLASSEX);
wClass.hInstance = hInstance;
wClass.lpszClassName = L"Window Class";
wClass.lpfnWndProc = (WNDPROC)WndProc;
wClass.style = CS_HREDRAW | CS_VREDRAW;
wClass.lpszMenuName = NULL;
wClass.hbrBackground = (HBRUSH)COLOR_WINDOW;
wClass.hCursor = LoadCursor(NULL,IDC_ARROW);
wClass.hIcon = NULL;
wClass.hIconSm = NULL;
wClass.cbClsExtra = 0;
wClass.cbWndExtra = 0;
RegisterClassEx(&wClass);
HWND hWnd=CreateWindowExW(
0, // in DWORD dwExStyle,
L"Window Class", // in_opt LPCTSTR lpClassName,
L"Windows application", // in_opt LPCTSTR lpWindowName,
WS_OVERLAPPEDWINDOW, // in DWORD dwStyle,
200, // in int x,
200, // in int y,
640, // in int nWidth,
480, // in int nHeight,
NULL, // in_opt HWND hWndParent,
NULL, // in_opt HMENU hMenu,
hInstance, // in_opt HINSTANCE hInstance,
NULL); // in_opt LPVOID lpParam
ShowWindow(hWnd,ShowCmd);
ZeroMemory(&msg,sizeof(MSG));
while(GetMessageW(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
return (int)&msg.wParam;
}
void Button_Proc (WPARAM, LPARAM);
LRESULT CALLBACK WndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
HWND GROUP1 = 0;
HWND GROUP2 = 0;
switch(msg)
{
case WM_CREATE:
{
// Create a group box
GROUP1 = CreateWindowExW(
0,
L"BUTTON",
L"Group",
WS_TABSTOP |
WS_VISIBLE |
WS_CHILD |
BS_NOTIFY |
BS_GROUPBOX ,
100,
60,
150,
80,
hWnd,
0,
GetModuleHandle(NULL),
0);
SetWindowSubclass(GROUP1, (SUBCLASSPROC) MyWndProc, 0, 0);
// Create a group box
GROUP2=CreateWindowExW(
0,
L"BUTTON",
L"Group 2",
WS_TABSTOP |
WS_VISIBLE |
WS_CHILD |
BS_GROUPBOX ,
100,
160,
150,
80,
hWnd,
0,
GetModuleHandle(NULL),
0);
SetWindowSubclass(GROUP2, (SUBCLASSPROC) MyWndProc, 0, 0);
// Create a push button
hWndButton1=CreateWindowExW(
0,
L"BUTTON",
L"Option 1",
WS_TABSTOP |
WS_VISIBLE |
WS_CHILD |
WS_GROUP |
BS_NOTIFY |
BS_AUTORADIOBUTTON ,
10,
20,
100,
24,
GROUP1,
(HMENU)IDC_MAIN_BUTTON_1,
GetModuleHandle(NULL),
0);
hWndButton2=CreateWindowExW(
0,
L"BUTTON",
L"Option 2",
WS_TABSTOP |
WS_VISIBLE |
WS_CHILD |
BS_NOTIFY |
BS_AUTORADIOBUTTON ,
10,
45,
100,
24,
GROUP1,
(HMENU)IDC_MAIN_BUTTON_2,
GetModuleHandle(NULL),
0);
hWndButton3=CreateWindowExW(
0,
L"BUTTON",
L"Option 3",
WS_TABSTOP |
WS_VISIBLE |
WS_CHILD |
WS_GROUP |
BS_NOTIFY |
BS_AUTORADIOBUTTON ,
10,
20,
100,
24,
GROUP2,
(HMENU)IDC_MAIN_BUTTON_3,
GetModuleHandle(NULL),
0);
hWndButton4=CreateWindowExW(
0,
L"BUTTON",
L"Option 4",
WS_TABSTOP |
WS_VISIBLE |
WS_CHILD |
BS_NOTIFY |
BS_AUTORADIOBUTTON ,
10,
45,
100,
24,
GROUP2,
(HMENU)IDC_MAIN_BUTTON_4,
GetModuleHandle(NULL),
0);
}
break;
case WM_NOTIFY:
switch(LOWORD(wParam))
{
case IDC_MAIN_BUTTON_1:
case IDC_MAIN_BUTTON_2:
case IDC_MAIN_BUTTON_3:
case IDC_MAIN_BUTTON_4:
{
Button_Proc(wParam,lParam);
}
break;
}
break;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDC_MAIN_BUTTON_1:
case IDC_MAIN_BUTTON_2:
case IDC_MAIN_BUTTON_3:
case IDC_MAIN_BUTTON_4:
{
Button_Proc(wParam,lParam);
}
break;
}
break;
case WM_DESTROY:
{
RemoveWindowSubclass(GROUP1, (SUBCLASSPROC) MyWndProc, 0);
RemoveWindowSubclass(GROUP2, (SUBCLASSPROC) MyWndProc, 0);
PostQuitMessage(0);
return 0;
}
break;
}
return DefWindowProcW(hWnd,msg,wParam,lParam);
}
void Button_Proc (WPARAM wParam, LPARAM lParam) {
switch (HIWORD(wParam))
{
case BN_CLICKED:
{
cerr << "Button clicked\n";
}
break;
case BN_DBLCLK:
{
cerr << "Button Double clicked\n";
}
break;
case BN_KILLFOCUS:
{
cerr << "Button Lost Focus\n";
}
break;
case BN_SETFOCUS:
{
cerr << "Button Set Focus\n";
}
break;
// case BCN_HOTITEMCHANGE: // Controls Version 6.
// case BCN_DROPDOWN: // Controls Version 6.
// case NM_CUSTOMDRAW: // Controls Version 6.
// case WM_CTLCOLORBTN: // Investigation Required.
}
// //http://msdn.microsoft.com/en-us/library/windows/desktop/bb849167(v=vs.85).aspx
// if ( Button_GetCheck((HWND) lParam) == BST_UNCHECKED) {
// Button_SetCheck( (HWND) lParam, BST_CHECKED);
// } else {
// Button_SetCheck( (HWND) lParam, BST_UNCHECKED);
// }
}
LRESULT CALLBACK MyWndProc (HWND hWnd,
UINT msg,
WPARAM wParam,
LPARAM lParam,
UINT_PTR uIdSubclass,
DWORD_PTR dwRefData) {
// cerr << "Subclass Proc Called\n";
switch (msg) {
case WM_COMMAND: {
switch(LOWORD(wParam)) {
case IDC_MAIN_BUTTON_1:
case IDC_MAIN_BUTTON_2:
case IDC_MAIN_BUTTON_3:
case IDC_MAIN_BUTTON_4: {
Button_Proc(wParam,lParam);
}
break;
}
}
break;
}
return DefSubclassProc(hWnd, msg, wParam, lParam);
}