Bug report #H7156 listed three items, all relating to perm_invent: 1) it shouldn't persist across save/restore since restore might be on a system which doesn't have enough room to display it (report actually complained that config file setting was ignored when restoring old games, which is an expected side-effect for options that persist across save/restore); 2) permanent inventory wasn't updated when using scroll of charging; 3) attempts to update permanent inventory during restore could lead to crash if it tries to access shop cost for unpaid items. Items (2) and (3) have already been fixed. This fixes (1). Replace 'flags.perm_invent' with a dummy flag, preserving save files while removing it from flags. Add 'iflags.perm_invent' to hold the value of the perm_invent option. The win32 files that are updated here haven't been tested. Whichever branch contains the curses interface needs to be updated; ditto for any other pending/potential interfaces which support perm_invent.
1187 lines
38 KiB
C
1187 lines
38 KiB
C
/* NetHack 3.6 mhmain.c $NHDT-Date: 1432512811 2015/05/25 00:13:31 $ $NHDT-Branch: master $:$NHDT-Revision: 1.62 $ */
|
|
/* Copyright (C) 2001 by Alex Kompel */
|
|
/* NetHack may be freely redistributed. See license for details. */
|
|
|
|
#include "winMS.h"
|
|
#include <commdlg.h>
|
|
#include "date.h"
|
|
#include "patchlevel.h"
|
|
#include "resource.h"
|
|
#include "mhmsg.h"
|
|
#include "mhinput.h"
|
|
#include "mhmain.h"
|
|
#include "mhmenu.h"
|
|
#include "mhstatus.h"
|
|
#include "mhmsgwnd.h"
|
|
#include "mhmap.h"
|
|
|
|
typedef struct mswin_nethack_main_window {
|
|
int mapAcsiiModeSave;
|
|
} NHMainWindow, *PNHMainWindow;
|
|
|
|
extern winid WIN_STATUS;
|
|
|
|
static TCHAR szMainWindowClass[] = TEXT("MSNHMainWndClass");
|
|
static TCHAR szTitle[MAX_LOADSTRING];
|
|
extern void mswin_display_splash_window(BOOL);
|
|
|
|
LRESULT CALLBACK MainWndProc(HWND, UINT, WPARAM, LPARAM);
|
|
LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM);
|
|
static LRESULT onWMCommand(HWND hWnd, WPARAM wParam, LPARAM lParam);
|
|
static void onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM lParam);
|
|
static void register_main_window_class(void);
|
|
static int menuid2mapmode(int menuid);
|
|
static int mapmode2menuid(int map_mode);
|
|
static void nhlock_windows(BOOL lock);
|
|
static char *nh_compose_ascii_screenshot();
|
|
static void mswin_apply_window_style_all();
|
|
// returns strdup() created pointer - callee assumes the ownership
|
|
|
|
HWND
|
|
mswin_init_main_window()
|
|
{
|
|
static int run_once = 0;
|
|
HWND ret;
|
|
WINDOWPLACEMENT wp;
|
|
|
|
/* register window class */
|
|
if (!run_once) {
|
|
LoadString(GetNHApp()->hApp, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
|
|
register_main_window_class();
|
|
run_once = 1;
|
|
}
|
|
|
|
/* create the main window */
|
|
ret =
|
|
CreateWindow(szMainWindowClass, /* registered class name */
|
|
szTitle, /* window name */
|
|
WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN, /* window style */
|
|
CW_USEDEFAULT, /* horizontal position of window */
|
|
CW_USEDEFAULT, /* vertical position of window */
|
|
CW_USEDEFAULT, /* window width */
|
|
CW_USEDEFAULT, /* window height */
|
|
NULL, /* handle to parent or owner window */
|
|
NULL, /* menu handle or child identifier */
|
|
GetNHApp()->hApp, /* handle to application instance */
|
|
NULL /* window-creation data */
|
|
);
|
|
|
|
if (!ret)
|
|
panic("Cannot create main window");
|
|
|
|
if (GetNHApp()->regMainMinX != CW_USEDEFAULT) {
|
|
wp.length = sizeof(wp);
|
|
wp.showCmd = GetNHApp()->regMainShowState;
|
|
|
|
wp.ptMinPosition.x = GetNHApp()->regMainMinX;
|
|
wp.ptMinPosition.y = GetNHApp()->regMainMinY;
|
|
|
|
wp.ptMaxPosition.x = GetNHApp()->regMainMaxX;
|
|
wp.ptMaxPosition.y = GetNHApp()->regMainMaxY;
|
|
|
|
wp.rcNormalPosition.left = GetNHApp()->regMainLeft;
|
|
wp.rcNormalPosition.top = GetNHApp()->regMainTop;
|
|
wp.rcNormalPosition.right = GetNHApp()->regMainRight;
|
|
wp.rcNormalPosition.bottom = GetNHApp()->regMainBottom;
|
|
SetWindowPlacement(ret, &wp);
|
|
} else
|
|
ShowWindow(ret, SW_SHOWDEFAULT);
|
|
|
|
UpdateWindow(ret);
|
|
return ret;
|
|
}
|
|
|
|
void
|
|
register_main_window_class()
|
|
{
|
|
WNDCLASS wcex;
|
|
|
|
ZeroMemory(&wcex, sizeof(wcex));
|
|
wcex.style = CS_HREDRAW | CS_VREDRAW;
|
|
wcex.lpfnWndProc = (WNDPROC) MainWndProc;
|
|
wcex.cbClsExtra = 0;
|
|
wcex.cbWndExtra = 0;
|
|
wcex.hInstance = GetNHApp()->hApp;
|
|
wcex.hIcon = LoadIcon(GetNHApp()->hApp, (LPCTSTR) IDI_NETHACKW);
|
|
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
|
|
wcex.hbrBackground = CreateSolidBrush(RGB(0, 0, 0));
|
|
wcex.lpszMenuName = (TCHAR *) IDC_NETHACKW;
|
|
wcex.lpszClassName = szMainWindowClass;
|
|
|
|
RegisterClass(&wcex);
|
|
}
|
|
|
|
/*
|
|
* Keypad keys are translated to the normal values below.
|
|
* Shifted keypad keys are translated to the
|
|
* shift values below.
|
|
*/
|
|
|
|
enum KEY_INDEXES {
|
|
KEY_NW,
|
|
KEY_N,
|
|
KEY_NE,
|
|
KEY_MINUS,
|
|
KEY_W,
|
|
KEY_GOINTERESTING,
|
|
KEY_E,
|
|
KEY_PLUS,
|
|
KEY_SW,
|
|
KEY_S,
|
|
KEY_SE,
|
|
KEY_INV,
|
|
KEY_WAITLOOK,
|
|
KEY_LAST
|
|
};
|
|
|
|
static const unsigned char
|
|
/* normal, shift, control */
|
|
keypad[KEY_LAST][3] =
|
|
{
|
|
{ 'y', 'Y', C('y') }, /* 7 */
|
|
{ 'k', 'K', C('k') }, /* 8 */
|
|
{ 'u', 'U', C('u') }, /* 9 */
|
|
{ 'm', C('p'), C('p') }, /* - */
|
|
{ 'h', 'H', C('h') }, /* 4 */
|
|
{ 'g', 'G', 'g' }, /* 5 */
|
|
{ 'l', 'L', C('l') }, /* 6 */
|
|
{ '+', 'P', C('p') }, /* + */
|
|
{ 'b', 'B', C('b') }, /* 1 */
|
|
{ 'j', 'J', C('j') }, /* 2 */
|
|
{ 'n', 'N', C('n') }, /* 3 */
|
|
{ 'i', 'I', C('i') }, /* Ins */
|
|
{ '.', ':', ':' } /* Del */
|
|
},
|
|
numpad[KEY_LAST][3] = {
|
|
{ '7', M('7'), '7' }, /* 7 */
|
|
{ '8', M('8'), '8' }, /* 8 */
|
|
{ '9', M('9'), '9' }, /* 9 */
|
|
{ 'm', C('p'), C('p') }, /* - */
|
|
{ '4', M('4'), '4' }, /* 4 */
|
|
{ '5', M('5'), '5' }, /* 5 */
|
|
{ '6', M('6'), '6' }, /* 6 */
|
|
{ '+', 'P', C('p') }, /* + */
|
|
{ '1', M('1'), '1' }, /* 1 */
|
|
{ '2', M('2'), '2' }, /* 2 */
|
|
{ '3', M('3'), '3' }, /* 3 */
|
|
{ '0', M('0'), '0' }, /* Ins */
|
|
{ '.', ':', ':' } /* Del */
|
|
};
|
|
|
|
#define STATEON(x) ((GetKeyState(x) & 0xFFFE) != 0)
|
|
#define KEYTABLE_REGULAR(x) ((iflags.num_pad ? numpad : keypad)[x][0])
|
|
#define KEYTABLE_SHIFT(x) ((iflags.num_pad ? numpad : keypad)[x][1])
|
|
#define KEYTABLE(x) \
|
|
(STATEON(VK_SHIFT) ? KEYTABLE_SHIFT(x) : KEYTABLE_REGULAR(x))
|
|
|
|
static const char *extendedlist = "acdefijlmnopqrstuvw?2";
|
|
|
|
#define SCANLO 0x02
|
|
static const char scanmap[] = {
|
|
/* ... */
|
|
'1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 0, 0, 0, 0, 'q', 'w',
|
|
'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n', 0, 'a', 's', 'd',
|
|
'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`', 0, '\\', 'z', 'x', 'c', 'v',
|
|
'b', 'n', 'm', ',', '.', '?' /* ... */
|
|
};
|
|
|
|
/*
|
|
// FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
|
|
//
|
|
// PURPOSE: Processes messages for the main window.
|
|
*/
|
|
LRESULT CALLBACK
|
|
MainWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
PNHMainWindow data;
|
|
|
|
switch (message) {
|
|
case WM_CREATE:
|
|
/* set window data */
|
|
data = (PNHMainWindow) malloc(sizeof(NHMainWindow));
|
|
if (!data)
|
|
panic("out of memory");
|
|
ZeroMemory(data, sizeof(NHMainWindow));
|
|
data->mapAcsiiModeSave = MAP_MODE_ASCII12x16;
|
|
SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR) data);
|
|
|
|
/* update menu items */
|
|
CheckMenuItem(
|
|
GetMenu(hWnd), IDM_SETTING_LOCKWINDOWS,
|
|
MF_BYCOMMAND
|
|
| (GetNHApp()->bWindowsLocked ? MF_CHECKED : MF_UNCHECKED));
|
|
|
|
CheckMenuItem(GetMenu(hWnd), IDM_SETTING_AUTOLAYOUT,
|
|
GetNHApp()->bAutoLayout ? MF_CHECKED : MF_UNCHECKED);
|
|
|
|
/* store handle to the mane menu in the application record */
|
|
GetNHApp()->hMainWnd = hWnd;
|
|
break;
|
|
|
|
case WM_MSNH_COMMAND:
|
|
onMSNHCommand(hWnd, wParam, lParam);
|
|
break;
|
|
|
|
case WM_KEYDOWN: {
|
|
data = (PNHMainWindow) GetWindowLongPtr(hWnd, GWLP_USERDATA);
|
|
|
|
/* translate arrow keys into nethack commands */
|
|
switch (wParam) {
|
|
case VK_LEFT:
|
|
if (STATEON(VK_CONTROL)) {
|
|
/* scroll map window one line left */
|
|
SendMessage(mswin_hwnd_from_winid(WIN_MAP), WM_HSCROLL,
|
|
MAKEWPARAM(SB_LINEUP, 0), (LPARAM) NULL);
|
|
} else {
|
|
NHEVENT_KBD(KEYTABLE(KEY_W));
|
|
}
|
|
return 0;
|
|
|
|
case VK_RIGHT:
|
|
if (STATEON(VK_CONTROL)) {
|
|
/* scroll map window one line right */
|
|
SendMessage(mswin_hwnd_from_winid(WIN_MAP), WM_HSCROLL,
|
|
MAKEWPARAM(SB_LINEDOWN, 0), (LPARAM) NULL);
|
|
} else {
|
|
NHEVENT_KBD(KEYTABLE(KEY_E));
|
|
}
|
|
return 0;
|
|
|
|
case VK_UP:
|
|
if (STATEON(VK_CONTROL)) {
|
|
/* scroll map window one line up */
|
|
SendMessage(mswin_hwnd_from_winid(WIN_MAP), WM_VSCROLL,
|
|
MAKEWPARAM(SB_LINEUP, 0), (LPARAM) NULL);
|
|
} else {
|
|
NHEVENT_KBD(KEYTABLE(KEY_N));
|
|
}
|
|
return 0;
|
|
|
|
case VK_DOWN:
|
|
if (STATEON(VK_CONTROL)) {
|
|
/* scroll map window one line down */
|
|
SendMessage(mswin_hwnd_from_winid(WIN_MAP), WM_VSCROLL,
|
|
MAKEWPARAM(SB_LINEDOWN, 0), (LPARAM) NULL);
|
|
} else {
|
|
NHEVENT_KBD(KEYTABLE(KEY_S));
|
|
}
|
|
return 0;
|
|
|
|
case VK_HOME:
|
|
if (STATEON(VK_CONTROL)) {
|
|
/* scroll map window to upper left corner */
|
|
SendMessage(mswin_hwnd_from_winid(WIN_MAP), WM_VSCROLL,
|
|
MAKEWPARAM(SB_THUMBTRACK, 0), (LPARAM) NULL);
|
|
|
|
SendMessage(mswin_hwnd_from_winid(WIN_MAP), WM_HSCROLL,
|
|
MAKEWPARAM(SB_THUMBTRACK, 0), (LPARAM) NULL);
|
|
} else {
|
|
NHEVENT_KBD(KEYTABLE(KEY_NW));
|
|
}
|
|
return 0;
|
|
|
|
case VK_END:
|
|
if (STATEON(VK_CONTROL)) {
|
|
/* scroll map window to lower right corner */
|
|
SendMessage(mswin_hwnd_from_winid(WIN_MAP), WM_VSCROLL,
|
|
MAKEWPARAM(SB_THUMBTRACK, ROWNO), (LPARAM) NULL);
|
|
|
|
SendMessage(mswin_hwnd_from_winid(WIN_MAP), WM_HSCROLL,
|
|
MAKEWPARAM(SB_THUMBTRACK, COLNO), (LPARAM) NULL);
|
|
} else {
|
|
NHEVENT_KBD(KEYTABLE(KEY_SW));
|
|
}
|
|
return 0;
|
|
|
|
case VK_PRIOR:
|
|
if (STATEON(VK_CONTROL)) {
|
|
/* scroll map window one page up */
|
|
SendMessage(mswin_hwnd_from_winid(WIN_MAP), WM_VSCROLL,
|
|
MAKEWPARAM(SB_PAGEUP, 0), (LPARAM) NULL);
|
|
} else {
|
|
NHEVENT_KBD(KEYTABLE(KEY_NE));
|
|
}
|
|
return 0;
|
|
|
|
case VK_NEXT:
|
|
if (STATEON(VK_CONTROL)) {
|
|
/* scroll map window one page down */
|
|
SendMessage(mswin_hwnd_from_winid(WIN_MAP), WM_VSCROLL,
|
|
MAKEWPARAM(SB_PAGEDOWN, 0), (LPARAM) NULL);
|
|
} else {
|
|
NHEVENT_KBD(KEYTABLE(KEY_SE));
|
|
}
|
|
return 0;
|
|
|
|
case VK_DECIMAL:
|
|
case VK_DELETE:
|
|
NHEVENT_KBD(KEYTABLE(KEY_WAITLOOK));
|
|
return 0;
|
|
|
|
case VK_INSERT:
|
|
NHEVENT_KBD(KEYTABLE(KEY_INV));
|
|
return 0;
|
|
|
|
case VK_SUBTRACT:
|
|
NHEVENT_KBD(KEYTABLE(KEY_MINUS));
|
|
return 0;
|
|
|
|
case VK_ADD:
|
|
NHEVENT_KBD(KEYTABLE(KEY_PLUS));
|
|
return 0;
|
|
|
|
case VK_CLEAR: /* This is the '5' key */
|
|
NHEVENT_KBD(KEYTABLE(KEY_GOINTERESTING));
|
|
return 0;
|
|
|
|
case VK_F4:
|
|
if (IS_MAP_FIT_TO_SCREEN(iflags.wc_map_mode)) {
|
|
mswin_select_map_mode(IS_MAP_ASCII(iflags.wc_map_mode)
|
|
? data->mapAcsiiModeSave
|
|
: MAP_MODE_TILES);
|
|
} else {
|
|
mswin_select_map_mode(IS_MAP_ASCII(iflags.wc_map_mode)
|
|
? MAP_MODE_ASCII_FIT_TO_SCREEN
|
|
: MAP_MODE_TILES_FIT_TO_SCREEN);
|
|
}
|
|
return 0;
|
|
|
|
case VK_F5:
|
|
if (IS_MAP_ASCII(iflags.wc_map_mode)) {
|
|
if (IS_MAP_FIT_TO_SCREEN(iflags.wc_map_mode)) {
|
|
mswin_select_map_mode(MAP_MODE_TILES_FIT_TO_SCREEN);
|
|
} else {
|
|
mswin_select_map_mode(MAP_MODE_TILES);
|
|
}
|
|
} else {
|
|
if (IS_MAP_FIT_TO_SCREEN(iflags.wc_map_mode)) {
|
|
mswin_select_map_mode(MAP_MODE_ASCII_FIT_TO_SCREEN);
|
|
} else {
|
|
mswin_select_map_mode(data->mapAcsiiModeSave);
|
|
}
|
|
}
|
|
return 0;
|
|
|
|
default: {
|
|
WORD c;
|
|
BYTE kbd_state[256];
|
|
|
|
c = 0;
|
|
ZeroMemory(kbd_state, sizeof(kbd_state));
|
|
GetKeyboardState(kbd_state);
|
|
|
|
if (ToAscii((UINT) wParam, (lParam >> 16) & 0xFF, kbd_state, &c, 0)) {
|
|
NHEVENT_KBD(c & 0xFF);
|
|
return 0;
|
|
} else {
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
} /* end switch */
|
|
} break;
|
|
|
|
case WM_SYSCHAR: /* Alt-char pressed */
|
|
{
|
|
/*
|
|
If not nethackmode, don't handle Alt-keys here.
|
|
If no Alt-key pressed it can never be an extended command
|
|
*/
|
|
if (GetNHApp()->regNetHackMode && ((lParam & 1 << 29) != 0)) {
|
|
unsigned char c = (unsigned char) (wParam & 0xFF);
|
|
unsigned char scancode = (lParam >> 16) & 0xFF;
|
|
if (index(extendedlist, tolower(c)) != 0) {
|
|
NHEVENT_KBD(M(tolower(c)));
|
|
} else if (scancode == (SCANLO + SIZE(scanmap)) - 1) {
|
|
NHEVENT_KBD(M('?'));
|
|
}
|
|
return 0;
|
|
}
|
|
return DefWindowProc(hWnd, message, wParam, lParam);
|
|
} break;
|
|
|
|
case WM_COMMAND:
|
|
/* process commands - menu commands mostly */
|
|
if (onWMCommand(hWnd, wParam, lParam))
|
|
return DefWindowProc(hWnd, message, wParam, lParam);
|
|
else
|
|
return 0;
|
|
|
|
case WM_MOVE:
|
|
case WM_SIZE: {
|
|
WINDOWPLACEMENT wp;
|
|
|
|
mswin_layout_main_window(NULL);
|
|
|
|
wp.length = sizeof(wp);
|
|
if (GetWindowPlacement(hWnd, &wp)) {
|
|
GetNHApp()->regMainShowState =
|
|
(wp.showCmd == SW_SHOWMAXIMIZED ? SW_SHOWMAXIMIZED
|
|
: SW_SHOWNORMAL);
|
|
|
|
GetNHApp()->regMainMinX = wp.ptMinPosition.x;
|
|
GetNHApp()->regMainMinY = wp.ptMinPosition.y;
|
|
|
|
GetNHApp()->regMainMaxX = wp.ptMaxPosition.x;
|
|
GetNHApp()->regMainMaxY = wp.ptMaxPosition.y;
|
|
|
|
GetNHApp()->regMainLeft = wp.rcNormalPosition.left;
|
|
GetNHApp()->regMainTop = wp.rcNormalPosition.top;
|
|
GetNHApp()->regMainRight = wp.rcNormalPosition.right;
|
|
GetNHApp()->regMainBottom = wp.rcNormalPosition.bottom;
|
|
}
|
|
break;
|
|
}
|
|
case WM_SETFOCUS:
|
|
/* if there is a menu window out there -
|
|
transfer input focus to it */
|
|
if (IsWindow(GetNHApp()->hPopupWnd)) {
|
|
SetFocus(GetNHApp()->hPopupWnd);
|
|
}
|
|
break;
|
|
|
|
case WM_CLOSE: {
|
|
/* exit gracefully */
|
|
if (program_state.gameover) {
|
|
/* assume the user really meant this, as the game is already
|
|
* over... */
|
|
/* to make sure we still save bones, just set stop printing flag
|
|
*/
|
|
program_state.stopprint++;
|
|
NHEVENT_KBD(
|
|
'\033'); /* and send keyboard input as if user pressed ESC */
|
|
/* additional code for this is done in menu and rip windows */
|
|
} else if (!program_state.something_worth_saving) {
|
|
/* User exited before the game started, e.g. during splash display
|
|
*/
|
|
/* Just get out. */
|
|
bail((char *) 0);
|
|
} else {
|
|
/* prompt user for action */
|
|
switch (NHMessageBox(hWnd, TEXT("Save?"),
|
|
MB_YESNOCANCEL | MB_ICONQUESTION)) {
|
|
case IDYES:
|
|
#ifdef SAFERHANGUP
|
|
/* destroy popup window - it has its own loop and we need to
|
|
return control to NetHack core at this point */
|
|
if (IsWindow(GetNHApp()->hPopupWnd))
|
|
SendMessage(GetNHApp()->hPopupWnd, WM_COMMAND, IDCANCEL,
|
|
0);
|
|
|
|
/* tell NetHack core that "hangup" is requested */
|
|
hangup(1);
|
|
#else
|
|
NHEVENT_KBD('y');
|
|
dosave();
|
|
#endif
|
|
break;
|
|
case IDNO:
|
|
NHEVENT_KBD('q');
|
|
done(QUIT);
|
|
break;
|
|
case IDCANCEL:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
|
|
case WM_DESTROY:
|
|
/* apparently we never get here
|
|
TODO: work on exit routines - need to send
|
|
WM_QUIT somehow */
|
|
|
|
/* clean up */
|
|
free((PNHMainWindow) GetWindowLongPtr(hWnd, GWLP_USERDATA));
|
|
SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR) 0);
|
|
|
|
// PostQuitMessage(0);
|
|
exit(1);
|
|
break;
|
|
|
|
default:
|
|
return DefWindowProc(hWnd, message, wParam, lParam);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void
|
|
onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
UNREFERENCED_PARAMETER(hWnd);
|
|
UNREFERENCED_PARAMETER(wParam);
|
|
UNREFERENCED_PARAMETER(lParam);
|
|
|
|
switch (wParam) {
|
|
/* new window was just added */
|
|
case MSNH_MSG_ADDWND: {
|
|
PMSNHMsgAddWnd msg_param = (PMSNHMsgAddWnd) lParam;
|
|
HWND child;
|
|
|
|
if (GetNHApp()->windowlist[msg_param->wid].type == NHW_MAP)
|
|
mswin_select_map_mode(iflags.wc_map_mode);
|
|
|
|
child = GetNHApp()->windowlist[msg_param->wid].win;
|
|
} break;
|
|
}
|
|
}
|
|
|
|
/* adjust windows to fit main window layout
|
|
---------------------------
|
|
| Status |
|
|
+-------------------------+
|
|
| |
|
|
| |
|
|
| MAP |
|
|
| |
|
|
| |
|
|
+-------------------------+
|
|
| Messages |
|
|
---------------------------
|
|
*/
|
|
void
|
|
mswin_layout_main_window(HWND changed_child)
|
|
{
|
|
winid i;
|
|
RECT client_rt, wnd_rect;
|
|
POINT status_org;
|
|
SIZE status_size;
|
|
POINT msg_org;
|
|
SIZE msg_size;
|
|
POINT map_org;
|
|
SIZE map_size;
|
|
SIZE menu_size;
|
|
HWND wnd_status, wnd_msg;
|
|
PNHMainWindow data;
|
|
|
|
if (GetNHApp()->bAutoLayout) {
|
|
GetClientRect(GetNHApp()->hMainWnd, &client_rt);
|
|
data = (PNHMainWindow) GetWindowLongPtr(GetNHApp()->hMainWnd,
|
|
GWLP_USERDATA);
|
|
|
|
/* get sizes of child windows */
|
|
wnd_status = mswin_hwnd_from_winid(WIN_STATUS);
|
|
if (IsWindow(wnd_status)) {
|
|
mswin_status_window_size(wnd_status, &status_size);
|
|
} else {
|
|
status_size.cx = status_size.cy = 0;
|
|
}
|
|
|
|
wnd_msg = mswin_hwnd_from_winid(WIN_MESSAGE);
|
|
if (IsWindow(wnd_msg)) {
|
|
mswin_message_window_size(wnd_msg, &msg_size);
|
|
} else {
|
|
msg_size.cx = msg_size.cy = 0;
|
|
}
|
|
|
|
/* find all menu windows and calculate the size */
|
|
menu_size.cx = menu_size.cy = 0;
|
|
for (i = 0; i < MAXWINDOWS; i++) {
|
|
SIZE tmp_size;
|
|
if (GetNHApp()->windowlist[i].win
|
|
&& !GetNHApp()->windowlist[i].dead
|
|
&& GetNHApp()->windowlist[i].type == NHW_MENU) {
|
|
mswin_menu_window_size(GetNHApp()->windowlist[i].win,
|
|
&tmp_size);
|
|
menu_size.cx = max(menu_size.cx, tmp_size.cx);
|
|
menu_size.cy = max(menu_size.cy, tmp_size.cy);
|
|
}
|
|
}
|
|
|
|
/* set window positions */
|
|
SetRect(&wnd_rect, client_rt.left, client_rt.top, client_rt.right,
|
|
client_rt.bottom);
|
|
switch (iflags.wc_align_status) {
|
|
case ALIGN_LEFT:
|
|
status_size.cx = (wnd_rect.right - wnd_rect.left) / 4;
|
|
status_size.cy =
|
|
(wnd_rect.bottom - wnd_rect.top); // that won't look good
|
|
status_org.x = wnd_rect.left;
|
|
status_org.y = wnd_rect.top;
|
|
wnd_rect.left += status_size.cx;
|
|
break;
|
|
|
|
case ALIGN_RIGHT:
|
|
status_size.cx = (wnd_rect.right - wnd_rect.left) / 4;
|
|
status_size.cy =
|
|
(wnd_rect.bottom - wnd_rect.top); // that won't look good
|
|
status_org.x = wnd_rect.right - status_size.cx;
|
|
status_org.y = wnd_rect.top;
|
|
wnd_rect.right -= status_size.cx;
|
|
break;
|
|
|
|
case ALIGN_TOP:
|
|
status_size.cx = (wnd_rect.right - wnd_rect.left);
|
|
status_org.x = wnd_rect.left;
|
|
status_org.y = wnd_rect.top;
|
|
wnd_rect.top += status_size.cy;
|
|
break;
|
|
|
|
case ALIGN_BOTTOM:
|
|
default:
|
|
status_size.cx = (wnd_rect.right - wnd_rect.left);
|
|
status_org.x = wnd_rect.left;
|
|
status_org.y = wnd_rect.bottom - status_size.cy;
|
|
wnd_rect.bottom -= status_size.cy;
|
|
break;
|
|
}
|
|
|
|
switch (iflags.wc_align_message) {
|
|
case ALIGN_LEFT:
|
|
msg_size.cx = (wnd_rect.right - wnd_rect.left) / 4;
|
|
msg_size.cy = (wnd_rect.bottom - wnd_rect.top);
|
|
msg_org.x = wnd_rect.left;
|
|
msg_org.y = wnd_rect.top;
|
|
wnd_rect.left += msg_size.cx;
|
|
break;
|
|
|
|
case ALIGN_RIGHT:
|
|
msg_size.cx = (wnd_rect.right - wnd_rect.left) / 4;
|
|
msg_size.cy = (wnd_rect.bottom - wnd_rect.top);
|
|
msg_org.x = wnd_rect.right - msg_size.cx;
|
|
msg_org.y = wnd_rect.top;
|
|
wnd_rect.right -= msg_size.cx;
|
|
break;
|
|
|
|
case ALIGN_TOP:
|
|
msg_size.cx = (wnd_rect.right - wnd_rect.left);
|
|
msg_org.x = wnd_rect.left;
|
|
msg_org.y = wnd_rect.top;
|
|
wnd_rect.top += msg_size.cy;
|
|
break;
|
|
|
|
case ALIGN_BOTTOM:
|
|
default:
|
|
msg_size.cx = (wnd_rect.right - wnd_rect.left);
|
|
msg_org.x = wnd_rect.left;
|
|
msg_org.y = wnd_rect.bottom - msg_size.cy;
|
|
wnd_rect.bottom -= msg_size.cy;
|
|
break;
|
|
}
|
|
|
|
/* map window */
|
|
map_org.x = wnd_rect.left;
|
|
map_org.y = wnd_rect.top;
|
|
map_size.cx = wnd_rect.right - wnd_rect.left;
|
|
map_size.cy = wnd_rect.bottom - wnd_rect.top;
|
|
|
|
GetNHApp()->rtStatusWindow.left = status_org.x;
|
|
GetNHApp()->rtStatusWindow.top = status_org.y;
|
|
GetNHApp()->rtStatusWindow.right = status_org.x + status_size.cx;
|
|
GetNHApp()->rtStatusWindow.bottom = status_org.y + status_size.cy;
|
|
|
|
GetNHApp()->rtTextWindow.left = map_org.x;
|
|
GetNHApp()->rtTextWindow.top = map_org.y;
|
|
GetNHApp()->rtTextWindow.right =
|
|
map_org.x + (wnd_rect.right - wnd_rect.left);
|
|
GetNHApp()->rtTextWindow.bottom = map_org.y + map_size.cy;
|
|
|
|
GetNHApp()->rtMapWindow.left = map_org.x;
|
|
GetNHApp()->rtMapWindow.top = map_org.y;
|
|
GetNHApp()->rtMapWindow.right = map_org.x + map_size.cx;
|
|
GetNHApp()->rtMapWindow.bottom = map_org.y + map_size.cy;
|
|
|
|
GetNHApp()->rtMsgWindow.left = msg_org.x;
|
|
GetNHApp()->rtMsgWindow.top = msg_org.y;
|
|
GetNHApp()->rtMsgWindow.right = msg_org.x + msg_size.cx;
|
|
GetNHApp()->rtMsgWindow.bottom = msg_org.y + msg_size.cy;
|
|
|
|
/* map_width/4 < menu_width < map_width*2/3 */
|
|
GetNHApp()->rtMenuWindow.left =
|
|
GetNHApp()->rtMapWindow.right
|
|
- min(map_size.cx * 2 / 3, max(map_size.cx / 4, menu_size.cx));
|
|
GetNHApp()->rtMenuWindow.top = GetNHApp()->rtMapWindow.top;
|
|
GetNHApp()->rtMenuWindow.right = GetNHApp()->rtMapWindow.right;
|
|
GetNHApp()->rtMenuWindow.bottom = GetNHApp()->rtMapWindow.bottom;
|
|
|
|
GetNHApp()->rtInvenWindow.left = GetNHApp()->rtMenuWindow.left;
|
|
GetNHApp()->rtInvenWindow.top = GetNHApp()->rtMenuWindow.top;
|
|
GetNHApp()->rtInvenWindow.right = GetNHApp()->rtMenuWindow.right;
|
|
GetNHApp()->rtInvenWindow.bottom = GetNHApp()->rtMenuWindow.bottom;
|
|
|
|
/* adjust map window size only if perm_invent is set */
|
|
if (iflags.perm_invent)
|
|
GetNHApp()->rtMapWindow.right = GetNHApp()->rtMenuWindow.left;
|
|
}
|
|
|
|
/* go through the windows list and adjust sizes */
|
|
for (i = 0; i < MAXWINDOWS; i++) {
|
|
if (GetNHApp()->windowlist[i].win
|
|
&& !GetNHApp()->windowlist[i].dead) {
|
|
RECT rt;
|
|
/* kludge - inventory window should have its own type (same as
|
|
menu-text
|
|
as a matter of fact) */
|
|
if (iflags.perm_invent && i == WIN_INVEN) {
|
|
mswin_get_window_placement(NHW_INVEN, &rt);
|
|
} else {
|
|
mswin_get_window_placement(GetNHApp()->windowlist[i].type,
|
|
&rt);
|
|
}
|
|
|
|
MoveWindow(GetNHApp()->windowlist[i].win, rt.left, rt.top,
|
|
rt.right - rt.left, rt.bottom - rt.top, TRUE);
|
|
}
|
|
}
|
|
if (IsWindow(changed_child))
|
|
SetForegroundWindow(changed_child);
|
|
}
|
|
|
|
LRESULT
|
|
onWMCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
int wmId, wmEvent;
|
|
PNHMainWindow data;
|
|
|
|
UNREFERENCED_PARAMETER(lParam);
|
|
|
|
data = (PNHMainWindow) GetWindowLongPtr(hWnd, GWLP_USERDATA);
|
|
wmId = LOWORD(wParam);
|
|
wmEvent = HIWORD(wParam);
|
|
|
|
// Parse the menu selections:
|
|
switch (wmId) {
|
|
case IDM_ABOUT:
|
|
mswin_display_splash_window(TRUE);
|
|
break;
|
|
|
|
case IDM_EXIT:
|
|
done2();
|
|
break;
|
|
|
|
case IDM_SAVE:
|
|
if (!program_state.gameover && !program_state.done_hup)
|
|
dosave();
|
|
else
|
|
MessageBeep(0);
|
|
break;
|
|
|
|
case IDM_MAP_TILES:
|
|
case IDM_MAP_ASCII4X6:
|
|
case IDM_MAP_ASCII6X8:
|
|
case IDM_MAP_ASCII8X8:
|
|
case IDM_MAP_ASCII16X8:
|
|
case IDM_MAP_ASCII7X12:
|
|
case IDM_MAP_ASCII8X12:
|
|
case IDM_MAP_ASCII12X16:
|
|
case IDM_MAP_ASCII16X12:
|
|
case IDM_MAP_ASCII10X18:
|
|
mswin_select_map_mode(menuid2mapmode(wmId));
|
|
break;
|
|
|
|
case IDM_MAP_FIT_TO_SCREEN:
|
|
if (IS_MAP_FIT_TO_SCREEN(iflags.wc_map_mode)) {
|
|
mswin_select_map_mode(IS_MAP_ASCII(iflags.wc_map_mode)
|
|
? data->mapAcsiiModeSave
|
|
: MAP_MODE_TILES);
|
|
} else {
|
|
mswin_select_map_mode(IS_MAP_ASCII(iflags.wc_map_mode)
|
|
? MAP_MODE_ASCII_FIT_TO_SCREEN
|
|
: MAP_MODE_TILES_FIT_TO_SCREEN);
|
|
}
|
|
break;
|
|
|
|
case IDM_SETTING_SCREEN_TO_CLIPBOARD: {
|
|
char *p;
|
|
size_t len;
|
|
HANDLE hglbCopy;
|
|
char *p_copy;
|
|
|
|
p = nh_compose_ascii_screenshot();
|
|
if (!p)
|
|
return 0;
|
|
len = strlen(p);
|
|
|
|
if (!OpenClipboard(hWnd)) {
|
|
NHMessageBox(hWnd, TEXT("Cannot open clipboard"),
|
|
MB_OK | MB_ICONERROR);
|
|
free(p);
|
|
return 0;
|
|
}
|
|
|
|
EmptyClipboard();
|
|
|
|
hglbCopy = GlobalAlloc(GMEM_MOVEABLE, (len + 1) * sizeof(char));
|
|
if (hglbCopy == NULL) {
|
|
CloseClipboard();
|
|
free(p);
|
|
return FALSE;
|
|
}
|
|
|
|
p_copy = (char *) GlobalLock(hglbCopy);
|
|
strncpy(p_copy, p, len);
|
|
p_copy[len] = 0; // null character
|
|
GlobalUnlock(hglbCopy);
|
|
|
|
SetClipboardData(SYMHANDLING(H_IBM) ? CF_OEMTEXT : CF_TEXT, hglbCopy);
|
|
|
|
CloseClipboard();
|
|
|
|
free(p);
|
|
} break;
|
|
|
|
case IDM_SETTING_SCREEN_TO_FILE: {
|
|
OPENFILENAME ofn;
|
|
TCHAR filename[1024];
|
|
TCHAR whackdir[MAX_PATH];
|
|
FILE *pFile;
|
|
char *text;
|
|
wchar_t *wtext;
|
|
int tlen = 0;
|
|
|
|
ZeroMemory(filename, sizeof(filename));
|
|
ZeroMemory(&ofn, sizeof(ofn));
|
|
ofn.lStructSize = sizeof(OPENFILENAME);
|
|
ofn.hwndOwner = hWnd;
|
|
ofn.hInstance = GetNHApp()->hApp;
|
|
ofn.lpstrFilter = TEXT("Text Files (*.txt)\x0*.txt\x0")
|
|
TEXT("All Files (*.*)\x0*.*\x0") TEXT("\x0\x0");
|
|
ofn.lpstrCustomFilter = NULL;
|
|
ofn.nMaxCustFilter = 0;
|
|
ofn.nFilterIndex = 1;
|
|
ofn.lpstrFile = filename;
|
|
ofn.nMaxFile = SIZE(filename);
|
|
ofn.lpstrFileTitle = NULL;
|
|
ofn.nMaxFileTitle = 0;
|
|
ofn.lpstrInitialDir = NH_A2W(hackdir, whackdir, MAX_PATH);
|
|
ofn.lpstrTitle = NULL;
|
|
ofn.Flags = OFN_LONGNAMES | OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST;
|
|
ofn.nFileOffset = 0;
|
|
ofn.nFileExtension = 0;
|
|
ofn.lpstrDefExt = TEXT("txt");
|
|
ofn.lCustData = 0;
|
|
ofn.lpfnHook = 0;
|
|
ofn.lpTemplateName = 0;
|
|
|
|
if (!GetSaveFileName(&ofn))
|
|
return FALSE;
|
|
|
|
text = nh_compose_ascii_screenshot();
|
|
if (!text)
|
|
return FALSE;
|
|
|
|
pFile = _tfopen(filename, TEXT("wt+,ccs=UTF-8"));
|
|
if (!pFile) {
|
|
TCHAR buf[4096];
|
|
_stprintf(buf, TEXT("Cannot open %s for writing!"), filename);
|
|
NHMessageBox(hWnd, buf, MB_OK | MB_ICONERROR);
|
|
free(text);
|
|
return FALSE;
|
|
}
|
|
|
|
tlen = strlen(text);
|
|
wtext = (wchar_t *) malloc(tlen * sizeof(wchar_t));
|
|
if (!wtext)
|
|
panic("out of memory");
|
|
MultiByteToWideChar(NH_CODEPAGE, 0, text, -1, wtext, tlen);
|
|
fwrite(wtext, tlen * sizeof(wchar_t), 1, pFile);
|
|
fclose(pFile);
|
|
free(text);
|
|
free(wtext);
|
|
} break;
|
|
|
|
case IDM_NHMODE: {
|
|
GetNHApp()->regNetHackMode = GetNHApp()->regNetHackMode ? 0 : 1;
|
|
mswin_menu_check_intf_mode();
|
|
mswin_apply_window_style_all();
|
|
break;
|
|
}
|
|
case IDM_CLEARSETTINGS: {
|
|
mswin_destroy_reg();
|
|
/* Notify the user that windows settings will not be saved this time.
|
|
*/
|
|
NHMessageBox(GetNHApp()->hMainWnd,
|
|
TEXT("Your Windows Settings will not be stored when you "
|
|
"exit this time."),
|
|
MB_OK | MB_ICONINFORMATION);
|
|
break;
|
|
}
|
|
|
|
case IDM_SETTING_AUTOLAYOUT:
|
|
GetNHApp()->bAutoLayout = !GetNHApp()->bAutoLayout;
|
|
mswin_layout_main_window(NULL);
|
|
|
|
/* Update menu item check-mark */
|
|
CheckMenuItem(GetMenu(GetNHApp()->hMainWnd), IDM_SETTING_AUTOLAYOUT,
|
|
GetNHApp()->bAutoLayout ? MF_CHECKED : MF_UNCHECKED);
|
|
break;
|
|
|
|
case IDM_SETTING_LOCKWINDOWS:
|
|
nhlock_windows(!GetNHApp()->bWindowsLocked);
|
|
break;
|
|
|
|
case IDM_HELP_LONG:
|
|
display_file(HELP, TRUE);
|
|
break;
|
|
|
|
case IDM_HELP_COMMANDS:
|
|
display_file(SHELP, TRUE);
|
|
break;
|
|
|
|
case IDM_HELP_HISTORY:
|
|
(void) dohistory();
|
|
break;
|
|
|
|
case IDM_HELP_INFO_CHAR:
|
|
(void) dowhatis();
|
|
break;
|
|
|
|
case IDM_HELP_INFO_KEY:
|
|
(void) dowhatdoes();
|
|
break;
|
|
|
|
case IDM_HELP_OPTIONS:
|
|
option_help();
|
|
break;
|
|
|
|
case IDM_HELP_OPTIONS_LONG:
|
|
display_file(OPTIONFILE, TRUE);
|
|
break;
|
|
|
|
case IDM_HELP_EXTCMD:
|
|
(void) doextlist();
|
|
break;
|
|
|
|
case IDM_HELP_LICENSE:
|
|
display_file(LICENSE, TRUE);
|
|
break;
|
|
|
|
case IDM_HELP_PORTHELP:
|
|
display_file(PORT_HELP, TRUE);
|
|
break;
|
|
|
|
default:
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
// Mesage handler for about box.
|
|
LRESULT CALLBACK
|
|
About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
char buf[BUFSZ];
|
|
TCHAR wbuf[BUFSZ];
|
|
RECT main_rt, dlg_rt;
|
|
SIZE dlg_sz;
|
|
|
|
UNREFERENCED_PARAMETER(lParam);
|
|
|
|
switch (message) {
|
|
case WM_INITDIALOG:
|
|
getversionstring(buf);
|
|
SetDlgItemText(hDlg, IDC_ABOUT_VERSION,
|
|
NH_A2W(buf, wbuf, sizeof(wbuf)));
|
|
|
|
SetDlgItemText(hDlg, IDC_ABOUT_COPYRIGHT,
|
|
NH_A2W(COPYRIGHT_BANNER_A "\n" COPYRIGHT_BANNER_B
|
|
"\n" COPYRIGHT_BANNER_C
|
|
"\n" COPYRIGHT_BANNER_D,
|
|
wbuf, BUFSZ));
|
|
|
|
/* center dialog in the main window */
|
|
GetWindowRect(GetNHApp()->hMainWnd, &main_rt);
|
|
GetWindowRect(hDlg, &dlg_rt);
|
|
dlg_sz.cx = dlg_rt.right - dlg_rt.left;
|
|
dlg_sz.cy = dlg_rt.bottom - dlg_rt.top;
|
|
|
|
dlg_rt.left = (main_rt.left + main_rt.right - dlg_sz.cx) / 2;
|
|
dlg_rt.right = dlg_rt.left + dlg_sz.cx;
|
|
dlg_rt.top = (main_rt.top + main_rt.bottom - dlg_sz.cy) / 2;
|
|
dlg_rt.bottom = dlg_rt.top + dlg_sz.cy;
|
|
MoveWindow(hDlg, (main_rt.left + main_rt.right - dlg_sz.cx) / 2,
|
|
(main_rt.top + main_rt.bottom - dlg_sz.cy) / 2, dlg_sz.cx,
|
|
dlg_sz.cy, TRUE);
|
|
|
|
return TRUE;
|
|
|
|
case WM_COMMAND:
|
|
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) {
|
|
EndDialog(hDlg, LOWORD(wParam));
|
|
return TRUE;
|
|
}
|
|
break;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
void
|
|
mswin_menu_check_intf_mode()
|
|
{
|
|
HMENU hMenu = GetMenu(GetNHApp()->hMainWnd);
|
|
|
|
if (GetNHApp()->regNetHackMode)
|
|
CheckMenuItem(hMenu, IDM_NHMODE, MF_CHECKED);
|
|
else
|
|
CheckMenuItem(hMenu, IDM_NHMODE, MF_UNCHECKED);
|
|
}
|
|
|
|
void
|
|
mswin_select_map_mode(int mode)
|
|
{
|
|
PNHMainWindow data;
|
|
winid map_id;
|
|
|
|
map_id = WIN_MAP;
|
|
data =
|
|
(PNHMainWindow) GetWindowLongPtr(GetNHApp()->hMainWnd, GWLP_USERDATA);
|
|
|
|
/* override for Rogue level */
|
|
if (Is_rogue_level(&u.uz) && !IS_MAP_ASCII(mode))
|
|
return;
|
|
|
|
/* set map mode menu mark */
|
|
if (IS_MAP_ASCII(mode)) {
|
|
CheckMenuRadioItem(
|
|
GetMenu(GetNHApp()->hMainWnd), IDM_MAP_TILES, IDM_MAP_ASCII10X18,
|
|
mapmode2menuid(IS_MAP_FIT_TO_SCREEN(mode) ? data->mapAcsiiModeSave
|
|
: mode),
|
|
MF_BYCOMMAND);
|
|
} else {
|
|
CheckMenuRadioItem(GetMenu(GetNHApp()->hMainWnd), IDM_MAP_TILES,
|
|
IDM_MAP_ASCII10X18, mapmode2menuid(MAP_MODE_TILES),
|
|
MF_BYCOMMAND);
|
|
}
|
|
|
|
/* set fit-to-screen mode mark */
|
|
CheckMenuItem(GetMenu(GetNHApp()->hMainWnd), IDM_MAP_FIT_TO_SCREEN,
|
|
MF_BYCOMMAND | (IS_MAP_FIT_TO_SCREEN(mode) ? MF_CHECKED
|
|
: MF_UNCHECKED));
|
|
|
|
if (IS_MAP_ASCII(iflags.wc_map_mode)
|
|
&& !IS_MAP_FIT_TO_SCREEN(iflags.wc_map_mode)) {
|
|
data->mapAcsiiModeSave = iflags.wc_map_mode;
|
|
}
|
|
|
|
iflags.wc_map_mode = mode;
|
|
|
|
/*
|
|
** first, check if WIN_MAP has been inialized.
|
|
** If not - attempt to retrieve it by type, then check it again
|
|
*/
|
|
if (map_id == WIN_ERR)
|
|
map_id = mswin_winid_from_type(NHW_MAP);
|
|
if (map_id != WIN_ERR)
|
|
mswin_map_mode(mswin_hwnd_from_winid(map_id), mode);
|
|
}
|
|
|
|
static struct t_menu2mapmode {
|
|
int menuID;
|
|
int mapMode;
|
|
} _menu2mapmode[] = { { IDM_MAP_TILES, MAP_MODE_TILES },
|
|
{ IDM_MAP_ASCII4X6, MAP_MODE_ASCII4x6 },
|
|
{ IDM_MAP_ASCII6X8, MAP_MODE_ASCII6x8 },
|
|
{ IDM_MAP_ASCII8X8, MAP_MODE_ASCII8x8 },
|
|
{ IDM_MAP_ASCII16X8, MAP_MODE_ASCII16x8 },
|
|
{ IDM_MAP_ASCII7X12, MAP_MODE_ASCII7x12 },
|
|
{ IDM_MAP_ASCII8X12, MAP_MODE_ASCII8x12 },
|
|
{ IDM_MAP_ASCII12X16, MAP_MODE_ASCII12x16 },
|
|
{ IDM_MAP_ASCII16X12, MAP_MODE_ASCII16x12 },
|
|
{ IDM_MAP_ASCII10X18, MAP_MODE_ASCII10x18 },
|
|
{ IDM_MAP_FIT_TO_SCREEN, MAP_MODE_ASCII_FIT_TO_SCREEN },
|
|
{ -1, -1 } };
|
|
|
|
int
|
|
menuid2mapmode(int menuid)
|
|
{
|
|
struct t_menu2mapmode *p;
|
|
for (p = _menu2mapmode; p->mapMode != -1; p++)
|
|
if (p->menuID == menuid)
|
|
return p->mapMode;
|
|
return -1;
|
|
}
|
|
|
|
int
|
|
mapmode2menuid(int map_mode)
|
|
{
|
|
struct t_menu2mapmode *p;
|
|
for (p = _menu2mapmode; p->mapMode != -1; p++)
|
|
if (p->mapMode == map_mode)
|
|
return p->menuID;
|
|
return -1;
|
|
}
|
|
|
|
void
|
|
nhlock_windows(BOOL lock)
|
|
{
|
|
/* update menu */
|
|
GetNHApp()->bWindowsLocked = lock;
|
|
CheckMenuItem(GetMenu(GetNHApp()->hMainWnd), IDM_SETTING_LOCKWINDOWS,
|
|
MF_BYCOMMAND | (lock ? MF_CHECKED : MF_UNCHECKED));
|
|
|
|
/* restyle windows */
|
|
mswin_apply_window_style_all();
|
|
}
|
|
|
|
void
|
|
mswin_apply_window_style(HWND hwnd) {
|
|
DWORD style = 0, exstyle = 0;
|
|
|
|
style = GetWindowLong(hwnd, GWL_STYLE);
|
|
exstyle = GetWindowLong(hwnd, GWL_EXSTYLE);
|
|
|
|
if( !GetNHApp()->bWindowsLocked ) {
|
|
style = WS_CHILD|WS_CLIPSIBLINGS|WS_CAPTION|WS_SIZEBOX|(style & (WS_VISIBLE|WS_VSCROLL|WS_HSCROLL));
|
|
exstyle = WS_EX_WINDOWEDGE;
|
|
} else if (GetNHApp()->regNetHackMode) {
|
|
/* do away borders */
|
|
style = WS_CHILD|WS_CLIPSIBLINGS|(style & (WS_VISIBLE|WS_VSCROLL|WS_HSCROLL));
|
|
exstyle = 0;
|
|
} else {
|
|
style = WS_CHILD|WS_CLIPSIBLINGS|WS_THICKFRAME|(style & (WS_VISIBLE|WS_VSCROLL|WS_HSCROLL));
|
|
exstyle = WS_EX_WINDOWEDGE;
|
|
}
|
|
|
|
SetWindowLong(hwnd, GWL_STYLE, style);
|
|
SetWindowLong(hwnd, GWL_EXSTYLE, exstyle);
|
|
SetWindowPos(hwnd, NULL, 0, 0, 0, 0,
|
|
SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOCOPYBITS);
|
|
}
|
|
|
|
void
|
|
mswin_apply_window_style_all() {
|
|
int i;
|
|
for (i = 0; i < MAXWINDOWS; i++) {
|
|
if (IsWindow(GetNHApp()->windowlist[i].win)
|
|
&& !GetNHApp()->windowlist[i].dead) {
|
|
mswin_apply_window_style(GetNHApp()->windowlist[i].win);
|
|
}
|
|
}
|
|
mswin_layout_main_window(NULL);
|
|
}
|
|
|
|
// returns strdup() created pointer - callee assumes the ownership
|
|
#define TEXT_BUFFER_SIZE 4096
|
|
char *
|
|
nh_compose_ascii_screenshot()
|
|
{
|
|
char *retval;
|
|
PMSNHMsgGetText text;
|
|
|
|
retval = (char *) malloc(3 * TEXT_BUFFER_SIZE);
|
|
|
|
text =
|
|
(PMSNHMsgGetText) malloc(sizeof(MSNHMsgGetText) + TEXT_BUFFER_SIZE);
|
|
text->max_size =
|
|
TEXT_BUFFER_SIZE
|
|
- 1; /* make sure we always have 0 at the end of the buffer */
|
|
|
|
ZeroMemory(text->buffer, TEXT_BUFFER_SIZE);
|
|
SendMessage(mswin_hwnd_from_winid(WIN_MESSAGE), WM_MSNH_COMMAND,
|
|
(WPARAM) MSNH_MSG_GETTEXT, (LPARAM) text);
|
|
strcpy(retval, text->buffer);
|
|
|
|
ZeroMemory(text->buffer, TEXT_BUFFER_SIZE);
|
|
SendMessage(mswin_hwnd_from_winid(WIN_MAP), WM_MSNH_COMMAND,
|
|
(WPARAM) MSNH_MSG_GETTEXT, (LPARAM) text);
|
|
strcat(retval, text->buffer);
|
|
|
|
ZeroMemory(text->buffer, TEXT_BUFFER_SIZE);
|
|
SendMessage(mswin_hwnd_from_winid(WIN_STATUS), WM_MSNH_COMMAND,
|
|
(WPARAM) MSNH_MSG_GETTEXT, (LPARAM) text);
|
|
strcat(retval, text->buffer);
|
|
|
|
free(text);
|
|
return retval;
|
|
}
|