3

在我的程序中,我创建了一个状态栏控件,然后为它设置了一个新字体。我遇到的问题是,当我包含 XP 视觉样式清单(即通用控件 6.0)时,状态栏不会调整大小以匹配新的字体大小。

例如

hGiantFont = CreateFont(-48, 0, 0, 0, FW_NORMAL, FALSE, FALSE,      
   FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
   CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH |    
   FF_DONTCARE, L"MS Shell Dlg 2");

hStatusBar = CreateWindowEx ( 
   0, STATUSCLASSNAME, NULL, WS_CHILD | WS_VISIBLE, 
   0, 0, 0, 0, hWnd, (HMENU)666, hInst, NULL    
);      

SendMessage(hStatusBar, WM_SETFONT, (WPARAM)hGiantFont,  
   (LPARAM)MAKELONG(TRUE, 0));

SendMessage(hStatusBar, WM_SIZE, 0, 0);

执行最后一行后,什么也没有发生!它不会调整大小。请注意,如果我不包括视觉样式清单,它可以正常工作!我用 ICC_BAR_CLASSES 尝试了 InitCommonControls() 和 InitCommonControlsEX() 都无济于事。

我还尝试使用 MoveWindow 和 SetWindowPos 来更改大小或移动状态栏。包含视觉样式清单后,状态栏不会移动,它似乎粘在特定的大小和位置上。

这是 ComCtl32.dll 6.0 中的错误吗?或者是一个非常烦人的预期功能。解决方法是什么?

还有其他人尝试过同样的事情并取得成功吗?

编辑:

好的,我决定将整个程序包含在下面,这样人们就可以尝试一下,看看我的意思。它只是一个简单的 Win32 应用程序,添加了几行代码。如果您注释掉顶部的 #pragma manifest 行,您会注意到它按预期工作,并且使用 manifest 行,状态栏不会调整大小。

// StupidStatusBar.cpp : Defines the entry point for the application.

#pragma comment(linker,"\"/manifestdependency:type='win32' \
name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \
processorArchitecture='*' publicKeyToken='6595b64144ccf1df'    language='*'\"") 

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <tchar.h>
#include <commctrl.h>
#pragma comment(lib, "comctl32.lib")

// Global Variables:
HINSTANCE hInst;                                    
wchar_t *szTitle = L"Stupid Status Bar";    
wchar_t *szWindowClass = L"StupidClass";    

// Forward declarations of functions included in this code module:
ATOM                MyRegisterClass(HINSTANCE hInstance);
BOOL                InitInstance(HINSTANCE, int);
LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);

int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
    MSG msg;
    INITCOMMONCONTROLSEX icex;

    icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
    icex.dwICC = ICC_WIN95_CLASSES;

    if(!InitCommonControlsEx(&icex))
    {
        MessageBox(NULL, L"Error initializing common controls", L"Error", MB_OK);
        return 1;
    }

    MyRegisterClass(hInstance);

    // Perform application initialization:
    if (!InitInstance (hInstance, nCmdShow))
        return FALSE;

    // Main message loop:
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return (int) msg.wParam;
}   

ATOM MyRegisterClass(HINSTANCE hInstance)
{
    WNDCLASSEX wcex;

    wcex.cbSize = sizeof(WNDCLASSEX);

    wcex.style      = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc    = WndProc;
    wcex.cbClsExtra     = 0;
    wcex.cbWndExtra     = 0;
    wcex.hInstance      = hInstance;
    wcex.hIcon      = LoadIcon(NULL, IDI_APPLICATION);
    wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
    wcex.lpszMenuName   = NULL;
    wcex.lpszClassName  = szWindowClass;
    wcex.hIconSm        = LoadIcon(NULL, IDI_APPLICATION);

    return RegisterClassEx(&wcex);
}

BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   HWND hWnd;

   hInst = hInstance; // Store instance handle in our global variable

   hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

   if (!hWnd)
      return FALSE;

   ShowWindow(hWnd, nCmdShow);
   UpdateWindow(hWnd);

   return TRUE;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    HWND hStatusBar;
    HFONT hGiantFont;

    switch (message)
    {
    case WM_CREATE:
        hGiantFont = CreateFont(-48, 0, 0, 0, FW_NORMAL, FALSE, FALSE,     FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
        CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, L"MS Shell Dlg 2");

        hStatusBar = CreateWindowEx ( 
            0, STATUSCLASSNAME, NULL, WS_CHILD | WS_VISIBLE, 
            0, 0, 0, 0, hWnd, (HMENU)666, hInst, NULL   
        );      
        SendMessage(hStatusBar, WM_SETFONT, (WPARAM)hGiantFont, (LPARAM)MAKELONG(TRUE, 0));
        SendMessage(hStatusBar, WM_SIZE, 0, 0);
        SetWindowText(hStatusBar, L"Testing Testing");
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}
4

2 回答 2

2

解决了。必须覆盖状态栏的默认 proc 并使其 WM_SIZE 大小写返回 0。然后在我的主窗口中使用 MoveWindow 手动调整大小。

于 2012-10-24T15:12:18.827 回答
0

我有一个类似的问题,我认为 Win32 API 库中没有废话,它可以工作,但必须遵循一定的程序,这在 Win32 API 文档中没有这么清楚地显示(截至目前,它在https ://code.msdn.microsoft.com/CppWindowsCommonControls-9ea0de64,L部分);如下:

1)全局,定义变量hWndStatusbar:

HWND hWndStatusbar;

2) 在主窗口过程的 WM_CREATE 的末尾添加以下代码(如果 WndProc 窗口过程中尚未处理“case WM_CREATE”,则添加它):

RECT rcStatusRect;

int iStatusBarWidths[1];

GetClientRect(hWnd, &rcStatusRect);

iStatusBarWidths[0] = rcStatusRect.right;

hWndStatusbar = CreateWindowEx(0, STATUSCLASSNAME, NULL, WS_CHILD | WS_VISIBLE | SBARS_SIZEGRIP, 0, 0, 0, 0, hWnd, NULL, hInst, NULL);

SendMessage(hWndStatusbar, SB_SETPARTS, (WPARAM)1, (LPARAM)iStatusBarWidths);

SendMessage((HWND)hWndStatusbar, (UINT)SB_SETTEXT, (WPARAM)(INT)0 | 0, (LPARAM)(LPSTR)TEXT("Hello"));

3) 如果你的 WndProc 窗口过程中没有处理“case WM_SIZE”,只需添加它,并在末尾添加以下代码:

int iStatusBarWidths[1];

iStatusBarWidths[0] = -1;

SendMessage(hWndStatusbar, SB_SETPARTS, (WPARAM)1, (LPARAM)iStatusBarWidths);

SendMessage(hWndStatusbar, WM_SIZE, 0, 0);

这就像一切,对我来说它就像这样,在 Visual Studio Community 2015 下。

于 2018-05-20T23:35:21.030 回答