📄 diskhandling.c
字号:
#include "StdSDK.h" // Standard application includes
#include "Towers.h" // Application specific declarations
#include "About.h" // For non-static function prototypes
#include "DiskHandling.h" // For non-static function prototypes
#include "resource.h" // For resource identifiers
//
// Function prototypes for static functions
//
static BOOL disk_IsTopDisk (HWND hwndDisk) ;
static BOOL disk_AddDiskToPost (HWND hwnd, UINT PostNum) ;
static void disk_MoveOneDisk (UINT FromPeg, UINT ToPeg) ;
static BOOL disk_RemoveDiskFromPost (HWND hwnd) ;
static void disk_TwiddleThumbs (HWND hwnd, UINT Delay) ;
//
// Static data definitions
//
static POINT ptOrigPos ;
static RECT rectOrigPos ;
//
// Global data definitions
//
HWND WhosOn [THIRD + 1][NUMDISKS] ;
WORD HowMany [THIRD + 1] ;
//
// Function prototypes for message handlers
//
static BOOL disk_OnCreate (HWND hwnd, LPCREATESTRUCT lpCreateStruct) ;
static void disk_OnLButtonDown (HWND hwnd, BOOL fDoubleClick, int x, int y, UINT keyFlags) ;
static void disk_OnLButtonUp (HWND hwnd, int x, int y, UINT keyFlags) ;
static void disk_OnMouseMove (HWND hwnd, int x, int y, UINT keyFlags) ;
static void disk_OnPaint (HWND hwnd) ;
//
// Typedefs
//
//
// LRESULT CALLBACK
// diskWndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
//
// hwnd Handle of window to which this message applies
// message Message number
// wParam Message parameter
// lParam Message parameter
//
// PURPOSE: Processes messages for the main window.
//
// MESSAGES:
//
// WM_CREATE - notification that a window is being created
// WM_LBUTTONDOWN - left button click in client area
// WM_LBUTTONUP - left button release in client area
// WM_MOUSEMOVE - mouse move in client area
// WM_PAINT - redraw all or part of the client area
//
LRESULT CALLBACK
diskWndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message) {
case WM_CREATE: // Notification that a window is being created
return HANDLE_WM_CREATE (hwnd, wParam, lParam, disk_OnCreate) ;
case WM_LBUTTONDOWN: // Left click in windows client area...
return HANDLE_WM_LBUTTONDOWN (hwnd, wParam, lParam, disk_OnLButtonDown) ;
case WM_LBUTTONUP: // Left button up in windows client area...
return HANDLE_WM_LBUTTONUP (hwnd, wParam, lParam, disk_OnLButtonUp) ;
case WM_MOUSEMOVE: // Mouse move
return HANDLE_WM_MOUSEMOVE (hwnd, wParam, lParam, disk_OnMouseMove) ;
case WM_PAINT: // Draw all or part of client area
return HANDLE_WM_PAINT (hwnd, wParam, lParam, disk_OnPaint) ;
default:
return DefWindowProc (hwnd, message, wParam, lParam) ;
}
}
//
// BOOL disk_OnCreate (HWND hwnd, LPCREATESTRUCT lpCreateStruct)
//
// hwnd Handle of window to which this message applies
// lpCreateStruct Points to a CREATESTRUCT structure that contains
// information about the window being created
//
// PURPOSE: Perform any per-window initialization in response
// to this message, such as creating any desired
// child windows such as toolbars and status bars.
//
// COMMENTS: Windows sends this message after the window is
// created, but before the window becomes visible.
// Return TRUE to continue creation of the window;
// otherwise return FALSE to fail the window creation.
//
static BOOL
disk_OnCreate (HWND hwnd, LPCREATESTRUCT lpCreateStruct)
{
/****************************************************/
/* A disk is being created. Place it on left post. */
/****************************************************/
disk_AddDiskToPost (hwnd, FIRST) ;
return TRUE ;
}
//
// void disk_OnLButtonDown (HWND hwnd, BOOL fDoubleClick, int x, int y, UINT keyFlags)
//
// hwnd Handle of window to which this message applies
// fDoubleClick TRUE when a double click, FALSE when a single click
// x x coordinate of cursor
// y y coordinate of cursor
// keyFlags state of keys
//
// PURPOSE: The mouse cursor has moved.
//
// COMMENTS:
//
static void
disk_OnLButtonDown (HWND hwnd, BOOL fDoubleClick, int x, int y, UINT keyFlags)
{
HWND hwndParent ;
RECT rect ;
/*******************************************************/
/* The left mouse button is pressed while over a disk. */
/* Prepare to drag the disk as long as it's depressed. */
/*******************************************************/
/*************************************************/
/* Only allow the topmost disk(s) to be dragged. */
/*************************************************/
if (!disk_IsTopDisk (hwnd))
return ;
/************************************************************/
/* Start tracking the cursor... */
/* This entails remembering from where it all started... */
/************************************************************/
ptOrigPos.x = x ;
ptOrigPos.y = y ;
ClientToScreen (hwnd, &ptOrigPos) ;
GetWindowRect (hwnd, &rectOrigPos) ;
/****************************************/
/* Capturing the mouse so all future */
/* movements are sent to this window... */
/****************************************/
SetCapture (hwnd) ;
/************************************************/
/* And restricting its movement to */
/* within the client area of our parent window. */
/************************************************/
hwndParent = GetParent (hwnd) ;
GetClientRect (hwndParent, &rect) ;
ClientToScreen (hwndParent, (LPPOINT) &rect.left) ;
ClientToScreen (hwndParent, (LPPOINT) &rect.right) ;
ClipCursor (&rect) ;
}
//
// void disk_OnLButtonUp (HWND hwnd, int x, int y, UINT keyFlags)
//
// hwnd Handle of window to which this message applies
// x x coordinate of cursor
// y y coordinate of cursor
// keyFlags state of keys
//
// PURPOSE: The mouse cursor has moved.
//
// COMMENTS:
//
static void
disk_OnLButtonUp (HWND hwnd, int x, int y, UINT keyFlags)
{
HDC hdc ;
HWND hwndParent ;
POINT cursor ;
RECT rect ;
UINT Nearest ;
/******************************************************/
/* The left mouse button was released. Stop dragging */
/* the disk and place it on the nearest post. When */
/* the nearest post is an illegal move, place the */
/* back in its original position. */
/******************************************************/
ReleaseCapture () ;
ClipCursor (NULL) ;
/********************************************************/
/* Determine the coordinates of the center of the disk. */
/********************************************************/
GetWindowRect (hwnd, &rect) ;
cursor.x = (rect.left + rect.right) / 2 ;
cursor.y = (rect.top + rect.bottom) / 2 ;
/* Convert screen coordinates to client coordinates. */
hwndParent = GetParent (hwnd) ;
ScreenToClient (hwndParent, &cursor) ;
/* Convert client coordinates to logical coordinates. */
hdc = GetDC (hwndParent) ;
DPtoLP (hdc, &cursor, 1) ;
ReleaseDC (hwndParent, hdc) ;
/**************************/
/* Find the nearest post. */
/**************************/
if (cursor.x < LEFTPOSTPOS / 2)
Nearest = FIRST ;
else if (cursor.x > RIGHTPOSTPOS / 2)
Nearest = THIRD ;
else
Nearest = SECOND ;
/***************************************************************/
/* Remove the disk from its current post, if possible. */
/* If successful, place it on the nearest post. */
/* If the add fails, then put the disk back on the orig. post. */
/***************************************************************/
if (disk_RemoveDiskFromPost (hwnd) &&
!disk_AddDiskToPost (hwnd, Nearest))
disk_AddDiskToPost (hwnd, disk_GetPostNum (hwnd)) ;
disk_PositionDiskWindow (hwnd) ;
}
//
// void disk_OnMouseMove (HWND hwnd, int x, int y, UINT keyFlags)
//
// hwnd Handle of window to which this message applies
// x x coordinate of cursor
// y y coordinate of cursor
// keyFlags state of keys
//
// PURPOSE: The mouse cursor has moved.
//
// COMMENTS:
//
static void
disk_OnMouseMove (HWND hwnd, int x, int y, UINT keyFlags)
{
HWND hwndParent ;
POINT cursor ;
RECT rect ;
/*******************************************************/
/* We may be dragging the disk. If so, calculate the */
/* displacement from the starting position of the drag */
/* to the current position of the cursor and move the */
/* disk so that the position that was under the cursor */
/* when the drag started is under the cursor now. */
/*******************************************************/
if (hwnd == GetCapture ()) {
/*******************************************/
/* Get the current position of the cursor. */
/*******************************************/
cursor.x = x ;
cursor.y = y ;
ClientToScreen (hwnd, &cursor) ;
/*******************************************/
/* Calculate the new position of the disk. */
/*******************************************/
rect = rectOrigPos ;
OffsetRect (&rect, cursor.x - ptOrigPos.x,
cursor.y - ptOrigPos.y) ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -