/* NetHack may be freely redistributed. See license for details. */
#include "winMS.h"
+#include <commdlg.h>
#include "patchlevel.h"
#include "resource.h"
#include "mhmsg.h"
static int menuid2mapmode(int menuid);
static int mapmode2menuid(int map_mode);
static void nhlock_windows( BOOL lock );
+static char* nh_compose_ascii_screenshot();
+ // returns strdup() created pointer - callee assumes the ownership
HWND mswin_init_main_window () {
static int run_once = 0;
}
break;
+ case IDM_SETTING_SCREEN_TO_CLIPBOARD:
+ {
+ char* p;
+ size_t len;
+ HANDLE hglbCopy;
+ TCHAR* 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);
+ return 0;
+ }
+
+ EmptyClipboard();
+
+ hglbCopy = GlobalAlloc(GMEM_MOVEABLE, (len + 1) * sizeof(TCHAR));
+ if (hglbCopy == NULL) {
+ CloseClipboard();
+ return FALSE;
+ }
+
+ p_copy = (TCHAR*)GlobalLock(hglbCopy);
+ NH_A2W( p, p_copy, len );
+ p_copy[len] = (TCHAR) 0; // null character
+ GlobalUnlock(hglbCopy);
+
+ SetClipboardData(CF_TEXT, hglbCopy);
+
+ CloseClipboard();
+
+ free(p);
+ } break;
+
+ case IDM_SETTING_SCREEN_TO_FILE: {
+ OPENFILENAME ofn;
+ char filename[1024];
+ FILE* pFile;
+ char* text;
+
+ ZeroMemory(filename, sizeof(filename));
+ ZeroMemory(&ofn, sizeof(ofn));
+ ofn.lStructSize = sizeof (OPENFILENAME);
+ ofn.hwndOwner = hWnd;
+ ofn.hInstance = GetNHApp()->hApp;
+ ofn.lpstrFilter =
+ "Text Files (*.txt)\x0*.txt\x0"
+ "All Files (*.*)\x0*.*\x0"
+ "\x0\x0";
+ ofn.lpstrCustomFilter = NULL;
+ ofn.nMaxCustFilter = 0;
+ ofn.nFilterIndex = 1;
+ ofn.lpstrFile = filename;
+ ofn.nMaxFile = sizeof(filename);
+ ofn.lpstrFileTitle = NULL;
+ ofn.nMaxFileTitle = 0;
+ ofn.lpstrInitialDir = hackdir;
+ ofn.lpstrTitle = NULL;
+ ofn.Flags = OFN_LONGNAMES | OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST;
+ ofn.nFileOffset = 0;
+ ofn.nFileExtension = 0;
+ ofn.lpstrDefExt = "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 = fopen(filename, "wb");
+ if( !pFile ) {
+ char buf[4096];
+ sprintf(buf, "Cannot open %s for writing!", filename);
+ NHMessageBox(hWnd, buf, MB_OK | MB_ICONERROR);
+ free(text);
+ return FALSE;
+ }
+
+ fwrite(text, strlen(text), 1, pFile);
+ fclose(pFile);
+ free(text);
+ } break;
+
case IDM_NHMODE:
{
GetNHApp()->regNetHackMode = GetNHApp()->regNetHackMode ? 0 : 1;
MF_BYCOMMAND |
(lock? MF_CHECKED : MF_UNCHECKED)
);
-}
\ No newline at end of file
+}
+
+// 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;
+}
ReleaseDC(hWnd, hdc);
} break;
- }
+
+ case MSNH_MSG_GETTEXT: {
+ PMSNHMsgGetText msg_data = (PMSNHMsgGetText)lParam;
+ size_t index;
+ int col, row;
+ int color;
+ unsigned special;
+ int mgch;
+
+ index = 0;
+ for( row=0; row<ROWNO; row++ ) {
+ for( col=0; col<COLNO; col++ ) {
+ if( index>=msg_data->max_size ) break;
+ if( data->map[col][row] == -1 ) {
+ mgch = ' ';
+ } else {
+ mapglyph(data->map[col][row], &mgch, &color,
+ &special, col, row);
+ }
+ msg_data->buffer[index] = mgch;
+ index++;
+ }
+ if( index>=msg_data->max_size-1 ) break;
+ msg_data->buffer[index++] = '\r';
+ msg_data->buffer[index++] = '\n';
+ }
+ } break;
+
+ } /* end switch(wParam) */
}
/* on WM_CREATE */
GetWindowRect(hWnd, &rt);
ScreenToClient(GetNHApp()->hMainWnd, (LPPOINT)&rt);
ScreenToClient(GetNHApp()->hMainWnd, ((LPPOINT)&rt)+1);
- mswin_update_window_placement(NHW_MENU, &rt);
+ if( flags.perm_invent && mswin_winid_from_handle(hWnd)==WIN_INVEN )
+ mswin_update_window_placement(NHW_INVEN, &rt);
+ else
+ mswin_update_window_placement(NHW_MENU, &rt);
} return FALSE;
case WM_CLOSE:
#define MSNH_MSG_ENDMENU 108
#define MSNH_MSG_DIED 109
#define MSNH_MSG_CARET 110
+#define MSNH_MSG_GETTEXT 111
typedef struct mswin_nhmsg_add_wnd {
winid wid;
const char* text;
} MSNHMsgEndMenu, *PMSNHMsgEndMenu;
+typedef struct mswin_nhmsg_get_text {
+ size_t max_size;
+ char buffer[];
+} MSNHMsgGetText, *PMSNHMsgGetText;
+
#endif
#define MSG_WRAP_TEXT
#define MSG_VISIBLE_LINES max(iflags.wc_vary_msgcount, 2)
-#define MAX_MSG_LINES 32
+#define MAX_MSG_LINES 128
#define MSG_LINES (int)min(iflags.msg_history, MAX_MSG_LINES)
#define MAXWINDOWTEXT TBUFSZ
}
break;
+ case WM_MOVE: {
+ RECT rt;
+ GetWindowRect(hWnd, &rt);
+ ScreenToClient(GetNHApp()->hMainWnd, (LPPOINT)&rt);
+ ScreenToClient(GetNHApp()->hMainWnd, ((LPPOINT)&rt)+1);
+ mswin_update_window_placement(NHW_MESSAGE, &rt);
+ }
+ break;
+
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
InvalidateRect(hWnd, NULL, TRUE);
#ifdef USER_SOUNDS
- play_sound_for_message(msg_data->text);
+ if( !GetNHApp()->bNoSounds ) play_sound_for_message(msg_data->text);
#endif
}
break;
}
break;
+ case MSNH_MSG_GETTEXT: {
+ PMSNHMsgGetText msg_data = (PMSNHMsgGetText)lParam;
+ int i;
+ size_t buflen;
+
+ buflen = 0;
+ for(i=0; i<MSG_LINES; i++ )
+ if( *data->window_text[i].text ) {
+ strncpy(&msg_data->buffer[buflen], data->window_text[i].text, msg_data->max_size - buflen );
+ buflen += strlen(data->window_text[i].text);
+ if( buflen >= msg_data->max_size ) break;
+
+ strncpy(&msg_data->buffer[buflen], "\r\n", msg_data->max_size - buflen );
+ buflen += 2;
+ if( buflen > msg_data->max_size ) break;
+ }
+ } break;
- }
+ } /* switch( wParam ) */
}
void onMSNH_VScroll(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
case WM_MSNH_COMMAND: {
switch( wParam ) {
+
case MSNH_MSG_PUTSTR: {
PMSNHMsgPutstr msg_data = (PMSNHMsgPutstr)lParam;
strncpy(data->window_text[data->index], msg_data->text,
MAXWINDOWTEXT);
data->index = (data->index+1) % NHSW_LINES;
InvalidateRect(hWnd, NULL, TRUE);
- break;
- }
- case MSNH_MSG_CLEAR_WINDOW:
+ } break;
+
+ case MSNH_MSG_CLEAR_WINDOW: {
data->index = 0;
ZeroMemory(data->window_text, sizeof(data->window_text));
InvalidateRect(hWnd, NULL, TRUE);
- break;
- }
+ } break;
+
+ case MSNH_MSG_GETTEXT: {
+ PMSNHMsgGetText msg_data = (PMSNHMsgGetText)lParam;
+ strncpy(msg_data->buffer, data->window_text[0], msg_data->max_size);
+ strncat(msg_data->buffer, "\r\n", msg_data->max_size - strlen(msg_data->buffer) );
+ strncat(msg_data->buffer, data->window_text[1], msg_data->max_size - strlen(msg_data->buffer) );
+ } break;
+
+ } /* end switch( wParam ) { */
} break;
case WM_PAINT: {
mswin_end_screen,
mswin_outrip,
mswin_preference_update,
- genl_getmsghistory,
- genl_putmsghistory,
+ mswin_getmsghistory,
+ mswin_putmsghistory,
};
}
+#define TEXT_BUFFER_SIZE 4096
+char *mswin_getmsghistory(BOOLEAN_P init)
+{
+ static PMSNHMsgGetText text = 0;
+ static char* next_message = 0;
+
+ if( init ) {
+ 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 );
+
+ next_message = text->buffer;
+ }
+
+ if( !(next_message && next_message[0]) ) {
+ free(text);
+ next_message = 0;
+ return (char*)0;
+ } else {
+ char* retval = next_message;
+ char* p;
+ next_message = p = strchr(next_message, '\n');
+ if( next_message ) next_message++;
+ if( p ) while( p>=retval && isspace(*p) ) *p-- = (char)0; /* delete trailing whitespace */
+ return retval;
+ }
+}
+
+void mswin_putmsghistory(const char * msg)
+{
+ BOOL save_sound_opt = GetNHApp()->bNoSounds;
+ GetNHApp()->bNoSounds = TRUE; /* disable sounds while restoring message history */
+ mswin_putstr_ex(WIN_MESSAGE, ATR_NONE, msg, 0);
+ clear_nhwindow(WIN_MESSAGE); /* it is in fact end-of-turn indication so each message will print on the new line */
+ GetNHApp()->bNoSounds = save_sound_opt; /* restore sounds option */
+}
void mswin_main_loop()
{
//{{NO_DEPENDENCIES}}
-// Microsoft Developer Studio generated include file.
+// Microsoft Visual C++ generated include file.
// Used by winhack.rc
//
#define IDC_MYICON 2
#define IDM_CLEARSETTINGS 32795
#define IDM_SETTING_AUTOLAYOUT 32796
#define IDM_SETTING_LOCKWINDOWS 32797
+#define IDM_SETTING_SCREEN_TO_CLIPBOARD 32798
+#define IDM_SETTING_SCREEN_TO_FILE 32799
#define IDC_STATIC -1
// Next default values for new objects
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 145
-#define _APS_NEXT_COMMAND_VALUE 32798
+#define _APS_NEXT_COMMAND_VALUE 32800
#define _APS_NEXT_CONTROL_VALUE 1332
#define _APS_NEXT_SYMED_VALUE 110
#endif
RECT rtTextWindow;
RECT rtInvenWindow;
BOOL bWindowsLocked; /* TRUE if windows are "locked" - no captions */
+
+ BOOL bNoSounds; /* disable sounds */
} NHWinApp, *PNHWinApp;
#define E extern
void mswin_end_screen(void);
void mswin_outrip(winid wid, int how);
void mswin_preference_update(const char *pref);
+char *mswin_getmsghistory(BOOLEAN_P init);
+void mswin_putmsghistory(const char * msg);
/* helper function */
HWND mswin_hwnd_from_winid(winid wid);
_nethack_app.bAutoLayout = TRUE;
_nethack_app.bWindowsLocked = TRUE;
+ _nethack_app.bNoSounds = FALSE;
+
// init controls
if (FAILED(GetComCtlVersion(&major, &minor)))
{
MENUITEM "&9 - ASCII (10x18)", IDM_MAP_ASCII10X18
MENUITEM SEPARATOR
MENUITEM "&Fit To Screen ", IDM_MAP_FIT_TO_SCREEN
+ MENUITEM SEPARATOR
+ MENUITEM "&Copy To Clipboard (ASCII)", IDM_SETTING_SCREEN_TO_CLIPBOARD
+ MENUITEM "&Save to File (ASCII)", IDM_SETTING_SCREEN_TO_FILE
END
POPUP "Windows &Settings"
BEGIN