c++ - 使用 XP 主题消隐控件

标签 c++ winapi themes

我一直在慢慢学习 Win32 API,并被这个难住了:

Blanked Controls

当我在 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/

相关文章:

c++ - mysqlpp 连接方法超时 - 我怎样才能控制它?

c++ - 通过c++ WinAPI计算MD5哈希值

css - 如何使用自定义样式覆盖默认的 PrimeFaces CSS?

c++ - 如何在 Windows 上编写 C++ FireFox 3 插件(不是扩展)?

iphone - UIView 和 XIB 连接。正在显示吗?

C++ 外部对象放置

css - 在 React 应用程序中使用 PrimeReact 主题和启用的 CSS 模块

c++ - 启用视觉样式的日期和时间选择器 -> 更改标题的背景颜色

c - TextOut() 和 Shift-JIS(日语字符)

themes - Prestashop 根目录