2025-11-28 00:35:46 +09:00

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;
}