Date: | July 23, 2003 / year-entry #3 |
Tags: | code |
Orig Link: | https://blogs.msdn.microsoft.com/oldnewthing/20030723-00/?p=43073 |
Comments: | 23 |
Summary: | 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... |
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 = TEXT("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( TEXT("Scratch"), /* Class Name */ TEXT("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 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. |
Comments (23)
Comments are closed. |
Just a note: MSDN says that InitCommonControls() is obsolete and that new applications should use InitCommonControlsEx().
Use the font-linking functions to change fonts as necessary.
Often programming is just assembling the building blocks you already have.
They allow information to cross security boundaries.
The shell gives you the IDataObject; all you have to do is drag it around.
Thinking through message pumping.
The two usually agree but are not required to.
The visual state becomes out of sync with the stack state.
Writing your own dialog loop.
It gives you a one-shot solid color brush.
The taskbar detects that you created a fullscreen window and gets out of the way automatically.
It doesn’t really help much.
Transparent text output requires extra attention.
The TTM_ADJUSTRECT message does the heavy lifting.
If you have a very high number of tools in one tooltip.
The text foreground and background colors play a role.
Large scale color changes by changing four bytes for each color.
It’s just WM_SETCURSOR, but that in itself is rather complicated.
PingBack from http://eschew.org/blog/?p=156
Both require special handling.
Bangs or bells.
For making dialog controls match a menu, as if anybody even does this any more.
PingBack from http://www.deez.info/sengelha/blog/2007/08/28/owner-drawn-tooltips/