208 lines
5.6 KiB
C
208 lines
5.6 KiB
C
/*****************************************************************************
|
|
*
|
|
* Fulldrag.c
|
|
*
|
|
* Copyright (c) 1997 Microsoft Corporation.
|
|
*
|
|
* Abstract:
|
|
*
|
|
* Sample program to demonstrate how a program can override
|
|
* Full Drag.
|
|
*
|
|
* This program is to be read in conjunction with KB article Q121541.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
#include "fulldrag.h"
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* Globals
|
|
*
|
|
* g_fMoveSize
|
|
*
|
|
* Set while we are in a move/size loop. The WM_ENTERSIZEMOVE
|
|
* and WM_EXITSIZEMOVE messages tell us when these things happen.
|
|
*
|
|
* g_fPaintDeferred
|
|
*
|
|
* Set if we deferred a paint that occured while we were
|
|
* busy doing a Move/Size. When the Move/Size completes
|
|
* and we discover that a paint was deferred, we force
|
|
* a full repaint to complete the deferred paint.
|
|
*
|
|
*
|
|
* Note:
|
|
*
|
|
* In a real (i.e., non-sample) program, these would not be global
|
|
* variables. They would be per-window variables.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
BOOL g_fDragging;
|
|
BOOL g_fPaintDeferred;
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* Hilbert
|
|
*
|
|
* Draws a segment of the hilbert curve.
|
|
*
|
|
* The math is not important. What is important is that drawing
|
|
* a hilbert curve takes a long time.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
#define MAXDEPTH 8 /* Bigger depth takes longer to draw */
|
|
|
|
void
|
|
Hilbert(HDC hdc, int x, int y, int vx, int vy, int wx, int wy, int n)
|
|
{
|
|
if (n >= MAXDEPTH) {
|
|
LineTo(hdc, x + (vx+wx)/2, y + (vy+wy)/2);
|
|
} else {
|
|
n++;
|
|
Hilbert(hdc, x, y, wx/2, wy/2, vx/2, vy/2, n);
|
|
Hilbert(hdc, x+vx/2, y+vy/2, vx/2, vy/2, wx/2, wy/2, n);
|
|
Hilbert(hdc, x+vx/2+wx/2, y+vy/2+wy/2, vx/2, vy/2, wx/2, wy/2, n);
|
|
Hilbert(hdc, x+vx/2+wx, y+vy/2+wy, -wx/2, -wy/2, -vx/2, -vy/2, n);
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* Hilbert_OnPaint
|
|
*
|
|
* Handle the WM_PAINT message.
|
|
*
|
|
* If the user is dragging the window, then don't do our painting,
|
|
* because that would make the dragging very jerky. Instead, just
|
|
* remember that there was a paint message that we ignored. After
|
|
* the size/move is complete, we will perform one big paint to do
|
|
* the things that we had ignored.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
void
|
|
Hilbert_OnPaint(HWND hwnd)
|
|
{
|
|
PAINTSTRUCT ps;
|
|
HDC hdc;
|
|
|
|
hdc = BeginPaint(hwnd, &ps);
|
|
if (hdc) {
|
|
if (g_fDragging) {
|
|
g_fPaintDeferred = TRUE;
|
|
} else {
|
|
|
|
HBRUSH hbrOld;
|
|
HPEN hpenOld;
|
|
HCURSOR hcurOld;
|
|
|
|
hcurOld = SetCursor(LoadCursor(0, IDC_WAIT));
|
|
|
|
hbrOld = SelectObject(hdc, GetStockObject(BLACK_BRUSH));
|
|
hpenOld = SelectObject(hdc, GetStockObject(BLACK_PEN));
|
|
|
|
MoveToEx(hdc, 0, 0, 0);
|
|
Hilbert(hdc, 0, 0, GetSystemMetrics(SM_CXFULLSCREEN), 0,
|
|
0, GetSystemMetrics(SM_CYFULLSCREEN), 0);
|
|
SelectObject(hdc, hpenOld);
|
|
SelectObject(hdc, hbrOld);
|
|
|
|
SetCursor(hcurOld);
|
|
}
|
|
EndPaint(hwnd, &ps);
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* Hilbert_WndProc
|
|
*
|
|
* Window procedure.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
LRESULT CALLBACK
|
|
Hilbert_WndProc(HWND hwnd, UINT wm, WPARAM wp, LPARAM lp)
|
|
{
|
|
switch (wm) {
|
|
case WM_PAINT:
|
|
Hilbert_OnPaint(hwnd);
|
|
break;
|
|
|
|
case WM_DESTROY:
|
|
PostQuitMessage(0);
|
|
break;
|
|
|
|
/*
|
|
* When we begin a size/move operation, remember the fact
|
|
* so we won't paint during the size/move.
|
|
*/
|
|
case WM_ENTERSIZEMOVE:
|
|
g_fDragging = TRUE;
|
|
break;
|
|
|
|
/*
|
|
* When we finish a size/move operation, remember the fact
|
|
* so we will resume painting, and if there were any deferred
|
|
* paint messages, re-invalidate ourselves so they will be
|
|
* regenerated.
|
|
*/
|
|
case WM_EXITSIZEMOVE:
|
|
g_fDragging = FALSE;
|
|
if (g_fPaintDeferred) {
|
|
g_fPaintDeferred = FALSE;
|
|
InvalidateRect(hwnd, 0, TRUE);
|
|
}
|
|
break;
|
|
|
|
}
|
|
|
|
return DefWindowProc(hwnd, wm, wp, lp);
|
|
}
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* WinMain
|
|
*
|
|
* Program entry point.
|
|
*
|
|
* Register the class, create the window, and go into a message loop.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
int WINAPI
|
|
WinMain(HINSTANCE hinst, HINSTANCE hinstPrev, LPSTR pszCmdLine, int nCmdShow)
|
|
{
|
|
HWND hwnd;
|
|
MSG msg;
|
|
WNDCLASS wc = {
|
|
0,
|
|
Hilbert_WndProc,
|
|
0,
|
|
0,
|
|
hinst,
|
|
LoadIcon(0, IDI_APPLICATION),
|
|
LoadCursor(0, IDC_ARROW),
|
|
(HBRUSH)(COLOR_WINDOW+1),
|
|
0,
|
|
TEXT("Hilbert")
|
|
};
|
|
|
|
RegisterClass(&wc);
|
|
hwnd = CreateWindow(TEXT("Hilbert"),
|
|
TEXT("Hilbert"), WS_OVERLAPPEDWINDOW,
|
|
CW_USEDEFAULT, CW_USEDEFAULT,
|
|
CW_USEDEFAULT, CW_USEDEFAULT,
|
|
0, 0, hinst, 0);
|
|
ShowWindow(hwnd, nCmdShow);
|
|
while (GetMessage(&msg, 0, 0, 0)) {
|
|
TranslateMessage(&msg);
|
|
DispatchMessage(&msg);
|
|
}
|
|
|
|
return 0;
|
|
}
|