Windows API CreateDialog:无法显示无模式对话框

时间:2014-01-17 07:44:56

标签: windows winapi user-interface window

即使经过广泛的Google搜索,我也无法弄清楚如何制作无模式对话框。 我想要做的是通过按主窗口上的按钮来触发对话框。

(所以,让我把所有的东西都放在这里。我没有把所有的东西放在一边,以免它看起来太乱了。)

我的代码如下:

#include "main.h"
#include "resource.h"
 #include <tchar.h>

INT_PTR CALLBACK AboutDlgProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
switch(Message)
{
    case WM_INITDIALOG:
    return TRUE;
    break;
    case WM_COMMAND:
        switch(LOWORD(wParam))
        {
            case IDOK:
                EndDialog(hwnd, IDOK);
            break;
            case IDCANCEL:
                EndDialog(hwnd, IDCANCEL);
            break;
        }
    break;
    default:
        return FALSE;
}
return TRUE;
}

LRESULT CALLBACK MainWinProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_COMMAND:
    switch(LOWORD(wParam))
    {
    case ID_FILE_EXIT:
        SendMessage(hwnd, WM_CLOSE, NULL, NULL);
        break;
    case LAUNCH_CONSOLE:
        HWND aDiag = CreateDialog((HINSTANCE) GetWindowLong(hwnd, GWL_HINSTANCE), MAKEINTRESOURCE(IDD_DIALOG1), hwnd, (DLGPROC) AboutDlgProc);
        if(aDiag == NULL)
    {
        MessageBox(hwnd, TEXT("Error"), TEXT("Error"), MB_OK);
        DWORD dwLE = GetLastError();
        TCHAR szLE[16];
        _ltoa_s(dwLE, szLE, 10 );
        MessageBox(hwnd, szLE, TEXT("Error"), MB_OK); 
    }
        ShowWindow(aDiag, SW_SHOW);
        break;
    }
    break;
case WM_CLOSE:
    DestroyWindow(hwnd);
    break;
case WM_DESTROY:
    PostQuitMessage(0);
    break;
default:
    break;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASS mainWindowClass = {};
mainWindowClass.style = CS_HREDRAW | CS_VREDRAW;
mainWindowClass.lpfnWndProc = MainWinProc;
mainWindowClass.hInstance = hInstance;
mainWindowClass.hbrBackground = (HBRUSH) COLOR_WINDOW;
mainWindowClass.lpszMenuName = MAKEINTRESOURCE(IDR_MENU1);
mainWindowClass.lpszClassName = TEXT("MainWindow");

RegisterClass(&mainWindowClass);
LONG units = GetDialogBaseUnits();
HWND aWindow = CreateWindow(TEXT("MainWindow"), TEXT("Briancheung"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
HWND aButton = CreateWindow("BUTTON", TEXT("Try"), WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, 100, 100, 50, 50, aWindow, (HMENU) LAUNCH_CONSOLE, hInstance, NULL);
ShowWindow(aWindow, SW_NORMAL);
MSG aMsg = {};
while(GetMessage(&aMsg, NULL, 0, 0))
{
    TranslateMessage(&aMsg);
    DispatchMessage(&aMsg);
}

return 0;
}

我的资源模板是VS2012生成的:

// Microsoft Visual C++ generated resource script.
//
#include "resource.h"

#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"

/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS

/////////////////////////////////////////////////////////////////////////////
// Chinese (Simplified, PRC) resources

#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED

#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//

1 TEXTINCLUDE 
BEGIN
"resource.h\0"
END

2 TEXTINCLUDE 
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END

3 TEXTINCLUDE 
BEGIN
"\r\n"
"\0"
END

#endif    // APSTUDIO_INVOKED

#endif    // Chinese (Simplified, PRC) resources
/////////////////////////////////////////////////////////////////////////////


/////////////////////////////////////////////////////////////////////////////
// Chinese (Traditional, Hong Kong S.A.R.) resources

#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ZHH)
LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_HONGKONG

/////////////////////////////////////////////////////////////////////////////
//
// Menu
//

IDR_MENU1 MENU
BEGIN
POPUP "File"
BEGIN
    MENUITEM "New",                         ID_FILE_NEW40001
    MENUITEM "Open",                        ID_FILE_OPEN40002
    MENUITEM SEPARATOR
    MENUITEM "Save",                        ID_FILE_SAVE40003
    MENUITEM "Save As",                     ID_FILE_SAVEAS
    MENUITEM SEPARATOR
    MENUITEM "Exit",                        ID_FILE_EXIT
END
POPUP "View"
BEGIN
    MENUITEM "Properties",                  ID_VIEW_PROPERTIES
END
POPUP "Help"
BEGIN
    MENUITEM "About",                       ID_HELP_ABOUT
END
END


/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//

IDD_DIALOG1 DIALOGEX 0, 0, 309, 90
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Dialog"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON   "OK",IDOK,198,69,50,14
PUSHBUTTON      "Cancel",IDCANCEL,252,69,50,14
CONTROL         "",IDC_OCX1,"{6BF52A52-394A-11D3-B153-00C04F79FAA6}",WS_TABSTOP,23,24,259,25
END


/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//

#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
IDD_DIALOG1, DIALOG
BEGIN
    LEFTMARGIN, 7
    RIGHTMARGIN, 302
    TOPMARGIN, 7
    BOTTOMMARGIN, 83
END
END
#endif    // APSTUDIO_INVOKED


/////////////////////////////////////////////////////////////////////////////
//
// Dialog Info
//

IDD_DIALOG1 DLGINIT
BEGIN
IDC_OCX1, 0x376, 166, 0
0x0000, 0x0000, 0x0300, 0x0000, 0x0008, 0x0000, 0x0000, 0x0005, 0x0000, 
0x0000, 0x0000, 0x3ff0, 0x0003, 0x0000, 0x0000, 0x0005, 0x0000, 0x0000, 
0x0000, 0x0000, 0x0008, 0x0002, 0x0000, 0x0000, 0x0003, 0x0001, 0x0000, 
0x000b, 0xffff, 0x0003, 0x0000, 0x0000, 0x000b, 0xffff, 0x0008, 0x0002, 
0x0000, 0x0000, 0x0003, 0x0032, 0x0000, 0x000b, 0x0000, 0x0008, 0x000a, 
0x0000, 0x0066, 0x0075, 0x006c, 0x006c, 0x0000, 0x000b, 0x0000, 0x000b, 
0x0000, 0x000b, 0xffff, 0x000b, 0xffff, 0x000b, 0x0000, 0x0008, 0x0002, 
0x0000, 0x0000, 0x0008, 0x0002, 0x0000, 0x0000, 0x0008, 0x0002, 0x0000, 
0x0000, 0x0008, 0x0002, 0x0000, 0x0000, 0x000b, 0x0000, 0x2834, 0x0000, 
0x043d, 0x0000, 
0
END

#endif    // Chinese (Traditional, Hong Kong S.A.R.) resources
/////////////////////////////////////////////////////////////////////////////



#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//


/////////////////////////////////////////////////////////////////////////////
#endif    // not APSTUDIO_INVOKED

一切似乎都没问题。该程序编译。 GetLastError为0.但是对话框不会显示出来。单击“尝试”按钮后,主窗口将关闭。

非常感谢您的评论和帮助。我很少在这里提问,因为大多数问题都可以通过谷歌搜索和修补来解决。但这个真的很难。我认为它应该非常简单,因为对话框是GUI中最基本的东西之一。

我的编程经验主要集中在Java之前。我想感叹Windows C更难,因为似乎没有太多警告来自编译器或IDE。

2 个答案:

答案 0 :(得分:3)

将代码的上述部分包含在{ }中,并告诉我们会发生什么。

您需要像这样修改WM_COMMAND代码:

case WM_COMMAND:
    switch(LOWORD(wParam))
    {
    case LAUNCH_CONSOLE:
        {
            HWND aDiag = CreateDialog( (HINSTANCE) GetWindowLong(hwnd, GWL_HINSTANCE),
                MAKEINTRESOURCE(IDD_DIALOG1), 
                hwnd, 
                (DLGPROC) AboutDlgProc );

           if(aDiag == NULL)
           {
                MessageBox(hwnd, TEXT("Error"), TEXT("Error"), MB_OK);
                DWORD dwLE = GetLastError();
                TCHAR szLE[16];
               _ltoa_s(dwLE, szLE, 10 );
               MessageBox(hwnd, szLE, TEXT("Error"), MB_OK); 
           }
           ShowWindow(aDiag, SW_SHOW);
           break;
        }
    // other commands

由于您已经要求一个小型演示应用程序演示按钮单击时创建对话框,因此以下是您可以复制/粘贴空.cpp文件的代码。 只需在.rc编辑器中创建自己的对话框:

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

INT_PTR CALLBACK AboutDlgProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
    switch(Message)
    {
    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;
    }
    return TRUE;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch(msg)
    {
    case WM_CREATE:
        CreateWindowEx( 0, L"Button", 
            L"Click me!", 
            WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
            50, 20, 100, 50, 
            hwnd, (HMENU)8000, 
            GetModuleHandle(NULL), 0 );
        return (LRESULT)0;
    case WM_COMMAND:
        switch( LOWORD(wParam) )
        {
        case 8000:
            {
                HWND hDlg = CreateDialog( GetModuleHandle(NULL),
                    MAKEINTRESOURCE(IDD_DIALOG1), 
                    hwnd,
                    AboutDlgProc );

                ShowWindow( hDlg, SW_SHOW );
            }
            break;
        default:
            break;
        }
        return (LRESULT)0;
    case WM_CLOSE:
        DestroyWindow(hwnd);
        return (LRESULT)0;
    case WM_DESTROY:
        PostQuitMessage(0);
        return (LRESULT)0;
    default:
        return DefWindowProc(hwnd, msg, wParam, lParam);
    }
    return 0;
}

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

    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  = NULL;
    wc.lpszClassName = L"Main_Window";
    wc.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);

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


    hwnd = CreateWindowEx(
            WS_EX_CLIENTEDGE,
            L"Main_Window",
            L"Test application",
            WS_OVERLAPPEDWINDOW,
            CW_USEDEFAULT, CW_USEDEFAULT, 240, 120,
            NULL, NULL, hInstance, NULL);

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

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

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

资源文件的编辑添加代码:

Resource.h

//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by resource.rc
//
#define IDD_DIALOG1                     101

// Next default values for new objects
// 
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE        102
#define _APS_NEXT_COMMAND_VALUE         40001
#define _APS_NEXT_CONTROL_VALUE         1001
#define _APS_NEXT_SYMED_VALUE           101
#endif
#endif

.rc档案:

// Microsoft Visual C++ generated resource script.
//
#include "resource.h"

#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"

/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS

/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources

#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32

#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//

1 TEXTINCLUDE 
BEGIN
    "resource.h\0"
END

2 TEXTINCLUDE 
BEGIN
    "#include ""afxres.h""\r\n"
    "\0"
END

3 TEXTINCLUDE 
BEGIN
    "\r\n"
    "\0"
END

#endif    // APSTUDIO_INVOKED


/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//

IDD_DIALOG1 DIALOGEX 0, 0, 316, 180
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Dialog"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
    DEFPUSHBUTTON   "OK",IDOK,205,159,50,14
    PUSHBUTTON      "Cancel",IDCANCEL,259,159,50,14
END


/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//

#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO 
BEGIN
    IDD_DIALOG1, DIALOG
    BEGIN
        LEFTMARGIN, 7
        RIGHTMARGIN, 309
        TOPMARGIN, 7
        BOTTOMMARGIN, 173
    END
END
#endif    // APSTUDIO_INVOKED

#endif    // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////



#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//


/////////////////////////////////////////////////////////////////////////////
#endif    // not APSTUDIO_INVOKED

答案 1 :(得分:2)

“主”WM_COMMAND处理错误,切换结束时没有中断。

因此,当WM_COMMANDID_FILE_EXITLAUNCH_CONSOLE处理LOWORD(wParam)时,WM_CLOSE代码将被执行。

使用:

case WM_COMMAND:
   switch(LOWORD(wParam))
   {
      case ID_FILE_EXIT:
         SendMessage(hwnd, WM_CLOSE, NULL, NULL);
         break;
      case LAUNCH_CONSOLE:
         HWND aDiag = CreateDialog((HINSTANCE) GetWindowLong(hwnd, GWL_INSTANCE),
                                   MAKEINTRESOURCE(IDD_DIALOG1), NULL,
                                   (DLGPROC),AboutDlgProc);
         ShowWindow(aDiag, SW_SHOW);
         break;
   }
   break; // <== breaking WM_COMMAND

编辑:如何查看GetLastError

的结果
DWORD dwLE = GetLastError();
TCHAR szLE[16];
_ltot( dwLe, szLE, 10 );
MessageBox(hwnd, szLE, TEXT("Error"), MB_OK);