📄 diskhandling.c
字号:
hwndParent = GetParent (hwnd) ;
ScreenToClient (hwndParent, (LPPOINT) &rect.left) ;
ScreenToClient (hwndParent, (LPPOINT) &rect.right) ;
/**************************************/
/* Move the disk to its new position. */
/**************************************/
MoveWindow (hwnd,
rect.left,
rect.top,
rect.right - rect.left,
rect.bottom - rect.top, TRUE) ;
/********************************************************/
/* Force the parent window's client area to be redrawn. */
/* This is necessary when the disk moves off of a peg */
/* so that ugly white gaps in the peg aren't left for */
/* indeterminate periods of time. They eventually get */
/* redrawn anyway but this makes it look nicer. */
/********************************************************/
UpdateWindow (hwndParent) ;
}
}
//
// void MainFrame_OnPaint (HWND hwnd)
//
// hwnd Handle of window to which this message applies
//
// PURPOSE: Windows calls this handler when the window needs repainting.
//
// COMMENTS:
//
static void
disk_OnPaint (HWND hwnd)
{
HDC hdc ;
PAINTSTRUCT ps ;
RECT rect ;
HBRUSH hbrush, hbrushOld ;
hdc = BeginPaint (hwnd, &ps) ;
hbrush = CreateSolidBrush (RGB (238, 120, 0)) ;
hbrushOld = SelectBrush (hdc, hbrush) ;
GetClientRect (hwnd, &rect) ;
RoundRect (hdc, rect.left, rect.top, rect.right, rect.bottom,
(rect.right - rect.left) / 5,
(rect.top - rect.bottom) / 5) ;
hbrush = SelectBrush (hdc, hbrushOld) ;
DeleteBrush (hbrush) ;
EndPaint (hwnd, &ps) ;
}
/*************************************************************/
/* */
/* AddDiskToPost */
/* */
/* Add a disk to the indicated post. A disk can only */
/* added to the top of the stack of disks on a post (if */
/* any). Additionally a larger disk may not be placed */
/* on top of a smaller disk. Return TRUE when the disk */
/* is added to the post and FALSE otherwise. */
/*************************************************************/
static BOOL
disk_AddDiskToPost (HWND hwnd, UINT PostNum)
{
int topDiskSize ;
/******************************************************/
/* If there are already disks on the post, */
/* insure that the top disk is larger than this disk. */
/******************************************************/
if (HowMany [PostNum] > 0) {
topDiskSize =
disk_GetDiskSize (WhosOn [PostNum][HowMany [PostNum] - 1]) ;
if (topDiskSize < disk_GetDiskSize (hwnd))
return FALSE ;
}
/*******************************************/
/* Add the disk to the stack on this post. */
/*******************************************/
WhosOn [PostNum][HowMany [PostNum]++] = hwnd ;
disk_SetPostNum (hwnd, PostNum) ;
return TRUE ;
}
/*************************************************************/
/* */
/* RemoveDiskFromPost */
/* */
/* Removes this disk from its current post. A disk can */
/* only be removed from a post when it is the top disk */
/* on the post. Return TRUE when the disk is removed */
/* from the post and FALSE otherwise. */
/*************************************************************/
static BOOL
disk_RemoveDiskFromPost (HWND hwndDisk)
{
/****************************************/
/* Determine which post the disk is on. */
/****************************************/
UINT PostNum = disk_GetPostNum (hwndDisk) ;
/*************************************************/
/* Can only remove the disk if it's the top one. */
/*************************************************/
if (!disk_IsTopDisk (hwndDisk))
return FALSE ;
/***********************************/
/* Remove the disk from the stack. */
/***********************************/
WhosOn [PostNum][--HowMany [PostNum]] = 0 ;
return TRUE ;
}
/******************************************************/
/* */
/* IsTopDisk */
/* */
/* Return TRUE if the disk is the topmost on its peg. */
/* Return FALSE otherwise. */
/******************************************************/
static BOOL
disk_IsTopDisk (HWND hwndDisk)
{
UINT PostNum ;
PostNum = disk_GetPostNum (hwndDisk) ;
return
(WhosOn [PostNum][HowMany [PostNum] - 1] == hwndDisk) ? TRUE : FALSE ;
}
/******************************************************/
/* */
/* PositionDiskWindow */
/* */
/* Move the window representing a disk to the proper */
/* position in the main application window's client */
/* area. */
/******************************************************/
void
disk_PositionDiskWindow (HWND hwndDisk)
{
HDC hdc ;
int HorzPos;
int VertPos ;
RECT rect ;
UINT i;
UINT DiskSize;
UINT PostNum ;
/*******************************************/
/* Get the important info about this disk. */
/*******************************************/
DiskSize = disk_GetDiskSize (hwndDisk) ;
PostNum = disk_GetPostNum (hwndDisk) ;
/************************************/
/* Determine its stacking position. */
/************************************/
for (i = 0; i < HowMany [PostNum]; i++)
if (WhosOn [PostNum][i] == hwndDisk)
break ;
/***************************************/
/* Calculate the position of the disk. */
/***************************************/
SetRectEmpty (&rect) ;
HorzPos = PostNum == FIRST ? LEFTPOSTPOS :
PostNum == SECOND ? CENTERPOSTPOS : RIGHTPOSTPOS ;
VertPos = (2 * i + 1) * DISKHEIGHT ;
OffsetRect (&rect, HorzPos, VertPos) ;
InflateRect (&rect, DISKWIDTHUNIT * (DiskSize + 2), DISKHEIGHT) ;
/********************************************************/
/* MoveWindow requires device coordinates. */
/* Translate logical coordinates to device coordinates. */
/********************************************************/
hdc = GetDC (GetParent (hwndDisk)) ;
LPtoDP (hdc, (LPPOINT) &rect, 2) ;
ReleaseDC (GetParent (hwndDisk), hdc) ;
MoveWindow (hwndDisk, rect.left, rect.bottom,
rect.right - rect.left, rect.top - rect.bottom, TRUE) ;
}
/******************************************************/
/* */
/* MoveTower */
/* */
/* Move an arbitrarily high tower of disks from one */
/* peg to another using a third as an intermediate. */
/******************************************************/
void
disk_MoveTower (UINT cDisks, UINT FromPeg, UINT AuxPeg, UINT ToPeg)
{
if (cDisks == 1)
disk_MoveOneDisk (FromPeg, ToPeg) ;
else {
disk_MoveTower (cDisks - 1, FromPeg, ToPeg, AuxPeg) ;
disk_MoveOneDisk (FromPeg, ToPeg) ;
disk_MoveTower (cDisks - 1, AuxPeg, FromPeg, ToPeg) ;
}
}
/**************************************************/
/* */
/* MoveOneDisk */
/* */
/* Move the top disk from one peg to another peg. */
/**************************************************/
static void
disk_MoveOneDisk (UINT FromPeg, UINT ToPeg)
{
HWND hwndDisk ;
/* Locate the top disk on the source peg. */
hwndDisk = WhosOn [FromPeg][HowMany [FromPeg] - 1] ;
/* Wait for a while... */
disk_TwiddleThumbs (GetParent (hwndDisk), 1250) ;
/* Take it off the source peg. */
disk_RemoveDiskFromPost (hwndDisk) ;
/* Put it on the destination peg. */
disk_AddDiskToPost (hwndDisk, ToPeg) ;
/* Update the display. */
disk_PositionDiskWindow (hwndDisk) ;
}
/***********************************************/
/* */
/* TwiddleThumbs */
/* */
/* Twiddle our thumbs (figuratively of course) */
/* for the specified length of time. Allow the */
/* user to close the program while we're so */
/* occupied. */
/***********************************************/
static void
disk_TwiddleThumbs (HWND hwnd, UINT Delay)
{
MSG msg ;
SetTimer (hwnd, 60, Delay, NULL) ;
while (GetMessage (&msg, 0, 0, 0)) {
if (msg.message == WM_TIMER) {
KillTimer (hwnd, 60) ;
return ;
}
else if (msg.message == WM_LBUTTONDOWN ||
msg.message == WM_LBUTTONUP)
continue ;
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
RaiseException (STATUS_TERMINATION_REQUEST,// exception code
EXCEPTION_NONCONTINUABLE, // continuable exception flag
0, // number of arguments in array
NULL) ; // address of array of arguments
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -