Chapter 6
Taking control
Now, taking the concepts and design we went over in chapter five, we’re going to begin adding code to JotStuffDownPad that will make it useful and shiny
Starting off
Begin by starting up Visual Studio and opening the workspace that you created in chapter four. Now, download these two files and save them in the project directory:
These files contain the routines that deal with representing notes internally, so you don’t have to be bothered. My gift to you
Once you’ve downloaded these files, go to the “Project” menu in Visual Studio, select “Add To Project,” and then “Files…”

Select “utilities.cpp” and “utilities.h” and click OK. You can now see those files in the FileView window.
Once you’ve done that, double-click on StdAfx.h. The majority of the code in this file isn’t ever going to be modified, but look for the line that says “Reference additional headers here”:
// TODO: reference additional headers your program requires here
Underneath this, insert the following lines:
#include <string.h> #include "utilities.h"
We’re including the header because, as stated in our design layout, we’ll be storing notes as an array of s. includes the list-handling code in . You don’t *need* to know what this code does line for line, since this is a GUI tutorial and not a string-handling tutorial, but it’s pretty heavily commented in case you want to poke at it anyway.
Now double-click on JotStuffDownPad.cpp. We need to add in some global variables, specifically HWNDs for each of the controls we’re creating. Put these lines at the top of JotStuffDownPad.cpp, underneath :
HWND newButton,deleteButton,saveButton,exitButton; HWND comboNotes; HWND editField;
Now to actually construct those controls! Just to clearly seperate the code, we’ll make a new function called “BuildControls” in which we’ll put all the functions. The only thing we’ll need to pass in is a handle to the parent window because needs it. In a critical function such as this, we should return a to indicate whether the function succeeded (all the controls were successfully created) or failed (one or more didn’t make it). So we add the following prototype…
bool BuildControls(HWND parent);
…and then add this function to JotStuffDownPad.exe:
bool BuildControls(HWND parent)
{
DWORD style, xstyle;
// We almost always use the default extended style
xstyle = WS_EX_LEFT;
// First we'll create the buttons
// We need WS_CHILD because they're controls, but we also want
// WS_VISIBLE so they show up when the window does
style = WS_CHILD | WS_VISIBLE;
// A note about coordinates for controls:
// The x and y coordinates are relative to the upper-left hand corner
// of the parent window. The x and y coordinates given to CreateWindowEx
// tell where the upper-left hand corner of the control is; for example,
// x = 0 and y = 0 will draw the control wedged into the upper-left of the window
int x = 10,y = 10;
// It's a good idea to put the width, height, and space between your controls into variables
// as well; it's easier to modify should you need to and it will help you figure out
// how to place controls relative to each other
int butW = 55, butH = 25, spacer = 10;
newButton = CreateWindowEx(xstyle,
"Button", // Use the predefined control class
"New", // This will be the text displayed on the button
style,
x,y,
butW,butH,
parent, // Here we pass in the parent's window handle
NULL,NULL,NULL); // For controls, the last arguments are NULL
x += butW + spacer; // Draw each button a little farther on down the line
deleteButton = CreateWindowEx(xstyle,"Button","Delete",style,
x,y,butW,butH,
parent,NULL,NULL,NULL);
x += butW + spacer;
saveButton = CreateWindowEx(xstyle,"Button","Save",style,
x,y,butW,butH,
parent,NULL,NULL,NULL);
x += butW + spacer;
exitButton = CreateWindowEx(xstyle,"Button","Exit",style,
x,y,butW,butH,
parent,NULL,NULL,NULL);
// Now for the combobox
// We want it to be a child window and visible, as before,
// but now we'll add a combobox-specific style, CBS_DROPDOWNLIST
// This tells CreateWindowEx that we want a combo box with a non-editable
// text field at the top that only displays the current selection from the dropdown
// list.
// Note that *w*indow styles are prefixed with WS and *c*ombo *b*ox styles are prefixed
// with CBS. This is convenient when you encounter a style that you're not immediately
// with, you can at least tell what it affects
style = WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST;
int cboW = 120,cboH = 120;
x += butW + spacer * 3;
comboNotes = CreateWindowEx(xstyle,"ComboBox","",style,
x,y,cboW,cboH,
parent,NULL,NULL,NULL);
// Finally, we'll create the edit field
// We want the edit box to appear "sunken" into the window (providing a 3D effect),
// so we add a new extended window style:
xstyle = WS_EX_LEFT | WS_EX_CLIENTEDGE;
// We want it to be a child window and visible, as before.
// Additionally, we'll specify a style that aligns the text to the left, a style that
// allows the window to scroll vertically, and a style that lets us put more than one
// line of text in (default is one line only).
style = WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_LEFT | ES_MULTILINE;
// We'll position the text field 5 pixels from the left and 10 pixels below the
// row of buttons. Set x to 5, we set y relative to the buttons
x = 5; y = y + butH + 10;
// We want the edit field to fill the remaining space in the window, so we take the
// window height (400), subtract 30 to space it a little from the bottom, and subtract
// the current top (y) of the edit field. For the width, we take the window width
// (500), subtract 10 to space it a little, and subtract the distance of the left edge
// of the edit field from the left edge of the window (5)
int editH = 400 - 30 - y, editW = 500 - 10 - 5;
editField = CreateWindowEx(xstyle,"Edit","Write things here",style,
x,y,editW,editH,
parent,NULL,NULL,NULL);
// If creation of any control failed (any HWND == NULL), return false
if(!editField || !comboNotes || !newButton || !deleteButton || !saveButton || !exitButton)
return false;
return true;
}
Hopefully the comments will tell you what’s going on in the code
It’s reasonable to point out here that the spacing between controls and the edges of the window is completely up to you. Feel free to insert your own values, and play around with the sizing and positions.
Adding in BuildControls()
Now that is…well, built, it’s time to call it. There are a couple places that we could add in the call; it must be done after the window is created and before the window is visible to the user (no one wants to see a blank window in which controls suddenly appear). Technically we could put the call in immediately before we return successfully…
if(retval == NULL) return NULL; // Something went wrong here if(!BuildControls(retval)) return NULL; // Control creation failed ShowWindow(retval,nCmdShow); // Show the newly created window return retval; // ...and return its handle
…but if we’re trying to do something as soon as the window is created, why not do it when Windows tells us the window is created? I stated earlier that Windows sends a message to your application for just about anything that happens to it; window creation is no exception. MSDN tells us specifically in the message entry that this message is sent immediately after the successful creation of a window by but before the window becomes visible. Exactly what we want! As such, we’ll add a new case into the statement in :
case WM_CREATE: if(!BuildControls(hwnd)) return -1; InitializeNotesList(comboNotes); return 0;
While we’re at it, we’ll also call , defined in , to get the list of notes started off. After doing this, the functions to add, remove, and modify notes can be called with no problem.
The return value from the processing of the WM_CREATE message is important to the continued life of your window. If it is processed by , there is no problem and creation of your window will proceed unhindered (unless hits an error). When the message is processed by the programmer, however, a must be returned in order to successfully complete window creation. If something went wrong and you wish to destroy the window before it is visible (i.e., if creation of the window’s controls failed), returning causes to return NULL, which in turn causes our function to return NULL, which causes our application to stop in its tracks. The circle of life continues!
Build, and gaze upon the wonder!
If you’ve got all the code in properly, you can now press F5 to run JotStuffDownPad in the debugger. Visual Studio will compile your files (hopefully with zero errors; if there are any, go back and check your copying of the code or skip to chapter eight to download the project files), and the beauty of a window with controls will present itself to you!

Now that you’ve gotten this far, go back to and play with the control sizing and spacing. Experiment until you get it to the way you like it!
Summary
We only added one new function to our code, and only learned about one new window message, but look what’s been accomplished! Our application is now the proud parent of six, count ‘em, six children windows in the form of four buttons, a combo box, and an edit field. In the next chapter we’ll put functionality behind the controls…buttons that do things when clicked, imagine that!
