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