1 /* NetHack 3.6 mhstatus.c $NHDT-Date: 1432512810 2015/05/25 00:13:30 $ $NHDT-Branch: master $:$NHDT-Revision: 1.22 $ */
2 /* Copyright (C) 2001 by Alex Kompel */
3 /* NetHack may be freely redistributed. See license for details. */
11 #define MAXWINDOWTEXT BUFSZ
13 extern COLORREF nhcolor_to_RGB(int c); /* from mhmap */
15 typedef struct mswin_nethack_status_window {
17 char window_text[NHSW_LINES][MAXWINDOWTEXT + 1];
20 boolean *activefields;
22 } NHStatusWindow, *PNHStatusWindow;
24 #ifdef STATUS_VIA_WINDOWPORT
25 static int fieldorder1[] = { BL_TITLE, BL_STR, BL_DX, BL_CO, BL_IN,
26 BL_WI, BL_CH, BL_ALIGN, BL_SCORE, -1 };
27 static int fieldorder2[] = { BL_LEVELDESC, BL_GOLD, BL_HP, BL_HPMAX,
28 BL_ENE, BL_ENEMAX, BL_AC, BL_XP,
29 BL_EXP, BL_HD, BL_TIME, BL_HUNGER,
30 BL_CAP, BL_CONDITION, -1 };
31 static int *fieldorders[] = { fieldorder1, fieldorder2, NULL };
32 #endif /* STATUS_VIA_WINDOWPORT */
34 static TCHAR szStatusWindowClass[] = TEXT("MSNHStatusWndClass");
35 LRESULT CALLBACK StatusWndProc(HWND, UINT, WPARAM, LPARAM);
36 static void register_status_window_class(void);
37 static LRESULT onWMPaint(HWND hWnd, WPARAM wParam, LPARAM lParam);
39 #define DEFAULT_COLOR_BG_STATUS COLOR_WINDOW
40 #define DEFAULT_COLOR_FG_STATUS COLOR_WINDOWTEXT
43 mswin_init_status_window()
45 static int run_once = 0;
51 register_status_window_class();
55 /* get window position */
56 if (GetNHApp()->bAutoLayout) {
57 SetRect(&rt, 0, 0, 0, 0);
59 mswin_get_window_placement(NHW_STATUS, &rt);
62 /* create status window object */
63 ret = CreateWindow(szStatusWindowClass, NULL,
64 WS_CHILD | WS_CLIPSIBLINGS | WS_SIZEBOX,
65 rt.left, /* horizontal position of window */
66 rt.top, /* vertical position of window */
67 rt.right - rt.left, /* window width */
68 rt.bottom - rt.top, /* window height */
69 GetNHApp()->hMainWnd, NULL, GetNHApp()->hApp, NULL);
71 panic("Cannot create status window");
73 /* Set window caption */
74 SetWindowText(ret, "Status");
76 /* create window data */
77 data = (PNHStatusWindow) malloc(sizeof(NHStatusWindow));
79 panic("out of memory");
81 ZeroMemory(data, sizeof(NHStatusWindow));
82 SetWindowLongPtr(ret, GWLP_USERDATA, (LONG_PTR) data);
87 register_status_window_class()
90 ZeroMemory(&wcex, sizeof(wcex));
92 wcex.style = CS_NOCLOSE;
93 wcex.lpfnWndProc = (WNDPROC) StatusWndProc;
96 wcex.hInstance = GetNHApp()->hApp;
98 wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
99 wcex.hbrBackground = status_bg_brush
101 : SYSCLR_TO_BRUSH(DEFAULT_COLOR_BG_STATUS);
102 wcex.lpszMenuName = NULL;
103 wcex.lpszClassName = szStatusWindowClass;
105 RegisterClass(&wcex);
109 StatusWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
111 PNHStatusWindow data;
113 data = (PNHStatusWindow) GetWindowLongPtr(hWnd, GWLP_USERDATA);
115 case WM_MSNH_COMMAND: {
117 case MSNH_MSG_PUTSTR: {
118 PMSNHMsgPutstr msg_data = (PMSNHMsgPutstr) lParam;
119 strncpy(data->window_text[data->index], msg_data->text,
121 data->index = (data->index + 1) % NHSW_LINES;
122 InvalidateRect(hWnd, NULL, TRUE);
125 case MSNH_MSG_CLEAR_WINDOW: {
127 ZeroMemory(data->window_text, sizeof(data->window_text));
128 InvalidateRect(hWnd, NULL, TRUE);
131 case MSNH_MSG_GETTEXT: {
132 PMSNHMsgGetText msg_data = (PMSNHMsgGetText) lParam;
133 #ifdef STATUS_VIA_WINDOWPORT
136 msg_data->buffer[0] = '\0';
137 if (data->n_fields > 0) {
138 for (fop = fieldorders; *fop; fop++) {
139 for (f = *fop; *f != -1; f++) {
140 if (data->activefields[*f])
141 strncat(msg_data->buffer, data->vals[*f],
143 - strlen(msg_data->buffer));
145 strncat(msg_data->buffer, "\r\n",
146 msg_data->max_size - strlen(msg_data->buffer));
149 #else /* STATUS_VIA_WINDOWPORT */
150 strncpy(msg_data->buffer, data->window_text[0],
152 strncat(msg_data->buffer, "\r\n",
153 msg_data->max_size - strlen(msg_data->buffer));
154 strncat(msg_data->buffer, data->window_text[1],
155 msg_data->max_size - strlen(msg_data->buffer));
156 #endif /* STATUS_VIA_WINDOWPORT */
159 case MSNH_MSG_UPDATE_STATUS: {
160 PMSNHMsgUpdateStatus msg_data = (PMSNHMsgUpdateStatus) lParam;
161 data->n_fields = msg_data->n_fields;
162 data->vals = msg_data->vals;
163 data->activefields = msg_data->activefields;
164 data->colors = msg_data->colors;
165 InvalidateRect(hWnd, NULL, TRUE);
167 } /* end switch( wParam ) { */
171 return onWMPaint(hWnd, wParam, lParam);
175 GetWindowRect(hWnd, &rt);
176 ScreenToClient(GetNHApp()->hMainWnd, (LPPOINT) &rt);
177 ScreenToClient(GetNHApp()->hMainWnd, ((LPPOINT) &rt) + 1);
178 mswin_update_window_placement(NHW_STATUS, &rt);
184 GetWindowRect(hWnd, &rt);
185 ScreenToClient(GetNHApp()->hMainWnd, (LPPOINT) &rt);
186 ScreenToClient(GetNHApp()->hMainWnd, ((LPPOINT) &rt) + 1);
187 mswin_update_window_placement(NHW_STATUS, &rt);
193 SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR) 0);
197 SetFocus(GetNHApp()->hMainWnd);
201 return DefWindowProc(hWnd, message, wParam, lParam);
206 #ifdef STATUS_VIA_WINDOWPORT
208 onWMPaint(HWND hWnd, WPARAM wParam, LPARAM lParam)
213 HGDIOBJ oldFont, normalFont, boldFont;
215 COLORREF OldBg, OldFg, Bg, Fg;
219 PNHStatusWindow data;
221 data = (PNHStatusWindow) GetWindowLongPtr(hWnd, GWLP_USERDATA);
223 hdc = BeginPaint(hWnd, &ps);
224 GetClientRect(hWnd, &rt);
226 normalFont = mswin_get_font(NHW_STATUS, ATR_NONE, hdc, FALSE);
227 boldFont = mswin_get_font(NHW_STATUS, ATR_BOLD, hdc, FALSE);
228 oldFont = SelectObject(hdc, normalFont);
230 Bg = status_bg_brush ? status_bg_color
231 : (COLORREF) GetSysColor(DEFAULT_COLOR_BG_STATUS);
232 OldBg = SetBkColor(hdc, Bg);
234 Fg = status_fg_brush ? status_fg_color
235 : (COLORREF) GetSysColor(DEFAULT_COLOR_FG_STATUS);
236 OldFg = SetTextColor(hdc, Fg);
238 for (fop = fieldorders; *fop; fop++) {
242 for (f = *fop; *f != -1; f++) {
243 if (((*f) >= data->n_fields) || (!data->activefields[*f]))
245 vlen = strlen(data->vals[*f]);
246 NH_A2W(data->vals[*f], wbuf, SIZE(wbuf));
248 if (!iflags.use_status_hilites) {
249 SelectObject(hdc, normalFont);
251 SetTextColor(hdc, Fg);
252 } else if (data->colors[*f] == CLR_MAX
253 || data->colors[*f] == BL_HILITE_NONE) {
254 SelectObject(hdc, normalFont);
256 SetTextColor(hdc, Fg);
257 } else if (data->colors[*f] > 0) {
258 SelectObject(hdc, normalFont);
260 SetTextColor(hdc, nhcolor_to_RGB(data->colors[*f]));
261 } else if (data->colors[*f] == BL_HILITE_INVERSE) {
262 SelectObject(hdc, normalFont);
264 SetTextColor(hdc, Bg);
265 } else if (data->colors[*f] == BL_HILITE_BOLD) {
266 SelectObject(hdc, boldFont);
268 SetTextColor(hdc, Fg);
270 SelectObject(hdc, normalFont);
272 SetTextColor(hdc, Fg);
275 GetTextExtentPoint32(hdc, wbuf, vlen, &sz);
276 DrawText(hdc, wbuf, vlen, &rt, DT_LEFT);
285 SelectObject(hdc, oldFont);
286 SetTextColor(hdc, OldFg);
287 SetBkColor(hdc, OldBg);
294 onWMPaint(HWND hWnd, WPARAM wParam, LPARAM lParam)
300 COLORREF OldBg, OldFg;
304 PNHStatusWindow data;
306 data = (PNHStatusWindow) GetWindowLongPtr(hWnd, GWLP_USERDATA);
308 hdc = BeginPaint(hWnd, &ps);
309 GetClientRect(hWnd, &rt);
312 SelectObject(hdc, mswin_get_font(NHW_STATUS, ATR_NONE, hdc, FALSE));
314 OldBg = SetBkColor(hdc, status_bg_brush ? status_bg_color
315 : (COLORREF) GetSysColor(
316 DEFAULT_COLOR_BG_STATUS));
317 OldFg = SetTextColor(hdc, status_fg_brush ? status_fg_color
318 : (COLORREF) GetSysColor(
319 DEFAULT_COLOR_FG_STATUS));
321 for (i = 0; i < NHSW_LINES; i++) {
322 int wlen = strlen(data->window_text[i]);
323 NH_A2W(data->window_text[i], wbuf, SIZE(wbuf));
324 GetTextExtentPoint32(hdc, wbuf, wlen, &sz);
325 DrawText(hdc, wbuf, wlen, &rt, DT_LEFT | DT_END_ELLIPSIS);
329 SelectObject(hdc, oldFont);
330 SetTextColor(hdc, OldFg);
331 SetBkColor(hdc, OldBg);
336 #endif /*STATUS_VIA_WINDOWPORT*/
339 mswin_status_window_size(HWND hWnd, LPSIZE sz)
344 PNHStatusWindow data;
348 GetClientRect(hWnd, &rt);
350 data = (PNHStatusWindow) GetWindowLongPtr(hWnd, GWLP_USERDATA);
353 saveFont = SelectObject(
354 hdc, mswin_get_font(NHW_STATUS, ATR_NONE, hdc, FALSE));
355 GetTextExtentPoint32(hdc, _T("W"), 1, &text_sz);
356 GetTextMetrics(hdc, &tm);
358 rt.bottom = rt.top + text_sz.cy * NHSW_LINES;
360 SelectObject(hdc, saveFont);
361 ReleaseDC(hWnd, hdc);
363 AdjustWindowRect(&rt, GetWindowLong(hWnd, GWL_STYLE), FALSE);
364 sz->cx = rt.right - rt.left;
365 sz->cy = rt.bottom - rt.top;