int lastIndex = 0; /* [HGM] autoinc: last game/position used in match mode */
int opponentKibitzes;
int lastSavedGame; /* [HGM] save: ID of game */
+char chatPartner[MAX_CHAT][MSG_SIZ]; /* [HGM] chat: list of chatting partners */
+extern int chatCount;
+int chattingPartner;
/* States for ics_getting_history */
#define H_FALSE 0
}
void
+KeepAlive()
+{ // [HGM] alive: periodically send dummy (date) command to ICS to prevent time-out
+ SendToICS("date\n");
+ if(appData.keepAlive) ScheduleDelayedEvent(KeepAlive, appData.keepAlive*60*1000);
+}
+
+void
SendToICS(s)
char *s;
{
int tkind;
int backup; /* [DM] For zippy color lines */
char *p;
+ char talker[MSG_SIZ]; // [HGM] chat
if (appData.debugMode) {
if (!error) {
parse[parse_pos++] = buf[i];
if (buf[i] == '\n') {
parse[parse_pos] = NULLCHAR;
+ if(chattingPartner>=0) {
+ char mess[MSG_SIZ];
+ sprintf(mess, "%s%s", talker, parse);
+ OutputChatMessage(chattingPartner, mess);
+ chattingPartner = -1;
+ } else
if(!suppressKibitz) // [HGM] kibitz
AppendComment(forwardMostMove, StripHighlight(parse));
else { // [HGM kibitz: divert memorized engine kibitz to engine-output window
}
} // [HGM] kibitz: end of patch
+//if(appData.debugMode) fprintf(debugFP, "hunt for tell, buf = %s\n", buf+i);
+
+ // [HGM] chat: intercept tells by users for which we have an open chat window
+ if(started == STARTED_NONE && (looking_at(buf, &i, "* tells you:") || looking_at(buf, &i, "* says:") ||
+ looking_at(buf, &i, "* whispers:"))) {
+ int p;
+ sscanf(star_match[0], "%[^(]", talker+1); // strip (C) or (U) off ICS handle
+ chattingPartner = -1;
+ if(buf[i-3] == 'r') // whisper; look if there is a WHISPER chatbox
+ for(p=0; p<MAX_CHAT; p++) if(!strcmp("WHISPER", chatPartner[p])) {
+ talker[0] = '['; strcat(talker, "]");
+ chattingPartner = p; break;
+ }
+ if(chattingPartner<0) // if not, look if there is a chatbox for this indivdual
+ for(p=0; p<MAX_CHAT; p++) if(!strcasecmp(talker+1, chatPartner[p])) {
+ talker[0] = 0;
+ chattingPartner = p; break;
+ }
+ if(chattingPartner<0) i = oldi; else {
+ started = STARTED_COMMENT;
+ parse_pos = 0; parse[0] = NULLCHAR;
+ savingComment = TRUE;
+ suppressKibitz = TRUE;
+ }
+ } // [HGM] chat: end of patch
+
if (appData.zippyTalk || appData.zippyPlay) {
/* [DM] Backup address for color zippy lines */
backup = i;
break;
}
SendToICS(user_move);
+ if(appData.keepAlive) // [HGM] alive: schedule sending of dummy 'date' command
+ ScheduleDelayedEvent(KeepAlive, appData.keepAlive*60*1000);
}
void
if(appData.autoKibitz && !appData.icsEngineAnalyze ) { /* [HGM] kibitz: send most-recent PV info to ICS */
char buf[3*MSG_SIZ];
- sprintf(buf, "kibitz !!! %+.2f/%d (%.2f sec, %u nodes, %1.0f knps) PV=%s\n",
+ sprintf(buf, "kibitz !!! %+.2f/%d (%.2f sec, %u nodes, %.0f knps) PV=%s\n",
programStats.score / 100.,
programStats.depth,
programStats.time / 100.,
(unsigned int)programStats.nodes / (10*abs(programStats.time) + 1.),
programStats.movelist);
SendToICS(buf);
+if(appData.debugMode) fprintf(debugFP, "nodes = %d, %lld\n", (int) programStats.nodes, programStats.nodes);
}
}
#endif
char *VariantName P((VariantClass v));
VariantClass StringToVariant P((char *e));
double u64ToDouble P((u64 value));
+void OutputChatMessage P((int partner, char *mess));
+
char *StrStr P((char *string, char *match));
char *StrCaseStr P((char *string, char *match));
extern char* StripHighlight P((char *)); /* returns static data */
extern char* StripHighlightAndTitle P((char *)); /* returns static data */
-typedef enum { CheckBox, ComboBox, TextBox, Button, Spin,
+typedef enum { CheckBox, ComboBox, TextBox, Button, Spin, ResetButton,
SaveButton, FileName, PathName, Slider, Message } Control;
typedef struct _OPT { // [HGM] options: descriptor of UCI-style option
char *secondOptions;
char *fenOverride1;
char *fenOverride2;
+ Boolean keepAlive; /* [HGM] alive */
} AppData, *AppDataPtr;
/* [AS] PGN tags (for showing in the game list) */
int holdingsWidth; /* number of files left and right of board, 0 or 2 */
} GameInfo;
+// [HGM] chat
+#define MAX_CHAT 3
+extern int chatCount;
+extern char chatPartner[MAX_CHAT][MSG_SIZ];
+
#endif
OBJS=backend.o book.o gamelist.o lists.o moves.o pgntags.o uci.o zippy.o\\r
parser.o wbres.o wclipbrd.o wedittags.o wengineo.o wevalgraph.o\\r
wgamelist.o whistory.o winboard.o wlayout.o woptions.o wsnap.o\\r
- wsockerr.o help.o wsettings.o\r
+ wsockerr.o help.o wsettings.o wchat.o\r
\r
\r
# make compiling less spammy\r
book.o: ../book.c ../common.h ../backend.h ../lists.h\r
$(call compile, $<)\r
\r
-uci.o: ../uci.c ..//common.h ../backend.h ../frontend.h ../lists.h\r
+uci.o: ../uci.c ../common.h ../backend.h ../frontend.h ../lists.h\r
$(call compile, $<)\r
\r
-wsettings.o: wsettings.c ..//common.h ../backend.h ../frontend.h ../lists.h\r
+wsettings.o: wsettings.c ../common.h ../backend.h ../frontend.h ../lists.h\r
+ $(call compile, $<)\r
+\r
+wchat.o: wchat.c winboard.h wsnap.h ../common.h ../backend.h ../frontend.h ../lists.h\r
$(call compile, $<)\r
\r
%.o: %.c\r
OBJS=backend.obj book.obj gamelist.obj lists.obj moves.obj pgntags.obj uci.obj\\r
zippy.obj parser.obj wclipbrd.obj wedittags.obj wengineo.obj wevalgraph.obj\\r
wgamelist.obj whistory.obj winboard.obj wlayout.obj woptions.obj wsnap.obj\\r
- wsockerr.obj help.obj wsettings.obj\r
+ wsockerr.obj help.obj wsettings.obj wchat.obj\r
\r
\r
# Debugging?\r
../backend.h ../backendz.h ../lists.h\r
$(CC) $(CFLAGS) ../zippy.c\r
\r
-uci.obj: ../uci.c ..//common.h ../backend.h ../frontend.h ../lists.h\r
+uci.obj: ../uci.c ../common.h ../backend.h ../frontend.h ../lists.h\r
$(CC) $(CFLAGS) ../uci.c\r
\r
\r
-wsettings.obj: wsettings.c ..//common.h ../backend.h ../frontend.h ../lists.h\r
+wsettings.obj: wsettings.c ../common.h ../backend.h ../frontend.h ../lists.h\r
$(CC) $(CFLAGS) wsettings.c\r
\r
+wchat.obj: wchat.c winboard.h wsnap.h ../common.h ../backend.h ../frontend.h ../lists.h\r
+ $(CC) $(CFLAGS) wchat.c\r
+\r
\r
$(PROJ).exe: $(OBJS) $(PROJ).res $(PROJ).hlp\r
$(LINK) $(LFLAGS) $(OBJS) wsock32.lib comctl32.lib winmm.lib shell32.lib\\r
#define IDM_FlipClock 1700\r
#define OPT_AllWhite 1701\r
#define OPT_UpsideDown 1702\r
+#define DLG_Chat 1720\r
+#define IDC_Change 1721\r
+#define IDC_ChatPartner 1722\r
+#define IDC_ChatMemo 1723\r
+#define OPT_ChatInput 1724\r
+#define IDC_Clear 1725\r
+#define IDC_Send 1726\r
+#define IDM_NewChat 1727\r
#define IDC_SPECIFY_ENG_STATIC 1814\r
#define IDC_SPECIFY_SERVER_STATIC 1815\r
#define OPT_MESS 1818\r
--- /dev/null
+/*\r
+ * Chat window (PV)\r
+ *\r
+ * Author: H.G.Muller (August 2009)\r
+ *\r
+ * ------------------------------------------------------------------------\r
+ *\r
+ * GNU XBoard is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or (at\r
+ * your option) any later version.\r
+ *\r
+ * GNU XBoard is distributed in the hope that it will be useful, but\r
+ * WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
+ * General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see http://www.gnu.org/licenses/. *\r
+ *\r
+ *------------------------------------------------------------------------\r
+ ** See the file ChangeLog for a revision history. */\r
+\r
+#include "config.h"\r
+\r
+#include <windows.h> /* required for all Windows applications */\r
+#include <richedit.h>\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <malloc.h>\r
+#include <commdlg.h>\r
+#include <dlgs.h>\r
+\r
+#include "common.h"\r
+#include "winboard.h"\r
+#include "frontend.h"\r
+#include "backend.h"\r
+\r
+#include "wsnap.h"\r
+\r
+int chatCount;\r
+extern char chatPartner[MAX_CHAT][MSG_SIZ];\r
+HANDLE chatHandle[MAX_CHAT];\r
+\r
+void SendToICS P((char *s));\r
+void ChatPopUp();\r
+void ChatPopDown();\r
+\r
+/* Imports from backend.c */\r
+char * SavePart(char *str);\r
+extern int opponentKibitzes;\r
+\r
+/* Imports from winboard.c */\r
+extern HWND ChatDialog;\r
+\r
+extern HINSTANCE hInst;\r
+extern HWND hwndMain;\r
+\r
+extern WindowPlacement wpChat[MAX_CHAT];\r
+\r
+extern BoardSize boardSize;\r
+\r
+/* Module variables */\r
+#define H_MARGIN 5\r
+#define V_MARGIN 5\r
+\r
+// front end, although we might make GetWindowRect front end instead\r
+static int GetControlWidth( HWND hDlg, int id )\r
+{\r
+ RECT rc;\r
+\r
+ GetWindowRect( GetDlgItem( hDlg, id ), &rc );\r
+\r
+ return rc.right - rc.left;\r
+}\r
+\r
+// front end?\r
+static int GetControlHeight( HWND hDlg, int id )\r
+{\r
+ RECT rc;\r
+\r
+ GetWindowRect( GetDlgItem( hDlg, id ), &rc );\r
+\r
+ return rc.bottom - rc.top;\r
+}\r
+\r
+static void SetControlPos( HWND hDlg, int id, int x, int y, int width, int height )\r
+{\r
+ HWND hControl = GetDlgItem( hDlg, id );\r
+\r
+ SetWindowPos( hControl, HWND_TOP, x, y, width, height, SWP_NOZORDER );\r
+}\r
+\r
+// Also here some of the size calculations should go to the back end, and their actual application to a front-end routine\r
+static void ResizeWindowControls( HWND hDlg )\r
+{\r
+ RECT rc;\r
+ int clientWidth;\r
+ int clientHeight;\r
+ int maxControlWidth;\r
+ int buttonWidth, buttonHeight;\r
+#if 0\r
+}\r
+#else\r
+ /* Initialize variables */\r
+ GetClientRect( hDlg, &rc );\r
+\r
+ clientWidth = rc.right - rc.left;\r
+ clientHeight = rc.bottom - rc.top;\r
+\r
+ maxControlWidth = clientWidth - 2*H_MARGIN;\r
+ buttonWidth = GetControlWidth(hDlg, IDC_Send);\r
+ buttonHeight = GetControlHeight(hDlg, IDC_Send);\r
+\r
+ /* Resize controls */\r
+ SetControlPos( hDlg, IDC_Clear, maxControlWidth+H_MARGIN-2*buttonWidth-5, V_MARGIN, buttonWidth, buttonHeight );\r
+ SetControlPos( hDlg, IDC_Send, maxControlWidth+H_MARGIN-buttonWidth, V_MARGIN, buttonWidth, buttonHeight );\r
+ SetControlPos( hDlg, IDC_ChatMemo, H_MARGIN, 2*V_MARGIN+buttonHeight, maxControlWidth, clientHeight-3*V_MARGIN-2*buttonHeight );\r
+ SetControlPos( hDlg, OPT_ChatInput, H_MARGIN, clientHeight-V_MARGIN-buttonHeight, maxControlWidth, buttonHeight );\r
+\r
+// InvalidateRect( GetDlgItem(hDlg,IDC_EngineMemo1), NULL, FALSE );\r
+// InvalidateRect( GetDlgItem(hDlg,IDC_EngineMemo2), NULL, FALSE );\r
+}\r
+#endif\r
+\r
+// front end. Actual printing of PV lines into the output field\r
+static void InsertIntoMemo( HANDLE hDlg, char * text )\r
+{\r
+ HANDLE hMemo = GetDlgItem(hDlg, IDC_ChatMemo);\r
+\r
+ SendMessage( hMemo, EM_SETSEL, 1000000, 1000000 );\r
+\r
+ SendMessage( hMemo, EM_REPLACESEL, (WPARAM) FALSE, (LPARAM) text );\r
+ SendMessage( hMemo, EM_SCROLLCARET, 0, 0);\r
+}\r
+\r
+// This seems pure front end\r
+LRESULT CALLBACK ChatProc( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam )\r
+{\r
+ static SnapData sd;\r
+ char buf[MSG_SIZ], mess[MSG_SIZ];\r
+ int partner = -1, i;\r
+\r
+ for(i=0; i<MAX_CHAT; i++) if(hDlg == chatHandle[i]) { partner = i; break; }\r
+\r
+ switch (message) {\r
+ case WM_INITDIALOG:\r
+ if(partner<0) {\r
+ for(i=0; i<MAX_CHAT; i++) if(chatHandle[i] == NULL) { partner = i; break; }\r
+ chatHandle[partner] = hDlg;\r
+ sprintf(buf, "Chat Window %s", first.tidy);\r
+ SetWindowText(hDlg, buf);\r
+ }\r
+ chatPartner[partner][0] = 0;\r
+\r
+ return FALSE;\r
+\r
+ case WM_COMMAND:\r
+ switch (LOWORD(wParam)) {\r
+\r
+ case IDCANCEL:\r
+ chatHandle[partner] = 0;\r
+ chatPartner[partner][0] = 0;\r
+ ChatPopDown();\r
+ EndDialog(hDlg, TRUE);\r
+ break;\r
+\r
+ case IDC_Clear:\r
+ SendMessage( GetDlgItem(hDlg, IDC_ChatMemo), WM_SETTEXT, 0, (LPARAM) "" );\r
+ break;\r
+\r
+ case IDC_Change:\r
+ GetDlgItemText(hDlg, IDC_ChatPartner, chatPartner[partner], MSG_SIZ);\r
+ break;\r
+\r
+ case IDC_Send:\r
+ GetDlgItemText(hDlg, OPT_ChatInput, mess, MSG_SIZ);\r
+ SetDlgItemText(hDlg, OPT_ChatInput, "");\r
+ // from here on it could be back-end\r
+ if(strcmp("WHISPER", chatPartner[partner])) {\r
+ sprintf(buf, "> %s\n", mess); // echo only tells, not whispers\r
+ InsertIntoMemo(hDlg, buf);\r
+ sprintf(buf, "tell %s %s\n", chatPartner[partner], mess);\r
+ } else sprintf(buf, "whisper %s\n", mess); // SAY box uses "say" to send\r
+ SendToICS(buf);\r
+ break;\r
+\r
+ default:\r
+ break;\r
+ }\r
+\r
+ break;\r
+\r
+ case WM_CLOSE:\r
+ chatHandle[partner] = 0;\r
+ chatPartner[partner][0] = 0;\r
+ ChatPopDown();\r
+ EndDialog(hDlg, TRUE);\r
+ break;\r
+\r
+ case WM_SIZE:\r
+ ResizeWindowControls( hDlg );\r
+ break;\r
+\r
+ case WM_ENTERSIZEMOVE:\r
+ return OnEnterSizeMove( &sd, hDlg, wParam, lParam );\r
+\r
+ case WM_SIZING:\r
+ return OnSizing( &sd, hDlg, wParam, lParam );\r
+\r
+ case WM_MOVING:\r
+ return OnMoving( &sd, hDlg, wParam, lParam );\r
+\r
+ case WM_EXITSIZEMOVE:\r
+ return OnExitSizeMove( &sd, hDlg, wParam, lParam );\r
+ }\r
+\r
+ return FALSE;\r
+}\r
+\r
+// front end\r
+void ChatPopUp()\r
+{\r
+ FARPROC lpProc;\r
+ \r
+ if(chatCount >= MAX_CHAT) return;\r
+\r
+ CheckMenuItem(GetMenu(hwndMain), IDM_NewChat, MF_CHECKED);\r
+ chatCount++;\r
+\r
+ lpProc = MakeProcInstance( (FARPROC) ChatProc, hInst );\r
+\r
+ /* Note to self: dialog must have the WS_VISIBLE style set, otherwise it's not shown! */\r
+ CreateDialog( hInst, MAKEINTRESOURCE(DLG_Chat), hwndMain, (DLGPROC)lpProc );\r
+\r
+ FreeProcInstance(lpProc);\r
+\r
+}\r
+\r
+// front end\r
+void ChatPopDown()\r
+{\r
+ if(--chatCount <= 0)\r
+ CheckMenuItem(GetMenu(hwndMain), IDM_NewChat, MF_UNCHECKED);\r
+}\r
+\r
+\r
+//------------------------ pure back-end routines -------------------------------\r
+\r
+void OutputChatMessage(int partner, char *text)\r
+{\r
+ if(!chatHandle[partner]) return;\r
+\r
+ InsertIntoMemo(chatHandle[partner], text);\r
+}\r
\r
extern int whiteFlag, blackFlag;\r
Boolean flipClock = FALSE;\r
+extern HANDLE chatHandle[];\r
+extern int ics_type;\r
\r
void DisplayHoldingsCount(HDC hdc, int x, int y, int align, int copyNumber);\r
VOID NewVariantPopup(HWND hwnd);\r
void AnimateAtomicCapture(int fromX, int fromY, int toX, int toY, int nFrames);\r
void DisplayMove P((int moveNumber));\r
Boolean ParseFEN P((Board board, int *blackPlaysFirst, char *fen));\r
+void ChatPopUp P(());\r
typedef struct {\r
ChessSquare piece; \r
POINT pos; /* window coordinates of current pos */\r
if(msg.hwnd == e2) currentElement = 3; else\r
if(msg.hwnd == moveHistoryDialog) currentElement = 4; else\r
if(msg.hwnd == mh) currentElement = 4; else\r
- if(msg.hwnd == evalGraphDialog) currentElement = 7; else\r
+ if(msg.hwnd == evalGraphDialog) currentElement = 6; else\r
if(msg.hwnd == hText) currentElement = 5; else\r
if(msg.hwnd == hInput) currentElement = 6; else\r
for (i = 0; i < N_BUTTONS; i++) {\r
case 4:\r
if(!MoveHistoryIsUp()) continue;\r
h = mh; break;\r
-// case 5: // input to eval graph does not seem to get here!\r
+// case 6: // input to eval graph does not seem to get here!\r
// if(!EvalGraphIsUp()) continue;\r
// h = evalGraphDialog; break;\r
case 5:\r
!(!frozen && TranslateAccelerator(hwndMain, hAccelMain, &msg)) && JAWS_ACCEL\r
!(!hwndConsole && TranslateAccelerator(hwndMain, hAccelNoICS, &msg)) &&\r
!(!hwndConsole && TranslateAccelerator(hwndMain, hAccelNoAlt, &msg))) {\r
+ int done = 0, i; // [HGM] chat: dispatch cat-box messages\r
+ for(i=0; i<MAX_CHAT; i++) \r
+ if(chatHandle[i] && IsDialogMessage(chatHandle[i], &msg)) {\r
+ done = 1; break;\r
+ }\r
+ if(done) continue; // [HGM] chat: end patch\r
TranslateMessage(&msg); /* Translates virtual key codes */\r
DispatchMessage(&msg); /* Dispatches message to window */\r
}\r
{ "secondOptions", ArgString, (LPVOID) &appData.secondOptions, FALSE },\r
{ "firstNeedsNoncompliantFEN", ArgString, (LPVOID) &appData.fenOverride1, FALSE },\r
{ "secondNeedsNoncompliantFEN", ArgString, (LPVOID) &appData.fenOverride2, FALSE },\r
+ { "keepAlive", ArgInt, (LPVOID) &appData.keepAlive, FALSE },\r
+ { "icstype", ArgInt, (LPVOID) &ics_type, FALSE },\r
\r
#ifdef ZIPPY\r
{ "zippyTalk", ArgBoolean, (LPVOID) &appData.zippyTalk, FALSE },\r
If promotion to Q is legal, all are legal! */\r
if(gameInfo.variant == VariantSuper || gameInfo.variant == VariantGreat)\r
{ ChessSquare p = boards[currentMove][fromY][fromX], q = boards[currentMove][toY][toX];\r
- // kludge to temporarily execute move on display, without promotng yet\r
+ // kludge to temporarily execute move on display, without promoting yet\r
promotionChoice = TRUE;\r
boards[currentMove][fromY][fromX] = EmptySquare; // move Pawn to 8th rank\r
boards[currentMove][toY][toX] = p;\r
GameListOptions();\r
break;\r
\r
+ case IDM_NewChat:\r
+ ChatPopUp();\r
+ break;\r
+\r
case IDM_CopyPosition:\r
CopyFENToClipboard();\r
break;\r
ScheduleDelayedEvent(DelayedEventCallback cb, long millisec)\r
{\r
if (delayedTimerEvent != 0) {\r
- if (appData.debugMode) {\r
+ if (appData.debugMode && cb != delayedTimerCallback) { // [HGM] alive: not too much debug\r
fprintf(debugFP, "ScheduleDelayedEvent: event already scheduled\n");\r
}\r
KillTimer(hwndMain, delayedTimerEvent);\r
ICON IDI_TRANS_14,IDC_StateIcon2,164,84,20,20\r
END\r
\r
+DLG_Chat DIALOGEX 0, 0, 256, 106\r
+STYLE WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME\r
+EXSTYLE WS_EX_TOOLWINDOW\r
+CAPTION "Chat Window"\r
+FONT 8, "MS Sans Serif"\r
+BEGIN\r
+ LTEXT "Chat partner:",IDC_STATIC,5,5,45,10\r
+ EDITTEXT IDC_ChatPartner,50,3,100,13,ES_AUTOHSCROLL\r
+ PUSHBUTTON "Change",IDC_Change,155,3,35,13\r
+ PUSHBUTTON "Clear",IDC_Clear,198,3,25,13\r
+ DEFPUSHBUTTON "Send",IDC_Send,228,3,25,13\r
+ CONTROL "",IDC_ChatMemo,"RICHEDIT",ES_MULTILINE | ES_READONLY |\r
+ ES_AUTOVSCROLL | ES_AUTOHSCROLL | WS_BORDER | WS_VSCROLL | \r
+ WS_HSCROLL | WS_TABSTOP,3,17,250,70\r
+ CONTROL "",OPT_ChatInput,"RICHEDIT",ES_AUTOHSCROLL | ES_NOHIDESEL | \r
+ WS_BORDER | WS_TABSTOP,3,90,250,13\r
+END\r
+\r
DLG_EnginePlayOptions DIALOG DISCARDABLE 0, 0, 208, 202\r
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU\r
CAPTION "Adjudications"\r
MENUITEM "Show Evaluation Graph\tAlt+Shift+E",IDM_ShowEvalGraph\r
MENUITEM "Show Game &List\tAlt+Shift+G", IDM_ShowGameList\r
MENUITEM "Show Move History\tAlt+Shift+H", IDM_ShowMoveHistory\r
+ MENUITEM "Open Chat Window", IDM_NewChat\r
MENUITEM SEPARATOR\r
MENUITEM "Edit &Tags...", IDM_EditTags\r
MENUITEM "Edit &Comment...", IDM_EditComment\r
break;\r
case Button:\r
case SaveButton:\r
+ case ResetButton:\r
fprintf(debugFP, "[ %26.26s ]", opt.name);\r
case Message:\r
break;\r
switch(nextType = optionList[nextOption].type) {\r
case CheckBox: checkList[checks++] = nextOption; lastType = CheckBox; break;\r
case ComboBox: comboList[combos++] = nextOption; lastType = ComboBox; break;\r
+ case ResetButton:\r
case SaveButton:\r
case Button: buttonList[buttons++] = nextOption; lastType = Button; break;\r
case TextBox:\r
AddControl(x+95, y-1, 50, 500, 0x0085, CBS_AUTOHSCROLL | CBS_DROPDOWN | WS_VISIBLE | WS_CHILD | WS_TABSTOP, i+1);\r
break;\r
case Button:\r
+ case ResetButton:\r
case SaveButton:\r
AddControl(x-2, y, 65, 13, 0x0080, BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD, i);\r
case Message:\r