]> granicus.if.org Git - nethack/commitdiff
From <Someone>,
authornethack.allison <nethack.allison>
Tue, 22 Jan 2002 00:30:58 +0000 (00:30 +0000)
committernethack.allison <nethack.allison>
Tue, 22 Jan 2002 00:30:58 +0000 (00:30 +0000)
Fixes:
- menu shortcuts implemented
- most windows close on space (except for menus with
  PICK_ANY style)
- "hilite_pet" option is implemented
- map scrolling is improved somewhat (it now scrolls if
  the char is within 5 spaces from the edge of the map -
  configurable by #define CLIPAROUND_MARGIN)
- added 3  winhack-specific options:

 win32_map_mode:[tiles|ascii4x6|ascii6x8|ascii8x8
                 |ascii16x8|ascii7x12|ascii8x12|ascii15x12
                 |ascii12x16|ascii10x18|fit_to_screen]=20
 win32_align_status:[left|top|right|bottom]
 win32_align_message:[left|top|right|bottom]

Note: aligning status window to left or right edge of the screen does
not look good.

15 files changed:
Files
include/ntconf.h
src/options.c
sys/winnt/nhsetup.bat
win/win32/mhinput.h
win/win32/mhmain.c
win/win32/mhmain.h
win/win32/mhmap.c
win/win32/mhmenu.c
win/win32/mhtext.c
win/win32/mswproc.c
win/win32/resource.h
win/win32/winMS.h
win/win32/winhack.c
win/win32/winhack.rc

diff --git a/Files b/Files
index 9ee2e74a91c8882fd1414e1d97faac8e4a4598c5..01a61dd52fd50c39761e4a6a5f2ecfaac11726cb 100644 (file)
--- a/Files
+++ b/Files
@@ -252,9 +252,10 @@ mhfont.h        mhinput.c       mhinput.h       mhmain.c        mhmain.h
 mhmap.c         mhmap.h         mhmenu.c        mhmenu.h        mhmsg.h
 mhmsgwnd.c      mhmsgwnd.h      mhrip.c         mhrip.h         mhstatus.c
 mhstatus.h      mhtext.c        mhtext.h        mnsel.uu        mnunsel.uu
-mswproc.c       nethack.dsw     recover.dsp     resource.h      tile2bmp.c
-tile2bmp.dsp    tilemap.dsp     tiles.dsp       tiles.mak       winhack.c
-winhack.dsp     winhack.h       winhack.rc      winMS.h         winnt.dsw
+mswproc.c       nethack.dsw     petmark.uu      recover.dsp     resource.h
+tile2bmp.c      tile2bmp.dsp    tilemap.dsp     tiles.dsp       tiles.mak
+winhack.c       winhack.dsp     winhack.h       winhack.rc      winMS.h
+winnt.dsw
 
 
 
index 31ca6a8eba3ef31188afc4109850f5f3aebedc8f..172bc790f1e0adc28f3ac3bf5b3d18681224597d 100644 (file)
@@ -132,4 +132,6 @@ int  _RTLENTRY _EXPFUNC open  (const char _FAR *__path, int __access,... /*unsig
 #endif
 #endif
 
+extern int FDECL(set_win32_option, (const char *, const char *));
+
 #endif /* NTCONF_H */
index 865b1a7ecac027e9fde285084850e0bcfcaca17d..7304ac901164dc85cc397503fea3b60063eeb590 100644 (file)
@@ -301,6 +301,11 @@ static struct Comp_Opt
 #endif
 #if 0
        { "warnlevel", "minimum monster level to trigger warning", 4, SET_IN_GAME },
+#endif
+#ifdef MSWIN_GRAPHICS
+       { "win32_map_mode", "map display mode under Windows", 20, SET_IN_FILE },
+       { "win32_align_status", "status window alignment", 20, SET_IN_FILE },
+       { "win32_align_message", "message window alignment", 20, SET_IN_FILE },
 #endif
        { "windowtype", "windowing system to use", WINTYPELEN, DISP_IN_GAME },
        { (char *)0, (char *)0, 0, 0 }
@@ -1689,6 +1694,52 @@ goodfruit:
        }
 #endif /* MSDOS */
 
+#ifdef MSWIN_GRAPHICS
+       /* win32_map_mode:[tiles|ascii4x6|ascii6x8|ascii8x8|ascii16x8|ascii7x12|ascii8x12|ascii15x12
+                          |ascii12x16|ascii10x18|fit_to_screen] */
+       fullname = "win32_map_mode";
+       if (match_optname(opts, fullname, sizeof("win32_map_mode")-1, TRUE)) {
+               if (negated) {
+                       bad_negation(fullname, FALSE);
+                       return;
+               }
+               else if (!(opts = string_for_env_opt(fullname, opts, FALSE))) {
+                       return;
+               }
+               if (!set_win32_option(fullname, opts))
+                       badoption(opts);
+               return;
+       }
+
+       /* win32_align_status:[left|top|right|bottom] */
+       fullname = "win32_align_status";
+       if (match_optname(opts, fullname, sizeof("win32_align_status")-1, TRUE)) {
+               if (negated) {
+                       bad_negation(fullname, FALSE);
+                       return;
+               }
+               else if (!(opts = string_for_env_opt(fullname, opts, FALSE))) {
+                       return;
+               }
+               if (!set_win32_option(fullname, opts))
+                       badoption(opts);
+               return;
+       }
+       /* win32_align_message:[left|top|right|bottom] */
+       fullname = "win32_align_message";
+       if (match_optname(opts, fullname, sizeof("win32_align_message")-1, TRUE)) {
+               if (negated) {
+                       bad_negation(fullname, FALSE);
+                       return;
+               }
+               else if (!(opts = string_for_env_opt(fullname, opts, FALSE))) {
+                       return;
+               }
+               if (!set_win32_option(fullname, opts))
+                       badoption(opts);
+               return;
+       }
+#endif /* MSWIN_GRAPHICS */
 
        fullname = "windowtype";
        if (match_optname(opts, fullname, 3, TRUE)) {
index 68736f3559090ab5adba108c3593117e449ac9c5..f1f2d8b2ffe00aae1365be9ef1cabf480e98260d 100755 (executable)
@@ -1,4 +1,4 @@
-@REM  SCCS Id: @(#)nhsetup.bat      2002/01/13
+@REM  SCCS Id: @(#)nhsetup.bat      2002/01/21
 @REM  Copyright (c) NetHack PC Development Team 1993, 1996, 2002
 @REM  NetHack may be freely redistributed.  See license for details. 
 @REM  Win32 setup batch file, see Install.nt for details
@@ -96,6 +96,18 @@ copy .\mnunsel.bmp ..\..\win\win32
 :hasmnuns2
 if NOT exist ..\..\win\win32\mnunsel.bmp set err_nouu=Y
 
+if exist ..\..\win\win32\petmark.bmp goto haspm2
+if exist .\petmark.bmp goto haspm1
+if exist ..\..\win\win32\petmark.uu uudecode ..\..\win\win32\petmark.uu >nul
+if exist .\petmark.bmp goto haspm1
+echo Error - No UUDECODE utility to decode ..\..\win\win32\petmark.uu
+goto haspm2
+:haspm1
+echo copy .\petmark.bmp ..\..\win\win32
+copy .\petmark.bmp ..\..\win\win32
+:haspm2
+if NOT exist ..\..\win\win32\petmark.bmp set err_nouu=Y
+
 echo "Decoding/Copying ICONS"
 if exist ..\..\win\win32\nethack.ico goto hasicon2
 if exist .\nethack.ico goto hasicon1
index 294bc9b222ff166474f86153f52b52e7c5676a81..f8037190b878e8471f0e438e760e5fc94aaf1028 100644 (file)
@@ -17,13 +17,14 @@ typedef struct mswin_event {
                } kbd;
 
                struct {
+                       int mod;
                        int x, y;
                } ms;
        };
 } MSNHEvent, *PMSNHEvent;
 
 #define NHEVENT_KBD(c) { MSNHEvent e; e.type=NHEVENT_CHAR; e.kbd.ch=(c); mswin_input_push(&e); }
-#define NHEVENT_MS(_x, _y) { MSNHEvent e; e.type=NHEVENT_MOUSE; e.ms.x=(_x); e.ms.y=(_y); mswin_input_push(&e); }
+#define NHEVENT_MS(_mod, _x, _y) { MSNHEvent e; e.type=NHEVENT_MOUSE; e.ms.mod = (_mod); e.ms.x=(_x); e.ms.y=(_y); mswin_input_push(&e); }
 
 void           mswin_nh_input_init();
 int                    mswin_have_input();
index 2d28919270d79feb063bf52957653b9e04349d52..d76ef74e61b16f40b13c7f36e68eade3c8d6be63 100644 (file)
@@ -175,7 +175,7 @@ LRESULT CALLBACK MainWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPar
                        /* exit gracefully */
                        switch(MessageBox(hWnd, TEXT("Save?"), TEXT("WinHack"), MB_YESNOCANCEL | MB_ICONQUESTION)) {
                        case IDYES:     NHEVENT_KBD('y'); dosave(); break;
-                       case IDNO: NHEVENT_KBD('y'); done2(); break;
+                       case IDNO: NHEVENT_KBD('q'); done(QUIT); break;
                        case IDCANCEL: break;
                        }
                } return 0;
@@ -235,10 +235,14 @@ void mswin_layout_main_window(HWND changed_child)
 {
        winid i;
        POINT pt;
-       RECT client_rt;
+       RECT client_rt, wnd_rect;
        SIZE menu_size;
+       POINT status_org;
        SIZE status_size;
+       POINT msg_org;
        SIZE msg_size;
+       POINT map_org;
+       SIZE map_size;
        HWND wnd_status, wnd_msg;
        PNHMainWindow  data;
 
@@ -257,36 +261,109 @@ void mswin_layout_main_window(HWND changed_child)
        if( IsWindow(wnd_msg) ) { 
                mswin_message_window_size(wnd_msg, &msg_size);
        } else {
-               status_size.cx = status_size.cy = 0;
+               msg_size.cx = msg_size.cy = 0;
+       }
+
+       /* set window positions */
+       SetRect(&wnd_rect, client_rt.left, client_rt.top, client_rt.right, client_rt.bottom);
+       switch(GetNHApp()->winStatusAlign) {
+       case NHWND_ALIGN_LEFT:
+               status_size.cx = (wnd_rect.right-wnd_rect.left)/4;
+               status_size.cy = (wnd_rect.bottom-wnd_rect.top); // that won't look good
+               status_org.x = wnd_rect.left;
+               status_org.y = wnd_rect.top;
+               wnd_rect.left += status_size.cx;
+               break;
+
+       case NHWND_ALIGN_RIGHT:  
+               status_size.cx = (wnd_rect.right-wnd_rect.left)/4; 
+               status_size.cy = (wnd_rect.bottom-wnd_rect.top); // that won't look good
+               status_org.x = wnd_rect.right - status_size.cx;
+               status_org.y = wnd_rect.top;
+               wnd_rect.right -= status_size.cx;
+               break;
+
+       case NHWND_ALIGN_TOP:    
+               status_size.cx = (wnd_rect.right-wnd_rect.left);
+               status_org.x = wnd_rect.left;
+               status_org.y = wnd_rect.top;
+               wnd_rect.top += status_size.cy;
+               break;
+
+       case NHWND_ALIGN_BOTTOM:
+       default:
+               status_size.cx = (wnd_rect.right-wnd_rect.left);
+               status_org.x = wnd_rect.left;
+               status_org.y = wnd_rect.bottom - status_size.cy;
+               wnd_rect.bottom -= status_size.cy;
+               break;
        }
 
+       switch(GetNHApp()->winMessageAlign) {
+       case NHWND_ALIGN_LEFT:
+               msg_size.cx = (wnd_rect.right-wnd_rect.left)/4;
+               msg_size.cy = (wnd_rect.bottom-wnd_rect.top); 
+               msg_org.x = wnd_rect.left;
+               msg_org.y = wnd_rect.top;
+               wnd_rect.left += msg_size.cx;
+               break;
+
+       case NHWND_ALIGN_RIGHT:  
+               msg_size.cx = (wnd_rect.right-wnd_rect.left)/4; 
+               msg_size.cy = (wnd_rect.bottom-wnd_rect.top); 
+               msg_org.x = wnd_rect.right - msg_size.cx;
+               msg_org.y = wnd_rect.top;
+               wnd_rect.right -= msg_size.cx;
+               break;
+
+       case NHWND_ALIGN_TOP:    
+               msg_size.cx = (wnd_rect.right-wnd_rect.left);
+               msg_org.x = wnd_rect.left;
+               msg_org.y = wnd_rect.top;
+               wnd_rect.top += msg_size.cy;
+               break;
+
+       case NHWND_ALIGN_BOTTOM:
+       default:
+               msg_size.cx = (wnd_rect.right-wnd_rect.left);
+               msg_org.x = wnd_rect.left;
+               msg_org.y = wnd_rect.bottom - msg_size.cy;
+               wnd_rect.bottom -= msg_size.cy;
+               break;
+       }
+
+       map_org.x = wnd_rect.left;
+       map_org.y = wnd_rect.top;
+       map_size.cx = wnd_rect.right - wnd_rect.left;
+       map_size.cy = wnd_rect.bottom - wnd_rect.top;
+
        /* go through the windows list and adjust sizes */
        for( i=0; i<MAXWINDOWS; i++ ) {
                if(GetNHApp()->windowlist[i].win && !GetNHApp()->windowlist[i].dead) {
                        switch( GetNHApp()->windowlist[i].type ) {
                        case NHW_STATUS:
                                MoveWindow(GetNHApp()->windowlist[i].win, 
-                                              client_rt.left, 
-                                                  client_rt.top,
-                                                  client_rt.right-client_rt.left
+                                              status_org.x,
+                                                  status_org.y,
+                                                  status_size.cx
                                                   status_size.cy, 
                                                   TRUE );
                                break;
 
                        case NHW_MAP:
                                MoveWindow(GetNHApp()->windowlist[i].win, 
-                                              client_rt.left
-                                                  client_rt.top+status_size.cy,
-                                                  client_rt.right-client_rt.left
-                                                  client_rt.bottom-client_rt.top-msg_size.cy-status_size.cy, 
+                                              map_org.x
+                                                  map_org.y,
+                                                  map_size.cx
+                                                  map_size.cy, 
                                                   TRUE );
                                break;
 
                        case NHW_MESSAGE:
                                MoveWindow(GetNHApp()->windowlist[i].win, 
-                                              client_rt.left,
-                                                  client_rt.bottom-msg_size.cy,
-                                                  client_rt.right-client_rt.left
+                                              msg_org.x, 
+                                                  msg_org.y,
+                                                  msg_size.cx
                                                   msg_size.cy, 
                                                   TRUE );
                                break;
@@ -295,14 +372,14 @@ void mswin_layout_main_window(HWND changed_child)
                                mswin_menu_window_size(GetNHApp()->windowlist[i].win, &menu_size);
                                menu_size.cx = min(menu_size.cx, (client_rt.right-client_rt.left));
 
-                               pt.x = max(0, (int)(client_rt.right-menu_size.cx));
-                               pt.y = client_rt.top+status_size.cy;
+                               pt.x = map_org.x + max(0, (int)(map_size.cx-menu_size.cx));
+                               pt.y = map_org.y;
                                ClientToScreen(GetNHApp()->hMainWnd, &pt);
                                MoveWindow(GetNHApp()->windowlist[i].win, 
                                                   pt.x, 
                                                   pt.y,
-                                                  min(menu_size.cx, client_rt.right), 
-                                                  client_rt.bottom-client_rt.top-msg_size.cy-status_size.cy, 
+                                                  min(menu_size.cx, map_size.cx), 
+                                                  map_size.cy, 
                                                   TRUE );
                                break;
                        }
index 4e4eac21aa967f2fba6f876873c734493201767f..5b07a7065a180027f7f5c8ff6fd482108711b757 100644 (file)
@@ -8,6 +8,11 @@
 
 #include "winMS.h"
 
+#define NHWND_ALIGN_LEFT       0 
+#define NHWND_ALIGN_RIGHT   1
+#define NHWND_ALIGN_TOP     2
+#define NHWND_ALIGN_BOTTOM  3
+
 HWND mswin_init_main_window ();
 void mswin_layout_main_window(HWND changed_child);
 
index 3d2f6a447ce1dd08b23b5062d884a8826796326d..456a0f2875217b38811ad5df60c92373e2370ae2 100644 (file)
@@ -9,6 +9,7 @@
 
 #define NHMAP_FONT_NAME TEXT("Terminal")
 #define MAXWINDOWTEXT 255
+#define CLIPAROUND_MARGIN  5
 
 extern short glyph2tile[];
 
@@ -262,7 +263,7 @@ void register_map_window_class()
        ZeroMemory( &wcex, sizeof(wcex));
 
        /* window class */
-       wcex.style                      = CS_NOCLOSE;
+       wcex.style                      = CS_NOCLOSE | CS_DBLCLKS;
        wcex.lpfnWndProc        = (WNDPROC)MapWndProc;
        wcex.cbClsExtra         = 0;
        wcex.cbWndExtra         = 0;
@@ -329,10 +330,19 @@ LRESULT CALLBACK MapWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPara
 
        case WM_LBUTTONDOWN:
                NHEVENT_MS( 
+                       CLICK_1,
                        max(0, min(COLNO, data->xPos + (LOWORD(lParam)-data->map_orig.x)/data->xScrTile)),
                        max(0, min(ROWNO, data->yPos + (HIWORD(lParam)-data->map_orig.y)/data->yScrTile))
                );
-       break;
+       return 0;
+
+       case WM_LBUTTONDBLCLK :
+               NHEVENT_MS( 
+                       CLICK_2,
+                       max(0, min(COLNO, data->xPos + (LOWORD(lParam)-data->map_orig.x)/data->xScrTile)),
+                       max(0, min(ROWNO, data->yPos + (HIWORD(lParam)-data->map_orig.y)/data->yScrTile))
+               );
+       return 0;
 
        case WM_DESTROY:
                if( data->hMapFont ) DeleteObject(data->hMapFont);
@@ -369,16 +379,39 @@ void onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
        {
                PMSNHMsgClipAround msg_data = (PMSNHMsgClipAround)lParam;
                int x, y;
-
-               /* get page size and center horizontally on x-position*/
-               if( !GetNHApp()->bNoHScroll ) {
-                       x = max(0, min(COLNO, msg_data->x - data->xPageSize/2));
+               BOOL scroll_x, scroll_y;
+
+               /* calculate if you should clip around */
+               scroll_x =  
+                       !GetNHApp()->bNoHScroll &&
+                       ( msg_data->x<(data->xPos+CLIPAROUND_MARGIN) ||
+                         msg_data->x>(data->xPos+data->xPageSize-CLIPAROUND_MARGIN) );
+               scroll_y =  
+                       !GetNHApp()->bNoVScroll &&
+                       ( msg_data->y<(data->yPos+CLIPAROUND_MARGIN) ||
+                         msg_data->y>(data->yPos+data->yPageSize-CLIPAROUND_MARGIN) );
+               
+               /* get page size and center horizontally on x-position */
+               if( scroll_x ) {
+                       if( data->xPageSize<=2*CLIPAROUND_MARGIN ) {
+                               x = max(0, min(COLNO, msg_data->x - data->xPageSize/2));
+                       } else if( msg_data->x < data->xPos+data->xPageSize/2 ) {
+                               x = max(0, min(COLNO, msg_data->x - CLIPAROUND_MARGIN));
+                       } else {
+                               x = max(0, min(COLNO, msg_data->x - data->xPageSize + CLIPAROUND_MARGIN));
+                       }
                        SendMessage( hWnd, WM_HSCROLL, (WPARAM)MAKELONG(SB_THUMBTRACK, x), (LPARAM)NULL );
                }
 
-               /* get page size and center vertically on y-position*/
-               if( !GetNHApp()->bNoVScroll ) {
-                       y = max(0, min(ROWNO, msg_data->y - data->yPageSize/2));
+               /* get page size and center vertically on y-position */
+               if( scroll_y ) {
+                       if( data->yPageSize<=2*CLIPAROUND_MARGIN ) {
+                               y = max(0, min(ROWNO, msg_data->y - data->yPageSize/2));
+                       } else if( msg_data->y < data->yPos+data->yPageSize/2 ) {
+                               y = max(0, min(ROWNO, msg_data->y - CLIPAROUND_MARGIN));
+                       } else {
+                               y = max(0, min(ROWNO, msg_data->y - data->yPageSize + CLIPAROUND_MARGIN));
+                       }
                        SendMessage( hWnd, WM_VSCROLL, (WPARAM)MAKELONG(SB_THUMBTRACK, y), (LPARAM)NULL );
                }
        } 
@@ -495,8 +528,7 @@ void onPaint(HWND hWnd)
                                
                                nhglyph2charcolor(data->map[i][j], &ch, &color);
                                
-                               if( color == NO_COLOR ) continue;
-                               else SetTextColor( hDC,  nhcolor_to_RGB(color) );
+                               SetTextColor( hDC,  nhcolor_to_RGB(color) );
 
                                nhcoord2display(data, i, j, &glyph_rect);
                                DrawText(hDC, 
@@ -539,6 +571,32 @@ void onPaint(HWND hWnd)
                                                TILE_Y, 
                                                SRCCOPY 
                                        );
+                                       if( glyph_is_pet(data->map[i][j]) && iflags.hilite_pet ) {
+                                               /* apply pet mark transparently over 
+                                                  pet image */
+                                               HDC hdcPetMark;
+                                               HBITMAP    bmPetMarkOld;
+
+                                               /* this is DC for petmark bitmap */
+                                               hdcPetMark = CreateCompatibleDC(hDC);
+                                               bmPetMarkOld = SelectObject(hdcPetMark, GetNHApp()->bmpPetMark);
+
+                                               nhapply_image_transparent( 
+                                                       hDC,
+                                                       glyph_rect.left,
+                                                       glyph_rect.top, 
+                                                       data->xScrTile,
+                                                       data->yScrTile,
+                                                       hdcPetMark,
+                                                       0,
+                                                       0,
+                                                       TILE_X, 
+                                                       TILE_Y,
+                                                       TILE_BK_COLOR 
+                                               );
+                                               SelectObject(hdcPetMark, bmPetMarkOld);
+                                               DeleteDC(hdcPetMark);
+                                       }
                                }
                        SelectObject(tileDC, saveBmp);
                        DeleteDC(tileDC);
@@ -752,7 +810,7 @@ COLORREF nhcolor_to_RGB(int c)
        case CLR_MAGENTA:               return RGB(255,   0, 255);      
        case CLR_CYAN:                  return RGB(  0, 255, 255);              
        case CLR_GRAY:                  return RGB(192, 192, 192);      
-       case NO_COLOR:                  return RGB(  0,   0,   0);              
+       case NO_COLOR:                  return RGB(255, 255, 255);              
        case CLR_ORANGE:                return RGB(255, 165,   0);      
        case CLR_BRIGHT_GREEN:  return RGB(  0, 255,   0);
        case CLR_YELLOW:                return RGB(255, 255,   0);      
@@ -763,3 +821,87 @@ COLORREF nhcolor_to_RGB(int c)
        default:                                return RGB(  0,   0,   0);      /* black */
        }
 }
+
+/* apply bitmap pointed by sourceDc transparently over 
+   bitmap pointed by hDC */
+void nhapply_image_transparent( 
+       HDC hDC, int x, int y, int width, int height,
+       HDC sourceDC, int s_x, int s_y, int s_width, int s_height,
+       COLORREF cTransparent
+)
+{
+       HDC        hdcMem, hdcBack, hdcObject, hdcSave;
+       COLORREF   cColor;
+       HBITMAP    bmAndBack, bmAndObject, bmAndMem, bmSave;
+       HBITMAP    bmBackOld, bmObjectOld, bmMemOld, bmSaveOld;
+
+       /* Create some DCs to hold temporary data. */
+       hdcBack   = CreateCompatibleDC(hDC);
+       hdcObject = CreateCompatibleDC(hDC);
+       hdcMem    = CreateCompatibleDC(hDC);
+       hdcSave   = CreateCompatibleDC(hDC);
+
+       /* this is bitmap for our pet image */
+       bmSave = CreateCompatibleBitmap(hDC, s_width, s_height);
+
+       /* Monochrome DC */
+       bmAndBack   = CreateBitmap(s_width, s_height, 1, 1, NULL);
+       bmAndObject = CreateBitmap(s_width, s_height, 1, 1, NULL);
+
+       /* resulting bitmap */
+       bmAndMem    = CreateCompatibleBitmap(hDC, s_width, s_height);
+
+       /* Each DC must select a bitmap object to store pixel data. */
+       bmBackOld   = SelectObject(hdcBack, bmAndBack);
+       bmObjectOld = SelectObject(hdcObject, bmAndObject);
+       bmMemOld    = SelectObject(hdcMem, bmAndMem);
+       bmSaveOld   = SelectObject(hdcSave, bmSave);
+
+       /* copy source image because it is going to be overwritten */
+       BitBlt(hdcSave, 0, 0, s_width, s_height, sourceDC, s_x, s_y, SRCCOPY);
+
+       /* Set the background color of the source DC to the color.
+          contained in the parts of the bitmap that should be transparent */
+       cColor = SetBkColor(hdcSave, cTransparent);
+
+       /* Create the object mask for the bitmap by performing a BitBlt
+          from the source bitmap to a monochrome bitmap. */
+       BitBlt(hdcObject, 0, 0, s_width, s_height, hdcSave, 0, 0, SRCCOPY);
+
+       /* Set the background color of the source DC back to the original
+          color. */
+       SetBkColor(hdcSave, cColor);
+
+       /* Create the inverse of the object mask. */
+       BitBlt(hdcBack, 0, 0, s_width, s_height, hdcObject, 0, 0, NOTSRCCOPY);
+
+       /* Copy background to the resulting image  */
+       StretchBlt(hdcMem, 0, 0, s_width, s_height, hDC, x, y, width, height, SRCCOPY);
+
+       /* Mask out the places where the source image will be placed. */
+       BitBlt(hdcMem, 0, 0, s_width, s_height, hdcObject, 0, 0, SRCAND);
+
+       /* Mask out the transparent colored pixels on the source image. */
+       BitBlt(hdcSave, 0, 0, s_width, s_height, hdcBack, 0, 0, SRCAND);
+
+       /* XOR the source image with the beckground. */
+       BitBlt(hdcMem, 0, 0, s_width, s_height, hdcSave, 0, 0, SRCPAINT);
+
+       /* blt resulting image to the screen */
+       StretchBlt( 
+               hDC, 
+               x, y, width, height, hdcMem,
+               0, 0, s_width, s_height, SRCCOPY 
+       );
+
+       /* cleanup */
+       DeleteObject(SelectObject(hdcBack, bmBackOld));
+       DeleteObject(SelectObject(hdcObject, bmObjectOld));
+       DeleteObject(SelectObject(hdcMem, bmMemOld));
+       DeleteObject(SelectObject(hdcSave, bmSaveOld));
+
+       DeleteDC(hdcMem);
+       DeleteDC(hdcBack);
+       DeleteDC(hdcObject);
+       DeleteDC(hdcSave);
+}
\ No newline at end of file
index 79e2a8ef34dbd29384a4394fb24c74bdb0537d63..3cc88053508c9d52ab66e9aaadd6ee2c4f9e64af 100644 (file)
@@ -3,7 +3,6 @@
 
 #include "winMS.h"
 #include <assert.h>
-#include <richedit.h>
 #include "resource.h"
 #include "mhmenu.h"
 #include "mhmain.h"
@@ -35,8 +34,7 @@ typedef struct mswin_nethack_menu_window {
                } menu;
 
                struct menu_text {
-                       int                             size;
-                       char*                   text;
+                       TCHAR*                  text;
                } text;
        };
        int result;
@@ -54,17 +52,12 @@ LRESULT CALLBACK    MenuWndProc(HWND, UINT, WPARAM, LPARAM);
 static void onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM lParam);
 static LRESULT onMeasureItem(HWND hWnd, WPARAM wParam, LPARAM lParam);
 static LRESULT onDrawItem(HWND hWnd, WPARAM wParam, LPARAM lParam);
+static LRESULT onListChar(HWND hWnd, HWND hwndList, WORD ch);
 static void LayoutMenu(HWND hwnd);
 static void SetMenuType(HWND hwnd, int type);
 static void SetMenuListType(HWND hwnd, int now);
 static HWND GetMenuControl(HWND hwnd);
-DWORD CALLBACK NHTextStreamCallback(
-  DWORD dwCookie, // application-defined value
-  LPBYTE pbBuff,      // data buffer
-  LONG cb,            // number of bytes to read or write
-  LONG *pcb           // number of bytes transferred
-);
-
+static int GetListPageSize( HWND hwndList );
 
 HWND mswin_init_menu_window (int type) {
        HWND ret;
@@ -256,6 +249,7 @@ LRESULT CALLBACK MenuWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPar
 
        case WM_SIZE:
                LayoutMenu(hWnd);
+       break;
        return FALSE;
 
        case WM_COMMAND: 
@@ -293,7 +287,6 @@ LRESULT CALLBACK MenuWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPar
                        }
                }
                break;
-
                }
        } break;
 
@@ -309,7 +302,7 @@ LRESULT CALLBACK MenuWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPar
     case WM_DRAWITEM:
                return onDrawItem(hWnd, wParam, lParam);
 
-       case WM_VKEYTOITEM: 
+       case WM_VKEYTOITEM:
        { 
                WORD c[4];
                BYTE kbd_state[256];
@@ -319,29 +312,16 @@ LRESULT CALLBACK MenuWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPar
                GetKeyboardState(kbd_state);
                
                if( ToAscii( LOWORD(wParam), 0, kbd_state, c, 0)==1 ) {
-                       int i = 0;
-                       for(i=0; i<data->menu.size; i++ ) {
-                               if( data->menu.items[i].accelerator == c[0] ) {
-                                       if( data->how == PICK_ANY ) {
-                                               SendMessage((HWND)lParam, 
-                                                               LB_SETSEL, 
-                                                                       (WPARAM)!SendMessage((HWND)lParam, LB_GETSEL, (WPARAM)i, (LPARAM)0),
-                                                                       (LPARAM)i);
-                                               return -2;
-                                       } else if( data->how == PICK_ONE ) {
-                                               SendMessage((HWND)lParam, LB_SETCURSEL, (WPARAM)i, (LPARAM)0);
-                                               data->result = 0;
-                                               data->done = 1;
-                                               return -2;
-                                       }
-                               }
-                       }
+                       return onListChar(hWnd, (HWND)lParam, c[0]);
                }
        } return -1;
 
        case WM_DESTROY:
                DeleteObject(data->bmpChecked);
                DeleteObject(data->bmpNotChecked);
+               if( data->type == MENU_TYPE_TEXT ) {
+                       if( data->text.text ) free(data->text.text);
+               }
                free(data);
                SetWindowLong(hWnd, GWL_USERDATA, (LONG)0);
                return TRUE;
@@ -359,37 +339,28 @@ void onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
        {
                PMSNHMsgPutstr msg_data = (PMSNHMsgPutstr)lParam;
                HWND   text_view;
-               EDITSTREAM txt_edit;
-               CHARFORMAT txt_format;
+               TCHAR   wbuf[BUFSZ];
+               size_t text_size;
 
                if( data->type!=MENU_TYPE_TEXT )
                        SetMenuType(hWnd, MENU_TYPE_TEXT);
 
+               if( !data->text.text ) {
+                       text_size = strlen(msg_data->text) + 4;
+                       data->text.text = (TCHAR*)malloc(text_size*sizeof(data->text.text[0]));
+                       ZeroMemory(data->text.text, text_size*sizeof(data->text.text[0]));
+               } else {
+                       text_size = _tcslen(data->text.text) + strlen(msg_data->text) + 4;
+                       data->text.text = (TCHAR*)realloc(data->text.text, text_size*sizeof(data->text.text[0]));
+               }
+               if( !data->text.text ) break;
+               
+               _tcscat(data->text.text, NH_A2W(msg_data->text, wbuf, BUFSZ)); 
+               _tcscat(data->text.text, TEXT("\r\n"));
+               
                text_view = GetDlgItem(hWnd, IDC_MENU_TEXT);
                if( !text_view ) panic("cannot get text view window");
-       
-               /* apply text format to the selection */
-               ZeroMemory(&txt_format, sizeof(txt_format));
-               txt_format.cbSize = sizeof(txt_format); 
-               txt_format.dwMask = CFM_BOLD | CFM_ITALIC | CFM_STRIKEOUT; 
-               txt_format.dwEffects = 
-                               ((msg_data->attr==ATR_BOLD || msg_data->attr==ATR_INVERSE)? CFE_BOLD : 0)  |
-                               ((msg_data->attr==ATR_BLINK)? CFE_ITALIC : 0) | 
-                               ((msg_data->attr==ATR_ULINE)? CFE_STRIKEOUT : 0)
-                               ;
-               /* txt_format.yHeight;  */
-               /* txt_format.yOffset;  */
-               /* txt_format.crTextColor; */
-               /* txt_format.bCharSet; */
-               /* txt_format.bPitchAndFamily = FIXED_PITCH; */
-               /* txt_format.szFaceName[LF_FACESIZE]; */
-               SendMessage(text_view, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&txt_format); 
-
-               /* inject text into control (see NHTextStreamCallback) */
-               ZeroMemory(&txt_edit, sizeof(txt_edit));
-               txt_edit.dwCookie = (DWORD)msg_data->text;
-               txt_edit.pfnCallback = NHTextStreamCallback;
-               SendMessage(text_view, EM_STREAMIN, SF_TEXT | SFF_SELECTION, (LPARAM)&txt_edit);
+               SetWindowText(text_view, data->text.text);
        } break;
 
        case MSNH_MSG_STARTMENU:
@@ -433,8 +404,6 @@ void onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
 void LayoutMenu(HWND hWnd) 
 {
        PNHMenuWindow data;
-//     HWND  menu_list;
-//     HWND  menu_text;
        HWND  menu_ok;
        HWND  menu_cancel;
        RECT  clrt, rt;
@@ -442,8 +411,6 @@ void LayoutMenu(HWND hWnd)
        SIZE  sz_elem, sz_ok, sz_cancel;
 
        data = (PNHMenuWindow)GetWindowLong(hWnd, GWL_USERDATA);
-//     menu_list = GetDlgItem(hWnd, IDC_MENU_LIST);
-//     menu_text = GetDlgItem(hWnd, IDC_MENU_TEXT);
        menu_ok = GetDlgItem(hWnd, IDOK);
        menu_cancel = GetDlgItem(hWnd, IDCANCEL);
 
@@ -479,7 +446,6 @@ void SetMenuType(HWND hWnd, int type)
        HWND list, text;
 
        data = (PNHMenuWindow)GetWindowLong(hWnd, GWL_USERDATA);
-//     if( type == data->type ) return;
 
        data->type = type;
        
@@ -525,13 +491,14 @@ void SetMenuListType(HWND hWnd, int how)
        case PICK_ONE: 
                dwStyles = WS_VISIBLE | WS_TABSTOP | WS_BORDER | WS_CHILD 
                        | WS_VSCROLL | WS_HSCROLL | LBS_WANTKEYBOARDINPUT
-                       | LBS_NOTIFY | LBS_NOINTEGRALHEIGHT     | LBS_OWNERDRAWFIXED; 
+                       | LBS_NOTIFY | LBS_NOINTEGRALHEIGHT     | LBS_OWNERDRAWFIXED 
+                       | LBS_HASSTRINGS; 
                break;
        case PICK_ANY: 
                dwStyles = WS_VISIBLE | WS_TABSTOP | WS_BORDER | WS_CHILD 
                        | WS_VSCROLL | WS_HSCROLL | LBS_WANTKEYBOARDINPUT
                        | LBS_NOTIFY | LBS_NOINTEGRALHEIGHT | LBS_MULTIPLESEL 
-                       | LBS_OWNERDRAWFIXED; 
+                       | LBS_OWNERDRAWFIXED | LBS_HASSTRINGS
                break;
        default: panic("how should be one of PICK_NONE, PICK_ONE or PICK_ANY");
        };
@@ -617,7 +584,6 @@ LRESULT onDrawItem(HWND hWnd, WPARAM wParam, LPARAM lParam)
        PNHMenuItem item;
        PNHMenuWindow data;
     TEXTMETRIC tm;
-       HGDIOBJ saveBmp;
        HGDIOBJ saveFont;
        HGDIOBJ savePen;
        HPEN    pen;
@@ -630,7 +596,7 @@ LRESULT onDrawItem(HWND hWnd, WPARAM wParam, LPARAM lParam)
        lpdis = (LPDRAWITEMSTRUCT) lParam; 
 
     /* If there are no list box items, skip this message. */
-    if (lpdis->itemID == -1) return FALSE;
+    if ( (int)(lpdis->itemID) < 0) return FALSE;
 
        data = (PNHMenuWindow)GetWindowLong(hWnd, GWL_USERDATA);
     switch (lpdis->itemAction) 
@@ -647,6 +613,7 @@ LRESULT onDrawItem(HWND hWnd, WPARAM wParam, LPARAM lParam)
 
                        /* print check mark */
                        if( NHMENU_IS_SELECTABLE(*item) ) {
+                               HGDIOBJ saveBmp;
                                char buf[2];
 
                                saveBmp = SelectObject(tileDC, 
@@ -664,16 +631,25 @@ LRESULT onDrawItem(HWND hWnd, WPARAM wParam, LPARAM lParam)
                                        TextOut(lpdis->hDC, x, y, NH_A2W(buf, wbuf, sizeof(wbuf)), 1); 
                                }
                                x += tm.tmAveCharWidth + 5;
+                               SelectObject(tileDC, saveBmp);
                        }
-                       
-                       SelectObject(tileDC, GetNHApp()->bmpTiles);
-                       ntile = glyph2tile[ item->glyph ];
-                       t_x = (ntile % TILES_PER_LINE)*TILE_X;
-                       t_y = (ntile / TILES_PER_LINE)*TILE_Y;
 
-                       y = (lpdis->rcItem.bottom + lpdis->rcItem.top - TILE_Y) / 2; 
+                       /* print glyph if present */
+                       if( item->glyph != NO_GLYPH ) {
+                               HGDIOBJ saveBmp;
 
-                       BitBlt(lpdis->hDC, x, y, TILE_X, TILE_Y, tileDC, t_x, t_y, SRCCOPY );
+                               saveBmp = SelectObject(tileDC, GetNHApp()->bmpTiles);                           
+                               ntile = glyph2tile[ item->glyph ];
+                               t_x = (ntile % TILES_PER_LINE)*TILE_X;
+                               t_y = (ntile / TILES_PER_LINE)*TILE_Y;
+
+                               y = (lpdis->rcItem.bottom + lpdis->rcItem.top - TILE_Y) / 2; 
+
+                               nhapply_image_transparent(
+                                       lpdis->hDC, x, y, TILE_X, TILE_Y, 
+                                       tileDC, t_x, t_y, TILE_X, TILE_Y, TILE_BK_COLOR );
+                               SelectObject(tileDC, saveBmp);
+                       }
                        x += TILE_X + 5;
 
             y = (lpdis->rcItem.bottom + lpdis->rcItem.top - 
@@ -686,8 +662,8 @@ LRESULT onDrawItem(HWND hWnd, WPARAM wParam, LPARAM lParam)
                 strlen(item->str)); 
 
                        mswin_destroy_font(SelectObject(lpdis->hDC, saveFont));
-                       SelectObject(tileDC, saveBmp);
                        DeleteDC(tileDC);
+                       
             break; 
 
         case ODA_FOCUS:
@@ -712,6 +688,168 @@ LRESULT onDrawItem(HWND hWnd, WPARAM wParam, LPARAM lParam)
        return TRUE;
 }
 
+LRESULT onListChar(HWND hWnd, HWND hwndList, WORD ch)
+{
+       int i = 0;
+       PNHMenuWindow data;
+       int topIndex, pageSize;
+
+       data = (PNHMenuWindow)GetWindowLong(hWnd, GWL_USERDATA);
+
+       switch( ch ) {
+       case MENU_FIRST_PAGE:
+               SendMessage(hwndList, LB_SETTOPINDEX, 0, 0);
+       return -2;
+
+       case MENU_LAST_PAGE:
+               SendMessage(hwndList, 
+                                       LB_SETTOPINDEX, 
+                                       (WPARAM)max(0, data->menu.size-1),
+                                       (LPARAM)0);
+       return -2;
+
+       case MENU_NEXT_PAGE:
+               topIndex = (int)SendMessage( hwndList, LB_GETTOPINDEX, 0, 0 );
+               pageSize = GetListPageSize( hwndList );
+               SendMessage(hwndList, 
+                                       LB_SETTOPINDEX, 
+                                       (WPARAM)min(topIndex+pageSize, data->menu.size-1),
+                                       (LPARAM)0);
+       return -2;
+
+       case MENU_PREVIOUS_PAGE:
+               topIndex = (int)SendMessage( hwndList, LB_GETTOPINDEX, 0, 0 );
+               pageSize = GetListPageSize( hwndList );
+               SendMessage(hwndList, 
+                                       LB_SETTOPINDEX, 
+                                       (WPARAM)max(topIndex-pageSize, 0),
+                                       (LPARAM)0);
+       break;
+
+       case MENU_SELECT_ALL:
+               if( data->how == PICK_ANY ) {
+                       for(i=0; i<data->menu.size; i++ ) {
+                               SendMessage(hwndList, LB_SETSEL, (WPARAM)TRUE, (LPARAM)i);
+                       }
+                       return -2;
+               }
+       break;
+
+       case MENU_UNSELECT_ALL:
+               if( data->how == PICK_ANY ) {
+                       for(i=0; i<data->menu.size; i++ ) {
+                               SendMessage(hwndList, LB_SETSEL, (WPARAM)FALSE, (LPARAM)i);
+                       }
+                       return -2;
+               }
+       break;
+
+       case MENU_INVERT_ALL:
+               if( data->how == PICK_ANY ) {
+                       for(i=0; i<data->menu.size; i++ ) {
+                               SendMessage(hwndList, 
+                                                       LB_SETSEL, 
+                                                       (WPARAM)!SendMessage(hwndList, LB_GETSEL, (WPARAM)i, (LPARAM)0),
+                                                       (LPARAM)i);
+                       }
+                       return -2;
+               }
+       break;
+
+       case MENU_SELECT_PAGE:
+               if( data->how == PICK_ANY ) {
+                       topIndex = (int)SendMessage( hwndList, LB_GETTOPINDEX, 0, 0 );
+                       pageSize = GetListPageSize( hwndList );
+                       for(i=0; i<pageSize; i++ ) {
+                               SendMessage(hwndList, LB_SETSEL, (WPARAM)TRUE, (LPARAM)topIndex+i);
+                       }
+                       return -2;
+               }
+       break;
+
+       case MENU_UNSELECT_PAGE:
+               if( data->how == PICK_ANY ) {
+                       topIndex = (int)SendMessage( hwndList, LB_GETTOPINDEX, 0, 0 );
+                       pageSize = GetListPageSize( hwndList );
+                       for(i=0; i<pageSize; i++ ) {
+                               SendMessage(hwndList, LB_SETSEL, (WPARAM)FALSE, (LPARAM)topIndex+i);
+                       }
+                       return -2;
+               }
+       break;
+
+       case MENU_INVERT_PAGE:
+               if( data->how == PICK_ANY ) {
+                       topIndex = (int)SendMessage( hwndList, LB_GETTOPINDEX, 0, 0 );
+                       pageSize = GetListPageSize( hwndList );
+                       for(i=0; i<pageSize; i++ ) {
+                               SendMessage(hwndList, 
+                                                       LB_SETSEL, 
+                                                       (WPARAM)!SendMessage(hwndList, LB_GETSEL, (WPARAM)topIndex+i, (LPARAM)0),
+                                                       (LPARAM)topIndex+i);
+                       }
+                       return -2;
+               }
+       break;
+
+       case MENU_SEARCH:
+           if( data->how==PICK_ANY || data->how==PICK_ONE ) {
+                       char buf[BUFSZ];
+                       mswin_getlin("Search for:", buf);
+                       if (!*buf || *buf == '\033') return -2;
+                       for(i=0; i<data->menu.size; i++ ) {
+                               if( NHMENU_IS_SELECTABLE(data->menu.items[i])
+                                       && strstr(data->menu.items[i].str, buf) ) {
+                                       if (data->how == PICK_ANY) {
+                                               SendMessage(hwndList, 
+                                                                       LB_SETSEL, 
+                                                                       (WPARAM)!SendMessage(hwndList, LB_GETSEL, (WPARAM)i, (LPARAM)0),
+                                                                       (LPARAM)i);
+                                       } else if( data->how == PICK_ONE ) {
+                                               SendMessage(hwndList, LB_SETCURSEL, (WPARAM)i, (LPARAM)0);
+                                               break;
+                                       }
+                               }
+                       } 
+               } else {
+                       mswin_nhbell();
+           }
+       return -2;
+
+       case ' ':
+               if( data->how==PICK_ONE || data->how==PICK_NONE ) {
+                       data->done = 1;
+                       data->result = 0;
+                       return -2;
+               }
+       break;
+       
+       default:
+               if( (ch>='a' && ch<='z') ||
+                       (ch>='A' && ch<='Z') ) {
+                       for(i=0; i<data->menu.size; i++ ) {
+                               if( data->menu.items[i].accelerator == ch ) {
+                                       if( data->how == PICK_ANY ) {
+                                               SendMessage(hwndList, 
+                                                                       LB_SETSEL, 
+                                                                       (WPARAM)!SendMessage(hwndList, LB_GETSEL, (WPARAM)i, (LPARAM)0),
+                                                                       (LPARAM)i);
+                                               return -2;
+                                       } else if( data->how == PICK_ONE ) {
+                                               SendMessage(hwndList, LB_SETCURSEL, (WPARAM)i, (LPARAM)0);
+                                               data->result = 0;
+                                               data->done = 1;
+                                               return -2;
+                                       }
+                               }
+                       }
+               }
+       break;
+       }
+       
+       return -1;
+}
+
 void mswin_menu_window_size (HWND hWnd, LPSIZE sz)
 {
     TEXTMETRIC tm;
@@ -726,7 +864,7 @@ void mswin_menu_window_size (HWND hWnd, LPSIZE sz)
        sz->cy = rt.bottom - rt.top;
 
        data = (PNHMenuWindow)GetWindowLong(hWnd, GWL_USERDATA);
-       if(data) {
+       if(data && data->type==MENU_TYPE_MENU ) {
                hdc = GetDC(GetMenuControl(hWnd));
                saveFont = SelectObject(hdc, mswin_create_font(NHW_MENU, ATR_INVERSE, hdc));
                GetTextMetrics(hdc, &tm);
@@ -742,43 +880,16 @@ void mswin_menu_window_size (HWND hWnd, LPSIZE sz)
        }
 }
 
-DWORD CALLBACK NHTextStreamCallback(
-  DWORD dwCookie, // application-defined value
-  LPBYTE pbBuff,      // data buffer
-  LONG cb,            // number of bytes to read or write
-  LONG *pcb           // number of bytes transferred
-)
+int GetListPageSize( HWND hwndList ) 
 {
-       static int   st = 0;
-       static char* _text_buf = 0;
-       size_t to_copy;
-
-       switch(st) {
-       case 0: 
-               _text_buf = (char*)dwCookie;
-               st = 1;
-               /* fall through */
-
-       case 1:
-               to_copy = min((size_t)cb, strlen(_text_buf));
-               if( *pcb>0 ) {
-                       strncpy((char*)pbBuff, _text_buf, to_copy);
-                       _text_buf += to_copy;
-                       *pcb = (LONG)to_copy;
-               }
-               if( !_text_buf[0] ) st = 3;
-               break;
+   int ntop, nRectheight, nVisibleItems;
+   RECT rc, itemrect;
 
-       case 3: 
-               *pcb = 2;
-               strncpy( (char*)pbBuff, "\r\n", *pcb);
-               st = 4;
-               break;
-               
-       case 4:
-               *pcb = 0;
-               st = 0;
-               break;
-       }
-       return 0;
-}
\ No newline at end of file
+   ntop = SendMessage(hwndList, LB_GETTOPINDEX, 0, 0); /* Top item index. */
+   GetClientRect(hwndList, &rc);                                               /* Get list box rectangle. */
+   nRectheight = rc.bottom - rc.top;                                   /* Compute list box height. */
+
+   SendMessage(hwndList, LB_GETITEMRECT, ntop, (DWORD)(&itemrect)); /* Get current line's rectangle. */
+   nVisibleItems = nRectheight/(itemrect.bottom - itemrect.top);
+   return max(1, nVisibleItems);
+}
index e9a64234f078b2cad7c76c6a72c4aa413dfcb8cb..ec74ad0902915d82cd4bb13e6ff2033b1ee37b46 100644 (file)
@@ -7,20 +7,31 @@
 #include "mhmsg.h"
 #include "mhfont.h"
 
+typedef struct mswin_nethack_text_window {
+       TCHAR*  window_text;
+} NHTextWindow, *PNHTextWindow;
+
 LRESULT CALLBACK       TextWndProc(HWND, UINT, WPARAM, LPARAM);
 static void onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM lParam);
 static void LayoutText(HWND hwnd);
 
 HWND mswin_init_text_window () {
        HWND ret;
+       PNHTextWindow data;
 
        ret = CreateDialog(
                        GetNHApp()->hApp,
-                       MAKEINTRESOURCE(IDD_TEXT),
+                       MAKEINTRESOURCE(IDD_NHTEXT),
                        GetNHApp()->hMainWnd,
                        TextWndProc
        );
        if( !ret ) panic("Cannot create text window");
+
+       data = (PNHTextWindow)malloc(sizeof(NHTextWindow));
+       if( !data ) panic("out of memory");
+
+       ZeroMemory(data, sizeof(NHTextWindow));
+       SetWindowLong(ret, GWL_USERDATA, (LONG)data);
        return ret;
 }
 
@@ -28,12 +39,21 @@ void mswin_display_text_window (HWND hWnd)
 {
        MSG msg;
        RECT rt;
-       HWND map_wnd;
+       PNHTextWindow data;
+       HWND mapWnd;
+       
+       data = (PNHTextWindow)GetWindowLong(hWnd, GWL_USERDATA);
+       if( data && data->window_text ) {
+               HWND control;
+               control = GetDlgItem(hWnd, IDC_TEXT_CONTROL);
+               SendMessage(control, EM_FMTLINES, 1, 0 );
+               SetWindowText(GetDlgItem(hWnd, IDC_TEXT_CONTROL), data->window_text);
+       }
 
        GetNHApp()->hMenuWnd = hWnd;
-       map_wnd = mswin_hwnd_from_winid(WIN_MAP);
-       if( !IsWindow(map_wnd) ) map_wnd = GetNHApp()->hMainWnd;
-       GetWindowRect(map_wnd, &rt);
+       mapWnd = mswin_hwnd_from_winid(WIN_MAP);
+       if( !IsWindow(mapWnd) ) mapWnd = GetNHApp()->hMainWnd;
+       GetWindowRect(mapWnd, &rt);
        MoveWindow(hWnd, rt.left, rt.top, rt.right-rt.left, rt.bottom-rt.top, TRUE);
        ShowWindow(hWnd, SW_SHOW);
        SetFocus(hWnd);
@@ -55,17 +75,22 @@ LRESULT CALLBACK TextWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPar
 {
        HWND control;
        HDC hdc;
-
+       PNHTextWindow data;
+       
+       data = (PNHTextWindow)GetWindowLong(hWnd, GWL_USERDATA);
        switch (message) 
        {
-
        case WM_INITDIALOG:
            /* set text control font */
-               control = GetDlgItem(hWnd, IDC_TEXT_VIEW);
+               control = GetDlgItem(hWnd, IDC_TEXT_CONTROL);
+               if( !control ) {
+                       panic("cannot get text view window");
+               }
+
                hdc = GetDC(control);
                SendMessage(control, WM_SETFONT, (WPARAM)mswin_create_font(NHW_TEXT, ATR_NONE, hdc), 0);
                ReleaseDC(control, hdc);
-               
+
                SetFocus(control);
        return FALSE;
 
@@ -89,34 +114,43 @@ LRESULT CALLBACK TextWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPar
                        SetFocus(GetNHApp()->hMainWnd);
                        return TRUE;
                }
+       break;
+
+       case WM_DESTROY:
+               if( data ) {
+                       if( data->window_text ) free(data->window_text);
+                       free(data);
+                       SetWindowLong(hWnd, GWL_USERDATA, (LONG)0);
+               }
+       break;
+
        }
        return FALSE;
 }
 
 void onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
 {
+       PNHTextWindow data;
+       
+       data = (PNHTextWindow)GetWindowLong(hWnd, GWL_USERDATA);
        switch( wParam ) {
        case MSNH_MSG_PUTSTR: {
                PMSNHMsgPutstr msg_data = (PMSNHMsgPutstr)lParam;
-               HWND   text_view;
-               TCHAR*  text;
                TCHAR   wbuf[BUFSZ];
                size_t text_size;
 
-               text_view = GetDlgItem(hWnd, IDC_TEXT_VIEW);
-               if( !text_view ) panic("cannot get text view window");
-               
-               text_size = GetWindowTextLength(text_view) + strlen(msg_data->text) + 3;
-               text = (TCHAR*)malloc(text_size*sizeof(text[0]));
-               if( !text ) break;
-               ZeroMemory(text, text_size*sizeof(text[0]));
+               if( !data->window_text ) {
+                       text_size = strlen(msg_data->text) + 4;
+                       data->window_text = (TCHAR*)malloc(text_size*sizeof(data->window_text[0]));
+                       ZeroMemory(data->window_text, text_size*sizeof(data->window_text[0]));
+               } else {
+                       text_size = _tcslen(data->window_text) + strlen(msg_data->text) + 4;
+                       data->window_text = (TCHAR*)realloc(data->window_text, text_size*sizeof(data->window_text[0]));
+               }
+               if( !data->window_text ) break;
                
-               GetWindowText(text_view, text, GetWindowTextLength(text_view));
-               _tcscat(text, NH_A2W(msg_data->text, wbuf, sizeof(wbuf))); 
-               _tcscat(text, TEXT("\n"));
-               SetWindowText(text_view, text);
-
-               free(text);
+               _tcscat(data->window_text, NH_A2W(msg_data->text, wbuf, BUFSZ)); 
+               _tcscat(data->window_text, TEXT("\r\n"));
                break;
        }
        }
@@ -130,7 +164,7 @@ void LayoutText(HWND hWnd)
        POINT pt_elem, pt_ok;
        SIZE  sz_elem, sz_ok;
 
-       text = GetDlgItem(hWnd, IDC_TEXT_VIEW);
+       text = GetDlgItem(hWnd, IDC_TEXT_CONTROL);
        btn_ok = GetDlgItem(hWnd, IDOK);
 
        /* get window coordinates */
index a09f98a653db549d53996716c2b8498944fab1a2..19ec2d73c3b735ada7b2f6b457f1f7c686fda256 100644 (file)
@@ -471,7 +471,6 @@ void mswin_display_file(const char *filename,BOOLEAN_P must_exist)
        } else {
                HWND hwnd;
                char line[LLEN];
-               RECT rt;
 
                hwnd = mswin_init_text_window();
 
@@ -487,10 +486,7 @@ void mswin_display_file(const char *filename,BOOLEAN_P must_exist)
                }
                (void) dlb_fclose(f);
 
-               GetNHApp()->hMenuWnd = hwnd;
-               GetWindowRect(mswin_hwnd_from_winid(WIN_MAP), &rt);
-               MoveWindow(hwnd, rt.left, rt.top, rt.right-rt.left, rt.bottom-rt.top, TRUE);
-               ShowWindow(hwnd, SW_SHOW);
+               mswin_display_text_window(hwnd);
        }
 }
 
@@ -788,7 +784,7 @@ int mswin_nh_poskey(int *x, int *y, int *mod)
        while( (event = mswin_input_pop())==NULL ) mswin_main_loop();
 
        if( event->type==NHEVENT_MOUSE ) {
-               *mod = CLICK_1;
+               *mod = event->ms.mod;
                *x = event->ms.x;
                *y = event->ms.y;
                key = 0;
index 48cca55b3143f2629bee3b7ba118c09097cd1f7c..dd5ad49a98a2e8996e72dde492ad5ff3682d76f3 100644 (file)
@@ -14,6 +14,7 @@
 #define IDR_MAINFRAME                   128
 #define IDB_TILES                       129
 #define IDD_TEXT                        130
+#define IDD_NHTEXT                      130
 #define IDD_MENU                        132
 #define IDB_MENU_SEL                    133
 #define IDB_MENU_UNSEL                  134
@@ -21,7 +22,9 @@
 #define IDD_GETLIN                      138
 #define IDD_EXTCMD                      139
 #define IDD_PLAYER_SELECTOR             141
+#define IDB_PETMARK                     143
 #define IDC_TEXT_VIEW                   1000
+#define IDC_TEXT_CONTROL                1000
 #define IDC_CMD_MOVE_NW                 1001
 #define IDC_CMD_MOVE_N                  1002
 #define IDC_MENU_LIST                   1003
 // 
 #ifdef APSTUDIO_INVOKED
 #ifndef APSTUDIO_READONLY_SYMBOLS
-#define _APS_NEXT_RESOURCE_VALUE        143
+#define _APS_NEXT_RESOURCE_VALUE        144
 #define _APS_NEXT_COMMAND_VALUE         32793
-#define _APS_NEXT_CONTROL_VALUE         1329
+#define _APS_NEXT_CONTROL_VALUE         1331
 #define _APS_NEXT_SYMED_VALUE           110
 #endif
 #endif
index 3b5e9cbfb6fb3d0b3d2cd80a295a15099ba33d44..805c2f204566001044c6a3fde2b9a7f602e18618 100644 (file)
@@ -25,6 +25,9 @@
 
 #define TILES_PER_LINE  40
 
+/* tile background color */
+#define TILE_BK_COLOR RGB(71, 108, 108)
+
 typedef struct mswin_nhwindow_data {
   HWND       win;
   int            type;
@@ -40,12 +43,16 @@ typedef struct mswin_nhwindow_app {
        MSNHWinData windowlist[MAXWINDOWS];
 
        HBITMAP         bmpTiles;
+       HBITMAP         bmpPetMark;
 
        boolean         bNoHScroll;     /* disable cliparound for horizontal grid (map) */
        boolean         bNoVScroll; /* disable cliparound for vertical grid (map) */
 
        int                     mapDisplayMode;         /* regular map display mode */
        int                     mapDisplayModeSave;     /* saved map display mode */
+
+       int                     winStatusAlign;         /* alignment of the status window */
+       int                     winMessageAlign;        /* alignment of the status window */
 } NHWinApp, *PNHWinApp;
 extern PNHWinApp GetNHApp();
 
@@ -105,6 +112,11 @@ winid mswin_winid_from_type(int type);
 winid mswin_winid_from_handle(HWND hWnd);
 void mswin_window_mark_dead(winid wid);
 void bail(const char *mesg);
+void nhapply_image_transparent( 
+       HDC hDC, int x, int y, int width, int height,
+       HDC sourceDC, int s_x, int s_y, int s_width, int s_height,
+       COLORREF cTransparent
+);
 
 /* unicode stuff */
 #ifdef UNICODE
index afdf05a5a6911b281829875eea3d6a5e0c097d93..fa1563feccbe1e18fcd69d8dc0e05c27ab63579b 100644 (file)
@@ -51,13 +51,15 @@ int APIENTRY WinMain(HINSTANCE hInstance,
        _nethack_app.hMenuWnd = NULL;
        _nethack_app.bmpTiles = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_TILES));
        if( _nethack_app.bmpTiles==NULL ) panic("cannot load tiles bitmap");
+       _nethack_app.bmpPetMark = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_PETMARK));
+       if( _nethack_app.bmpPetMark==NULL ) panic("cannot load pet mark bitmap");
        _nethack_app.bNoHScroll = FALSE;
        _nethack_app.bNoVScroll = FALSE;
        _nethack_app.mapDisplayMode = NHMAP_VIEW_TILES;
+       _nethack_app.winStatusAlign = NHWND_ALIGN_BOTTOM;
+       _nethack_app.winMessageAlign = NHWND_ALIGN_TOP;
 
        // init controls
-       LoadLibrary( TEXT("RICHED32.DLL") );
-
        ZeroMemory(&InitCtrls, sizeof(InitCtrls));
        InitCtrls.dwSize = sizeof(InitCtrls);
        InitCtrls.dwICC = ICC_LISTVIEW_CLASSES;
@@ -129,3 +131,63 @@ PNHWinApp GetNHApp()
        return &_nethack_app;
 }
 
+/* options */
+struct t_win32_opt_int {
+       const char* val;
+       int   opt;
+};
+static struct t_win32_opt_int _win32_map_mode[] = 
+{
+       { "tiles", NHMAP_VIEW_TILES                             },
+       { "ascii4x6", NHMAP_VIEW_ASCII4x6               },      
+       { "ascii6x8", NHMAP_VIEW_ASCII6x8               },      
+       { "ascii8x8", NHMAP_VIEW_ASCII8x8               },      
+       { "ascii16x8", NHMAP_VIEW_ASCII16x8             },
+       { "ascii7x12", NHMAP_VIEW_ASCII7x12             },
+       { "ascii8x12", NHMAP_VIEW_ASCII8x12             },
+       { "ascii16x12", NHMAP_VIEW_ASCII16x12   },      
+       { "ascii12x16", NHMAP_VIEW_ASCII12x16   },      
+       { "ascii10x18", NHMAP_VIEW_ASCII10x18   },      
+       { "fit_to_screen", NHMAP_VIEW_FIT_TO_SCREEN     },
+       { NULL, -1 }
+};
+
+static struct t_win32_opt_int _win32_align[] = 
+{
+       { "left", NHWND_ALIGN_LEFT },
+       { "right", NHWND_ALIGN_RIGHT },
+       { "top", NHWND_ALIGN_TOP },
+       { "bottom", NHWND_ALIGN_BOTTOM },
+       { NULL, -1 }
+};
+
+int set_win32_option( const char * name, const char * val)
+{
+       struct t_win32_opt_int* p;
+       if( _stricmp(name, "win32_map_mode")==0 ) {
+               for( p=_win32_map_mode; p->val; p++ ) {
+                       if( _stricmp(p->val, val)==0 ){
+                               GetNHApp()->mapDisplayMode = p->opt;
+                               return 1;
+                       }
+               }
+               return 0;
+       } else if( _stricmp(name, "win32_align_status")==0 ) {
+               for( p=_win32_align; p->val; p++ ) {
+                       if( _stricmp(p->val, val)==0 ) {
+                               GetNHApp()->winStatusAlign = p->opt;
+                               return 1;
+                       }
+               }
+               return 0;
+       } else if( _stricmp(name, "win32_align_message")==0 ) {
+               for( p=_win32_align; p->val; p++ ) {
+                       if( _stricmp(p->val, val)==0 ) {
+                               GetNHApp()->winMessageAlign = p->opt;
+                               return 1;
+                       }
+               }
+               return 0;
+       }
+       return 0;
+}
\ No newline at end of file
index 9365bd9747d07422e7c743b70615e7d77f012af2..c857afdaab5caebfe0e94e181f9e3ddba07fc7cf 100644 (file)
@@ -103,31 +103,28 @@ BEGIN
     DEFPUSHBUTTON   "OK",IDOK,195,6,30,11,WS_GROUP
 END
 
-IDD_TEXT DIALOGEX 0, 0, 172, 178
+IDD_NHTEXT DIALOGEX 0, 0, 172, 178
 STYLE DS_SETFOREGROUND | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | 
     WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
 EXSTYLE WS_EX_STATICEDGE
 CAPTION "Text"
-FONT 8, "MS Sans Serif", 0, 0, 0x1
+FONT 8, "MS Sans Serif"
 BEGIN
     DEFPUSHBUTTON   "OK",IDOK,54,163,50,14
-    CONTROL         "",IDC_TEXT_VIEW,"RICHEDIT",ES_MULTILINE | ES_READONLY | 
-                    ES_WANTRETURN | WS_BORDER | WS_VSCROLL | WS_HSCROLL | 
-                    WS_TABSTOP,0,0,173,155
+    EDITTEXT        IDC_TEXT_CONTROL,0,0,170,160,ES_MULTILINE | 
+                    ES_OEMCONVERT | ES_READONLY | WS_VSCROLL | WS_HSCROLL
 END
 
 IDD_MENU DIALOGEX 0, 0, 187, 153
 STYLE WS_POPUP | WS_CLIPSIBLINGS | WS_THICKFRAME
 EXSTYLE WS_EX_CLIENTEDGE | WS_EX_CONTROLPARENT | WS_EX_STATICEDGE
-FONT 8, "MS Sans Serif", 0, 0, 0x1
+FONT 8, "MS Sans Serif"
 BEGIN
     DEFPUSHBUTTON   "OK",IDOK,7,132,50,14,BS_FLAT
     PUSHBUTTON      "Cancel",IDCANCEL,130,132,50,14,BS_FLAT
-    CONTROL         "",IDC_MENU_TEXT,"RICHEDIT",ES_MULTILINE | ES_READONLY | 
-                    ES_WANTRETURN | WS_BORDER | WS_VSCROLL | WS_HSCROLL | 
-                    WS_TABSTOP,7,67,173,61
-    LISTBOX         IDC_MENU_LIST,10,10,170,55,LBS_SORT | 
-                    LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
+    LISTBOX         IDC_MENU_LIST,10,10,170,55,LBS_SORT | WS_TABSTOP
+    EDITTEXT        IDC_MENU_TEXT,10,70,170,60,ES_MULTILINE | ES_OEMCONVERT | 
+                    ES_READONLY | WS_VSCROLL | WS_HSCROLL
 END
 
 IDD_GETLIN DIALOG DISCARDABLE  0, 0, 131, 29
@@ -220,6 +217,7 @@ END
 IDB_TILES               BITMAP  DISCARDABLE     "tiles.bmp"
 IDB_MENU_SEL            BITMAP  DISCARDABLE     "mnsel.bmp"
 IDB_MENU_UNSEL          BITMAP  DISCARDABLE     "mnunsel.bmp"
+IDB_PETMARK             BITMAP  DISCARDABLE     "petmark.bmp"
 
 /////////////////////////////////////////////////////////////////////////////
 //
@@ -229,7 +227,7 @@ IDB_MENU_UNSEL          BITMAP  DISCARDABLE     "mnunsel.bmp"
 #ifdef APSTUDIO_INVOKED
 GUIDELINES DESIGNINFO DISCARDABLE 
 BEGIN
-    IDD_TEXT, DIALOG
+    IDD_NHTEXT, DIALOG
     BEGIN
         BOTTOMMARGIN, 177
     END