OSDN Git Service

upgrade to 3.6.1
[jnethack/source.git] / win / win32 / mhtext.c
1 /* NetHack 3.6  mhtext.c        $NHDT-Date: 1432512813 2015/05/25 00:13:33 $  $NHDT-Branch: master $:$NHDT-Revision: 1.25 $ */
2 /* Copyright (C) 2001 by Alex Kompel     */
3 /* NetHack may be freely redistributed.  See license for details. */
4
5 #include "winMS.h"
6 #include "resource.h"
7 #include "mhtext.h"
8 #include "mhmsg.h"
9 #include "mhfont.h"
10
11 PNHWinApp GetNHApp(void);
12
13 typedef struct mswin_nethack_text_window {
14     TCHAR *window_text;
15 } NHTextWindow, *PNHTextWindow;
16
17 static WNDPROC editControlWndProc = 0;
18 #define DEFAULT_COLOR_BG_TEXT COLOR_WINDOW
19 #define DEFAULT_COLOR_FG_TEXT COLOR_WINDOWTEXT
20
21 INT_PTR CALLBACK NHTextWndProc(HWND, UINT, WPARAM, LPARAM);
22 LRESULT CALLBACK NHEditHookWndProc(HWND, UINT, WPARAM, LPARAM);
23 static void onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM lParam);
24 static void LayoutText(HWND hwnd);
25
26 HWND
27 mswin_init_text_window()
28 {
29     HWND ret;
30     PNHTextWindow data;
31     RECT rt;
32
33     /* get window position */
34     if (GetNHApp()->bAutoLayout) {
35         SetRect(&rt, 0, 0, 0, 0);
36     } else {
37         mswin_get_window_placement(NHW_TEXT, &rt);
38     }
39
40     /* create text widnow object */
41     ret = CreateDialog(GetNHApp()->hApp, MAKEINTRESOURCE(IDD_NHTEXT),
42                        GetNHApp()->hMainWnd, NHTextWndProc);
43     if (!ret)
44         panic("Cannot create text window");
45
46     /* move it in the predefined position */
47     if (!GetNHApp()->bAutoLayout) {
48         MoveWindow(ret, rt.left, rt.top, rt.right - rt.left,
49                    rt.bottom - rt.top, TRUE);
50     }
51
52     /* Set window caption */
53     SetWindowText(ret, "Text");
54
55     /* create and set window data */
56     data = (PNHTextWindow) malloc(sizeof(NHTextWindow));
57     if (!data)
58         panic("out of memory");
59     ZeroMemory(data, sizeof(NHTextWindow));
60     SetWindowLongPtr(ret, GWLP_USERDATA, (LONG_PTR) data);
61
62     mswin_apply_window_style(ret);
63
64     return ret;
65 }
66
67 void
68 mswin_display_text_window(HWND hWnd)
69 {
70     PNHTextWindow data;
71
72     data = (PNHTextWindow) GetWindowLongPtr(hWnd, GWLP_USERDATA);
73     if (data && data->window_text) {
74         HWND control;
75         control = GetDlgItem(hWnd, IDC_TEXT_CONTROL);
76         SendMessage(control, EM_FMTLINES, 1, 0);
77         SetWindowText(control, data->window_text);
78     }
79
80     mswin_popup_display(hWnd, NULL);
81     mswin_popup_destroy(hWnd);
82 }
83
84 INT_PTR CALLBACK
85 NHTextWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
86 {
87     HWND control;
88     HDC hdc;
89     PNHTextWindow data;
90     TCHAR title[MAX_LOADSTRING];
91
92     data = (PNHTextWindow) GetWindowLongPtr(hWnd, GWLP_USERDATA);
93     switch (message) {
94     case WM_INITDIALOG:
95         /* set text control font */
96         control = GetDlgItem(hWnd, IDC_TEXT_CONTROL);
97         if (!control) {
98             panic("cannot get text view window");
99         }
100
101         hdc = GetDC(control);
102         SendMessage(control, WM_SETFONT,
103                     (WPARAM) mswin_get_font(NHW_TEXT, ATR_NONE, hdc, FALSE),
104                     0);
105         ReleaseDC(control, hdc);
106
107         /* subclass edit control */
108         editControlWndProc =
109             (WNDPROC) GetWindowLongPtr(control, GWLP_WNDPROC);
110         SetWindowLongPtr(control, GWLP_WNDPROC, (LONG_PTR) NHEditHookWndProc);
111
112         SetFocus(control);
113
114         /* Even though the dialog has no caption, you can still set the title
115            which shows on Alt-Tab */
116         LoadString(GetNHApp()->hApp, IDS_APP_TITLE, title, MAX_LOADSTRING);
117         SetWindowText(hWnd, title);
118         return FALSE;
119
120     case WM_MSNH_COMMAND:
121         onMSNHCommand(hWnd, wParam, lParam);
122         break;
123
124     case WM_SIZE: {
125         RECT rt;
126
127         GetWindowRect(hWnd, &rt);
128         ScreenToClient(GetNHApp()->hMainWnd, (LPPOINT) &rt);
129         ScreenToClient(GetNHApp()->hMainWnd, ((LPPOINT) &rt) + 1);
130         mswin_update_window_placement(NHW_TEXT, &rt);
131
132         LayoutText(hWnd);
133     }
134         return FALSE;
135
136     case WM_MOVE: {
137         RECT rt;
138         GetWindowRect(hWnd, &rt);
139         ScreenToClient(GetNHApp()->hMainWnd, (LPPOINT) &rt);
140         ScreenToClient(GetNHApp()->hMainWnd, ((LPPOINT) &rt) + 1);
141         mswin_update_window_placement(NHW_TEXT, &rt);
142     }
143         return FALSE;
144
145     case WM_COMMAND:
146         switch (LOWORD(wParam)) {
147         case IDOK:
148         case IDCANCEL:
149             mswin_window_mark_dead(mswin_winid_from_handle(hWnd));
150             if (GetNHApp()->hMainWnd == hWnd)
151                 GetNHApp()->hMainWnd = NULL;
152             DestroyWindow(hWnd);
153             SetFocus(GetNHApp()->hMainWnd);
154             return TRUE;
155         }
156         break;
157
158     case WM_CTLCOLORSTATIC: { /* sent by edit control before it is drawn */
159         HDC hdcEdit = (HDC) wParam;
160         HWND hwndEdit = (HWND) lParam;
161         if (hwndEdit == GetDlgItem(hWnd, IDC_TEXT_CONTROL)) {
162             SetBkColor(hdcEdit, text_bg_brush ? text_bg_color
163                                               : (COLORREF) GetSysColor(
164                                                     DEFAULT_COLOR_BG_TEXT));
165             SetTextColor(hdcEdit, text_fg_brush ? text_fg_color
166                                                 : (COLORREF) GetSysColor(
167                                                       DEFAULT_COLOR_FG_TEXT));
168             return (INT_PTR)(text_bg_brush
169                                  ? text_bg_brush
170                                  : SYSCLR_TO_BRUSH(DEFAULT_COLOR_BG_TEXT));
171         }
172     }
173         return FALSE;
174
175     case WM_DESTROY:
176         if (data) {
177             if (data->window_text)
178                 free(data->window_text);
179             free(data);
180             SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR) 0);
181         }
182         break;
183     }
184     return FALSE;
185 }
186
187 void
188 onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
189 {
190     PNHTextWindow data;
191
192     data = (PNHTextWindow) GetWindowLongPtr(hWnd, GWLP_USERDATA);
193     switch (wParam) {
194     case MSNH_MSG_PUTSTR: {
195         PMSNHMsgPutstr msg_data = (PMSNHMsgPutstr) lParam;
196         TCHAR wbuf[BUFSZ];
197         size_t text_size;
198
199         if (!data->window_text) {
200             text_size = strlen(msg_data->text) + 4;
201             data->window_text =
202                 (TCHAR *) malloc(text_size * sizeof(data->window_text[0]));
203             ZeroMemory(data->window_text,
204                        text_size * sizeof(data->window_text[0]));
205         } else {
206             text_size =
207                 _tcslen(data->window_text) + strlen(msg_data->text) + 4;
208             data->window_text = (TCHAR *) realloc(
209                 data->window_text, text_size * sizeof(data->window_text[0]));
210         }
211         if (!data->window_text)
212             break;
213
214         _tcscat(data->window_text, NH_A2W(msg_data->text, wbuf, BUFSZ));
215         _tcscat(data->window_text, TEXT("\r\n"));
216         break;
217     }
218     }
219 }
220
221 void
222 LayoutText(HWND hWnd)
223 {
224     HWND btn_ok;
225     HWND text;
226     RECT clrt, rt;
227     POINT pt_elem, pt_ok;
228     SIZE sz_elem, sz_ok;
229
230     text = GetDlgItem(hWnd, IDC_TEXT_CONTROL);
231     btn_ok = GetDlgItem(hWnd, IDOK);
232
233     /* get window coordinates */
234     GetClientRect(hWnd, &clrt);
235
236     if( !GetNHApp()->regNetHackMode ) {
237         /* set window placements */
238         GetWindowRect(btn_ok, &rt);
239         sz_ok.cx = clrt.right - clrt.left;
240         sz_ok.cy = rt.bottom - rt.top;
241         pt_ok.x = clrt.left;
242         pt_ok.y = clrt.bottom - sz_ok.cy;
243
244         pt_elem.x = clrt.left;
245         pt_elem.y = clrt.top;
246         sz_elem.cx = clrt.right - clrt.left;
247         sz_elem.cy = pt_ok.y;
248
249         MoveWindow(text, pt_elem.x, pt_elem.y, sz_elem.cx, sz_elem.cy, TRUE);
250         MoveWindow(btn_ok, pt_ok.x, pt_ok.y, sz_ok.cx, sz_ok.cy, TRUE);
251     } else {
252         sz_ok.cx = sz_ok.cy = 0;
253
254         pt_ok.x = pt_ok.y = 0;
255         pt_elem.x = clrt.left;
256         pt_elem.y = clrt.top;
257
258         sz_elem.cx = clrt.right - clrt.left;
259         sz_elem.cy = clrt.bottom - clrt.top;
260
261         ShowWindow(btn_ok, SW_HIDE);
262         MoveWindow(text, pt_elem.x, pt_elem.y, sz_elem.cx, sz_elem.cy, TRUE );
263     }
264     mswin_apply_window_style(text);
265 }
266
267 /* Edit box hook */
268 LRESULT CALLBACK
269 NHEditHookWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
270 {
271     HDC hDC;
272     RECT rc;
273
274     switch (message) {
275     case WM_ERASEBKGND:
276         hDC = (HDC) wParam;
277         GetClientRect(hWnd, &rc);
278         FillRect(hDC, &rc, text_bg_brush
279                                ? text_bg_brush
280                                : SYSCLR_TO_BRUSH(DEFAULT_COLOR_BG_TEXT));
281         return 1;
282
283     case WM_KEYDOWN:
284         switch (wParam) {
285         /* close on space in Windows mode
286            page down on space in NetHack mode */
287         case VK_SPACE: {
288             SCROLLINFO si;
289
290             si.cbSize = sizeof(SCROLLINFO);
291             si.fMask = SIF_POS | SIF_RANGE | SIF_PAGE;
292             GetScrollInfo(hWnd, SB_VERT, &si);
293             /* If nethackmode and not at the end of the list */
294             if (GetNHApp()->regNetHackMode
295                 && (si.nPos + (int) si.nPage) <= (si.nMax - si.nMin))
296                 SendMessage(hWnd, EM_SCROLL, SB_PAGEDOWN, 0);
297             else
298                 PostMessage(GetParent(hWnd), WM_COMMAND, MAKELONG(IDOK, 0),
299                             0);
300             return 0;
301         }
302         case VK_NEXT:
303             SendMessage(hWnd, EM_SCROLL, SB_PAGEDOWN, 0);
304             return 0;
305         case VK_PRIOR:
306             SendMessage(hWnd, EM_SCROLL, SB_PAGEUP, 0);
307             return 0;
308         case VK_UP:
309             SendMessage(hWnd, EM_SCROLL, SB_LINEUP, 0);
310             return 0;
311         case VK_DOWN:
312             SendMessage(hWnd, EM_SCROLL, SB_LINEDOWN, 0);
313             return 0;
314         }
315         break;
316
317     case WM_CHAR:
318         switch(wParam) {
319         case MENU_FIRST_PAGE:
320             SendMessage(hWnd, EM_SCROLL, SB_TOP, 0);
321             return 0;
322         case MENU_LAST_PAGE:
323             SendMessage(hWnd, EM_SCROLL, SB_BOTTOM, 0);
324             return 0;
325         case MENU_NEXT_PAGE:
326             SendMessage(hWnd, EM_SCROLL, SB_PAGEDOWN, 0);
327             return 0;
328         case MENU_PREVIOUS_PAGE:
329             SendMessage(hWnd, EM_SCROLL, SB_PAGEUP, 0);
330             return 0;
331         }
332         break;
333
334     /* edit control needs to know nothing of focus. We will take care of it
335      * for it */
336     case WM_SETFOCUS:
337         HideCaret(hWnd);
338         return 0;
339     }
340
341     if (editControlWndProc)
342         return CallWindowProc(editControlWndProc, hWnd, message, wParam,
343                               lParam);
344     else
345         return 0;
346 }