summaryrefslogtreecommitdiff
path: root/apps/plugins/puzzles/src/windows.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/puzzles/src/windows.c')
-rw-r--r--apps/plugins/puzzles/src/windows.c807
1 files changed, 222 insertions, 585 deletions
diff --git a/apps/plugins/puzzles/src/windows.c b/apps/plugins/puzzles/src/windows.c
index 38559c5454..5273e17842 100644
--- a/apps/plugins/puzzles/src/windows.c
+++ b/apps/plugins/puzzles/src/windows.c
@@ -7,11 +7,7 @@
7#ifndef NO_HTMLHELP 7#ifndef NO_HTMLHELP
8#include <htmlhelp.h> 8#include <htmlhelp.h>
9#endif /* NO_HTMLHELP */ 9#endif /* NO_HTMLHELP */
10 10#include <io.h>
11#ifdef _WIN32_WCE
12#include <commdlg.h>
13#include <aygshell.h>
14#endif
15 11
16#include <stdio.h> 12#include <stdio.h>
17#include <assert.h> 13#include <assert.h>
@@ -23,10 +19,6 @@
23 19
24#include "puzzles.h" 20#include "puzzles.h"
25 21
26#ifdef _WIN32_WCE
27#include "resource.h"
28#endif
29
30#define IDM_NEW 0x0010 22#define IDM_NEW 0x0010
31#define IDM_RESTART 0x0020 23#define IDM_RESTART 0x0020
32#define IDM_UNDO 0x0030 24#define IDM_UNDO 0x0030
@@ -43,10 +35,14 @@
43#define IDM_SAVE 0x00E0 35#define IDM_SAVE 0x00E0
44#define IDM_LOAD 0x00F0 36#define IDM_LOAD 0x00F0
45#define IDM_PRINT 0x0100 37#define IDM_PRINT 0x0100
46#define IDM_PRESETS 0x0110 38#define IDM_PREFS 0x0110
47#define IDM_GAMES 0x0300
48 39
49#define IDM_KEYEMUL 0x0400 40/* Menu items for preset game_params go up from IDM_PRESET_BASE in
41 * steps of MENUITEM_STEP = 0x20. Menu items for selecting different
42 * games (in -DCOMBINED mode) go up from IDM_GAME_BASE similarly. */
43#define IDM_PRESET_BASE 0x0120
44#define IDM_GAME_BASE 0x0130
45#define MENUITEM_STEP 0x0020
50 46
51#define HELP_FILE_NAME "puzzles.hlp" 47#define HELP_FILE_NAME "puzzles.hlp"
52#define HELP_CNT_NAME "puzzles.cnt" 48#define HELP_CNT_NAME "puzzles.cnt"
@@ -77,56 +73,12 @@ bool help_has_contents;
77#define CLASSNAME thegame.name 73#define CLASSNAME thegame.name
78#endif 74#endif
79 75
80#ifdef _WIN32_WCE
81
82/*
83 * Wrapper implementations of functions not supplied by the
84 * PocketPC API.
85 */
86
87#define SHGetSubMenu(hWndMB,ID_MENU) (HMENU)SendMessage((hWndMB), SHCMBM_GETSUBMENU, (WPARAM)0, (LPARAM)ID_MENU)
88
89#undef MessageBox
90
91int MessageBox(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType)
92{
93 TCHAR wText[2048];
94 TCHAR wCaption[2048];
95
96 MultiByteToWideChar (CP_ACP, 0, lpText, -1, wText, 2048);
97 MultiByteToWideChar (CP_ACP, 0, lpCaption, -1, wCaption, 2048);
98
99 return MessageBoxW (hWnd, wText, wCaption, uType);
100}
101
102BOOL SetDlgItemTextA(HWND hDlg, int nIDDlgItem, LPCSTR lpString)
103{
104 TCHAR wText[256];
105
106 MultiByteToWideChar (CP_ACP, 0, lpString, -1, wText, 256);
107 return SetDlgItemTextW(hDlg, nIDDlgItem, wText);
108}
109
110LPCSTR getenv(LPCSTR buf)
111{
112 return NULL;
113}
114
115BOOL GetKeyboardState(PBYTE pb)
116{
117 return false;
118}
119
120static TCHAR wClassName[256], wGameName[256];
121
122#endif
123
124#ifdef DEBUGGING 76#ifdef DEBUGGING
125static FILE *debug_fp = NULL; 77static FILE *debug_fp = NULL;
126static HANDLE debug_hdl = INVALID_HANDLE_VALUE; 78static HANDLE debug_hdl = INVALID_HANDLE_VALUE;
127static int debug_got_console = 0; 79static int debug_got_console = 0;
128 80
129void dputs(char *buf) 81static void dputs(char *buf)
130{ 82{
131 /*DWORD dw; 83 /*DWORD dw;
132 84
@@ -144,8 +96,8 @@ void dputs(char *buf)
144 WriteFile(debug_hdl, buf, strlen(buf), &dw, NULL); 96 WriteFile(debug_hdl, buf, strlen(buf), &dw, NULL);
145 } 97 }
146 if (debug_fp) { 98 if (debug_fp) {
147 fputs(buf, debug_fp); 99 fputs(buf, debug_fp);
148 fflush(debug_fp); 100 fflush(debug_fp);
149 }*/ 101 }*/
150 OutputDebugString(buf); 102 OutputDebugString(buf);
151} 103}
@@ -157,7 +109,7 @@ void debug_printf(const char *fmt, ...)
157 static int debugging = -1; 109 static int debugging = -1;
158 110
159 if (debugging == -1) 111 if (debugging == -1)
160 debugging = getenv("DEBUG_PUZZLES") ? 1 : 0; 112 debugging = getenv_bool("DEBUG_PUZZLES", false);
161 113
162 if (debugging) { 114 if (debugging) {
163 va_start(ap, fmt); 115 va_start(ap, fmt);
@@ -168,14 +120,12 @@ void debug_printf(const char *fmt, ...)
168} 120}
169#endif 121#endif
170 122
171#ifndef _WIN32_WCE
172#define WINFLAGS (WS_OVERLAPPEDWINDOW &~ \ 123#define WINFLAGS (WS_OVERLAPPEDWINDOW &~ \
173 (WS_MAXIMIZEBOX | WS_OVERLAPPED)) 124 (WS_MAXIMIZEBOX | WS_OVERLAPPED))
174#else
175#define WINFLAGS (WS_CAPTION | WS_SYSMENU)
176#endif
177 125
178static void new_game_size(frontend *fe, float scale); 126static void new_game_size(frontend *fe, float scale);
127static void load_prefs(midend *me);
128static char *save_prefs(midend *me);
179 129
180struct font { 130struct font {
181 HFONT font; 131 HFONT font;
@@ -204,9 +154,6 @@ struct frontend {
204 const game *game; 154 const game *game;
205 midend *me; 155 midend *me;
206 HWND hwnd, statusbar, cfgbox; 156 HWND hwnd, statusbar, cfgbox;
207#ifdef _WIN32_WCE
208 HWND numpad; /* window handle for the numeric pad */
209#endif
210 HINSTANCE inst; 157 HINSTANCE inst;
211 HBITMAP bitmap, prevbm; 158 HBITMAP bitmap, prevbm;
212 RECT bitmapPosition; /* game bitmap position within game window */ 159 RECT bitmapPosition; /* game bitmap position within game window */
@@ -308,19 +255,9 @@ void get_random_seed(void **randseed, int *randseedsize)
308 255
309static void win_status_bar(void *handle, const char *text) 256static void win_status_bar(void *handle, const char *text)
310{ 257{
311#ifdef _WIN32_WCE
312 TCHAR wText[255];
313#endif
314 frontend *fe = (frontend *)handle; 258 frontend *fe = (frontend *)handle;
315 259
316#ifdef _WIN32_WCE
317 MultiByteToWideChar (CP_ACP, 0, text, -1, wText, 255);
318 SendMessage(fe->statusbar, SB_SETTEXT,
319 (WPARAM) 255 | SBT_NOBORDERS,
320 (LPARAM) wText);
321#else
322 SetWindowText(fe->statusbar, text); 260 SetWindowText(fe->statusbar, text);
323#endif
324} 261}
325 262
326static blitter *win_blitter_new(void *handle, int w, int h) 263static blitter *win_blitter_new(void *handle, int w, int h)
@@ -464,13 +401,6 @@ static void win_set_brush(frontend *fe, int colour)
464 if (hatch < 0) { 401 if (hatch < 0) {
465 br = CreateSolidBrush(RGB(r * 255, g * 255, b * 255)); 402 br = CreateSolidBrush(RGB(r * 255, g * 255, b * 255));
466 } else { 403 } else {
467#ifdef _WIN32_WCE
468 /*
469 * This is only ever required during printing, and the
470 * PocketPC port doesn't support printing.
471 */
472 fatal("CreateHatchBrush not supported");
473#else
474 br = CreateHatchBrush(hatch == HATCH_BACKSLASH ? HS_FDIAGONAL : 404 br = CreateHatchBrush(hatch == HATCH_BACKSLASH ? HS_FDIAGONAL :
475 hatch == HATCH_SLASH ? HS_BDIAGONAL : 405 hatch == HATCH_SLASH ? HS_BDIAGONAL :
476 hatch == HATCH_HORIZ ? HS_HORIZONTAL : 406 hatch == HATCH_HORIZ ? HS_HORIZONTAL :
@@ -478,7 +408,6 @@ static void win_set_brush(frontend *fe, int colour)
478 hatch == HATCH_PLUS ? HS_CROSS : 408 hatch == HATCH_PLUS ? HS_CROSS :
479 /* hatch == HATCH_X ? */ HS_DIAGCROSS, 409 /* hatch == HATCH_X ? */ HS_DIAGCROSS,
480 RGB(0,0,0)); 410 RGB(0,0,0));
481#endif
482 } 411 }
483 } else { 412 } else {
484 br = fe->brushes[colour]; 413 br = fe->brushes[colour];
@@ -602,9 +531,6 @@ static void win_draw_text(void *handle, int x, int y, int fonttype,
602 lf.lfPitchAndFamily = (fonttype == FONT_FIXED ? 531 lf.lfPitchAndFamily = (fonttype == FONT_FIXED ?
603 FIXED_PITCH | FF_DONTCARE : 532 FIXED_PITCH | FF_DONTCARE :
604 VARIABLE_PITCH | FF_SWISS); 533 VARIABLE_PITCH | FF_SWISS);
605#ifdef _WIN32_WCE
606 wcscpy(lf.lfFaceName, TEXT("Tahoma"));
607#endif
608 534
609 fe->fonts[i].font = CreateFontIndirect(&lf); 535 fe->fonts[i].font = CreateFontIndirect(&lf);
610 } 536 }
@@ -708,7 +634,7 @@ static void win_draw_circle(void *handle, int cx, int cy, int radius,
708 win_reset_pen(fe); 634 win_reset_pen(fe);
709} 635}
710 636
711static void win_draw_polygon(void *handle, int *coords, int npoints, 637static void win_draw_polygon(void *handle, const int *coords, int npoints,
712 int fillcolour, int outlinecolour) 638 int fillcolour, int outlinecolour)
713{ 639{
714 frontend *fe = (frontend *)handle; 640 frontend *fe = (frontend *)handle;
@@ -754,9 +680,7 @@ static void win_start_draw(void *handle)
754 fe->prevbm = SelectObject(fe->hdc, fe->bitmap); 680 fe->prevbm = SelectObject(fe->hdc, fe->bitmap);
755 ReleaseDC(fe->hwnd, hdc_win); 681 ReleaseDC(fe->hwnd, hdc_win);
756 fe->clip = NULL; 682 fe->clip = NULL;
757#ifndef _WIN32_WCE
758 SetMapMode(fe->hdc, MM_TEXT); 683 SetMapMode(fe->hdc, MM_TEXT);
759#endif
760 fe->drawstatus = DRAWING; 684 fe->drawstatus = DRAWING;
761} 685}
762 686
@@ -999,7 +923,6 @@ const struct drawing_api win_drawing = {
999 923
1000void print(frontend *fe) 924void print(frontend *fe)
1001{ 925{
1002#ifndef _WIN32_WCE
1003 PRINTDLG pd; 926 PRINTDLG pd;
1004 char doctitle[256]; 927 char doctitle[256];
1005 document *doc; 928 document *doc;
@@ -1019,6 +942,7 @@ void print(frontend *fe)
1019 game_params *params; 942 game_params *params;
1020 943
1021 nme = midend_new(NULL, fe->game, NULL, NULL); 944 nme = midend_new(NULL, fe->game, NULL, NULL);
945 load_prefs(nme);
1022 946
1023 /* 947 /*
1024 * Set the non-interactive mid-end to have the same 948 * Set the non-interactive mid-end to have the same
@@ -1090,7 +1014,6 @@ void print(frontend *fe)
1090 1014
1091 DeleteDC(pd.hDC); 1015 DeleteDC(pd.hDC);
1092 document_free(doc); 1016 document_free(doc);
1093#endif
1094} 1017}
1095 1018
1096void deactivate_timer(frontend *fe) 1019void deactivate_timer(frontend *fe)
@@ -1168,7 +1091,6 @@ void write_clip(HWND hwnd, char *data)
1168 */ 1091 */
1169static void init_help(void) 1092static void init_help(void)
1170{ 1093{
1171#ifndef _WIN32_WCE
1172 char b[2048], *p, *q, *r; 1094 char b[2048], *p, *q, *r;
1173 FILE *fp; 1095 FILE *fp;
1174 1096
@@ -1232,11 +1154,8 @@ static void init_help(void)
1232 } 1154 }
1233 1155
1234 help_type = NONE; /* didn't find any */ 1156 help_type = NONE; /* didn't find any */
1235#endif
1236} 1157}
1237 1158
1238#ifndef _WIN32_WCE
1239
1240/* 1159/*
1241 * Start Help. 1160 * Start Help.
1242 */ 1161 */
@@ -1257,7 +1176,7 @@ static void start_help(frontend *fe, const char *topic)
1257 } else { 1176 } else {
1258 cmd = HELP_CONTENTS; 1177 cmd = HELP_CONTENTS;
1259 } 1178 }
1260 WinHelp(fe->hwnd, help_path, cmd, (DWORD)str); 1179 WinHelp(fe->hwnd, help_path, cmd, (ULONG_PTR)str);
1261 fe->help_running = true; 1180 fe->help_running = true;
1262 break; 1181 break;
1263 case CHM: 1182 case CHM:
@@ -1306,8 +1225,6 @@ static void stop_help(frontend *fe)
1306 } 1225 }
1307} 1226}
1308 1227
1309#endif
1310
1311/* 1228/*
1312 * Terminate Help on process exit. 1229 * Terminate Help on process exit.
1313 */ 1230 */
@@ -1338,10 +1255,8 @@ static void adjust_statusbar(frontend *fe, RECT *r)
1338 if (!fe->statusbar) return; 1255 if (!fe->statusbar) return;
1339 1256
1340 sy = get_statusbar_height(fe); 1257 sy = get_statusbar_height(fe);
1341#ifndef _WIN32_WCE
1342 SetWindowPos(fe->statusbar, NULL, 0, r->bottom-r->top-sy, r->right-r->left, 1258 SetWindowPos(fe->statusbar, NULL, 0, r->bottom-r->top-sy, r->right-r->left,
1343 sy, SWP_NOZORDER); 1259 sy, SWP_NOZORDER);
1344#endif
1345} 1260}
1346 1261
1347static void get_menu_size(HWND wh, RECT *r) 1262static void get_menu_size(HWND wh, RECT *r)
@@ -1378,7 +1293,7 @@ static bool check_window_resize(frontend *fe, int cx, int cy,
1378 * See if we actually got the window size we wanted, and adjust 1293 * See if we actually got the window size we wanted, and adjust
1379 * the puzzle size if not. 1294 * the puzzle size if not.
1380 */ 1295 */
1381 midend_size(fe->me, &x, &y, true); 1296 midend_size(fe->me, &x, &y, true, 1.0);
1382 if (x != cx || y != cy) { 1297 if (x != cx || y != cy) {
1383 /* 1298 /*
1384 * Resize the window, now we know what size we _really_ 1299 * Resize the window, now we know what size we _really_
@@ -1416,13 +1331,8 @@ static void check_window_size(frontend *fe, int *px, int *py)
1416 cx = r.right - r.left; 1331 cx = r.right - r.left;
1417 cy = r.bottom - r.top; 1332 cy = r.bottom - r.top;
1418 1333
1419 if (check_window_resize(fe, cx, cy, px, py, &wx, &wy)) { 1334 if (check_window_resize(fe, cx, cy, px, py, &wx, &wy))
1420#ifdef _WIN32_WCE 1335 SetWindowPos(fe->hwnd, NULL, 0, 0, wx, wy, SWP_NOMOVE | SWP_NOZORDER);
1421 SetWindowPos(fe->hwnd, NULL, 0, 0, wx, wy,
1422 SWP_NOMOVE | SWP_NOZORDER);
1423#endif
1424 ;
1425 }
1426 1336
1427 GetClientRect(fe->hwnd, &r); 1337 GetClientRect(fe->hwnd, &r);
1428 adjust_statusbar(fe, &r); 1338 adjust_statusbar(fe, &r);
@@ -1452,23 +1362,6 @@ static void get_max_puzzle_size(frontend *fe, int *x, int *y)
1452 } 1362 }
1453} 1363}
1454 1364
1455#ifdef _WIN32_WCE
1456/* Toolbar buttons on the numeric pad */
1457static TBBUTTON tbNumpadButtons[] =
1458{
1459 {0, IDM_KEYEMUL + '1', TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, -1},
1460 {1, IDM_KEYEMUL + '2', TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, -1},
1461 {2, IDM_KEYEMUL + '3', TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, -1},
1462 {3, IDM_KEYEMUL + '4', TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, -1},
1463 {4, IDM_KEYEMUL + '5', TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, -1},
1464 {5, IDM_KEYEMUL + '6', TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, -1},
1465 {6, IDM_KEYEMUL + '7', TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, -1},
1466 {7, IDM_KEYEMUL + '8', TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, -1},
1467 {8, IDM_KEYEMUL + '9', TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, -1},
1468 {9, IDM_KEYEMUL + ' ', TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, -1}
1469};
1470#endif
1471
1472/* 1365/*
1473 * Allocate a new frontend structure and create its main window. 1366 * Allocate a new frontend structure and create its main window.
1474 */ 1367 */
@@ -1502,34 +1395,6 @@ static frontend *frontend_new(HINSTANCE inst)
1502 1395
1503 fe->puzz_scale = 1.0; 1396 fe->puzz_scale = 1.0;
1504 1397
1505 #ifdef _WIN32_WCE
1506 MultiByteToWideChar (CP_ACP, 0, nogame, -1, wGameName, 256);
1507 fe->hwnd = CreateWindowEx(0, wClassName, wGameName,
1508 WS_VISIBLE,
1509 CW_USEDEFAULT, CW_USEDEFAULT,
1510 CW_USEDEFAULT, CW_USEDEFAULT,
1511 NULL, NULL, inst, NULL);
1512
1513 {
1514 SHMENUBARINFO mbi;
1515 RECT rc, rcBar, rcTB, rcClient;
1516
1517 memset (&mbi, 0, sizeof(SHMENUBARINFO));
1518 mbi.cbSize = sizeof(SHMENUBARINFO);
1519 mbi.hwndParent = fe->hwnd;
1520 mbi.nToolBarId = IDR_MENUBAR1;
1521 mbi.hInstRes = inst;
1522
1523 SHCreateMenuBar(&mbi);
1524
1525 GetWindowRect(fe->hwnd, &rc);
1526 GetWindowRect(mbi.hwndMB, &rcBar);
1527 rc.bottom -= rcBar.bottom - rcBar.top;
1528 MoveWindow(fe->hwnd, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, false);
1529
1530 fe->numpad = NULL;
1531 }
1532#else
1533 fe->hwnd = CreateWindowEx(0, CLASSNAME, nogame, 1398 fe->hwnd = CreateWindowEx(0, CLASSNAME, nogame,
1534 WS_OVERLAPPEDWINDOW &~ 1399 WS_OVERLAPPEDWINDOW &~
1535 (WS_MAXIMIZEBOX), 1400 (WS_MAXIMIZEBOX),
@@ -1540,7 +1405,6 @@ static frontend *frontend_new(HINSTANCE inst)
1540 DWORD lerr = GetLastError(); 1405 DWORD lerr = GetLastError();
1541 printf("no window: 0x%x\n", (unsigned)lerr); 1406 printf("no window: 0x%x\n", (unsigned)lerr);
1542 } 1407 }
1543#endif
1544 1408
1545 fe->gamemenu = NULL; 1409 fe->gamemenu = NULL;
1546 fe->preset_menu = NULL; 1410 fe->preset_menu = NULL;
@@ -1586,6 +1450,7 @@ static midend *midend_for_new_game(frontend *fe, const game *cgame,
1586 if (!arg) { 1450 if (!arg) {
1587 if (me) midend_free(me); 1451 if (me) midend_free(me);
1588 me = midend_new(fe, cgame, &win_drawing, fe); 1452 me = midend_new(fe, cgame, &win_drawing, fe);
1453 load_prefs(me);
1589 midend_new_game(me); 1454 midend_new_game(me);
1590 } else { 1455 } else {
1591 FILE *fp; 1456 FILE *fp;
@@ -1626,6 +1491,7 @@ static midend *midend_for_new_game(frontend *fe, const game *cgame,
1626 if (!err_load) { 1491 if (!err_load) {
1627 if (me) midend_free(me); 1492 if (me) midend_free(me);
1628 me = midend_new(fe, loadgame, &win_drawing, fe); 1493 me = midend_new(fe, loadgame, &win_drawing, fe);
1494 load_prefs(me);
1629 err_load = midend_deserialise(me, savefile_read, fp); 1495 err_load = midend_deserialise(me, savefile_read, fp);
1630 } 1496 }
1631 } else { 1497 } else {
@@ -1638,6 +1504,7 @@ static midend *midend_for_new_game(frontend *fe, const game *cgame,
1638 */ 1504 */
1639 if (me) midend_free(me); 1505 if (me) midend_free(me);
1640 me = midend_new(fe, cgame, &win_drawing, fe); 1506 me = midend_new(fe, cgame, &win_drawing, fe);
1507 load_prefs(me);
1641 err_param = midend_game_id(me, arg); 1508 err_param = midend_game_id(me, arg);
1642 if (!err_param) { 1509 if (!err_param) {
1643 midend_new_game(me); 1510 midend_new_game(me);
@@ -1676,7 +1543,8 @@ static void populate_preset_menu(frontend *fe,
1676 UINT flags = MF_ENABLED; 1543 UINT flags = MF_ENABLED;
1677 1544
1678 if (entry->params) { 1545 if (entry->params) {
1679 id_or_sub = (UINT_PTR)(IDM_PRESETS + 0x10 * entry->id); 1546 id_or_sub = (UINT_PTR)(
1547 IDM_PRESET_BASE + MENUITEM_STEP * entry->id);
1680 1548
1681 fe->preset_menuitems[entry->id].which_menu = winmenu; 1549 fe->preset_menuitems[entry->id].which_menu = winmenu;
1682 fe->preset_menuitems[entry->id].item_index = 1550 fe->preset_menuitems[entry->id].item_index =
@@ -1694,15 +1562,7 @@ static void populate_preset_menu(frontend *fe,
1694 * here. 1562 * here.
1695 */ 1563 */
1696 1564
1697#ifndef _WIN32_WCE
1698 AppendMenu(winmenu, flags, id_or_sub, entry->title); 1565 AppendMenu(winmenu, flags, id_or_sub, entry->title);
1699#else
1700 {
1701 TCHAR wName[255];
1702 MultiByteToWideChar(CP_ACP, 0, entry->title, -1, wName, 255);
1703 AppendMenu(winmenu, flags, id_or_sub, wName);
1704 }
1705#endif
1706 } 1566 }
1707} 1567}
1708 1568
@@ -1763,41 +1623,14 @@ static int fe_set_midend(frontend *fe, midend *me)
1763 fe->statusbar = NULL; 1623 fe->statusbar = NULL;
1764 1624
1765 get_max_puzzle_size(fe, &x, &y); 1625 get_max_puzzle_size(fe, &x, &y);
1766 midend_size(fe->me, &x, &y, false); 1626 midend_size(fe->me, &x, &y, false, 1.0);
1767 1627
1768 r.left = r.top = 0; 1628 r.left = r.top = 0;
1769 r.right = x; 1629 r.right = x;
1770 r.bottom = y; 1630 r.bottom = y;
1771 AdjustWindowRectEx(&r, WINFLAGS, true, 0); 1631 AdjustWindowRectEx(&r, WINFLAGS, true, 0);
1772 1632
1773#ifdef _WIN32_WCE
1774 if (fe->numpad)
1775 DestroyWindow(fe->numpad);
1776 if (fe->game->flags & REQUIRE_NUMPAD)
1777 {
1778 fe->numpad = CreateToolbarEx (fe->hwnd,
1779 WS_VISIBLE | WS_CHILD | CCS_NOPARENTALIGN | TBSTYLE_FLAT,
1780 0, 10, fe->inst, IDR_PADTOOLBAR,
1781 tbNumpadButtons, sizeof (tbNumpadButtons) / sizeof (TBBUTTON),
1782 0, 0, 14, 15, sizeof (TBBUTTON));
1783 GetWindowRect(fe->numpad, &rcTB);
1784 GetClientRect(fe->hwnd, &rcClient);
1785 MoveWindow(fe->numpad,
1786 0,
1787 rcClient.bottom - (rcTB.bottom - rcTB.top) - 1,
1788 rcClient.right,
1789 rcTB.bottom - rcTB.top,
1790 false);
1791 SendMessage(fe->numpad, TB_SETINDENT, (rcClient.right - (10 * 21)) / 2, 0);
1792 }
1793 else {
1794 fe->numpad = NULL;
1795 }
1796 MultiByteToWideChar (CP_ACP, 0, fe->game->name, -1, wGameName, 256);
1797 SetWindowText(fe->hwnd, wGameName);
1798#else
1799 SetWindowText(fe->hwnd, fe->game->name); 1633 SetWindowText(fe->hwnd, fe->game->name);
1800#endif
1801 1634
1802 if (fe->statusbar) 1635 if (fe->statusbar)
1803 DestroyWindow(fe->statusbar); 1636 DestroyWindow(fe->statusbar);
@@ -1807,24 +1640,15 @@ static int fe_set_midend(frontend *fe, midend *me)
1807 WS_CHILD | WS_VISIBLE, 1640 WS_CHILD | WS_VISIBLE,
1808 0, 0, 0, 0, /* status bar does these */ 1641 0, 0, 0, 0, /* status bar does these */
1809 fe->hwnd, NULL, fe->inst, NULL); 1642 fe->hwnd, NULL, fe->inst, NULL);
1810#ifdef _WIN32_WCE
1811 /* Flat status bar looks better on the Pocket PC */
1812 SendMessage(fe->statusbar, SB_SIMPLE, (WPARAM) true, 0);
1813 SendMessage(fe->statusbar, SB_SETTEXT,
1814 (WPARAM) 255 | SBT_NOBORDERS,
1815 (LPARAM) L"");
1816#endif
1817 1643
1818 /* 1644 /*
1819 * Now resize the window to take account of the status bar. 1645 * Now resize the window to take account of the status bar.
1820 */ 1646 */
1821 GetWindowRect(fe->statusbar, &sr); 1647 GetWindowRect(fe->statusbar, &sr);
1822 GetWindowRect(fe->hwnd, &r); 1648 GetWindowRect(fe->hwnd, &r);
1823#ifndef _WIN32_WCE
1824 SetWindowPos(fe->hwnd, NULL, 0, 0, r.right - r.left, 1649 SetWindowPos(fe->hwnd, NULL, 0, 0, r.right - r.left,
1825 r.bottom - r.top + sr.bottom - sr.top, 1650 r.bottom - r.top + sr.bottom - sr.top,
1826 SWP_NOMOVE | SWP_NOZORDER); 1651 SWP_NOMOVE | SWP_NOZORDER);
1827#endif
1828 } else { 1652 } else {
1829 fe->statusbar = NULL; 1653 fe->statusbar = NULL;
1830 } 1654 }
@@ -1832,24 +1656,17 @@ static int fe_set_midend(frontend *fe, midend *me)
1832 { 1656 {
1833 HMENU oldmenu = GetMenu(fe->hwnd); 1657 HMENU oldmenu = GetMenu(fe->hwnd);
1834 1658
1835#ifndef _WIN32_WCE
1836 HMENU bar = CreateMenu(); 1659 HMENU bar = CreateMenu();
1837 HMENU menu = CreateMenu(); 1660 HMENU menu = CreateMenu();
1838 RECT menusize; 1661 RECT menusize;
1839 1662
1840 AppendMenu(bar, MF_ENABLED|MF_POPUP, (UINT)menu, "&Game"); 1663 AppendMenu(bar, MF_ENABLED|MF_POPUP, (UINT_PTR)menu, "&Game");
1841#else
1842 HMENU menu = SHGetSubMenu(SHFindMenuBar(fe->hwnd), ID_GAME);
1843 DeleteMenu(menu, 0, MF_BYPOSITION);
1844#endif
1845 fe->gamemenu = menu; 1664 fe->gamemenu = menu;
1846 AppendMenu(menu, MF_ENABLED, IDM_NEW, TEXT("&New")); 1665 AppendMenu(menu, MF_ENABLED, IDM_NEW, TEXT("&New"));
1847 AppendMenu(menu, MF_ENABLED, IDM_RESTART, TEXT("&Restart")); 1666 AppendMenu(menu, MF_ENABLED, IDM_RESTART, TEXT("&Restart"));
1848#ifndef _WIN32_WCE
1849 /* ...here I run out of sensible accelerator characters. */ 1667 /* ...here I run out of sensible accelerator characters. */
1850 AppendMenu(menu, MF_ENABLED, IDM_DESC, TEXT("Speci&fic...")); 1668 AppendMenu(menu, MF_ENABLED, IDM_DESC, TEXT("Speci&fic..."));
1851 AppendMenu(menu, MF_ENABLED, IDM_SEED, TEXT("Rando&m Seed...")); 1669 AppendMenu(menu, MF_ENABLED, IDM_SEED, TEXT("Rando&m Seed..."));
1852#endif
1853 1670
1854 assert(!fe->preset_menu); 1671 assert(!fe->preset_menu);
1855 1672
@@ -1863,14 +1680,9 @@ static int fe_set_midend(frontend *fe, midend *me)
1863 fe->preset_menuitems[i].which_menu = NULL; 1680 fe->preset_menuitems[i].which_menu = NULL;
1864 } 1681 }
1865 if (fe->preset_menu->n_entries > 0 || fe->game->can_configure) { 1682 if (fe->preset_menu->n_entries > 0 || fe->game->can_configure) {
1866#ifndef _WIN32_WCE
1867 HMENU sub = CreateMenu(); 1683 HMENU sub = CreateMenu();
1868 1684
1869 AppendMenu(bar, MF_ENABLED|MF_POPUP, (UINT)sub, "&Type"); 1685 AppendMenu(bar, MF_ENABLED|MF_POPUP, (UINT_PTR)sub, "&Type");
1870#else
1871 HMENU sub = SHGetSubMenu(SHFindMenuBar(fe->hwnd), ID_TYPE);
1872 DeleteMenu(sub, 0, MF_BYPOSITION);
1873#endif
1874 1686
1875 populate_preset_menu(fe, fe->preset_menu, sub); 1687 populate_preset_menu(fe, fe->preset_menu, sub);
1876 1688
@@ -1884,27 +1696,25 @@ static int fe_set_midend(frontend *fe, midend *me)
1884 } 1696 }
1885 1697
1886#ifdef COMBINED 1698#ifdef COMBINED
1887#ifdef _WIN32_WCE
1888#error Windows CE does not support COMBINED build.
1889#endif
1890 { 1699 {
1891 HMENU games = CreateMenu(); 1700 HMENU games = CreateMenu();
1892 int i; 1701 int i;
1893 1702
1894 AppendMenu(menu, MF_SEPARATOR, 0, 0); 1703 AppendMenu(menu, MF_SEPARATOR, 0, 0);
1895 AppendMenu(menu, MF_ENABLED|MF_POPUP, (UINT)games, "&Other"); 1704 AppendMenu(menu, MF_ENABLED|MF_POPUP, (UINT_PTR)games, "&Other");
1896 for (i = 0; i < gamecount; i++) { 1705 for (i = 0; i < gamecount; i++) {
1897 if (strcmp(gamelist[i]->name, fe->game->name) != 0) { 1706 if (strcmp(gamelist[i]->name, fe->game->name) != 0) {
1898 /* only include those games that aren't the same as the 1707 /* only include those games that aren't the same as the
1899 * game we're currently playing. */ 1708 * game we're currently playing. */
1900 AppendMenu(games, MF_ENABLED, IDM_GAMES + i, gamelist[i]->name); 1709 AppendMenu(games, MF_ENABLED,
1710 IDM_GAME_BASE + MENUITEM_STEP * i,
1711 gamelist[i]->name);
1901 } 1712 }
1902 } 1713 }
1903 } 1714 }
1904#endif 1715#endif
1905 1716
1906 AppendMenu(menu, MF_SEPARATOR, 0, 0); 1717 AppendMenu(menu, MF_SEPARATOR, 0, 0);
1907#ifndef _WIN32_WCE
1908 AppendMenu(menu, MF_ENABLED, IDM_LOAD, TEXT("&Load...")); 1718 AppendMenu(menu, MF_ENABLED, IDM_LOAD, TEXT("&Load..."));
1909 AppendMenu(menu, MF_ENABLED, IDM_SAVE, TEXT("&Save...")); 1719 AppendMenu(menu, MF_ENABLED, IDM_SAVE, TEXT("&Save..."));
1910 AppendMenu(menu, MF_SEPARATOR, 0, 0); 1720 AppendMenu(menu, MF_SEPARATOR, 0, 0);
@@ -1912,27 +1722,23 @@ static int fe_set_midend(frontend *fe, midend *me)
1912 AppendMenu(menu, MF_ENABLED, IDM_PRINT, TEXT("&Print...")); 1722 AppendMenu(menu, MF_ENABLED, IDM_PRINT, TEXT("&Print..."));
1913 AppendMenu(menu, MF_SEPARATOR, 0, 0); 1723 AppendMenu(menu, MF_SEPARATOR, 0, 0);
1914 } 1724 }
1915#endif
1916 AppendMenu(menu, MF_ENABLED, IDM_UNDO, TEXT("Undo")); 1725 AppendMenu(menu, MF_ENABLED, IDM_UNDO, TEXT("Undo"));
1917 AppendMenu(menu, MF_ENABLED, IDM_REDO, TEXT("Redo")); 1726 AppendMenu(menu, MF_ENABLED, IDM_REDO, TEXT("Redo"));
1918#ifndef _WIN32_WCE
1919 if (fe->game->can_format_as_text_ever) { 1727 if (fe->game->can_format_as_text_ever) {
1920 AppendMenu(menu, MF_SEPARATOR, 0, 0); 1728 AppendMenu(menu, MF_SEPARATOR, 0, 0);
1921 AppendMenu(menu, MF_ENABLED, IDM_COPY, TEXT("&Copy")); 1729 AppendMenu(menu, MF_ENABLED, IDM_COPY, TEXT("&Copy"));
1922 } 1730 }
1923#endif
1924 if (fe->game->can_solve) { 1731 if (fe->game->can_solve) {
1925 AppendMenu(menu, MF_SEPARATOR, 0, 0); 1732 AppendMenu(menu, MF_SEPARATOR, 0, 0);
1926 AppendMenu(menu, MF_ENABLED, IDM_SOLVE, TEXT("Sol&ve")); 1733 AppendMenu(menu, MF_ENABLED, IDM_SOLVE, TEXT("Sol&ve"));
1927 } 1734 }
1928 AppendMenu(menu, MF_SEPARATOR, 0, 0); 1735 AppendMenu(menu, MF_SEPARATOR, 0, 0);
1929#ifndef _WIN32_WCE 1736 AppendMenu(menu, MF_ENABLED, IDM_PREFS, TEXT("Pre&ferences"));
1737 AppendMenu(menu, MF_SEPARATOR, 0, 0);
1930 AppendMenu(menu, MF_ENABLED, IDM_QUIT, TEXT("E&xit")); 1738 AppendMenu(menu, MF_ENABLED, IDM_QUIT, TEXT("E&xit"));
1931 menu = CreateMenu(); 1739 menu = CreateMenu();
1932 AppendMenu(bar, MF_ENABLED|MF_POPUP, (UINT)menu, TEXT("&Help")); 1740 AppendMenu(bar, MF_ENABLED|MF_POPUP, (UINT_PTR)menu, TEXT("&Help"));
1933#endif
1934 AppendMenu(menu, MF_ENABLED, IDM_ABOUT, TEXT("&About")); 1741 AppendMenu(menu, MF_ENABLED, IDM_ABOUT, TEXT("&About"));
1935#ifndef _WIN32_WCE
1936 if (help_type != NONE) { 1742 if (help_type != NONE) {
1937 char *item; 1743 char *item;
1938 AppendMenu(menu, MF_SEPARATOR, 0, 0); 1744 AppendMenu(menu, MF_SEPARATOR, 0, 0);
@@ -1947,7 +1753,6 @@ static int fe_set_midend(frontend *fe, midend *me)
1947 SetMenu(fe->hwnd, bar); 1753 SetMenu(fe->hwnd, bar);
1948 get_menu_size(fe->hwnd, &menusize); 1754 get_menu_size(fe->hwnd, &menusize);
1949 fe->xmin = (menusize.right - menusize.left) + 25; 1755 fe->xmin = (menusize.right - menusize.left) + 25;
1950#endif
1951 } 1756 }
1952 1757
1953 if (fe->bitmap) DeleteObject(fe->bitmap); 1758 if (fe->bitmap) DeleteObject(fe->bitmap);
@@ -1968,36 +1773,6 @@ static void show_window(frontend *fe)
1968 midend_redraw(fe->me); 1773 midend_redraw(fe->me);
1969} 1774}
1970 1775
1971#ifdef _WIN32_WCE
1972static HFONT dialog_title_font()
1973{
1974 static HFONT hf = NULL;
1975 LOGFONT lf;
1976
1977 if (hf)
1978 return hf;
1979
1980 memset (&lf, 0, sizeof(LOGFONT));
1981 lf.lfHeight = -11; /* - ((8 * GetDeviceCaps(hdc, LOGPIXELSY)) / 72) */
1982 lf.lfWeight = FW_BOLD;
1983 wcscpy(lf.lfFaceName, TEXT("Tahoma"));
1984
1985 return hf = CreateFontIndirect(&lf);
1986}
1987
1988static void make_dialog_full_screen(HWND hwnd)
1989{
1990 SHINITDLGINFO shidi;
1991
1992 /* Make dialog full screen */
1993 shidi.dwMask = SHIDIM_FLAGS;
1994 shidi.dwFlags = SHIDIF_DONEBUTTON | SHIDIF_SIZEDLGFULLSCREEN |
1995 SHIDIF_EMPTYMENU;
1996 shidi.hDlg = hwnd;
1997 SHInitDialog(&shidi);
1998}
1999#endif
2000
2001static int CALLBACK AboutDlgProc(HWND hwnd, UINT msg, 1776static int CALLBACK AboutDlgProc(HWND hwnd, UINT msg,
2002 WPARAM wParam, LPARAM lParam) 1777 WPARAM wParam, LPARAM lParam)
2003{ 1778{
@@ -2005,39 +1780,15 @@ static int CALLBACK AboutDlgProc(HWND hwnd, UINT msg,
2005 1780
2006 switch (msg) { 1781 switch (msg) {
2007 case WM_INITDIALOG: 1782 case WM_INITDIALOG:
2008#ifdef _WIN32_WCE
2009 {
2010 char title[256];
2011
2012 make_dialog_full_screen(hwnd);
2013
2014 sprintf(title, "About %.250s", fe->game->name);
2015 SetDlgItemTextA(hwnd, IDC_ABOUT_CAPTION, title);
2016
2017 SendDlgItemMessage(hwnd, IDC_ABOUT_CAPTION, WM_SETFONT,
2018 (WPARAM) dialog_title_font(), 0);
2019
2020 SetDlgItemTextA(hwnd, IDC_ABOUT_GAME, fe->game->name);
2021 SetDlgItemTextA(hwnd, IDC_ABOUT_VERSION, ver);
2022 }
2023#endif
2024 return 1; 1783 return 1;
2025 1784
2026 case WM_COMMAND: 1785 case WM_COMMAND:
2027 if (LOWORD(wParam) == IDOK) 1786 if (LOWORD(wParam) == IDOK)
2028#ifdef _WIN32_WCE
2029 EndDialog(hwnd, 1);
2030#else
2031 fe->dlg_done = 1; 1787 fe->dlg_done = 1;
2032#endif
2033 return 0; 1788 return 0;
2034 1789
2035 case WM_CLOSE: 1790 case WM_CLOSE:
2036#ifdef _WIN32_WCE
2037 EndDialog(hwnd, 1);
2038#else
2039 fe->dlg_done = 1; 1791 fe->dlg_done = 1;
2040#endif
2041 return 0; 1792 return 0;
2042 } 1793 }
2043 1794
@@ -2137,119 +1888,6 @@ static const char *frontend_set_config(
2137 } 1888 }
2138} 1889}
2139 1890
2140#ifdef _WIN32_WCE
2141/* Separate version of mkctrl function for the Pocket PC. */
2142/* Control coordinates should be specified in dialog units. */
2143HWND mkctrl(frontend *fe, int x1, int x2, int y1, int y2,
2144 LPCTSTR wclass, int wstyle,
2145 int exstyle, const char *wtext, INT_PTR wid)
2146{
2147 RECT rc;
2148 TCHAR wwtext[256];
2149
2150 /* Convert dialog units into pixels */
2151 rc.left = x1; rc.right = x2;
2152 rc.top = y1; rc.bottom = y2;
2153 MapDialogRect(fe->cfgbox, &rc);
2154
2155 MultiByteToWideChar (CP_ACP, 0, wtext, -1, wwtext, 256);
2156
2157 return CreateWindowEx(exstyle, wclass, wwtext,
2158 wstyle | WS_CHILD | WS_VISIBLE,
2159 rc.left, rc.top,
2160 rc.right - rc.left, rc.bottom - rc.top,
2161 fe->cfgbox, (HMENU) wid, fe->inst, NULL);
2162}
2163
2164static void create_config_controls(frontend * fe)
2165{
2166 int id, nctrls;
2167 int col1l, col1r, col2l, col2r, y;
2168 config_item *i;
2169 struct cfg_aux *j;
2170 HWND ctl;
2171
2172 /* Control placement done in dialog units */
2173 col1l = 4; col1r = 96; /* Label column */
2174 col2l = 100; col2r = 154; /* Input column (edit boxes and combo boxes) */
2175
2176 /*
2177 * Count the controls so we can allocate cfgaux.
2178 */
2179 for (nctrls = 0, i = fe->cfg; i->type != C_END; i++)
2180 nctrls++;
2181 fe->cfgaux = snewn(nctrls, struct cfg_aux);
2182
2183 id = 1000;
2184 y = 22; /* Leave some room for the dialog title */
2185 for (i = fe->cfg, j = fe->cfgaux; i->type != C_END; i++, j++) {
2186 switch (i->type) {
2187 case C_STRING:
2188 /*
2189 * Edit box with a label beside it.
2190 */
2191 mkctrl(fe, col1l, col1r, y + 1, y + 11,
2192 TEXT("Static"), SS_LEFTNOWORDWRAP, 0, i->name, id++);
2193 mkctrl(fe, col2l, col2r, y, y + 12,
2194 TEXT("EDIT"), WS_BORDER | WS_TABSTOP | ES_AUTOHSCROLL,
2195 0, "", (j->ctlid = id++));
2196 SetDlgItemTextA(fe->cfgbox, j->ctlid, i->u.string.sval);
2197 break;
2198
2199 case C_BOOLEAN:
2200 /*
2201 * Simple checkbox.
2202 */
2203 mkctrl(fe, col1l, col2r, y + 1, y + 11, TEXT("BUTTON"),
2204 BS_NOTIFY | BS_AUTOCHECKBOX | WS_TABSTOP,
2205 0, i->name, (j->ctlid = id++));
2206 CheckDlgButton(fe->cfgbox, j->ctlid, (i->u.boolean.bval != 0));
2207 break;
2208
2209 case C_CHOICES:
2210 /*
2211 * Drop-down list with a label beside it.
2212 */
2213 mkctrl(fe, col1l, col1r, y + 1, y + 11,
2214 TEXT("STATIC"), SS_LEFTNOWORDWRAP, 0, i->name, id++);
2215 ctl = mkctrl(fe, col2l, col2r, y, y + 48,
2216 TEXT("COMBOBOX"), WS_BORDER | WS_TABSTOP |
2217 CBS_DROPDOWNLIST | CBS_HASSTRINGS,
2218 0, "", (j->ctlid = id++));
2219 {
2220 char c;
2221 const char *p, *q;
2222 char *str;
2223
2224 p = i->u.choices.choicenames;
2225 c = *p++;
2226 while (*p) {
2227 q = p;
2228 while (*q && *q != c) q++;
2229 str = snewn(q-p+1, char);
2230 strncpy(str, p, q-p);
2231 str[q-p] = '\0';
2232 {
2233 TCHAR ws[50];
2234 MultiByteToWideChar (CP_ACP, 0, str, -1, ws, 50);
2235 SendMessage(ctl, CB_ADDSTRING, 0, (LPARAM)ws);
2236 }
2237
2238 sfree(str);
2239 if (*q) q++;
2240 p = q;
2241 }
2242 }
2243 SendMessage(ctl, CB_SETCURSEL, i->u.choices.selected, 0);
2244 break;
2245 }
2246
2247 y += 15;
2248 }
2249
2250}
2251#endif
2252
2253static int CALLBACK ConfigDlgProc(HWND hwnd, UINT msg, 1891static int CALLBACK ConfigDlgProc(HWND hwnd, UINT msg,
2254 WPARAM wParam, LPARAM lParam) 1892 WPARAM wParam, LPARAM lParam)
2255{ 1893{
@@ -2259,25 +1897,6 @@ static int CALLBACK ConfigDlgProc(HWND hwnd, UINT msg,
2259 1897
2260 switch (msg) { 1898 switch (msg) {
2261 case WM_INITDIALOG: 1899 case WM_INITDIALOG:
2262#ifdef _WIN32_WCE
2263 {
2264 char *title;
2265
2266 fe = (frontend *) lParam;
2267 SetWindowLongPtr(hwnd, GWLP_USERDATA, lParam);
2268 fe->cfgbox = hwnd;
2269
2270 fe->cfg = frontend_get_config(fe, fe->cfg_which, &title);
2271
2272 make_dialog_full_screen(hwnd);
2273
2274 SetDlgItemTextA(hwnd, IDC_CONFIG_CAPTION, title);
2275 SendDlgItemMessage(hwnd, IDC_CONFIG_CAPTION, WM_SETFONT,
2276 (WPARAM) dialog_title_font(), 0);
2277
2278 create_config_controls(fe);
2279 }
2280#endif
2281 return 1; 1900 return 1;
2282 1901
2283 case WM_COMMAND: 1902 case WM_COMMAND:
@@ -2293,18 +1912,10 @@ static int CALLBACK ConfigDlgProc(HWND hwnd, UINT msg,
2293 MessageBox(hwnd, err, "Validation error", 1912 MessageBox(hwnd, err, "Validation error",
2294 MB_ICONERROR | MB_OK); 1913 MB_ICONERROR | MB_OK);
2295 } else { 1914 } else {
2296#ifdef _WIN32_WCE
2297 EndDialog(hwnd, 2);
2298#else
2299 fe->dlg_done = 2; 1915 fe->dlg_done = 2;
2300#endif
2301 } 1916 }
2302 } else { 1917 } else {
2303#ifdef _WIN32_WCE
2304 EndDialog(hwnd, 1);
2305#else
2306 fe->dlg_done = 1; 1918 fe->dlg_done = 1;
2307#endif
2308 } 1919 }
2309 return 0; 1920 return 0;
2310 } 1921 }
@@ -2321,13 +1932,7 @@ static int CALLBACK ConfigDlgProc(HWND hwnd, UINT msg,
2321 1932
2322 if (i->type == C_STRING && HIWORD(wParam) == EN_CHANGE) { 1933 if (i->type == C_STRING && HIWORD(wParam) == EN_CHANGE) {
2323 char buffer[4096]; 1934 char buffer[4096];
2324#ifdef _WIN32_WCE
2325 TCHAR wBuffer[4096];
2326 GetDlgItemText(fe->cfgbox, j->ctlid, wBuffer, 4096);
2327 WideCharToMultiByte(CP_ACP, 0, wBuffer, -1, buffer, 4096, NULL, NULL);
2328#else
2329 GetDlgItemText(fe->cfgbox, j->ctlid, buffer, lenof(buffer)); 1935 GetDlgItemText(fe->cfgbox, j->ctlid, buffer, lenof(buffer));
2330#endif
2331 buffer[lenof(buffer)-1] = '\0'; 1936 buffer[lenof(buffer)-1] = '\0';
2332 sfree(i->u.string.sval); 1937 sfree(i->u.string.sval);
2333 i->u.string.sval = dupstr(buffer); 1938 i->u.string.sval = dupstr(buffer);
@@ -2351,7 +1956,6 @@ static int CALLBACK ConfigDlgProc(HWND hwnd, UINT msg,
2351 return 0; 1956 return 0;
2352} 1957}
2353 1958
2354#ifndef _WIN32_WCE
2355HWND mkctrl(frontend *fe, int x1, int x2, int y1, int y2, 1959HWND mkctrl(frontend *fe, int x1, int x2, int y1, int y2,
2356 char *wclass, int wstyle, 1960 char *wclass, int wstyle,
2357 int exstyle, const char *wtext, INT_PTR wid) 1961 int exstyle, const char *wtext, INT_PTR wid)
@@ -2363,13 +1967,9 @@ HWND mkctrl(frontend *fe, int x1, int x2, int y1, int y2,
2363 SendMessage(ret, WM_SETFONT, (WPARAM)fe->cfgfont, MAKELPARAM(true, 0)); 1967 SendMessage(ret, WM_SETFONT, (WPARAM)fe->cfgfont, MAKELPARAM(true, 0));
2364 return ret; 1968 return ret;
2365} 1969}
2366#endif
2367 1970
2368static void about(frontend *fe) 1971static void about(frontend *fe)
2369{ 1972{
2370#ifdef _WIN32_WCE
2371 DialogBox(fe->inst, MAKEINTRESOURCE(IDD_ABOUT), fe->hwnd, AboutDlgProc);
2372#else
2373 int i; 1973 int i;
2374 WNDCLASS wc; 1974 WNDCLASS wc;
2375 MSG msg; 1975 MSG msg;
@@ -2518,19 +2118,10 @@ static void about(frontend *fe)
2518 SetForegroundWindow(fe->hwnd); 2118 SetForegroundWindow(fe->hwnd);
2519 DestroyWindow(fe->cfgbox); 2119 DestroyWindow(fe->cfgbox);
2520 DeleteObject(fe->cfgfont); 2120 DeleteObject(fe->cfgfont);
2521#endif
2522} 2121}
2523 2122
2524static bool get_config(frontend *fe, int which) 2123static bool get_config(frontend *fe, int which)
2525{ 2124{
2526#ifdef _WIN32_WCE
2527 fe->cfg_which = which;
2528
2529 return DialogBoxParam(fe->inst,
2530 MAKEINTRESOURCE(IDD_CONFIG),
2531 fe->hwnd, ConfigDlgProc,
2532 (LPARAM) fe) == 2;
2533#else
2534 config_item *i; 2125 config_item *i;
2535 struct cfg_aux *j; 2126 struct cfg_aux *j;
2536 char *title; 2127 char *title;
@@ -2770,38 +2361,8 @@ static bool get_config(frontend *fe, int which)
2770 sfree(fe->cfgaux); 2361 sfree(fe->cfgaux);
2771 2362
2772 return (fe->dlg_done == 2); 2363 return (fe->dlg_done == 2);
2773#endif
2774} 2364}
2775 2365
2776#ifdef _WIN32_WCE
2777static void calculate_bitmap_position(frontend *fe, int x, int y)
2778{
2779 /* Pocket PC - center the game in the full screen window */
2780 int yMargin;
2781 RECT rcClient;
2782
2783 GetClientRect(fe->hwnd, &rcClient);
2784 fe->bitmapPosition.left = (rcClient.right - x) / 2;
2785 yMargin = rcClient.bottom - y;
2786
2787 if (fe->numpad != NULL) {
2788 RECT rcPad;
2789 GetWindowRect(fe->numpad, &rcPad);
2790 yMargin -= rcPad.bottom - rcPad.top;
2791 }
2792
2793 if (fe->statusbar != NULL) {
2794 RECT rcStatus;
2795 GetWindowRect(fe->statusbar, &rcStatus);
2796 yMargin -= rcStatus.bottom - rcStatus.top;
2797 }
2798
2799 fe->bitmapPosition.top = yMargin / 2;
2800
2801 fe->bitmapPosition.right = fe->bitmapPosition.left + x;
2802 fe->bitmapPosition.bottom = fe->bitmapPosition.top + y;
2803}
2804#else
2805static void calculate_bitmap_position(frontend *fe, int x, int y) 2366static void calculate_bitmap_position(frontend *fe, int x, int y)
2806{ 2367{
2807 /* Plain Windows - position the game in the upper-left corner */ 2368 /* Plain Windows - position the game in the upper-left corner */
@@ -2810,7 +2371,6 @@ static void calculate_bitmap_position(frontend *fe, int x, int y)
2810 fe->bitmapPosition.right = fe->bitmapPosition.left + x; 2371 fe->bitmapPosition.right = fe->bitmapPosition.left + x;
2811 fe->bitmapPosition.bottom = fe->bitmapPosition.top + y; 2372 fe->bitmapPosition.bottom = fe->bitmapPosition.top + y;
2812} 2373}
2813#endif
2814 2374
2815static void new_bitmap(frontend *fe, int x, int y) 2375static void new_bitmap(frontend *fe, int x, int y)
2816{ 2376{
@@ -2830,12 +2390,12 @@ static void new_game_size(frontend *fe, float scale)
2830 int x, y; 2390 int x, y;
2831 2391
2832 get_max_puzzle_size(fe, &x, &y); 2392 get_max_puzzle_size(fe, &x, &y);
2833 midend_size(fe->me, &x, &y, false); 2393 midend_size(fe->me, &x, &y, false, 1.0);
2834 2394
2835 if (scale != 1.0) { 2395 if (scale != 1.0) {
2836 x = (int)((float)x * fe->puzz_scale); 2396 x = (int)((float)x * fe->puzz_scale);
2837 y = (int)((float)y * fe->puzz_scale); 2397 y = (int)((float)y * fe->puzz_scale);
2838 midend_size(fe->me, &x, &y, true); 2398 midend_size(fe->me, &x, &y, true, 1.0);
2839 } 2399 }
2840 fe->ymin = (fe->xmin * y) / x; 2400 fe->ymin = (fe->xmin * y) / x;
2841 2401
@@ -2849,26 +2409,19 @@ static void new_game_size(frontend *fe, float scale)
2849 } else { 2409 } else {
2850 sr.left = sr.right = sr.top = sr.bottom = 0; 2410 sr.left = sr.right = sr.top = sr.bottom = 0;
2851 } 2411 }
2852#ifndef _WIN32_WCE
2853 SetWindowPos(fe->hwnd, NULL, 0, 0, 2412 SetWindowPos(fe->hwnd, NULL, 0, 0,
2854 r.right - r.left, 2413 r.right - r.left,
2855 r.bottom - r.top + sr.bottom - sr.top, 2414 r.bottom - r.top + sr.bottom - sr.top,
2856 SWP_NOMOVE | SWP_NOZORDER); 2415 SWP_NOMOVE | SWP_NOZORDER);
2857#endif
2858 2416
2859 check_window_size(fe, &x, &y); 2417 check_window_size(fe, &x, &y);
2860 2418
2861#ifndef _WIN32_WCE
2862 if (fe->statusbar != NULL) 2419 if (fe->statusbar != NULL)
2863 SetWindowPos(fe->statusbar, NULL, 0, y, x, 2420 SetWindowPos(fe->statusbar, NULL, 0, y, x,
2864 sr.bottom - sr.top, SWP_NOZORDER); 2421 sr.bottom - sr.top, SWP_NOZORDER);
2865#endif
2866 2422
2867 new_bitmap(fe, x, y); 2423 new_bitmap(fe, x, y);
2868 2424
2869#ifdef _WIN32_WCE
2870 InvalidateRect(fe->hwnd, NULL, true);
2871#endif
2872 midend_redraw(fe->me); 2425 midend_redraw(fe->me);
2873} 2426}
2874 2427
@@ -2895,13 +2448,13 @@ static void adjust_game_size(frontend *fe, RECT *proposed, bool isedge,
2895 ydiff = (proposed->bottom - proposed->top) - (wr.bottom - wr.top); 2448 ydiff = (proposed->bottom - proposed->top) - (wr.bottom - wr.top);
2896 2449
2897 if (isedge) { 2450 if (isedge) {
2898 /* These next four lines work around the fact that midend_size 2451 /* These next four lines work around the fact that midend_size
2899 * is happy to shrink _but not grow_ if you change one dimension 2452 * is happy to shrink _but not grow_ if you change one dimension
2900 * but not the other. */ 2453 * but not the other. */
2901 if (xdiff > 0 && ydiff == 0) 2454 if (xdiff > 0 && ydiff == 0)
2902 ydiff = (xdiff * (wr.right - wr.left)) / (wr.bottom - wr.top); 2455 ydiff = (xdiff * (wr.right - wr.left)) / (wr.bottom - wr.top);
2903 if (xdiff == 0 && ydiff > 0) 2456 if (xdiff == 0 && ydiff > 0)
2904 xdiff = (ydiff * (wr.bottom - wr.top)) / (wr.right - wr.left); 2457 xdiff = (ydiff * (wr.bottom - wr.top)) / (wr.right - wr.left);
2905 } 2458 }
2906 2459
2907 if (check_window_resize(fe, 2460 if (check_window_resize(fe,
@@ -2951,6 +2504,138 @@ static void update_type_menu_tick(frontend *fe)
2951 DrawMenuBar(fe->hwnd); 2504 DrawMenuBar(fe->hwnd);
2952} 2505}
2953 2506
2507static char *prefs_dir(void)
2508{
2509 const char *var;
2510 if ((var = getenv("APPDATA")) != NULL) {
2511 size_t size = strlen(var) + 80;
2512 char *dir = snewn(size, char);
2513 sprintf(dir, "%s\\Simon Tatham's Portable Puzzle Collection", var);
2514 return dir;
2515 }
2516 return NULL;
2517}
2518
2519static char *prefs_path_general(const game *game, const char *suffix)
2520{
2521 char *dir, *path;
2522
2523 dir = prefs_dir();
2524 if (!dir)
2525 return NULL;
2526
2527 path = make_prefs_path(dir, "\\", game, suffix);
2528
2529 sfree(dir);
2530 return path;
2531}
2532
2533static char *prefs_path(const game *game)
2534{
2535 return prefs_path_general(game, ".conf");
2536}
2537
2538static char *prefs_tmp_path(const game *game)
2539{
2540 return prefs_path_general(game, ".tmp");
2541}
2542
2543static void load_prefs(midend *me)
2544{
2545 const game *game = midend_which_game(me);
2546 char *path = prefs_path(game);
2547 if (!path)
2548 return;
2549 FILE *fp = fopen(path, "r");
2550 if (!fp)
2551 return;
2552 const char *err = midend_load_prefs(me, savefile_read, fp);
2553 fclose(fp);
2554 if (err)
2555 fprintf(stderr, "Unable to load preferences file %s:\n%s\n",
2556 path, err);
2557 sfree(path);
2558}
2559
2560static char *save_prefs(midend *me)
2561{
2562 const game *game = midend_which_game(me);
2563 char *dir_path = prefs_dir();
2564 char *file_path = prefs_path(game);
2565 char *tmp_path = prefs_tmp_path(game);
2566 HANDLE fh;
2567 FILE *fp;
2568 bool cleanup_dir = false, cleanup_tmpfile = false;
2569 char *err = NULL;
2570
2571 if (!dir_path || !file_path || !tmp_path) {
2572 sprintf(err = snewn(256, char),
2573 "Unable to save preferences:\n"
2574 "Could not determine pathname for configuration files");
2575 goto out;
2576 }
2577
2578 if (!CreateDirectory(dir_path, NULL)) {
2579 /* Ignore errors while trying to make the directory. It may
2580 * well already exist, and even if we got some error code
2581 * other than EEXIST, it's still worth at least _trying_ to
2582 * make the file inside it, and see if that goes wrong. */
2583 } else {
2584 cleanup_dir = true;
2585 }
2586
2587 fh = CreateFile(tmp_path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
2588 FILE_ATTRIBUTE_NORMAL, NULL);
2589 if (fh == INVALID_HANDLE_VALUE) {
2590 char *os_err = geterrstr();
2591 sprintf(err = snewn(256 + strlen(tmp_path) + strlen(os_err), char),
2592 "Unable to save preferences:\n"
2593 "Unable to create file '%s':\n%s", tmp_path, os_err);
2594 sfree(os_err);
2595 goto out;
2596 } else {
2597 cleanup_tmpfile = true;
2598 }
2599
2600 fp = _fdopen(_open_osfhandle((intptr_t)fh, 0), "w");
2601 SetLastError(0);
2602 midend_save_prefs(me, savefile_write, fp);
2603 fclose(fp);
2604 if (GetLastError()) {
2605 char *os_err = geterrstr();
2606 sprintf(err = snewn(80 + strlen(tmp_path) + strlen(os_err), char),
2607 "Unable to write file '%s':\n%s", tmp_path, os_err);
2608 sfree(os_err);
2609 goto out;
2610 }
2611
2612 if (MoveFileEx(tmp_path, file_path, MOVEFILE_REPLACE_EXISTING) < 0) {
2613 char *os_err = geterrstr();
2614 sprintf(err = snewn(256 + strlen(tmp_path) + strlen(file_path) +
2615 strlen(os_err), char),
2616 "Unable to save preferences:\n"
2617 "Unable to rename '%s' to '%s':\n%s", tmp_path, file_path,
2618 os_err);
2619 sfree(os_err);
2620 goto out;
2621 } else {
2622 cleanup_dir = false;
2623 cleanup_tmpfile = false;
2624 }
2625
2626 out:
2627 if (cleanup_tmpfile) {
2628 if (!DeleteFile(tmp_path)) { /* can't do anything about this */ }
2629 }
2630 if (cleanup_dir) {
2631 if (!RemoveDirectory(dir_path)) { /* can't do anything about this */ }
2632 }
2633 sfree(dir_path);
2634 sfree(file_path);
2635 sfree(tmp_path);
2636 return err;
2637}
2638
2954static void update_copy_menu_greying(frontend *fe) 2639static void update_copy_menu_greying(frontend *fe)
2955{ 2640{
2956 UINT enable = (midend_can_format_as_text_now(fe->me) ? 2641 UINT enable = (midend_can_format_as_text_now(fe->me) ?
@@ -2990,28 +2675,21 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
2990 DestroyWindow(hwnd); 2675 DestroyWindow(hwnd);
2991 return 0; 2676 return 0;
2992 case WM_COMMAND: 2677 case WM_COMMAND:
2993#ifdef _WIN32_WCE
2994 /* Numeric pad sends WM_COMMAND messages */
2995 if ((wParam >= IDM_KEYEMUL) && (wParam < IDM_KEYEMUL + 256))
2996 {
2997 midend_process_key(fe->me, 0, 0, wParam - IDM_KEYEMUL);
2998 }
2999#endif
3000 cmd = wParam & ~0xF; /* low 4 bits reserved to Windows */ 2678 cmd = wParam & ~0xF; /* low 4 bits reserved to Windows */
3001 switch (cmd) { 2679 switch (cmd) {
3002 case IDM_NEW: 2680 case IDM_NEW:
3003 if (!midend_process_key(fe->me, 0, 0, UI_NEWGAME)) 2681 if (midend_process_key(fe->me, 0, 0, UI_NEWGAME) == PKR_QUIT)
3004 PostQuitMessage(0); 2682 PostQuitMessage(0);
3005 break; 2683 break;
3006 case IDM_RESTART: 2684 case IDM_RESTART:
3007 midend_restart_game(fe->me); 2685 midend_restart_game(fe->me);
3008 break; 2686 break;
3009 case IDM_UNDO: 2687 case IDM_UNDO:
3010 if (!midend_process_key(fe->me, 0, 0, UI_UNDO)) 2688 if (midend_process_key(fe->me, 0, 0, UI_UNDO) == PKR_QUIT)
3011 PostQuitMessage(0); 2689 PostQuitMessage(0);
3012 break; 2690 break;
3013 case IDM_REDO: 2691 case IDM_REDO:
3014 if (!midend_process_key(fe->me, 0, 0, UI_REDO)) 2692 if (midend_process_key(fe->me, 0, 0, UI_REDO) == PKR_QUIT)
3015 PostQuitMessage(0); 2693 PostQuitMessage(0);
3016 break; 2694 break;
3017 case IDM_COPY: 2695 case IDM_COPY:
@@ -3033,7 +2711,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
3033 } 2711 }
3034 break; 2712 break;
3035 case IDM_QUIT: 2713 case IDM_QUIT:
3036 if (!midend_process_key(fe->me, 0, 0, UI_QUIT)) 2714 if (midend_process_key(fe->me, 0, 0, UI_QUIT) == PKR_QUIT)
3037 PostQuitMessage(0); 2715 PostQuitMessage(0);
3038 break; 2716 break;
3039 case IDM_CONFIG: 2717 case IDM_CONFIG:
@@ -3052,6 +2730,16 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
3052 if (get_config(fe, CFG_PRINT)) 2730 if (get_config(fe, CFG_PRINT))
3053 print(fe); 2731 print(fe);
3054 break; 2732 break;
2733 case IDM_PREFS:
2734 if (get_config(fe, CFG_PREFS)) {
2735 char *prefs_err = save_prefs(fe->me);
2736 if (prefs_err) {
2737 MessageBox(fe->hwnd, prefs_err, "Error saving preferences",
2738 MB_ICONERROR | MB_OK);
2739 sfree(prefs_err);
2740 }
2741 }
2742 break;
3055 case IDM_ABOUT: 2743 case IDM_ABOUT:
3056 about(fe); 2744 about(fe);
3057 break; 2745 break;
@@ -3173,7 +2861,6 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
3173 } 2861 }
3174 2862
3175 break; 2863 break;
3176#ifndef _WIN32_WCE
3177 case IDM_HELPC: 2864 case IDM_HELPC:
3178 start_help(fe, NULL); 2865 start_help(fe, NULL);
3179 break; 2866 break;
@@ -3182,34 +2869,38 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
3182 start_help(fe, help_type == CHM ? 2869 start_help(fe, help_type == CHM ?
3183 fe->game->htmlhelp_topic : fe->game->winhelp_topic); 2870 fe->game->htmlhelp_topic : fe->game->winhelp_topic);
3184 break; 2871 break;
3185#endif 2872 default: {
3186 default: 2873 unsigned n;
2874
3187#ifdef COMBINED 2875#ifdef COMBINED
3188 if (wParam >= IDM_GAMES && wParam < (IDM_GAMES + (WPARAM)gamecount)) { 2876 n = (wParam - IDM_GAME_BASE) / MENUITEM_STEP;
3189 int p = wParam - IDM_GAMES; 2877 if (n < gamecount && wParam == IDM_GAME_BASE + MENUITEM_STEP * n) {
3190 char *error = NULL; 2878 char *error = NULL;
3191 fe_set_midend(fe, midend_for_new_game(fe, gamelist[p], NULL, 2879 fe_set_midend(fe, midend_for_new_game(fe, gamelist[n], NULL,
3192 false, false, &error)); 2880 false, false, &error));
3193 sfree(error); 2881 sfree(error);
3194 } else 2882 break;
2883 }
3195#endif 2884#endif
3196 { 2885
2886 n = (wParam - IDM_PRESET_BASE) / MENUITEM_STEP;
2887 if (wParam == IDM_PRESET_BASE + MENUITEM_STEP * n) {
3197 game_params *preset = preset_menu_lookup_by_id( 2888 game_params *preset = preset_menu_lookup_by_id(
3198 fe->preset_menu, 2889 fe->preset_menu, n);
3199 ((wParam &~ 0xF) - IDM_PRESETS) / 0x10);
3200 2890
3201 if (preset) { 2891 if (preset) {
3202 midend_set_params(fe->me, preset); 2892 midend_set_params(fe->me, preset);
3203 new_game_type(fe); 2893 new_game_type(fe);
2894 break;
3204 } 2895 }
3205 } 2896 }
3206 break; 2897
2898 break;
2899 }
3207 } 2900 }
3208 break; 2901 break;
3209 case WM_DESTROY: 2902 case WM_DESTROY:
3210#ifndef _WIN32_WCE
3211 stop_help(fe); 2903 stop_help(fe);
3212#endif
3213 frontend_free(fe); 2904 frontend_free(fe);
3214 PostQuitMessage(0); 2905 PostQuitMessage(0);
3215 return 0; 2906 return 0;
@@ -3223,9 +2914,6 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
3223 hdc = BeginPaint(hwnd, &p); 2914 hdc = BeginPaint(hwnd, &p);
3224 hdc2 = CreateCompatibleDC(hdc); 2915 hdc2 = CreateCompatibleDC(hdc);
3225 prevbm = SelectObject(hdc2, fe->bitmap); 2916 prevbm = SelectObject(hdc2, fe->bitmap);
3226#ifdef _WIN32_WCE
3227 FillRect(hdc, &(p.rcPaint), (HBRUSH) GetStockObject(WHITE_BRUSH));
3228#endif
3229 IntersectRect(&rcDest, &(fe->bitmapPosition), &(p.rcPaint)); 2917 IntersectRect(&rcDest, &(fe->bitmapPosition), &(p.rcPaint));
3230 BitBlt(hdc, 2918 BitBlt(hdc,
3231 rcDest.left, rcDest.top, 2919 rcDest.left, rcDest.top,
@@ -3310,7 +2998,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
3310 } 2998 }
3311 2999
3312 if (key != -1) { 3000 if (key != -1) {
3313 if (!midend_process_key(fe->me, 0, 0, key)) 3001 if (midend_process_key(fe->me, 0, 0, key) == PKR_QUIT)
3314 PostQuitMessage(0); 3002 PostQuitMessage(0);
3315 } else { 3003 } else {
3316 MSG m; 3004 MSG m;
@@ -3338,32 +3026,12 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
3338 else if (message == WM_RBUTTONDOWN || is_alt_pressed()) 3026 else if (message == WM_RBUTTONDOWN || is_alt_pressed())
3339 button = RIGHT_BUTTON; 3027 button = RIGHT_BUTTON;
3340 else 3028 else
3341#ifndef _WIN32_WCE
3342 button = LEFT_BUTTON; 3029 button = LEFT_BUTTON;
3343#else
3344 if ((fe->game->flags & REQUIRE_RBUTTON) == 0)
3345 button = LEFT_BUTTON;
3346 else
3347 {
3348 SHRGINFO shrgi;
3349
3350 shrgi.cbSize = sizeof(SHRGINFO);
3351 shrgi.hwndClient = hwnd;
3352 shrgi.ptDown.x = (signed short)LOWORD(lParam);
3353 shrgi.ptDown.y = (signed short)HIWORD(lParam);
3354 shrgi.dwFlags = SHRG_RETURNCMD;
3355
3356 if (GN_CONTEXTMENU == SHRecognizeGesture(&shrgi))
3357 button = RIGHT_BUTTON;
3358 else
3359 button = LEFT_BUTTON;
3360 }
3361#endif
3362 3030
3363 if (!midend_process_key(fe->me, 3031 if (midend_process_key(fe->me,
3364 (signed short)LOWORD(lParam) - fe->bitmapPosition.left, 3032 (signed short)LOWORD(lParam) - fe->bitmapPosition.left,
3365 (signed short)HIWORD(lParam) - fe->bitmapPosition.top, 3033 (signed short)HIWORD(lParam) - fe->bitmapPosition.top,
3366 button)) 3034 button) == PKR_QUIT)
3367 PostQuitMessage(0); 3035 PostQuitMessage(0);
3368 3036
3369 SetCapture(hwnd); 3037 SetCapture(hwnd);
@@ -3387,10 +3055,10 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
3387 else 3055 else
3388 button = LEFT_RELEASE; 3056 button = LEFT_RELEASE;
3389 3057
3390 if (!midend_process_key(fe->me, 3058 if (midend_process_key(fe->me,
3391 (signed short)LOWORD(lParam) - fe->bitmapPosition.left, 3059 (signed short)LOWORD(lParam) - fe->bitmapPosition.left,
3392 (signed short)HIWORD(lParam) - fe->bitmapPosition.top, 3060 (signed short)HIWORD(lParam) - fe->bitmapPosition.top,
3393 button)) 3061 button) == PKR_QUIT)
3394 PostQuitMessage(0); 3062 PostQuitMessage(0);
3395 3063
3396 ReleaseCapture(); 3064 ReleaseCapture();
@@ -3407,10 +3075,10 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
3407 else 3075 else
3408 button = LEFT_DRAG; 3076 button = LEFT_DRAG;
3409 3077
3410 if (!midend_process_key(fe->me, 3078 if (midend_process_key(fe->me,
3411 (signed short)LOWORD(lParam) - fe->bitmapPosition.left, 3079 (signed short)LOWORD(lParam) - fe->bitmapPosition.left,
3412 (signed short)HIWORD(lParam) - fe->bitmapPosition.top, 3080 (signed short)HIWORD(lParam) - fe->bitmapPosition.top,
3413 button)) 3081 button) == PKR_QUIT)
3414 PostQuitMessage(0); 3082 PostQuitMessage(0);
3415 } 3083 }
3416 break; 3084 break;
@@ -3424,7 +3092,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
3424 (keystate[VK_CONTROL] & 0x80)) 3092 (keystate[VK_CONTROL] & 0x80))
3425 key = UI_REDO; 3093 key = UI_REDO;
3426 } 3094 }
3427 if (!midend_process_key(fe->me, 0, 0, key)) 3095 if (midend_process_key(fe->me, 0, 0, key) == PKR_QUIT)
3428 PostQuitMessage(0); 3096 PostQuitMessage(0);
3429 } 3097 }
3430 return 0; 3098 return 0;
@@ -3436,7 +3104,6 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
3436 fe->timer_last_tickcount = now; 3104 fe->timer_last_tickcount = now;
3437 } 3105 }
3438 return 0; 3106 return 0;
3439#ifndef _WIN32_WCE
3440 case WM_SIZING: 3107 case WM_SIZING:
3441 { 3108 {
3442 RECT *sr = (RECT *)lParam; 3109 RECT *sr = (RECT *)lParam;
@@ -3468,29 +3135,11 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
3468 return true; 3135 return true;
3469 } 3136 }
3470 break; 3137 break;
3471#endif
3472 } 3138 }
3473 3139
3474 return DefWindowProc(hwnd, message, wParam, lParam); 3140 return DefWindowProc(hwnd, message, wParam, lParam);
3475} 3141}
3476 3142
3477#ifdef _WIN32_WCE
3478static int FindPreviousInstance()
3479{
3480 /* Check if application is running. If it's running then focus on the window */
3481 HWND hOtherWnd = NULL;
3482
3483 hOtherWnd = FindWindow (wGameName, wGameName);
3484 if (hOtherWnd)
3485 {
3486 SetForegroundWindow (hOtherWnd);
3487 return true;
3488 }
3489
3490 return false;
3491}
3492#endif
3493
3494/* 3143/*
3495 * Split a complete command line into argc/argv, attempting to do it 3144 * Split a complete command line into argc/argv, attempting to do it
3496 * exactly the same way the Visual Studio C library would do it (so 3145 * exactly the same way the Visual Studio C library would do it (so
@@ -3723,12 +3372,6 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
3723 3372
3724 split_into_argv(cmdline, &argc, &argv, NULL); 3373 split_into_argv(cmdline, &argc, &argv, NULL);
3725 3374
3726#ifdef _WIN32_WCE
3727 MultiByteToWideChar (CP_ACP, 0, CLASSNAME, -1, wClassName, 256);
3728 if (FindPreviousInstance ())
3729 return 0;
3730#endif
3731
3732 InitCommonControls(); 3375 InitCommonControls();
3733 3376
3734 if (!prev) { 3377 if (!prev) {
@@ -3740,18 +3383,12 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
3740 wndclass.cbWndExtra = 0; 3383 wndclass.cbWndExtra = 0;
3741 wndclass.hInstance = inst; 3384 wndclass.hInstance = inst;
3742 wndclass.hIcon = LoadIcon(inst, MAKEINTRESOURCE(200)); 3385 wndclass.hIcon = LoadIcon(inst, MAKEINTRESOURCE(200));
3743#ifndef _WIN32_WCE
3744 if (!wndclass.hIcon) /* in case resource file is absent */ 3386 if (!wndclass.hIcon) /* in case resource file is absent */
3745 wndclass.hIcon = LoadIcon(inst, IDI_APPLICATION); 3387 wndclass.hIcon = LoadIcon(inst, IDI_APPLICATION);
3746#endif
3747 wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); 3388 wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
3748 wndclass.hbrBackground = NULL; 3389 wndclass.hbrBackground = NULL;
3749 wndclass.lpszMenuName = NULL; 3390 wndclass.lpszMenuName = NULL;
3750#ifdef _WIN32_WCE
3751 wndclass.lpszClassName = wClassName;
3752#else
3753 wndclass.lpszClassName = CLASSNAME; 3391 wndclass.lpszClassName = CLASSNAME;
3754#endif
3755 3392
3756 RegisterClass(&wndclass); 3393 RegisterClass(&wndclass);
3757 } 3394 }