From: nethack.allison Date: Mon, 3 Mar 2003 23:31:36 +0000 (+0000) Subject: win32 stuff held until after bugfix release (from ) X-Git-Tag: MOVE2GIT~2113 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=27977b7c1599824635c1c948067f1bae4a737b73;p=nethack win32 stuff held until after bugfix release (from ) -better handling of "more" prompt for messages that would have scrolled off the window -support perm_invent -menu option to add/remove windows captions --- diff --git a/doc/fixes35.0 b/doc/fixes35.0 index 153362244..8963d41c4 100644 --- a/doc/fixes35.0 +++ b/doc/fixes35.0 @@ -13,6 +13,8 @@ expert fireball/cone of cold could not target a monster seen only with Platform- and/or Interface-Specific Fixes ----------------------------------------- +win32gui: better handling of "more" prompt for messages that would have scrolled + off the window General New Features @@ -21,3 +23,6 @@ General New Features Platform- and/or Interface-Specific New Features ------------------------------------------------ +win32gui: support perm_invent +win32gui: menu option to add/remove windows captions + diff --git a/sys/share/pcmain.c b/sys/share/pcmain.c index 5c8c713e5..be6b4e389 100644 --- a/sys/share/pcmain.c +++ b/sys/share/pcmain.c @@ -410,6 +410,8 @@ char *argv[]; if (discover) You("are in non-scoring discovery mode."); + update_inventory(); + if (discover || wizard) { if(yn("Do you want to keep the save file?") == 'n'){ (void) delete_savefile(); @@ -428,6 +430,7 @@ not_recovered: set_wear(); (void) pickup(1); read_engr_at(u.ux,u.uy); + update_inventory(); } #ifndef NO_SIGNAL diff --git a/win/win32/mhaskyn.c b/win/win32/mhaskyn.c index 81be13373..679f5ac46 100644 --- a/win/win32/mhaskyn.c +++ b/win/win32/mhaskyn.c @@ -9,3 +9,4 @@ int mswin_yes_no_dialog( const char *question, const char *choices, int def) { return '\032'; } + diff --git a/win/win32/mhaskyn.h b/win/win32/mhaskyn.h index a386b0971..688611217 100644 --- a/win/win32/mhaskyn.h +++ b/win/win32/mhaskyn.h @@ -9,3 +9,4 @@ int mswin_yes_no_dialog( const char *question, const char *choices, int def); #endif /* MSWINAskYesNO_h */ + diff --git a/win/win32/mhdlg.c b/win/win32/mhdlg.c index ac1ece2de..325535be5 100644 --- a/win/win32/mhdlg.c +++ b/win/win32/mhdlg.c @@ -727,3 +727,4 @@ int plselFinalSelection(HWND hWnd, int* selection) return TRUE; } + diff --git a/win/win32/mhdlg.h b/win/win32/mhdlg.h index b96483881..b5ad0feaf 100644 --- a/win/win32/mhdlg.h +++ b/win/win32/mhdlg.h @@ -13,3 +13,4 @@ int mswin_ext_cmd_window (int* selection); int mswin_player_selection_window(int* selection); #endif /* MSWINDlgWindow_h */ + diff --git a/win/win32/mhfont.h b/win/win32/mhfont.h index 291bfd32b..08c7ffacb 100644 --- a/win/win32/mhfont.h +++ b/win/win32/mhfont.h @@ -14,3 +14,4 @@ void mswin_destroy_splashfonts(void); UINT mswin_charset(void); #endif /* MSWINFont_h */ + diff --git a/win/win32/mhinput.c b/win/win32/mhinput.c index 77fd5eaf2..946d4797e 100644 --- a/win/win32/mhinput.c +++ b/win/win32/mhinput.c @@ -83,3 +83,4 @@ PMSNHEvent mswin_input_peek() } return retval; } + diff --git a/win/win32/mhinput.h b/win/win32/mhinput.h index 23ed41b0c..36ac48db1 100644 --- a/win/win32/mhinput.h +++ b/win/win32/mhinput.h @@ -33,3 +33,4 @@ PMSNHEvent mswin_input_pop(void); PMSNHEvent mswin_input_peek(void); #endif /* MSWINInput_h */ + diff --git a/win/win32/mhmain.c b/win/win32/mhmain.c index 147d296be..5b4e9a68e 100644 --- a/win/win32/mhmain.c +++ b/win/win32/mhmain.c @@ -27,6 +27,7 @@ static void onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM lParam); static void register_main_window_class(void); static int menuid2mapmode(int menuid); static int mapmode2menuid(int map_mode); +static void nhlock_windows( BOOL lock ); HWND mswin_init_main_window () { static int run_once = 0; @@ -77,8 +78,8 @@ HWND mswin_init_main_window () { } else ShowWindow(ret, SW_SHOWDEFAULT); - UpdateWindow(ret); + UpdateWindow(ret); return ret; } @@ -535,9 +536,7 @@ void onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM lParam) void mswin_layout_main_window(HWND changed_child) { winid i; - POINT pt; RECT client_rt, wnd_rect; - SIZE menu_size; POINT status_org; SIZE status_size; POINT msg_org; @@ -547,144 +546,153 @@ void mswin_layout_main_window(HWND changed_child) HWND wnd_status, wnd_msg; PNHMainWindow data; - GetClientRect(GetNHApp()->hMainWnd, &client_rt); - data = (PNHMainWindow)GetWindowLong(GetNHApp()->hMainWnd, GWL_USERDATA); + if( GetNHApp()->bAutoLayout ) { + GetClientRect(GetNHApp()->hMainWnd, &client_rt); + data = (PNHMainWindow)GetWindowLong(GetNHApp()->hMainWnd, GWL_USERDATA); - /* get sizes of child windows */ - wnd_status = mswin_hwnd_from_winid(WIN_STATUS); - if( IsWindow(wnd_status) ) { - mswin_status_window_size(wnd_status, &status_size); - } else { - status_size.cx = status_size.cy = 0; - } + /* get sizes of child windows */ + wnd_status = mswin_hwnd_from_winid(WIN_STATUS); + if( IsWindow(wnd_status) ) { + mswin_status_window_size(wnd_status, &status_size); + } else { + status_size.cx = status_size.cy = 0; + } - wnd_msg = mswin_hwnd_from_winid(WIN_MESSAGE); - if( IsWindow(wnd_msg) ) { - mswin_message_window_size(wnd_msg, &msg_size); - } else { - msg_size.cx = msg_size.cy = 0; - } + wnd_msg = mswin_hwnd_from_winid(WIN_MESSAGE); + if( IsWindow(wnd_msg) ) { + mswin_message_window_size(wnd_msg, &msg_size); + } else { + 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(iflags.wc_align_status) { - case 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; + /* set window positions */ + SetRect(&wnd_rect, client_rt.left, client_rt.top, client_rt.right, client_rt.bottom); + switch(iflags.wc_align_status) { + case 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 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 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 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 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 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; - } + case 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(iflags.wc_align_message) { - case 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; + switch(iflags.wc_align_message) { + case 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 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 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 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 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 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; - } + case 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; + /* map window */ + 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; + + + GetNHApp()->rtStatusWindow.left = status_org.x; + GetNHApp()->rtStatusWindow.top = status_org.y; + GetNHApp()->rtStatusWindow.right = status_org.x + status_size.cx; + GetNHApp()->rtStatusWindow.bottom= status_org.y + status_size.cy; + + GetNHApp()->rtTextWindow.left = map_org.x; + GetNHApp()->rtTextWindow.top = map_org.y; + GetNHApp()->rtTextWindow.right = map_org.x + (wnd_rect.right - wnd_rect.left); + GetNHApp()->rtTextWindow.bottom = map_org.y + map_size.cy; + + GetNHApp()->rtMapWindow.left = map_org.x; + GetNHApp()->rtMapWindow.top = map_org.y; + GetNHApp()->rtMapWindow.right = map_org.x + map_size.cx; + GetNHApp()->rtMapWindow.bottom = map_org.y + map_size.cy; + + GetNHApp()->rtMsgWindow.left = msg_org.x; + GetNHApp()->rtMsgWindow.top = msg_org.y; + GetNHApp()->rtMsgWindow.right = msg_org.x + msg_size.cx; + GetNHApp()->rtMsgWindow.bottom = msg_org.y + msg_size.cy; + + GetNHApp()->rtMenuWindow.left = map_org.x + map_size.cx*2/3; + GetNHApp()->rtMenuWindow.top = map_org.y; + GetNHApp()->rtMenuWindow.right = map_org.x + map_size.cx; + GetNHApp()->rtMenuWindow.bottom = map_org.y + map_size.cy; + + GetNHApp()->rtInvenWindow.left = GetNHApp()->rtMenuWindow.left; + GetNHApp()->rtInvenWindow.top = GetNHApp()->rtMenuWindow.top; + GetNHApp()->rtInvenWindow.right = GetNHApp()->rtMenuWindow.right; + GetNHApp()->rtInvenWindow.bottom = GetNHApp()->rtMenuWindow.bottom; + + /* adjust map window size only if perm_invent is set */ + if( flags.perm_invent ) + GetNHApp()->rtMapWindow.right = GetNHApp()->rtMenuWindow.left; + } /* go through the windows list and adjust sizes */ for( i=0; iwindowlist[i].win && !GetNHApp()->windowlist[i].dead) { - switch( GetNHApp()->windowlist[i].type ) { - case NHW_STATUS: - MoveWindow(GetNHApp()->windowlist[i].win, - status_org.x, - status_org.y, - status_size.cx, - status_size.cy, - TRUE ); - break; - - case NHW_TEXT: // same as the map window - case NHW_MAP: - MoveWindow(GetNHApp()->windowlist[i].win, - map_org.x, - map_org.y, - map_size.cx, - map_size.cy, - TRUE ); - break; - - case NHW_MESSAGE: - MoveWindow(GetNHApp()->windowlist[i].win, - msg_org.x, - msg_org.y, - msg_size.cx, - msg_size.cy, - TRUE ); - break; - - case NHW_MENU: - 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 = map_org.x + max(0, (int)(map_size.cx-menu_size.cx)); - pt.y = map_org.y; - MoveWindow(GetNHApp()->windowlist[i].win, - pt.x, - pt.y, - min(menu_size.cx, map_size.cx), - map_size.cy, - TRUE ); - break; - } - ShowWindow(GetNHApp()->windowlist[i].win, SW_SHOW); + RECT rt; + /* kludge - inventory window should have its own type (same as menu-text + as a matter of fact) */ + if( flags.perm_invent && i==WIN_INVEN ) + mswin_get_window_placement(NHW_INVEN, &rt); + else + mswin_get_window_placement(GetNHApp()->windowlist[i].type, &rt); + + MoveWindow(GetNHApp()->windowlist[i].win, + rt.left, + rt.top, + rt.right - rt.left, + rt.bottom - rt.top, + TRUE + ); } } } @@ -758,6 +766,17 @@ LRESULT onWMCommand(HWND hWnd, WPARAM wParam, LPARAM lParam) "NetHack", MB_OK | MB_ICONINFORMATION); break; } + + case IDM_SETTING_AUTOLAYOUT: + GetNHApp()->bAutoLayout = TRUE; + mswin_layout_main_window(NULL); + GetNHApp()->bAutoLayout = FALSE; + break; + + case IDM_SETTING_LOCKWINDOWS: + nhlock_windows( !GetNHApp()->bWindowsLocked ); + break; + case IDM_HELP_LONG: display_file(HELP, TRUE); break; @@ -957,3 +976,37 @@ int mapmode2menuid(int map_mode) if(p->mapMode==map_mode ) return p->menuID; return -1; } + +void nhlock_windows( BOOL lock ) +{ + int i; + + /* go through the windows list and adjust sizes */ + for( i=0; iwindowlist[i].win) && !GetNHApp()->windowlist[i].dead) { + DWORD style; + style = GetWindowLong(GetNHApp()->windowlist[i].win, GWL_STYLE); + if( lock ) style &= ~WS_CAPTION; + else style |= WS_CAPTION; + SetWindowLong(GetNHApp()->windowlist[i].win, GWL_STYLE, style); + SetWindowPos( + GetNHApp()->windowlist[i].win, + NULL, + 0, + 0, + 0, + 0, + SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED + ); + } + } + + /* update menu */ + GetNHApp()->bWindowsLocked = lock; + CheckMenuItem( + GetMenu(GetNHApp()->hMainWnd), + IDM_SETTING_LOCKWINDOWS, + MF_BYCOMMAND | + (lock? MF_CHECKED : MF_UNCHECKED) + ); +} \ No newline at end of file diff --git a/win/win32/mhmain.h b/win/win32/mhmain.h index 3f4071448..d422965a0 100644 --- a/win/win32/mhmain.h +++ b/win/win32/mhmain.h @@ -14,3 +14,4 @@ void mswin_select_map_mode(int map_mode); void mswin_menu_check_intf_mode(void); #endif /* MSWINMainWindow_h */ + diff --git a/win/win32/mhmap.c b/win/win32/mhmap.c index de0f8b3ba..4d046592d 100644 --- a/win/win32/mhmap.c +++ b/win/win32/mhmap.c @@ -48,20 +48,29 @@ static COLORREF nhcolor_to_RGB(int c); HWND mswin_init_map_window () { static int run_once = 0; HWND ret; + RECT rt; if( !run_once ) { register_map_window_class(); run_once = 1; } - + + /* get window position */ + if( GetNHApp()->bAutoLayout ) { + SetRect( &rt, 0, 0, 0, 0); + } else { + mswin_get_window_placement(NHW_MAP, &rt); + } + + /* create map window object */ ret = CreateWindow( szNHMapWindowClass, /* registered class name */ NULL, /* window name */ - WS_CHILD | WS_HSCROLL | WS_VSCROLL | WS_CLIPSIBLINGS, /* window style */ - 0, /* horizontal position of window - set it later */ - 0, /* vertical position of window - set it later */ - 0, /* window width - set it later */ - 0, /* window height - set it later*/ + WS_CHILD | WS_HSCROLL | WS_VSCROLL | WS_CLIPSIBLINGS | WS_SIZEBOX, /* window style */ + rt.left, /* horizontal position of window */ + rt.top, /* vertical position of window */ + rt.right - rt.left, /* window width */ + rt.bottom - rt.top, /* window height */ GetNHApp()->hMainWnd, /* handle to parent or owner window */ NULL, /* menu handle or child identifier */ GetNHApp()->hApp, /* handle to application instance */ @@ -69,6 +78,10 @@ HWND mswin_init_map_window () { if( !ret ) { panic("Cannot create map window"); } + + /* Set window caption */ + SetWindowText(ret, "Map"); + return ret; } @@ -349,6 +362,7 @@ LRESULT CALLBACK MapWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPara case WM_SIZE: { + RECT rt; SIZE size; if( data->bFitToScreenMode ) { @@ -360,9 +374,23 @@ LRESULT CALLBACK MapWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPara size.cy = data->yScrTile*ROWNO; } mswin_map_stretch(hWnd, &size, TRUE); + + /* update window placement */ + GetWindowRect(hWnd, &rt); + ScreenToClient(GetNHApp()->hMainWnd, (LPPOINT)&rt); + ScreenToClient(GetNHApp()->hMainWnd, ((LPPOINT)&rt)+1); + mswin_update_window_placement(NHW_MAP, &rt); } 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_MAP, &rt); + } return FALSE; + case WM_LBUTTONDOWN: NHEVENT_MS( CLICK_1, @@ -974,3 +1002,4 @@ void nhapply_image_transparent( DeleteDC(hdcObject); DeleteDC(hdcSave); } + diff --git a/win/win32/mhmap.h b/win/win32/mhmap.h index 401561d9e..772fb3a81 100644 --- a/win/win32/mhmap.h +++ b/win/win32/mhmap.h @@ -19,3 +19,4 @@ int mswin_map_mode(HWND hWnd, int mode); #define DEF_CLIPAROUND_AMOUNT 1 #endif /* MSWINMapWindow_h */ + diff --git a/win/win32/mhmenu.c b/win/win32/mhmenu.c index 94fc0cb09..99bbf83c4 100644 --- a/win/win32/mhmenu.c +++ b/win/win32/mhmenu.c @@ -59,6 +59,8 @@ typedef struct mswin_nethack_menu_window { HBITMAP bmpChecked; HBITMAP bmpCheckedCount; HBITMAP bmpNotChecked; + + BOOL is_active; } NHMenuWindow, *PNHMenuWindow; extern short glyph2tile[]; @@ -86,7 +88,16 @@ static BOOL onListChar(HWND hWnd, HWND hwndList, WORD ch); /*-----------------------------------------------------------------------------*/ HWND mswin_init_menu_window (int type) { HWND ret; + RECT rt; + /* get window position */ + if( GetNHApp()->bAutoLayout ) { + SetRect( &rt, 0, 0, 0, 0); + } else { + mswin_get_window_placement(NHW_MENU, &rt); + } + + /* create menu window object */ ret = CreateDialog( GetNHApp()->hApp, MAKEINTRESOURCE(IDD_MENU), @@ -96,12 +107,28 @@ HWND mswin_init_menu_window (int type) { if( !ret ) { panic("Cannot create menu window"); } - + + /* move it in the predefined position */ + if( !GetNHApp()->bAutoLayout ) { + MoveWindow(ret, rt.left, rt.top, rt.right - rt.left, rt.bottom - rt.top, TRUE); + } + + /* Set window caption */ + SetWindowText(ret, "Menu/Text"); + + if( !GetNHApp()->bWindowsLocked ) { + DWORD style; + style = GetWindowLong(ret, GWL_STYLE); + style |= WS_CAPTION; + SetWindowLong(ret, GWL_STYLE, style); + SetWindowPos(ret, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED); + } + SetMenuType(ret, type); return ret; } /*-----------------------------------------------------------------------------*/ -int mswin_menu_window_select_menu (HWND hWnd, int how, MENU_ITEM_P ** _selected) +int mswin_menu_window_select_menu (HWND hWnd, int how, MENU_ITEM_P ** _selected, BOOL activate) { PNHMenuWindow data; int ret_val; @@ -115,6 +142,14 @@ int mswin_menu_window_select_menu (HWND hWnd, int how, MENU_ITEM_P ** _selected) data = (PNHMenuWindow)GetWindowLong(hWnd, GWL_USERDATA); + /* force activate for certain menu types */ + if( data->type == MENU_TYPE_MENU && + (how == PICK_ONE || how == PICK_ANY) ) { + activate = TRUE; + } + + data->is_active = activate; + /* set menu type */ SetMenuListType(hWnd, how); @@ -156,7 +191,14 @@ int mswin_menu_window_select_menu (HWND hWnd, int how, MENU_ITEM_P ** _selected) reset_menu_count(NULL, data); } - mswin_popup_display(hWnd, &data->done); + LayoutMenu(hWnd); // show dialog buttons + + if( activate ) { + mswin_popup_display(hWnd, &data->done); + } else { + SetFocus(GetNHApp()->hMainWnd); + mswin_layout_main_window(hWnd); + } /* get the result */ if( data->result != -1 ) { @@ -193,8 +235,11 @@ int mswin_menu_window_select_menu (HWND hWnd, int how, MENU_ITEM_P ** _selected) } } - mswin_popup_destroy(hWnd); - + if( activate ) { + data->is_active = FALSE; + LayoutMenu(hWnd); // hide dialog buttons + mswin_popup_destroy(hWnd); + } return ret_val; } /*-----------------------------------------------------------------------------*/ @@ -219,6 +264,7 @@ BOOL CALLBACK MenuWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) data->bmpChecked = LoadBitmap(GetNHApp()->hApp, MAKEINTRESOURCE(IDB_MENU_SEL)); data->bmpCheckedCount = LoadBitmap(GetNHApp()->hApp, MAKEINTRESOURCE(IDB_MENU_SEL_COUNT)); data->bmpNotChecked = LoadBitmap(GetNHApp()->hApp, MAKEINTRESOURCE(IDB_MENU_UNSEL)); + data->is_active = FALSE; SetWindowLong(hWnd, GWL_USERDATA, (LONG)data); /* set font for the text cotrol */ @@ -235,16 +281,35 @@ BOOL CALLBACK MenuWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) which shows on Alt-Tab */ LoadString(GetNHApp()->hApp, IDS_APP_TITLE, title, MAX_LOADSTRING); SetWindowText(hWnd, title); - break; + + /* set focus to text control for now */ + SetFocus(control); + return FALSE; case WM_MSNH_COMMAND: onMSNHCommand(hWnd, wParam, lParam); break; - case WM_SIZE: + case WM_SIZE: { + RECT rt; LayoutMenu(hWnd); - return FALSE; + GetWindowRect(hWnd, &rt); + ScreenToClient(GetNHApp()->hMainWnd, (LPPOINT)&rt); + ScreenToClient(GetNHApp()->hMainWnd, ((LPPOINT)&rt)+1); + 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_MOVE: { + RECT rt; + GetWindowRect(hWnd, &rt); + ScreenToClient(GetNHApp()->hMainWnd, (LPPOINT)&rt); + ScreenToClient(GetNHApp()->hMainWnd, ((LPPOINT)&rt)+1); + mswin_update_window_placement(NHW_MENU, &rt); + } return FALSE; + case WM_CLOSE: if (program_state.gameover) { data->result = -1; @@ -375,10 +440,13 @@ BOOL CALLBACK MenuWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) } break; case WM_SETFOCUS: - if( hWnd!=GetNHApp()->hPopupWnd ) { - SetFocus(GetNHApp()->hPopupWnd ); + if( hWnd!=GetNHApp()->hPopupWnd) { + SetFocus(GetNHApp()->hMainWnd); + } else { + if( IsWindow(GetMenuControl(hWnd)) ) + SetFocus(GetMenuControl(hWnd)); } - break; + return FALSE; case WM_MEASUREITEM: if( wParam==IDC_MENU_LIST ) @@ -562,28 +630,55 @@ void LayoutMenu(HWND hWnd) /* get window coordinates */ GetClientRect(hWnd, &clrt ); - - /* set window placements */ - GetWindowRect(menu_ok, &rt); - sz_ok.cx = (clrt.right - clrt.left)/2 - 2*MENU_MARGIN; - sz_ok.cy = rt.bottom-rt.top; - pt_ok.x = clrt.left + MENU_MARGIN; - pt_ok.y = clrt.bottom - MENU_MARGIN - sz_ok.cy; - - GetWindowRect(menu_cancel, &rt); - sz_cancel.cx = (clrt.right - clrt.left)/2 - 2*MENU_MARGIN; - sz_cancel.cy = rt.bottom-rt.top; - pt_cancel.x = (clrt.left + clrt.right)/2 + MENU_MARGIN; - pt_cancel.y = clrt.bottom - MENU_MARGIN - sz_cancel.cy; + + // OK button + if( data->is_active ) { + GetWindowRect(menu_ok, &rt); + if( data->type == MENU_TYPE_TEXT || + (data->type == MENU_TYPE_MENU && data->how == PICK_NONE ) ) { + sz_ok.cx = (clrt.right - clrt.left) - 2*MENU_MARGIN; + } else { + sz_ok.cx = (clrt.right - clrt.left)/2 - 2*MENU_MARGIN; + } + sz_ok.cy = rt.bottom-rt.top; + pt_ok.x = clrt.left + MENU_MARGIN; + pt_ok.y = clrt.bottom - MENU_MARGIN - sz_ok.cy; + ShowWindow(menu_ok, SW_SHOW); + MoveWindow(menu_ok, pt_ok.x, pt_ok.y, sz_ok.cx, sz_ok.cy, TRUE ); + } else { + sz_ok.cx = sz_ok.cy = 0; + pt_ok.x = pt_ok.y = 0; + ShowWindow(menu_ok, SW_HIDE); + } + + // CANCEL button + if( data->is_active && + !( data->type == MENU_TYPE_TEXT || + (data->type == MENU_TYPE_MENU && data->how == PICK_NONE ) ) ) { + GetWindowRect(menu_ok, &rt); + sz_cancel.cx = (clrt.right - clrt.left)/2 - 2*MENU_MARGIN; + pt_cancel.x = (clrt.left + clrt.right)/2 + MENU_MARGIN; + sz_cancel.cy = rt.bottom - rt.top; + pt_cancel.y = clrt.bottom - MENU_MARGIN - sz_cancel.cy; + ShowWindow(menu_cancel, SW_SHOW); + MoveWindow(menu_cancel, pt_cancel.x, pt_cancel.y, sz_cancel.cx, sz_cancel.cy, TRUE ); + } else { + sz_cancel.cx = sz_cancel.cy = 0; + pt_cancel.x = pt_cancel.y = 0; + ShowWindow(menu_cancel, SW_HIDE); + } + + // main menu control pt_elem.x = clrt.left + MENU_MARGIN; pt_elem.y = clrt.top + MENU_MARGIN; sz_elem.cx = (clrt.right - clrt.left) - 2*MENU_MARGIN; - sz_elem.cy = min(pt_cancel.y, pt_ok.y) - 2*MENU_MARGIN; - + if( data->is_active ) { + sz_elem.cy = (clrt.bottom - clrt.top) - max(sz_ok.cy, sz_cancel.cy) - 3*MENU_MARGIN; + } else { + sz_elem.cy = (clrt.bottom - clrt.top) - 2*MENU_MARGIN; + } MoveWindow(GetMenuControl(hWnd), pt_elem.x, pt_elem.y, sz_elem.cx, sz_elem.cy, TRUE ); - MoveWindow(menu_ok, pt_ok.x, pt_ok.y, sz_ok.cx, sz_ok.cy, TRUE ); - MoveWindow(menu_cancel, pt_cancel.x, pt_cancel.y, sz_cancel.cx, sz_cancel.cy, TRUE ); } /*-----------------------------------------------------------------------------*/ void SetMenuType(HWND hWnd, int type) @@ -602,13 +697,13 @@ void SetMenuType(HWND hWnd, int type) EnableWindow(list, FALSE); EnableWindow(text, TRUE); ShowWindow(text, SW_SHOW); - SetFocus(text); + if( data->is_active ) SetFocus(text); } else { ShowWindow(text, SW_HIDE); EnableWindow(text, FALSE); EnableWindow(list, TRUE); ShowWindow(list, SW_SHOW); - SetFocus(list); + if( data->is_active ) SetFocus(list); } LayoutMenu(hWnd); } @@ -708,7 +803,7 @@ void SetMenuListType(HWND hWnd, int how) panic("cannot insert menu item"); } } - SetFocus(control); + if( data->is_active ) SetFocus(control); } /*-----------------------------------------------------------------------------*/ HWND GetMenuControl(HWND hWnd) @@ -1057,7 +1152,7 @@ BOOL onListChar(HWND hWnd, HWND hwndList, WORD ch) if( mswin_getlin_window("Search for:", buf, BUFSZ)==IDCANCEL ) { strcpy(buf, "\033"); } - SetFocus(hwndList); // set focus back to the list control + if( data->is_active ) SetFocus(hwndList); // set focus back to the list control if (!*buf || *buf == '\033') return -2; for(i=0; imenu.size; i++ ) { if( NHMENU_IS_SELECTABLE(data->menu.items[i]) @@ -1377,6 +1472,11 @@ LRESULT CALLBACK NHMenuListWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARA bUpdateFocusItem = TRUE; break; + case WM_SETFOCUS: + if( GetParent(hWnd)!=GetNHApp()->hPopupWnd) { + SetFocus(GetNHApp()->hMainWnd); + } + return FALSE; } if( bUpdateFocusItem ) { @@ -1446,3 +1546,4 @@ LRESULT CALLBACK NHMenuTextWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARA return 0; } /*-----------------------------------------------------------------------------*/ + diff --git a/win/win32/mhmenu.h b/win/win32/mhmenu.h index aa9a90db9..1d40c7a01 100644 --- a/win/win32/mhmenu.h +++ b/win/win32/mhmenu.h @@ -12,7 +12,8 @@ #define MENU_TYPE_MENU 2 HWND mswin_init_menu_window ( int type ); -int mswin_menu_window_select_menu (HWND hwnd, int how, MENU_ITEM_P **); +int mswin_menu_window_select_menu (HWND hwnd, int how, MENU_ITEM_P ** selected, BOOL activate); void mswin_menu_window_size (HWND hwnd, LPSIZE sz); #endif /* MSWINTextWindow_h */ + diff --git a/win/win32/mhmsg.h b/win/win32/mhmsg.h index 4f46974df..34d735e75 100644 --- a/win/win32/mhmsg.h +++ b/win/win32/mhmsg.h @@ -60,3 +60,4 @@ typedef struct mswin_nhmsg_end_menu { } MSNHMsgEndMenu, *PMSNHMsgEndMenu; #endif + diff --git a/win/win32/mhmsgwnd.c b/win/win32/mhmsgwnd.c index 7daca460c..bcab40806 100644 --- a/win/win32/mhmsgwnd.c +++ b/win/win32/mhmsgwnd.c @@ -20,21 +20,14 @@ struct window_line { int attr; - char text[MAXWINDOWTEXT]; + char text[MAXWINDOWTEXT+1]; }; typedef struct mswin_nethack_message_window { size_t max_text; struct window_line window_text[MAX_MSG_LINES]; -#ifdef MSG_WRAP_TEXT - int window_text_lines[MAX_MSG_LINES]; /* How much space this text line takes */ -#endif int lines_last_turn; /* lines added during the last turn */ - int cleared; /* clear was called */ - int last_line; /* last line in the message history */ - struct window_line new_line; int lines_not_seen; /* lines not yet seen by user after last turn or --More-- */ - int in_more; /* We are in a --More-- prompt */ int nevermore; /* We want no more --More-- prompts */ int xChar; /* horizontal scrolling unit */ @@ -58,6 +51,11 @@ static void onMSNH_HScroll(HWND hWnd, WPARAM wParam, LPARAM lParam); static COLORREF setMsgTextColor(HDC hdc, int gray); static void onPaint(HWND hWnd); static void onCreate(HWND hWnd, WPARAM wParam, LPARAM lParam); +static BOOL can_append_text(HWND hWnd, int attr, const char* text ); + /* check if text can be appended to the last line without wrapping */ + +static BOOL more_prompt_check(HWND hWnd); + /* check if "--more--" promt needs to be displayed */ #ifdef USER_SOUNDS extern void play_sound_for_message(const char* str); @@ -67,16 +65,24 @@ HWND mswin_init_message_window () { static int run_once = 0; HWND ret; DWORD style; + RECT rt; if( !run_once ) { register_message_window_class( ); run_once = 1; } + /* get window position */ + if( GetNHApp()->bAutoLayout ) { + SetRect( &rt, 0, 0, 0, 0); + } else { + mswin_get_window_placement(NHW_MESSAGE, &rt); + } + #ifdef MSG_WRAP_TEXT - style = WS_CHILD | WS_CLIPSIBLINGS | WS_VSCROLL; + style = WS_CHILD | WS_CLIPSIBLINGS | WS_VSCROLL | WS_SIZEBOX; #else - style = WS_CHILD | WS_CLIPSIBLINGS | WS_VSCROLL | WS_HSCROLL; + style = WS_CHILD | WS_CLIPSIBLINGS | WS_VSCROLL | WS_HSCROLL | WS_SIZEBOX; #endif ret = CreateWindowEx( @@ -84,10 +90,10 @@ HWND mswin_init_message_window () { szMessageWindowClass, /* registered class name */ NULL, /* window name */ style, /* window style */ - 0, /* horizontal position of window */ - 0, /* vertical position of window */ - 0, /* window width */ - 0, /* window height - set it later */ + rt.left, /* horizontal position of window */ + rt.top, /* vertical position of window */ + rt.right - rt.left, /* window width */ + rt.bottom - rt.top, /* window height */ GetNHApp()->hMainWnd, /* handle to parent or owner window */ NULL, /* menu handle or child identifier */ GetNHApp()->hApp, /* handle to application instance */ @@ -95,6 +101,9 @@ HWND mswin_init_message_window () { if( !ret ) panic("Cannot create message window"); + /* Set window caption */ + SetWindowText(ret, "Messages"); + return ret; } @@ -161,6 +170,7 @@ LRESULT CALLBACK NHMessageWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM int xNewSize; int yNewSize; PNHMessageWindow data; + RECT rt; data = (PNHMessageWindow)GetWindowLong(hWnd, GWL_USERDATA); @@ -196,6 +206,12 @@ LRESULT CALLBACK NHMessageWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM si.nPos = data->yPos; SetScrollInfo(hWnd, SB_VERT, &si, TRUE); } + + /* update NetHack internal window position */ + GetWindowRect(hWnd, &rt); + ScreenToClient(GetNHApp()->hMainWnd, (LPPOINT)&rt); + ScreenToClient(GetNHApp()->hMainWnd, ((LPPOINT)&rt)+1); + mswin_update_window_placement(NHW_MESSAGE, &rt); } break; @@ -215,22 +231,76 @@ void onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM lParam) { PMSNHMsgPutstr msg_data = (PMSNHMsgPutstr)lParam; SCROLLINFO si; + char* p; if( msg_data->append == 1) { /* Forcibly append to line, even if we pass the edge */ - strncat(data->window_text[data->last_line].text, msg_data->text, - MAXWINDOWTEXT - strlen(data->window_text[data->last_line].text)); + strncat(data->window_text[MSG_LINES-1].text, msg_data->text, + MAXWINDOWTEXT - strlen(data->window_text[MSG_LINES-1].text)); } else if( msg_data->append < 0) { /* remove that many chars */ - int len = strlen(data->window_text[data->last_line].text); + int len = strlen(data->window_text[MSG_LINES-1].text); int newend = max(len + msg_data->append, 0); - data->window_text[data->last_line].text[newend] = '\0'; + data->window_text[MSG_LINES-1].text[newend] = '\0'; } else { - /* Try to append but move the whole message to the next line if - it doesn't fit */ - /* just schedule for displaying */ - data->new_line.attr = msg_data->attr; - strncpy(data->new_line.text, msg_data->text, MAXWINDOWTEXT); + if( can_append_text(hWnd, msg_data->attr, msg_data->text ) ) { + strncat(data->window_text[MSG_LINES-1].text, " ", MAXWINDOWTEXT-strlen(data->window_text[MSG_LINES-1].text)); + strncat(data->window_text[MSG_LINES-1].text, msg_data->text, MAXWINDOWTEXT-strlen(data->window_text[MSG_LINES-1].text)); + } else { + /* check for "--more--" */ + if( !data->nevermore && more_prompt_check(hWnd) ) { + int okkey = 0; + int chop; + // @@@ Ok respnses + + /* append more prompt and inticate the update */ + strncat(data->window_text[MSG_LINES-1].text, MORE, MAXWINDOWTEXT - strlen(data->window_text[MSG_LINES-1].text)); + InvalidateRect(hWnd, NULL, TRUE); + + /* get the input */ + while (!okkey) { + char c = mswin_nhgetch(); + + switch (c) + { + /* space or enter */ + case ' ': + case '\015': + okkey = 1; + break; + /* ESC */ + case '\033': + data->nevermore = 1; + okkey = 1; + break; + default: + break; + } + } + + /* erase the "--more--" prompt */ + chop = strlen(data->window_text[MSG_LINES-1].text) - strlen(MORE); + data->window_text[MSG_LINES-1].text[chop] = '\0'; + data->lines_not_seen = 0; + } + + /* check if the string is empty */ + for(p = data->window_text[MSG_LINES-1].text; *p && isspace(*p); p++); + + if( *p ) { + /* last string is not empty - scroll up */ + memmove(&data->window_text[0], + &data->window_text[1], + (MSG_LINES-1)*sizeof(data->window_text[0])); + } + + /* append new text to the end of the array */ + data->window_text[MSG_LINES-1].attr = msg_data->attr; + strncpy(data->window_text[MSG_LINES-1].text, msg_data->text, MAXWINDOWTEXT); + + data->lines_not_seen++; + data->lines_last_turn++; + } } /* reset V-scroll position to display new text */ @@ -253,9 +323,8 @@ void onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM lParam) case MSNH_MSG_CLEAR_WINDOW: { - data->cleared = 1; + data->lines_last_turn = 0; data->lines_not_seen = 0; - /* do --More-- again if needed */ data->nevermore = 0; break; } @@ -480,7 +549,6 @@ void onPaint(HWND hWnd) LastLine = min (MSG_LINES-1, data->yPos - (client_rt.bottom - ps.rcPaint.bottom)/data->yChar); y = min( ps.rcPaint.bottom, client_rt.bottom ); for (i=LastLine; i>=FirstLine; i--) { - int lineidx = (data->last_line + 1 + i) % MSG_LINES; x = data->xChar * (2 - data->xPos); draw_rt.left = x; @@ -488,123 +556,21 @@ void onPaint(HWND hWnd) draw_rt.top = y - data->yChar; draw_rt.bottom = y; - oldFont = SelectObject(hdc, mswin_get_font(NHW_MESSAGE, data->window_text[lineidx].attr, hdc, FALSE)); - - /* find out if we can concatenate the scheduled message without wrapping, - but only if no clear_nhwindow was done just before putstr'ing this one, - and only if not in a more prompt already (to prevent concatenating to - a line containing --More-- when resizing while --More-- is displayed.) - */ - if (i == MSG_LINES-1 - && strlen(data->new_line.text) > 0 - && !data->in_more) { - /* concatenate to the previous line if that is not empty, and - if it has the same attribute, and no clear was done. - */ - if (strlen(data->window_text[lineidx].text) > 0 - && (data->window_text[lineidx].attr - == data->new_line.attr) - && !data->cleared) { - RECT tmpdraw_rt = draw_rt; - /* assume this will never work when textsize is near MAXWINDOWTEXT */ - char tmptext[MAXWINDOWTEXT]; - TCHAR tmpwbuf[MAXWINDOWTEXT+2]; - - strcpy(tmptext, data->window_text[lineidx].text); - strncat(tmptext, " ", - MAXWINDOWTEXT - strlen(tmptext)); - strncat(tmptext, data->new_line.text, - MAXWINDOWTEXT - strlen(tmptext)); - /* Always keep room for a --More-- */ - strncat(tmptext, MORE, - MAXWINDOWTEXT - strlen(tmptext)); - NH_A2W(tmptext, tmpwbuf, sizeof(tmpwbuf)); - /* Find out how large the bounding rectangle of the text is */ - DrawText(hdc, tmpwbuf, _tcslen(tmpwbuf), &tmpdraw_rt, DT_NOPREFIX | DT_WORDBREAK | DT_CALCRECT); - if ((tmpdraw_rt.bottom - tmpdraw_rt.top) == (draw_rt.bottom - draw_rt.top) /* fits pixelwise */ - && (strlen(data->window_text[lineidx].text) - + strlen(data->new_line.text) < MAXWINDOWTEXT)) /* fits charwise */ - { - /* strip off --More-- of this combined line and make it so */ - tmptext[strlen(tmptext) - strlen(MORE)] = '\0'; - strcpy(data->window_text[lineidx].text, tmptext); - data->new_line.text[0] = '\0'; - i++; /* Start from the last line again */ - continue; - } - } - if (strlen(data->new_line.text) > 0) { - /* if we get here, the new line was not concatenated. Add it on a new line, - but first check whether we should --More--. */ - RECT tmpdraw_rt = draw_rt; - TCHAR tmpwbuf[MAXWINDOWTEXT+2]; - HGDIOBJ oldFont; - int new_screen_lines; - int screen_lines_not_seen = 0; - /* Count how many screen lines we haven't seen yet. */ -#ifdef MSG_WRAP_TEXT - { - int n; - for (n = data->lines_not_seen - 1; n >= 0; n--) { - screen_lines_not_seen += - data->window_text_lines[(data->last_line - n + MSG_LINES) % MSG_LINES]; - } - } -#else - screen_lines_not_seen = data->lines_not_seen; -#endif - /* Now find out how many screen lines we would like to add */ - NH_A2W(data->new_line.text, tmpwbuf, sizeof(tmpwbuf)); - /* Find out how large the bounding rectangle of the text is */ - oldFont = SelectObject(hdc, mswin_get_font(NHW_MESSAGE, data->window_text[lineidx].attr, hdc, FALSE)); - DrawText(hdc, tmpwbuf, _tcslen(tmpwbuf), &tmpdraw_rt, DT_NOPREFIX | DT_WORDBREAK | DT_CALCRECT); - SelectObject(hdc, oldFont); - new_screen_lines = (tmpdraw_rt.bottom - tmpdraw_rt.top) / data->yChar; - /* If this together is more than fits on the window, we must - --More--, unless: - - We are in --More-- already (the user is scrolling the window) - - The user pressed ESC - */ - if (screen_lines_not_seen + new_screen_lines > MSG_VISIBLE_LINES - && !data->in_more && !data->nevermore) { - data->in_more = 1; - /* Show --More-- on last line */ - strcat(data->window_text[data->last_line].text, MORE); - /* Go on drawing, but remember we must do a more afterwards */ - do_more = 1; - } else if (!data->in_more) { - data->last_line++; - data->last_line %= MSG_LINES; - data->window_text[data->last_line].attr = data->new_line.attr; - strncpy(data->window_text[data->last_line].text, data->new_line.text, MAXWINDOWTEXT); - data->new_line.text[0] = '\0'; - if (data->cleared) { - /* now we are drawing a new line, the old lines can be redrawn in grey.*/ - data->lines_last_turn = 0; - data->cleared = 0; - } - data->lines_last_turn++; - data->lines_not_seen++; - /* and start over */ - i++; /* Start from the last line again */ - continue; - } - } - } + oldFont = SelectObject(hdc, mswin_get_font(NHW_MESSAGE, data->window_text[i].attr, hdc, FALSE)); + /* convert to UNICODE */ - NH_A2W(data->window_text[lineidx].text, wbuf, sizeof(wbuf)); + NH_A2W(data->window_text[i].text, wbuf, sizeof(wbuf)); wlen = _tcslen(wbuf); setMsgTextColor(hdc, i < (MSG_LINES - data->lines_last_turn)); #ifdef MSG_WRAP_TEXT /* Find out how large the bounding rectangle of the text is */ DrawText(hdc, wbuf, wlen, &draw_rt, DT_NOPREFIX | DT_WORDBREAK | DT_CALCRECT); - /* move that rectangle up, so that the bottom remains at the same height */ + /* move that rectangle up, so that the bottom remains at the same height */ draw_rt.top = y - (draw_rt.bottom - draw_rt.top); draw_rt.bottom = y; - /* Remember the height of this line for subsequent --More--'s */ - data->window_text_lines[lineidx] = (draw_rt.bottom - draw_rt.top) / data->yChar; - /* Now really draw it */ - DrawText(hdc, wbuf, wlen, &draw_rt, DT_NOPREFIX | DT_WORDBREAK); + + /* Now really draw it */ + DrawText(hdc, wbuf, wlen, &draw_rt, DT_NOPREFIX | DT_WORDBREAK); /* Find out the cursor (caret) position */ if (i == MSG_LINES-1) { @@ -647,39 +613,6 @@ void onPaint(HWND hWnd) SelectObject(hdc, oldFont); y -= draw_rt.bottom - draw_rt.top; } - if (do_more) { - int okkey = 0; - int chop; - // @@@ Ok respnses - - while (!okkey) { - char c = mswin_nhgetch(); - - switch (c) - { - /* space or enter */ - case ' ': - case '\015': - okkey = 1; - break; - /* ESC */ - case '\033': - data->nevermore = 1; - okkey = 1; - break; - default: - break; - } - } - chop = strlen(data->window_text[data->last_line].text) - - strlen(MORE); - data->window_text[data->last_line].text[chop] = '\0'; - data->in_more = 0; - data->lines_not_seen = 0; - /* We did the --More--, reset the lines_not_seen; now draw that - new line. This is the easiest method */ - InvalidateRect(hWnd, NULL, TRUE); - } } SetTextColor (hdc, OldFg); SetBkColor (hdc, OldBg); @@ -740,3 +673,99 @@ void mswin_message_window_size (HWND hWnd, LPSIZE sz) sz->cy = sz->cy - (client_rt.bottom - client_rt.top) + data->yChar * MSG_VISIBLE_LINES; } + +/* check if text can be appended to the last line without wrapping */ +BOOL can_append_text(HWND hWnd, int attr, const char* text ) +{ + PNHMessageWindow data; + char tmptext[MAXWINDOWTEXT+1]; + HDC hdc; + HGDIOBJ saveFont; + RECT draw_rt; + BOOL retval = FALSE; + + data = (PNHMessageWindow)GetWindowLong(hWnd, GWL_USERDATA); + + /* cannot append if lines_not_seen is 0 (beginning of the new turn */ + if( data->lines_not_seen==0 ) return FALSE; + + /* cannot append text with different attrbutes */ + if( data->window_text[MSG_LINES-1].attr != attr ) return FALSE; + + /* check if the maximum string langth will be exceeded */ + if( strlen(data->window_text[MSG_LINES-1].text)+ + 2 + /* space characters */ + strlen(text) + + strlen(MORE) >= MAXWINDOWTEXT ) return FALSE; + + /* check if the text is goinf to fin into a single line */ + strcpy(tmptext, data->window_text[MSG_LINES-1].text ); + strcat(tmptext, " " ); + strcat(tmptext, text ); + strcat(tmptext, MORE ); + + hdc = GetDC(hWnd); + saveFont = SelectObject(hdc, mswin_get_font(NHW_MESSAGE, data->window_text[MSG_LINES-1].attr, hdc, FALSE)); + GetClientRect(hWnd, &draw_rt); + draw_rt.bottom = draw_rt.top; /* we only need width for the DrawText */ + DrawText(hdc, tmptext, strlen(tmptext), &draw_rt, DT_NOPREFIX | DT_WORDBREAK | DT_CALCRECT); + + /* we will check against 1.5 of the font size in order to determine + if the text is single-line or not - just to be on the safe size */ + retval = (draw_rt.bottom-draw_rt.top)<(data->yChar+data->yChar/2); + + /* free device context */ + SelectObject(hdc, saveFont); + ReleaseDC (hWnd, hdc); + return retval; +} + +/* check if "--more--" promt needs to be displayed + basically, check if the lines not seen are going to find in the message window +*/ +BOOL more_prompt_check(HWND hWnd) +{ + PNHMessageWindow data; + HDC hdc; + HGDIOBJ saveFont; + RECT client_rt, draw_rt; + BOOL retval = FALSE; + int visible_lines = 0; + int i; + int remaining_height; + char tmptext[MAXWINDOWTEXT+1]; + + data = (PNHMessageWindow)GetWindowLong(hWnd, GWL_USERDATA); + + if( data->lines_not_seen==0 ) return FALSE; /* don't bother checking - nothig to "more" */ + if( data->lines_not_seen>=MSG_LINES ) return TRUE; /* history size exceeded - always more */ + + GetClientRect(hWnd, &client_rt); + remaining_height = client_rt.bottom - client_rt.top; + + hdc = GetDC(hWnd); + saveFont = SelectObject(hdc, mswin_get_font(NHW_MESSAGE, ATR_NONE, hdc, FALSE)); + for( i=0; ilines_not_seen; i++ ) { + /* we only need width for the DrawText */ + SetRect(&draw_rt, client_rt.left, client_rt.top, client_rt.right, client_rt.top); + SelectObject(hdc, mswin_get_font(NHW_MESSAGE, data->window_text[MSG_LINES-i-1].attr, hdc, FALSE)); + + strcpy(tmptext, data->window_text[MSG_LINES-i-1].text ); + if( i==0 ) strcat(tmptext, MORE ); + + remaining_height -= + DrawText( hdc, + tmptext, + strlen(tmptext), + &draw_rt, + DT_NOPREFIX | DT_WORDBREAK | DT_CALCRECT + ); + if( remaining_height<=0 ) break; + } + + /* free device context */ + SelectObject(hdc, saveFont); + ReleaseDC (hWnd, hdc); + return (remaining_height<=0); /* TRUE if lines_not_seen take more that window height */ +} + diff --git a/win/win32/mhmsgwnd.h b/win/win32/mhmsgwnd.h index a4f673644..52be9b0bf 100644 --- a/win/win32/mhmsgwnd.h +++ b/win/win32/mhmsgwnd.h @@ -13,3 +13,4 @@ void mswin_message_window_size (HWND hWnd, LPSIZE sz); #endif /* MSWINMessageWindow_h */ + diff --git a/win/win32/mhrip.c b/win/win32/mhrip.c index 69f4916cc..f15dfbf45 100644 --- a/win/win32/mhrip.c +++ b/win/win32/mhrip.c @@ -263,3 +263,4 @@ void mswin_finish_rip_text(winid wid) { SendMessage (mswin_hwnd_from_winid(wid), WM_MSNH_COMMAND, MSNH_MSG_DIED, 0); } + diff --git a/win/win32/mhrip.h b/win/win32/mhrip.h index cc4935509..697553204 100644 --- a/win/win32/mhrip.h +++ b/win/win32/mhrip.h @@ -13,3 +13,4 @@ HWND mswin_init_RIP_window (void); void mswin_display_RIP_window (HWND hwnd); #endif /* MSWINRIPWindow_h */ + diff --git a/win/win32/mhsplash.c b/win/win32/mhsplash.c index 96760dd74..4f4ed2677 100644 --- a/win/win32/mhsplash.c +++ b/win/win32/mhsplash.c @@ -32,7 +32,6 @@ void mswin_display_splash_window (BOOL show_ver) { MSG msg; RECT rt; - HWND mapWnd; RECT splashrt; RECT clientrt; RECT controlrt; @@ -44,8 +43,6 @@ void mswin_display_splash_window (BOOL show_ver) if( !hWnd ) panic("Cannot create Splash window"); mswin_init_splashfonts(hWnd); GetNHApp()->hPopupWnd = hWnd; - mapWnd = mswin_hwnd_from_winid(WIN_MAP); - if( !IsWindow(mapWnd) ) mapWnd = GetNHApp()->hMainWnd; /* Get control size */ GetWindowRect (GetDlgItem(hWnd, IDOK), &controlrt); controlrt.right -= controlrt.left; @@ -60,7 +57,7 @@ void mswin_display_splash_window (BOOL show_ver) splashrt.right += SPLASH_WIDTH + SPLASH_OFFSET_X * 2 - clientrt.right; splashrt.bottom += SPLASH_HEIGHT + controlrt.bottom + SPLASH_OFFSET_Y * 3 - clientrt.bottom; /* Place the window centered */ - GetWindowRect(mapWnd, &rt); + GetWindowRect(GetNHApp()->hMainWnd, &rt); rt.left += (rt.right - rt.left - splashrt.right) / 2; rt.top += (rt.bottom - rt.top - splashrt.bottom) / 2; MoveWindow(hWnd, rt.left, rt.top, splashrt.right, splashrt.bottom, TRUE); @@ -91,7 +88,6 @@ void mswin_display_splash_window (BOOL show_ver) /* Show news, if any */ FILE *nf; - iflags.news = 0; /* prevent newgame() from re-displaying news */ nf = fopen(NEWS, "r"); if (nf != NULL) { char *buf = NULL; @@ -228,3 +224,4 @@ BOOL CALLBACK NHSplashWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPa } return FALSE; } + diff --git a/win/win32/mhsplash.h b/win/win32/mhsplash.h index 9966c3d19..da6143c54 100644 --- a/win/win32/mhsplash.h +++ b/win/win32/mhsplash.h @@ -11,3 +11,4 @@ void mswin_display_splash_window (BOOL); #endif /* MSWINSplashWindow_h */ + diff --git a/win/win32/mhstatus.c b/win/win32/mhstatus.c index 050b8baa1..f98a77460 100644 --- a/win/win32/mhstatus.c +++ b/win/win32/mhstatus.c @@ -25,28 +25,39 @@ HWND mswin_init_status_window () { static int run_once = 0; HWND ret; NHStatusWindow* data; + RECT rt; if( !run_once ) { register_status_window_class( ); run_once = 1; } - + + /* get window position */ + if( GetNHApp()->bAutoLayout ) { + SetRect( &rt, 0, 0, 0, 0); + } else { + mswin_get_window_placement(NHW_STATUS, &rt); + } + + /* create status window object */ ret = CreateWindow( szStatusWindowClass, NULL, - WS_CHILD | WS_DISABLED | WS_CLIPSIBLINGS, - 0, /* x position */ - 0, /* y position */ - 0, /* x-size - we will set it later */ - 0, /* y-size - we will set it later */ + WS_CHILD | WS_CLIPSIBLINGS | WS_SIZEBOX, + rt.left, /* horizontal position of window */ + rt.top, /* vertical position of window */ + rt.right - rt.left, /* window width */ + rt.bottom - rt.top, /* window height */ GetNHApp()->hMainWnd, NULL, GetNHApp()->hApp, NULL ); if( !ret ) panic("Cannot create status window"); - - EnableWindow(ret, FALSE); + /* Set window caption */ + SetWindowText(ret, "Status"); + + /* create window data */ data = (PNHStatusWindow)malloc(sizeof(NHStatusWindow)); if( !data ) panic("out of memory"); @@ -92,8 +103,6 @@ LRESULT CALLBACK StatusWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lP PMSNHMsgPutstr msg_data = (PMSNHMsgPutstr)lParam; strncpy(data->window_text[data->index], msg_data->text, MAXWINDOWTEXT); - strncat(data->window_text[data->index], "\n", - MAXWINDOWTEXT-strlen(data->window_text[data->index])); data->index = (data->index+1) % NHSW_LINES; InvalidateRect(hWnd, NULL, TRUE); break; @@ -136,6 +145,22 @@ LRESULT CALLBACK StatusWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lP EndPaint(hWnd, &ps); } break; + case WM_SIZE: { + RECT rt; + GetWindowRect(hWnd, &rt); + ScreenToClient(GetNHApp()->hMainWnd, (LPPOINT)&rt); + ScreenToClient(GetNHApp()->hMainWnd, ((LPPOINT)&rt)+1); + mswin_update_window_placement(NHW_STATUS, &rt); + } return FALSE; + + case WM_MOVE: { + RECT rt; + GetWindowRect(hWnd, &rt); + ScreenToClient(GetNHApp()->hMainWnd, (LPPOINT)&rt); + ScreenToClient(GetNHApp()->hMainWnd, ((LPPOINT)&rt)+1); + mswin_update_window_placement(NHW_STATUS, &rt); + } return FALSE; + case WM_DESTROY: free(data); SetWindowLong(hWnd, GWL_USERDATA, (LONG)0); @@ -168,9 +193,10 @@ void mswin_status_window_size (HWND hWnd, LPSIZE sz) saveFont = SelectObject(hdc, mswin_get_font(NHW_STATUS, ATR_NONE, hdc, FALSE)); GetTextMetrics(hdc, &tm); - sz->cy = tm.tmHeight * NHSW_LINES; + sz->cy = tm.tmHeight * NHSW_LINES + 2*GetSystemMetrics(SM_CYSIZEFRAME); SelectObject(hdc, saveFont); ReleaseDC(hWnd, hdc); } } + diff --git a/win/win32/mhstatus.h b/win/win32/mhstatus.h index e073a8025..1fc08467b 100644 --- a/win/win32/mhstatus.h +++ b/win/win32/mhstatus.h @@ -12,3 +12,4 @@ HWND mswin_init_status_window (void); void mswin_status_window_size (HWND hWnd, LPSIZE sz); #endif /* MSWINStatusWindow_h */ + diff --git a/win/win32/mhtext.c b/win/win32/mhtext.c index 3d541d5f3..c27d4d0f8 100644 --- a/win/win32/mhtext.c +++ b/win/win32/mhtext.c @@ -25,7 +25,16 @@ static void LayoutText(HWND hwnd); HWND mswin_init_text_window () { HWND ret; PNHTextWindow data; + RECT rt; + /* get window position */ + if( GetNHApp()->bAutoLayout ) { + SetRect( &rt, 0, 0, 0, 0); + } else { + mswin_get_window_placement(NHW_TEXT, &rt); + } + + /* create text widnow object */ ret = CreateDialog( GetNHApp()->hApp, MAKEINTRESOURCE(IDD_NHTEXT), @@ -34,9 +43,24 @@ HWND mswin_init_text_window () { ); if( !ret ) panic("Cannot create text window"); + /* move it in the predefined position */ + if( !GetNHApp()->bAutoLayout ) { + MoveWindow(ret, rt.left, rt.top, rt.right - rt.left, rt.bottom - rt.top, TRUE); + } + + /* Set window caption */ + SetWindowText(ret, "Text"); + if( !GetNHApp()->bWindowsLocked ) { + DWORD style; + style = GetWindowLong(ret, GWL_STYLE); + style |= WS_CAPTION; + SetWindowLong(ret, GWL_STYLE, style); + SetWindowPos(ret, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED); + } + + /* create and set window data */ data = (PNHTextWindow)malloc(sizeof(NHTextWindow)); if( !data ) panic("out of memory"); - ZeroMemory(data, sizeof(NHTextWindow)); SetWindowLong(ret, GWL_USERDATA, (LONG)data); return ret; @@ -95,9 +119,24 @@ BOOL CALLBACK NHTextWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPara onMSNHCommand(hWnd, wParam, lParam); break; - case WM_SIZE: + case WM_SIZE: { + RECT rt; + + GetWindowRect(hWnd, &rt); + ScreenToClient(GetNHApp()->hMainWnd, (LPPOINT)&rt); + ScreenToClient(GetNHApp()->hMainWnd, ((LPPOINT)&rt)+1); + mswin_update_window_placement(NHW_TEXT, &rt); + LayoutText(hWnd); - return FALSE; + } return FALSE; + + case WM_MOVE: { + RECT rt; + GetWindowRect(hWnd, &rt); + ScreenToClient(GetNHApp()->hMainWnd, (LPPOINT)&rt); + ScreenToClient(GetNHApp()->hMainWnd, ((LPPOINT)&rt)+1); + mswin_update_window_placement(NHW_TEXT, &rt); + } return FALSE; case WM_COMMAND: switch (LOWORD(wParam)) @@ -252,3 +291,4 @@ LRESULT CALLBACK NHEditHookWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARA else return 0; } + diff --git a/win/win32/mhtext.h b/win/win32/mhtext.h index 64be03d4f..8cd136f9d 100644 --- a/win/win32/mhtext.h +++ b/win/win32/mhtext.h @@ -12,3 +12,4 @@ HWND mswin_init_text_window (void); void mswin_display_text_window (HWND hwnd); #endif /* MSWINTextWindow_h */ + diff --git a/win/win32/mswproc.c b/win/win32/mswproc.c index 4b2b93549..ce27794ee 100644 --- a/win/win32/mswproc.c +++ b/win/win32/mswproc.c @@ -241,7 +241,8 @@ void mswin_init_nhwindows(int* argc, char** argv) mswin_color_from_string(iflags.wc_backgrnd_status, &status_bg_brush, &status_bg_color); mswin_color_from_string(iflags.wc_backgrnd_text, &text_bg_brush, &text_bg_color); - if (iflags.wc_splash_screen) mswin_display_splash_window(FALSE); + if (iflags.wc_splash_screen) mswin_display_splash_window(FALSE); + iflags.window_inited = TRUE; } @@ -813,9 +814,10 @@ void mswin_display_nhwindow(winid wid, BOOLEAN_P block) logDebug("mswin_display_nhwindow(%d, %d)\n", wid, block); if (GetNHApp()->windowlist[wid].win != NULL) { + ShowWindow(GetNHApp()->windowlist[wid].win, SW_SHOW); if (GetNHApp()->windowlist[wid].type == NHW_MENU) { MENU_ITEM_P* p; - mswin_menu_window_select_menu(GetNHApp()->windowlist[wid].win, PICK_NONE, &p); + mswin_menu_window_select_menu(GetNHApp()->windowlist[wid].win, PICK_NONE, &p, TRUE); } if (GetNHApp()->windowlist[wid].type == NHW_TEXT) { mswin_display_text_window(GetNHApp()->windowlist[wid].win); } if (GetNHApp()->windowlist[wid].type == NHW_RIP) { @@ -1163,7 +1165,13 @@ int mswin_select_menu(winid wid, int how, MENU_ITEM_P **selected) (wid < MAXWINDOWS) && (GetNHApp()->windowlist[wid].win != NULL)) { - nReturned = mswin_menu_window_select_menu(GetNHApp()->windowlist[wid].win, how, selected); + ShowWindow(GetNHApp()->windowlist[wid].win, SW_SHOW); + nReturned = mswin_menu_window_select_menu( + GetNHApp()->windowlist[wid].win, + how, + selected, + !(flags.perm_invent && wid==WIN_INVEN && how==PICK_NONE) /* don't activate inventory window if perm_invent is on */ + ); } return nReturned; } @@ -1176,6 +1184,10 @@ int mswin_select_menu(winid wid, int how, MENU_ITEM_P **selected) void mswin_update_inventory() { logDebug("mswin_update_inventory()\n"); + if( flags.perm_invent && + program_state.something_worth_saving && + iflags.window_inited && + WIN_INVEN!=WIN_ERR ) display_inventory(NULL, FALSE); } /* @@ -1984,6 +1996,7 @@ void mswin_popup_display(HWND hWnd, int* done_indicator) /* bring menu window on top */ SetWindowPos(hWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW); + SetFocus(hWnd); /* go into message loop */ while( IsWindow(hWnd) && @@ -2022,10 +2035,8 @@ void mswin_popup_destroy(HWND hWnd) } DrawMenuBar( GetNHApp()->hMainWnd ); - SetWindowPos(hWnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_HIDEWINDOW); + ShowWindow(hWnd, SW_HIDE); GetNHApp()->hPopupWnd = NULL; - mswin_window_mark_dead( mswin_winid_from_handle(hWnd) ); - DestroyWindow(hWnd); mswin_layout_main_window(hWnd); @@ -2067,6 +2078,27 @@ logDebug(const char *fmt, ...) #define MAINRIGHTKEY "MainRight" #define MAINTOPKEY "MainTop" #define MAINBOTTOMKEY "MainBottom" +#define MAINAUTOLAYOUT "AutoLayout" +#define MAPLEFT "MapLeft" +#define MAPRIGHT "MapRight" +#define MAPTOP "MapTop" +#define MAPBOTTOM "MapBottom" +#define MSGLEFT "MsgLeft" +#define MSGRIGHT "MsgRight" +#define MSGTOP "MsgTop" +#define MSGBOTTOM "MsgBottom" +#define STATUSLEFT "StatusLeft" +#define STATUSRIGHT "StatusRight" +#define STATUSTOP "StatusTop" +#define STATUSBOTTOM "StatusBottom" +#define MENULEFT "MenuLeft" +#define MENURIGHT "MenuRight" +#define MENUTOP "MenuTop" +#define MENUBOTTOM "MenuBottom" +#define TEXTLEFT "TextLeft" +#define TEXTRIGHT "TextRight" +#define TEXTTOP "TextTop" +#define TEXTBOTTOM "TextBottom" /* #define all the subkeys here */ #define INTFKEY "Interface" @@ -2076,6 +2108,7 @@ mswin_read_reg() { HKEY key; DWORD size; + DWORD safe_buf; char keystring[MAX_PATH]; sprintf(keystring, "%s\\%s\\%s\\%s", @@ -2091,20 +2124,63 @@ mswin_read_reg() return; size = sizeof(DWORD); - /* Read the keys here. */ - RegQueryValueEx(key, INTFKEY, 0, NULL, (unsigned char *)(&(GetNHApp()->regNetHackMode)), &size); - /* Main window placement */ - RegQueryValueEx(key, MAINSHOWSTATEKEY, 0, NULL, (unsigned char *)(&(GetNHApp()->regMainShowState)), &size); - RegQueryValueEx(key, MAINMINXKEY, 0, NULL, (unsigned char *)(&(GetNHApp()->regMainMinX)), &size); - RegQueryValueEx(key, MAINMINYKEY, 0, NULL, (unsigned char *)(&(GetNHApp()->regMainMinY)), &size); - RegQueryValueEx(key, MAINMAXXKEY, 0, NULL, (unsigned char *)(&(GetNHApp()->regMainMaxX)), &size); - RegQueryValueEx(key, MAINMAXYKEY, 0, NULL, (unsigned char *)(&(GetNHApp()->regMainMaxY)), &size); - RegQueryValueEx(key, MAINLEFTKEY, 0, NULL, (unsigned char *)(&(GetNHApp()->regMainLeft)), &size); - RegQueryValueEx(key, MAINRIGHTKEY, 0, NULL, (unsigned char *)(&(GetNHApp()->regMainRight)), &size); - RegQueryValueEx(key, MAINTOPKEY, 0, NULL, (unsigned char *)(&(GetNHApp()->regMainTop)), &size); - RegQueryValueEx(key, MAINBOTTOMKEY, 0, NULL, (unsigned char *)(&(GetNHApp()->regMainBottom)), &size); + +#define NHGETREG_DWORD(name, val) \ + RegQueryValueEx(key, (name), 0, NULL, (unsigned char *)(&safe_buf), &size); (val) = safe_buf; + + /* read the keys here */ + NHGETREG_DWORD(INTFKEY, GetNHApp()->regNetHackMode); + + /* read window placement */ + NHGETREG_DWORD(MAINSHOWSTATEKEY, GetNHApp()->regMainShowState); + NHGETREG_DWORD(MAINMINXKEY, GetNHApp()->regMainMinX); + NHGETREG_DWORD(MAINMINYKEY, GetNHApp()->regMainMinY); + NHGETREG_DWORD(MAINMAXXKEY, GetNHApp()->regMainMaxX); + NHGETREG_DWORD(MAINMAXYKEY, GetNHApp()->regMainMaxY); + NHGETREG_DWORD(MAINLEFTKEY, GetNHApp()->regMainLeft); + NHGETREG_DWORD(MAINRIGHTKEY, GetNHApp()->regMainRight); + NHGETREG_DWORD(MAINTOPKEY, GetNHApp()->regMainTop); + NHGETREG_DWORD(MAINBOTTOMKEY, GetNHApp()->regMainBottom); + + NHGETREG_DWORD(MAINAUTOLAYOUT, GetNHApp()->bAutoLayout); + NHGETREG_DWORD(MAPLEFT, GetNHApp()->rtMapWindow.left); + NHGETREG_DWORD(MAPRIGHT, GetNHApp()->rtMapWindow.right); + NHGETREG_DWORD(MAPTOP, GetNHApp()->rtMapWindow.top); + NHGETREG_DWORD(MAPBOTTOM, GetNHApp()->rtMapWindow.bottom); + NHGETREG_DWORD(MSGLEFT, GetNHApp()->rtMsgWindow.left); + NHGETREG_DWORD(MSGRIGHT, GetNHApp()->rtMsgWindow.right); + NHGETREG_DWORD(MSGTOP, GetNHApp()->rtMsgWindow.top); + NHGETREG_DWORD(MSGBOTTOM, GetNHApp()->rtMsgWindow.bottom); + NHGETREG_DWORD(STATUSLEFT, GetNHApp()->rtStatusWindow.left); + NHGETREG_DWORD(STATUSRIGHT, GetNHApp()->rtStatusWindow.right); + NHGETREG_DWORD(STATUSTOP, GetNHApp()->rtStatusWindow.top); + NHGETREG_DWORD(STATUSBOTTOM, GetNHApp()->rtStatusWindow.bottom); + NHGETREG_DWORD(MENULEFT, GetNHApp()->rtMenuWindow.left); + NHGETREG_DWORD(MENURIGHT, GetNHApp()->rtMenuWindow.right); + NHGETREG_DWORD(MENUTOP, GetNHApp()->rtMenuWindow.top); + NHGETREG_DWORD(MENUBOTTOM, GetNHApp()->rtMenuWindow.bottom); + NHGETREG_DWORD(TEXTLEFT, GetNHApp()->rtTextWindow.left); + NHGETREG_DWORD(TEXTRIGHT, GetNHApp()->rtTextWindow.right); + NHGETREG_DWORD(TEXTTOP, GetNHApp()->rtTextWindow.top); + NHGETREG_DWORD(TEXTBOTTOM, GetNHApp()->rtTextWindow.bottom); + NHGETREG_DWORD(TEXTLEFT, GetNHApp()->rtInvenWindow.left); + NHGETREG_DWORD(TEXTRIGHT, GetNHApp()->rtInvenWindow.right); + NHGETREG_DWORD(TEXTTOP, GetNHApp()->rtInvenWindow.top); + NHGETREG_DWORD(TEXTBOTTOM, GetNHApp()->rtInvenWindow.bottom); +#undef NHGETREG_DWORD RegCloseKey(key); + + /* check the data for validity */ + if( IsRectEmpty(&GetNHApp()->rtMapWindow) || + IsRectEmpty(&GetNHApp()->rtMsgWindow) || + IsRectEmpty(&GetNHApp()->rtStatusWindow) || + IsRectEmpty(&GetNHApp()->rtMenuWindow) || + IsRectEmpty(&GetNHApp()->rtTextWindow) || + IsRectEmpty(&GetNHApp()->rtInvenWindow) ) + { + GetNHApp()->bAutoLayout = TRUE; + } } void @@ -2116,6 +2192,7 @@ mswin_write_reg() if (GetNHApp()->saveRegistrySettings) { char keystring[MAX_PATH]; + DWORD safe_buf; sprintf(keystring, "%s\\%s\\%s\\%s", CATEGORYKEY, COMPANYKEY, PRODUCTKEY, SETTINGSKEY); @@ -2126,18 +2203,49 @@ mswin_write_reg() REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &key, &disposition); } +#define NHSETREG_DWORD(name, val) \ + RegSetValueEx(key, (name), 0, REG_DWORD, (unsigned char *)((safe_buf=(val)), &safe_buf), sizeof(DWORD)); + /* Write the keys here */ - RegSetValueEx(key, INTFKEY, 0, REG_DWORD, (unsigned char *)(&(GetNHApp()->regNetHackMode)), sizeof(DWORD)); + NHSETREG_DWORD(INTFKEY, GetNHApp()->regNetHackMode); + /* Main window placement */ - RegSetValueEx(key, MAINSHOWSTATEKEY, 0, REG_DWORD, (unsigned char *)(&(GetNHApp()->regMainShowState)), sizeof(DWORD)); - RegSetValueEx(key, MAINMINXKEY, 0, REG_DWORD, (unsigned char *)(&(GetNHApp()->regMainMinX)), sizeof(DWORD)); - RegSetValueEx(key, MAINMINYKEY, 0, REG_DWORD, (unsigned char *)(&(GetNHApp()->regMainMinY)), sizeof(DWORD)); - RegSetValueEx(key, MAINMAXXKEY, 0, REG_DWORD, (unsigned char *)(&(GetNHApp()->regMainMaxX)), sizeof(DWORD)); - RegSetValueEx(key, MAINMAXYKEY, 0, REG_DWORD, (unsigned char *)(&(GetNHApp()->regMainMaxY)), sizeof(DWORD)); - RegSetValueEx(key, MAINLEFTKEY, 0, REG_DWORD, (unsigned char *)(&(GetNHApp()->regMainLeft)), sizeof(DWORD)); - RegSetValueEx(key, MAINRIGHTKEY, 0, REG_DWORD, (unsigned char *)(&(GetNHApp()->regMainRight)), sizeof(DWORD)); - RegSetValueEx(key, MAINTOPKEY, 0, REG_DWORD, (unsigned char *)(&(GetNHApp()->regMainTop)), sizeof(DWORD)); - RegSetValueEx(key, MAINBOTTOMKEY, 0, REG_DWORD, (unsigned char *)(&(GetNHApp()->regMainBottom)), sizeof(DWORD)); + NHSETREG_DWORD(MAINSHOWSTATEKEY, GetNHApp()->regMainShowState); + NHSETREG_DWORD(MAINMINXKEY, GetNHApp()->regMainMinX); + NHSETREG_DWORD(MAINMINYKEY, GetNHApp()->regMainMinY); + NHSETREG_DWORD(MAINMAXXKEY, GetNHApp()->regMainMaxX); + NHSETREG_DWORD(MAINMAXYKEY, GetNHApp()->regMainMaxY); + NHSETREG_DWORD(MAINLEFTKEY, GetNHApp()->regMainLeft); + NHSETREG_DWORD(MAINRIGHTKEY, GetNHApp()->regMainRight); + NHSETREG_DWORD(MAINTOPKEY, GetNHApp()->regMainTop); + NHSETREG_DWORD(MAINBOTTOMKEY, GetNHApp()->regMainBottom); + + NHSETREG_DWORD(MAINAUTOLAYOUT, GetNHApp()->bAutoLayout); + NHSETREG_DWORD(MAPLEFT, GetNHApp()->rtMapWindow.left); + NHSETREG_DWORD(MAPRIGHT, GetNHApp()->rtMapWindow.right); + NHSETREG_DWORD(MAPTOP, GetNHApp()->rtMapWindow.top); + NHSETREG_DWORD(MAPBOTTOM, GetNHApp()->rtMapWindow.bottom); + NHSETREG_DWORD(MSGLEFT, GetNHApp()->rtMsgWindow.left); + NHSETREG_DWORD(MSGRIGHT, GetNHApp()->rtMsgWindow.right); + NHSETREG_DWORD(MSGTOP, GetNHApp()->rtMsgWindow.top); + NHSETREG_DWORD(MSGBOTTOM, GetNHApp()->rtMsgWindow.bottom); + NHSETREG_DWORD(STATUSLEFT, GetNHApp()->rtStatusWindow.left); + NHSETREG_DWORD(STATUSRIGHT, GetNHApp()->rtStatusWindow.right); + NHSETREG_DWORD(STATUSTOP, GetNHApp()->rtStatusWindow.top); + NHSETREG_DWORD(STATUSBOTTOM, GetNHApp()->rtStatusWindow.bottom); + NHSETREG_DWORD(MENULEFT, GetNHApp()->rtMenuWindow.left); + NHSETREG_DWORD(MENURIGHT, GetNHApp()->rtMenuWindow.right); + NHSETREG_DWORD(MENUTOP, GetNHApp()->rtMenuWindow.top); + NHSETREG_DWORD(MENUBOTTOM, GetNHApp()->rtMenuWindow.bottom); + NHSETREG_DWORD(TEXTLEFT, GetNHApp()->rtTextWindow.left); + NHSETREG_DWORD(TEXTRIGHT, GetNHApp()->rtTextWindow.right); + NHSETREG_DWORD(TEXTTOP, GetNHApp()->rtTextWindow.top); + NHSETREG_DWORD(TEXTBOTTOM, GetNHApp()->rtTextWindow.bottom); + NHSETREG_DWORD(TEXTLEFT, GetNHApp()->rtInvenWindow.left); + NHSETREG_DWORD(TEXTRIGHT, GetNHApp()->rtInvenWindow.right); + NHSETREG_DWORD(TEXTTOP, GetNHApp()->rtInvenWindow.top); + NHSETREG_DWORD(TEXTBOTTOM, GetNHApp()->rtInvenWindow.bottom); +#undef NHSETREG_DWORD RegCloseKey(key); } @@ -2291,3 +2399,80 @@ static void mswin_color_from_string(char *colorstring, HBRUSH* brushptr, COLORRE *brushptr = CreateSolidBrush(*colorptr); brush_table[max_brush++] = *brushptr; } + +void mswin_get_window_placement(int type, LPRECT rt) +{ + switch (type) { + case NHW_MAP: + *rt = GetNHApp()->rtMapWindow; + break; + + case NHW_MESSAGE: + *rt = GetNHApp()->rtMsgWindow; + break; + + case NHW_STATUS: + *rt = GetNHApp()->rtStatusWindow; + break; + + case NHW_MENU: + *rt = GetNHApp()->rtMenuWindow; + break; + + case NHW_TEXT: + *rt = GetNHApp()->rtTextWindow; + break; + + case NHW_INVEN: + *rt = GetNHApp()->rtInvenWindow; + break; + + default: + SetRect(rt, 0, 0, 0, 0); + break; + } +} + +void mswin_update_window_placement(int type, LPRECT rt) +{ + LPRECT rt_conf = NULL; + + switch (type) { + case NHW_MAP: + rt_conf = &GetNHApp()->rtMapWindow; + break; + + case NHW_MESSAGE: + rt_conf = &GetNHApp()->rtMsgWindow; + break; + + case NHW_STATUS: + rt_conf = &GetNHApp()->rtStatusWindow; + break; + + case NHW_MENU: + rt_conf = &GetNHApp()->rtMenuWindow; + break; + + case NHW_TEXT: + rt_conf = &GetNHApp()->rtTextWindow; + break; + + case NHW_INVEN: + rt_conf = &GetNHApp()->rtInvenWindow; + break; + } + + if( rt_conf && + !IsRectEmpty(rt) && + !EqualRect(rt_conf, rt) ) + { + *rt_conf = *rt; + + /* if window changed size while the game is in progess - + it was most likely resized by the user */ + if( program_state.something_worth_saving ) + GetNHApp()->bAutoLayout = FALSE; + } +} + diff --git a/win/win32/resource.h b/win/win32/resource.h index fb8436af3..c9c06af37 100644 --- a/win/win32/resource.h +++ b/win/win32/resource.h @@ -136,6 +136,8 @@ #define IDM_MAP_FIT_TO_SCREEN 32792 #define IDM_NHMODE 32794 #define IDM_CLEARSETTINGS 32795 +#define IDM_SETTING_AUTOLAYOUT 32796 +#define IDM_SETTING_LOCKWINDOWS 32797 #define IDC_STATIC -1 // Next default values for new objects @@ -143,7 +145,7 @@ #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 145 -#define _APS_NEXT_COMMAND_VALUE 32796 +#define _APS_NEXT_COMMAND_VALUE 32798 #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 b424799ca..684be30cd 100644 --- a/win/win32/winMS.h +++ b/win/win32/winMS.h @@ -16,7 +16,8 @@ #define MAXWINDOWS 15 #endif -#define NHW_RIP 32 +#define NHW_RIP 32 +#define NHW_INVEN 33 #ifndef TILE_X #define TILE_X 16 @@ -77,6 +78,15 @@ typedef struct mswin_nhwindow_app { LONG regMainBottom; LONG regMainRight; DWORD regMainShowState; + + BOOL bAutoLayout; + RECT rtMapWindow; + RECT rtMsgWindow; + RECT rtStatusWindow; + RECT rtMenuWindow; + RECT rtTextWindow; + RECT rtInvenWindow; + BOOL bWindowsLocked; /* TRUE if windows are "locked" - no captions */ } NHWinApp, *PNHWinApp; #define E extern @@ -151,6 +161,9 @@ void mswin_read_reg(void); void mswin_destroy_reg(void); void mswin_write_reg(void); +void mswin_get_window_placement(int type, LPRECT rt); +void mswin_update_window_placement(int type, LPRECT rt); + extern HBRUSH menu_bg_brush; extern HBRUSH menu_fg_brush; extern HBRUSH text_bg_brush; @@ -198,3 +211,4 @@ extern COLORREF message_fg_color; #endif #endif /* WINmswin_H */ + diff --git a/win/win32/winhack.c b/win/win32/winhack.c index b254f472e..84061748f 100644 --- a/win/win32/winhack.c +++ b/win/win32/winhack.c @@ -113,6 +113,9 @@ int APIENTRY WinMain(HINSTANCE hInstance, _nethack_app.bNoVScroll = FALSE; _nethack_app.saved_text = strdup(""); + _nethack_app.bAutoLayout = TRUE; + _nethack_app.bWindowsLocked = TRUE; + // init controls if (FAILED(GetComCtlVersion(&major, &minor))) { diff --git a/win/win32/winhack.rc b/win/win32/winhack.rc index 82be7c279..32d210a57 100644 --- a/win/win32/winhack.rc +++ b/win/win32/winhack.rc @@ -69,6 +69,9 @@ BEGIN MENUITEM "NetHack Mode", IDM_NHMODE MENUITEM SEPARATOR MENUITEM "&Clear All Settings", IDM_CLEARSETTINGS + MENUITEM SEPARATOR + MENUITEM "Auto &Arrange Windows", IDM_SETTING_AUTOLAYOUT + MENUITEM "&Lock Windows", IDM_SETTING_LOCKWINDOWS END POPUP "&Help" BEGIN @@ -116,24 +119,24 @@ END IDD_NHTEXT DIALOGEX 0, 0, 172, 178 STYLE DS_SETFOREGROUND | WS_CHILD | WS_THICKFRAME -EXSTYLE WS_EX_STATICEDGE -FONT 8, "MS Sans Serif" +EXSTYLE WS_EX_CLIENTEDGE +FONT 8, "MS Sans Serif", 0, 0, 0x1 BEGIN DEFPUSHBUTTON "OK",IDOK,54,163,50,14 - EDITTEXT IDC_TEXT_CONTROL,0,0,170,160,ES_MULTILINE | + EDITTEXT IDC_TEXT_CONTROL,0,0,172,160,ES_MULTILINE | ES_OEMCONVERT | ES_READONLY | WS_VSCROLL | WS_HSCROLL END IDD_MENU DIALOGEX 0, 0, 187, 153 STYLE WS_CHILD | WS_CLIPSIBLINGS | WS_THICKFRAME -EXSTYLE WS_EX_CLIENTEDGE | WS_EX_CONTROLPARENT | WS_EX_STATICEDGE -FONT 8, "MS Sans Serif" +EXSTYLE WS_EX_CLIENTEDGE | WS_EX_CONTROLPARENT +FONT 8, "MS Sans Serif", 0, 0, 0x1 BEGIN - DEFPUSHBUTTON "OK",IDOK,7,132,50,14,BS_FLAT - PUSHBUTTON "Cancel",IDCANCEL,130,132,50,14,BS_FLAT - LISTBOX IDC_MENU_LIST,10,10,170,55,LBS_SORT | WS_TABSTOP + DEFPUSHBUTTON "OK",IDOK,7,132,50,14,BS_FLAT | NOT WS_TABSTOP + PUSHBUTTON "Cancel",IDCANCEL,130,132,50,14,BS_FLAT | NOT WS_TABSTOP + LISTBOX IDC_MENU_LIST,10,10,170,55,LBS_SORT EDITTEXT IDC_MENU_TEXT,10,70,170,60,ES_MULTILINE | ES_OEMCONVERT | - ES_READONLY | WS_VSCROLL | WS_HSCROLL + ES_READONLY | WS_VSCROLL | WS_HSCROLL | NOT WS_TABSTOP END IDD_GETLIN DIALOG DISCARDABLE 0, 0, 131, 29 @@ -192,7 +195,7 @@ END IDD_NHRIP DIALOGEX 0, 0, 281, 209 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Here lies..." -FONT 8, "MS Sans Serif" +FONT 8, "MS Sans Serif", 0, 0, 0x1 BEGIN DEFPUSHBUTTON "OK",IDOK,82,188,50,14 END @@ -203,7 +206,7 @@ CAPTION "Welcome to NetHack" FONT 8, "MS Sans Serif" BEGIN DEFPUSHBUTTON "OK",IDOK,224,236,50,14 - EDITTEXT IDC_EXTRAINFO,7,191,267,37,ES_MULTILINE | ES_READONLY | + EDITTEXT IDC_EXTRAINFO,7,191,267,37,ES_MULTILINE | ES_READONLY | WS_VSCROLL END