GameProgrammer.org
tutorials for dummies bug source let me google it for you my blog all about me
Basic User Interface
In this tutorial we start using some Windows controls like label, edit box and button. Every Windows control in fact is a window, so you create a windows control using CreateWindowEx(), if you remember from last tutorial we used this command to create our main window. CreateWindowEx() requires a window class that created window will inherit from that, of course you can create the class your self or use a predefined window class, predefined window classes are : BUTTON, EDIT, LISTBOX, MDICLIENT, SCROLLBAR and STATIC.

OK, Let's see the code:

#include <windows.h>

#define BTN_SHOWMESSAGE        1
#define EDT_MESSAGE            2

LRESULT CALLBACK WndProc( HWND hWnd , UINT message , WPARAM wParam , LPARAM lParam)
{
    switch(message){
    case WM_COMMAND:
        if(LOWORD(wParam)==BTN_SHOWMESSAGE){
            char string[256];
            GetDlgItemText(hWnd, EDT_MESSAGE, string, 256);
            MessageBox(hWnd, string, "Welcome",MB_OK);
        }
        break;
    }
    return DefWindowProc(hWnd,message,wParam,lParam);
}

INT WINAPI WinMain( HINSTANCE , HINSTANCE , LPSTR , INT )
{

    // Create A Window Class Structure
    WNDCLASSEX wc;
    wc.cbClsExtra = 0;
    wc.cbSize = sizeof(wc);
    wc.cbWndExtra = 0;
    wc.hbrBackground = GetSysColorBrush(COLOR_BTNFACE);
    wc.hCursor = LoadCursor(NULL, MAKEINTRESOURCE(IDC_ARROW));
    wc.hIcon = LoadIcon(NULL, MAKEINTRESOURCE(IDI_HAND));
    wc.hIconSm = LoadIcon(NULL, MAKEINTRESOURCE(IDI_HAND));
    wc.hInstance = GetModuleHandle(NULL);
    wc.lpfnWndProc = WndProc;
    wc.lpszClassName = "X3D";
    wc.lpszMenuName = NULL;
    wc.style = CS_VREDRAW|CS_HREDRAW|CS_OWNDC;
    
    // Register Window Class
    RegisterClassEx(&wc);
    
    // Create a Window
    HWND hWnd = CreateWindowEx(0,
        "X3D", "X3D Win32 Tutorial 1",
        WS_OVERLAPPEDWINDOW, 100,100,400,200,
        NULL,NULL,wc.hInstance,0);

    // Create a label
    HWND text = CreateWindowEx(0,
        "STATIC", "Welcome!",
        WS_CHILD|WS_VISIBLE, 10,10,100,20,
        hWnd,NULL,NULL,0);

    // Create a edit box
    HWND edit = CreateWindowEx(0,
        "EDIT", "Your Message...",
        WS_CHILD|WS_VISIBLE|WS_BORDER, 10,50,370,20,
        hWnd,(HMENU)EDT_MESSAGE,NULL,0);
    
    // Create a button
    HWND button = CreateWindowEx(0,
        "BUTTON", "Show Message",
        WS_CHILD|WS_VISIBLE, 10,90,100,20,
        hWnd,(HMENU)BTN_SHOWMESSAGE,NULL,0);
    
    ShowWindow(hWnd,SW_SHOW);
    
    // Message Loop
    MSG msg;
    while(GetMessage(&msg,hWnd,0,0)>0){
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    
    return 0;
}

If you compile and run the code, you will see a window containing a label, an edit box and a button. when you click on the button, the message on the edit box will be displayed in a message box.

So let's start explaining the code, First we defined two constant:

#define BTN_SHOWMESSAGE        1
#define EDT_MESSAGE            2

Later we will use this defined values to identify the button and edit box. Then we defined our message processor like this:

LRESULT CALLBACK WndProc( HWND hWnd , UINT message , WPARAM wParam , LPARAM lParam)
{
    switch(message){
    case WM_COMMAND:
        if(LOWORD(wParam)==BTN_SHOWMESSAGE){
            char string[256];
            GetDlgItemText(hWnd, EDT_MESSAGE, string, 256);
            MessageBox(hWnd, string, "Welcome",MB_OK);
        }
        break;
    }
    return DefWindowProc(hWnd,message,wParam,lParam);
}

Here we just processed WM_COMMAND message, This command is sent to message processor when a menu item is selected or when a control sends a message to its parent or when an accelerator keystroke is translated. As we said before, wParam and lParam specify attributes of the message. when WM_COMMAND is sent, low order word of wParam specifies the identifier of the menu item, control or accelerator and high order word of wParam specifies the notification code if the message is from a control ( if the message is form an accelerator, it is 1 and it is 0 if message is form a menu ). After ensuring that the message is WM_COMMAND, we checked low order word of wParam, If the command is sent from "Show Message" button then we get the edit box text by GetDlgItemText() function and display it in a message box. GetDlgItemText() gets four parameters, First parameter is a handle to the dialog box that contains the control, second parameter is the identifier of the control, next is a string buffer to store the message and last parameter is length of the buffer. Now let's see how we can create a label:

// Create a label
HWND text = CreateWindowEx(0,
    "STATIC", "Welcome!",
    WS_CHILD|WS_VISIBLE, 10,10,100,20,
    hWnd,NULL,NULL,0);

As we said before, every windows control is a window and you can create them by CreateWindowEx() function, you just need to specify the window class to "STATIC" to create a text label. Of course WS_CHILD window style is very important, this flag specifies that this window has a parent window which is given by hWnd ( ninth parameter ). Then we create the edit box:

// Create a edit box
HWND edit = CreateWindowEx(0,
    "EDIT", "Your Message...",
    WS_CHILD|WS_VISIBLE|WS_BORDER, 10,50,370,20,
    hWnd,(HMENU)EDT_MESSAGE,NULL,0);

Here we used WS_BORDER flag that indicates a border around the edit box. Another difference is in tenth parameter of CreateWindowEx(), this parameter specifies the identifier of the window, This value must be unique for all controls on a window. Our last control is a button:

// Create a button
HWND button = CreateWindowEx(0,
    "BUTTON", "Show Message",
    WS_CHILD|WS_VISIBLE, 10,90,100,20,
    hWnd,(HMENU)BTN_SHOWMESSAGE,NULL,0);

We set BTN_SHOWMESSAGE to be identifier of the button. At last, message loop has a little difference from previous tutorial:

// Message Loop
MSG msg;
while(GetMessage(&msg,hWnd,0,0)>0){
    TranslateMessage(&msg);
    DispatchMessage(&msg);
}

We used GetMessage() function which is more prefer for windows applications rather than PeekMessage(). GetMessage() makes program to wait until receiving a message by windows, then places the message in the MSG structure which is given. This function returns zero if WM_QUIT message is received and returns -1 if an error accured.

OK, That's it! Now you can use windows controls in your application to create a more user friendly interface. Finally, Don't hesitate to send your questions and/or comments for us!

Good Luck

Posted on : 23 Apr 2004
Vahid Kazemi

Copyright © 2003-2010 Vahid Kazemi, GameProgrammer.org

iPhone Games