0
votes

I am learning the Win32 API. In my main / first window I would like to have an open window 2 button that then opens a new Window. So the idea is, when the button is pressed a function is called to open window 2. Yet I am not sure how to call this function here:

LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
     switch (message)
    {
        case WM_COMMAND:
        {
            switch(wParam) {
            case OPEN_WINDOW2_BUTTON:
        {}                              // <------------------------- what do I put here?
            }
        }
        case WM_CREATE:{
            AddControls1(hwnd);
            break;
        }
        case WM_DESTROY:
            PostQuitMessage (0);
            break;
        default:

            return DefWindowProc (hwnd, message, wParam, lParam);
        }
        return 0;
}

And here is my entire code:

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

#include <tchar.h>
#include <iostream>
#include <tchar.h>
#include <windows.h>


#define OPEN_WINDOW2_BUTTON 1

using namespace std;

LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK windowprocessforwindow2(HWND handleforwindow2,UINT message,WPARAM wParam,LPARAM lParam);

void AddControls1(HWND);
void createwindow2 (WNDCLASSEX wincl_2, HWND& hwnd, HINSTANCE hThisInstance, int nCmdShow);

HWND hMainWindow, hwnd, hHeader;

TCHAR szClassName[ ] = _T("CodeBlocksWindowsApp");

int WINAPI WinMain(HINSTANCE hThisInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR lpszArgument,
                     int nCmdShow)
{
    bool endprogram=false;

    //create window 1

    MSG messages;            /* Here messages to the application are saved */
    WNDCLASSEX wincl_1;        /* Data structure for the windowclass */

    /* The Window structure */
    wincl_1.hInstance = hThisInstance;
    wincl_1.lpszClassName = szClassName;
    wincl_1.lpfnWndProc = WindowProcedure;      /* This function is called by windows */
    wincl_1.style = CS_DBLCLKS;                 /* Catch double-clicks */
    wincl_1.cbSize = sizeof (WNDCLASSEX);

    /* Use default icon and mouse-pointer */
    wincl_1.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wincl_1.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
    wincl_1.hCursor = LoadCursor (NULL, IDC_ARROW);
    wincl_1.lpszMenuName = NULL;                 /* No menu */
    wincl_1.cbClsExtra = 0;                      /* No extra bytes after the window class */
    wincl_1.cbWndExtra = 0;                      /* structure or the window instance */
    /* Use Windows's default colour as the background of the window */
    wincl_1.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
 //----

    if (!RegisterClassEx (&wincl_1))
        return 0;

    /* The class is registered, let's create the program*/
    hwnd = CreateWindowEx (
           0,                   /* Extended possibilites for variation */
           szClassName,         /* Classname */
           _T("Code::Blocks Template Windows App"),       /* Title Text */
           WS_OVERLAPPEDWINDOW, /* default window */
           CW_USEDEFAULT,       /* Windows decides the position */
           CW_USEDEFAULT,       /* where the window ends up on the screen */
           1800,                 /* The programs width */
           920,                 /* and height in pixels */
           HWND_DESKTOP,        /* The window is a child-window to desktop */
           NULL,                /* No menu */
           hThisInstance,       /* Program Instance handler */
           NULL                 /* No Window Creation data */
           );
    /* Make the window visible on the screen */
    ShowWindow(hwnd,nCmdShow);

    /* 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;
}

void createwindow2 (WNDCLASSEX wincl_2, HWND& hwnd, HINSTANCE hThisInstance, int nCmdShow)
{
    if (!RegisterClassEx (&wincl_2))
    wincl_2.hInstance = hThisInstance;
    wincl_2.lpszClassName = szClassName;
    wincl_2.lpfnWndProc = (WNDPROC)windowprocessforwindow2;      /* This function is called by windows */
    wincl_2.style = CS_DBLCLKS;                 /* Catch double-clicks */
    wincl_2.cbSize = sizeof (WNDCLASSEX);

    /* Use default icon and mouse-pointer */
    wincl_2.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wincl_2.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
    wincl_2.hCursor = LoadCursor (NULL, IDC_ARROW);
    wincl_2.lpszMenuName = NULL;                 /* No menu */
    wincl_2.cbClsExtra = 0;                      /* No extra bytes after the window class */
    wincl_2.cbWndExtra = 0;                      /* structure or the window instance */
    /* Use Windows's default colour as the background of the window */
    wincl_2.hbrBackground = (HBRUSH) COLOR_BACKGROUND;

    HWND handleforwindow2 = CreateWindowEx (
           0,                   /* Extended possibilites for variation */
           szClassName,         /* Classname */
           _T("Code::Blocks Template Windows App"),       /* Title Text */
           WS_OVERLAPPEDWINDOW, /* default window */
           CW_USEDEFAULT,       /* Windows decides the position */
           CW_USEDEFAULT,       /* where the window ends up on the screen */
           330,                 /* The programs width */
           320,                 /* and height in pixels */
           HWND_DESKTOP,        /* The window is a child-window to desktop */
           NULL,                /* No menu */
           hThisInstance,       /* Program Instance handler */
           NULL                 /* No Window Creation data */
           );
    /* Make the window visible on the screen */
    ShowWindow(handleforwindow2,nCmdShow);
}

LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
     switch (message)
    {
        case WM_COMMAND:
        {
            switch(wParam) {
            case OPEN_WINDOW2_BUTTON:
        {}                              // <------------------------- what do I put here?
            }
        }
        case WM_CREATE:{
            AddControls1(hwnd);
            break;
        }
        case WM_DESTROY:
            PostQuitMessage (0);
            break;
        default:

            return DefWindowProc (hwnd, message, wParam, lParam);
        }
        return 0;
}

LRESULT CALLBACK windowprocessforwindow2(HWND handleforwindow2,UINT msg,WPARAM wParam,LPARAM lParam)
{
    switch(msg)
    {
         case WM_COMMAND:
        {
            switch(wParam) {

            }
        }
        case WM_CREATE:{
            AddControls1(hwnd);
            break;
        }
        case WM_DESTROY:
            PostQuitMessage (0);
            break;
        default:

    return DefWindowProc(handleforwindow2,msg,wParam,lParam);
    }
    return 0;
}

void AddControls1(HWND hwnd)
{
    CreateWindowW(L"Button",L" Open Window 2", WS_VISIBLE | WS_CHILD, 215,285,300,30,hwnd, (HMENU)OPEN_WINDOW2_BUTTON,NULL,NULL);
}


Any help would be greatly appreciated. Thanks!

1
If you have a second window, then you must do like for the first one. Create it, and then Show it.Simon Mourier
Fixup AddControls1 to create your child window similar to what you originally did and call AddControls1 in your button handler. Looks like you are calling it already in WM_CREATE but not showing it (ShowWindow).kvr
You also need to specify the behaviour of the new window, i mean do you want the new window to replace the old window or it will be like a popup windowma1169

1 Answers

0
votes

First, you can get the instance handle of the application through the GetWindowLong function.

Then create a WNDCLASSEX structure and pass it into your createwindow2 function.

Finally, it is called in the OPEN_WINDOW2_BUTTON message(The hwnd parameter in the original createwindow2 function is not needed).

The modified code is as follows:

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

#include <tchar.h>
#include <iostream>
#include <tchar.h>
#include <windows.h>


#define OPEN_WINDOW2_BUTTON 1

using namespace std;

LRESULT CALLBACK WindowProcedure(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK windowprocessforwindow2(HWND handleforwindow2, UINT message, WPARAM wParam, LPARAM lParam);

void AddControls1(HWND);
void createwindow2(WNDCLASSEX& wincl_2, HINSTANCE& hThisInstance, int nCmdShow);
void AddControls2(HWND hwnd);
HWND hMainWindow, hwnd, hHeader;

TCHAR szClassName[] = _T("CodeBlocksWindowsApp");
TCHAR szClassName2[] = _T("CodeBlocksWindowsApp2");

int WINAPI WinMain(HINSTANCE hThisInstance,
    HINSTANCE hPrevInstance,
    LPSTR lpszArgument,
    int nCmdShow)
{
    bool endprogram = false;

    //create window 1

    MSG messages;            /* Here messages to the application are saved */
    WNDCLASSEX wincl_1;        /* Data structure for the windowclass */

    /* The Window structure */
    wincl_1.hInstance = hThisInstance;
    wincl_1.lpszClassName = szClassName;
    wincl_1.lpfnWndProc = WindowProcedure;      /* This function is called by windows */
    wincl_1.style = CS_DBLCLKS;                 /* Catch double-clicks */
    wincl_1.cbSize = sizeof(WNDCLASSEX);

    /* Use default icon and mouse-pointer */
    wincl_1.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wincl_1.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
    wincl_1.hCursor = LoadCursor(NULL, IDC_ARROW);
    wincl_1.lpszMenuName = NULL;                 /* No menu */
    wincl_1.cbClsExtra = 0;                      /* No extra bytes after the window class */
    wincl_1.cbWndExtra = 0;                      /* structure or the window instance */
    /* Use Windows's default colour as the background of the window */
    wincl_1.hbrBackground = (HBRUSH)COLOR_BACKGROUND;
    //----

    if (!RegisterClassEx(&wincl_1))
        return 0;

    /* The class is registered, let's create the program*/
    hwnd = CreateWindowEx(
        0,                   /* Extended possibilites for variation */
        szClassName,         /* Classname */
        _T("Code::Blocks Template Windows App"),       /* Title Text */
        WS_OVERLAPPEDWINDOW, /* default window */
        CW_USEDEFAULT,       /* Windows decides the position */
        CW_USEDEFAULT,       /* where the window ends up on the screen */
        1800,                 /* The programs width */
        920,                 /* and height in pixels */
        HWND_DESKTOP,        /* The window is a child-window to desktop */
        NULL,                /* No menu */
        hThisInstance,       /* Program Instance handler */
        NULL                 /* No Window Creation data */
    );
    /* Make the window visible on the screen */
    ShowWindow(hwnd, nCmdShow);

    /* 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;
}

void createwindow2(WNDCLASSEX &wincl_2,HINSTANCE &hThisInstance, int nCmdShow)
{
    wincl_2.hInstance = hThisInstance;
    wincl_2.lpszClassName = szClassName2;
    wincl_2.lpfnWndProc = (WNDPROC)windowprocessforwindow2;      /* This function is called by windows */
    wincl_2.style = CS_DBLCLKS;                 /* Catch double-clicks */
    wincl_2.cbSize = sizeof(WNDCLASSEX);

    /* Use default icon and mouse-pointer */
    wincl_2.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wincl_2.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
    wincl_2.hCursor = LoadCursor(NULL, IDC_ARROW);
    wincl_2.lpszMenuName = NULL;                 /* No menu */
    wincl_2.cbClsExtra = 0;                      /* No extra bytes after the window class */
    wincl_2.cbWndExtra = 0;                      /* structure or the window instance */
    /* Use Windows's default colour as the background of the window */
    wincl_2.hbrBackground = (HBRUSH)COLOR_BACKGROUND;
    if (!RegisterClassEx(&wincl_2))
        return;
    HWND handleforwindow2 = CreateWindowEx(
        0,                   /* Extended possibilites for variation */
        szClassName2,         /* Classname */
        _T("Code::Blocks Template Windows App"),       /* Title Text */
        WS_OVERLAPPEDWINDOW, /* default window */
        CW_USEDEFAULT,       /* Windows decides the position */
        CW_USEDEFAULT,       /* where the window ends up on the screen */
        330,                 /* The programs width */
        320,                 /* and height in pixels */
        HWND_DESKTOP,        /* The window is a child-window to desktop */
        NULL,                /* No menu */
        hThisInstance,       /* Program Instance handler */
        NULL                 /* No Window Creation data */
    );
    /* Make the window visible on the screen */
    ShowWindow(handleforwindow2, nCmdShow);
}

LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
        static HINSTANCE hInstance;
    case WM_COMMAND:
    {
        switch (wParam) {
        case OPEN_WINDOW2_BUTTON:
        {
            WNDCLASSEX w2;
            hInstance = (HINSTANCE)::GetWindowLong(hwnd, GWL_HINSTANCE);
            createwindow2(w2, hInstance,SW_SHOW);
        }                              // <------------------------- what do I put here?
        }
    }
    case WM_CREATE: {
        AddControls1(hwnd);
        break;
    }
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:

        return DefWindowProc(hwnd, message, wParam, lParam);
    }
    return 0;
}

LRESULT CALLBACK windowprocessforwindow2(HWND handleforwindow2, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg)
    {
    case WM_COMMAND:
    {
        switch (wParam) {

        }
    }
    return 0;
    case WM_CREATE: {
        AddControls2(handleforwindow2);
        break;
    }
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:

        return DefWindowProc(handleforwindow2, msg, wParam, lParam);
    }
    return 0;
}

void AddControls1(HWND hwnd)
{
    CreateWindowW(L"Button", L" Open Window 2", WS_VISIBLE | WS_CHILD, 215, 285, 300, 30, hwnd, (HMENU)OPEN_WINDOW2_BUTTON, NULL, NULL);
}

void AddControls2(HWND hwnd)
{
    CreateWindowW(L"Button", L" A NEW WINDOW", WS_VISIBLE | WS_CHILD, 215, 285, 300, 30, hwnd, (HMENU)2, NULL, NULL);
}