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 "mhtext.h"
6 #include "mhmsg.h"
7 #include "mhfont.h"
8 #include "mhcolor.h"
9 #include "mhtxtbuf.h"
10 
11 typedef struct mswin_nethack_text_window {
12 	PNHTextBuffer  window_text;
13 	int done;
14 } NHTextWindow, *PNHTextWindow;
15 
16 static WNDPROC editControlWndProc = NULL;
17 
18 LRESULT CALLBACK	TextWndProc(HWND, UINT, WPARAM, LPARAM);
19 LRESULT CALLBACK	NHTextControlWndProc(HWND, UINT, WPARAM, LPARAM);
20 static void onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM lParam);
21 static void LayoutText(HWND hwnd);
22 
mswin_init_text_window()23 HWND mswin_init_text_window () {
24 	HWND ret;
25 	PNHTextWindow data;
26 
27 	ret = CreateDialog(
28 			GetNHApp()->hApp,
29 			MAKEINTRESOURCE(IDD_NHTEXT),
30 			GetNHApp()->hMainWnd,
31 			TextWndProc
32 	);
33 	if( !ret ) panic("Cannot create text window");
34 
35 	data = (PNHTextWindow)malloc(sizeof(NHTextWindow));
36 	if( !data ) panic("out of memory");
37 
38 	ZeroMemory(data, sizeof(NHTextWindow));
39 	data->window_text = mswin_init_text_buffer(
40 			program_state.gameover? FALSE : GetNHApp()->bWrapText
41 		);
42 	SetWindowLong(ret, GWL_USERDATA, (LONG)data);
43 	return ret;
44 }
45 
mswin_display_text_window(HWND hWnd)46 void mswin_display_text_window (HWND hWnd)
47 {
48 	PNHTextWindow data;
49 
50 	data = (PNHTextWindow)GetWindowLong(hWnd, GWL_USERDATA);
51 	if( data ) {
52 		HWND control;
53 		control = GetDlgItem(hWnd, IDC_TEXT_CONTROL);
54 		SendMessage(control, EM_FMTLINES, 1, 0 );
55 		mswin_render_text(data->window_text, GetDlgItem(hWnd, IDC_TEXT_CONTROL));
56 
57 		data->done = 0;
58 		mswin_popup_display(hWnd, &data->done);
59 		mswin_popup_destroy(hWnd);
60 	}
61 }
62 
TextWndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)63 LRESULT CALLBACK TextWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
64 {
65 	HWND control;
66 	HDC hdc;
67 	PNHTextWindow data;
68 
69 	data = (PNHTextWindow)GetWindowLong(hWnd, GWL_USERDATA);
70 	switch (message)
71 	{
72 	case WM_INITDIALOG:
73 	    /* set text control font */
74 		control = GetDlgItem(hWnd, IDC_TEXT_CONTROL);
75 		if( !control ) {
76 			panic("cannot get text view window");
77 		}
78 
79 		hdc = GetDC(control);
80 		SendMessage(control, WM_SETFONT, (WPARAM)mswin_get_font(NHW_TEXT, ATR_NONE, hdc, FALSE), 0);
81 		ReleaseDC(control, hdc);
82 
83 #if defined(WIN_CE_SMARTPHONE)
84 		/* special initialization for SmartPhone dialogs */
85 		NHSPhoneDialogSetup(hWnd, FALSE, GetNHApp()->bFullScreen);
86 #endif
87 		/* subclass edit control */
88 		editControlWndProc = (WNDPROC)GetWindowLong(control, GWL_WNDPROC);
89 		SetWindowLong(control, GWL_WNDPROC, (LONG)NHTextControlWndProc);
90 
91 		if( !program_state.gameover && GetNHApp()->bWrapText ) {
92 			DWORD styles;
93 			styles = GetWindowLong(control, GWL_STYLE);
94 			if( styles ) {
95 				SetWindowLong(control, GWL_STYLE, styles & (~WS_HSCROLL));
96 				SetWindowPos(control, NULL, 0, 0, 0, 0,
97 							  SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE );
98 			}
99 		}
100 
101 		SetFocus(control);
102 	return FALSE;
103 
104 	case WM_MSNH_COMMAND:
105 		onMSNHCommand(hWnd, wParam, lParam);
106 	break;
107 
108 	case WM_SIZE:
109 		LayoutText(hWnd);
110 	return FALSE;
111 
112 	case WM_COMMAND:
113 		switch (LOWORD(wParam))
114         {
115           case IDOK:
116 		  case IDCANCEL:
117 			data->done = 1;
118 			return TRUE;
119 		}
120 	break;
121 
122 	case WM_CTLCOLORBTN:
123 	case WM_CTLCOLOREDIT:
124 	case WM_CTLCOLORSTATIC: { /* sent by edit control before it is drawn */
125 		HDC hdcEdit = (HDC) wParam;
126 		HWND hwndEdit = (HWND) lParam;
127 		if( hwndEdit == GetDlgItem(hWnd, IDC_TEXT_CONTROL) ) {
128 			SetBkColor(hdcEdit, mswin_get_color(NHW_TEXT, MSWIN_COLOR_BG));
129 			SetTextColor(hdcEdit, mswin_get_color(NHW_TEXT, MSWIN_COLOR_FG));
130 			return (BOOL)mswin_get_brush(NHW_TEXT, MSWIN_COLOR_BG);
131 		}
132 	} return FALSE;
133 
134 	case WM_DESTROY:
135 		if( data ) {
136 			mswin_free_text_buffer(data->window_text);
137 			free(data);
138 			SetWindowLong(hWnd, GWL_USERDATA, (LONG)0);
139 		}
140 	break;
141 
142 	}
143 	return FALSE;
144 }
145 
onMSNHCommand(HWND hWnd,WPARAM wParam,LPARAM lParam)146 void onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
147 {
148 	PNHTextWindow data;
149 
150 	data = (PNHTextWindow)GetWindowLong(hWnd, GWL_USERDATA);
151 	switch( wParam ) {
152 	case MSNH_MSG_PUTSTR: {
153 		PMSNHMsgPutstr msg_data = (PMSNHMsgPutstr)lParam;
154 		mswin_add_text(data->window_text, msg_data->attr, msg_data->text);
155 		break;
156 	}
157 	}
158 }
159 
LayoutText(HWND hWnd)160 void LayoutText(HWND hWnd)
161 {
162 	HWND  btn_ok;
163 	HWND  text;
164 	RECT  clrt, rt;
165 	POINT pt_elem, pt_ok;
166 	SIZE  sz_elem, sz_ok;
167 
168 	text = GetDlgItem(hWnd, IDC_TEXT_CONTROL);
169 	btn_ok = GetDlgItem(hWnd, IDOK);
170 
171 	/* get window coordinates */
172 	GetClientRect(hWnd, &clrt );
173 
174 	/* set window placements */
175 	if( IsWindow(btn_ok) ) {
176 		GetWindowRect(btn_ok, &rt);
177 		sz_ok.cx = clrt.right - clrt.left;
178 		sz_ok.cy = rt.bottom-rt.top;
179 		pt_ok.x = clrt.left;
180 		pt_ok.y = clrt.bottom - sz_ok.cy;
181 		MoveWindow(btn_ok, pt_ok.x, pt_ok.y, sz_ok.cx, sz_ok.cy, TRUE );
182 
183 		pt_elem.x = clrt.left;
184 		pt_elem.y = clrt.top;
185 		sz_elem.cx = clrt.right - clrt.left;
186 		sz_elem.cy = pt_ok.y;
187 		MoveWindow(text, pt_elem.x, pt_elem.y, sz_elem.cx, sz_elem.cy, TRUE );
188 	} else {
189 		pt_elem.x = clrt.left;
190 		pt_elem.y = clrt.top;
191 		sz_elem.cx = clrt.right - clrt.left;
192 		sz_elem.cy = clrt.bottom - clrt.top;
193 		MoveWindow(text, pt_elem.x, pt_elem.y, sz_elem.cx, sz_elem.cy, TRUE );
194 	}
195 }
196 
197 /* Text control window proc - implements close on space and scrolling on arrows */
NHTextControlWndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)198 LRESULT CALLBACK NHTextControlWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
199 {
200 	switch(message) {
201 	case WM_KEYUP:
202 		switch( wParam ) {
203 		case VK_SPACE:
204 		case VK_RETURN:
205 			/* close on space */
206 			PostMessage(GetParent(hWnd), WM_COMMAND, MAKELONG(IDOK, 0), 0);
207 			return 0;
208 
209 		case VK_UP:
210 			/* scoll up */
211 			PostMessage(hWnd, WM_VSCROLL, MAKEWPARAM(SB_LINEUP, 0), (LPARAM)NULL);
212 			return 0;
213 
214 		case VK_DOWN:
215 			/* scoll down */
216 			PostMessage(hWnd, WM_VSCROLL, MAKEWPARAM(SB_LINEDOWN, 0), (LPARAM)NULL);
217 			return 0;
218 
219 		case VK_LEFT:
220 			/* scoll left */
221 			PostMessage(hWnd, WM_HSCROLL, MAKEWPARAM(SB_LINELEFT, 0), (LPARAM)NULL);
222 			return 0;
223 
224 		case VK_RIGHT:
225 			/* scoll right */
226 			PostMessage(hWnd, WM_HSCROLL, MAKEWPARAM(SB_LINERIGHT, 0), (LPARAM)NULL);
227 			return 0;
228 		}
229 		break; /* case WM_KEYUP: */
230 	}
231 
232 	if( editControlWndProc )
233 		return CallWindowProc(editControlWndProc, hWnd, message, wParam, lParam);
234 	else
235 		return 0;
236 }
237