Welcome to MSDN Blogs Sign in | Join | Help

The scratch program

Occasionally, there is need to illustrate a point with a full program. To avoid reproducing the boring parts of the program, let's agree on using the following template for our sample programs.

For expository purposes, I won't use a C++ class. I'll just keep all my variables global. In a real program, of course, instance data would be attached to the window instead of floating globally.

#define STRICT
#include <windows.h>
#include <windowsx.h>
#include <ole2.h>
#include <commctrl.h>
#include <shlwapi.h>

HINSTANCE g_hinst;                          /* This application's HINSTANCE */
HWND g_hwndChild;                           /* Optional child window */

/*
 *  OnSize
 *      If we have an inner child, resize it to fit.
 */
void
OnSize(HWND hwnd, UINT state, int cx, int cy)
{
    if (g_hwndChild) {
        MoveWindow(g_hwndChild, 0, 0, cx, cy, TRUE);
    }
}

/*
 *  OnCreate
 *      Applications will typically override this and maybe even
 *      create a child window.
 */
BOOL
OnCreate(HWND hwnd, LPCREATESTRUCT lpcs)
{
    return TRUE;
}

/*
 *  OnDestroy
 *      Post a quit message because our application is over when the
 *      user closes this window.
 */
void
OnDestroy(HWND hwnd)
{
    PostQuitMessage(0);
}

/*
 *  PaintContent
 *      Interesting things will be painted here eventually.
 */
void
PaintContent(HWND hwnd, PAINTSTRUCT *pps)
{
}

/*
 *  OnPaint
 *      Paint the content as part of the paint cycle.
 */
void
OnPaint(HWND hwnd)
{
    PAINTSTRUCT ps;
    BeginPaint(hwnd, &ps);
    PaintContent(hwnd, &ps);
    EndPaint(hwnd, &ps);
}

/*
 *  OnPrintClient
 *      Paint the content as requested by USER.
 */
void
OnPrintClient(HWND hwnd, HDC hdc)
{
    PAINTSTRUCT ps;
    ps.hdc = hdc;
    GetClientRect(hwnd, &ps.rcPaint);
    PaintContent(hwnd, &ps);

}

/*
 *  Window procedure
 */
LRESULT CALLBACK
WndProc(HWND hwnd, UINT uiMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uiMsg) {

    HANDLE_MSG(hwnd, WM_CREATE, OnCreate);
    HANDLE_MSG(hwnd, WM_SIZE, OnSize);
    HANDLE_MSG(hwnd, WM_DESTROY, OnDestroy);
    HANDLE_MSG(hwnd, WM_PAINT, OnPaint);
    case WM_PRINTCLIENT: OnPrintClient(hwnd, (HDC)wParam); return 0;
    }

    return DefWindowProc(hwnd, uiMsg, wParam, lParam);
}

BOOL
InitApp(void)
{
    WNDCLASS wc;

    wc.style = 0;
    wc.lpfnWndProc = WndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = g_hinst;
    wc.hIcon = NULL;
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wc.lpszMenuName = NULL;
    wc.lpszClassName = "Scratch";

    if (!RegisterClass(&wc)) return FALSE;

    InitCommonControls();               /* In case we use a common control */

    return TRUE;
}

int WINAPI WinMain(HINSTANCE hinst, HINSTANCE hinstPrev,
                   LPSTR lpCmdLine, int nShowCmd)
{
    MSG msg;
    HWND hwnd;

    g_hinst = hinst;

    if (!InitApp()) return 0;

    if (SUCCEEDED(CoInitialize(NULL))) {/* In case we use COM */

        hwnd = CreateWindow(
            "Scratch",                      /* Class Name */
            "Scratch",                      /* Title */
            WS_OVERLAPPEDWINDOW,            /* Style */
            CW_USEDEFAULT, CW_USEDEFAULT,   /* Position */
            CW_USEDEFAULT, CW_USEDEFAULT,   /* Size */
            NULL,                           /* Parent */
            NULL,                           /* No menu */
            hinst,                          /* Instance */
            0);                             /* No special parameters */

        ShowWindow(hwnd, nShowCmd);

        while (GetMessage(&msg, NULL, 0, 0)) {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }

        CoUninitialize();
    }

    return 0;
}

Notice that all painting gets funneled through the PaintContent function. This allows us to route the WM_PRINTCLIENT message through the same paint function, which has as an immediate consequence the ability to animate the window with AnimateWindow. This will also prove useful for printing high-resolution screenshots.

Other than the trickiness with painting, there really isn't anything here that you shouldn't already know. The point of this program is to be a template for future programs.

My first mission will be an eight-part series on scrollbars.

That's right. Scrollbars.

I can't believe I have an eight-part series on scrollbars. And you probably can't believe you're reading about it.

Published Wednesday, July 23, 2003 3:46 PM by oldnewthing
Filed under:

Comments

# RE: The scratch program

Wednesday, August 20, 2003 1:06 PM by Jason Doucette
Just a note: MSDN says that InitCommonControls() is obsolete and that new applications should use InitCommonControlsEx().

# How to display a string without those ugly boxes

Friday, July 16, 2004 10:00 AM by The Old New Thing
Use the font-linking functions to change fonts as necessary.

# Querying information from an Explorer window

Tuesday, July 20, 2004 10:02 AM by The Old New Thing
Often programming is just assembling the building blocks you already have.

# Why .shared sections are a security hole

Wednesday, August 04, 2004 11:51 AM by The Old New Thing
They allow information to cross security boundaries.

# Dragging a shell object, part 1: Getting the IDataObject

Monday, December 06, 2004 10:00 AM by The Old New Thing
The shell gives you the IDataObject; all you have to do is drag it around.

# The dangers of filtering window messages

Wednesday, February 09, 2005 10:00 AM by The Old New Thing
Thinking through message pumping.

# Modality, part 1: UI-modality vs code-modality

Friday, February 18, 2005 10:01 AM by The Old New Thing
The two usually agree but are not required to.

# Modality, part 4: The importance of setting the correct owner for modal UI

Wednesday, February 23, 2005 10:00 AM by The Old New Thing
The visual state becomes out of sync with the stack state.

# The dialog manager, part 5: Converting a non-modal dialog box to modal

Monday, April 04, 2005 9:04 AM by The Old New Thing
Writing your own dialog loop.

# What is the DC brush good for?

Wednesday, April 20, 2005 9:04 AM by The Old New Thing
It gives you a one-shot solid color brush.

# How do I cover the taskbar with a fullscreen window?

Thursday, May 05, 2005 9:02 AM by The Old New Thing
The taskbar detects that you created a fullscreen window and gets out of the way automatically.

# The forgotten common controls: The MenuHelp function

Thursday, June 08, 2006 10:00 AM by The Old New Thing
It doesn't really help much.

# Pitfalls of transparent rendering of anti-aliased fonts

Wednesday, June 14, 2006 10:00 AM by The Old New Thing
Transparent text output requires extra attention.

# Coding in-place tooltips

Monday, June 26, 2006 10:00 AM by The Old New Thing
The TTM_ADJUSTRECT message does the heavy lifting.

# Multiplexing multiple tools into one in a tooltip

Wednesday, June 28, 2006 10:00 AM by The Old New Thing
If you have a very high number of tools in one tooltip.

# Blitting between color and monochrome DCs

Tuesday, November 14, 2006 10:00 AM by The Old New Thing

The text foreground and background colors play a role.

# Manipulating the DIB color table for fun and profit

Wednesday, November 15, 2006 10:00 AM by The Old New Thing

Large scale color changes by changing four bytes for each color.

# What is the process by which the cursor gets set?

Tuesday, November 21, 2006 10:00 AM by The Old New Thing

It's just WM_SETCURSOR, but that in itself is rather complicated.

# eschew &raquo; Blog Archive &raquo; links for 2006-11-22

Sunday, November 26, 2006 9:53 PM by eschew » Blog Archive » links for 2006-11-22

# Displaying infotips for folded and unfolded listview items

Wednesday, December 13, 2006 10:00 AM by The Old New Thing

Both require special handling.

# How a bullet turns into a beep

Thursday, January 04, 2007 10:00 AM by The Old New Thing

Bangs or bells.

# The forgotten common controls: The ShowHideMenuCtl function

Tuesday, July 10, 2007 10:25 AM by The Old New Thing

For making dialog controls match a menu, as if anybody even does this any more.

# Steven Engelhardt &raquo; Blog Archive &raquo; Owner-Drawn Tooltips

Tuesday, August 28, 2007 12:55 AM by Steven Engelhardt » Blog Archive » Owner-Drawn Tooltips
New Comments to this post are disabled
 
Page view tracker