windows-nt/Source/XPSP1/NT/shell/osshell/ep/winmine/winmine.c
2020-09-26 16:20:57 +08:00

1045 lines
22 KiB
C

/****************************************************************************
PROGRAM: WinMine (a.k.a. Mines, BombSquad, MineSweeper...)
****************************************************************************/
#define _WINDOWS
#include <windows.h>
#include <port1632.h>
#include <htmlhelp.h> // for HtmlHelp()
#include <commctrl.h> // for fusion classes.
#include "main.h"
#include "rtns.h"
#include "grafix.h"
#include "res.h"
#include "pref.h"
#include "util.h"
#include "sound.h"
#include "context.h"
#include "string.h"
#include "stdio.h"
#include "dos.h"
#ifndef WM_ENTERMENULOOP
#define WM_ENTERMENULOOP 0x0211
#define WM_EXITMENULOOP 0x0212
#endif
BOOL bInitMinimized; /* Bug #13328: HACK! Don't permit MoveWindow or */
/* InvalidateRect when initially minimized. */
/* 19 September 1991 Clark R. Cyr */
HANDLE hInst;
HWND hwndMain;
HMENU hMenu;
// Icon handles to load the winmine icon.
HICON hIconMain;
BOOL fButton1Down = fFalse;
BOOL fBlock = fFalse;
BOOL fIgnoreClick = fFalse;
INT dypCaption;
INT dypMenu;
INT dypBorder;
INT dxpBorder;
INT fStatus = (fDemo + fIcon);
BOOL fLocalPause = fFalse;
TCHAR szClass[cchNameMax];
#define szWindowTitle szClass
TCHAR szTime[cchNameMax];
TCHAR szDefaultName[cchNameMax];
extern BOOL fUpdateIni;
extern INT xCur;
extern INT yCur;
extern INT iButtonCur;
extern INT xBoxMac;
extern INT yBoxMac;
extern PREF Preferences;
extern INT cBoxVisit;
INT dxWindow;
INT dyWindow;
INT dypCaption;
INT dypMenu;
INT dypAdjust;
INT idRadCurr = 0;
#define iPrefMax 3
#define idRadMax 3
INT rgPrefEditID[iPrefMax] =
{ID_EDIT_MINES, ID_EDIT_HEIGHT, ID_EDIT_WIDTH};
INT rgLevelData[idRadMax][iPrefMax] = {
{10, MINHEIGHT, MINWIDTH, },
{40, 16, 16,},
{99, 16, 30,}
};
#ifndef DEBUG
#define XYZZY
#define cchXYZZY 5
INT iXYZZY = 0;
TCHAR szXYZZY[cchXYZZY+1] = TEXT("XYZZY");
extern CHAR rgBlk[cBlkMax];
#endif
LRESULT APIENTRY MainWndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR APIENTRY PrefDlgProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR APIENTRY BestDlgProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR APIENTRY EnterDlgProc(HWND, UINT, WPARAM, LPARAM);
/****** W I N M A I N ******/
MMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow)
/* { */
MSG msg;
HANDLE hAccel;
hInst = hInstance;
InitConst();
bInitMinimized = (nCmdShow == SW_SHOWMINNOACTIVE) ||
(nCmdShow == SW_SHOWMINIMIZED) ;
#ifdef WIN16
if (hPrevInstance)
{
HWND hWnd = FindWindow(szClass, NULL);
hWnd = GetLastActivePopup(hWnd);
BringWindowToTop(hWnd);
if (!bInitMinimized && IsIconic(hWnd))
SendMessage(hwnd, WM_SYSCOMMAND, SC_RESTORE, 0L);
return fFalse;
}
#endif
#ifdef NOSERVER /*** Not in final release ***/
{
TCHAR szFile[256];
GetModuleFileName(hInst, szFile, 250);
if (szFile[0] > TEXT('C'))
{
szFile[0] = TEXT('X');
if (!lstrcmp(szFile, TEXT("X:\\WINGAMES\\WINMINE\\WINMINE.EXE")))
{
MessageBox(GetFocus(),
TEXT("Please copy winmine.exe and aboutwep.dll to your machine and run it from there."),
TEXT("NO NO NO NO NO"),
MB_OK);
return fFalse;
}
}
}
#endif
#ifdef EXPIRE /*** Not in final release ***/
{
struct dosdate_t ddt;
_dos_getdate(&ddt);
if ((ddt.month + ddt.year*12) > (9 + 1990*12))
{
MessageBox(GetFocus(),
TEXT("This game has expired. Please obtain an official copy from the Windows Entertainment Package."),
TEXT("SORRY"),
MB_OK);
return fFalse;
}
}
#endif
{
WNDCLASS wc;
INITCOMMONCONTROLSEX icc; // common control registration.
// Register the common controls.
icc.dwSize = sizeof(INITCOMMONCONTROLSEX);
icc.dwICC = ICC_ANIMATE_CLASS | ICC_BAR_CLASSES | ICC_COOL_CLASSES | ICC_HOTKEY_CLASS | ICC_LISTVIEW_CLASSES |
ICC_PAGESCROLLER_CLASS | ICC_PROGRESS_CLASS | ICC_TAB_CLASSES | ICC_UPDOWN_CLASS | ICC_USEREX_CLASSES;
InitCommonControlsEx(&icc);
hIconMain = LoadIcon(hInst, MAKEINTRESOURCE(ID_ICON_MAIN));
wc.style = 0;
wc.lpfnWndProc = MainWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInst;
wc.hIcon = hIconMain;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = GetStockObject(LTGRAY_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = szClass;
if (!RegisterClass(&wc))
return fFalse;
}
hMenu = LoadMenu(hInst, MAKEINTRESOURCE(ID_MENU));
hAccel = LoadAccelerators(hInst, MAKEINTRESOURCE(ID_MENU_ACCEL));
ReadPreferences();
hwndMain = CreateWindow( szClass, szWindowTitle,
WS_OVERLAPPED | WS_MINIMIZEBOX | WS_CAPTION | WS_SYSMENU,
Preferences.xWindow-dxpBorder, Preferences.yWindow-dypAdjust,
dxWindow+dxpBorder, dyWindow +dypAdjust,
NULL, NULL, hInst, NULL);
if (!hwndMain)
{
ReportErr(1000);
return fFalse;
}
AdjustWindow(fCalc);
if (!FInitLocal())
{
ReportErr(ID_ERR_MEM);
return fFalse;
}
SetMenuBar(Preferences.fMenu);
StartGame();
ShowWindow(hwndMain, SW_SHOWNORMAL);
UpdateWindow(hwndMain);
bInitMinimized = FALSE;
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(hwndMain, hAccel, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
CleanUp();
if (fUpdateIni)
WritePreferences();
return ((INT) msg.wParam);
}
/****** F L O C A L B U T T O N ******/
BOOL FLocalButton(LPARAM lParam)
{
BOOL fDown = fTrue;
RECT rcCapt;
MSG msg;
msg.pt.x = LOWORD(lParam);
msg.pt.y = HIWORD(lParam);
rcCapt.right = dxButton + (rcCapt.left = (dxWindow-dxButton) >> 1);
rcCapt.bottom = dyButton + (rcCapt.top = dyTopLed);
if (!PtInRect(&rcCapt, msg.pt))
return fFalse;
SetCapture(hwndMain);
DisplayButton(iButtonDown);
MapWindowPoints(hwndMain , NULL , (LPPOINT) &rcCapt , 2);
while (fTrue)
{
if (PeekMessage(&msg, hwndMain, WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE))
{
switch (msg.message)
{
case WM_LBUTTONUP:
if (fDown)
{
if (PtInRect(&rcCapt, msg.pt))
{
DisplayButton(iButtonCur = iButtonHappy);
StartGame();
}
}
ReleaseCapture();
return fTrue;
case WM_MOUSEMOVE:
if (PtInRect(&rcCapt, msg.pt))
{
if (!fDown)
{
fDown = fTrue;
DisplayButton(iButtonDown);
}
}
else
{
if (fDown)
{
fDown = fFalse;
DisplayButton(iButtonCur);
}
}
default:
;
} /* switch */
}
} /* while */
}
/****** F I X M E N U S ******/
VOID FixMenus(VOID)
{
CheckEm(IDM_BEGIN, Preferences.wGameType == wGameBegin);
CheckEm(IDM_INTER, Preferences.wGameType == wGameInter);
CheckEm(IDM_EXPERT, Preferences.wGameType == wGameExpert);
CheckEm(IDM_CUSTOM, Preferences.wGameType == wGameOther);
CheckEm(IDM_COLOR, Preferences.fColor);
CheckEm(IDM_MARK, Preferences.fMark);
CheckEm(IDM_SOUND, Preferences.fSound);
}
/****** D O P R E F ******/
VOID DoPref(VOID)
{
DialogBox(hInst, MAKEINTRESOURCE(ID_DLG_PREF), hwndMain, PrefDlgProc);
Preferences.wGameType = wGameOther;
FixMenus();
fUpdateIni = fTrue;
StartGame();
}
/****** D O E N T E R N A M E ******/
VOID DoEnterName(VOID)
{
DialogBox(hInst, MAKEINTRESOURCE(ID_DLG_ENTER), hwndMain, EnterDlgProc);
fUpdateIni = fTrue;
}
/****** D O D I S P L A Y B E S T ******/
VOID DoDisplayBest(VOID)
{
DialogBox(hInst, MAKEINTRESOURCE(ID_DLG_BEST), hwndMain, BestDlgProc);
}
/****** M A I N W N D P R O C ******/
LRESULT APIENTRY MainWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_WINDOWPOSCHANGED:
if (!fStatusIcon)
{
Preferences.xWindow = ((LPWINDOWPOS) (lParam))->x;
Preferences.yWindow = ((LPWINDOWPOS) (lParam))->y;
}
break;
case WM_SYSCOMMAND:
switch (wParam & 0xFFF0)
{
case SC_MINIMIZE:
PauseGame();
SetStatusPause;
SetStatusIcon;
break;
case SC_RESTORE:
ClrStatusPause;
ClrStatusIcon;
ResumeGame();
//Japan Bug fix: 1/19/93 Enable the first click after restoring from icon.
fIgnoreClick = fFalse;
break;
default:
break;
}
break;
case WM_COMMAND:
{
switch(GET_WM_COMMAND_ID(wParam, lParam)) {
case IDM_NEW:
StartGame();
break;
/** IDM_NEW **/
case IDM_EXIT:
ShowWindow(hwndMain, SW_HIDE);
#ifdef ORGCODE
goto LExit;
#else
SendMessage(hwndMain, WM_SYSCOMMAND, SC_CLOSE, 0);
return(0);
#endif
/** IDM_SKILL **/
case IDM_BEGIN:
case IDM_INTER:
case IDM_EXPERT:
Preferences.wGameType = (WORD)(GET_WM_COMMAND_ID(wParam, lParam) - IDM_BEGIN);
Preferences.Mines = rgLevelData[Preferences.wGameType][0];
Preferences.Height = rgLevelData[Preferences.wGameType][1];
Preferences.Width = rgLevelData[Preferences.wGameType][2];
StartGame();
goto LUpdateMenu;
case IDM_CUSTOM:
DoPref();
break;
/** IDM_OPTIONS **/
case IDM_SOUND:
if (Preferences.fSound)
{
EndTunes();
Preferences.fSound = fFalse;
}
else
{
Preferences.fSound = FInitTunes();
}
goto LUpdateMenu;
case IDM_COLOR:
Preferences.fColor = !Preferences.fColor;
FreeBitmaps();
if (!FLoadBitmaps())
{
ReportErr(ID_ERR_MEM);
#ifdef ORGCODE
goto LExit;
#else
SendMessage(hwndMain, WM_SYSCOMMAND, SC_CLOSE, 0);
return(0);
#endif
}
DisplayScreen();
goto LUpdateMenu;
case IDM_MARK:
Preferences.fMark = !Preferences.fMark;
/* IE goto LUpdateMenu; */
LUpdateMenu:
fUpdateIni = fTrue;
SetMenuBar(Preferences.fMenu);
break;
case IDM_BEST:
DoDisplayBest();
break;
/** IDM_HELP **/
case IDM_HELP:
DoHelp(HELP_INDEX, HH_DISPLAY_TOPIC);
break;
case IDM_HOW2PLAY:
DoHelp(HELP_CONTEXT, HH_DISPLAY_INDEX);
break;
case IDM_HELP_HELP:
DoHelp(HELP_HELPONHELP, HH_DISPLAY_TOPIC);
break;
case IDM_HELP_ABOUT:
DoAbout();
return 0;
default:
break;
}
} /**** END OF MENUS ****/
break;
case WM_KEYDOWN:
switch (wParam)
{
#if 0
case VK_F1:
DoHelp(HELP_INDEX, 0L);
break;
case VK_F2:
StartGame();
break;
case VK_F3:
break;
#endif
case VK_F4:
if (FSoundSwitchable())
if (FSoundOn())
{
EndTunes();
Preferences.fSound = fsoundOff;
}
else
Preferences.fSound = FInitTunes();
break;
case VK_F5:
if (FMenuSwitchable())
SetMenuBar(fmenuOff);
break;
case VK_F6:
if (FMenuSwitchable())
SetMenuBar(fmenuOn);
break;
#ifdef XYZZY
case VK_SHIFT:
if (iXYZZY >= cchXYZZY)
iXYZZY ^= 20;
break;
default:
if (iXYZZY < cchXYZZY)
iXYZZY = (szXYZZY[iXYZZY] == (TCHAR) wParam) ? iXYZZY+1 : 0;
break;
#else
default:
break;
#endif
}
break;
/* case WM_QUERYENDSESSION: SHOULDNT BE USED (JAP)*/
case WM_DESTROY:
//LExit:
KillTimer(hwndMain, ID_TIMER);
PostQuitMessage(0);
break;
case WM_MBUTTONDOWN:
if (fIgnoreClick)
{
fIgnoreClick = fFalse;
return 0;
}
if (!fStatusPlay)
break;
fBlock = fTrue;
goto LBigStep;
case WM_LBUTTONDOWN:
if (fIgnoreClick)
{
fIgnoreClick = fFalse;
return 0;
}
if (FLocalButton(lParam))
return 0;
if (!fStatusPlay)
break;
fBlock = (wParam & (MK_SHIFT | MK_RBUTTON)) ? fTrue : fFalse;
LBigStep:
SetCapture(hWnd);
fButton1Down = fTrue;
xCur = -1;
yCur = -1;
DisplayButton(iButtonCaution);
case WM_MOUSEMOVE:
if (fButton1Down)
{
if (fStatus & fPlay)
TrackMouse(xBoxFromXpos(LOWORD(lParam)), yBoxFromYpos(HIWORD(lParam)) );
else
goto LFixTimeOut;
}
#ifdef XYZZY
//
// This is the cheat:
// If you hold down the shift key and type 'XYZZY'
// then when you hold down the control key, to upper
// left hand corner pixel will show the state of the
// mine field under the mouse. Oh. joy. I can win.
//
else if (iXYZZY != 0)
if (((iXYZZY == cchXYZZY) && (wParam & MK_CONTROL))
||(iXYZZY > cchXYZZY))
{
xCur = xBoxFromXpos(LOWORD(lParam));
yCur = yBoxFromYpos(HIWORD(lParam));
if (fInRange(xCur, yCur))
{
HDC hDC = GetDC(NULL);
SetPixel(hDC, 0, 0, fISBOMB(xCur, yCur) ? 0L : 0x00FFFFFFL);
ReleaseDC(NULL, hDC);
}
}
#endif
break;
case WM_RBUTTONUP:
case WM_MBUTTONUP:
case WM_LBUTTONUP:
if (fButton1Down)
{
LFixTimeOut:
fButton1Down = fFalse;
ReleaseCapture();
if (fStatus & fPlay)
DoButton1Up();
else
TrackMouse(-2,-2);
}
break;
case WM_RBUTTONDOWN:
if (fIgnoreClick)
{
fIgnoreClick = fFalse;
return 0;
}
if(!fStatusPlay)
break;
if (fButton1Down)
{
TrackMouse(-3,-3);
fBlock = fTrue;
PostMessage(hwndMain, WM_MOUSEMOVE, wParam, lParam);
}
else if (wParam & MK_LBUTTON)
goto LBigStep;
else if (!fLocalPause)
MakeGuess(xBoxFromXpos(LOWORD(lParam)), yBoxFromYpos(HIWORD(lParam)) );
return 0;
case WM_ACTIVATE:
/* Window is being activated by a mouse click */
if (GET_WM_ACTIVATE_STATE(wParam, lParam) == 2)
fIgnoreClick = fTrue;
break;
case WM_TIMER:
#ifdef CHEAT
if (!fLocalPause)
#endif
DoTimer();
return 0;
case WM_ENTERMENULOOP:
fLocalPause = fTrue;
break;
case WM_EXITMENULOOP:
fLocalPause = fFalse;
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hDC = BeginPaint(hWnd,&ps);
DrawScreen(hDC);
EndPaint(hWnd, &ps);
}
return 0;
default:
break;
}
return (DefWindowProc(hWnd, message, wParam, lParam));
}
/****** DIALOG PROCEDURES ******/
/*** P R E F D L G P R O C ***/
INT_PTR APIENTRY PrefDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
// for context sensitive help
static DWORD aIds[] = {
ID_EDIT_HEIGHT, IDH_PREF_EDIT_HEIGHT,
ID_EDIT_WIDTH, IDH_PREF_EDIT_WIDTH,
ID_EDIT_MINES, IDH_PREF_EDIT_MINES,
ID_TXT_HEIGHT, IDH_PREF_EDIT_HEIGHT,
ID_TXT_WIDTH, IDH_PREF_EDIT_WIDTH,
ID_TXT_MINES, IDH_PREF_EDIT_MINES,
0,0 };
switch (message)
{
case WM_INITDIALOG:
SetDlgItemInt(hDlg, ID_EDIT_HEIGHT, Preferences.Height ,fFalse);
SetDlgItemInt(hDlg, ID_EDIT_WIDTH, Preferences.Width ,fFalse);
SetDlgItemInt(hDlg, ID_EDIT_MINES, Preferences.Mines ,fFalse);
return (fTrue);
case WM_COMMAND:
switch(GET_WM_COMMAND_ID(wParam, lParam)) {
case ID_BTN_OK:
case IDOK:
{
Preferences.Height = GetDlgInt(hDlg, ID_EDIT_HEIGHT, MINHEIGHT, 24);
Preferences.Width = GetDlgInt(hDlg, ID_EDIT_WIDTH, MINWIDTH, 30);
Preferences.Mines = GetDlgInt(hDlg, ID_EDIT_MINES, 10,
min(999, (Preferences.Height-1) * (Preferences.Width-1) ) );
}
/* Fall Through & Exit */
case ID_BTN_CANCEL:
case IDCANCEL:
EndDialog(hDlg, fTrue); /* Exits the dialog box */
return fTrue;
default:
break;
}
break;
// context sensitive help.
case WM_HELP:
WinHelp(((LPHELPINFO) lParam)->hItemHandle, TEXT("winmine.hlp"),
HELP_WM_HELP, (ULONG_PTR) aIds);
break;
case WM_CONTEXTMENU:
WinHelp((HWND) wParam, TEXT("winmine.hlp"), HELP_CONTEXTMENU,
(ULONG_PTR) aIds);
break;
}
return (fFalse); /* Didn't process a message */
}
/*** S E T D T E X T ***/
VOID SetDText(HWND hDlg, INT id, INT time, TCHAR FAR * szName)
{
TCHAR sz[cchNameMax];
wsprintf(sz, szTime, time);
SetDlgItemText(hDlg, id, sz);
SetDlgItemText(hDlg, id+1, szName);
}
/****** B E S T D L G P R O C ******/
INT_PTR APIENTRY BestDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
// for context sensitive help
static DWORD aIds[] = {
ID_BTN_RESET, IDH_BEST_BTN_RESET,
ID_STEXT1, IDH_STEXT,
ID_STEXT2, IDH_STEXT,
ID_STEXT3, IDH_STEXT,
ID_TIME_BEGIN, IDH_STEXT,
ID_TIME_INTER, IDH_STEXT,
ID_TIME_EXPERT, IDH_STEXT,
ID_NAME_BEGIN, IDH_STEXT,
ID_NAME_INTER, IDH_STEXT,
ID_NAME_EXPERT, IDH_STEXT,
0,0 };
switch (message)
{
case WM_INITDIALOG:
LReset:
SetDText(hDlg, ID_TIME_BEGIN, Preferences.rgTime[wGameBegin], Preferences.szBegin);
SetDText(hDlg, ID_TIME_INTER, Preferences.rgTime[wGameInter], Preferences.szInter);
SetDText(hDlg, ID_TIME_EXPERT, Preferences.rgTime[wGameExpert], Preferences.szExpert);
return (fTrue);
case WM_COMMAND:
switch(GET_WM_COMMAND_ID(wParam, lParam)) {
case ID_BTN_RESET:
Preferences.rgTime[wGameBegin] = Preferences.rgTime[wGameInter]
= Preferences.rgTime[wGameExpert] = 999;
lstrcpy(Preferences.szBegin, szDefaultName);
lstrcpy(Preferences.szInter, szDefaultName);
lstrcpy(Preferences.szExpert, szDefaultName);
fUpdateIni = fTrue;
goto LReset;
case ID_BTN_OK:
case IDOK:
case ID_BTN_CANCEL:
case IDCANCEL:
EndDialog(hDlg, fTrue); /* Exits the dialog box */
return fTrue;
default:
break;
}
break;
// context sensitive help.
case WM_HELP:
WinHelp(((LPHELPINFO) lParam)->hItemHandle, TEXT("winmine.hlp"),
HELP_WM_HELP, (ULONG_PTR) aIds);
break;
case WM_CONTEXTMENU:
WinHelp((HWND) wParam, TEXT("winmine.hlp"), HELP_CONTEXTMENU,
(ULONG_PTR) aIds);
break;
}
return (fFalse); /* Didn't process a message */
}
/****** E N T E R D L G P R O C ******/
INT_PTR APIENTRY EnterDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
{
TCHAR sz[cchMsgMax];
LoadSz((WORD)(Preferences.wGameType+ID_MSG_BEGIN), sz, ARRAYSIZE(sz));
SetDlgItemText(hDlg, ID_TEXT_BEST, sz);
SendMessage(GetDlgItem(hDlg, ID_EDIT_NAME), EM_SETLIMITTEXT, cchNameMax, 0L);
SetDlgItemText(hDlg, ID_EDIT_NAME,
(Preferences.wGameType == wGameBegin) ? Preferences.szBegin :
(Preferences.wGameType == wGameInter) ? Preferences.szInter :
Preferences.szExpert);
}
return (fTrue);
case WM_COMMAND:
switch(GET_WM_COMMAND_ID(wParam, lParam)) {
case ID_BTN_OK:
case IDOK:
case ID_BTN_CANCEL:
case IDCANCEL:
GetDlgItemText(hDlg, ID_EDIT_NAME,
(Preferences.wGameType == wGameBegin) ? Preferences.szBegin :
(Preferences.wGameType == wGameInter) ? Preferences.szInter :
Preferences.szExpert, cchNameMax);
EndDialog(hDlg, fTrue); /* Exits the dialog box */
return fTrue;
default:
break;
}
}
return (fFalse); /* Didn't process a message */
(lParam);
}
/****** A D J U S T W I N D O W ******/
// Our verion of GetSystemMetrics
//
// Tries to return whole screen (include other monitor) info
//
INT OurGetSystemMetrics( INT nIndex )
{
INT Result=0;
switch( nIndex )
{
case SM_CXSCREEN:
Result= GetSystemMetrics( SM_CXVIRTUALSCREEN );
if( !Result )
Result= GetSystemMetrics( SM_CXSCREEN );
break;
case SM_CYSCREEN:
Result= GetSystemMetrics( SM_CYVIRTUALSCREEN );
if( !Result )
Result= GetSystemMetrics( SM_CYSCREEN );
break;
default:
Result= GetSystemMetrics( nIndex );
break;
}
return( Result );
}
VOID AdjustWindow(INT fAdjust)
{
REGISTER t;
RECT rect;
BOOL bDiffLevel = FALSE;
RECT rectGame, rectHelp;
// an extra check
if (!hwndMain)
return;
dypAdjust = dypCaption;
if (FMenuOn())
{
// dypMenu is initialized to GetSystemMetrics(SM_CYMENU) + 1,
// which is the height of one menu line
dypAdjust += dypMenu;
// If the menu extends on two lines (because of the large-size
// font the user has chosen for the menu), increase the size
// of the window.
// The two menus : "Game" and "Help" are on the same line, if
// their enclosing rectangles top match. In that case, we don't
// need to extend the window size.
// If the tops do not match, that means they are on two lines.
// In that case, extend the size of the window by size of
// one menu line.
if (hMenu && GetMenuItemRect(hwndMain, hMenu, 0, &rectGame) &&
GetMenuItemRect(hwndMain, hMenu, 1, &rectHelp))
{
if (rectGame.top != rectHelp.top)
{
dypAdjust += dypMenu;
bDiffLevel = TRUE;
}
}
}
dxWindow = dxBlk * xBoxMac + dxGridOff + dxRightSpace;
dyWindow = dyBlk * yBoxMac + dyGridOff + dyBottomSpace;
if ((t = Preferences.xWindow+dxWindow - OurGetSystemMetrics(SM_CXSCREEN)) > 0)
{
fAdjust |= fResize;
Preferences.xWindow -= t;
}
if ((t = Preferences.yWindow+dyWindow - OurGetSystemMetrics(SM_CYSCREEN)) > 0)
{
fAdjust |= fResize;
Preferences.yWindow -= t;
}
if (!bInitMinimized)
{
if (fAdjust & fResize)
{
MoveWindow(hwndMain, Preferences.xWindow, Preferences.yWindow,
dxWindow+dxpBorder, dyWindow + dypAdjust, fTrue);
}
// after the window is adjusted, the "Game" and "Help" may move to the
// same line creating extra space at the bottom. so check again!
if (bDiffLevel && hMenu && GetMenuItemRect(hwndMain, hMenu, 0, &rectGame) &&
GetMenuItemRect(hwndMain, hMenu, 1, &rectHelp))
{
if (rectGame.top == rectHelp.top)
{
dypAdjust -= dypMenu;
MoveWindow(hwndMain, Preferences.xWindow, Preferences.yWindow,
dxWindow+dxpBorder, dyWindow + dypAdjust, fTrue);
}
}
if (fAdjust & fDisplay)
{
SetRect(&rect, 0, 0, dxWindow, dyWindow);
InvalidateRect(hwndMain, &rect, fTrue);
}
}
}