对话框没有被创建

时间:2015-03-17 23:19:09

标签: c winapi dialog

在一个简单的WINAPI程序中,我正在创建一个对话框(我用ResEdit创建)。

但是,对话框未显示,DialogBox()调用返回-1。 GetLastError()返回1812(指定的图像文件不包含资源部分。)

的main.cpp

/*default stuff, like including windows.h, etc... */
int WINAPI WinMain (HINSTANCE hThisInstance,
                 HINSTANCE hPrevInstance,
                 LPSTR lpszArgument,
                 int nCmdShow)
{
hInst = hThisInstance;
HWND hwnd;               /* This is the handle for our window */
MSG messages;            /* Here messages to the application are saved */
WNDCLASSEX wincl;        /* Data structure for the windowclass */

/*default stuff, initializing fields of WNDCLASSEX struct */

hwnd = CreateWindowEx (
       0,                   /* Extended possibilites for variation */
       szClassName,         /* Classname */
       _T("Hello World"),   /* Title Text */
       WS_OVERLAPPEDWINDOW, /* default window */
       CW_USEDEFAULT,       /* Windows decides the position */
       CW_USEDEFAULT,       /* where the window ends up on the screen */
       544,                 /* The programs width */
       375,                 /* and height in pixels */
       0,        /* The window is a child-window to desktop */
       NULL,                /* No menu */
       hThisInstance,       /* Program Instance handler */
       NULL                 /* No Window Creation data */
       );
/* Creating controls ... */

/* Make the window visible on the screen */
ShowWindow (hwnd, nCmdShow);

/* Default : message loop. It will run until GetMessage() returns 0 */

/* The program return-value is 0 - The value that PostQuitMessage() gave */
return messages.wParam;
}


/*  This function is called by the Windows function DispatchMessage()  */

LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam,   LPARAM lParam)
{
switch (message)                  /* handle the messages */
{
    case WM_CREATE:
        HMENU hMenu, hSubMenu;
        HICON hIcon, hIconSm;
        hMenu = CreateMenu();
        hSubMenu = CreatePopupMenu();

        AppendMenu(hSubMenu, MF_STRING, ID_FILE_EXIT, "E&xit");
        AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT) hSubMenu, "&File");

        hSubMenu = CreatePopupMenu();
        AppendMenu(hSubMenu, MF_STRING, ID_HELP_ABT, "&About");
        AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT) hSubMenu, "&Help");

        SetMenu(hwnd, hMenu);

        hIcon = (HICON) LoadImage(NULL, "iconBIG.ico", IMAGE_ICON, 32, 32, LR_LOADFROMFILE);
        if (hIcon)
            SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM) hIcon);
        hIconSm = (HICON) LoadImage(NULL, "iconSMALL.ico", IMAGE_ICON, 16, 16, LR_LOADFROMFILE);
        if (hIconSm)
            SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM) hIconSm);

        break;
    case WM_DESTROY:
        PostQuitMessage(0);       /* send a WM_QUIT to the message queue */
        break;
    case WM_COMMAND:
        switch (LOWORD(wParam)) {
        case IDC_ACCEPTBTN:
            /* handling the controls */
            break;
        case ID_FILE_EXIT:
            /* handling more controls ... */
            PostQuitMessage(0);
            break;
        case ID_HELP_ABT:
            int ret = DialogBox(GetModuleHandle, MAKEINTRESOURCE(IDD_DIALOG1), hwnd, myDialog); 
/*PROBLEM: DialogBox returns -1*/

            if (ret == -1) {
                DWORD dw = GetLastError(); // error 1812
                char buffer[70];
                sprintf(buffer, "Failed with %d", dw);


                MessageBox(hwnd, buffer, "", MB_OK);
            }
            break;
        }
        break;
    default:
        return DefWindowProc(hwnd, message, wParam, lParam);
}
return 0;
}
BOOL CALLBACK myDialog(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg) {
case WM_INITDIALOG:
    return TRUE;
case WM_COMMAND:
    switch (LOWORD(wParam)) {
    case IDOK:
        EndDialog(hwnd, IDOK);
        break;
    case IDCANCEL:
        EndDialog(hwnd, IDCANCEL);
        break;
    }
    break;
default: return FALSE;
}
}

resourceDialog.rc

#include <windows.h>
#include <commctrl.h>
#include <richedit.h>
#include "resource.h"

LANGUAGE 0, SUBLANG_NEUTRAL
IDD_DIALOG1 DIALOG 0, 0, 186, 95
STYLE DS_3DLOOK | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_CAPTION |       WS_VISIBLE | WS_POPUP | WS_SYSMENU
CAPTION "Dialog"
FONT 8, "Ms Shell Dlg"
{
GROUPBOX        "Static", 0, 3, 7, 118, 82, 0, WS_EX_LEFT
LTEXT           "hello,\nworld!", 0, 16, 21, 20, 17, SS_LEFT, WS_EX_LEFT
PUSHBUTTON      "Cancel", IDCANCEL, 129, 24, 50, 14, 0, WS_EX_LEFT
DEFPUSHBUTTON   "OK", IDOK, 129, 7, 50, 14, 0, WS_EX_LEFT
}

RESOURCE.H

#ifndef IDC_STATIC
#define IDC_STATIC (-1)
#endif

#define IDD_DIALOG1                             100
/* Dont redefine IDOK and IDCANCEL */
/*#define IDOK                                    40000
#define IDCANCEL                                40001*/

为什么对话框不显示?我正在关注winprog.org的教程并按照他们的说法进行操作。

Ide:代码块 编译:GCC

2 个答案:

答案 0 :(得分:1)

GetModuleHandle是一个功能。您无法将函数的名称传递给HINSTANCE的{​​{1}}参数,并希望它能够正常工作。事实上,即使编译我也很惊讶!为当前可执行文件调用它的正确方法是DialogBox()

但是有更好的方法:GetModuleHandle(NULL)的第一个参数也是可执行文件的WinMain()。只需将其存储在全局变量中,然后直接使用它。


在包含HINSTANCE 之前添加以下行有助于捕获此类错误:

<windows.h>

答案 1 :(得分:1)

全能的Gawd!我不得不重新加入的东西(首先是在那里,对吗?)令人震惊。虽然我赞赏你努力保持问题的简短,但在发布代码片段时需要非常小心。你发布的那个不会编译,然后当它发生时,仍然存在大量的遗漏 - 由于没有逐字发布你的代码,很难知道问题是什么。

这是编辑后main.cpp的内容。我仍然不知道你的问题是什么 - 你可以将这个文件与你自己的文件进行比较,以便为自己推断,我希望如此。 :)

您可能还需要删除用于类注册的结构中的图标引用,因为您在WM_CREATE中设置它

/*
    These are the steps I took.

    1. Add this to the code:

            #if defined(UNICODE) && !defined(_UNICODE)
            #define _UNICODE
            #elif defined(_UNICODE) && !defined(UNICODE)
            #define UNICODE
            #endif

            #include <tchar.h>
            #include <windows.h>
            #include <cstdio>
            #include "resource.h"
            HINSTANCE hInst;
            TCHAR *szClassName = _T("mClassName");

            #define ID_FILE_EXIT    40001
            #define IDC_ACCEPTBTN   40002
            #define ID_HELP_ABT    40003

            BOOL CALLBACK myDialog(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);

    2.  Change
            this: int ret = DialogBox(GetModuleHandle, MAKEINTRESOURCE(IDD_DIALOG1), hwnd, myDialog);

        to
            this: int ret = DialogBox(hInst, MAKEINTRESOURCE(IDD_DIALOG1), hwnd, myDialog);


    3.  Add the message loop back in.
    UpdateWindow(hwnd);

    // Run the message loop. It will run until GetMessage() returns 0
    while (GetMessage (&messages, NULL, 0, 0))
    {
        // Translate virtual-key messages into character messages
        TranslateMessage(&messages);
        // Send message to WindowProcedure
        DispatchMessage(&messages);
    }
    // The program return-value is 0 - The value that PostQuitMessage() gave
    return messages.wParam;

    4. Change the ShowWindow command to this (i.e ignore the nCmdShow var passed to main by the OS
        ShowWindow (hwnd, SW_SHOWNORMAL);

    5. Add in class registration stuff:
        WNDCLASSEX WndClsEx;

        WndClsEx.cbSize        = sizeof(WNDCLASSEX);
        WndClsEx.style         = CS_HREDRAW | CS_VREDRAW;
        WndClsEx.lpfnWndProc   = WindowProcedure;
        WndClsEx.cbClsExtra    = 0;
        WndClsEx.cbWndExtra    = 0;
        WndClsEx.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
        WndClsEx.hCursor       = LoadCursor(NULL, IDC_ARROW);
        WndClsEx.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
        WndClsEx.lpszMenuName  = NULL;
        WndClsEx.lpszClassName = szClassName;
        WndClsEx.hInstance     = hInst;
        WndClsEx.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);

        // Register the window class, and if it fails quit the program
        RegisterClassEx(&WndClsEx);

    6. Add WindowProcedure forward declaration
*/

#if defined(UNICODE) && !defined(_UNICODE)
#define _UNICODE
#elif defined(_UNICODE) && !defined(UNICODE)
#define UNICODE
#endif

#include <tchar.h>
#include <windows.h>
#include <cstdio>
#include "resource.h"
HINSTANCE hInst;
TCHAR *szClassName = _T("mClassName");

#define ID_FILE_EXIT    40001
#define IDC_ACCEPTBTN   40002
#define ID_HELP_ABT    40003

BOOL CALLBACK myDialog(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam,   LPARAM lParam);


/*default stuff, like including windows.h, etc... */
int WINAPI WinMain (HINSTANCE hThisInstance,
                    HINSTANCE hPrevInstance,
                    LPSTR lpszArgument,
                    int nCmdShow)
{
    hInst = hThisInstance;
    HWND hwnd;               /* This is the handle for our window */
    MSG messages;            /* Here messages to the application are saved */
    WNDCLASSEX wincl;        /* Data structure for the windowclass */

    /*default stuff, initializing fields of WNDCLASSEX struct */
    WNDCLASSEX WndClsEx;

    WndClsEx.cbSize        = sizeof(WNDCLASSEX);
    WndClsEx.style         = CS_HREDRAW | CS_VREDRAW;
    WndClsEx.lpfnWndProc   = WindowProcedure;
    WndClsEx.cbClsExtra    = 0;
    WndClsEx.cbWndExtra    = 0;
    WndClsEx.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
    WndClsEx.hCursor       = LoadCursor(NULL, IDC_ARROW);
    WndClsEx.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
    WndClsEx.lpszMenuName  = NULL;
    WndClsEx.lpszClassName = szClassName;
    WndClsEx.hInstance     = hInst;
    WndClsEx.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);


    /* Register the window class, and if it fails quit the program */
    RegisterClassEx(&WndClsEx);


    hwnd = CreateWindowEx (
               0,                   /* Extended possibilites for variation */
               szClassName,         /* Classname */
               _T("Hello World"),   /* Title Text */
               WS_OVERLAPPEDWINDOW, /* default window */
               CW_USEDEFAULT,       /* Windows decides the position */
               CW_USEDEFAULT,       /* where the window ends up on the screen */
               544,                 /* The programs width */
               375,                 /* and height in pixels */
               0,        /* The window is a child-window to desktop */
               NULL,                /* No menu */
               hThisInstance,       /* Program Instance handler */
               NULL                 /* No Window Creation data */
           );
    /* Creating controls ... */

    /* Make the window visible on the screen */
    ShowWindow (hwnd, SW_SHOWNORMAL);

    /* Default : message loop. It will run until GetMessage() returns 0 */
    UpdateWindow(hwnd);

    /* Run the message loop. It will run until GetMessage() returns 0 */
    while (GetMessage (&messages, NULL, 0, 0))
    {
        /* Translate virtual-key messages into character messages */
        TranslateMessage(&messages);
        /* Send message to WindowProcedure */
        DispatchMessage(&messages);
    }

    /* The program return-value is 0 - The value that PostQuitMessage() gave */
    return messages.wParam;
}


/*  This function is called by the Windows function DispatchMessage()  */

LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam,   LPARAM lParam)
{
    switch (message)                  /* handle the messages */
    {
    case WM_CREATE:
        HMENU hMenu, hSubMenu;
        HICON hIcon, hIconSm;
        hMenu = CreateMenu();
        hSubMenu = CreatePopupMenu();

        AppendMenu(hSubMenu, MF_STRING, ID_FILE_EXIT, "E&xit");
        AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT) hSubMenu, "&File");

        hSubMenu = CreatePopupMenu();
        AppendMenu(hSubMenu, MF_STRING, ID_HELP_ABT, "&About");
        AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT) hSubMenu, "&Help");

        SetMenu(hwnd, hMenu);

        hIcon = (HICON) LoadImage(NULL, "iconBIG.ico", IMAGE_ICON, 32, 32, LR_LOADFROMFILE);
        if (hIcon)
            SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM) hIcon);
        hIconSm = (HICON) LoadImage(NULL, "iconSMALL.ico", IMAGE_ICON, 16, 16, LR_LOADFROMFILE);
        if (hIconSm)
            SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM) hIconSm);
        break;

    case WM_DESTROY:
        PostQuitMessage(0);       /* send a WM_QUIT to the message queue */
        break;
    case WM_COMMAND:
        switch (LOWORD(wParam))
        {
        case IDC_ACCEPTBTN:
            /* handling the controls */
            break;
        case ID_FILE_EXIT:
            /* handling more controls ... */
            PostQuitMessage(0);
            break;
        case ID_HELP_ABT:
            int ret = DialogBox(hInst, MAKEINTRESOURCE(IDD_DIALOG1), hwnd, myDialog);
            /*PROBLEM: DialogBox returns -1*/

            if (ret == -1)
            {
                DWORD dw = GetLastError(); // error 1812
                char buffer[70];
                sprintf(buffer, "Failed with %d", dw);


                MessageBox(hwnd, buffer, "", MB_OK);
            }
            break;
        }
        break;
    default:
        return DefWindowProc(hwnd, message, wParam, lParam);
    }
    return 0;
}
BOOL CALLBACK myDialog(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg)
    {
    case WM_INITDIALOG:
        return TRUE;
    case WM_COMMAND:
        switch (LOWORD(wParam))
        {
        case IDOK:
            EndDialog(hwnd, IDOK);
            break;
        case IDCANCEL:
            EndDialog(hwnd, IDCANCEL);
            break;
        }
        break;
    default:
        return FALSE;
    }
}