Dialog Boxes
here we will cover a dialog box, with a dialog box you will be able to do
all the basic Windows programming you'll ever want to do!
First, a little background...
Windows runs as a messaging system. Everything you see in windows (edit boxes, buttons, etc.)
is actually classified as a "window". All these windows communicate with each other by sending
messages. Windows OS is very much a messaging system. In future lessons we'll cover how to tell
Windows to listen for messages, but for now it will do it automatically - however you'll still catch
the messages you want to listen for.
Now to the hard stuff!...
To create a dialog box you go to Project->Add Resource... and then choose Dialog and press "New".
Here you are presented with a fresh dialog box! It will have an OK and CANCEL button on it.
If you right click the dialog box and choose properites, it will bring up the properties panel.
This has many different settings you can use to adjust the look and feel of the box. Here are the
ones we want to mess with.. first "Caption".
Change "Caption" to read what you want, I put "My First Dialog Box". After you type it and hit enter you will see the caption reflected in the actual dialog
on the left.
Next, look for a property named "Visible", you'll want to set this to "true" so the dialog
will be visible when it starts up.
Now, go near the bottom and look for "Center", set this to "true" as well so it appears in the center of the screen :)
Finally, we need to change the ID of the dialog box to something more suitable. Look for the "ID", it will say IDD_DIALOG1 - change it to something you
would prefer, but keep the IDD_ prefix. I'll call mine IDD_MYDIALOG
Ok, so now arrange the OK and Cancel buttons as you would like them to appear, and make the dialog box
a size you want. When you are done, hit the exclamation button in the top left corner of visual studio -
it will give you a quick preview of your dialog.
Now back to code! Create a winmain.cpp file that has the winmain entry point function. Remember that I
said windows was based on messaging? Well we need to make a function that receives all the windows messages
to our dialog box. The function is standard across dialog windows. Call it whatever you want, but it must look like this:
INT_PTR CALLBACK DialogMessages(
HWND hwnd, // handle to dialog box
UINT uMsg, // message
WPARAM wparam, // first message parameter
LPARAM lparam // second message parameter
)
{
return FALSE;
}
This function, which I called DialogMessages will be called by windows - not you - whenever a message
is sent to the dialog box. Then you can choose if you want to handle the message or not. Put this function
in winmain.cpp, above your winmain entry point. The return value of this function tells windows if we dealt
with the message or not, right now we are not dealing with any of the messages, so we return false. We would
return true if we dealt with the message.
Now, inside winmain we are going to create our dialogbox. The function call to create it and display it is
called DialogBox. This function will create it and wait until the dialog box is closed, once the dialog box
is closed the function will exit and continue with the rest of the winmain function.
DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_MAINDLG),
NULL, DialogMessages);
The first parameter: GetModuleHandle(NULL) is a windows call that gets the instance of our application, no
need to worry about the specifics here - just make sure you put it in :)
The next parameter MAKEINTRESOURCE(IDD_MAINDLG) takes the id of our dialogbox and turns it into a string that
windows associates with the dialogbox we created in our resource editor.
The next parameter is the handle to the parent window that owns this dialog box, we have no parent so it can be NULL.
The final paramter is the function that should be called to receive all the dialog messages, this is the function
that I had you put above winmain which deals with the messages and currently returns false.
Ok! now we just have to receive the messages we are interested in! For now we will listen to the
OK and cancel button. After we get through this app, we're going to spend some intense time on windows
messaging, so don't worry if you dont' understand it all right now.
Go inside the curly braces of your message listening function (I called it DialogMessages). The parameter uMsg is the ID of the message
coming in from windows. We want to use an if statement to see if it matches the windows message BN_CLICKED,
if it does that means a button on the dialog box was clicked. if ( uMsg == BN_CLICKED ). If that conditional
passes then we want to see if it was the OK or the CANCEL button that was pressed. The ok and cancel button
have the ids: IDOK and IDCANCEL.
You can see the IDs by going back to your dialog box (in your solution explorerer under Resource Files). Right click on the OK or the CANCEL button, choose properties, and look
at the ID in the property window. To check if it was the OK button, we need to check the low end of the wparam.
There are 2 parameters passed into your message receiving function, they are called wparam and lparam. They are
basically additional parameters included with the message. They are each 32 bits long (like an int). we check
to see if it is the ok button by checking to see if IDOK is the low 16 bits of the 32 bit wparam.
(did that make your head hurt) ? We do the same with the cancel button. Now, before you freak out -
I'll put the code below with comments - this is very very very tough the first few times through - but soon it will be second nature.
//if the incoming message is a clicked button
if ( uMsg == BN_CLICKED )
{
//LOWORD is a function that returns the
//low 16 bits of wparam, if the match IDOK then the ok
//button was pressed
if (LOWORD(wparam) == IDOK)
{
//ok button was pressed
//return true to tell windows
//we handled the message
return TRUE;
}
//if the ok button wasn't pressed,
//see if it was the cancel button
else if (LOWORD(wparam) == IDCANCEL)
{
//cancel button was pressed
//return true to tell windows
//we handled the message
return TRUE;
}
}
//return FALSE because we didn't handle the message
return FALSE;
now remember, this goes inside your function that receives the mssages
from the dialog box. Finally, you'll want to make sure to include windows.h
and a new one, "resource.h". resource.h is the IDs associated with the
dialog box you created.
EndDialog takes two parameters, the handle to the dialog window and a user parameter
to close with. the handle to the dialog window is passed into the dialog message
function as hwnd. so use that for the first parameter to EndDialog, and the second
paramater we don't care about for now so just make it 0.
so, wherever you want to close the dialog (say when cancel or ok is pressed) call
EndDialog( hwnd, 0 );
__________________________________________________________
#include <stdio.h>
#include <windows.h>
#include "resource.h"
INT_PTR CALLBACK DialogMessages(
HWND hwnd,
UINT uMsg,
WPARAM wparam,
LPARAM lparam
)
{
if ( uMsg == WM_COMMAND )
{
if ( HIWORD(wparam) == BN_CLICKED )
{
if (LOWORD(wparam) == IDOK)
{
MessageBox( NULL,"You pressed the OK button",
"messagebox", MB_OK|MB_ICONEXCLAMATION );
EndDialog( hwnd, 0 );
return TRUE;
}
else if (LOWORD(wparam) == IDCANCEL)
{
EndDialog( hwnd, 0 );
return TRUE;
}
}
}
return FALSE;
}
int WINAPI WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR pCmdLine,
int iCmdShow
)
{
DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_MYDIALOG),
NULL, DialogMessages);
return 0;
}
|