CreateDialog Windows API: The Modeless dialog box does not appear

advertisements

I really can't figure out how to make a modeless dialog box even after googling extensively. What I want to do is to trigger a dialog box by pressing a button on main window.

(So let me put the whole stuff here. I haven't put the whole stuff up before lest it is too messy to read.)

My code is as followed:

#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;
}

My resource template is VS2012 generated:

// 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

Everything seems okay. The program compiles. GetLastError is 0. But the dialog just would not show up. The main window closes after clicking the Try button.

Really thank you for your comment and help. I rarely ask questions in here because most of the problems can be solved by Googling and tinkering. But this one is really difficult. I believe it should be very easy since making a dialog is one of the most basic things in GUI.

My programming experience mainly focuses on Java previously. I want to lament that Windows C is much harder since it seems that not much warning comes from compiler or IDE.


Enclose the above part of your code in { } and tell us what happens.

You need to modify your WM_COMMAND code like this:

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


Since you have asked a small demo application to demonstrate creation of a dialog on button click, here is the code you can copy/paste on empty .cpp file. Just create your own dialog box in .rc editor:

#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;
}

EDIT-ADDED CODE FOR RESOURCE FILES:

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 file:

// 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