win32gui message history; also clipboard support (from <Someone>)
- added 2 menu options: Copy ASCII Screenshot To Clipboard, Save ASCII Screenshot To File - implemented saving message history
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
#include "winMS.h"
|
||||
#include <commdlg.h>
|
||||
#include "patchlevel.h"
|
||||
#include "resource.h"
|
||||
#include "mhmsg.h"
|
||||
@@ -28,6 +29,8 @@ 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();
|
||||
// returns strdup() created pointer - callee assumes the ownership
|
||||
|
||||
HWND mswin_init_main_window () {
|
||||
static int run_once = 0;
|
||||
@@ -802,6 +805,93 @@ LRESULT onWMCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
|
||||
}
|
||||
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;
|
||||
@@ -1065,4 +1155,36 @@ void nhlock_windows( BOOL lock )
|
||||
MF_BYCOMMAND |
|
||||
(lock? MF_CHECKED : MF_UNCHECKED)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
@@ -520,7 +520,35 @@ void onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
|
||||
|
||||
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 */
|
||||
|
||||
@@ -309,7 +309,10 @@ BOOL CALLBACK MenuWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
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:
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#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;
|
||||
@@ -59,5 +60,10 @@ typedef struct mswin_nhmsg_end_menu {
|
||||
const char* text;
|
||||
} MSNHMsgEndMenu, *PMSNHMsgEndMenu;
|
||||
|
||||
typedef struct mswin_nhmsg_get_text {
|
||||
size_t max_size;
|
||||
char buffer[];
|
||||
} MSNHMsgGetText, *PMSNHMsgGetText;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#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
|
||||
|
||||
@@ -218,6 +218,15 @@ LRESULT CALLBACK NHMessageWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM
|
||||
}
|
||||
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);
|
||||
}
|
||||
@@ -319,7 +328,7 @@ void onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM 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;
|
||||
@@ -344,8 +353,25 @@ void onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
|
||||
}
|
||||
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)
|
||||
|
||||
@@ -99,20 +99,29 @@ LRESULT CALLBACK StatusWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lP
|
||||
{
|
||||
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: {
|
||||
|
||||
@@ -121,8 +121,8 @@ struct window_procs mswin_procs = {
|
||||
mswin_end_screen,
|
||||
mswin_outrip,
|
||||
mswin_preference_update,
|
||||
genl_getmsghistory,
|
||||
genl_putmsghistory,
|
||||
mswin_getmsghistory,
|
||||
mswin_putmsghistory,
|
||||
};
|
||||
|
||||
|
||||
@@ -1929,6 +1929,45 @@ void mswin_preference_update(const char *pref)
|
||||
|
||||
}
|
||||
|
||||
#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()
|
||||
{
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Developer Studio generated include file.
|
||||
// Microsoft Visual C++ generated include file.
|
||||
// Used by winhack.rc
|
||||
//
|
||||
#define IDC_MYICON 2
|
||||
@@ -139,6 +139,8 @@
|
||||
#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
|
||||
@@ -146,7 +148,7 @@
|
||||
#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
|
||||
|
||||
@@ -87,6 +87,8 @@ typedef struct mswin_nhwindow_app {
|
||||
RECT rtTextWindow;
|
||||
RECT rtInvenWindow;
|
||||
BOOL bWindowsLocked; /* TRUE if windows are "locked" - no captions */
|
||||
|
||||
BOOL bNoSounds; /* disable sounds */
|
||||
} NHWinApp, *PNHWinApp;
|
||||
|
||||
#define E extern
|
||||
@@ -141,6 +143,8 @@ void mswin_start_screen(void);
|
||||
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);
|
||||
|
||||
@@ -110,6 +110,8 @@ int APIENTRY WinMain(HINSTANCE hInstance,
|
||||
_nethack_app.bAutoLayout = TRUE;
|
||||
_nethack_app.bWindowsLocked = TRUE;
|
||||
|
||||
_nethack_app.bNoSounds = FALSE;
|
||||
|
||||
// init controls
|
||||
if (FAILED(GetComCtlVersion(&major, &minor)))
|
||||
{
|
||||
|
||||
@@ -63,6 +63,9 @@ BEGIN
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user