⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 diskhandling.c

📁 一个用vc
💻 C
📖 第 1 页 / 共 2 页
字号:
        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 + -