无法更改背景颜色MDI c ++

时间:2014-10-08 12:16:37

标签: c++ winapi

我正在写一个程序,我有一个问题,我希望你们能帮助我。

就像你可以在下面的代码中看到的那样,我有WinMain WINAPI,它创建了主机(父窗口)。当我尝试更改 wc.hbrBackground 变量中的背景颜色时,没有任何事情发生。我真的不明白为什么。我几乎尝试了一切。无论我选择哪种颜色,它都保持深灰色背景 - 并且不会发生错误。我怀疑客户区域的“标记”是问题,但我无法弄清楚 你能帮助我改变一下吗?

我在main.cpp中的代码摘录:

HWND CreateNewMDIChild(HWND hMDIClient)
{
   MDICREATESTRUCT mcs;
   HWND hChild;

   mcs.szTitle = "[Untitled]";
   mcs.szClass = g_szChildClassName;
   mcs.hOwner  = GetModuleHandle(NULL);
   mcs.x = mcs.cx = CW_USEDEFAULT;
   mcs.y = mcs.cy = CW_USEDEFAULT;
   mcs.style = MDIS_ALLCHILDSTYLES;

   hChild = (HWND)SendMessage(hMDIClient, WM_MDICREATE, 0, (LONG)&mcs);
   if(!hChild)
   {
      MessageBox(hMDIClient, "MDI Child creation failed.", "Oh Oh...",
        MB_ICONEXCLAMATION | MB_OK);
   }
   return hChild;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
   switch(msg)
   {
        case WM_CREATE:
        {                       
             HWND hStatus;
             int statwidths[] = {100, -1};

             CLIENTCREATESTRUCT ccs;

             // Create MDI Client

             // Find window menu where children will be listed
             ccs.hWindowMenu  = GetSubMenu(GetMenu(hwnd), 5);
             ccs.idFirstChild = ID_MDI_FIRSTCHILD;

             g_hMDIClient = CreateWindowEx(WS_EX_CLIENTEDGE, "mdiclient", NULL,
                 WS_CHILD | WS_CLIPCHILDREN | WS_VSCROLL | WS_HSCROLL | WS_VISIBLE,
                 CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
                 hwnd, (HMENU)IDC_MAIN_MDI, GetModuleHandle(NULL), (LPVOID)&ccs);

             if(g_hMDIClient == NULL)
                  MessageBox(hwnd, "Could not create MDI client.", "Error", MB_OK | MB_ICONERROR);

             // Create Toolbar

             HWND hTool;
             TBBUTTON tbb[5];
             TBADDBITMAP tbab;

             hTool = CreateWindowEx(0, TOOLBARCLASSNAME, NULL, WS_CHILD | WS_VISIBLE, 0, 0, 0, 0,
                    hwnd, (HMENU)IDC_MAIN_TOOL, GetModuleHandle(NULL), NULL);
             if(hTool == NULL)
                   MessageBox(hwnd, "Could not create tool bar.", "Error", MB_OK | MB_ICONERROR);

             // Send the TB_BUTTONSTRUCTSIZE message, which is required for
             // backward compatibility.
             SendMessage(hTool, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);

             tbab.hInst = HINST_COMMCTRL;
             tbab.nID = IDB_STD_SMALL_COLOR;
             SendMessage(hTool, TB_ADDBITMAP, 0, (LPARAM)&tbab);

             ZeroMemory(tbb, sizeof(tbb));
             tbb[0].iBitmap = STD_FILENEW;
             tbb[0].fsState = TBSTATE_ENABLED;
             tbb[0].fsStyle = TBSTYLE_BUTTON;
             tbb[0].idCommand = ID_FILE_NEW;


            SendMessage(hTool, TB_ADDBUTTONS, sizeof(tbb)/sizeof(TBBUTTON), (LPARAM)&tbb);

            // Create Status bar

           hStatus = CreateWindowEx(0, STATUSCLASSNAME, NULL,
                   WS_CHILD | WS_VISIBLE | SBARS_SIZEGRIP, 0, 0, 0, 0,
                   hwnd, (HMENU)IDC_MAIN_STATUS, GetModuleHandle(NULL), NULL);

           SendMessage(hStatus, SB_SETPARTS, sizeof(statwidths)/sizeof(int), (LPARAM)statwidths);
           SendMessage(hStatus, SB_SETTEXT, 0, (LPARAM)"Version 1.0.0 beta");

    }
    break;
    case WM_SIZE:
    {
        HWND hTool;
        RECT rcTool;
        int iToolHeight;

        HWND hStatus;
        RECT rcStatus;
        int iStatusHeight;

        HWND hMDI;
        int iMDIHeight;
        RECT rcClient;

        // Size toolbar and get height

        hTool = GetDlgItem(hwnd, IDC_MAIN_TOOL);
        SendMessage(hTool, TB_AUTOSIZE, 0, 0);

        GetWindowRect(hTool, &rcTool);
        iToolHeight = rcTool.bottom - rcTool.top;

        // Size status bar and get height

        hStatus = GetDlgItem(hwnd, IDC_MAIN_STATUS);
        SendMessage(hStatus, WM_SIZE, 0, 0);

        GetWindowRect(hStatus, &rcStatus);
        iStatusHeight = rcStatus.bottom - rcStatus.top;

        // Calculate remaining height and size edit

        GetClientRect(hwnd, &rcClient);

        iMDIHeight = rcClient.bottom - iToolHeight - iStatusHeight;

        hMDI = GetDlgItem(hwnd, IDC_MAIN_MDI);
        SetWindowPos(hMDI, NULL, 0, iToolHeight, rcClient.right, iMDIHeight, SWP_NOZORDER); 
    }
    break;
    case WM_CLOSE:
        DestroyWindow(hwnd);
    break;
    case WM_DESTROY:
        PostQuitMessage(0);
    break;
    case WM_COMMAND:
        // Some code
    default:
        return DefFrameProc(hwnd, g_hMDIClient, msg, wParam, lParam);
}
return 0;
}

LRESULT CALLBACK MDIChildWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
    case WM_CREATE:
    {
                CreateWindow("EDIT", "", WS_VISIBLE | WS_CHILD | WS_BORDER | WS_TABSTOP | WS_GROUP, 270, 40, 80, 20, hwnd, (HMENU) ID_EB_1, NULL, NULL);
            CreateWindow("EDIT", "", WS_VISIBLE | WS_CHILD | WS_BORDER | WS_TABSTOP, 270, 70, 80, 20, hwnd, (HMENU) ID_EB_2, NULL, NULL);
            CreateWindow("EDIT", "", WS_VISIBLE | WS_CHILD | WS_BORDER | WS_TABSTOP, 430, 70, 80, 20, hwnd, (HMENU) ID_EB_3, NULL, NULL);

            CreateWindow("EDIT", "", WS_VISIBLE | WS_CHILD | WS_BORDER | WS_TABSTOP, 270, 135, 80, 20, hwnd, (HMENU) ID_EB_4, NULL, NULL);
            CreateWindow("EDIT", "", WS_VISIBLE | WS_CHILD | WS_BORDER | WS_TABSTOP, 430, 135, 80, 20, hwnd, (HMENU) ID_EB_5, NULL, NULL);
    }
    break;
    case WM_COMMAND:
                 // Some code
    break;
    return DefMDIChildProc(hwnd, msg, wParam, lParam);
    default:
        return DefMDIChildProc(hwnd, msg, wParam, lParam);

}
return 0;
}

BOOL SetUpMDIChildWindowClass(HINSTANCE hInstance)
{
WNDCLASSEX wc;

wc.cbSize        = sizeof(WNDCLASSEX);
wc.style         = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc   = MDIChildWndProc;
wc.cbClsExtra    = 0;
wc.cbWndExtra    = 0;
wc.hInstance     = hInstance;
wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_3DFACE+1);
wc.lpszMenuName  = NULL;
wc.lpszClassName = g_szChildClassName;
wc.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);

if(!RegisterClassEx(&wc))
{
    MessageBox(0, "Could Not Register Child Window", "Oh Oh...",
        MB_ICONEXCLAMATION | MB_OK);
    return FALSE;
}
else
    return TRUE;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wc;
HWND hwnd;
MSG Msg;

InitCommonControls();

wc.cbSize        = sizeof(WNDCLASSEX);
wc.style         = 0;
wc.lpfnWndProc   = WndProc;
wc.cbClsExtra    = 0;
wc.cbWndExtra    = 0;
wc.hInstance     = hInstance;
wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszMenuName  = MAKEINTRESOURCE(IDR_MAINMENU);
wc.lpszClassName = g_szClassName;
wc.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);

if(!RegisterClassEx(&wc))
{
    MessageBox(NULL, "Window Registration Failed!", "Error!",
        MB_ICONEXCLAMATION | MB_OK);
    return 0;
}

if(!SetUpMDIChildWindowClass(hInstance))
    return 0;

hwnd = CreateWindowEx(
    0,
    g_szClassName,
    "Conosoft Enomi - Version 1.0.0 (beta)",
    WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
    CW_USEDEFAULT, CW_USEDEFAULT, 1100, 700,
    NULL, NULL, hInstance, NULL);

if(hwnd == NULL)
{
    MessageBox(NULL, "Window Creation Failed!", "Error!",
        MB_ICONEXCLAMATION | MB_OK);
    return 0;
}

g_hMainWindow = hwnd;

ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);

while(GetMessage(&Msg, NULL, 0, 0) > 0)
{
        if (!TranslateMDISysAccel(g_hMDIClient, &Msg))
        {
            TranslateMessage(&Msg);
            DispatchMessage(&Msg);
        }
}
return Msg.wParam;
}

我真的希望你们能帮助我,谢谢! :)

2 个答案:

答案 0 :(得分:2)

您无法使用hbrBackground实现此更改,因为客户端窗口类是由系统预定义的。创建客户端窗口时,您将"mdiclient"作为窗口类名称传递。您没有注册该类,它是预先定义的。顺便说一下,您应该使用宏MDICLIENT来指定该类名。

相反,您需要子类化客户端窗口并处理WM_ERASEBKGND以根据需要绘制背景。

答案 1 :(得分:0)

这对我有用。更改MDI应用程序的背景颜色时,需要寻找几个地方。

+----------------------------+
|                            |
+----------------------------+
|                            |
|   +-------------+          |
|   |             |          |
|   |     +---------------+  |
|   +-----|               |  |
|         |      (c)      |  |
|         +---------------+  |
|   (f)                      |
+----------------------------+

(c)是子窗口的背景,在您的示例中,该窗口在wc.hbrBackground中定义为SetUpMDIChildWindowClass()

BOOL SetUpMDIChildWindowClass(HINSTANCE hInstance)
{
    ...
    wc.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);

您可以使用

  1. COLOR_... + 1,就像您一样。 WinUser.h中有一些预定义的值。
  2. GetStockObject(BLACK_BRUSH),如果普通画笔适合您的需求。
  3. NULL,如果您想自己处理WM_ERASEBKGND,并可能绘制精美的背景图片。
  4. CreateSolidBrush(...)(如果要使用选择的颜色创建画笔)。关闭应用程序之前,请确保将其删除。

这是最后一种情况的一个例子。

HBRUSH BackgroundBrush;
int WINAPI WinMain(...)
{
    ...
    hBackgroundBrush = CreateSolidBrush(BACKGROUND_COLOR);

LRESULT CALLBACK WndProc(...)
{
    ...
    case WM_DESTROY:
        DeleteObject(hBackgroundBrush);

(f)是框架窗口的背景。如果子窗口最大化,您将看不到它。在您的情况下,它在wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);中定义为WinMain()

请注意,如果子窗口的子窗口覆盖了子窗口的整个客户区域,则需要让子窗口处理背景。例如,我的子窗口具有一个涵盖整个子窗口的“编辑”控件。

LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT uMsg,
                              WPARAM wParam, LPARAM lParam) {
    ...
    case WM_CTLCOLOREDIT:
        SetTextColor((HDC)wParam, TEXT_COLOR);
        SetBkColor((HDC)wParam, BACKGROUND_COLOR);
        return (LRESULT)hBackgroundBrush;