modeless dialog box

Posted by suckablesausage on Tue, 16 Jul 2019 23:19:54 +0200

    Dialog boxes are divided into modal and non-modal ones. Modal dialog boxes are commonly used. A new dialog box can be created in the resource file, and then DialogBox can be called in WinMain function to display the dialog box. When the modal dialog box is not closed, the main window can not be operated on, it must be closed before it can be modeless paired. The dialog box is not necessary. The non-modal dialog box is usually created by CreateDialog. In the fifth edition of windows Programming, there is a HexCalc applet. It does not create a new dialog template in the resource file, but in a new way. It has not been used before. After a little time, it feels necessary to write it down.
    After creating an empty project, add the source file, and then add the icon resource as the icon of the program.

HexCalc.cpp:
/*----------------------------------------
HEXCALC.C -- Hexadecimal Calculator
(c) Charles Petzold, 1998
----------------------------------------*/

/*
//HEXCALC.DLG dialog script
//This is the content of HesCalc.dlg

HexCalc DIALOG 100, 100, 102, 122
STYLE WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX
CLASS "HexCalc"
CAPTION "Hex Calculator"
{
            Button button text ID (ascii code) x y width height

        PUSHBUTTON "D", 68, 8, 24, 14, 14
        PUSHBUTTON "A", 65, 8, 40, 14, 14
        PUSHBUTTON "7", 55, 8, 56, 14, 14
        PUSHBUTTON "4", 52, 8, 72, 14, 14
        PUSHBUTTON "1", 49, 8, 88, 14, 14
        PUSHBUTTON "0", 48, 8, 104, 14, 14

        //This is the button that displays the results, initially 0, #define VK_ESCAPE 0x1B
        //When the equal key is pressed, the text of the button is changed. 0x1B is decimal 27.
        PUSHBUTTON "0", 27, 26, 4, 50, 14

        PUSHBUTTON "E", 69, 26, 24, 14, 14
        PUSHBUTTON "B", 66, 26, 40, 14, 14
        PUSHBUTTON "8", 56, 26, 56, 14, 14
        PUSHBUTTON "5", 53, 26, 72, 14, 14
        PUSHBUTTON "2", 50, 26, 88, 14, 14
        PUSHBUTTON "Back", 8, 26, 104, 32, 14
        PUSHBUTTON "C", 67, 44, 40, 14, 14
        PUSHBUTTON "F", 70, 44, 24, 14, 14
        PUSHBUTTON "9", 57, 44, 56, 14, 14
        PUSHBUTTON "6", 54, 44, 72, 14, 14
        PUSHBUTTON "3", 51, 44, 88, 14, 14
        PUSHBUTTON "+", 43, 62, 24, 14, 14
        PUSHBUTTON "-", 45, 62, 40, 14, 14
        PUSHBUTTON "*", 42, 62, 56, 14, 14
        PUSHBUTTON "/", 47, 62, 72, 14, 14
        PUSHBUTTON "%", 37, 62, 88, 14, 14
        PUSHBUTTON "Equals", 61, 62, 104, 32, 14
        PUSHBUTTON "&&", 38, 80, 24, 14, 14
        PUSHBUTTON "|", 124, 80, 40, 14, 14
        PUSHBUTTON "^", 94, 80, 56, 14, 14
        PUSHBUTTON "<", 60, 80, 72, 14, 14
        PUSHBUTTON ">", 62, 80, 88, 14, 14
}
*/

#include <windows.h>

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    PSTR szCmdLine, int iCmdShow)
{
    static TCHAR szAppName[] = TEXT("HexCalc");
    HWND         hwnd;
    MSG          msg;
    WNDCLASS     wndclass;

    wndclass.style = CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc = WndProc;
    wndclass.cbClsExtra = 0;
    wndclass.cbWndExtra = DLGWINDOWEXTRA;    // Note!
    wndclass.hInstance = hInstance;
    wndclass.hIcon = LoadIcon(hInstance, szAppName);
    wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
    wndclass.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
    wndclass.lpszMenuName = NULL;
    wndclass.lpszClassName = TEXT("hexcalc");

    if (!RegisterClass(&wndclass))
    {
        MessageBox(NULL, TEXT("This program requires Windows NT!"),
            szAppName, MB_ICONERROR);
        return 0;
    }

    //No parent window, window class szAppName
    hwnd = CreateDialog(hInstance, szAppName, 0, NULL);

    ShowWindow(hwnd, iCmdShow);

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

//Display results
void ShowNumber(HWND hwnd, UINT iNumber)
{
    TCHAR szBuffer[20];

    wsprintf(szBuffer, TEXT("%X"), iNumber);

    //This is not very good and misleading. The second parameter is the ID of the control. The ID of the button in HexCalc.dlg is 27.
    //It happens to be VK_ESCAPE. The author's intention is that pressing the esc key is equivalent to pressing the button and resetting it.
    SetDlgItemText(hwnd, VK_ESCAPE, szBuffer);
}

//Calculation
DWORD CalcIt(UINT iFirstNum, int iOperation, UINT iNum)
{
    switch (iOperation)
    {
    case '=': return iNum;
    case '+': return iFirstNum + iNum;
    case '-': return iFirstNum - iNum;
    case '*': return iFirstNum *  iNum;
    case '&': return iFirstNum &  iNum;
    case '|': return iFirstNum | iNum;
    case '^': return iFirstNum ^  iNum;
    case '<': return iFirstNum << iNum;
    case '>': return iFirstNum >> iNum;
    case '/': return iNum ? iFirstNum / iNum : MAXDWORD;
    case '%': return iNum ? iFirstNum % iNum : MAXDWORD;
    default: return 0;
    }
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    static BOOL  bNewNumber = TRUE;
    static int   iOperation = '=';
    static UINT  iNumber, iFirstNum;
    HWND         hButton;

    switch (message)
    {
    case WM_KEYDOWN:                   // left arrow --> backspace
        if (wParam != VK_LEFT)      
            break;
        //Pressing the left arrow key is equivalent to backspace
        wParam = VK_BACK;   //#define VK_BACK           0x08
        // fall through
    case WM_CHAR:
        //#define VK_RETURN         0x0D
        //Pressing the Enter key is equivalent to pressing the = key.
        if ((wParam = (WPARAM)CharUpper((TCHAR *)wParam)) == VK_RETURN)
            wParam = '=';

        if (hButton = GetDlgItem(hwnd, wParam))
        {
            SendMessage(hButton, BM_SETSTATE, 1, 0);
            //If not paused, the button will not see the pop-up effect, such as pressing 1, etc.
            Sleep(100);
            SendMessage(hButton, BM_SETSTATE, 0, 0);
        }
        else
        {
            MessageBeep(0);
            break;
        }
        // fall through
    case WM_COMMAND:
        //wParam is the control ID, just above the HesCalc.dlg modeless dialog box is its ASCII code as the ID
        SetFocus(hwnd);

        if (LOWORD(wParam) == VK_BACK)         // backspace
            ShowNumber(hwnd, iNumber /= 16);

        else if (LOWORD(wParam) == VK_ESCAPE)  // escape
            ShowNumber(hwnd, iNumber = 0);

        else if (isxdigit(LOWORD(wParam)))    // hex digit
        {
            if (bNewNumber)
            {
                iFirstNum = iNumber;
                iNumber = 0;
            }
            bNewNumber = FALSE;

            if (iNumber <= MAXDWORD >> 4)
                ShowNumber(hwnd, iNumber = 16 * iNumber + wParam -
                    (isdigit(wParam) ? '0' : 'A' - 10));
            else
                MessageBeep(0);
        }
        else                                    // operation
        {
            if (!bNewNumber)
                ShowNumber(hwnd, iNumber =
                    CalcIt(iFirstNum, iOperation, iNumber));
            bNewNumber = TRUE;
            iOperation = LOWORD(wParam);
        }
        return 0;

    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc(hwnd, message, wParam, lParam);
}

How to add dialog template? That's what the book says.

The book is not particularly clear, but also know the general, click on the "file - new" of vs.-
Documents"

Select Text Files

Then copy the following text in:

//HEXCALC.DLG dialog script
//This is the content of HesCalc.dlg

HexCalc DIALOG 100, 100, 102, 122
STYLE WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX
CLASS "HexCalc"
CAPTION "Hex Calculator"
{
            //Button button text ID (ascii code) x y width height

        PUSHBUTTON "D", 68, 8, 24, 14, 14
        PUSHBUTTON "A", 65, 8, 40, 14, 14
        PUSHBUTTON "7", 55, 8, 56, 14, 14
        PUSHBUTTON "4", 52, 8, 72, 14, 14
        PUSHBUTTON "1", 49, 8, 88, 14, 14
        PUSHBUTTON "0", 48, 8, 104, 14, 14

        //This is the button that displays the results, initially 0, #define VK_ESCAPE 0x1B
        //When the equal key is pressed, the text of the button is changed. 0x1B is decimal 27.
        PUSHBUTTON "0", 27, 26, 4, 50, 14

        PUSHBUTTON "E", 69, 26, 24, 14, 14
        PUSHBUTTON "B", 66, 26, 40, 14, 14
        PUSHBUTTON "8", 56, 26, 56, 14, 14
        PUSHBUTTON "5", 53, 26, 72, 14, 14
        PUSHBUTTON "2", 50, 26, 88, 14, 14
        PUSHBUTTON "Back", 8, 26, 104, 32, 14
        PUSHBUTTON "C", 67, 44, 40, 14, 14
        PUSHBUTTON "F", 70, 44, 24, 14, 14
        PUSHBUTTON "9", 57, 44, 56, 14, 14
        PUSHBUTTON "6", 54, 44, 72, 14, 14
        PUSHBUTTON "3", 51, 44, 88, 14, 14
        PUSHBUTTON "+", 43, 62, 24, 14, 14
        PUSHBUTTON "-", 45, 62, 40, 14, 14
        PUSHBUTTON "*", 42, 62, 56, 14, 14
        PUSHBUTTON "/", 47, 62, 72, 14, 14
        PUSHBUTTON "%", 37, 62, 88, 14, 14
        PUSHBUTTON "Equals", 61, 62, 104, 32, 14
        PUSHBUTTON "&&", 38, 80, 24, 14, 14
        PUSHBUTTON "|", 124, 80, 40, 14, 14
        PUSHBUTTON "^", 94, 80, 56, 14, 14
        PUSHBUTTON "<", 60, 80, 72, 14, 14
        PUSHBUTTON ">", 62, 80, 88, 14, 14
}

Save the file named "HexCalc.dlg"
Then, click Resource View - Right-click Resource File - Resources include

Then make some changes.

Now run the program.

Successfully, it was difficult to create a dialog template in this way before, and when it ran, you could not see the program, but you could find it on the task manager.
By the way, the class name of the window must be the same as the class of the window, otherwise the window will not be seen. Try it, if only the case is different, it is also possible.

Topics: Windows calculator ascii Programming