]> granicus.if.org Git - nethack/commitdiff
win32gui message history; also clipboard support (from <Someone>)
authornethack.allison <nethack.allison>
Mon, 13 Oct 2003 14:48:13 +0000 (14:48 +0000)
committernethack.allison <nethack.allison>
Mon, 13 Oct 2003 14:48:13 +0000 (14:48 +0000)
- added 2 menu options: Copy ASCII Screenshot To Clipboard, Save
  ASCII Screenshot To File
- implemented saving message history

win/win32/mhmain.c
win/win32/mhmap.c
win/win32/mhmenu.c
win/win32/mhmsg.h
win/win32/mhmsgwnd.c
win/win32/mhstatus.c
win/win32/mswproc.c
win/win32/resource.h
win/win32/winMS.h
win/win32/winhack.c
win/win32/winhack.rc

index 7f56e195f804560a5c451f0dcd61328990090c7b..2d3cbd89779ccd2db283d2ed471e8bdbc476e95f 100644 (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)
        );
-}
\ 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;
+}
index 4d046592d90f54b83960e2ad18ecb5bef1763de6..d7b9d29b86094865a6c63ae6028b8d17929016fe 100644 (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 */
index 61303afb5dd32189843330f53fc5fccc603643c2..b5e216d125cdb33d6c1121bf79c4f2a6e0d71c8d 100644 (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:
index 34d735e751b1ecfcaace1304d1e00130ed026492..709f2dbf1dbaf402fffd760965a357788dfcf4d9 100644 (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
 
index 169efc954483d6522c6c059728106c6e8fe90a62..b257a56adee153c51b43ce38abe83b8bad0d06cb 100644 (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)
index f98a77460ba14a53db9dad4591ed1cddb038cefb..2b4995354d95ae12abc446489c35415a4357f1d3 100644 (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: {
index 2d2448bf6aef1b8a5b27bccfc6df25394012a5bf..18317a28414e31b810a5c521ea92490bdb203c81 100644 (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()
 {
index 8cc7dd4b466349858bc7e64fb7d6f62cd653c52e..caca5debd82b5df74a15951342fe7ea0a2b0a62d 100644 (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
 #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
index c2a7d0daa345a0ae4240e40951a2b3b11c180c20..1004990903dc3c9bfc001db71e1c7a6270f91352 100644 (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);
index 07b31e8ee0b454cee6a2a1f8c5c4befc421cd796..9e1298a382100a0d36b3de2ea878988efe0701a4 100644 (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)))
     {
index aaa289964c15f30a889b8f2049e8040700663bef..6e7787f7d04860b0177d4f626872ad960edb955f 100644 (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