How can I destroy one window, and make another within the same program?

Hi all,

I am very new to windows gui programming and I was wondering how I would go about destroying a window and then creating another different window right after.

I am making a sort of database program. The first window that opens asks the user for the name of a file in the same directory. After a non null character array is successfully captured, I would like the program to close the first window, do some background work such as sorting and file I/O, and then make a new window that is different from the inital file selection window.

I was wondering, how to go about this... Can I just call DestroyWindow, do the processing like any console application, and then call CreateWindow with the information for the new window? What code would I need to repeate, and can any of the code that originally came in the project be reused in the new window?

Here is the code I have so far... This makes one window with some form elements, and an alert box if input is null:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#include <windows.h>
char textfilename[50] = ""; // Variable to store the name of the file.

/*  Declare Windows procedure  */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);

/*  Make the class name into a global variable  */
char szClassName[ ] = "Assignment5";

int WINAPI WinMain (HINSTANCE hThisInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR lpszArgument,
                     int nCmdShow)
{
    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 */

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

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

    /* Register the window class, and if it fails quit the program */
    if (!RegisterClassEx (&wincl))
        return 0;

    /* The class is registered, let's create the program*/
    hwnd = CreateWindowEx (
           0,                   /* Extended possibilites for variation */
           szClassName,         /* Classname */
           "Wii Game Organizer",       /* Title Text */
           WS_SYSMENU, /* default window */
           CW_USEDEFAULT,       /* Windows decides the position */
           CW_USEDEFAULT,       /* where the window ends up on the screen */
           400,                 /* The programs width */
           250,                 /* 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;
}

//More global variables, representing the handles for the 3 elements of the ask for file name window... They dont seem to work non global.
HWND TextFileField;
HWND FileField;
HWND OKButtonFileField;

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

            TextFileField = CreateWindow (TEXT("STATIC"), // User prompt
                         TEXT("Enter the name below of the file you want to open. Include the extension."),
                         WS_VISIBLE | WS_CHILD,
                         10,10,380,50,
                         hwnd, (HMENU) NULL,NULL,NULL
                         );
            FileField = CreateWindow (TEXT("edit"), // box to read the file name from
                          TEXT(""),
                          WS_VISIBLE | WS_CHILD | WS_BORDER,
                          50,100,300,20,
                          hwnd,(HMENU) 2, NULL,NULL);
            OKButtonFileField = CreateWindow (TEXT ("BUTTON"), // This is the ok button, which signifies the user is finished typing the file name
                          TEXT("Ok"),
                          WS_VISIBLE | WS_CHILD | WS_BORDER,
                          100,150,200,50,
                          hwnd,(HMENU) 1, NULL, NULL);
            break;
        case WM_COMMAND:

            if (LOWORD(wParam) == 1)
            {
                int gwt; // store the return from GetWindowText(), used for error checking
                gwt = GetWindowText(FileField,textfilename,50);
                if (gwt == 0)
                {
                    MessageBeep(0xFFFFFFFF);
                    ::MessageBox(hwnd, TEXT("Invalid Text File Name"),TEXT("Invalid Name"), MB_OK);
                }
                else
                {
                    //::MessageBox (hwnd,TEXT(textfilename), TEXT("This was what you entered:"), MB_OK);
                    // delete old window and make new window when this point is reached
                }
            }

            break;
        case WM_DESTROY:
            PostQuitMessage (0);       /* send a WM_QUIT to the message queue */
            break;
        default:                      /* for messages that we don't deal with */
            return DefWindowProc (hwnd, message, wParam, lParam);
    }

    return 0;
}


Line 115 is the place of interest, where if that code executes, I would like to destroy the window and proceed with the program (without closing the process)

Also, is there any easy way to redraw an existing window (if for example, I assign variables to staic text boxes, and then the variables change through out the program, can I just refresh the window somehow?)

Thanks so much,
Ryan
Why destroy the data entry window? Just put a "Submit" button on it, a click of which inserts the record in the database, clears the existing text in the data entry text boxes, and awaits for a new piece of data entry in the existing window.

But to exactly answer your question, you can use CreateWindow() or CreateWindowEx() calls to create any kind of window which has been registered with Windows through a RegisterClass() or RegisterClassEx() function call. That isn't exactly right, but 'close enough for goverment work'.
What you're doing is rather non-standard.

The idiomatic approach would be to use a dialog to get the file name. You could either:
- display the dialog before creating the main window, in WinMain
- or create the main window (without making it visible to start with) and then get it to display the dialog. The main window would then be made visible, if the use clicks OK or the app instructed to exit, if they cancel.

It is possible to create a new top level window in your WM_COMMAND handler, but then you would have to make the WM_DESTROY handler smarter so it doesn't just call PostQuitMessage and terminate the program (in both this WndProc and the other one you'll need for your other window)

It would also be possible to code a window which destroys and creates different child windows (or controls). But then the WndProc would get rather messy. You'd need to work what role the window was playing before responding to a message.

The idiomatic solution to your problem would be to use a dialog.

Andy
Last edited on
Thanks for your reply,

What i ended up doing is just destroying the child elements on the inital window, then instead of killing it, i resized it with no reposition set, then drawing new child elemnts on the window after that happens. Seems to work well... though I like the idea of creating a dialog box. unfortunatly it was already due (extension untill midnight though) so I dont think I will be able to implement it in this project.

Id like to thank you both for your replies, and Andy you contributed a lot on various other threads, so thanks a lot.

Ryan
Topic archived. No new replies allowed.