1 /* $Id: winmain.c,v 1.6 2000/11/16 14:21:32 amura Exp $ */
2 /* OS dependent code used by Ng for WinCE.
3 * Copyright (C) 1998 Eiichiro Ito
4 * Modified for Ng for Win32
5 * Copyright (C) 1999,2000 Toru Imai
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * ree Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */
21 /*
22 * NG : NG program main routine
23 *
24 * 1998/11/14:Eiichiroh Itoh
25 *
26 */
27
28 /*
29 * $Log: winmain.c,v $
30 * Revision 1.6 2000/11/16 14:21:32 amura
31 * merge Ng for win32 0.5
32 *
33 * Revision 1.5 2000/10/23 16:52:52 amura
34 * add GPL copyright to header
35 *
36 * Revision 1.4 2000/09/01 19:41:21 amura
37 * fix for suppress buffer overrun
38 *
39 * Revision 1.3 2000/07/22 20:46:33 amura
40 * support "Drag&Drop"
41 *
42 * Revision 1.2 2000/07/18 12:42:34 amura
43 * support IME convertion on the spot
44 *
45 * Revision 1.1.1.1 2000/06/27 01:48:00 amura
46 * import to CVS
47 *
48 */
49
50 #include <windows.h>
51 #include <windowsx.h>
52 #include <commdlg.h>
53 #include <commctrl.h>
54 #include "config.h"
55 #include "def.h"
56 #include "ttyctrl.h"
57 #include "resource.h"
58 #include "winmain.h"
59 #include "tools.h"
60
61 #ifdef KANJI
62 #ifdef USE_KCTRL
63 #include "kctrl.h"
64 #include "cefep.h"
65 #define VALID_KCTRL_VERSION 13
66 #else /* not USE_KCTRL */
67 #include <imm.h>
68 #endif /* USE_KCTRL */
69 #endif /* KANJI */
70
71 #if defined(WIN32_PLATFORM_PSPC) && 300 <= _WIN32_WCE
72 #define USE_SHMENU /* Define a macro to indicate using PocketPC menu */
73 #define POCKETPC_MENU_HEIGHT 26 /* Height of Menubar */
74 #else
75 #define POCKETPC_MENU_HEIGHT 0
76 #endif
77
78 /* #define MG_FOR_PPC
79 This should be defined in the Makefile or dsp file */
80
81 #if defined(MG_FOR_PPC) || defined(__PsPC__) || 300 <= _WIN32_WCE
82 #include <aygshell.h>
83 #endif
84
85 #ifdef COMMANDBANDS
86 #if 200 <= _WIN32_WCE
87 #define USE_COMMANDBANDS
88 /* #define USE_BEGINTHREAD */
89 /* instead of CreateThread. Though I do not care... */
90 #endif
91 #endif
92
93 #if !defined(MG_FOR_PPC) && !defined(_WIN32_WCE_EMULATION)
94 #ifndef USE_KCTRL
95 #define MG_IME_CONTROL
96 #endif /* USE_KCTRL */
97 #endif /* !defined(MG_FOR_PPC) && !defined(_WIN32_WCE_EMULATION) */
98
99 #define EXCEPTION_QUIT (1)
100 #define IDM_START (1001)
101 #define IDM_EXIT (1002)
102 #define IDC_TTY (2001)
103
104 #ifdef KANJI
105 #define MGTITLE TEXT("Ng")
106 #define MGCLASS TEXT("NG")
107 #else
108 #define MGTITLE TEXT("Mg")
109 #define MGCLASS TEXT("MG")
110 #endif
111
112 HINSTANCE g_hInst ;
113 HWND g_hwndMain ;
114 HWND g_hwndTty ;
115 HANDLE g_hevtGetChar = 0 ;
116 HANDLE g_hThread = 0 ;
117 BOOL g_bExit = FALSE ;
118 TCHAR g_szTitleName[ MAX_PATH ] = MGTITLE;
119 TCHAR g_szClassName[] = MGCLASS;
120 DWORD g_dwAppVersion = 12 ;
121 TCHAR MessageBuf[ MAX_PATH ] = TEXT("") ;
122 CHAR g_szArgBuf[ 256 ] ;
123 int g_dwArgc ;
124 LPSTR g_szArgv[ 128 ] ;
125 #if defined(COMMANDBANDS) && defined(USE_COMMANDBANDS)
126 HIMAGELIST g_himlrebar; /* Image list for rebar bands */
127 #endif
128 #ifdef CTRLMAP
129 DWORD g_ctrlmap;
130 #endif
131 DWORD g_beepsound, g_keyboardlocale;
132 TCHAR g_beepfile[128];
133 #if defined(KANJI) && defined(USE_KCTRL)
134 DWORD g_dwDllVersion = 0 ;
135 #endif
136
137 #if (defined(COMMANDBANDS) && !defined(USE_SHMENU)) || !defined(_WIN32_WCE)
138 #define USE_REGINFO
139 #endif
140
141 #ifdef USE_REGINFO
142 /* Settings stored in registry */
143 struct reginfo {
144 #if defined(COMMANDBANDS) && !defined(USE_SHMENU)
145 BOOL showbands;
146 #endif /* COMMANDBANDS */
147 #ifndef _WIN32_WCE
148 BOOL maximized;
149 RECT rect; /* rect for the window */
150 #else /* if _WIN32_WCE */
151 #if defined(COMMANDBANDS) && defined(USE_COMMANDBANDS) \
152 && !defined(USE_SHMENU)
153 COMMANDBANDSRESTOREINFO cbinfo[2]; /* Info for Bands */
154 #endif
155 #endif /* _WIN32_WCE */
156 BOOL valid; /* tell if stored info is valid */
157 };
158
159 static struct reginfo g_reginfo;
160 #endif /* USE_REGINFO */
161
162 static BOOL init_application( void ) ;
163 static BOOL init_instance( int nCmdShow ) ;
164 LRESULT CALLBACK MainWndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ) ;
165 static void cmdline2args( LPSTR cmdline, int *argc, char **argv ) ;
166 static void ThreadMain( void ) ;
167
168 #ifdef CTRLMAP
169 #define VK_EISU 0xf0
170 #define VK_SOMETHING 0xe5
171
172 static BOOL
controlkey_swap(MSG * msg)173 controlkey_swap(MSG *msg)
174 {
175 if (msg->message == WM_KEYDOWN || msg->message == WM_KEYUP) {
176 if ((int)msg->wParam == VK_EISU) {
177 if (msg->message == WM_KEYDOWN && !(msg->lParam & (1 << 30))) {
178 /* key was up before this message */
179 keybd_event(VK_CONTROL, 0, 0, 0);
180 }
181 else if (msg->message == WM_KEYUP && (msg->lParam & (1 << 30))) {
182 /* key was down before this message */
183 keybd_event(VK_CONTROL, 0, KEYEVENTF_KEYUP, 0);
184 }
185 return TRUE;
186 }
187 if ((int)msg->wParam == VK_SOMETHING) { /* What's this? */
188 /* Although I don't know the reason and details, some specific
189 virtual code is generated according to a key press of
190 Japanese mode-related keys such as EISU, HIRAGANA, HANKAKU
191 and so on. Curiously, the virtual code is only generated for
192 depressing while Japanese input mode is open. The following
193 program detects the virtual code and treats as control key in
194 case EISU is depressed. */
195
196 SHORT eisu_down;
197
198 eisu_down = GetAsyncKeyState(VK_EISU);
199 if (eisu_down) {
200 if (msg->message == WM_KEYDOWN && !(msg->lParam & (1 << 30))) {
201 /* key was up before this message */
202 keybd_event(VK_CONTROL, 0, 0, 0);
203 }
204 return TRUE;
205 }
206 }
207 }
208 return FALSE;
209 }
210 #endif /* CTRLMAP */
211
212 int WINAPI
213 #ifdef _WIN32_WCE
WinMain(HINSTANCE hThisInst,HINSTANCE hPrevInst,LPTSTR lpszArgs,int nWinMode)214 WinMain( HINSTANCE hThisInst, HINSTANCE hPrevInst,
215 LPTSTR lpszArgs, int nWinMode )
216 #else /* _WIN32_WCE */
217 WinMain( HINSTANCE hThisInst, HINSTANCE hPrevInst,
218 LPSTR lpszArgs, int nWinMode )
219 #endif /* _WIN32_WCE */
220 {
221 MSG msg ;
222
223 g_hInst = hThisInst ;
224 #if defined(KANJI) && defined(USE_KCTRL)
225 g_dwDllVersion = GetKVersion() ;
226 if ( g_dwDllVersion < VALID_KCTRL_VERSION ) {
227 wsprintf( MessageBuf,
228 TEXT("Obsolete KCTRL.DLL used\r\nPlease use Ver%d.%02d or later"),
229 VALID_KCTRL_VERSION / 100, VALID_KCTRL_VERSION % 100 ) ;
230 MessageBox( NULL, MessageBuf, g_szTitleName, MB_OK|MB_ICONASTERISK ) ;
231 return FALSE ;
232 }
233 if ( !InitFep() ) {
234 MessageBox( NULL, TEXT("Can't initialize FEP."), g_szTitleName, MB_OK|MB_ICONASTERISK ) ;
235 return FALSE ;
236 }
237 if ( !InitKanjiControls() ) {
238 wsprintf( MessageBuf,
239 TEXT("KCTRL.DLL Initialize error\r\nError=%x"),
240 GetLastError() ) ;
241 MessageBox( NULL, MessageBuf, g_szTitleName, MB_OK|MB_ICONASTERISK ) ;
242 return FALSE ;
243 }
244 #endif
245 /* define a TTY Window */
246 if ( !TtyViewRegisterClass( g_hInst ) ) {
247 goto ExitMain ;
248 }
249 /* create an event for keyboard input notification */
250 g_hevtGetChar = CreateEvent( NULL, FALSE, FALSE, NULL ) ;
251 if ( g_hevtGetChar == NULL ) {
252 goto ExitMain ;
253 }
254 /* define a window class */
255 if ( !init_application() ) {
256 goto ExitMain ;
257 }
258 /* create a window */
259 if ( !init_instance( nWinMode ) ) {
260 goto ExitMain ;
261 }
262
263 {
264 DWORD foo;
265 /* read configuration for Ng for Win32 */
266 #ifdef CTRLMAP
267 g_ctrlmap = RegQueryDWord(HKEY_CURRENT_USER, NGREGKEY,
268 NGCTRLKEYMAPVAL) ? TRUE : FALSE;
269 #endif
270 g_beepsound = RegQueryDWord(HKEY_CURRENT_USER, NGREGKEY,
271 NGBEEPSOUNDVAL);
272 g_keyboardlocale = RegQueryDWord(HKEY_CURRENT_USER, NGREGKEY,
273 NGKEYBOARDLOCALEVAL);
274 if (g_keyboardlocale == 0) {
275 #ifndef JAPANESE_KEYBOARD
276 g_keyboardlocale = NGKEYBOARD_US;
277 #else
278 g_keyboardlocale = NGKEYBOARD_JP;
279 #endif
280 }
281 SendMessage(g_hwndTty, TTYM_SETKEYBOARDLOCALE,
282 (WPARAM)g_keyboardlocale, 0);
283
284 foo = sizeof(g_beepfile);
285 RegQueryString(HKEY_CURRENT_USER, NGREGKEY, NGBEEPFILEVAL,
286 g_beepfile, &foo);
287 }
288
289 /* create a command line processing routine */
290 #ifdef _WIN32_WCE
291 unicode2sjis( lpszArgs, g_szArgBuf, sizeof g_szArgBuf ) ;
292 #else /* _WIN32_WCE */
293 strncpy(g_szArgBuf, lpszArgs, sizeof g_szArgBuf);
294 g_szArgBuf[(sizeof g_szArgBuf)-1] = '\0';
295 #endif /* _WIN32_WCE */
296 cmdline2args( g_szArgBuf, &g_dwArgc, g_szArgv ) ;
297 /* event loop */
298 while ( GetMessage( &msg, NULL, 0, 0 ) ) {
299 #ifdef CTRLMAP
300 if (!g_ctrlmap || !controlkey_swap(&msg)) {
301 /* call controlkey_swap() if g_ctrlmap is TRUE */
302 TranslateMessage(&msg);
303 DispatchMessage(&msg);
304 }
305 #else
306 TranslateMessage(&msg);
307 DispatchMessage(&msg);
308 #endif
309 }
310
311 ExitMain:
312 if ( g_hevtGetChar ) {
313 /* close the event for keyboard input notification */
314 CloseHandle( g_hevtGetChar ) ;
315 }
316 #if defined(KANJI) && defined(USE_KCTRL)
317 ReleaseKanjiControls() ;
318 #endif
319 return TRUE ;
320 }
321
322 /*
323 * register the main window class
324 */
325 static BOOL
init_application(void)326 init_application( void )
327 {
328 WNDCLASS wcl ;
329 wcl.style = 0 ;
330 wcl.lpfnWndProc = MainWndProc ;
331 wcl.cbClsExtra = 0 ;
332 wcl.cbWndExtra = 0 ;
333 wcl.hInstance = g_hInst ;
334 #ifdef _WIN32_WCE
335 wcl.hIcon = NULL ;
336 wcl.hCursor = NULL ;
337 #else
338 wcl.hIcon = LoadIcon (g_hInst,
339 (LPCTSTR)MAKEINTRESOURCE(IDI_APPICON));
340 wcl.hCursor = LoadCursor(NULL, IDC_ARROW);
341 #endif
342 wcl.hbrBackground = (HBRUSH) GetStockObject( WHITE_BRUSH ) ;
343 wcl.lpszMenuName = 0 ;
344 wcl.lpszClassName = g_szClassName ;
345 if ( !RegisterClass( &wcl ) ) {
346 return FALSE ;
347 }
348
349 /* initialize common controls */
350 #if 200 <= _WIN32_WCE
351 {
352 INITCOMMONCONTROLSEX icex;
353
354 icex.dwSize = sizeof(icex);
355 icex.dwICC = ICC_BAR_CLASSES | ICC_COOL_CLASSES;
356 InitCommonControlsEx(&icex);
357 }
358 #else
359 InitCommonControls();
360 #endif
361 return TRUE ;
362 }
363
364 #define RegQueryBinary(r, k, v, d, s) RegQueryString(r, k, v, (LPTSTR)d, s)
365
366 #ifdef COMMANDBANDS
367 static HWND g_hwndCB;
368 #endif
369
370 /*
371 * create a main window
372 */
373 static BOOL
init_instance(int nCmdShow)374 init_instance( int nCmdShow )
375 {
376 RECT rect ;
377 HMENU hMenu = NULL;
378 int x, y, cx, cy;
379 #ifdef USE_REGINFO
380 DWORD foo;
381 #endif
382
383 #ifndef _WIN32_WCE
384 hMenu = LoadMenu(g_hInst, MAKEINTRESOURCE(IDR_MAINMENU));
385 #endif /* _WIN32_WCE */
386
387 #ifdef USE_REGINFO /* get window position from registry */
388 foo = sizeof(g_reginfo);
389 if (RegQueryBinary(HKEY_CURRENT_USER, NGREGKEY, NGPREVPOSVAL,
390 &g_reginfo, &foo) == ERROR_SUCCESS) {
391 #ifndef _WIN32_WCE
392 #define MG_MIN_HEIGHT 120
393 #define MG_MIN_WIDTH 160
394 if (g_reginfo.rect.bottom - g_reginfo.rect.top < MG_MIN_HEIGHT) {
395 g_reginfo.rect.bottom = g_reginfo.rect.top + MG_MIN_HEIGHT;
396 }
397 if (g_reginfo.rect.right - g_reginfo.rect.left < MG_MIN_WIDTH) {
398 g_reginfo.rect.right = g_reginfo.rect.left + MG_MIN_WIDTH;
399 }
400 #endif /* _WIN32_WCE */
401 }
402 else {
403 g_reginfo.valid = FALSE;
404 #ifndef _WIN32_WCE
405 g_reginfo.rect.top = 0;
406 g_reginfo.rect.bottom = 296;
407 g_reginfo.rect.left = 0;
408 g_reginfo.rect.right = 500;
409 #endif /* _WIN32_WCE */
410 }
411
412 #if defined(COMMANDBANDS) && !defined(USE_SHMENU)
413 if (!g_reginfo.valid) {
414 g_reginfo.showbands = TRUE;
415 }
416 #endif /* defined(COMMANDBANDS) && !defined(USE_SHMENU) */
417 #endif /* USE_REGINFO */
418
419 x = y = cx = cy = CW_USEDEFAULT;
420 #if defined(WIN32_PLATFORM_PSPC) && 300 <= _WIN32_WCE
421 {
422 SIPINFO si;
423
424 memset(&si, 0, sizeof(SIPINFO));
425 si.cbSize = sizeof(si);
426 if (SHSipInfo(SPI_GETSIPINFO, 0, &si, 0)) {
427 if (si.fdwFlags & SIPF_ON) {
428 x = si.rcVisibleDesktop.left;
429 y = si.rcVisibleDesktop.top;
430 cx = si.rcVisibleDesktop.right - si.rcVisibleDesktop.left;
431 cy = si.rcVisibleDesktop.bottom - si.rcVisibleDesktop.top
432 + POCKETPC_MENU_HEIGHT;
433 }
434 }
435 }
436 #endif
437
438 /* create a main window */
439 g_hwndMain = CreateWindowEx( 0, g_szClassName,
440 g_szTitleName,
441 #ifdef _WIN32_WCE
442 x, y, cx, cy,
443 #else /* _WIN32_WCE */
444 WS_OVERLAPPEDWINDOW | WS_VISIBLE,
445 g_reginfo.rect.left,
446 g_reginfo.rect.top,
447 g_reginfo.rect.right -
448 g_reginfo.rect.left,
449 g_reginfo.rect.bottom -
450 g_reginfo.rect.top,
451 #endif /* _WIN32_WCE */
452 NULL, hMenu, g_hInst, NULL ) ;
453 if ( !g_hwndMain ) {
454 return FALSE;
455 }
456 GetClientRect( g_hwndMain, &rect ) ;
457
458 #ifdef COMMANDBANDS
459 {
460 int nCommandHeight = 0;
461
462 #ifdef _WIN32_WCE
463 #ifndef USE_SHMENU
464 #ifdef USE_COMMANDBANDS
465 CommandBands_Show(g_hwndCB, g_reginfo.showbands);
466 if (g_reginfo.showbands) {
467 nCommandHeight = CommandBands_Height(g_hwndCB);
468 }
469 #else
470 CommandBar_Show(g_hwndCB, g_reginfo.showbands);
471 if (g_reginfo.showbands) {
472 nCommandHeight = CommandBar_Height(g_hwndCB);
473 }
474 #endif /* USE_COMMANDBANDS */
475 #else /* if USE_SHMENU */
476 nCommandHeight = 0;
477 #endif /* USE_SHMENU */
478 #endif /* _WIN32_WCE */
479 rect.top += nCommandHeight;
480 }
481 #endif /* COMMANDBANDS */
482
483 /* create a TTY window */
484 g_hwndTty = CreateWindowEx( 0, CTRL_TTYVIEW,
485 TEXT(""),
486 WS_VISIBLE|WS_CHILD,
487 rect.left, rect.top,
488 rect.right - rect.left,
489 rect.bottom - rect.top,
490 g_hwndMain, (HMENU) IDC_TTY, g_hInst, NULL ) ;
491 if ( !g_hwndTty ) {
492 return FALSE;
493 }
494 /* configure the event for keyboard input notification */
495 SendMessage( g_hwndTty, TTYM_SETEVENT, (WPARAM) g_hevtGetChar, 0 ) ;
496
497 /* show the main window */
498 ShowWindow( g_hwndMain, nCmdShow ) ;
499 UpdateWindow( g_hwndMain ) ;
500 SetFocus( g_hwndTty ) ;
501
502 /* send a message to commence a thread */
503 PostMessage( g_hwndMain, WM_COMMAND, IDM_START, 0 ) ;
504 return TRUE ;
505 }
506
507 #ifdef COMMANDBANDS
508
509 #if defined(USE_COMMANDBANDS) && !defined(USE_SHMENU)
510 #define RB_ICON_CX 11
511 #define RB_ICON_CY 15
512
513 /* Initialize the images for rebar bands */
514 static HIMAGELIST
InitRebarImageLists(HWND hwnd)515 InitRebarImageLists(HWND hwnd)
516 {
517 HBITMAP hbmp;
518 HIMAGELIST res;
519
520 /* Create the image list for the item pictures */
521 res = ImageList_Create(RB_ICON_CX, RB_ICON_CY, ILC_COLOR | ILC_MASK, 2, 0);
522 /* Create two. No more will be added. */
523
524 if (res) {
525 /* Add the bitmaps to the list */
526 hbmp = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_REBAR));
527 if (hbmp) {
528 if (ImageList_AddMasked(res, hbmp, RGB(255, 0, 0)) != -1) {
529 /* Fail if not all the images were added */
530 if (3 <= ImageList_GetImageCount(res)) {
531 /* All is fine. But this specific condition does not check
532 anything. */
533 }
534 }
535 /* Clean up the GDI objects */
536 DeleteObject(hbmp);
537 }
538 else {
539 ImageList_Destroy(res);
540 res = (HIMAGELIST)NULL;
541 }
542 }
543 return res;
544 }
545 #endif /* defined(USE_COMMANDBANDS) && !defined(USE_SHMENU) */
546
547 #ifndef USE_SHMENU
548 /* It is very strange for me to define this by myself... */
549 #define NUM_STD_BITMAPS 15
550
551 #define TBSTATE_DISABLED 0
552
553 #define BTNID(x) ((x) - IDBN_MARK + NUM_STD_BITMAPS)
554
555 /* Tool buttons */
556 static TBBUTTON MGButton[] = {
557 #ifndef USE_COMMANDBANDS
558 /* For a space */
559 {0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0, 0, 0},
560 #endif
561 {BTNID(IDBN_MARK), IDC_MARK, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, -1},
562 {0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0, 0, 0},
563 {STD_CUT, IDC_CUT, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, -1},
564 {STD_COPY, IDC_COPY, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, -1},
565 {STD_PASTE, IDC_PASTE, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, -1},
566 {0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0, 0, 0},
567 {BTNID(IDBN_PRIOR), IDC_PRIOR, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, -1},
568 {BTNID(IDBN_NEXT), IDC_NEXT, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, -1},
569 };
570
571 /* Tool tips */
572 static int MGTips[] = {
573 IDS_MARK,
574 IDS_CUT,
575 IDS_COPY,
576 IDS_PASTE,
577 IDS_PRIOR,
578 IDS_NEXT,
579 };
580
581 #define NUM_TIPS (sizeof(MGTips) / sizeof(int))
582
583 #define MAX_TIP_STRING 32 /* Max string length for tool tips */
584
585 static LPTSTR *g_tooltips;
586
587 /* Create resource from Tool tip strings */
588 static LPTSTR *
LoadToolTips(int * tips)589 LoadToolTips(int *tips)
590 {
591 int *p, *ep;
592 LPTSTR *res, *ps;
593 TCHAR buf[MAX_TIP_STRING];
594
595 res = LocalAlloc(LPTR, sizeof(LPTSTR) * NUM_TIPS);
596 if (res) {
597 for (p = MGTips, ep = p + NUM_TIPS, ps = res ; p < ep ; p++, ps++) {
598 LoadString(g_hInst, *p, buf, MAX_TIP_STRING);
599 *ps = LocalAlloc(LPTR, sizeof(TCHAR) * (lstrlen(buf) + 1));
600 if (*ps) {
601 lstrcpy(*ps, buf);
602 }
603 else {
604 LPTSTR *q;
605
606 for (q = res ; q < ps ; q++) {
607 LocalFree(*q);
608 }
609 LocalFree(res);
610 return NULL;
611 }
612 }
613 }
614 g_tooltips = res;
615 return res;
616 }
617
618 /* Destroy Tool tip strings */
619 static void
FreeToolTips(void)620 FreeToolTips(void)
621 {
622 if (g_tooltips) {
623 LPTSTR *p, *ep;
624
625 for (p = g_tooltips, ep = p + NUM_TIPS ; p < ep ; p++) {
626 LocalFree(*p);
627 }
628 LocalFree(g_tooltips);
629 g_tooltips = NULL;
630 }
631 }
632
633 /* Create tool buttons */
634 static void
CreateToolButtons(HWND hwnd)635 CreateToolButtons(HWND hwnd)
636 {
637 #ifdef _WIN32_WCE
638 /* Are there any macro for "16"? */
639 CommandBar_AddBitmap(hwnd, HINST_COMMCTRL, IDB_STD_SMALL_COLOR,
640 NUM_STD_BITMAPS, 16, 16);
641 CommandBar_AddBitmap(hwnd, g_hInst, IDB_BUTTONS, 3, 16, 16);
642 CommandBar_AddButtons(hwnd, sizeof(MGButton)/sizeof(TBBUTTON), MGButton);
643
644 if (LoadToolTips(MGTips)) {
645 CommandBar_AddToolTips(hwnd, NUM_TIPS, g_tooltips);
646 }
647 #endif /* _WIN32_WCE */
648 }
649
650 #endif /* !USE_SHMENU */
651
652 #define IDD_REBAR 901 /* ID used at message processing */
653 #define SF_RBMENU 902
654 #define SF_RBBUTTON 903
655
656 #endif /* COMMANDBANDS */
657
658 void
MainWMCreate(HWND hWnd)659 MainWMCreate( HWND hWnd )
660 {
661 HICON hIcon ;
662
663 hIcon = (HICON) LoadImage( g_hInst, MAKEINTRESOURCE(IDI_APPICON),
664 IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR ) ;
665 if ( hIcon ) {
666 SendMessage( hWnd, WM_SETICON, FALSE, (LPARAM)hIcon ) ;
667 }
668
669 #ifdef _WIN32_WCE
670 #ifdef COMMANDBANDS
671 #ifndef USE_SHMENU
672 #ifndef USE_COMMANDBANDS
673 g_hwndCB = CommandBar_Create(g_hInst, hWnd, 1);
674 CommandBar_InsertMenubar(g_hwndCB, g_hInst, IDR_MAINMENU, 0);
675 CreateToolButtons(g_hwndCB);
676 #ifndef MG_FOR_PPC
677 /* add [X] Button */
678 CommandBar_AddAdornments(g_hwndCB, 0, 0);
679 #endif
680 #else /* if USE_COMMANDBANDS */
681 {
682 HWND hwnd2;
683 REBARBANDINFO arbbi[2];
684
685 /* Initialize images for Rebar bands */
686 g_himlrebar = InitRebarImageLists(hWnd);
687
688 g_hwndCB = CommandBands_Create(g_hInst, hWnd, IDD_REBAR,
689 RBS_VARHEIGHT | RBS_BANDBORDERS |
690 RBS_SMARTLABELS, g_himlrebar);
691
692 arbbi[0].cbSize = sizeof(REBARBANDINFO);
693 arbbi[0].fMask = RBBIM_STYLE | RBBIM_SIZE | RBBIM_IMAGE | RBBIM_ID;
694 arbbi[0].wID = SF_RBMENU;
695 arbbi[0].iImage = 0;
696 arbbi[0].fStyle = RBBS_NOGRIPPER;
697 arbbi[0].cx = 62;
698
699 arbbi[1].cbSize = sizeof(REBARBANDINFO);
700 arbbi[1].fMask = RBBIM_STYLE | RBBIM_SIZE | RBBIM_IMAGE | RBBIM_ID;
701 arbbi[1].wID = SF_RBBUTTON;
702 arbbi[1].iImage = 1;
703 arbbi[1].fStyle = 0;
704 arbbi[1].cx = 300;
705
706 if (g_reginfo.valid) { /* if valid info stored in registry */
707 arbbi[0].fStyle = g_reginfo.cbinfo[0].fStyle;
708 arbbi[1].fStyle = g_reginfo.cbinfo[1].fStyle;
709 arbbi[0].cx = g_reginfo.cbinfo[0].cxRestored;
710 arbbi[1].cx = g_reginfo.cbinfo[1].cxRestored;
711 }
712
713 CommandBands_AddBands(g_hwndCB, g_hInst, 2, arbbi);
714
715 /* Add Menu */
716 hwnd2 = CommandBands_GetCommandBar(g_hwndCB, 0);
717 CommandBar_InsertMenubar(hwnd2, g_hInst, IDR_MAINMENU, 0);
718
719 /* Add Buttons */
720 hwnd2 = CommandBands_GetCommandBar(g_hwndCB, 1);
721 CreateToolButtons(hwnd2);
722
723 #ifndef MG_FOR_PPC
724 /* add [X] Button */
725 CommandBands_AddAdornments(g_hwndCB, g_hInst, 0, 0);
726 #endif
727
728 if (g_reginfo.valid) { /* if valid info stored in registry */
729 if (g_reginfo.cbinfo[0].fMaximized) {
730 SendMessage(g_hwndCB, RB_MAXIMIZEBAND, (WPARAM)0, (LPARAM)0);
731 }
732 if (g_reginfo.cbinfo[1].fMaximized) {
733 SendMessage(g_hwndCB, RB_MAXIMIZEBAND, (WPARAM)1, (LPARAM)0);
734 }
735 }
736 }
737 #endif /* USE_COMMANDBANDS */
738 #else /* USE_SHMENU */
739 {
740 SHMENUBARINFO mbi;
741 RECT rc;
742
743 memset(&mbi, 0, sizeof(SHMENUBARINFO));
744 mbi.cbSize = sizeof(SHMENUBARINFO);
745 mbi.hwndParent = hWnd;
746 mbi.dwFlags = 0;
747 mbi.nToolBarId = IDR_PPCMENU;
748 mbi.hInstRes = g_hInst;
749 mbi.nBmpId = IDB_BUTTONS;
750 mbi.cBmpImages = 3;
751
752 if (SHCreateMenuBar(&mbi)) {
753 g_hwndCB = mbi.hwndMB;
754 }
755 else {
756 g_hwndCB = (HWND)NULL;
757 }
758
759 GetWindowRect(hWnd, &rc);
760 rc.bottom -= POCKETPC_MENU_HEIGHT;
761 if (g_hwndCB) {
762 MoveWindow(hWnd, rc.left, rc.top,
763 rc.right - rc.left, rc.bottom - rc.top, FALSE);
764 }
765 }
766 #endif /* USE_SHMENU */
767 #endif /* COMMANDBANDS */
768 #endif /* _WIN32_WCE */
769 }
770
771 #ifdef SPI_GETSIPINFO
772 static void
AdjustAgainstSIP(HWND hWnd,UINT param)773 AdjustAgainstSIP(HWND hWnd, UINT param)
774 {
775 SIPINFO sipinf;
776 BOOL sipres;
777
778 sipinf.cbSize = sizeof(sipinf);
779 sipinf.dwImDataSize = 0;
780 sipinf.pvImData = NULL;
781
782 #if _WIN32_WCE >= 210
783 sipres = SipGetInfo(&sipinf);
784 #else
785 sipres = SHSipInfo(SPI_GETSIPINFO, param, &sipinf, 0);
786 #endif
787
788 if (sipres) {
789 RECT winrect;
790
791 GetWindowRect(hWnd, &winrect);
792 if (!EqualRect(&winrect, &sipinf.rcVisibleDesktop)) {
793 int shmenuheight = 0;
794
795 #ifdef USE_SHMENU
796 if (!(sipinf.fdwFlags & SIPF_ON)) {
797 shmenuheight = POCKETPC_MENU_HEIGHT;
798 }
799 #endif /* USE_SHMENU */
800
801 MoveWindow(hWnd,
802 sipinf.rcVisibleDesktop.left,
803 sipinf.rcVisibleDesktop.top,
804 sipinf.rcVisibleDesktop.right -
805 sipinf.rcVisibleDesktop.left,
806 sipinf.rcVisibleDesktop.bottom -
807 sipinf.rcVisibleDesktop.top - shmenuheight, FALSE);
808 }
809 }
810 }
811 #endif /* SPI_GETSIPINFO */
812
813 static void
AdjustPane(HWND hwnd)814 AdjustPane(HWND hwnd)
815 {
816 RECT rect;
817 #ifdef _WIN32_WCE
818 #ifdef COMMANDBANDS
819 int nCommandHeight;
820 #endif /* COMMANDBANDS */
821 #endif /* _WIN32_WCE */
822
823 GetClientRect(g_hwndMain, &rect);
824
825 #ifdef _WIN32_WCE
826 #ifdef COMMANDBANDS
827 #ifndef USE_SHMENU
828 #ifndef USE_COMMANDBANDS
829 if (CommandBar_IsVisible(g_hwndCB)) {
830 nCommandHeight = CommandBar_Height(g_hwndCB);
831 }
832 #else /* if USE_COMMANDBANDS */
833 if (CommandBands_IsVisible(g_hwndCB)) {
834 nCommandHeight = CommandBands_Height(g_hwndCB);
835 }
836 else {
837 nCommandHeight = 0;
838 }
839 #endif /* USE_COMMANDBANDS */
840 #else /* if USE_SHMENU */
841 nCommandHeight = 0;
842 #endif /* USE_SHMENU */
843 rect.top += nCommandHeight;
844 #endif /* COMMANDBANDS */
845 #endif /* _WIN32_WCE */
846
847 MoveWindow(g_hwndTty, rect.left, rect.top,
848 rect.right - rect.left,
849 rect.bottom - rect.top, TRUE);
850 }
851
852 int ConfigStartupFilePath(int, int);
853
854 /*
855 * WinProc for main window
856 */
857 LRESULT CALLBACK
MainWndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)858 MainWndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
859 {
860 #ifdef SPI_GETSIPINFO
861 static BOOL SIPChanged = FALSE;
862 #endif
863 DWORD threadID ;
864
865 switch ( message ) {
866 case WM_CREATE:
867 MainWMCreate( hWnd ) ;
868 break ;
869 case WM_CLOSE:
870 SendMessage(g_hwndTty, TTYM_COMMAND,
871 (WPARAM)IDC_CLOSE, (LPARAM)NULL);
872 break ;
873 case WM_DESTROY:
874 #ifdef CTRLMAP
875 if (g_ctrlmap) {
876 /* send ctrl key `up' event in order to prevent
877 ctrl key to be kept in a state of `depressed' */
878 keybd_event(VK_CONTROL, 0, KEYEVENTF_KEYUP, 0);
879 }
880 #endif
881 #if defined(COMMANDBANDS) && !defined(USE_SHMENU)
882 #ifdef _WIN32_WCE
883 #ifdef USE_COMMANDBANDS
884 g_reginfo.cbinfo[0].cbSize = sizeof(COMMANDBANDSRESTOREINFO);
885 CommandBands_GetRestoreInformation(g_hwndCB,
886 SendMessage(g_hwndCB, RB_IDTOINDEX, (WPARAM)SF_RBMENU, (LPARAM)0),
887 g_reginfo.cbinfo);
888 CommandBands_GetRestoreInformation(g_hwndCB,
889 SendMessage(g_hwndCB, RB_IDTOINDEX, (WPARAM)SF_RBBUTTON,
890 (LPARAM)0), g_reginfo.cbinfo + 1);
891 /* Is "Destroy" necessary?
892 No. Because there are no CommandBands_Destroy()!? */
893 #else /* if !USE_COMMANDBANDS */
894 CommandBar_Destroy(g_hwndCB);
895 #endif /* !USE_COMMANDBANDS */
896 #endif /* _WIN32_WCE */
897 /* Free Tool Tip strings */
898 FreeToolTips();
899 #endif /* COMMANDBANDS && !USE_SHMENU */
900
901 #ifndef _WIN32_WCE
902 if (!g_reginfo.maximized)
903 GetWindowRect(g_hwndMain, &g_reginfo.rect);
904 #endif /* _WIN32_WCE */
905 #ifdef USE_REGINFO
906 /* Store settings to registry db */
907 g_reginfo.valid = TRUE;
908 RegSetBinary(HKEY_CURRENT_USER, NGREGKEY, NGPREVPOSVAL,
909 (LPBYTE)&g_reginfo, sizeof(g_reginfo));
910 #endif
911
912 #ifdef _WIN32_WCE
913 #if defined(COMMANDBANDS) && defined(USE_COMMANDBANDS) \
914 && !defined(USE_SHMENU)
915 if (g_himlrebar) { /* Destroy Image List */
916 ImageList_Destroy(g_himlrebar);
917 g_himlrebar = NULL;
918 }
919 #endif
920 #else /* not _WIN32_WCE */
921 /* Destroy Menu */
922 if (GetMenu(hWnd)) {
923 DestroyMenu(GetMenu(hWnd));
924 }
925 #endif
926 g_bExit = TRUE ;
927 Sleep( 1000 ) ;
928 PostQuitMessage( 0 ) ;
929 break ;
930 case WM_SETFOCUS:
931 #ifdef SPI_GETSIPINFO
932 AdjustAgainstSIP(hWnd, 0);
933 SIPChanged = FALSE;
934 #endif
935 SetFocus( g_hwndTty ) ;
936 break ;
937
938 #if !defined(_WIN32_WCE) || 200 <= _WIN32_WCE
939 case WM_SIZE:
940 switch (wParam) {
941 case SIZE_MAXIMIZED:
942 case SIZE_RESTORED:
943 AdjustPane(g_hwndMain);
944 #ifndef _WIN32_WCE
945 /* the following processing is intended to save the
946 previous window position */
947 g_reginfo.maximized = (wParam == SIZE_MAXIMIZED);
948 #endif
949 break;
950
951 default:
952 break;
953 }
954 return 0;
955 #endif
956
957 case WM_COMMAND:
958 switch ( GET_WM_COMMAND_ID( wParam, lParam ) ) {
959 case IDM_START:
960 g_hThread = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE) ThreadMain, 0, 0, &threadID ) ;
961 if ( g_hThread != NULL ) {
962 CloseHandle( g_hThread ) ;
963 break ;
964 }
965 //
966 case IDM_EXIT:
967 DestroyWindow(hWnd);
968 break ;
969
970 case IDC_OPTION:
971 ConfigStartupFilePath(0, 0);
972 break;
973
974 default:
975 SendMessage(g_hwndTty, TTYM_COMMAND, wParam, lParam);
976 break;
977 }
978 break ;
979
980 #ifdef SPI_GETSIPINFO
981 case WM_SETTINGCHANGE:
982 switch (wParam) {
983 case SPI_SETSIPINFO:
984 case SPI_SETCURRENTIM:
985 if (GetActiveWindow())
986 AdjustAgainstSIP(hWnd, (UINT)lParam);
987 else
988 SIPChanged = TRUE;
989 break;
990 #endif
991
992 case WM_NOTIFY:
993 switch(((LPNMHDR)lParam)->code) {
994 #ifdef RBN_HEIGHTCHANGE
995 /* The height of Rebar has changed */
996 case RBN_HEIGHTCHANGE:
997 AdjustPane(hWnd);
998 break;
999 #endif
1000 }
1001 break;
1002 default:
1003 return DefWindowProc( hWnd, message, wParam, lParam ) ;
1004 }
1005 return 0 ;
1006 }
1007
1008 int
1009 Kbhit( void )
1010 {
1011 return SendMessage( g_hwndTty, TTYM_KBHIT, 0, 0 ) ? 1 : 0 ;
1012 }
1013
1014 int
1015 KbhitSleep( DWORD sec )
1016 {
1017 WaitForSingleObject( g_hevtGetChar, sec * 1000 ) ;
1018 if ( g_bExit ) {
1019 ExitThread( 0 ) ;
1020 return FALSE ;
1021 }
1022 return Kbhit() ;
1023 }
1024
1025 int
1026 GetChar( void )
1027 {
1028 int c ;
1029
1030 while ( 1 ) {
1031 while (1) {
1032 extern VOID MouseEvent pro((int, int, int));
1033 c = SendMessage(g_hwndTty, TTYM_GETWINDOWEVENT, 0, 0);
1034 if (c < 0) {
1035 break;
1036 }
1037 else {
1038 switch (c & TTY_WM_MASK) {
1039 case TTY_WM_MOUSE:
1040 MouseEvent(0, (c >> 4) & 0x3fff, (c >> 18) & 0x3fff);
1041 break;
1042
1043 #if !defined(_WIN32_WCE) || 200 <= _WIN32_WCE
1044 case TTY_WM_RESIZE:
1045 {
1046 extern int refresh pro((int, int));
1047 refresh(FFRAND, 0); /* Very easy way... */
1048 }
1049 break;
1050 #endif
1051
1052 #ifdef DROPFILES /* 00.07.07 by sahf */
1053 case TTY_WM_DROPFILES:
1054 {
1055 HLOCAL hMemory;
1056 extern VOID DropEvent pro((const char *, int));
1057 /* hMemory got filename buffer address... */
1058 c = SendMessage( g_hwndTty, TTYM_DROPFILES, 0, (LPARAM)&hMemory );
1059 if ( c == -1 ) {
1060 break ;
1061 }
1062 DropEvent((const char *)hMemory, c);
1063 LocalFree(hMemory); /* allocated in ttyctrl.cpp */
1064 }
1065 break;
1066 #endif /* DROPFILES */
1067 }
1068 }
1069 }
1070 c = SendMessage( g_hwndTty, TTYM_GETCHAR, 0, 0 ) ;
1071 if ( c != -1 ) {
1072 break ;
1073 }
1074 WaitForSingleObject( g_hevtGetChar, INFINITE ) ;
1075 if ( g_bExit ) {
1076 ExitThread( 0 ) ;
1077 break ;
1078 }
1079 }
1080 ResetEvent( g_hevtGetChar ) ;
1081 return c ;
1082 }
1083
1084 void
1085 GotoXY( int x, int y )
1086 {
1087 SendMessage( g_hwndTty, TTYM_GOTOXY, MAKEWPARAM( y, x ), 0 ) ;
1088 }
1089
1090 void
1091 EraseEOL( void )
1092 {
1093 SendMessage( g_hwndTty, TTYM_ERASEEOL, 0, 0 ) ;
1094 }
1095
1096 void
1097 EraseEOP( void )
1098 {
1099 SendMessage( g_hwndTty, TTYM_ERASEEOP, 0, 0 ) ;
1100 }
1101
1102 void
1103 PutChar( char c )
1104 {
1105 SendMessage( g_hwndTty, TTYM_PUTCHAR, (WPARAM) c, 0 ) ;
1106 }
1107
1108 void
1109 PutKChar( char c1, char c2 )
1110 {
1111 SendMessage(g_hwndTty, TTYM_PUTKCHAR, MAKEWPARAM(c2, c1), 0);
1112 }
1113
1114 void
1115 PutLine( int y, unsigned char *sjis, short color )
1116 {
1117 SendMessage( g_hwndTty, TTYM_PUTLINE, MAKEWPARAM( color, y ), (LPARAM) sjis ) ;
1118 }
1119
1120 void
1121 Flush( void )
1122 {
1123 SendMessage( g_hwndTty, TTYM_FLUSH, 0, 0 ) ;
1124 }
1125
1126 void
1127 GetWH( int *w, int *h )
1128 {
1129 DWORD ret ;
1130
1131 ret = SendMessage( g_hwndTty, TTYM_GETWH, 0, 0 ) ;
1132 *w = HIWORD( ret ) ;
1133 *h = LOWORD( ret ) ;
1134 }
1135
1136 void
1137 Exit( int code )
1138 {
1139 RaiseException( EXCEPTION_QUIT, 0, 0, 0 ) ;
1140 }
1141
1142 void
1143 MessageOut( LPCSTR buf )
1144 {
1145 sjis2unicode( buf, MessageBuf, sizeof MessageBuf ) ;
1146 MessageBox( g_hwndMain, MessageBuf, MGTITLE, MB_OK ) ;
1147 }
1148
1149 /*
1150 * Command line related procedure
1151 */
1152 static void
1153 cmdline2args( LPSTR cmdline, int *argc, char **argv )
1154 {
1155 CHAR c ;
1156 BOOL f_skip = TRUE, f_quote = FALSE ;
1157
1158 argv[ 0 ] = "" ;
1159 *argc = 1 ;
1160 while ( c = *cmdline ) {
1161 if ( f_skip ) {
1162 if ( !(c == ' ' || c == '\t') ) {
1163 if ( c == '"' ) {
1164 f_quote = TRUE ;
1165 cmdline ++ ;
1166 }
1167 argv[ (*argc) ++ ] = cmdline ;
1168 f_skip = FALSE ;
1169 }
1170 } else {
1171 if ( f_quote ) {
1172 if ( c == '"' ) {
1173 f_quote = FALSE ;
1174 *cmdline = 0 ;
1175 f_skip = TRUE ;
1176 }
1177 } else if ( (c == ' ' || c == '\t') ) {
1178 *cmdline = 0 ;
1179 f_skip = TRUE ;
1180 }
1181 }
1182 cmdline ++ ;
1183 }
1184 }
1185
1186 /*
1187 * main routine for a thread
1188 */
1189 static void
1190 ThreadMain( void )
1191 {
1192 __try {
1193 Main( g_dwArgc, g_szArgv ) ;
1194 } __except ( GetExceptionCode() == EXCEPTION_QUIT ) {
1195 // do nothing
1196 }
1197 SendMessage( g_hwndMain, WM_COMMAND, IDM_EXIT, 0 ) ;
1198 ExitThread( 0 ) ;
1199 }
1200
1201 #ifdef FEPCTRL
1202 #define fep_init() /* nothing to do */
1203 #define fep_term() /* nothing to do */
1204
1205 static int fepctrl = FALSE; /* FEP control enable flag */
1206 static int fepmode = TRUE; /* now FEP mode */
1207
1208 static BOOL g_ime_prevopened;
1209
1210 fepmode_on()
1211 {
1212 #ifndef USE_KCTRL
1213 if (fepctrl && !fepmode) {
1214 HIMC hIMC = ImmGetContext(g_hwndTty);
1215 if (hIMC) {
1216 ImmSetOpenStatus(hIMC, g_ime_prevopened);
1217 ImmReleaseContext(g_hwndTty, hIMC);
1218 }
1219 fepmode = TRUE;
1220 }
1221 #endif
1222 return 0;
1223 }
1224
1225 /* The following fepmode_off() provides a doubled fepmode_off()
1226 feature. That is, the second call for the fepmode_off() is
1227 expected to change the previous fep mode as off, without doing any
1228 actual fep control since the fep mode has been already turned off
1229 by the first call of the function. So, the succeeding fepmode_on()
1230 will not turn on the fep mode even if the previous fep mode was on
1231 before the first call of fepmode_off().
1232
1233 By Tillanosoft, Mar 21, 1999 */
1234 fepmode_off()
1235 {
1236 #ifndef USE_KCTRL
1237 if (fepctrl) {
1238 if (fepmode) {
1239 HIMC hIMC = ImmGetContext(g_hwndTty);
1240 if (hIMC) {
1241 g_ime_prevopened = ImmGetOpenStatus(hIMC);
1242 if (g_ime_prevopened)
1243 ImmSetOpenStatus(hIMC, FALSE);
1244 ImmReleaseContext(g_hwndTty, hIMC);
1245 }
1246 fepmode = FALSE;
1247 }
1248 else {
1249 g_ime_prevopened = FALSE;
1250 }
1251 }
1252 #endif
1253 return 0;
1254 }
1255
1256 fepmode_set(f, n)
1257 {
1258 register int s;
1259 char buf[NFILEN];
1260 /* extern int ereply(); *//* declared in def.h */
1261
1262 if (f & FFARG) {
1263 n = (n > 0);
1264 }
1265 else {
1266 if ((s = ereply("FEP Control: ", buf, NFILEN)) != TRUE)
1267 return (s);
1268 if (ISDIGIT(buf[0]) || buf[0] == '-')
1269 n = (atoi(buf) > 0);
1270 else if (buf[0] == 't' || buf[0] == 'T')
1271 n = TRUE;
1272 else /* if (buf[0] == 'n' || buf[0] == 'N') */
1273 n = FALSE;
1274 }
1275
1276 if (!fepctrl && n) {
1277 fepmode = TRUE;
1278 }
1279 else if (fepctrl && !n) {
1280 /* nothing to do */
1281 }
1282 fepctrl = n;
1283
1284 return TRUE;
1285 }
1286
1287 fepmode_chg(f, n)
1288 {
1289 fepctrl = !fepctrl;
1290 if (fepctrl) {
1291 fepmode = TRUE;
1292 }
1293 return TRUE;
1294 }
1295
1296 int
1297 fepmode_toggle( int f, int n )
1298 {
1299 #ifdef USE_KCTRL
1300 Fep_Execute( g_hwndMain ) ;
1301 return TRUE ;
1302 #else /* if !USE_KCTRL */
1303 HIMC hIMC = ImmGetContext(g_hwndTty);
1304 if (hIMC) {
1305 BOOL ime_open = ImmGetOpenStatus(hIMC);
1306 g_ime_prevopened = !ime_open;
1307 ImmSetOpenStatus(hIMC, !ime_open);
1308 ImmReleaseContext(g_hwndTty, hIMC);
1309 }
1310 return TRUE;
1311 #endif
1312 }
1313 #endif /* FEPCTRL */
1314
1315 #ifdef KANJI
1316 #define etos(c1, c2) \
1317 {\
1318 c1 &= 0x7f;\
1319 c2 &= 0x7f;\
1320 if(c1 >= 0x5f)\
1321 c1 += 0x80;\
1322 if((c1 % 2) == 0) {\
1323 c1 = (c1 - 0x30) / 2 + 0x88;\
1324 c2 += 0x7e;\
1325 } else {\
1326 if(c2 >= 0x60)\
1327 c2 += 0x01;\
1328 c1 = (c1 - 0x31) / 2 + 0x89;\
1329 c2 += 0x1f;\
1330 }\
1331 c1 &= 0xff;\
1332 c2 &= 0xff;\
1333 }
1334 #endif
1335
1336 void
1337 #ifdef HANKANA /* 92.11.21 by S.Sasaki */
1338 putline( int row, int column, unsigned char *s, unsigned char *t, short color )
1339 #else
1340 putline(int row, int column, unsigned char *s, short color)
1341 #endif
1342 {
1343 #ifdef KANJI
1344 int c1 = 0, c2;
1345 #ifdef HANKANA
1346 unsigned char *ccp1;
1347 #endif
1348 #endif
1349 int c;
1350 unsigned char sjis[ 256 ], *dst, *cp1, *cp2;
1351
1352 dst = sjis ;
1353 cp1 = &s[0] ;
1354 cp2 = &s[ncol] ;
1355 #ifdef HANKANA
1356 ccp1 = &t[0] ;
1357 #endif
1358 while ( cp1 != cp2 ) {
1359 c = *cp1 ++ ;
1360 #ifdef KANJI
1361 #ifdef HANKANA
1362 c2 = *ccp1 ++ ;
1363 #endif
1364 if ( c1 ) {
1365 etos( c1, c ) ;
1366 *dst++ = c1 ;
1367 *dst++ = c ;
1368 c1 = 0 ;
1369 #ifdef HANKANA
1370 } else if ( (c & 0xFF) == 0x8E && c2 != 0 ) {
1371 *dst++ = c2 ;
1372 #endif
1373 } else if ( ISKANJI( c ) ) {
1374 c1 = c ;
1375 } else
1376 #endif
1377 *dst++ = c ;
1378 }
1379 *dst = 0 ;
1380 PutLine(row, sjis, (short)(color == CMODE ? 1 : 0));
1381 }
1382
1383 #if defined(COMMANDBANDS) && !defined(USE_SHMENU)
1384 static BOOL CALLBACK
1385 ViewProc(HWND hDlg, UINT message, UINT wParam, LONG lParam)
1386 {
1387 switch (message) {
1388 case WM_INITDIALOG:
1389 Button_SetCheck(GetDlgItem(hDlg, IDC_SHOWMENUBAR), g_reginfo.showbands);
1390 return 1;
1391
1392 case WM_COMMAND:
1393 #if 0
1394 switch (LOWORD(wParam)) {
1395 case IDC_SHOWMENUBAR:
1396 break;
1397 }
1398 #endif
1399 return 0;
1400
1401 case WM_NOTIFY:
1402 switch (((LPNMHDR)lParam)->code) {
1403 case PSN_SETACTIVE: /* Visit this page */
1404 SetWindowLong(hDlg, DWL_MSGRESULT, 0);
1405 return TRUE;
1406
1407 case PSN_APPLY:
1408 {
1409 BOOL newvalue;
1410 newvalue = Button_GetCheck(GetDlgItem(hDlg, IDC_SHOWMENUBAR));
1411 if (g_reginfo.showbands != newvalue) {
1412 g_reginfo.showbands = newvalue;
1413 #ifdef _WIN32_WCE
1414 #ifdef USE_COMMANDBANDS
1415 CommandBands_Show(g_hwndCB, newvalue);
1416 #else
1417 CommandBar_Show(g_hwndCB, newvalue);
1418 #endif
1419 AdjustPane(g_hwndMain);
1420 #endif
1421 }
1422 }
1423 SetWindowLong(hDlg, DWL_MSGRESULT, PSNRET_NOERROR);
1424 return TRUE;
1425
1426 case PSN_KILLACTIVE: /* Go away from this page */
1427 SetWindowLong(hDlg, DWL_MSGRESULT, FALSE);
1428 return(TRUE);
1429
1430 case PSN_RESET: /* CANCEL Button */
1431 return TRUE;
1432 }
1433
1434 default:
1435 return 0;
1436 }
1437 }
1438 #endif /* defined(COMMANDBANDS) && !defined(USE_SHMENU) */
1439
1440 #ifndef NO_STARTUP
1441 /* Dialog Proc to change the startup file path */
1442
1443 #define MAXFILENAMESIZE 160
1444 #define INIFILEFILTER TEXT("INI file (*.ini)\0*.ini\0All files (*.*)\0*.*\0")
1445
1446 static OPENFILENAME templateofn = {
1447 sizeof(OPENFILENAME), NULL, 0, INIFILEFILTER, NULL, 0, 0,
1448 NULL, 0, NULL, 0, NULL, TEXT("INI File"),
1449 OFN_HIDEREADONLY, 0, 0, NULL, 0, NULL, NULL};
1450
1451 static BOOL CALLBACK
1452 StartFileProc(HWND hDlg, UINT message, UINT wParam, LONG lParam)
1453 {
1454 TCHAR unicode[MAX_PATH];
1455 DWORD foo = sizeof(unicode);
1456
1457 switch (message) {
1458 case WM_INITDIALOG:
1459 if (RegQueryString(HKEY_CURRENT_USER, NGREGKEY, NGSTARTUPFILEVAL,
1460 unicode, &foo) == ERROR_SUCCESS) {
1461 SetDlgItemText(hDlg, IDC_STARTUPFILE, unicode);
1462 }
1463 return 1;
1464
1465 case WM_COMMAND:
1466 switch (LOWORD(wParam)) {
1467 case IDC_FILEOPENDLG:
1468 {
1469 OPENFILENAME ofn;
1470 TCHAR filename[MAXFILENAMESIZE];
1471 int stat;
1472
1473 ofn = templateofn;
1474 ofn.lpstrFile = filename;
1475 ofn.nMaxFile = MAXFILENAMESIZE;
1476 ofn.lpstrFile[0] = (TCHAR)0;
1477 stat = GetOpenFileName(&ofn);
1478 if (stat) {
1479 SetDlgItemText(hDlg, IDC_STARTUPFILE, ofn.lpstrFile);
1480 }
1481 }
1482 break;
1483
1484 #ifndef _WIN32_WCE
1485 case IDC_STARTUPFILE:
1486 switch (HIWORD(wParam)) {
1487 case EN_CHANGE:
1488 SendMessage(GetParent(hDlg), PSM_CHANGED, (WPARAM)(HWND)hDlg, 0L);
1489 break;
1490 }
1491 break;
1492 #endif
1493 }
1494 return 0;
1495
1496 case WM_NOTIFY:
1497 switch (((LPNMHDR)lParam)->code) {
1498 case PSN_SETACTIVE: /* Visit this page */
1499 SetWindowLong(hDlg, DWL_MSGRESULT, 0);
1500 return TRUE;
1501
1502 case PSN_APPLY:
1503 GetDlgItemText(hDlg, IDC_STARTUPFILE, unicode, foo / sizeof(TCHAR));
1504 RegSetString(HKEY_CURRENT_USER, NGREGKEY, NGSTARTUPFILEVAL, unicode);
1505 SetWindowLong(hDlg, DWL_MSGRESULT, PSNRET_NOERROR);
1506 return TRUE;
1507
1508 case PSN_KILLACTIVE: /* Go away from this page */
1509 SetWindowLong(hDlg, DWL_MSGRESULT, FALSE);
1510 return(TRUE);
1511
1512 case PSN_RESET: /* CANCEL Button */
1513 return TRUE;
1514 }
1515
1516 default:
1517 return 0;
1518 }
1519 }
1520 #endif
1521
1522 #if defined(CTRLMAP) || defined(JAPANESE_KEYBOARD)
1523 static BOOL CALLBACK
1524 KeyMapProc(HWND hDlg, UINT message, UINT wParam, LONG lParam)
1525 {
1526 DWORD val;
1527
1528 switch (message) {
1529 case WM_INITDIALOG:
1530 #ifdef CTRLMAP
1531 val = RegQueryDWord(HKEY_CURRENT_USER, NGREGKEY,
1532 NGCTRLKEYMAPVAL) ? TRUE : FALSE;
1533 Button_SetCheck(GetDlgItem(hDlg, IDC_CONTROLMAP), val);
1534 #else /* if !CTRLMAP */
1535 EnableWindow(GetDlgItem(hDlg, IDC_CONTROLMAP), FALSE);
1536 #endif /* !CTRLMAP */
1537
1538 #ifdef JAPANESE_KEYBOARD
1539 val = RegQueryDWord(HKEY_CURRENT_USER, NGREGKEY, NGKEYBOARDLOCALEVAL);
1540 switch (val) {
1541 case NGKEYBOARD_US:
1542 val = BST_UNCHECKED;
1543 break;
1544 case NGKEYBOARD_JP:
1545 val = BST_CHECKED;
1546 break;
1547 default:
1548 case 0:
1549 val = BST_CHECKED;
1550 break;
1551 }
1552 Button_SetCheck(GetDlgItem(hDlg, IDC_KEYBOARDLOCALE), val);
1553 #else /* if !JAPANESE_KEYBOARD */
1554 EnableWindow(GetDlgItem(hDlg, IDC_KEYBOARDLOCALE), FALSE);
1555 #endif /* !JAPANESE_KEYBOARD */
1556 return 1;
1557
1558 case WM_COMMAND:
1559 switch (LOWORD(wParam)) {
1560 #if 0 /* Did not work as I supposed. */
1561 case IDC_ALT:
1562 alt = !alt;
1563 Button_SetState(GetDlgItem(hDlg, IDC_ALT), alt);
1564 if (alt) {
1565 keybd_event(VK_MENU, 0, 0, 0);
1566 }
1567 else {
1568 keybd_event(VK_MENU, 0, KEYEVENTF_KEYUP, 0);
1569 }
1570 break;
1571 #endif
1572 #if defined(CTRLMAP) && !defined(_WIN32_WCE)
1573 case IDC_CONTROLMAP:
1574 SendMessage(GetParent(hDlg), PSM_CHANGED, (WPARAM)(HWND)hDlg, 0L);
1575 break;
1576 #endif
1577 }
1578 return 0;
1579
1580 case WM_NOTIFY:
1581 switch (((LPNMHDR)lParam)->code) {
1582 case PSN_SETACTIVE: /* Visit this page */
1583 SetWindowLong(hDlg, DWL_MSGRESULT, 0);
1584 return TRUE;
1585
1586 case PSN_APPLY:
1587 #ifdef CTRLMAP
1588 val = Button_GetCheck(GetDlgItem(hDlg, IDC_CONTROLMAP));
1589 RegSetDWord(HKEY_CURRENT_USER, NGREGKEY, NGCTRLKEYMAPVAL, val);
1590 g_ctrlmap = val;
1591 #endif
1592 #ifdef JAPANESE_KEYBOARD
1593 val = Button_GetCheck(GetDlgItem(hDlg, IDC_KEYBOARDLOCALE)) ?
1594 NGKEYBOARD_JP : NGKEYBOARD_US;
1595 RegSetDWord(HKEY_CURRENT_USER, NGREGKEY, NGKEYBOARDLOCALEVAL, val);
1596 g_keyboardlocale = val;
1597 SendMessage(g_hwndTty, TTYM_SETKEYBOARDLOCALE, (WPARAM)val, 0);
1598 #endif
1599 SetWindowLong(hDlg, DWL_MSGRESULT, PSNRET_NOERROR);
1600 return TRUE;
1601
1602 case PSN_KILLACTIVE: /* Go away from this page */
1603 SetWindowLong(hDlg, DWL_MSGRESULT, FALSE);
1604 return(TRUE);
1605
1606 case PSN_RESET: /* CANCEL Button */
1607 return TRUE;
1608 }
1609
1610 default:
1611 return 0;
1612 }
1613 }
1614 #endif
1615
1616 struct _beepsounds {
1617 UINT title;
1618 UINT val;
1619 } beepsounds[] = {
1620 {IDS_OK, MB_OK},
1621 {IDS_ICONASTERISK, MB_ICONASTERISK},
1622 {IDS_ICONEXCLAMATION, MB_ICONEXCLAMATION},
1623 {IDS_ICONHAND, MB_ICONHAND},
1624 {IDS_ICONQUESTION, MB_ICONQUESTION}
1625 };
1626
1627 #define NUMBEEPSOUNDS (sizeof(beepsounds) / sizeof(struct _beepsounds))
1628
1629 #define WAVFILEFILTER TEXT("Wave file (*.wav)\0*.wav\0All files (*.*)\0*.*\0")
1630
1631 static OPENFILENAME templatewaveofn = {
1632 sizeof(OPENFILENAME), NULL, 0, WAVFILEFILTER, NULL, 0, 0,
1633 NULL, 0, NULL, 0, TEXT("\\Windows"), TEXT("Wave File"),
1634 OFN_HIDEREADONLY, 0, 0, NULL, 0, NULL, NULL};
1635
1636 static void
1637 SetBeepRadio(HWND hDlg, BOOL messagebeep)
1638 {
1639 EnableWindow(GetDlgItem(hDlg, IDC_MESSAGECOMBO), messagebeep);
1640 EnableWindow(GetDlgItem(hDlg, IDC_SOUNDFILE), !messagebeep);
1641 EnableWindow(GetDlgItem(hDlg, IDC_SOUNDBUTTON), !messagebeep);
1642 }
1643
1644 static void
1645 SetBeepButtons(HWND hDlg, DWORD dobeep)
1646 {
1647 EnableWindow(GetDlgItem(hDlg, IDC_PLAY), dobeep);
1648 EnableWindow(GetDlgItem(hDlg, IDC_MESSAGEBEEP), dobeep);
1649 EnableWindow(GetDlgItem(hDlg, IDC_MESSAGECOMBO), dobeep);
1650
1651 #ifdef TARGET_WCEVER_IS_100
1652 EnableWindow(GetDlgItem(hDlg, IDC_PLAYSOUND), FALSE);
1653 EnableWindow(GetDlgItem(hDlg, IDC_SOUNDFILE), FALSE);
1654 EnableWindow(GetDlgItem(hDlg, IDC_SOUNDBUTTON), FALSE);
1655 #else
1656 EnableWindow(GetDlgItem(hDlg, IDC_PLAYSOUND), dobeep);
1657 EnableWindow(GetDlgItem(hDlg, IDC_SOUNDFILE), dobeep);
1658 EnableWindow(GetDlgItem(hDlg, IDC_SOUNDBUTTON), dobeep);
1659 #endif
1660 if (dobeep) {
1661 /* dobeep == 1 means to use sndPlaySound(), not to use MessageBeep() */
1662 Button_SetCheck(GetDlgItem(hDlg, IDC_MESSAGEBEEP), dobeep != 1);
1663 Button_SetCheck(GetDlgItem(hDlg, IDC_PLAYSOUND), dobeep == 1);
1664 SetBeepRadio(hDlg, dobeep != 1);
1665 }
1666 }
1667
1668 static void
1669 BeepGetButtons(HWND hDlg, DWORD *beep, LPTSTR beepfile, int len)
1670 {
1671 DWORD val;
1672
1673 val = Button_GetCheck(GetDlgItem(hDlg, IDC_BEEP));
1674 if (val) {
1675 if (Button_GetCheck(GetDlgItem(hDlg, IDC_PLAYSOUND))) {
1676 *beep = 1;
1677 }
1678 else {
1679 DWORD sel;
1680 sel = SendMessage(GetDlgItem(hDlg, IDC_MESSAGECOMBO),
1681 CB_GETCURSEL, (WPARAM)0, (LPARAM)0);
1682 if (sel != CB_ERR) {
1683 *beep = beepsounds[sel].val + NG_WAVE_OFFSET;
1684 }
1685 }
1686 }
1687 else {
1688 *beep = 0;
1689 }
1690 GetDlgItemText(hDlg, IDC_SOUNDFILE, beepfile, len);
1691 }
1692
1693 static BOOL CALLBACK
1694 BeepProc(HWND hDlg, UINT message, UINT wParam, LONG lParam)
1695 {
1696 DWORD val;
1697 HWND hcb;
1698 struct _beepsounds *pb, *epb;
1699 TCHAR buf[128];
1700 UINT cursound, nth = 0;
1701
1702 switch (message) {
1703 case WM_INITDIALOG:
1704 /* initialize the combo box */
1705 cursound = g_beepsound - NG_WAVE_OFFSET;
1706 hcb = GetDlgItem(hDlg, IDC_MESSAGECOMBO);
1707 SendMessage(hcb, CB_RESETCONTENT, 0, 0);
1708 for (pb = beepsounds, epb = pb + NUMBEEPSOUNDS ; pb < epb ; pb++) {
1709 if (cursound == pb->val) {
1710 nth = pb - beepsounds;
1711 }
1712 LoadString(g_hInst, pb->title, buf, sizeof(buf) / sizeof(TCHAR));
1713 SendMessage(hcb, CB_ADDSTRING, 0, (LONG)buf);
1714 }
1715 SendMessage(hcb, CB_SETCURSEL, (WPARAM)nth, (LPARAM)0);
1716
1717 /* initialize the edit box */
1718 if (g_beepfile[0]) {
1719 SetDlgItemText(hDlg, IDC_SOUNDFILE, g_beepfile);
1720 }
1721
1722 /* set the current configuration for beep sounds */
1723 Button_SetCheck(GetDlgItem(hDlg, IDC_BEEP), g_beepsound);
1724 SetBeepButtons(hDlg, g_beepsound);
1725 return 1;
1726
1727 case WM_COMMAND:
1728 switch (LOWORD(wParam)) {
1729 case IDC_MESSAGEBEEP:
1730 case IDC_PLAYSOUND:
1731 SetBeepRadio(hDlg, LOWORD(wParam) == IDC_MESSAGEBEEP);
1732 #ifndef _WIN32_WCE
1733 SendMessage(GetParent(hDlg), PSM_CHANGED, (WPARAM)(HWND)hDlg, 0L);
1734 #endif
1735 break;
1736
1737 case IDC_BEEP:
1738 val = Button_GetCheck(GetDlgItem(hDlg, IDC_BEEP));
1739 if (val) {
1740 val = Button_GetCheck(GetDlgItem(hDlg, IDC_PLAYSOUND)) ? 1 : 2;
1741 }
1742 SetBeepButtons(hDlg, val);
1743 #ifndef _WIN32_WCE
1744 SendMessage(GetParent(hDlg), PSM_CHANGED, (WPARAM)(HWND)hDlg, 0L);
1745 #endif
1746 break;
1747
1748 case IDC_SOUNDBUTTON:
1749 {
1750 OPENFILENAME ofn;
1751 TCHAR filename[MAXFILENAMESIZE];
1752 int stat;
1753
1754 ofn = templatewaveofn;
1755 ofn.lpstrFile = filename;
1756 ofn.nMaxFile = MAXFILENAMESIZE;
1757 ofn.lpstrFile[0] = (TCHAR)0;
1758 #ifndef _WIN32_WCE
1759 #define MEDIA_FOLDER TEXT("\\Media")
1760 #define MEDIA_FOLDER_LEN (sizeof(MEDIA_FOLDER) / sizeof(TCHAR))
1761 {
1762 TCHAR initialdir[MAX_PATH];
1763 int len = GetWindowsDirectory(initialdir, MAX_PATH);
1764 if (0 < len) {
1765 if (len < MAX_PATH - MEDIA_FOLDER_LEN) {
1766 lstrcat(initialdir, MEDIA_FOLDER);
1767 }
1768 ofn.lpstrInitialDir = initialdir;
1769 }
1770 }
1771 #endif
1772 stat = GetOpenFileName(&ofn);
1773 if (stat) {
1774 SetDlgItemText(hDlg, IDC_SOUNDFILE, ofn.lpstrFile);
1775 #ifndef _WIN32_WCE
1776 SendMessage(GetParent(hDlg), PSM_CHANGED, (WPARAM)(HWND)hDlg, 0L);
1777 #endif
1778 }
1779 }
1780 break;
1781
1782 case IDC_PLAY:
1783 val = g_beepsound;
1784 lstrcpy(buf, g_beepfile);
1785 BeepGetButtons(hDlg, &g_beepsound,
1786 g_beepfile, sizeof(g_beepfile) / sizeof(TCHAR));
1787 ttbeep();
1788 g_beepsound = val;
1789 lstrcpy(g_beepfile, buf);
1790 break;
1791
1792 #ifndef _WIN32_WCE
1793 case IDC_MESSAGECOMBO:
1794 SendMessage(GetParent(hDlg), PSM_CHANGED, (WPARAM)(HWND)hDlg, 0L);
1795 break;
1796
1797 case IDC_SOUNDFILE:
1798 switch (HIWORD(wParam)) {
1799 case EN_CHANGE:
1800 SendMessage(GetParent(hDlg), PSM_CHANGED, (WPARAM)(HWND)hDlg, 0L);
1801 break;
1802 }
1803 break;
1804 #endif
1805 }
1806 return 0;
1807
1808 case WM_NOTIFY:
1809 switch (((LPNMHDR)lParam)->code) {
1810 case PSN_SETACTIVE: /* Visit this page */
1811 SetWindowLong(hDlg, DWL_MSGRESULT, 0);
1812 return TRUE;
1813
1814 case PSN_APPLY:
1815 BeepGetButtons(hDlg, &g_beepsound,
1816 g_beepfile, sizeof(g_beepfile) / sizeof(TCHAR));
1817 RegSetDWord(HKEY_CURRENT_USER, NGREGKEY, NGBEEPSOUNDVAL, g_beepsound);
1818 RegSetString(HKEY_CURRENT_USER, NGREGKEY, NGBEEPFILEVAL, g_beepfile);
1819 SetWindowLong(hDlg, DWL_MSGRESULT, PSNRET_NOERROR);
1820 return TRUE;
1821
1822 case PSN_KILLACTIVE: /* Go away from this page */
1823 SetWindowLong(hDlg, DWL_MSGRESULT, FALSE);
1824 return(TRUE);
1825
1826 case PSN_RESET: /* CANCEL Button */
1827 return TRUE;
1828 }
1829
1830 default:
1831 return 0;
1832 }
1833 }
1834
1835 #ifndef USE_KCTRL /* font configuration is not made functional for KCTRL */
1836 #define CONFIG_FONT
1837 #endif
1838
1839 #ifdef CONFIG_FONT
1840
1841 #ifdef KANJI
1842 #define REQUIRED_CHARSET SHIFTJIS_CHARSET
1843 #ifndef _WIN32_WCE
1844 #define REQUIRED_PITCH FIXED_PITCH
1845 #endif
1846 #else /* !KANJI */
1847 #define REQUIRED_PITCH FIXED_PITCH
1848 #endif /* !KANJI */
1849
1850 static int CALLBACK
1851 SetFontNames(CONST LOGFONT *lpelf, CONST TEXTMETRIC *lpntm,
1852 DWORD FontType, LPARAM lParam)
1853 {
1854 HWND hDlg = (HWND)lParam, hcb = GetDlgItem(hDlg, IDC_FONTNAME);
1855
1856 if ((lpelf->lfPitchAndFamily &
1857 (FF_ROMAN | FF_SWISS | FF_MODERN | FF_SCRIPT | FF_DECORATIVE)) ==
1858 FF_MODERN
1859 #ifdef REQUIRED_CHARSET
1860 && lpelf->lfCharSet == REQUIRED_CHARSET
1861 #endif
1862 #ifdef REQUIRED_PITCH
1863 && (lpelf->lfPitchAndFamily & REQUIRED_PITCH)
1864 #endif
1865 ) {
1866 SendMessage(hcb, CB_ADDSTRING, 0, (LONG)lpelf->lfFaceName);
1867 }
1868 return 1;
1869 }
1870
1871 static LPTSTR fontpoints[] = {
1872 TEXT("8"),
1873 TEXT("9"),
1874 TEXT("10"),
1875 TEXT("11"),
1876 TEXT("12"),
1877 TEXT("14"),
1878 TEXT("16"),
1879 TEXT("18"),
1880 TEXT("20"),
1881 TEXT("22"),
1882 TEXT("24"),
1883 TEXT("28"),
1884 TEXT("32")
1885 };
1886
1887 #define NUMPOINTS (sizeof(fontpoints) / sizeof(int))
1888
1889 #define MAX_LINESPACE 32
1890
1891 static void
1892 SetFontEntries(HWND hDlg)
1893 {
1894 HDC hdc;
1895 HWND hSpin;
1896 LPTSTR *p, *ep;
1897 TCHAR fontname[LF_FACESIZE];
1898 DWORD val;
1899
1900 hdc = GetDC(g_hwndTty);
1901 SendMessage(GetDlgItem(hDlg, IDC_FONTNAME), CB_RESETCONTENT, 0, 0);
1902 EnumFontFamilies(hdc, NULL, SetFontNames, (LPARAM)hDlg);
1903 ReleaseDC(g_hwndTty, hdc);
1904
1905 SendMessage(GetDlgItem(hDlg, IDC_POINT), CB_RESETCONTENT, 0, 0);
1906 for (p = fontpoints, ep = p + NUMPOINTS ; p < ep ; p++) {
1907 SendMessage(GetDlgItem(hDlg, IDC_POINT), CB_ADDSTRING, 0, (LONG)*p);
1908 }
1909
1910 /* Do something for spin (up-down) control */
1911 hSpin = GetDlgItem(hDlg, IDC_SPIN);
1912 SendMessage(hSpin, UDM_SETRANGE, (WPARAM)0,
1913 (LPARAM)MAKELONG((short)MAX_LINESPACE, (short)0));
1914 SendMessage(hSpin, UDM_SETPOS, (WPARAM)0,
1915 (LPARAM)MAKELONG((short)0, 0)); /* line space after (short) */
1916
1917 /* set the current configurations */
1918 val = sizeof(fontname);
1919 if (RegQueryString(HKEY_CURRENT_USER, NGREGKEY, NGFONTNAMEVAL,
1920 fontname, &val) == ERROR_SUCCESS) {
1921 SendMessage(GetDlgItem(hDlg, IDC_FONTNAME), CB_SELECTSTRING,
1922 (WPARAM)-1, (LPARAM)fontname);
1923 val = RegQueryDWord(HKEY_CURRENT_USER, NGREGKEY, NGFONTSIZEVAL);
1924 if (val > 0) {
1925 SetDlgItemInt(hDlg, IDC_POINT, val, FALSE);
1926 val = RegQueryDWord(HKEY_CURRENT_USER, NGREGKEY, NGLINESPACEVAL);
1927 SetDlgItemInt(hDlg, IDC_LINESPACE, val, FALSE);
1928 Button_SetCheck(GetDlgItem(hDlg, IDC_SPECIFY), TRUE);
1929 return;
1930 }
1931 }
1932 Button_SetCheck(GetDlgItem(hDlg, IDC_NOSPECIFY), TRUE);
1933 }
1934
1935 static void
1936 ApplyFontEntries(HWND hDlg)
1937 {
1938 DWORD point, linespace;
1939 TCHAR fontname[LF_FACESIZE];
1940
1941 if (Button_GetCheck(GetDlgItem(hDlg, IDC_SPECIFY))) {
1942 point = GetDlgItemInt(hDlg, IDC_POINT, NULL, FALSE);
1943 linespace = GetDlgItemInt(hDlg, IDC_LINESPACE, NULL, FALSE);
1944 GetDlgItemText(hDlg, IDC_FONTNAME, fontname, LF_FACESIZE);
1945
1946 RegSetString(HKEY_CURRENT_USER, NGREGKEY, NGFONTNAMEVAL, fontname);
1947 RegSetDWord(HKEY_CURRENT_USER, NGREGKEY, NGFONTSIZEVAL, point);
1948 RegSetDWord(HKEY_CURRENT_USER, NGREGKEY, NGLINESPACEVAL, linespace);
1949 }
1950 else {
1951 RegRemoveValue(HKEY_CURRENT_USER, NGREGKEY, NGFONTNAMEVAL);
1952 RegRemoveValue(HKEY_CURRENT_USER, NGREGKEY, NGFONTSIZEVAL);
1953 RegRemoveValue(HKEY_CURRENT_USER, NGREGKEY, NGLINESPACEVAL);
1954 }
1955
1956 /* To force the screen to be refreshed. */
1957 nrow = 4; /* This number (4) of rows may not be used... */
1958
1959 /* Then, notify the change to TTYCTRL */
1960 SendMessage(g_hwndTty, TTYM_FONTCHANGED, (WPARAM)0, (LPARAM)0);
1961 }
1962
1963 static BOOL CALLBACK
1964 FontProc(HWND hDlg, UINT message, UINT wParam, LONG lParam)
1965 {
1966 switch (message) {
1967 case WM_INITDIALOG:
1968 SetFontEntries(hDlg);
1969 return 1;
1970
1971 case WM_COMMAND:
1972 switch (LOWORD(wParam)) {
1973 #ifndef _WIN32_WCE
1974 case IDC_NOSPECIFY:
1975 case IDC_SPECIFY:
1976 case IDC_FONTNAME:
1977 case IDC_POINT:
1978 case IDC_LINESPACE:
1979 SendMessage(GetParent(hDlg), PSM_CHANGED, (WPARAM)(HWND)hDlg, 0L);
1980 break;
1981 #endif
1982 default:
1983 break;
1984 }
1985 return 0;
1986
1987 case WM_NOTIFY:
1988 switch (((LPNMHDR)lParam)->code) {
1989 case PSN_SETACTIVE: /* Visit this page */
1990 SetWindowLong(hDlg, DWL_MSGRESULT, 0);
1991 return TRUE;
1992
1993 case PSN_APPLY:
1994 ApplyFontEntries(hDlg);
1995 SetWindowLong(hDlg, DWL_MSGRESULT, PSNRET_NOERROR);
1996 return TRUE;
1997
1998 case PSN_KILLACTIVE: /* Go away from this page */
1999 SetWindowLong(hDlg, DWL_MSGRESULT, FALSE);
2000 return(TRUE);
2001
2002 case PSN_RESET: /* CANCEL Button */
2003 return TRUE;
2004 }
2005
2006 default:
2007 return 0;
2008 }
2009 }
2010
2011 #endif /* CONFIG_FONT */
2012
2013 #define MAX_PAGES 5
2014
2015 /*
2016 Add one property sheet page.
2017 */
2018
2019 static void
2020 AddPage(LPPROPSHEETHEADER ppsh, UINT id, DLGPROC pfn)
2021 {
2022 if (ppsh->nPages < MAX_PAGES) {
2023 PROPSHEETPAGE psp;
2024
2025 psp.dwSize = sizeof(psp);
2026 psp.dwFlags = PSP_DEFAULT;
2027 psp.hInstance = ppsh->hInstance;
2028 #ifdef __BORLANDC__
2029 psp.DUMMYUNIONNAME.pszTemplate = MAKEINTRESOURCE(id);
2030 #else
2031 psp.pszTemplate = MAKEINTRESOURCE(id);
2032 #endif
2033 psp.pfnDlgProc = pfn;
2034 psp.lParam = 0;
2035
2036 #ifdef __BORLANDC__
2037 ppsh->DUMMYUNIONNAME3.phpage[ppsh->nPages] = CreatePropertySheetPage(&psp);
2038 if (ppsh->DUMMYUNIONNAME3.phpage[ppsh->nPages]) {
2039 #else
2040 ppsh->phpage[ppsh->nPages] = CreatePropertySheetPage(&psp);
2041 if (ppsh->phpage[ppsh->nPages]) {
2042 #endif
2043 ppsh->nPages++;
2044 }
2045 }
2046 }
2047
2048 /*
2049 CreatePropertySheet creates a property sheet.
2050 */
2051
2052 static void
2053 CreatePropertySheet(HINSTANCE hInstance, HWND hwnd)
2054 {
2055 PROPSHEETHEADER psh;
2056 HPROPSHEETPAGE rPages[MAX_PAGES];
2057
2058 psh.hwndParent = hwnd;
2059 psh.dwSize = sizeof(psh);
2060 psh.dwFlags = 0;
2061 psh.hInstance = hInstance;
2062 #ifdef __BORLANDC__
2063 psh.DUMMYUNIONNAME.hIcon = NULL;
2064 #else
2065 psh.hIcon = NULL;
2066 #endif
2067 psh.pszCaption = MAKEINTRESOURCE(IDS_CONFIGNAME);
2068 psh.nPages = 0;
2069 #ifdef __BORLANDC__
2070 psh.DUMMYUNIONNAME2.nStartPage = 0;
2071 psh.DUMMYUNIONNAME3.phpage = rPages;
2072 #else
2073 psh.nStartPage = 0;
2074 psh.phpage = rPages;
2075 #endif
2076 psh.pfnCallback = NULL;
2077
2078 #if defined(_WIN32_WCE) && defined(COMMANDBANDS) && !defined(USE_SHMENU)
2079 AddPage(&psh, IDD_VIEW, ViewProc);
2080 #endif
2081 #ifndef NO_STARTUP
2082 AddPage(&psh, IDD_STARTUPFILE, StartFileProc);
2083 #endif
2084 #if defined(CTRLMAP) || defined(JAPANESE_KEYBOARD)
2085 AddPage(&psh, IDD_KEY, KeyMapProc);
2086 #endif
2087 AddPage(&psh, IDD_BEEP, BeepProc);
2088 #ifdef CONFIG_FONT
2089 AddPage(&psh, IDD_FONT, FontProc);
2090 #endif
2091
2092 PropertySheet(&psh);
2093 }
2094
2095
2096 /* change the path to store the path into the registry database of Win32 */
2097
2098 int
2099 ConfigStartupFilePath(int f, int n)
2100 {
2101 CreatePropertySheet(g_hInst, g_hwndTty);
2102 return TRUE;
2103 }
2104
2105