2

我一直在慢慢学习 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);
}
4

1 回答 1

0

如果要去除控件的黑色背景,可以尝试EnableThemeDialogTexture().

第二种方法(来自正确绘制的 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;
于 2015-07-20T10:31:21.343 回答