OSDN Git Service

upgrade to 3.6.2
[jnethack/source.git] / win / win32 / mhrip.c
1 /* NetHack 3.6  mhrip.c $NHDT-Date: 1432512812 2015/05/25 00:13:32 $  $NHDT-Branch: master $:$NHDT-Revision: 1.19 $ */
2 /* Copyright (C) 2001 by Alex Kompel     */
3 /* NetHack may be freely redistributed.  See license for details. */
4
5 #include "win10.h"
6 #include "winMS.h"
7 #include "resource.h"
8 #include "mhrip.h"
9 #include "mhmsg.h"
10 #include "mhfont.h"
11
12 #define RIP_WIDTH 400
13 #define RIP_HEIGHT 200
14
15 #define RIP_GRAVE_HEIGHT 120
16 #define RIP_GRAVE_WIDTH 115
17 #define RIP_GRAVE_X 90
18 #define RIP_GRAVE_Y 60
19
20 #define RIP_OFFSET_X 10
21 #define RIP_OFFSET_Y 10
22
23 PNHWinApp GetNHApp(void);
24
25 typedef struct mswin_nethack_text_window {
26     HANDLE rip_bmp;
27     TCHAR *window_text;
28     TCHAR *rip_text;
29     int x;
30     int y;
31     int width;
32     int height;
33     int graveX;
34     int graveY;
35     int graveHeight;
36     int graveWidth;
37 } NHRIPWindow, *PNHRIPWindow;
38
39 INT_PTR CALLBACK NHRIPWndProc(HWND, UINT, WPARAM, LPARAM);
40 static void onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM lParam);
41
42 HWND
43 mswin_init_RIP_window()
44 {
45     HWND ret;
46     PNHRIPWindow data;
47
48     ret = CreateDialog(GetNHApp()->hApp, MAKEINTRESOURCE(IDD_NHRIP),
49                        GetNHApp()->hMainWnd, NHRIPWndProc);
50     if (!ret)
51         panic("Cannot create rip window");
52
53     data = (PNHRIPWindow) malloc(sizeof(NHRIPWindow));
54     if (!data)
55         panic("out of memory");
56
57     ZeroMemory(data, sizeof(NHRIPWindow));
58     SetWindowLongPtr(ret, GWLP_USERDATA, (LONG_PTR) data);
59     return ret;
60 }
61
62 void
63 mswin_display_RIP_window(HWND hWnd)
64 {
65     MSG msg;
66     RECT rt;
67     PNHRIPWindow data;
68     HWND mapWnd;
69     RECT riprt;
70     RECT clientrect;
71     RECT textrect;
72     HFONT OldFont;
73     MonitorInfo monitorInfo;
74
75     win10_monitor_info(hWnd, &monitorInfo);
76
77     data = (PNHRIPWindow) GetWindowLongPtr(hWnd, GWLP_USERDATA);
78
79     data->x = (int)(RIP_OFFSET_X * monitorInfo.scale);
80     data->y = (int)(RIP_OFFSET_Y * monitorInfo.scale);
81     data->width = (int)(RIP_WIDTH * monitorInfo.scale);
82     data->height = (int)(RIP_HEIGHT * monitorInfo.scale);
83     data->graveX = (int)(RIP_GRAVE_X * monitorInfo.scale);
84     data->graveY = (int)(RIP_GRAVE_Y * monitorInfo.scale);
85     data->graveWidth = (int)(RIP_GRAVE_WIDTH * monitorInfo.scale);
86     data->graveHeight = (int)(RIP_GRAVE_HEIGHT * monitorInfo.scale);
87
88     GetNHApp()->hPopupWnd = hWnd;
89     mapWnd = mswin_hwnd_from_winid(WIN_MAP);
90     if (!IsWindow(mapWnd))
91         mapWnd = GetNHApp()->hMainWnd;
92     GetWindowRect(mapWnd, &rt);
93     GetWindowRect(hWnd, &riprt);
94     GetClientRect(hWnd, &clientrect);
95     textrect = clientrect;
96     textrect.top += data->y;
97     textrect.left += data->x;
98     textrect.right -= data->x;
99     if (data->window_text) {
100         HDC hdc = GetDC(hWnd);
101         OldFont = SelectObject(hdc, mswin_get_font(NHW_TEXT, 0, hdc, FALSE)->hFont);
102         DrawText(hdc, data->window_text, strlen(data->window_text), &textrect,
103                  DT_LEFT | DT_NOPREFIX | DT_CALCRECT);
104         SelectObject(hdc, OldFont);
105         ReleaseDC(hWnd, hdc);
106     }
107     if (textrect.right - textrect.left > data->width)
108         clientrect.right = textrect.right + data->y - clientrect.right;
109     else
110         clientrect.right =
111             textrect.left + 2 * data->x + data->width - clientrect.right;
112     clientrect.bottom =
113         textrect.bottom + data->height + data->y - clientrect.bottom;
114     GetWindowRect(GetDlgItem(hWnd, IDOK), &textrect);
115     textrect.right -= textrect.left;
116     textrect.bottom -= textrect.top;
117     clientrect.bottom += textrect.bottom + data->y;
118     riprt.right -= riprt.left;
119     riprt.bottom -= riprt.top;
120     riprt.right += clientrect.right;
121     riprt.bottom += clientrect.bottom;
122     rt.left += (rt.right - rt.left - riprt.right) / 2;
123     rt.top += (rt.bottom - rt.top - riprt.bottom) / 2;
124
125     MoveWindow(hWnd, rt.left, rt.top, riprt.right, riprt.bottom, TRUE);
126     GetClientRect(hWnd, &clientrect);
127     MoveWindow(GetDlgItem(hWnd, IDOK),
128                (clientrect.right - clientrect.left - textrect.right) / 2,
129                clientrect.bottom - textrect.bottom - data->y,
130                textrect.right, textrect.bottom, TRUE);
131     ShowWindow(hWnd, SW_SHOW);
132
133     while (IsWindow(hWnd) && GetMessage(&msg, NULL, 0, 0) != 0) {
134         if (!IsDialogMessage(hWnd, &msg)) {
135             TranslateMessage(&msg);
136             DispatchMessage(&msg);
137         }
138     }
139
140     GetNHApp()->hPopupWnd = NULL;
141 }
142
143 INT_PTR CALLBACK
144 NHRIPWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
145 {
146     PNHRIPWindow data = (PNHRIPWindow) GetWindowLongPtr(hWnd, GWLP_USERDATA);
147     switch (message) {
148     case WM_INITDIALOG: {
149         HDC hdc = GetDC(hWnd);
150         cached_font * font = mswin_get_font(NHW_TEXT, ATR_NONE, hdc, FALSE);
151
152         /* set text control font */
153         SendMessage(hWnd, WM_SETFONT, (WPARAM)font->hFont, 0);
154         ReleaseDC(hWnd, hdc);
155
156         SetFocus(GetDlgItem(hWnd, IDOK));
157     } break;
158
159     case WM_MSNH_COMMAND:
160         onMSNHCommand(hWnd, wParam, lParam);
161         break;
162
163     case WM_PAINT: {
164         int bitmap_offset;
165         RECT clientrect;
166         RECT textrect;
167         HDC hdcBitmap;
168         HANDLE OldBitmap;
169         PAINTSTRUCT ps;
170         HFONT OldFont;
171         HDC hdc = BeginPaint(hWnd, &ps);
172         cached_font * font = mswin_get_font(NHW_TEXT, ATR_NONE, hdc, FALSE);
173
174         OldFont = SelectObject(hdc, font->hFont);
175         hdcBitmap = CreateCompatibleDC(hdc);
176         SetBkMode(hdc, TRANSPARENT);
177         GetClientRect(hWnd, &clientrect);
178         textrect = clientrect;
179         textrect.top += data->y;
180         textrect.left += data->x;
181         textrect.right -= data->x;
182         if (data->window_text) {
183             DrawText(hdc, data->window_text, strlen(data->window_text),
184                      &textrect, DT_LEFT | DT_NOPREFIX | DT_CALCRECT);
185             DrawText(hdc, data->window_text, strlen(data->window_text),
186                      &textrect, DT_LEFT | DT_NOPREFIX);
187         }
188         OldBitmap = SelectObject(hdcBitmap, GetNHApp()->bmpRip);
189         SetBkMode(hdc, OPAQUE);
190         bitmap_offset = (textrect.right - textrect.left - data->width) / 2;
191         StretchBlt(hdc, textrect.left + bitmap_offset, textrect.bottom,
192             data->width, data->height, 
193             hdcBitmap, 0, 0, RIP_WIDTH, RIP_HEIGHT, SRCCOPY);
194         SetBkMode(hdc, TRANSPARENT);
195         if (data->rip_text) {
196             textrect.left += data->graveX + bitmap_offset;
197             textrect.top = textrect.bottom + data->graveY;
198             textrect.right = textrect.left + data->graveWidth;
199             textrect.bottom = textrect.top + data->graveHeight;
200             DrawText(hdc, data->rip_text, strlen(data->rip_text), &textrect,
201                      DT_CENTER | DT_VCENTER | DT_NOPREFIX | DT_WORDBREAK);
202         }
203         SelectObject(hdcBitmap, OldBitmap);
204         SelectObject(hdc, OldFont);
205         DeleteDC(hdcBitmap);
206         EndPaint(hWnd, &ps);
207     } break;
208
209     case WM_COMMAND:
210         switch (LOWORD(wParam)) {
211         case IDOK:
212             mswin_window_mark_dead(mswin_winid_from_handle(hWnd));
213             if (GetNHApp()->hMainWnd == hWnd)
214                 GetNHApp()->hMainWnd = NULL;
215             DestroyWindow(hWnd);
216             SetFocus(GetNHApp()->hMainWnd);
217             return TRUE;
218         }
219         break;
220
221     case WM_CLOSE:
222         /* if we get this here, we saved the bones so we can just force a quit
223          */
224
225         mswin_window_mark_dead(mswin_winid_from_handle(hWnd));
226         if (GetNHApp()->hMainWnd == hWnd)
227             GetNHApp()->hMainWnd = NULL;
228         DestroyWindow(hWnd);
229         SetFocus(GetNHApp()->hMainWnd);
230         program_state.stopprint++;
231         return TRUE;
232
233     case WM_DESTROY:
234         if (data) {
235             if (data->window_text)
236                 free(data->window_text);
237             if (data->rip_text)
238                 free(data->rip_text);
239             if (data->rip_bmp != NULL)
240                 DeleteObject(data->rip_bmp);
241             free(data);
242             SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR) 0);
243         }
244         break;
245     }
246     return FALSE;
247 }
248
249 void
250 onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
251 {
252     PNHRIPWindow data;
253     static int InRipText = 1;
254     data = (PNHRIPWindow) GetWindowLongPtr(hWnd, GWLP_USERDATA);
255     switch (wParam) {
256     case MSNH_MSG_PUTSTR: {
257         PMSNHMsgPutstr msg_data = (PMSNHMsgPutstr) lParam;
258         TCHAR wbuf[BUFSZ];
259         size_t text_size;
260
261         if (!data->window_text) {
262             text_size = strlen(msg_data->text) + 4;
263             data->window_text =
264                 (TCHAR *) malloc(text_size * sizeof(data->window_text[0]));
265             ZeroMemory(data->window_text,
266                        text_size * sizeof(data->window_text[0]));
267         } else {
268             text_size =
269                 _tcslen(data->window_text) + strlen(msg_data->text) + 4;
270             data->window_text = (TCHAR *) realloc(
271                 data->window_text, text_size * sizeof(data->window_text[0]));
272         }
273         if (!data->window_text)
274             break;
275
276         _tcscat(data->window_text, NH_A2W(msg_data->text, wbuf, BUFSZ));
277         _tcscat(data->window_text, TEXT("\r\n"));
278         break;
279     }
280     case MSNH_MSG_DIED: {
281         data->rip_text = data->window_text;
282         data->window_text = NULL;
283         break;
284     }
285
286         case MSNH_MSG_RANDOM_INPUT:
287                 nhassert(0); // unexpected
288                 break;
289
290     }
291 }
292
293 void
294 mswin_finish_rip_text(winid wid)
295 {
296     SendMessage(mswin_hwnd_from_winid(wid), WM_MSNH_COMMAND, MSNH_MSG_DIED,
297                 0);
298 }