From: nethack.allison Date: Mon, 13 Oct 2003 14:48:13 +0000 (+0000) Subject: win32gui message history; also clipboard support (from ) X-Git-Tag: MOVE2GIT~1709 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=21eaf22be48bc88aad8c5dfc5833aa0602dc6c41;p=nethack win32gui message history; also clipboard support (from ) - added 2 menu options: Copy ASCII Screenshot To Clipboard, Save ASCII Screenshot To File - implemented saving message history --- diff --git a/win/win32/mhmain.c b/win/win32/mhmain.c index 7f56e195f..2d3cbd897 100644 --- a/win/win32/mhmain.c +++ b/win/win32/mhmain.c @@ -2,6 +2,7 @@ /* NetHack may be freely redistributed. See license for details. */ #include "winMS.h" +#include #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) ); -} \ 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; +} diff --git a/win/win32/mhmap.c b/win/win32/mhmap.c index 4d046592d..d7b9d29b8 100644 --- a/win/win32/mhmap.c +++ b/win/win32/mhmap.c @@ -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=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 */ diff --git a/win/win32/mhmenu.c b/win/win32/mhmenu.c index 61303afb5..b5e216d12 100644 --- a/win/win32/mhmenu.c +++ b/win/win32/mhmenu.c @@ -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: diff --git a/win/win32/mhmsg.h b/win/win32/mhmsg.h index 34d735e75..709f2dbf1 100644 --- a/win/win32/mhmsg.h +++ b/win/win32/mhmsg.h @@ -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 diff --git a/win/win32/mhmsgwnd.c b/win/win32/mhmsgwnd.c index 169efc954..b257a56ad 100644 --- a/win/win32/mhmsgwnd.c +++ b/win/win32/mhmsgwnd.c @@ -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; iwindow_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) diff --git a/win/win32/mhstatus.c b/win/win32/mhstatus.c index f98a77460..2b4995354 100644 --- a/win/win32/mhstatus.c +++ b/win/win32/mhstatus.c @@ -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: { diff --git a/win/win32/mswproc.c b/win/win32/mswproc.c index 2d2448bf6..18317a284 100644 --- a/win/win32/mswproc.c +++ b/win/win32/mswproc.c @@ -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() { diff --git a/win/win32/resource.h b/win/win32/resource.h index 8cc7dd4b4..caca5debd 100644 --- a/win/win32/resource.h +++ b/win/win32/resource.h @@ -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 diff --git a/win/win32/winMS.h b/win/win32/winMS.h index c2a7d0daa..100499090 100644 --- a/win/win32/winMS.h +++ b/win/win32/winMS.h @@ -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); diff --git a/win/win32/winhack.c b/win/win32/winhack.c index 07b31e8ee..9e1298a38 100644 --- a/win/win32/winhack.c +++ b/win/win32/winhack.c @@ -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))) { diff --git a/win/win32/winhack.rc b/win/win32/winhack.rc index aaa289964..6e7787f7d 100644 --- a/win/win32/winhack.rc +++ b/win/win32/winhack.rc @@ -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