OSDN Git Service

adjust for patch
[jnethack/source.git] / win / win32 / mhstatus.c
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. */
4
5 #include "winMS.h"
6 #include "mhstatus.h"
7 #include "mhmsg.h"
8 #include "mhfont.h"
9
10 #define NHSW_LINES 2
11 #define MAXWINDOWTEXT BUFSZ
12
13 extern COLORREF nhcolor_to_RGB(int c); /* from mhmap */
14
15 typedef struct mswin_nethack_status_window {
16     int index;
17     char window_text[NHSW_LINES][MAXWINDOWTEXT + 1];
18     int n_fields;
19     const char **vals;
20     boolean *activefields;
21     int *colors;
22 } NHStatusWindow, *PNHStatusWindow;
23
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 */
33
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);
38
39 #define DEFAULT_COLOR_BG_STATUS COLOR_WINDOW
40 #define DEFAULT_COLOR_FG_STATUS COLOR_WINDOWTEXT
41
42 HWND
43 mswin_init_status_window()
44 {
45     static int run_once = 0;
46     HWND ret;
47     NHStatusWindow *data;
48     RECT rt;
49
50     if (!run_once) {
51         register_status_window_class();
52         run_once = 1;
53     }
54
55     /* get window position */
56     if (GetNHApp()->bAutoLayout) {
57         SetRect(&rt, 0, 0, 0, 0);
58     } else {
59         mswin_get_window_placement(NHW_STATUS, &rt);
60     }
61
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);
70     if (!ret)
71         panic("Cannot create status window");
72
73     /* Set window caption */
74     SetWindowText(ret, "Status");
75
76     /* create window data */
77     data = (PNHStatusWindow) malloc(sizeof(NHStatusWindow));
78     if (!data)
79         panic("out of memory");
80
81     ZeroMemory(data, sizeof(NHStatusWindow));
82     SetWindowLongPtr(ret, GWLP_USERDATA, (LONG_PTR) data);
83     return ret;
84 }
85
86 void
87 register_status_window_class()
88 {
89     WNDCLASS wcex;
90     ZeroMemory(&wcex, sizeof(wcex));
91
92     wcex.style = CS_NOCLOSE;
93     wcex.lpfnWndProc = (WNDPROC) StatusWndProc;
94     wcex.cbClsExtra = 0;
95     wcex.cbWndExtra = 0;
96     wcex.hInstance = GetNHApp()->hApp;
97     wcex.hIcon = NULL;
98     wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
99     wcex.hbrBackground = status_bg_brush
100                              ? status_bg_brush
101                              : SYSCLR_TO_BRUSH(DEFAULT_COLOR_BG_STATUS);
102     wcex.lpszMenuName = NULL;
103     wcex.lpszClassName = szStatusWindowClass;
104
105     RegisterClass(&wcex);
106 }
107
108 LRESULT CALLBACK
109 StatusWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
110 {
111     PNHStatusWindow data;
112
113     data = (PNHStatusWindow) GetWindowLongPtr(hWnd, GWLP_USERDATA);
114     switch (message) {
115     case WM_MSNH_COMMAND: {
116         switch (wParam) {
117         case MSNH_MSG_PUTSTR: {
118             PMSNHMsgPutstr msg_data = (PMSNHMsgPutstr) lParam;
119             strncpy(data->window_text[data->index], msg_data->text,
120                     MAXWINDOWTEXT);
121             data->index = (data->index + 1) % NHSW_LINES;
122             InvalidateRect(hWnd, NULL, TRUE);
123         } break;
124
125         case MSNH_MSG_CLEAR_WINDOW: {
126             data->index = 0;
127             ZeroMemory(data->window_text, sizeof(data->window_text));
128             InvalidateRect(hWnd, NULL, TRUE);
129         } break;
130
131         case MSNH_MSG_GETTEXT: {
132             PMSNHMsgGetText msg_data = (PMSNHMsgGetText) lParam;
133 #ifdef STATUS_VIA_WINDOWPORT
134             int **fop;
135             int *f;
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],
142                                     msg_data->max_size
143                                         - strlen(msg_data->buffer));
144                     }
145                     strncat(msg_data->buffer, "\r\n",
146                             msg_data->max_size - strlen(msg_data->buffer));
147                 }
148             }
149 #else  /*  STATUS_VIA_WINDOWPORT */
150             strncpy(msg_data->buffer, data->window_text[0],
151                     msg_data->max_size);
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 */
157         } break;
158
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);
166         } break;
167         } /* end switch( wParam ) { */
168     } break;
169
170     case WM_PAINT:
171         return onWMPaint(hWnd, wParam, lParam);
172
173     case WM_SIZE: {
174         RECT rt;
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);
179     }
180         return FALSE;
181
182     case WM_MOVE: {
183         RECT 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);
188     }
189         return FALSE;
190
191     case WM_DESTROY:
192         free(data);
193         SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR) 0);
194         break;
195
196     case WM_SETFOCUS:
197         SetFocus(GetNHApp()->hMainWnd);
198         break;
199
200     default:
201         return DefWindowProc(hWnd, message, wParam, lParam);
202     }
203     return 0;
204 }
205
206 #ifdef STATUS_VIA_WINDOWPORT
207 static LRESULT
208 onWMPaint(HWND hWnd, WPARAM wParam, LPARAM lParam)
209 {
210     int *f;
211     int **fop;
212     SIZE sz;
213     HGDIOBJ oldFont, normalFont, boldFont;
214     TCHAR wbuf[BUFSZ];
215     COLORREF OldBg, OldFg, Bg, Fg;
216     RECT rt;
217     PAINTSTRUCT ps;
218     HDC hdc;
219     PNHStatusWindow data;
220
221     data = (PNHStatusWindow) GetWindowLongPtr(hWnd, GWLP_USERDATA);
222
223     hdc = BeginPaint(hWnd, &ps);
224     GetClientRect(hWnd, &rt);
225
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);
229
230     Bg = status_bg_brush ? status_bg_color
231                          : (COLORREF) GetSysColor(DEFAULT_COLOR_BG_STATUS);
232     OldBg = SetBkColor(hdc, Bg);
233
234     Fg = status_fg_brush ? status_fg_color
235                          : (COLORREF) GetSysColor(DEFAULT_COLOR_FG_STATUS);
236     OldFg = SetTextColor(hdc, Fg);
237
238     for (fop = fieldorders; *fop; fop++) {
239         LONG left = rt.left;
240         LONG cy = 0;
241         int vlen;
242         for (f = *fop; *f != -1; f++) {
243             if (((*f) >= data->n_fields) || (!data->activefields[*f]))
244                 continue;
245             vlen = strlen(data->vals[*f]);
246             NH_A2W(data->vals[*f], wbuf, SIZE(wbuf));
247
248             if (!iflags.use_status_hilites) {
249                 SelectObject(hdc, normalFont);
250                 SetBkColor(hdc, Bg);
251                 SetTextColor(hdc, Fg);
252             } else if (data->colors[*f] == CLR_MAX
253                 || data->colors[*f] == BL_HILITE_NONE) {
254                 SelectObject(hdc, normalFont);
255                 SetBkColor(hdc, Bg);
256                 SetTextColor(hdc, Fg);
257             } else if (data->colors[*f] > 0) {
258                 SelectObject(hdc, normalFont);
259                 SetBkColor(hdc, Bg);
260                 SetTextColor(hdc, nhcolor_to_RGB(data->colors[*f]));
261             } else if (data->colors[*f] == BL_HILITE_INVERSE) {
262                 SelectObject(hdc, normalFont);
263                 SetBkColor(hdc, Fg);
264                 SetTextColor(hdc, Bg);
265             } else if (data->colors[*f] == BL_HILITE_BOLD) {
266                 SelectObject(hdc, boldFont);
267                 SetBkColor(hdc, Bg);
268                 SetTextColor(hdc, Fg);
269             } else {
270                 SelectObject(hdc, normalFont);
271                 SetBkColor(hdc, Bg);
272                 SetTextColor(hdc, Fg);
273             }
274
275             GetTextExtentPoint32(hdc, wbuf, vlen, &sz);
276             DrawText(hdc, wbuf, vlen, &rt, DT_LEFT);
277
278             rt.left += sz.cx;
279             cy = max(cy, sz.cy);
280         }
281         rt.left = left;
282         rt.top += cy;
283     }
284
285     SelectObject(hdc, oldFont);
286     SetTextColor(hdc, OldFg);
287     SetBkColor(hdc, OldBg);
288     EndPaint(hWnd, &ps);
289
290     return 0;
291 }
292 #else
293 static LRESULT
294 onWMPaint(HWND hWnd, WPARAM wParam, LPARAM lParam)
295 {
296     int i;
297     SIZE sz;
298     HGDIOBJ oldFont;
299     TCHAR wbuf[BUFSZ];
300     COLORREF OldBg, OldFg;
301     RECT rt;
302     PAINTSTRUCT ps;
303     HDC hdc;
304     PNHStatusWindow data;
305
306     data = (PNHStatusWindow) GetWindowLongPtr(hWnd, GWLP_USERDATA);
307
308     hdc = BeginPaint(hWnd, &ps);
309     GetClientRect(hWnd, &rt);
310
311     oldFont =
312         SelectObject(hdc, mswin_get_font(NHW_STATUS, ATR_NONE, hdc, FALSE));
313
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));
320
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);
326         rt.top += sz.cy;
327     }
328
329     SelectObject(hdc, oldFont);
330     SetTextColor(hdc, OldFg);
331     SetBkColor(hdc, OldBg);
332     EndPaint(hWnd, &ps);
333
334     return 0;
335 }
336 #endif /*STATUS_VIA_WINDOWPORT*/
337
338 void
339 mswin_status_window_size(HWND hWnd, LPSIZE sz)
340 {
341     TEXTMETRIC tm;
342     HGDIOBJ saveFont;
343     HDC hdc;
344     PNHStatusWindow data;
345     RECT rt;
346     SIZE text_sz;
347
348     GetClientRect(hWnd, &rt);
349
350     data = (PNHStatusWindow) GetWindowLongPtr(hWnd, GWLP_USERDATA);
351     if (data) {
352         hdc = GetDC(hWnd);
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);
357
358         rt.bottom = rt.top + text_sz.cy * NHSW_LINES;
359
360         SelectObject(hdc, saveFont);
361         ReleaseDC(hWnd, hdc);
362     }
363     AdjustWindowRect(&rt, GetWindowLong(hWnd, GWL_STYLE), FALSE);
364     sz->cx = rt.right - rt.left;
365     sz->cy = rt.bottom - rt.top;
366 }