802 lines
20 KiB
C
802 lines
20 KiB
C
#include "sol.h"
|
|
#include <shellapi.h> // To pick up ShellAbout()
|
|
#include <htmlhelp.h>
|
|
#include <commctrl.h> // for fusion classes.
|
|
|
|
VSZASSERT
|
|
|
|
|
|
#define rgbGreen RGB(0x00,0x80,0x00)
|
|
#define rgbWhite RGB(0xff,0xff,0xff)
|
|
|
|
PT ptNil = {0x7fff, 0x7fff};
|
|
TCHAR szAppName[10]; // name of this app: 'solitaire'
|
|
TCHAR szScore[50]; // 'score:' for internationalization
|
|
|
|
/* Instance info */
|
|
static HANDLE hAccel; // accelerators handle
|
|
|
|
HWND hwndApp; // window handle to this app
|
|
HANDLE hinstApp; // instance handle to this app
|
|
BOOL fBW=FALSE; // true if on true monochrome video! (never true on NT)
|
|
HBRUSH hbrTable; // brush for background of table top
|
|
LONG rgbTable; // RGB value of table top
|
|
|
|
BOOL fIconic = fFalse; // true if app is 'iconic'
|
|
|
|
INT dyChar; // tmHeight of font in hdc
|
|
INT dxChar; // tmMaxCharWidth of font in hdc
|
|
|
|
|
|
#define modeNil -1
|
|
INT modeFaceDown = modeNil; // back of cards ID
|
|
|
|
|
|
GM *pgmCur = NULL; // current game
|
|
|
|
/* card extent info */
|
|
DEL delCrd;
|
|
DEL delScreen;
|
|
|
|
RC rcClient; // client rectangle
|
|
|
|
INT igmCur; /* the current game #, srand seeded with this */
|
|
#ifdef DEBUG
|
|
BOOL fScreenShots = fFalse;
|
|
#endif
|
|
|
|
/* window messages for external app drawing */
|
|
static UINT wmCardDraw;
|
|
|
|
|
|
HDC hdcCur = NULL; // current hdc to draw on
|
|
INT usehdcCur = 0; // hdcCur use count
|
|
X xOrgCur = 0;
|
|
Y yOrgCur = 0;
|
|
|
|
static TCHAR szClass[] = TEXT("Solitaire");
|
|
|
|
TCHAR szOOM[50];
|
|
|
|
// BUG: some of these should go in gm struct
|
|
//
|
|
BOOL fStatusBar = fTrue;
|
|
BOOL fTimedGame = fTrue;
|
|
BOOL fKeepScore = fFalse;
|
|
SMD smd = smdStandard; /* Score MoDe */
|
|
INT ccrdDeal = 3;
|
|
BOOL fOutlineDrag = fFalse;
|
|
|
|
BOOL fHalfCards = fFalse;
|
|
|
|
|
|
INT xCardMargin;
|
|
#define MIN_MARGIN (dxCrd / 8 + 3)
|
|
|
|
|
|
/******************** Internal Functions ****************/
|
|
BOOL FSolInit( HANDLE, HANDLE, LPTSTR, INT );
|
|
VOID GetIniFlags( BOOL * );
|
|
VOID APIENTRY cdtTerm( VOID );
|
|
VOID DoHelp( INT );
|
|
|
|
LRESULT APIENTRY SolWndProc(HWND, UINT, WPARAM, LPARAM);
|
|
|
|
// International stuff
|
|
//
|
|
INT iCurrency;
|
|
TCHAR szCurrency[5];
|
|
|
|
|
|
/******************************************************************************
|
|
* WINMAIN/ENTRY POINT
|
|
* This is the main entry-point for the application. It uses the porting
|
|
* macro MMain() since it was ported from 16bit Windows.
|
|
*
|
|
* The accelerator-table was added from demo-purposes.
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
MMain( hinst, hinstPrev, lpstrCmdLine, sw )
|
|
|
|
MSG msg;
|
|
LPTSTR lpszCmdLine = GetCommandLine();
|
|
|
|
|
|
// Initialize the application.
|
|
//
|
|
if (!FSolInit(hinst, hinstPrev, lpszCmdLine, sw))
|
|
return(0);
|
|
|
|
|
|
// Message-Polling loop.
|
|
//
|
|
msg.wParam = 1;
|
|
while (GetMessage((LPMSG)&msg, NULL, 0, 0))
|
|
{
|
|
if( !TranslateAccelerator( hwndApp, hAccel, &msg ))
|
|
{
|
|
TranslateMessage((LPMSG)&msg);
|
|
DispatchMessage((LPMSG)&msg);
|
|
}
|
|
}
|
|
|
|
return ((int)(msg.wParam ? 1 : 0));
|
|
|
|
// Eliminate unreferenced-variable warnings from
|
|
// porting macro.
|
|
//
|
|
(void)_argv;
|
|
(void)_argc;
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
* FSolInit
|
|
*
|
|
* Main program initialization.
|
|
*
|
|
* Arguments:
|
|
* hinst - instance of this task
|
|
* hinstPrev - previous instance, or NULL if this is the
|
|
* first instance
|
|
* lpszCmdLine - command line argument string
|
|
* sw - show window command
|
|
*
|
|
* Returns:
|
|
* fFalse on failure.
|
|
*
|
|
*****************************************************************************/
|
|
BOOL FSolInit(HANDLE hinst, HANDLE hinstPrev, LPTSTR lpszCmdLine, INT sw)
|
|
{
|
|
WNDCLASSEX cls;
|
|
HDC hdc;
|
|
TEXTMETRIC tm;
|
|
HANDLE hcrsArrow;
|
|
BOOL fStartIconic;
|
|
TCHAR FAR *lpch;
|
|
BOOL fOutline;
|
|
TCHAR szT[20];
|
|
RECT rect;
|
|
INITCOMMONCONTROLSEX icc; // common control registration.
|
|
WORD APIENTRY TimerProc(HWND, UINT, UINT_PTR, DWORD);
|
|
|
|
hinstApp = hinst;
|
|
|
|
/* create stock objects */
|
|
|
|
CchString(szOOM, idsOOM, ARRAYSIZE(szOOM));
|
|
if(!cdtInit((INT FAR *)&dxCrd, (INT FAR *)&dyCrd))
|
|
{
|
|
goto OOMError;
|
|
}
|
|
hcrsArrow = LoadCursor(NULL, IDC_ARROW);
|
|
hdc = GetDC(NULL);
|
|
if(hdc == NULL)
|
|
{
|
|
OOMError:
|
|
OOM();
|
|
return fFalse;
|
|
}
|
|
|
|
GetTextMetrics(hdc, (LPTEXTMETRIC)&tm);
|
|
dyChar = tm.tmHeight;
|
|
dxChar = tm.tmMaxCharWidth;
|
|
if (GetDeviceCaps(hdc, NUMCOLORS) == 2)
|
|
fBW = fTrue;
|
|
|
|
/* BUG: if HORZRES not big enough, have to call cdtDrawExt & shrink dxCrd */
|
|
/* BUG: Need to check VERTRES and divide dxCrd by 2 (esp w/ lores ega) */
|
|
dxScreen = GetDeviceCaps(hdc, HORZRES);
|
|
dyScreen = GetDeviceCaps(hdc, VERTRES);
|
|
if(fHalfCards = dyScreen < 300)
|
|
dyCrd /= 2;
|
|
ReleaseDC(NULL, hdc);
|
|
rgbTable = fBW ? rgbWhite : rgbGreen;
|
|
hbrTable = CreateSolidBrush(rgbTable);
|
|
|
|
srand((WORD) time(NULL));
|
|
|
|
/* load strings */
|
|
CchString(szAppName, idsAppName, ARRAYSIZE(szAppName));
|
|
CchString(szScore, idsScore, ARRAYSIZE(szScore));
|
|
|
|
CchString(szT, idsCardDraw, ARRAYSIZE(szT));
|
|
wmCardDraw = RegisterWindowMessage(szT);
|
|
|
|
/* scan cmd line to see if should come up iconic */
|
|
/* this may be unnecessary with win3.0 (function may be provided to */
|
|
/* do it automatically */
|
|
|
|
fStartIconic = fFalse;
|
|
for(lpch = lpszCmdLine; *lpch != TEXT('\000'); lpch++)
|
|
{
|
|
if(*lpch == TEXT('/') && *(lpch+1) == TEXT('I'))
|
|
{
|
|
fStartIconic = fTrue;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
// 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);
|
|
|
|
/* Load the solitaire icon */
|
|
|
|
hIconMain = LoadIcon(hinstApp, MAKEINTRESOURCE(ID_ICON_MAIN));
|
|
|
|
/* Load the solitaire icon image */
|
|
|
|
hImageMain = LoadImage(hinstApp, MAKEINTRESOURCE(ID_ICON_MAIN),
|
|
IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
|
|
|
|
|
|
/* register window classes */
|
|
|
|
if (hinstPrev == NULL)
|
|
{
|
|
ZeroMemory( &cls, sizeof(cls) );
|
|
cls.cbSize= sizeof(cls);
|
|
cls.style = CS_BYTEALIGNWINDOW | CS_DBLCLKS,
|
|
cls.lpfnWndProc = SolWndProc;
|
|
cls.hInstance = hinstApp;
|
|
cls.hIcon = hIconMain;
|
|
cls.hIconSm= hImageMain;
|
|
cls.hCursor = hcrsArrow;
|
|
cls.hbrBackground = hbrTable;
|
|
cls.lpszMenuName = MAKEINTRESOURCE(idmSol);
|
|
cls.lpszClassName = (LPTSTR)szClass;
|
|
if (!RegisterClassEx(&cls))
|
|
{
|
|
goto OOMError;
|
|
}
|
|
}
|
|
|
|
/* Determine the proper starting size for the window */
|
|
|
|
/* Card margin is just a little bigger than 1/8 of a card */
|
|
xCardMargin = MIN_MARGIN;
|
|
|
|
/* We need 7 card widths and 8 margins */
|
|
rect.right = dxCrd * 7 + 8 * xCardMargin;
|
|
|
|
/* Compute the window size we need for a client area this big */
|
|
rect.bottom = dyCrd * 4;
|
|
rect.left = rect.top = 0;
|
|
AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, TRUE);
|
|
rect.right -= rect.left;
|
|
rect.bottom -= rect.top;
|
|
|
|
/* Make sure it's not too big */
|
|
if (rect.bottom > dyScreen)
|
|
rect.bottom = dyScreen;
|
|
|
|
/* create our windows */
|
|
if (!
|
|
(hwndApp = CreateWindow( (LPTSTR)szClass, (LPTSTR)szAppName,
|
|
fStartIconic ? WS_OVERLAPPEDWINDOW | WS_MINIMIZE | WS_CLIPCHILDREN:
|
|
WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
|
|
CW_USEDEFAULT, 0,
|
|
rect.right, rect.bottom,
|
|
(HWND)NULL, (HMENU)NULL, hinstApp, (LPTSTR)NULL)))
|
|
{
|
|
goto OOMError;
|
|
}
|
|
|
|
GetIniFlags(&fOutline);
|
|
|
|
|
|
if(SetTimer(hwndApp, 666, 250, TimerProc) == 0)
|
|
{
|
|
goto OOMError;
|
|
}
|
|
|
|
FInitGm();
|
|
FSetDrag(fOutline);
|
|
|
|
ShowWindow(hwndApp, sw);
|
|
UpdateWindow(hwndApp);
|
|
|
|
hAccel = LoadAccelerators( hinst, TEXT("HiddenAccel") );
|
|
|
|
FRegisterStat(hinstPrev == NULL);
|
|
if(fStatusBar)
|
|
FCreateStat();
|
|
|
|
Assert(pgmCur != NULL);
|
|
if(sw != SW_SHOWMINNOACTIVE && sw != SW_MINIMIZE)
|
|
PostMessage(hwndApp, WM_COMMAND, idsInitiate, 0L);
|
|
|
|
return(fTrue);
|
|
}
|
|
|
|
|
|
|
|
VOID DoPaint(HWND hwnd)
|
|
{
|
|
PAINTSTRUCT paint;
|
|
|
|
BeginPaint(hwnd, (LPPAINTSTRUCT) &paint);
|
|
if(pgmCur)
|
|
SendGmMsg(pgmCur, msggPaint, (INT_PTR) &paint, 0);
|
|
EndPaint(hwnd, (LPPAINTSTRUCT) &paint);
|
|
}
|
|
|
|
|
|
/* SolWndProc
|
|
*
|
|
* Window procedure for main Sol window.
|
|
*
|
|
* Arguments:
|
|
* hwnd - window handle receiving the message - should
|
|
* be hwndSol
|
|
* wm - window message
|
|
* wParam, lParam - more info as required by wm
|
|
*
|
|
* Returns:
|
|
* depends on the message
|
|
*/
|
|
LRESULT APIENTRY SolWndProc(HWND hwnd, UINT wm, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
HMENU hmenu;
|
|
PT pt;
|
|
INT msgg;
|
|
VOID NewGame();
|
|
VOID StatString();
|
|
|
|
switch (wm)
|
|
{
|
|
default:
|
|
if(wm == wmCardDraw)
|
|
{
|
|
switch(wParam)
|
|
{
|
|
case drwInit:
|
|
return MAKELONG(dxCrd, dyCrd);
|
|
|
|
case drwDrawCard:
|
|
#define lpcddr ((CDDR FAR *)lParam)
|
|
return cdtDraw(lpcddr->hdc, lpcddr->x, lpcddr->y, lpcddr->cd, lpcddr->mode, lpcddr->rgbBgnd);
|
|
#undef lpcddr
|
|
|
|
case drwClose:
|
|
PostMessage(hwndApp, WM_SYSCOMMAND, SC_CLOSE, 0L);
|
|
return fTrue;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case WM_HELP:
|
|
DoHelp( idsHelpIndex );
|
|
break;
|
|
|
|
case WM_DESTROY:
|
|
KillTimer(hwndApp, 666);
|
|
SendGmMsg(pgmCur, msggEnd, 0, 0);
|
|
FSetDrag(fTrue); /* Free up screen bitmaps if we made em */
|
|
cdtTerm();
|
|
DeleteObject(hbrTable);
|
|
PostQuitMessage(0);
|
|
break;
|
|
|
|
case WM_ACTIVATE:
|
|
if( GET_WM_ACTIVATE_STATE(wParam, lParam) &&
|
|
!GET_WM_ACTIVATE_FMINIMIZED(wParam, lParam) )
|
|
DoPaint(hwnd);
|
|
break;
|
|
|
|
case WM_KILLFOCUS:
|
|
if(pgmCur->fButtonDown)
|
|
SendGmMsg(pgmCur, msggMouseUp, 0, fTrue);
|
|
/* Fall through. */
|
|
case WM_SETFOCUS:
|
|
ShowCursor(wm == WM_SETFOCUS);
|
|
break;
|
|
|
|
|
|
case WM_SIZE:
|
|
{
|
|
int nNewMargin;
|
|
int nMinMargin;
|
|
|
|
fIconic = IsIconic(hwnd);
|
|
GetClientRect(hwnd, (LPRECT) &rcClient);
|
|
|
|
/* Compute the new margin size if any and if necessary, redraw */
|
|
nNewMargin = ((short)lParam - 7 * (short)dxCrd) / 8;
|
|
nMinMargin = MIN_MARGIN;
|
|
if (nNewMargin < nMinMargin && xCardMargin != nMinMargin)
|
|
nNewMargin = nMinMargin;
|
|
if (nNewMargin >= nMinMargin)
|
|
{
|
|
xCardMargin = nNewMargin;
|
|
PositionCols();
|
|
InvalidateRect(hwnd, NULL, TRUE);
|
|
}
|
|
|
|
/* Code always falls through here */
|
|
}
|
|
|
|
|
|
case WM_MOVE:
|
|
StatMove();
|
|
break;
|
|
|
|
|
|
case WM_MENUSELECT:
|
|
// Don't send in garbage if not a menu item
|
|
if( GET_WM_MENUSELECT_FLAGS( wParam, lParam ) & MF_POPUP ||
|
|
GET_WM_MENUSELECT_FLAGS( wParam, lParam ) & MF_SYSMENU ||
|
|
GET_WM_MENUSELECT_FLAGS( wParam, lParam ) & MF_SEPARATOR ) {
|
|
|
|
StatString(idsNil);
|
|
}
|
|
else {
|
|
StatString( GET_WM_MENUSELECT_CMD( wParam, lParam ));
|
|
}
|
|
break;
|
|
|
|
case WM_KEYDOWN:
|
|
Assert(pgmCur);
|
|
SendGmMsg(pgmCur, msggKeyHit, wParam, 0);
|
|
break;
|
|
|
|
case WM_LBUTTONDOWN:
|
|
/* ProfStart(); */
|
|
SetCapture(hwnd);
|
|
if(pgmCur->fButtonDown)
|
|
break;
|
|
msgg = msggMouseDown;
|
|
goto DoMouse;
|
|
|
|
case WM_LBUTTONDBLCLK:
|
|
msgg = msggMouseDblClk;
|
|
if(pgmCur->fButtonDown)
|
|
break;
|
|
goto DoMouse;
|
|
|
|
case WM_RBUTTONDOWN:
|
|
// If the left mousebutton is down, ignore the right click.
|
|
if (GetCapture())
|
|
break;
|
|
msgg = msggMouseRightClk;
|
|
goto DoMouse;
|
|
|
|
case WM_LBUTTONUP:
|
|
/* ProfStop(); */
|
|
ReleaseCapture();
|
|
msgg = msggMouseUp;
|
|
if(!pgmCur->fButtonDown)
|
|
break;
|
|
goto DoMouse;
|
|
|
|
case WM_MOUSEMOVE:
|
|
msgg = msggMouseMove;
|
|
if(!pgmCur->fButtonDown)
|
|
break;
|
|
DoMouse:
|
|
Assert(pgmCur != NULL);
|
|
LONG2POINT( lParam, pt );
|
|
Assert(pgmCur);
|
|
SendGmMsg(pgmCur, msgg, (INT_PTR) &pt, 0);
|
|
break;
|
|
|
|
|
|
case WM_COMMAND:
|
|
switch( GET_WM_COMMAND_ID( wParam, lParam ))
|
|
{
|
|
/* Game menu */
|
|
case idsInitiate:
|
|
NewGame(fTrue, fFalse);
|
|
break;
|
|
case idsUndo:
|
|
Assert(pgmCur);
|
|
SendGmMsg(pgmCur, msggUndo, 0, 0);
|
|
break;
|
|
case idsBacks:
|
|
DoBacks();
|
|
break;
|
|
case idsOptions:
|
|
DoOptions();
|
|
break;
|
|
case idsExit:
|
|
PostMessage(hwnd, WM_SYSCOMMAND, SC_CLOSE, 0L);
|
|
break;
|
|
/* Help Menu */
|
|
case (WORD)idsHelpIndex:
|
|
case (WORD)idsHelpSearch:
|
|
case (WORD)idsHelpUsing:
|
|
DoHelp( (INT)(SHORT)GET_WM_COMMAND_ID( wParam, lParam ));
|
|
break;
|
|
case idsAbout:
|
|
{
|
|
TCHAR szExtraInfo[100];
|
|
CchString(szExtraInfo, idsExtraInfo, ARRAYSIZE(szExtraInfo));
|
|
#ifndef _GAMBIT_
|
|
ShellAbout(hwnd, szAppName, szExtraInfo, hIconMain);
|
|
#endif
|
|
break;
|
|
}
|
|
case idsForceWin:
|
|
SendGmMsg(pgmCur, msggForceWin, 0, 0);
|
|
break;
|
|
#ifdef DEBUG
|
|
case idsGameNo:
|
|
if(FSetGameNo())
|
|
NewGame(fFalse, fFalse);
|
|
break;
|
|
|
|
case idsCardMacs:
|
|
PrintCardMacs(pgmCur);
|
|
break;
|
|
case idsAssertFail:
|
|
Assert(fFalse);
|
|
break;
|
|
case idsMarquee:
|
|
break;
|
|
|
|
case idsScreenShots:
|
|
fScreenShots ^= 1;
|
|
CheckMenuItem(GetMenu(hwnd), idsScreenShots, fScreenShots ? MF_CHECKED|MF_BYCOMMAND : MF_UNCHECKED|MF_BYCOMMAND);
|
|
InvalidateRect(hwndStat, NULL, fTrue);
|
|
if(fScreenShots)
|
|
InvalidateRect(hwnd, NULL, fTrue);
|
|
break;
|
|
#endif
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case WM_INITMENU:
|
|
hmenu = GetMenu(hwnd);
|
|
Assert(pgmCur);
|
|
EnableMenuItem(hmenu, idsUndo,
|
|
pgmCur->udr.fAvail && !FSelOfGm(pgmCur) ? MF_ENABLED : MF_DISABLED|MF_GRAYED);
|
|
EnableMenuItem(hmenu, idsInitiate, FSelOfGm(pgmCur) ? MF_DISABLED|MF_GRAYED : MF_ENABLED);
|
|
EnableMenuItem(hmenu, idsBacks, FSelOfGm(pgmCur) ? MF_DISABLED|MF_GRAYED : MF_ENABLED);
|
|
EnableMenuItem(hmenu, idsAbout, FSelOfGm(pgmCur) ? MF_DISABLED|MF_GRAYED : MF_ENABLED);
|
|
break;
|
|
|
|
case WM_PAINT:
|
|
if(!fIconic)
|
|
{
|
|
DoPaint(hwnd);
|
|
return(0L);
|
|
}
|
|
break;
|
|
}
|
|
|
|
return(DefWindowProc(hwnd, wm, wParam, lParam));
|
|
}
|
|
|
|
|
|
|
|
HDC HdcSet(HDC hdc, X xOrg, Y yOrg)
|
|
{
|
|
HDC hdcT = hdcCur;
|
|
hdcCur = hdc;
|
|
xOrgCur = xOrg;
|
|
yOrgCur = yOrg;
|
|
return hdcT;
|
|
}
|
|
|
|
|
|
|
|
BOOL FGetHdc()
|
|
{
|
|
HDC hdc;
|
|
|
|
Assert(hwndApp);
|
|
if(hdcCur != NULL)
|
|
{
|
|
usehdcCur++;
|
|
return fTrue;
|
|
}
|
|
|
|
hdc = GetDC(hwndApp);
|
|
if(hdc == NULL)
|
|
return fFalse;
|
|
HdcSet(hdc, 0, 0);
|
|
usehdcCur = 1;
|
|
return fTrue;
|
|
}
|
|
|
|
|
|
VOID ReleaseHdc()
|
|
{
|
|
if(hdcCur == NULL)
|
|
return;
|
|
if(--usehdcCur == 0)
|
|
{
|
|
ReleaseDC(hwndApp, hdcCur);
|
|
hdcCur = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
WORD APIENTRY TimerProc(HWND hwnd, UINT wm, UINT_PTR id, DWORD dwTime)
|
|
{
|
|
|
|
if(pgmCur != NULL)
|
|
SendGmMsg(pgmCur, msggTimer, 0, 0);
|
|
return fTrue;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
VOID ChangeBack(INT mode)
|
|
{
|
|
|
|
if(mode == modeFaceDown)
|
|
return;
|
|
modeFaceDown = mode;
|
|
InvalidateRect(hwndApp, NULL, fTrue);
|
|
}
|
|
|
|
|
|
VOID NewGame(BOOL fNewSeed, BOOL fZeroScore)
|
|
{
|
|
|
|
#ifdef DEBUG
|
|
InitDebug();
|
|
#endif
|
|
if(fNewSeed)
|
|
{
|
|
static INT lastrnd= -1; // previous rand() value
|
|
INT rnd1; // trial rand() value
|
|
INT Param;
|
|
|
|
// It was reported that games never changed.
|
|
// We could not repro it so see if it happens
|
|
// and output a message to the debugger.
|
|
//
|
|
|
|
Param= (INT) time(NULL);
|
|
srand( igmCur = ((WORD) Param) & 0x7fff);
|
|
|
|
#ifdef DEBUG
|
|
rnd1= rand();
|
|
|
|
if( lastrnd == rnd1 )
|
|
{
|
|
TCHAR szText[100];
|
|
wsprintf(szText,TEXT("Games repeat: time= %d GetLastError= %d\n"),
|
|
Param, GetLastError());
|
|
OutputDebugString(szText);
|
|
}
|
|
|
|
lastrnd= rnd1;
|
|
#endif
|
|
|
|
}
|
|
|
|
#ifdef DEBUG
|
|
SendGmMsg(pgmCur, msggChangeScore, 0, 0);
|
|
#endif
|
|
SendGmMsg(pgmCur, msggDeal, fZeroScore, 0);
|
|
}
|
|
|
|
|
|
|
|
INT_PTR APIENTRY About(HWND hdlg, UINT iMessage, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
if (iMessage == WM_COMMAND)
|
|
{
|
|
EndDialog(hdlg,fTrue);
|
|
return fTrue;
|
|
}
|
|
else if (iMessage == WM_INITDIALOG)
|
|
return fTrue;
|
|
else
|
|
return fFalse;
|
|
}
|
|
|
|
|
|
VOID DoHelp(INT idContext)
|
|
{
|
|
CHAR sz[100];
|
|
HWND hwndResult;
|
|
|
|
LoadStringA(hinstApp, (WORD)idsHelpFile, (LPSTR)sz, 100);
|
|
|
|
#ifndef _GAMBIT_
|
|
switch(idContext)
|
|
{
|
|
case idsHelpUsing:
|
|
hwndResult = HtmlHelpA(GetDesktopWindow(), "NTHelp.chm", HH_DISPLAY_TOPIC, 0);
|
|
break;
|
|
case idsHelpIndex:
|
|
hwndResult = HtmlHelpA(GetDesktopWindow(), sz, HH_DISPLAY_TOPIC, 0);
|
|
break;
|
|
case idsHelpSearch:
|
|
hwndResult = HtmlHelpA(GetDesktopWindow(), sz, HH_DISPLAY_INDEX, 0);
|
|
break;
|
|
}
|
|
if(!hwndResult)
|
|
ErrorIds(idsNoHelp);
|
|
#endif
|
|
}
|
|
|
|
|
|
VOID GetIniFlags(BOOL *pfOutline)
|
|
{
|
|
INI ini;
|
|
INT mode;
|
|
|
|
ini.w = 0;
|
|
ini.grbit.fStatusBar = fStatusBar;
|
|
ini.grbit.fTimedGame = fTimedGame;
|
|
ini.grbit.fOutlineDrag = fOutlineDrag;
|
|
ini.grbit.fDrawThree = ccrdDeal == 3;
|
|
ini.grbit.fKeepScore = fKeepScore;
|
|
ini.grbit.fSMD = 0;
|
|
|
|
ini.w = GetIniInt(idsAppName, idsOpts, ini.w);
|
|
|
|
fStatusBar = ini.grbit.fStatusBar ? 1 : 0;
|
|
fTimedGame = ini.grbit.fTimedGame ? 1 : 0;
|
|
*pfOutline = ini.grbit.fOutlineDrag ? 1 : 0;
|
|
ccrdDeal = ini.grbit.fDrawThree ? 3 : 1;
|
|
fKeepScore = ini.grbit.fKeepScore ? 1 : 0;
|
|
switch(ini.grbit.fSMD)
|
|
{
|
|
default:
|
|
smd = smdStandard;
|
|
break;
|
|
case 1:
|
|
smd = smdVegas;
|
|
break;
|
|
case 2:
|
|
smd = smdNone;
|
|
break;
|
|
}
|
|
|
|
mode = GetIniInt(idsAppName, idsBack, rand() % cIDFACEDOWN) + IDFACEDOWNFIRST-1;
|
|
ChangeBack(PegRange(mode, IDFACEDOWNFIRST, IDFACEDOWN12));
|
|
|
|
iCurrency = GetIniInt(idsIntl, idsiCurrency, 0);
|
|
FGetIniString(idsIntl, idssCurrency, szCurrency, TEXT("$"), sizeof(szCurrency));
|
|
}
|
|
|
|
|
|
VOID WriteIniFlags(INT wif)
|
|
{
|
|
INI ini;
|
|
|
|
if(wif & wifOpts)
|
|
{
|
|
ini.w = 0;
|
|
ini.grbit.fStatusBar = fStatusBar;
|
|
ini.grbit.fTimedGame = fTimedGame;
|
|
ini.grbit.fOutlineDrag = fOutlineDrag;
|
|
ini.grbit.fDrawThree = ccrdDeal == 3;
|
|
ini.grbit.fKeepScore = fKeepScore;
|
|
switch(smd)
|
|
{
|
|
default:
|
|
Assert(fFalse);
|
|
break;
|
|
case smdStandard:
|
|
ini.grbit.fSMD = 0;
|
|
break;
|
|
case smdVegas:
|
|
ini.grbit.fSMD = 1;
|
|
break;
|
|
case smdNone:
|
|
ini.grbit.fSMD = 2;
|
|
break;
|
|
}
|
|
|
|
FWriteIniInt(idsAppName, idsOpts, ini.w);
|
|
}
|
|
if(wif & wifBack)
|
|
FWriteIniInt(idsAppName, idsBack, modeFaceDown-IDFACEDOWNFIRST+1);
|
|
}
|