【问题标题】:DialogBox not rendering correctly?对话框没有正确呈现?
【发布时间】:2017-01-25 06:18:06
【问题描述】:

我不确定我做错了什么,但它看起来是这样的(没有关闭按钮,没有标题栏):

看起来好像没有更新/勾选/重新绘制。

这是我的 Resource.rc 文件:

#include "resource.h"
#include "windows.h"

#define IDC_STATIC -1

ID_ICON_MAIN ICON "Smile.ico"

ID_DIALOG_ABOUT DIALOG 0, 0, 240, 70
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_BORDER
CAPTION "About"
FONT 8, "Terminal"
{
        DEFPUSHBUTTON   "&OK", IDOK, 174, 18, 50, 14
        PUSHBUTTON      "&Cancel", IDCANCEL, 174, 36, 50, 14
        GROUPBOX        "About this program...", IDC_STATIC, 7, 7, 225, 52
        CTEXT           "An example program\r\nBy vexe", IDC_STATIC, 16, 18, 144, 33
}

更改样式、标题、字体大小等不会改变任何内容。请注意,我使用的是 Windows 经典主题,更改为标准 Windows 7 也无济于事,因此这不是主题问题。

这是我的窗口代码:

#include <Windows.h>
#include "resource.h"

INT_PTR WINAPI DialogWndProc(HWND Window, UINT Message,
                             WPARAM WParam, LPARAM LParam)
{
    INT_PTR Result = TRUE;

    switch (Message)
    {
        case WM_INITDIALOG:
        {
            // UpdateWindow(Window); // Doesn't really help. Taking out the case didn't do anything either
        }
        break;

        case WM_COMMAND:
        {
            int Command = LOWORD(WParam);
            switch(Command)
            {
                case IDOK:
                {
                    EndDialog(Window, IDOK);
                }
                break;

                case IDCANCEL:
                {
                    EndDialog(Window, IDCANCEL);
                }
                break;

                default:
                {
                    Result = FALSE;
                }
                break;
            }
        }
        break;
    }

    return(Result);
}

LRESULT WINAPI MainWndProc(HWND Window, UINT Message, 
                           WPARAM WParam, LPARAM LParam)
{
    LRESULT Result = 0;

    switch (Message)
    {
        // (Causes GetMessage to return false)
        case WM_CLOSE:
        {
            DestroyWindow(Window);
        }
        break;

        case WM_DESTROY:
        {
            PostQuitMessage(0);
        }
        break;

        case WM_COMMAND:
        {
            int Command = LOWORD(WParam);
            switch (Command)
            {
                case ID_MENU_FILE_EXIT:
                {
                    PostMessage(Window, WM_QUIT, 0, 0);
                }
                break;

                case ID_MENU_HELP_ABOUT:
                {
                    int Choice = DialogBox(0, MAKEINTRESOURCE(ID_DIALOG_ABOUT), Window, DialogWndProc);
                    switch (Choice)
                    {
                        case IDOK: MessageBox(Window, "Okay!", "OK", MB_OK | MB_ICONINFORMATION); break;
                        case IDCANCEL: MessageBox(Window, "Canceled!", "Cancel", MB_OK | MB_ICONINFORMATION); break;
                    }
                }
                break;
            }
        }
        break;

        case WM_CREATE:
        {
            HMENU Menu;
            HMENU SubMenu;

            // Create the main menu
            Menu = CreateMenu();

            // Create submenus
            {
                SubMenu = CreatePopupMenu();
                AppendMenu(SubMenu, MF_STRING, ID_MENU_FILE_EXIT, "E&xit");
                AppendMenu(Menu, MF_STRING | MF_POPUP, (UINT_PTR)SubMenu, "&File");

                SubMenu = CreatePopupMenu();
                AppendMenu(SubMenu, MF_STRING, ID_MENU_HELP_ABOUT, "&About");
                AppendMenu(Menu, MF_STRING | MF_POPUP, (UINT_PTR)SubMenu, "&Help");
            }

            // Set the menu on the window
            SetMenu(Window, Menu);
        }
        break;

        default:
        {
            Result = DefWindowProc(Window, Message, WParam, LParam);
        }
    }

    return(Result);
}

int CALLBACK WinMain(HINSTANCE Instance, HINSTANCE Previous, LPSTR CommandLine, int CmdShow)
{
    // Create window class
    WNDCLASSEX WindowClass = {0};
    WindowClass.cbSize = sizeof(WNDCLASSEX);
    WindowClass.style = CS_HREDRAW | CS_VREDRAW;
    WindowClass.lpfnWndProc = (WNDPROC)MainWndProc;
    WindowClass.hInstance = Instance;
    WindowClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
    WindowClass.lpszMenuName = MAKEINTRESOURCE(ID_MENU_MAIN);
    WindowClass.lpszClassName = "SaedoGames_0";
    WindowClass.hIcon = LoadIcon(Instance, MAKEINTRESOURCE(ID_ICON_MAIN));
    WindowClass.hIconSm = (HICON)LoadImage(0, "Smile.ico", IMAGE_ICON, 16, 16, LR_LOADFROMFILE);
    RegisterClassEx(&WindowClass);

    // Create window
    HWND Window = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW, "SaedoGames_0", "Test Window",
        WS_OVERLAPPEDWINDOW | WS_VISIBLE,
        CW_USEDEFAULT, CW_USEDEFAULT,
        640, 480,
        0, 0,
        Instance, 0
    );

    // Show window
    ShowWindow(Window, CmdShow);
    UpdateWindow(Window);

    // Message loop
    MSG Msg;
    while (GetMessage(&Msg, Window, 0, 0) > 0)
    {
        TranslateMessage(&Msg);
        DispatchMessage(&Msg);
    }

    return(0);
}

很确定我错过了一个简单的函数调用,但不确定它是什么。我错过了什么?

【问题讨论】:

  • 尝试 WS_OVERLAPPED(WINDOW) 而不是 WS_POPUP
  • @VuVirt 这并没有起到什么作用。 andlabs 的答案是正确的!

标签: c winapi dialog


【解决方案1】:

您的对话过程无条件地向每条消息返回TRUE,这意味着“我处理了消息,您无需执行任何其他操作”。您的对话过程通过在函数顶部将Result 设置为TRUE 来实现这一点,然后永远不要更改它(除非您从未知控件获得WM_COMMAND)。这是错误的;如果您不自己处理消息,则需要返回FALSE

WM_INITDIALOG 是少数直接将其值返回到对话系统而不是通过DWLP_MSGRESULT 的消息之一。在这种情况下并且仅在那种情况下,您确实需要返回 TRUE(除非您手动调整了制表位)。

【讨论】:

  • 解决了!感谢你的回答。这实际上是我的意图。我想说的是:默认情况下它是被处理的(true),除非我遇到一个我不关心的命令。但这不考虑 WM_COMMAND 之外的“其他”类型的消息。
  • 我不确定您对 WM_INITDIALOG 的含义。我现在正在做的是,我将Result 默认设置为 FALSE,当我处理命令案例时设置为 TRUE。即使我将 WM_INITDIALOG 留空(即仍然返回 FALSE),或者将其设置为 TRUE,也不会受到太大影响。 Edit 阅读文档,似乎与键盘焦点有关,如果我返回 TRUE,我将获得默认的键盘焦点。是这样还是有别的?
  • 是的,就是这样。由于您尚未调整键盘焦点,因此应将其保留为默认值。
猜你喜欢
  • 2014-07-14
  • 1970-01-01
  • 1970-01-01
  • 2012-01-10
  • 2014-05-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-15
相关资源
最近更新 更多