1 /* Copyright (C) 2001 by Alex Kompel <shurikk@pacbell.net> */
2 /* NetHack may be freely redistributed. See license for details. */
13 #include "patchlevel.h"
15 #define MAX_LOADSTRING 100
17 typedef struct mswin_nethack_main_window {
19 } NHMainWindow, *PNHMainWindow;
21 TCHAR szMainWindowClass[] = TEXT("MSNHMainWndClass");
22 static TCHAR szTitle[MAX_LOADSTRING];
24 LRESULT CALLBACK MainWndProc(HWND, UINT, WPARAM, LPARAM);
25 LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM);
26 static LRESULT onWMCommand(HWND hWnd, WPARAM wParam, LPARAM lParam);
27 static void onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM lParam);
28 static void register_main_window_class();
29 static void select_map_mode(int map_mode);
30 static int menuid2mapmode(int menuid);
31 static int mapmode2menuid(int map_mode);
32 static HMENU _get_main_menu(UINT menu_id);
34 HWND mswin_init_main_window () {
35 static int run_once = 0;
39 /* register window class */
41 LoadString(GetNHApp()->hApp, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
42 register_main_window_class( );
46 /* create the main window */
47 SystemParametersInfo(SPI_GETWORKAREA, 0, &rc, 0);
50 szMainWindowClass, /* registered class name */
51 szTitle, /* window name */
52 WS_CLIPCHILDREN, /* window style */
53 rc.left, /* horizontal position of window */
54 rc.top, /* vertical position of window */
55 rc.right - rc.left, /* window width */
56 rc.bottom - rc.top, /* window height */
57 NULL, /* handle to parent or owner window */
58 NULL, /* menu handle or child identifier */
59 GetNHApp()->hApp, /* handle to application instance */
60 NULL /* window-creation data */
63 if( !ret ) panic("Cannot create main window");
67 void register_main_window_class()
71 ZeroMemory(&wcex, sizeof(wcex));
72 wcex.style = CS_HREDRAW | CS_VREDRAW;
73 wcex.lpfnWndProc = (WNDPROC)MainWndProc;
76 wcex.hInstance = GetNHApp()->hApp;
77 wcex.hIcon = LoadIcon(GetNHApp()->hApp, (LPCTSTR)IDI_WINHACK);
78 wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
79 wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
80 wcex.lpszMenuName = NULL;
81 wcex.lpszClassName = szMainWindowClass;
87 * Keypad keys are translated to the normal values below.
88 * Shifted keypad keys are translated to the
93 KEY_NW, KEY_N, KEY_NE, KEY_MINUS,
94 KEY_W, KEY_GOINTERESTING, KEY_E, KEY_PLUS,
95 KEY_SW, KEY_S, KEY_SE,
96 KEY_INV, KEY_WAITLOOK,
99 static const unsigned char
100 /* normal, shift, control */
101 keypad[KEY_LAST][3] = {
102 {'y', 'Y', C('y')}, /* 7 */
103 {'k', 'K', C('k')}, /* 8 */
104 {'u', 'U', C('u')}, /* 9 */
105 {'m', C('p'), C('p')}, /* - */
106 {'h', 'H', C('h')}, /* 4 */
107 {'g', 'G', 'g'}, /* 5 */
108 {'l', 'L', C('l')}, /* 6 */
109 {'+', 'P', C('p')}, /* + */
110 {'b', 'B', C('b')}, /* 1 */
111 {'j', 'J', C('j')}, /* 2 */
112 {'n', 'N', C('n')}, /* 3 */
113 {'i', 'I', C('i')}, /* Ins */
114 {'.', ':', ':'} /* Del */
116 numpad[KEY_LAST][3] = {
117 {'7', M('7'), '7'}, /* 7 */
118 {'8', M('8'), '8'}, /* 8 */
119 {'9', M('9'), '9'}, /* 9 */
120 {'m', C('p'), C('p')}, /* - */
121 {'4', M('4'), '4'}, /* 4 */
122 {'g', 'G', 'g'}, /* 5 */
123 {'6', M('6'), '6'}, /* 6 */
124 {'+', 'P', C('p')}, /* + */
125 {'1', M('1'), '1'}, /* 1 */
126 {'2', M('2'), '2'}, /* 2 */
127 {'3', M('3'), '3'}, /* 3 */
128 {'i', 'I', C('i')}, /* Ins */
129 {'.', ':', ':'} /* Del */
132 #define STATEON(x) ((GetKeyState(x) & 0xFFFE) != 0)
133 #define KEYTABLE_REGULAR(x) ((iflags.num_pad ? numpad : keypad)[x][0])
134 #define KEYTABLE_SHIFT(x) ((iflags.num_pad ? numpad : keypad)[x][1])
135 #define KEYTABLE(x) (STATEON(VK_SHIFT) ? KEYTABLE_SHIFT(x) : KEYTABLE_REGULAR(x))
137 /* map mode macros */
138 #define IS_MAP_FIT_TO_SCREEN(mode) ((mode)==MAP_MODE_ASCII_FIT_TO_SCREEN || \
139 (mode)==MAP_MODE_TILES_FIT_TO_SCREEN )
141 #define IS_MAP_ASCII(mode) ((mode)!=MAP_MODE_TILES && (mode)!=MAP_MODE_TILES_FIT_TO_SCREEN)
145 // FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
147 // PURPOSE: Processes messages for the main window.
149 LRESULT CALLBACK MainWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
155 /*-----------------------------------------------------------------------*/
157 #if defined(WIN_CE_POCKETPC) || defined(WIN_CE_SMARTPHONE)
158 SHMENUBARINFO menubar;
160 /* set window data */
161 data = (PNHMainWindow)malloc(sizeof(NHMainWindow));
162 if( !data ) panic("out of memory");
163 ZeroMemory(data, sizeof(NHMainWindow));
164 data->mapAcsiiModeSave = MAP_MODE_ASCII12x16;
165 SetWindowLong(hWnd, GWL_USERDATA, (LONG)data);
167 GetNHApp()->hMainWnd = hWnd;
169 /* create menu bar */
170 #if defined(WIN_CE_POCKETPC) || defined(WIN_CE_SMARTPHONE)
171 ZeroMemory(&menubar, sizeof(menubar));
172 menubar.cbSize = sizeof(menubar);
173 menubar.hwndParent = hWnd;
175 menubar.nToolBarId = IDC_WINHACK;
176 menubar.hInstRes = GetNHApp()->hApp;
177 # if defined(WIN_CE_POCKETPC)
178 menubar.nBmpId = IDB_MENUBAR;
179 menubar.cBmpImages = 2;
182 menubar.cBmpImages = 0;
184 if( !SHCreateMenuBar(&menubar) ) panic("cannot create menu");
185 GetNHApp()->hMenuBar = menubar.hwndMB;
187 GetNHApp()->hMenuBar = CommandBar_Create(GetNHApp()->hApp, hWnd, 1);
188 if( !GetNHApp()->hMenuBar ) panic("cannot create menu");
189 CommandBar_InsertMenubar(
190 GetNHApp()->hMenuBar, GetNHApp()->hApp,
194 _get_main_menu(ID_VIEW),
197 (GetNHApp()->bCmdPad? MF_CHECKED : MF_UNCHECKED)
200 /* create command pad (keyboard emulator) */
201 GetNHApp()->hCmdWnd = mswin_init_command_window();
204 /*-----------------------------------------------------------------------*/
206 case WM_MSNH_COMMAND:
207 onMSNHCommand(hWnd, wParam, lParam);
210 /*-----------------------------------------------------------------------*/
213 data = (PNHMainWindow)GetWindowLong(hWnd, GWL_USERDATA);
215 /* translate arrow keys into nethack commands */
219 if( STATEON(VK_CONTROL) ) {
220 /* scroll map window one line left */
222 mswin_hwnd_from_winid(WIN_MAP),
224 MAKEWPARAM(SB_LINEUP, 0),
228 NHEVENT_KBD(KEYTABLE(KEY_W));
233 if( STATEON(VK_CONTROL) ) {
234 /* scroll map window one line right */
236 mswin_hwnd_from_winid(WIN_MAP),
238 MAKEWPARAM(SB_LINEDOWN, 0),
242 NHEVENT_KBD(KEYTABLE(KEY_E));
247 if( STATEON(VK_CONTROL) ) {
248 /* scroll map window one line up */
250 mswin_hwnd_from_winid(WIN_MAP),
252 MAKEWPARAM(SB_LINEUP, 0),
256 NHEVENT_KBD(KEYTABLE(KEY_N));
261 if( STATEON(VK_CONTROL) ) {
262 /* scroll map window one line down */
264 mswin_hwnd_from_winid(WIN_MAP),
266 MAKEWPARAM(SB_LINEDOWN, 0),
270 NHEVENT_KBD(KEYTABLE(KEY_S));
275 if( STATEON(VK_CONTROL) ) {
276 /* scroll map window to upper left corner */
278 mswin_hwnd_from_winid(WIN_MAP),
280 MAKEWPARAM(SB_THUMBTRACK, 0),
285 mswin_hwnd_from_winid(WIN_MAP),
287 MAKEWPARAM(SB_THUMBTRACK, 0),
291 NHEVENT_KBD(KEYTABLE(KEY_NW));
296 if( STATEON(VK_CONTROL) ) {
297 /* scroll map window to lower right corner */
299 mswin_hwnd_from_winid(WIN_MAP),
301 MAKEWPARAM(SB_THUMBTRACK, ROWNO),
306 mswin_hwnd_from_winid(WIN_MAP),
308 MAKEWPARAM(SB_THUMBTRACK, COLNO),
312 NHEVENT_KBD(KEYTABLE(KEY_SW));
317 if( STATEON(VK_CONTROL) ) {
318 /* scroll map window one page up */
320 mswin_hwnd_from_winid(WIN_MAP),
322 MAKEWPARAM(SB_PAGEUP, 0),
326 NHEVENT_KBD(KEYTABLE(KEY_NE));
331 if( STATEON(VK_CONTROL) ) {
332 /* scroll map window one page down */
334 mswin_hwnd_from_winid(WIN_MAP),
336 MAKEWPARAM(SB_PAGEDOWN, 0),
340 NHEVENT_KBD(KEYTABLE(KEY_SE));
346 NHEVENT_KBD(KEYTABLE(KEY_WAITLOOK));
350 NHEVENT_KBD(KEYTABLE(KEY_INV));
354 NHEVENT_KBD(KEYTABLE(KEY_MINUS));
358 NHEVENT_KBD(KEYTABLE(KEY_PLUS));
361 case VK_CLEAR: /* This is the '5' key */
362 NHEVENT_KBD(KEYTABLE(KEY_GOINTERESTING));
366 if( IS_MAP_FIT_TO_SCREEN(iflags.wc_map_mode) ) {
367 mswin_select_map_mode(
368 IS_MAP_ASCII(iflags.wc_map_mode)?
369 data->mapAcsiiModeSave :
373 mswin_select_map_mode(
374 IS_MAP_ASCII(iflags.wc_map_mode)?
375 MAP_MODE_ASCII_FIT_TO_SCREEN :
376 MAP_MODE_TILES_FIT_TO_SCREEN
382 if( IS_MAP_ASCII(iflags.wc_map_mode) ) {
383 if( IS_MAP_FIT_TO_SCREEN(iflags.wc_map_mode) ) {
384 mswin_select_map_mode(MAP_MODE_TILES_FIT_TO_SCREEN);
386 mswin_select_map_mode(MAP_MODE_TILES);
389 if( IS_MAP_FIT_TO_SCREEN(iflags.wc_map_mode) ) {
390 mswin_select_map_mode(MAP_MODE_ASCII_FIT_TO_SCREEN);
392 mswin_select_map_mode(data->mapAcsiiModeSave);
398 NHEVENT_MS( CLICK_1, u.ux, u.uy);
402 #if defined(WIN_CE_SMARTPHONE)
403 if( NHSPhoneTranslateKbdMessage(wParam, lParam, TRUE) ) return 0;
405 return 1; /* end of WM_KEYDOWN */
407 /*-----------------------------------------------------------------------*/
409 #if defined(WIN_CE_SMARTPHONE)
411 if( NHSPhoneTranslateKbdMessage(wParam, lParam, FALSE) ) return 0;
412 return 1; /* end of WM_KEYUP */
414 /*-----------------------------------------------------------------------*/
416 #if !defined(WIN_CE_SMARTPHONE)
418 if( wParam=='\n' || wParam=='\r' || wParam==C('M') ) return 0; /* we already processed VK_RETURN */
420 /* all characters go to nethack except Ctrl-P that scrolls message window up */
421 if( wParam==C('P') || wParam==C('p') ) {
422 SendMessage(mswin_hwnd_from_winid(WIN_MESSAGE), WM_VSCROLL, MAKEWPARAM(SB_LINEUP, 0), (LPARAM)NULL);
424 NHEVENT_KBD( (lParam & 1<<29)? M(tolower(wParam)) : wParam );
429 /*-----------------------------------------------------------------------*/
432 /* process commands - menu commands mostly */
433 if( IsWindow(GetNHApp()->hPopupWnd) ) {
434 return SendMessage(GetNHApp()->hPopupWnd, message, wParam, lParam);
435 } else if( onWMCommand(hWnd, wParam, lParam) )
436 return DefWindowProc(hWnd, message, wParam, lParam);
440 /*-----------------------------------------------------------------------*/
443 if( LOWORD(wParam)!=WA_INACTIVE ) {
444 #if defined(WIN_CE_POCKETPC) || defined(WIN_CE_SMARTPHONE)
445 if( GetNHApp()->bFullScreen )
446 SHFullScreen(GetNHApp()->hMainWnd, SHFS_HIDETASKBAR | SHFS_HIDESTARTICON);
448 SHFullScreen(GetNHApp()->hMainWnd, SHFS_SHOWTASKBAR | SHFS_SHOWSTARTICON);
450 mswin_layout_main_window(NULL);
454 case WM_SETTINGCHANGE:
455 #if defined(WIN_CE_POCKETPC) || defined(WIN_CE_SMARTPHONE)
456 if( GetNHApp()->bFullScreen )
457 SHFullScreen(GetNHApp()->hMainWnd, SHFS_HIDETASKBAR | SHFS_HIDESTARTICON);
459 SHFullScreen(GetNHApp()->hMainWnd, SHFS_SHOWTASKBAR | SHFS_SHOWSTARTICON);
461 mswin_layout_main_window(NULL);
465 mswin_layout_main_window(NULL);
468 /*-----------------------------------------------------------------------*/
471 /* if there is a menu window out there -
472 transfer input focus to it */
473 if( IsWindow( GetNHApp()->hPopupWnd ) ) {
474 SetFocus( GetNHApp()->hPopupWnd );
478 /*-----------------------------------------------------------------------*/
482 /* exit gracefully */
486 /*-----------------------------------------------------------------------*/
489 /* apparently we never get here
490 TODO: work on exit routines - need to send
494 free( (PNHMainWindow)GetWindowLong(hWnd, GWL_USERDATA) );
495 SetWindowLong(hWnd, GWL_USERDATA, (LONG)0);
497 terminate(EXIT_SUCCESS);
500 /*-----------------------------------------------------------------------*/
503 return DefWindowProc(hWnd, message, wParam, lParam);
508 void onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
512 /* new window was just added */
513 case MSNH_MSG_ADDWND: {
514 PMSNHMsgAddWnd msg_param = (PMSNHMsgAddWnd)lParam;
515 HWND child = GetNHApp()->windowlist[msg_param->wid].win;
517 if( GetNHApp()->windowlist[msg_param->wid].type == NHW_MAP )
518 mswin_select_map_mode(iflags.wc_map_mode);
520 if( child ) mswin_layout_main_window(child);
526 /* adjust windows to fit main window layout
527 ---------------------------
529 +-------------------------+
535 +-------------------------+
537 +-------------------------+
539 ---------------------------
541 void mswin_layout_main_window(HWND changed_child)
544 RECT client_rt, wnd_rect;
553 HWND wnd_status, wnd_msg;
555 #if defined(WIN_CE_POCKETPC)
562 GetClientRect(GetNHApp()->hMainWnd, &client_rt);
564 #if defined(WIN_CE_POCKETPC)
565 ZeroMemory(&sip, sizeof(sip));
566 sip.cbSize = sizeof(sip);
567 SHSipInfo(SPI_GETSIPINFO, 0, &sip, 0);
568 if( GetNHApp()->bFullScreen ) sip.rcVisibleDesktop.top = 0;
570 /* adjust client rectangle size */
571 GetWindowRect(GetNHApp()->hMenuBar, &menu_bar);
572 client_rt.bottom -= menu_bar.bottom-menu_bar.top;
574 /* calcuate visible rect in client coordinates */
575 pt.x = sip.rcVisibleDesktop.left;
576 pt.y = sip.rcVisibleDesktop.top;
577 ScreenToClient(GetNHApp()->hMainWnd, &pt);
581 pt.x+sip.rcVisibleDesktop.right-sip.rcVisibleDesktop.left,
582 pt.y+sip.rcVisibleDesktop.bottom-sip.rcVisibleDesktop.top );
583 IntersectRect(&visible_rt, &client_rt, &wnd_rect);
585 # if !defined(WIN_CE_SMARTPHONE)
586 client_rt.top += CommandBar_Height(GetNHApp()->hMenuBar);
588 /* Smartphone only */
589 if( GetNHApp()->bFullScreen ) {
591 GetWindowRect(GetNHApp()->hMenuBar, &menu_bar);
592 client_rt.bottom -= menu_bar.bottom-menu_bar.top;
597 /* get window data */
598 data = (PNHMainWindow)GetWindowLong(GetNHApp()->hMainWnd, GWL_USERDATA);
600 /* get sizes of child windows */
601 wnd_status = mswin_hwnd_from_winid(WIN_STATUS);
602 if( IsWindow(wnd_status) ) {
603 mswin_status_window_size(wnd_status, &status_size);
605 status_size.cx = status_size.cy = 0;
608 wnd_msg = mswin_hwnd_from_winid(WIN_MESSAGE);
609 if( IsWindow(wnd_msg) ) {
610 mswin_message_window_size(wnd_msg, &msg_size);
612 msg_size.cx = msg_size.cy = 0;
615 cmd_size.cx = cmd_size.cy = 0;
616 if( GetNHApp()->bCmdPad && IsWindow(GetNHApp()->hCmdWnd) ) {
617 mswin_command_window_size(GetNHApp()->hCmdWnd, &cmd_size);
620 /* set window positions */
622 /* calculate the application windows size */
623 #if defined(WIN_CE_POCKETPC)
624 SetRect(&wnd_rect, visible_rt.left, visible_rt.top, visible_rt.right, visible_rt.bottom);
625 if( sip.fdwFlags & SIPF_ON )
626 cmd_size.cx = cmd_size.cy = 0; /* hide keypad window */
628 SetRect(&wnd_rect, client_rt.left, client_rt.top, client_rt.right, client_rt.bottom);
631 #if !defined(WIN_CE_SMARTPHONE)
632 /* other ports have it at the bottom of the screen */
633 cmd_size.cx = (wnd_rect.right-wnd_rect.left);
634 cmd_org.x = wnd_rect.left;
635 cmd_org.y = wnd_rect.bottom - cmd_size.cy;
636 wnd_rect.bottom -= cmd_size.cy;
640 switch(iflags.wc_align_status) {
642 status_size.cx = (wnd_rect.right-wnd_rect.left)/4;
643 status_size.cy = (wnd_rect.bottom-wnd_rect.top); // that won't look good
644 status_org.x = wnd_rect.left;
645 status_org.y = wnd_rect.top;
646 wnd_rect.left += status_size.cx;
650 status_size.cx = (wnd_rect.right-wnd_rect.left)/4;
651 status_size.cy = (wnd_rect.bottom-wnd_rect.top); // that won't look good
652 status_org.x = wnd_rect.right - status_size.cx;
653 status_org.y = wnd_rect.top;
654 wnd_rect.right -= status_size.cx;
658 status_size.cx = (wnd_rect.right-wnd_rect.left);
659 status_org.x = wnd_rect.left;
660 status_org.y = wnd_rect.top;
661 wnd_rect.top += status_size.cy;
666 status_size.cx = (wnd_rect.right-wnd_rect.left);
667 status_org.x = wnd_rect.left;
668 status_org.y = wnd_rect.bottom - status_size.cy;
669 wnd_rect.bottom -= status_size.cy;
674 switch(iflags.wc_align_message) {
676 #if defined(WIN_CE_SMARTPHONE)
677 /* smartphone has a keypad window on the right (bottom) side of the message window */
678 msg_size.cx = cmd_size.cx = max(msg_size.cx, cmd_size.cx);
679 msg_size.cy = (wnd_rect.bottom-wnd_rect.top) - cmd_size.cy;
680 msg_org.x = cmd_org.x = wnd_rect.left;
681 msg_org.y = wnd_rect.top;
682 cmd_org.y = msg_org.y + msg_size.cy;
684 msg_size.cx = (wnd_rect.right-wnd_rect.left)/4;
685 msg_size.cy = (wnd_rect.bottom-wnd_rect.top);
686 msg_org.x = wnd_rect.left;
687 msg_org.y = wnd_rect.top;
689 wnd_rect.left += msg_size.cx;
694 #if defined(WIN_CE_SMARTPHONE)
695 /* smartphone has a keypad window on the right (bottom) side of the message window */
696 msg_size.cx = cmd_size.cx = max(msg_size.cx, cmd_size.cx);
697 msg_size.cy = (wnd_rect.bottom-wnd_rect.top) - cmd_size.cy;
698 msg_org.x = cmd_org.x = wnd_rect.right - msg_size.cx;
699 msg_org.y = wnd_rect.top;
700 cmd_org.y = msg_org.y + msg_size.cy;
702 msg_size.cx = (wnd_rect.right-wnd_rect.left)/4;
703 msg_size.cy = (wnd_rect.bottom-wnd_rect.top);
704 msg_org.x = wnd_rect.right - msg_size.cx;
705 msg_org.y = wnd_rect.top;
708 wnd_rect.right -= msg_size.cx;
712 #if defined(WIN_CE_SMARTPHONE)
713 /* smartphone has a keypad window on the right side of the message window */
714 msg_size.cy = cmd_size.cy = max(msg_size.cy, cmd_size.cy);
715 msg_size.cx = (wnd_rect.right - wnd_rect.left) - cmd_size.cx;
716 msg_org.x = wnd_rect.left;
717 cmd_org.x = msg_org.x + msg_size.cx;
718 msg_org.y = cmd_org.y = wnd_rect.bottom - msg_size.cy;
720 msg_size.cx = (wnd_rect.right-wnd_rect.left);
721 msg_org.x = wnd_rect.left;
722 msg_org.y = wnd_rect.top;
724 wnd_rect.top += msg_size.cy;
729 #if defined(WIN_CE_SMARTPHONE)
730 /* smartphone has a keypad window on the right side of the message window */
731 msg_size.cy = cmd_size.cy = max(msg_size.cy, cmd_size.cy);
732 msg_size.cx = (wnd_rect.right - wnd_rect.left) - cmd_size.cx;
733 msg_org.x = wnd_rect.left;
734 cmd_org.x = msg_org.x + msg_size.cx;
735 msg_org.y = cmd_org.y = wnd_rect.bottom - msg_size.cy;
737 msg_size.cx = (wnd_rect.right-wnd_rect.left);
738 msg_org.x = wnd_rect.left;
739 msg_org.y = wnd_rect.bottom - msg_size.cy;
741 wnd_rect.bottom -= msg_size.cy;
745 map_org.x = wnd_rect.left;
746 map_org.y = wnd_rect.top;
747 map_size.cx = wnd_rect.right - wnd_rect.left;
748 map_size.cy = wnd_rect.bottom - wnd_rect.top;
750 /* go through the windows list and adjust sizes */
751 for( i=0; i<MAXWINDOWS; i++ ) {
752 if(GetNHApp()->windowlist[i].win && !GetNHApp()->windowlist[i].dead) {
753 switch( GetNHApp()->windowlist[i].type ) {
755 MoveWindow(GetNHApp()->windowlist[i].win,
763 MoveWindow(GetNHApp()->windowlist[i].win,
771 MoveWindow(GetNHApp()->windowlist[i].win,
786 menu_org.x = client_rt.left;
787 menu_org.y = client_rt.top;
788 #if defined(WIN_CE_POCKETPC)
789 menu_size.cx = min(sip.rcVisibleDesktop.right-sip.rcVisibleDesktop.left,
790 client_rt.right - client_rt.left);
791 menu_size.cy = min(sip.rcVisibleDesktop.bottom-sip.rcVisibleDesktop.top,
792 client_rt.bottom - client_rt.top);
794 menu_size.cx = client_rt.right - client_rt.left;
795 menu_size.cy = client_rt.bottom - client_rt.top;
798 #if defined(WIN_CE_SMARTPHONE)
799 /* leave room for the command window */
800 if( GetNHApp()->windowlist[i].type == NHW_MENU ) {
801 menu_size.cy -= cmd_size.cy;
804 /* dialogs are popup windows unde SmartPhone so we need
805 to convert to screen coordinates */
806 ClientToScreen(GetNHApp()->hMainWnd, &menu_org);
808 MoveWindow(GetNHApp()->windowlist[i].win,
816 ShowWindow(GetNHApp()->windowlist[i].win, SW_SHOW);
817 InvalidateRect(GetNHApp()->windowlist[i].win, NULL, TRUE);
821 if( IsWindow(GetNHApp()->hCmdWnd) ) {
822 /* show command window only if it exists and
823 the game is ready (plname is set) */
824 if( GetNHApp()->bCmdPad && cmd_size.cx>0 && cmd_size.cy>0 && *plname) {
825 MoveWindow(GetNHApp()->hCmdWnd,
831 ShowWindow(GetNHApp()->hCmdWnd, SW_SHOW);
833 ShowWindow(GetNHApp()->hCmdWnd, SW_HIDE);
838 LRESULT onWMCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
843 data = (PNHMainWindow)GetWindowLong(hWnd, GWL_USERDATA);
844 wmId = LOWORD(wParam);
845 wmEvent = HIWORD(wParam);
847 // process the menu selections:
851 DialogBox(GetNHApp()->hApp, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
863 case IDM_MAP_ASCII4X6:
864 case IDM_MAP_ASCII6X8:
865 case IDM_MAP_ASCII8X8:
866 case IDM_MAP_ASCII16X8:
867 case IDM_MAP_ASCII7X12:
868 case IDM_MAP_ASCII8X12:
869 case IDM_MAP_ASCII12X16:
870 case IDM_MAP_ASCII16X12:
871 case IDM_MAP_ASCII10X18:
872 mswin_select_map_mode(menuid2mapmode(wmId));
875 case IDM_MAP_FIT_TO_SCREEN:
876 if( IS_MAP_FIT_TO_SCREEN(iflags.wc_map_mode) ) {
877 mswin_select_map_mode(
878 IS_MAP_ASCII(iflags.wc_map_mode)?
879 data->mapAcsiiModeSave :
883 mswin_select_map_mode(
884 IS_MAP_ASCII(iflags.wc_map_mode)?
885 MAP_MODE_ASCII_FIT_TO_SCREEN :
886 MAP_MODE_TILES_FIT_TO_SCREEN
891 case IDM_VIEW_KEYPAD:
892 GetNHApp()->bCmdPad = !GetNHApp()->bCmdPad;
894 _get_main_menu(ID_VIEW),
897 (GetNHApp()->bCmdPad? MF_CHECKED : MF_UNCHECKED)
899 mswin_layout_main_window(GetNHApp()->hCmdWnd);
902 case IDM_VIEW_OPTIONS:
907 display_file(HELP, TRUE);
910 case IDM_HELP_COMMANDS:
911 display_file(SHELP, TRUE);
914 case IDM_HELP_HISTORY:
918 case IDM_HELP_INFO_CHAR:
922 case IDM_HELP_INFO_KEY:
926 case IDM_HELP_OPTIONS:
930 case IDM_HELP_OPTIONS_LONG:
931 display_file(OPTIONFILE, TRUE);
934 case IDM_HELP_EXTCMD:
938 case IDM_HELP_LICENSE:
939 display_file(LICENSE, TRUE);
952 // Mesage handler for about box.
953 LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
956 TCHAR wbuf[NHSTR_BUFSIZE];
957 RECT main_rt, dlg_rt;
963 getversionstring(buf);
964 SetDlgItemText(hDlg, IDC_ABOUT_VERSION, NH_A2W(buf, wbuf, NHSTR_BUFSIZE));
966 SetDlgItemText(hDlg, IDC_ABOUT_COPYRIGHT,
968 COPYRIGHT_BANNER_A "\n"
969 COPYRIGHT_BANNER_B "\n"
976 /* center dialog in the main window */
977 GetWindowRect(GetNHApp()->hMainWnd, &main_rt);
978 GetWindowRect(hDlg, &dlg_rt);
979 dlg_sz.cx = dlg_rt.right - dlg_rt.left;
980 dlg_sz.cy = dlg_rt.bottom - dlg_rt.top;
982 dlg_rt.left = (main_rt.left+main_rt.right-dlg_sz.cx)/2;
983 dlg_rt.right = dlg_rt.left + dlg_sz.cx;
984 dlg_rt.top = (main_rt.top+main_rt.bottom-dlg_sz.cy)/2;
985 dlg_rt.bottom = dlg_rt.top + dlg_sz.cy;
987 (main_rt.left+main_rt.right-dlg_sz.cx)/2,
988 (main_rt.top+main_rt.bottom-dlg_sz.cy)/2,
996 if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
998 EndDialog(hDlg, LOWORD(wParam));
1007 /* Set map display mode */
1008 void mswin_select_map_mode(int mode)
1015 data = (PNHMainWindow)GetWindowLong(GetNHApp()->hMainWnd, GWL_USERDATA);
1016 #if defined(WIN_CE_SMARTPHONE)
1017 /* Smartphone manu has only 2 items */
1018 hmenuMap = _get_main_menu(ID_VIEW);
1020 hmenuMap = _get_main_menu(ID_MAP);
1023 /* override for Rogue level */
1024 #ifdef REINCARNATION
1025 if( Is_rogue_level(&u.uz) && !IS_MAP_ASCII(mode) ) return;
1028 /* set map mode menu mark */
1029 if( IS_MAP_ASCII(mode) ) {
1033 IDM_MAP_FIT_TO_SCREEN,
1034 mapmode2menuid( IS_MAP_FIT_TO_SCREEN(mode)? data->mapAcsiiModeSave : mode ),
1040 IDM_MAP_FIT_TO_SCREEN,
1041 mapmode2menuid( MAP_MODE_TILES ),
1045 #if defined(WIN_CE_SMARTPHONE)
1046 /* update "Fit To Screen" item text */
1051 ZeroMemory( wbuf, sizeof(wbuf) );
1054 (IS_MAP_FIT_TO_SCREEN(mode)? IDS_CAP_NORMALMAP : IDS_CAP_ENTIREMAP),
1057 panic("cannot load main menu strings");
1060 ZeroMemory( &tbbi, sizeof(tbbi) );
1061 tbbi.cbSize = sizeof(tbbi);
1062 tbbi.dwMask = TBIF_TEXT;
1063 tbbi.pszText = wbuf;
1065 GetNHApp()->hMenuBar,
1067 IDM_MAP_FIT_TO_SCREEN,
1069 error( "Cannot update IDM_MAP_FIT_TO_SCREEN menu item." );
1073 /* set fit-to-screen mode mark */
1076 IDM_MAP_FIT_TO_SCREEN,
1078 (IS_MAP_FIT_TO_SCREEN(mode)? MF_CHECKED : MF_UNCHECKED)
1082 if( IS_MAP_ASCII(iflags.wc_map_mode) && !IS_MAP_FIT_TO_SCREEN(iflags.wc_map_mode)) {
1083 data->mapAcsiiModeSave = iflags.wc_map_mode;
1086 iflags.wc_map_mode = mode;
1089 ** first, check if WIN_MAP has been inialized.
1090 ** If not - attempt to retrieve it by type, then check it again
1092 if( map_id==WIN_ERR )
1093 map_id = mswin_winid_from_type(NHW_MAP);
1094 if( map_id!=WIN_ERR )
1095 mswin_map_mode(mswin_hwnd_from_winid(map_id), mode);
1098 static struct t_menu2mapmode {
1103 { IDM_MAP_TILES, MAP_MODE_TILES },
1104 { IDM_MAP_ASCII4X6, MAP_MODE_ASCII4x6 },
1105 { IDM_MAP_ASCII6X8, MAP_MODE_ASCII6x8 },
1106 { IDM_MAP_ASCII8X8, MAP_MODE_ASCII8x8 },
1107 { IDM_MAP_ASCII16X8, MAP_MODE_ASCII16x8 },
1108 { IDM_MAP_ASCII7X12, MAP_MODE_ASCII7x12 },
1109 { IDM_MAP_ASCII8X12, MAP_MODE_ASCII8x12 },
1110 { IDM_MAP_ASCII12X16, MAP_MODE_ASCII12x16 },
1111 { IDM_MAP_ASCII16X12, MAP_MODE_ASCII16x12 },
1112 { IDM_MAP_ASCII10X18, MAP_MODE_ASCII10x18 },
1113 { IDM_MAP_FIT_TO_SCREEN, MAP_MODE_ASCII_FIT_TO_SCREEN },
1117 int menuid2mapmode(int menuid)
1119 struct t_menu2mapmode* p;
1120 for( p = _menu2mapmode; p->mapMode!=-1; p++ )
1121 if(p->menuID==menuid ) return p->mapMode;
1125 int mapmode2menuid(int map_mode)
1127 struct t_menu2mapmode* p;
1128 for( p = _menu2mapmode; p->mapMode!=-1; p++ )
1129 if(p->mapMode==map_mode ) return p->menuID;
1133 HMENU _get_main_menu(UINT menu_id)
1136 #if defined(WIN_CE_POCKETPC) || defined(WIN_CE_SMARTPHONE)
1140 #if defined(WIN_CE_POCKETPC) || defined(WIN_CE_SMARTPHONE)
1141 tbbi.cbSize = sizeof(tbbi);
1142 tbbi.dwMask = TBIF_LPARAM;
1143 SendMessage( GetNHApp()->hMenuBar, TB_GETBUTTONINFO, menu_id, (LPARAM)&tbbi);
1144 hmenuMap = (HMENU)tbbi.lParam;
1146 hmenuMap = CommandBar_GetMenu(GetNHApp()->hMenuBar, 0);