我一直在慢慢学习 Win32 API,并被这个难住了:
当我在 Windows 7 上以“经典外观”和“Windows 7 Aero Glass”外观运行它时,一切正常,它甚至在控件上具有 Aero 外观,它们看起来很正常。当我在我的 XP 机器上运行它时,再次使用“经典外观”,一切看起来都不错,但是当我在具有“Windows XP 主题”的 XP 上运行它时,我得到的是上面的结果。
遵循 Microsoft 在 http://msdn.microsoft.com/en-us/library/bb773175%28VS.85%29.aspx 上的视觉样式指南我需要做三件事:
1 . Link to ComCtl32.lib and call InitCommonControls.
检查,这样做,我将 comctl32 添加到我的链接器设置中。
2 . Add a file called YourApp.exe.manifest to your source tree that has the XML manifest format.
检查,这样做了。我有一个正在使用的版本,但为了安全起见,我尝试了他们网站上建议的版本,我什至将其重命名为指定的开始版本以涵盖所有基础。 (是的,我知道给它取我的应用程序的名称....)
3 . Add the manifest to your application's resource file as follows:
检查,这样做了。我将他们建议的指定行添加到我的 rc 文件中。
因此,在所有条件下,一切正常,Windows XP 风格主题除外。
我唯一想剩下的就是我没有响应 WM_PAINT 消息,但我将它传递给默认窗口过程,以允许 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);
}
最佳答案
如果你想删除控件的黑色背景,
你可以试试EnableThemeDialogTexture()
.
第二种方法(来自Correctly drawn themed dialogs in WinXP):
// WM_INITDIALOG
RECT rc;
GetWindowRect(hWnd,&rc);
HDC hDC=GetDC(hWnd);
HDC hDCMem=CreateCompatibleDC(hDC);
HBITMAP hBmp=CreateCompatibleBitmap(hDC,rc.right-rc.left,rc.bottom-rc.top);
HBITMAP hBmpOld=(HBITMAP)SelectObject(hDCMem,hBmp);
SendMessage(hWnd,WM_PRINTCLIENT,(WPARAM)hDCMem,(LPARAM)(PRF_ERASEBKGND|PRF_CLIENT|PRF_NONCLIENT));
hBrush=CreatePatternBrush(hBmp); // HBRUSH hBrush is global
SelectObject(hDCMem,hBmpOld);
DeleteObject(hBmp);
DeleteDC(hDCMem);
ReleaseDC(hWnd,hDC);
//WM_CTLCOLORSTATIC
RECT rc;
SetBkMode((HDC)wParam,TRANSPARENT);
GetWindowRect((HWND)lParam,&rc);
MapWindowPoints(NULL,hWnd,(LPPOINT)&rc,2);
SetBrushOrgEx((HDC)(wParam),-rc.left,-rc.top,NULL);
return (LRESULT)hBrush;
关于c++ - 使用 XP 主题消隐控件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10974346/