1 /* Copyright (C) 2001 by Alex Kompel <shurikk@pacbell.net> */
2 /* NetHack may be freely redistributed. See license for details. */
3
4 #include "winMS.h"
5 #include "resource.h"
6 #include "mhtext.h"
7 #include "mhmsg.h"
8 #include "mhfont.h"
9
10 PNHWinApp GetNHApp(void);
11
12 typedef struct mswin_nethack_text_window {
13 TCHAR* window_text;
14 } NHTextWindow, *PNHTextWindow;
15
16 static WNDPROC editControlWndProc = 0;
17 #define DEFAULT_COLOR_BG_TEXT COLOR_WINDOW
18 #define DEFAULT_COLOR_FG_TEXT COLOR_WINDOWTEXT
19
20 BOOL CALLBACK NHTextWndProc(HWND, UINT, WPARAM, LPARAM);
21 LRESULT CALLBACK NHEditHookWndProc(HWND, UINT, WPARAM, LPARAM);
22 static void onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM lParam);
23 static void LayoutText(HWND hwnd);
24
mswin_init_text_window()25 HWND mswin_init_text_window () {
26 HWND ret;
27 PNHTextWindow data;
28
29 ret = CreateDialog(
30 GetNHApp()->hApp,
31 MAKEINTRESOURCE(IDD_NHTEXT),
32 GetNHApp()->hMainWnd,
33 NHTextWndProc
34 );
35 if( !ret ) panic("Cannot create text window");
36
37 data = (PNHTextWindow)malloc(sizeof(NHTextWindow));
38 if( !data ) panic("out of memory");
39
40 ZeroMemory(data, sizeof(NHTextWindow));
41 SetWindowLong(ret, GWL_USERDATA, (LONG)data);
42 return ret;
43 }
44
mswin_display_text_window(HWND hWnd)45 void mswin_display_text_window (HWND hWnd)
46 {
47 PNHTextWindow data;
48
49 data = (PNHTextWindow)GetWindowLong(hWnd, GWL_USERDATA);
50 if( data && data->window_text ) {
51 HWND control;
52 control = GetDlgItem(hWnd, IDC_TEXT_CONTROL);
53 SendMessage(control, EM_FMTLINES, 1, 0 );
54 SetWindowText(GetDlgItem(hWnd, IDC_TEXT_CONTROL), data->window_text);
55 }
56
57 mswin_popup_display(hWnd, NULL);
58 mswin_popup_destroy(hWnd);
59 }
60
NHTextWndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)61 BOOL CALLBACK NHTextWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
62 {
63 HWND control;
64 HDC hdc;
65 PNHTextWindow data;
66 TCHAR title[MAX_LOADSTRING];
67
68 data = (PNHTextWindow)GetWindowLong(hWnd, GWL_USERDATA);
69 switch (message)
70 {
71 case WM_INITDIALOG:
72 /* set text control font */
73 control = GetDlgItem(hWnd, IDC_TEXT_CONTROL);
74 if( !control ) {
75 panic("cannot get text view window");
76 }
77
78 hdc = GetDC(control);
79 SendMessage(control, WM_SETFONT, (WPARAM)mswin_get_font(NHW_TEXT, ATR_NONE, hdc, FALSE), 0);
80 ReleaseDC(control, hdc);
81
82 /* subclass edit control */
83 editControlWndProc = (WNDPROC)GetWindowLong(control, GWL_WNDPROC);
84 SetWindowLong(control, GWL_WNDPROC, (LONG)NHEditHookWndProc);
85
86 SetFocus(control);
87
88 /* Even though the dialog has no caption, you can still set the title
89 which shows on Alt-Tab */
90 LoadString(GetNHApp()->hApp, IDS_APP_TITLE, title, MAX_LOADSTRING);
91 SetWindowText(hWnd, title);
92 return FALSE;
93
94 case WM_MSNH_COMMAND:
95 onMSNHCommand(hWnd, wParam, lParam);
96 break;
97
98 case WM_SIZE:
99 LayoutText(hWnd);
100 return FALSE;
101
102 case WM_COMMAND:
103 switch (LOWORD(wParam))
104 {
105 case IDOK:
106 case IDCANCEL:
107 mswin_window_mark_dead(mswin_winid_from_handle(hWnd));
108 if( GetNHApp()->hMainWnd==hWnd )
109 GetNHApp()->hMainWnd=NULL;
110 DestroyWindow(hWnd);
111 SetFocus(GetNHApp()->hMainWnd);
112 return TRUE;
113 case IDC_TEXT_CONTROL:
114 switch (HIWORD(wParam))
115 {
116 case EN_SETFOCUS:
117 HideCaret((HWND)lParam);
118 return TRUE;
119 }
120 }
121 break;
122
123 case WM_CTLCOLORSTATIC: { /* sent by edit control before it is drawn */
124 HDC hdcEdit = (HDC) wParam;
125 HWND hwndEdit = (HWND) lParam;
126 if( hwndEdit == GetDlgItem(hWnd, IDC_TEXT_CONTROL) ) {
127 SetBkColor(hdcEdit,
128 text_bg_brush ? text_bg_color : (COLORREF)GetSysColor(DEFAULT_COLOR_BG_TEXT)
129 );
130 SetTextColor(hdcEdit,
131 text_fg_brush ? text_fg_color : (COLORREF)GetSysColor(DEFAULT_COLOR_FG_TEXT)
132 );
133 return (BOOL)(text_bg_brush
134 ? text_bg_brush : SYSCLR_TO_BRUSH(DEFAULT_COLOR_BG_TEXT));
135 }
136 } return FALSE;
137
138 case WM_DESTROY:
139 if( data ) {
140 if( data->window_text ) free(data->window_text);
141 free(data);
142 SetWindowLong(hWnd, GWL_USERDATA, (LONG)0);
143 }
144 break;
145
146 }
147 return FALSE;
148 }
149
onMSNHCommand(HWND hWnd,WPARAM wParam,LPARAM lParam)150 void onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
151 {
152 PNHTextWindow data;
153
154 data = (PNHTextWindow)GetWindowLong(hWnd, GWL_USERDATA);
155 switch( wParam ) {
156 case MSNH_MSG_PUTSTR: {
157 PMSNHMsgPutstr msg_data = (PMSNHMsgPutstr)lParam;
158 TCHAR wbuf[BUFSZ];
159 size_t text_size;
160
161 if( !data->window_text ) {
162 text_size = strlen(msg_data->text) + 4;
163 data->window_text = (TCHAR*)malloc(text_size*sizeof(data->window_text[0]));
164 ZeroMemory(data->window_text, text_size*sizeof(data->window_text[0]));
165 } else {
166 text_size = _tcslen(data->window_text) + strlen(msg_data->text) + 4;
167 data->window_text = (TCHAR*)realloc(data->window_text, text_size*sizeof(data->window_text[0]));
168 }
169 if( !data->window_text ) break;
170
171 _tcscat(data->window_text, NH_A2W(msg_data->text, wbuf, BUFSZ));
172 _tcscat(data->window_text, TEXT("\r\n"));
173 break;
174 }
175 }
176 }
177
LayoutText(HWND hWnd)178 void LayoutText(HWND hWnd)
179 {
180 HWND btn_ok;
181 HWND text;
182 RECT clrt, rt;
183 POINT pt_elem, pt_ok;
184 SIZE sz_elem, sz_ok;
185
186 text = GetDlgItem(hWnd, IDC_TEXT_CONTROL);
187 btn_ok = GetDlgItem(hWnd, IDOK);
188
189 /* get window coordinates */
190 GetClientRect(hWnd, &clrt );
191
192 /* set window placements */
193 GetWindowRect(btn_ok, &rt);
194 sz_ok.cx = clrt.right - clrt.left;
195 sz_ok.cy = rt.bottom-rt.top;
196 pt_ok.x = clrt.left;
197 pt_ok.y = clrt.bottom - sz_ok.cy;
198
199 pt_elem.x = clrt.left;
200 pt_elem.y = clrt.top;
201 sz_elem.cx = clrt.right - clrt.left;
202 sz_elem.cy = pt_ok.y;
203
204 MoveWindow(text, pt_elem.x, pt_elem.y, sz_elem.cx, sz_elem.cy, TRUE );
205 MoveWindow(btn_ok, pt_ok.x, pt_ok.y, sz_ok.cx, sz_ok.cy, TRUE );
206 }
207
208 /* Edit box hook */
NHEditHookWndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)209 LRESULT CALLBACK NHEditHookWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
210 {
211 switch(message) {
212
213 case WM_KEYDOWN:
214 switch (wParam)
215 {
216 /* close on space in Windows mode
217 page down on space in NetHack mode */
218 case VK_SPACE:
219 {
220 SCROLLINFO si;
221
222 si.cbSize = sizeof(SCROLLINFO);
223 si.fMask = SIF_POS | SIF_RANGE | SIF_PAGE;
224 GetScrollInfo(hWnd, SB_VERT, &si);
225 /* If nethackmode and not at the end of the list */
226 if (GetNHApp()->regNetHackMode &&
227 (si.nPos + (int)si.nPage) <= (si.nMax - si.nMin))
228 SendMessage(hWnd, EM_SCROLL, SB_PAGEDOWN, 0);
229 else
230 PostMessage(GetParent(hWnd), WM_COMMAND, MAKELONG(IDOK, 0), 0);
231 return 0;
232 }
233 case VK_NEXT:
234 SendMessage(hWnd, EM_SCROLL, SB_PAGEDOWN, 0);
235 return 0;
236 case VK_PRIOR:
237 SendMessage(hWnd, EM_SCROLL, SB_PAGEUP, 0);
238 return 0;
239 case VK_UP:
240 SendMessage(hWnd, EM_SCROLL, SB_LINEUP, 0);
241 return 0;
242 case VK_DOWN:
243 SendMessage(hWnd, EM_SCROLL, SB_LINEDOWN, 0);
244 return 0;
245
246 }
247 break;
248 }
249
250 if( editControlWndProc )
251 return CallWindowProc(editControlWndProc, hWnd, message, wParam, lParam);
252 else
253 return 0;
254 }
255