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:
nethack.allison
2003-10-13 14:48:13 +00:00
parent 2d99bb91be
commit 21eaf22be4
11 changed files with 259 additions and 15 deletions

View File

@@ -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;
}

View File

@@ -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 */

View File

@@ -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:

View File

@@ -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

View File

@@ -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)

View File

@@ -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: {

View File

@@ -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()
{

View File

@@ -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

View File

@@ -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);

View File

@@ -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)))
{

View File

@@ -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