使用XP主题消隐的控件

时间:2012-06-11 03:54:57

标签: c++ winapi themes

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

Blanked Controls

当我在“经典外观”和“Windows 7 Aero Glass”外观的Windows 7上运行时,一切都很好,甚至在控件上都有Aero外观,它们看起来很正常。当我在我的XP机器上运行它时,再次使用“经典外观”,一切看起来都不错,但是当我使用“Windows XP主题”在XP上运行它时,上面就是我得到的。

遵循Microsoft http://msdn.microsoft.com/en-us/library/bb773175%28VS.85%29.aspx的视觉样式指南,我需要做三件事:

  

1。链接到ComCtl32.lib并调用InitCommonControls。

检查,这样做,我将comctl32添加到我的链接器设置。

  

2。将名为YourApp.exe.manifest的文件添加到具有XML清单格式的源树中。

检查,做到了这一点。我有一个我正在使用的版本,但为了安全起见,我尝试了在他们网站上建议的版本,我甚至将它重命名为指定覆盖所有基础的开始。 (是的,我知道给它申请的名字......)

  

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);
}

1 个答案:

答案 0 :(得分:0)

如果要删除控件的黑色背景, 你可以尝试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;