📄 mainframe.c
字号:
#include "StdSDK.h" // Standard application includes
#include "About.h" // For non-static function prototypes
#include "Initialization.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 mainFrame_DisplayContextMenu (HWND hwnd, POINT pt) ;
static BOOL mainFrame_IntersectRect (LPRECT rect1, LPRECT rect2) ;
static void mainFrame_ResetDisks (HWND hwnd) ;
static void mainFrame_SetHanoiMappingMode (HWND hwnd, int cxClient, int cyClient) ;
static void mainFrame_SolveProblem (HWND hwnd) ;
//
// Function prototypes for callback functions
//
BOOL CALLBACK mainFrame_SysColorChangeEnumeration (HWND hwnd, LPARAM lParam) ;
LRESULT CALLBACK mainFrameWndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) ;
//
// Function prototypes for message handlers
//
static void mainFrame_OnCommand (HWND hwnd, int id, HWND hwndCtl, UINT codeNotify) ;
static BOOL mainFrame_OnContextMenu (HWND hwnd, HWND hwndCtl, int xPos, int yPos) ;
static BOOL mainFrame_OnCreate (HWND hwnd, LPCREATESTRUCT lpCreateStruct) ;
static void mainFrame_OnDestroy (HWND hwnd) ;
static void mainFrame_OnDisplayChange (HWND hwnd, UINT cBitsPerPixel, UINT cxScreen, UINT cyScreen) ;
static void mainFrame_OnNCRButtonUp (HWND hwnd, int x, int y, UINT codeHitTest) ;
static BOOL mainFrame_OnNotify (HWND hwnd, int idFrom, NMHDR FAR* pnmhdr) ;
static void mainFrame_OnPaint (HWND hwnd) ;
static void mainFrame_OnPrintClient (HWND hwnd, HDC hdc, UINT uFlags) ;
static void mainFrame_OnRButtonDown (HWND hwnd, BOOL fDoubleClick, int x, int y, UINT keyFlags) ;
static void mainFrame_OnSettingChange (HWND hwnd, UINT uiFlag, LPCTSTR pszMetrics) ;
static void mainFrame_OnSize (HWND hwnd, UINT state, int cx, int cy) ;
static void mainFrame_OnSysColorChange(HWND hwnd) ;
static void mainFrame_OnUserChanged (HWND hwnd) ;
static void mainFrame_OnWinIniChange (HWND hwnd, LPCTSTR pszSection) ;
BOOL CALLBACK mainFrame_SysColorChangeNotification (HWND hwnd, LPARAM lParam) ;
LRESULT CALLBACK mainFrameWndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) ;
LRESULT CALLBACK
mainFrameWndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message) {
case WM_COMMAND: // Notification from menu or control
return HANDLE_WM_COMMAND (hwnd, wParam, lParam, mainFrame_OnCommand) ;
case WM_CONTEXTMENU: // Request to display a context menu
return HANDLE_WM_CONTEXTMENU (hwnd, wParam, lParam, mainFrame_OnContextMenu) ;
case WM_CREATE: // Notification that a window is being created
return HANDLE_WM_CREATE (hwnd, wParam, lParam, mainFrame_OnCreate) ;
case WM_DESTROY: // Window is being destroyed
return HANDLE_WM_DESTROY (hwnd, wParam, lParam, mainFrame_OnDestroy) ;
case WM_DISPLAYCHANGE: // Only comes through on plug'n'play systems
return HANDLE_WM_DISPLAYCHANGE (hwnd, wParam, lParam, mainFrame_OnDisplayChange) ;
case WM_NCRBUTTONUP: // Right click on windows non-client area...
return HANDLE_WM_NCRBUTTONUP (hwnd, wParam, lParam, mainFrame_OnNCRButtonUp) ;
case WM_NOTIFY: // Notification from a Common Control
return HANDLE_WM_NOTIFY (hwnd, wParam, lParam, mainFrame_OnNotify) ;
case WM_PAINT: // Draw all or part of client area
return HANDLE_WM_PAINT (hwnd, wParam, lParam, mainFrame_OnPaint) ;
case WM_PRINTCLIENT: // Draw all of client area into provided DC
return HANDLE_WM_PRINTCLIENT (hwnd, wParam, lParam, mainFrame_OnPrintClient) ;
case WM_RBUTTONDOWN: // Right click in windows client area...
return HANDLE_WM_RBUTTONDOWN (hwnd, wParam, lParam, mainFrame_OnRButtonDown) ;
case WM_SETTINGCHANGE: // An application changed a systemwide setting
// case WM_WININICHANGE: // A WIN.INI setting has changed
return HANDLE_WM_SETTINGCHANGE (hwnd, wParam, lParam, mainFrame_OnSettingChange) ;
case WM_SIZE: // Window size has changed
return HANDLE_WM_SIZE (hwnd, wParam, lParam, mainFrame_OnSize) ;
case WM_SYSCOLORCHANGE: // A change has been made to a system color setting
return HANDLE_WM_SYSCOLORCHANGE (hwnd, wParam, lParam, mainFrame_OnSysColorChange) ;
case WM_USERCHANGED: // User logged in or out
return HANDLE_WM_USERCHANGED (hwnd, wParam, lParam, mainFrame_OnUserChanged) ;
default:
return DefWindowProc (hwnd, message, wParam, lParam) ;
}
}
static void
mainFrame_OnCommand (HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
{
switch (id) {
case ID_APP_ABOUT:
doAbout(hwnd);
return ;
case ID_APP_EXIT:
DestroyWindow (hwnd) ;
return ;
case ID_HELP_HELP_TOPICS:
{
BOOL bGotHelp = WinHelp (hwnd, getHelpFileName (), HELP_FINDER, (DWORD) 0) ;
if (!bGotHelp)
MessageBox (GetFocus(), TEXT("Unable to activate help"), getAppName (), MB_OK|MB_ICONHAND) ;
}
return ;
case IDM_HELP_HOWTO:
doHow(hwnd);
return ;
case IDM_RESET_DISKS:
mainFrame_ResetDisks (hwnd) ;
return ;
case IDM_SOLVE_PROBLEM:
{
HMENU hmenu = GetMenu (hwnd) ;
EnableMenuItem (hmenu, IDM_RESET_DISKS, MF_DISABLED | MF_GRAYED) ;
EnableMenuItem (hmenu, IDM_SOLVE_PROBLEM, MF_DISABLED | MF_GRAYED) ;
DrawMenuBar (hwnd) ;
mainFrame_SolveProblem (hwnd) ;
EnableMenuItem (hmenu, IDM_RESET_DISKS, MF_ENABLED) ;
EnableMenuItem (hmenu, IDM_SOLVE_PROBLEM, MF_ENABLED) ;
DrawMenuBar (hwnd) ;
}
return ;
default:
FORWARD_WM_COMMAND (hwnd, id, hwndCtl, codeNotify, DefWindowProc) ;
}
}
static BOOL
mainFrame_OnContextMenu (HWND hwnd, HWND hwndCtl, int xPos, int yPos)
{
POINT pt = { xPos, yPos } ; // location of mouse click
RECT rc ; // client area of window
// Get the bounding rectangle of the client area.
GetClientRect (hwnd, &rc) ;
// Convert the mouse position to client coordinates.
ScreenToClient (hwnd, &pt) ;
// If the mouse click was in the client area,
// display the appropriate floating popup menu.
if (PtInRect (&rc, pt))
if (mainFrame_DisplayContextMenu (hwnd, pt))
return TRUE ;
// Otherwise forward the message for default processing
return FORWARD_WM_CONTEXTMENU (hwnd, hwndCtl, xPos, yPos, DefWindowProc) ;
}
static BOOL
mainFrame_OnCreate (HWND hwnd, LPCREATESTRUCT lpCreateStruct)
{
mainFrame_CreateDiskWindows (hwnd) ;
return TRUE ;
}
static void
mainFrame_OnDestroy (HWND hwnd)
{
// Tell WinHelp we don't need it any more...
WinHelp (hwnd, getHelpFileName (), HELP_QUIT, (DWORD) 0) ;
PostQuitMessage (0) ;
}
static void
mainFrame_OnDisplayChange (HWND hwnd, UINT cBitsPerPixel, UINT cxScreen, UINT cyScreen)
{
FORWARD_WM_DISPLAYCHANGE (hwnd, cBitsPerPixel, cxScreen, cyScreen, DefWindowProc) ;
}
static void
mainFrame_OnNCRButtonUp (HWND hwnd, int x, int y, UINT codeHitTest)
{
switch (codeHitTest) {
case HTSYSMENU:
return ;
case HTCAPTION:
case HTREDUCE:
case HTZOOM:
return ;
}
// Allow default message processing regardless
FORWARD_WM_NCRBUTTONUP (hwnd, x, y, codeHitTest, DefWindowProc) ;
}
static BOOL
mainFrame_OnNotify (HWND hwnd, int idFrom, LPNMHDR pnmhdr)
{
return TRUE ;
}
static void
mainFrame_OnPaint (HWND hwnd)
{
HBRUSH hbrush ;
HDC hdc ;
PAINTSTRUCT ps ;
RECT rect ;
hdc = BeginPaint (hwnd, &ps) ;
hbrush = GetStockObject (BLACK_BRUSH) ;
SetRect (&rect,
CENTERPOSTPOS - POSTWIDTH / 2, POSTHEIGHT,
CENTERPOSTPOS + POSTWIDTH / 2, 0) ;
if (mainFrame_IntersectRect (&rect, &ps.rcPaint))
FillRect (hdc, &rect, hbrush) ;
SetRect (&rect,
LEFTPOSTPOS - POSTWIDTH / 2, POSTHEIGHT,
LEFTPOSTPOS + POSTWIDTH / 2, 0) ;
if (mainFrame_IntersectRect (&rect, &ps.rcPaint))
FillRect (hdc, &rect, hbrush) ;
SetRect (&rect,
RIGHTPOSTPOS - POSTWIDTH / 2, POSTHEIGHT,
RIGHTPOSTPOS + POSTWIDTH / 2, 0) ;
if (mainFrame_IntersectRect (&rect, &ps.rcPaint))
FillRect (hdc, &rect, hbrush) ;
EndPaint (hwnd, &ps) ;
}
static void
mainFrame_OnPrintClient (HWND hwnd, HDC hdc, UINT uFlags)
{
}
static void
mainFrame_OnRButtonDown (HWND hwnd, BOOL fDoubleClick, int x, int y, UINT keyFlags)
{
POINT pt = { x, y } ;
mainFrame_DisplayContextMenu (hwnd, pt) ;
}
static void
mainFrame_OnSettingChange (HWND hwnd, UINT uiFlag, LPCTSTR pszMetrics)
{
}
static void mainFrame_OnSize (HWND hwnd, UINT state, int cx, int cy)
{
HWND hwndDisk ;
mainFrame_SetHanoiMappingMode (hwnd, cx, cy) ;
hwndDisk = GetFirstChild (hwnd) ;
while (hwndDisk) {
disk_PositionDiskWindow (hwndDisk) ;
hwndDisk = GetNextSibling (hwndDisk) ;
}
}
static void
mainFrame_OnSysColorChange (HWND hwnd)
{
EnumChildWindows (hwnd, mainFrame_SysColorChangeNotification, (LPARAM) NULL) ;
}
BOOL CALLBACK
mainFrame_SysColorChangeNotification (HWND hwnd, LPARAM lParam)
{
// Forward the message to a child window
FORWARD_WM_SYSCOLORCHANGE (hwnd, SendMessage) ;
// Keep on enumerating...
return TRUE ;
lParam ; // Parameter not referenced
}
static void
mainFrame_OnUserChanged (HWND hwnd)
{
}
BOOL mainFrame_DisplayContextMenu (HWND hwnd, POINT pt)
{
HMENU hmenuBar, hmenuPopup ;
int nItems ;
hmenuBar = GetMenu (hwnd) ;
ASSERT (NULL != hmenuBar) ;
// Get the count of items on the main menu
nItems = GetMenuItemCount (hmenuBar) ;
ASSERT (-1 != nItems) ;
// ASSUMPTION: Help menu is the rightmost on the menu bar
hmenuPopup = GetSubMenu (hmenuBar, nItems - 1) ;
ASSERT (NULL != hmenuPopup) ;
// Convert click location to screen coordinates
ClientToScreen (hwnd, &pt) ;
return TrackPopupMenu (hmenuPopup,
TPM_LEFTALIGN | TPM_RIGHTBUTTON,
pt.x, pt.y, 0, hwnd, NULL) ;
}
static void
mainFrame_SetHanoiMappingMode (HWND hwnd, int cxClient, int cyClient)
{
HDC hdc ;
hdc = GetDC (hwnd) ;
SetMapMode (hdc, MM_ANISOTROPIC) ;
// The origin of the window is (still) at point (0,0).
SetWindowOrgEx (hdc, 0, 0, NULL) ;
SetViewportOrgEx (hdc, cxClient / 2, cyClient, NULL) ;
SetWindowExtEx (hdc, 2048, 2048, NULL) ;
SetViewportExtEx (hdc, cxClient, -cyClient, NULL) ;
ReleaseDC (hwnd, hdc) ;
}
static BOOL
mainFrame_IntersectRect (LPRECT rect1, LPRECT rect2)
{
int nHighestLeft, nLowestRight ;
int nHighestBottom, nLowestTop ;
nHighestLeft = max (rect1->left, rect2->left) ;
nLowestRight = min (rect1->right, rect2->right) ;
if (nHighestLeft >= nLowestRight)
return FALSE ;
nHighestBottom = max (rect1->bottom, rect1->bottom) ;
nLowestTop = min (rect1->top, rect2->top) ;
return (nHighestBottom >= nLowestTop ? FALSE : TRUE) ;
}
static void
mainFrame_ResetDisks (HWND hwnd)
{
HWND hwndDisk ;
int i, nPostPos ;
HowMany [FIRST] = NUMDISKS ;
HowMany [SECOND] = 0 ;
HowMany [THIRD] = 0 ;
// Move all disks to the left peg.
hwndDisk = GetFirstChild (hwnd) ;
while (hwndDisk) {
disk_SetPostNum (hwndDisk, FIRST) ;
nPostPos = NUMDISKS - disk_GetDiskSize (hwndDisk) ;
WhosOn [FIRST][nPostPos] = hwndDisk ;
hwndDisk = GetNextSibling (hwndDisk) ;
}
for (i = 0; i < NUMDISKS; i++)
disk_PositionDiskWindow (WhosOn [FIRST][i]) ;
}
static void
mainFrame_SolveProblem (HWND hwnd)
{
__try {
mainFrame_ResetDisks (hwnd) ;
disk_MoveTower (NUMDISKS, FIRST, SECOND, THIRD) ;
}
__except (GetExceptionCode() == STATUS_TERMINATION_REQUEST) {
PostQuitMessage (0) ;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -