{"id":43073,"date":"2003-07-23T07:00:00","date_gmt":"2003-07-23T07:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2003\/07\/23\/the-scratch-program\/"},"modified":"2003-07-23T07:00:00","modified_gmt":"2003-07-23T07:00:00","slug":"the-scratch-program","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20030723-00\/?p=43073","title":{"rendered":"The scratch program"},"content":{"rendered":"<p>Occasionally, there is need to illustrate a point with a full program. To avoid reproducing the boring parts of the program, let&#8217;s agree on using the following template for our sample programs. <\/p>\n<p>For expository purposes, I won&#8217;t use a C++ class. I&#8217;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. <\/p>\n<pre>#define STRICT\n#include &lt;windows.h&gt;\n#include &lt;windowsx.h&gt;\n#include &lt;ole2.h&gt;\n#include &lt;commctrl.h&gt;\n#include &lt;shlwapi.h&gt;\nHINSTANCE g_hinst;                          \/* This application's HINSTANCE *\/\nHWND g_hwndChild;                           \/* Optional child window *\/\n\/*\n *  OnSize\n *      If we have an inner child, resize it to fit.\n *\/\nvoid\nOnSize(HWND hwnd, UINT state, int cx, int cy)\n{\n    if (g_hwndChild) {\n        MoveWindow(g_hwndChild, 0, 0, cx, cy, TRUE);\n    }\n}\n\/*\n *  OnCreate\n *      Applications will typically override this and maybe even\n *      create a child window.\n *\/\nBOOL\nOnCreate(HWND hwnd, LPCREATESTRUCT lpcs)\n{\n    return TRUE;\n}\n\/*\n *  OnDestroy\n *      Post a quit message because our application is over when the\n *      user closes this window.\n *\/\nvoid\nOnDestroy(HWND hwnd)\n{\n    PostQuitMessage(0);\n}\n\/*\n *  PaintContent\n *      Interesting things will be painted here eventually.\n *\/\nvoid\nPaintContent(HWND hwnd, PAINTSTRUCT *pps)\n{\n}\n\/*\n *  OnPaint\n *      Paint the content as part of the paint cycle.\n *\/\nvoid\nOnPaint(HWND hwnd)\n{\n    PAINTSTRUCT ps;\n    BeginPaint(hwnd, &amp;ps);\n    PaintContent(hwnd, &amp;ps);\n    EndPaint(hwnd, &amp;ps);\n}\n\/*\n *  OnPrintClient\n *      Paint the content as requested by USER.\n *\/\nvoid\nOnPrintClient(HWND hwnd, HDC hdc)\n{\n    PAINTSTRUCT ps;\n    ps.hdc = hdc;\n    GetClientRect(hwnd, &amp;ps.rcPaint);\n    PaintContent(hwnd, &amp;ps);\n}\n\/*\n *  Window procedure\n *\/\nLRESULT CALLBACK\nWndProc(HWND hwnd, UINT uiMsg, WPARAM wParam, LPARAM lParam)\n{\n    switch (uiMsg) {\n    HANDLE_MSG(hwnd, WM_CREATE, OnCreate);\n    HANDLE_MSG(hwnd, WM_SIZE, OnSize);\n    HANDLE_MSG(hwnd, WM_DESTROY, OnDestroy);\n    HANDLE_MSG(hwnd, WM_PAINT, OnPaint);\n    case WM_PRINTCLIENT: OnPrintClient(hwnd, (HDC)wParam); return 0;\n    }\n    return DefWindowProc(hwnd, uiMsg, wParam, lParam);\n}\nBOOL\nInitApp(void)\n{\n    WNDCLASS wc;\n    wc.style = 0;\n    wc.lpfnWndProc = WndProc;\n    wc.cbClsExtra = 0;\n    wc.cbWndExtra = 0;\n    wc.hInstance = g_hinst;\n    wc.hIcon = NULL;\n    wc.hCursor = LoadCursor(NULL, IDC_ARROW);\n    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);\n    wc.lpszMenuName = NULL;\n    wc.lpszClassName = TEXT(\"Scratch\");\n    if (!RegisterClass(&amp;wc)) return FALSE;\n    InitCommonControls();               \/* In case we use a common control *\/\n    return TRUE;\n}\nint WINAPI WinMain(HINSTANCE hinst, HINSTANCE hinstPrev,\n                   LPSTR lpCmdLine, int nShowCmd)\n{\n    MSG msg;\n    HWND hwnd;\n    g_hinst = hinst;\n    if (!InitApp()) return 0;\n    if (SUCCEEDED(CoInitialize(NULL))) {\/* In case we use COM *\/\n        hwnd = CreateWindow(\n            TEXT(\"Scratch\"),                \/* Class Name *\/\n            TEXT(\"Scratch\"),                \/* Title *\/\n            WS_OVERLAPPEDWINDOW,            \/* Style *\/\n            CW_USEDEFAULT, CW_USEDEFAULT,   \/* Position *\/\n            CW_USEDEFAULT, CW_USEDEFAULT,   \/* Size *\/\n            NULL,                           \/* Parent *\/\n            NULL,                           \/* No menu *\/\n            hinst,                          \/* Instance *\/\n            0);                             \/* No special parameters *\/\n        ShowWindow(hwnd, nShowCmd);\n        while (GetMessage(&amp;msg, NULL, 0, 0)) {\n            TranslateMessage(&amp;msg);\n            DispatchMessage(&amp;msg);\n        }\n        CoUninitialize();\n    }\n    return 0;\n}\n<\/pre>\n<p>Notice that all painting gets funneled through\nthe <code>PaintContent<\/code> function.\nThis allows us to route\nthe <code>WM_PRINTCLIENT<\/code> message\nthrough the same paint function,\nwhich has as an immediate consequence\nthe ability to animate the window with <code>AnimateWindow<\/code>.\nThis will also prove useful for printing high-resolution screenshots.\n<\/p>\n<p>Other than the trickiness with painting, there really isn&#8217;t anything here that you shouldn&#8217;t already know. The point of this program is to be a template for future programs. <\/p>\n<p>My first mission will be an eight-part series on scrollbars. <\/p>\n<p>That&#8217;s right. Scrollbars. <\/p>\n<p>I can&#8217;t believe I have an eight-part series on scrollbars. And you probably can&#8217;t believe you&#8217;re reading about it. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>Occasionally, there is need to illustrate a point with a full program. To avoid reproducing the boring parts of the program, let&#8217;s agree on using the following template for our sample programs. For expository purposes, I won&#8217;t use a C++ class. I&#8217;ll just keep all my variables global. In a real program, of course, instance [&hellip;]<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-43073","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Occasionally, there is need to illustrate a point with a full program. To avoid reproducing the boring parts of the program, let&#8217;s agree on using the following template for our sample programs. For expository purposes, I won&#8217;t use a C++ class. I&#8217;ll just keep all my variables global. In a real program, of course, instance [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/43073","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=43073"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/43073\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=43073"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=43073"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=43073"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}