1 /*	SCCS Id: @(#)win32msg.c	3.2	95/09/06	*/
2 /* Copyright (c) NetHack MS Windows Porting Team 1993, 1994       */
3 /* NetHack may be freely redistributed.  See license for details. */
4 
5 /*
6  * The routines in this file build on the initial MS Windows NetHack
7  * groundwork done by Bill Dyer.
8  *
9  * This file contains all of the Win32 Window Procedures.
10  */
11 
12 #include "hack.h"
13 
14 #ifdef WIN32_GRAPHICS
15 
16 # ifndef NO_SIGNAL
17 #include <signal.h>
18 # endif
19 #include <ctype.h>
20 #include <sys\stat.h>
21 #include "win32api.h"
22 #include "nhwin32.h"
23 
24 #ifdef DEBUG_FULL
25 static char debugbuf[256];
26 #endif
27 
BaseWndProc(HWND hWnd,UINT messg,UINT wParam,LONG lParam)28 LONG WINAPI BaseWndProc(HWND hWnd,UINT messg,UINT wParam,LONG lParam)
29 {
30 	HDC hdc;
31 	static int xClientView,yClientView;
32 	static HWND hInst;
33 	static FARPROC fpfnAboutDiaProc;
34 	static RECT rcWindow;
35 	RECT rect;
36 	unsigned char ch;
37 
38 	switch (messg)
39 	{
40 	   case WM_CREATE:
41 	     hdc = GetDC(hWnd);
42 	     SelectObject(hdc,hDefFnt);
43 	     GetTextMetrics(hdc, &tm);
44 	     ReleaseDC(hWnd,hdc);
45 
46 	     DefCharWidth = tm.tmAveCharWidth;
47 	     DefCharHeight = tm.tmHeight;
48 	     BaseUnits = DefCharHeight;
49 
50 	     GetClientRect(hWnd, &rect);
51 	     rect.top += GetSystemMetrics(SM_CYMENU) +
52 			 (GetSystemMetrics(SM_CYFRAME) * 2) +
53 			 GetSystemMetrics(SM_CYSIZE);
54 	     rect.left += GetSystemMetrics(SM_CXFRAME) * 2;
55 	     rect.right = rect.left + (COLNO * DefCharWidth);
56    	     rect.bottom = rect.top + ((5 + ROWNO + 2) * BaseUnits);
57 	     (void) AdjustWindowRect(&rect,WS_OVERLAPPEDWINDOW, TRUE);
58 	     BaseWidth = rect.right - rect.left + 1;
59 	     BaseHeight = rect.bottom - rect.top + 1;
60 	     MoveWindow(hWnd, rect.left, rect.top, BaseWidth, BaseHeight, TRUE);
61 	     GetClientRect(hWnd, &rcClient);
62 
63 	     MessageHeight  = BaseUnits * 5;
64 	     MessageWidth   = BaseWidth - GetSystemMetrics(SM_CXVSCROLL);
65 	     MessageX = rcClient.left;
66 	     MessageY = rcClient.top;
67 	     MapHeight = BaseUnits * ROWNO;
68 	     MapWidth  = BaseWidth;
69 	     MapX = rcClient.left;
70 	     MapY = rcClient.top + MessageHeight;
71 	     StatusHeight = BaseUnits * 2;
72 	     StatusWidth  = BaseWidth;
73 	     StatusX = rcClient.left;
74 	     StatusY = rcClient.top + MessageHeight + MapHeight;
75 	     break;
76 	  case WM_SIZE:
77 	     GetClientRect(hWnd, &rcClient);
78 	     EnumChildWindows(hWnd, EnumChildProc,(LPARAM)&rcClient);
79 	     return 0;
80 	     break;
81 
82 	  case WM_CHAR:
83 	    switch(wParam) {
84 		default:
85 			ch = (unsigned char) wParam;
86 			if (pchPut >= pchBuf + (RINGBUFSIZE - 1)) {
87 				pchPut = pchBuf;		/* wrap it */
88 			}
89 			*pchPut++ = ch;
90 			++pchCount;
91 	    }
92 #ifdef DEBUG_FULL
93 	    sprintf(debugbuf,"Message = %X, wParam = %d, pchCount = %d",
94 				messg, wParam, pchCount);
95 	    DEBUG_MSG(debugbuf);
96 #endif
97 	    break;
98 	  case WM_DESTROY:
99 	    PostQuitMessage(0);
100 	    exit(EXIT_SUCCESS);
101 	    break;
102 
103 	  default:
104 	    return(DefWindowProc(hWnd,messg,wParam,lParam));
105 	}
106 	return(0L);
107 }
108 
TextWndProc(HWND hWnd,UINT messg,UINT wParam,LONG lParam)109 LONG WINAPI TextWndProc(HWND hWnd,UINT messg,UINT wParam,LONG lParam)
110 {
111 	int idChild;
112 	HDC hdc;
113 #if 0
114 	char buf[BUFSZ];
115 #endif
116 	PAINTSTRUCT ps;
117 
118 	static int xClientView,yClientView;
119 	static HWND hInst;
120 	static FARPROC fpfnAboutDiaProc;
121 	int row,col;
122 	int srow, scol;
123 	int colcount, rowcount;
124 	int offset;
125 	uchar ch;
126 	uchar *pch;
127 	int color;
128 	int *pcolor;
129 	/* RECT rect; */
130 	char tch[2]="X";
131 
132 	idChild = GetWindowLong(hWnd, GWL_ID);
133 	switch (messg)
134 	{
135 
136           case WM_CREATE:
137 	    wins[idChild]->dwCharX = DefCharWidth;
138 	    wins[idChild]->dwCharY = DefCharHeight;
139 	    return 0;
140 #if 0
141 	  case WM_SIZE:
142 	    break;
143 #endif
144 	  case WM_PAINT:
145 	    HideCaret(hWnd);
146 	    hdc=BeginPaint(hWnd,&ps);
147 	    SelectObject(hdc,wins[idChild]->hFnt);
148 
149 	    scol = ps.rcPaint.left / DefCharWidth;
150 	    srow = ps.rcPaint.top  / DefCharHeight;
151 	    rowcount = ((ps.rcPaint.bottom / DefCharHeight) - srow) + 1;
152 	    colcount = ((ps.rcPaint.right / DefCharWidth) - scol) + 1;
153 	    switch(wins[idChild]->type) {
154 	 	case NHW_MESSAGE:
155 		    col = ps.rcPaint.left / wins[NHW_MESSAGE]->dwCharX;
156 		    offset = (srow * wins[NHW_MESSAGE]->maxcols) + col;
157 		    SelectObject(hdc,wins[NHW_MESSAGE]->hFnt);
158 		    SetBkColor(hdc,wins[NHW_MESSAGE]->BackGroundColor);
159 		    for (row = srow; row <= srow + rowcount; ++row) {
160 		    	offset = (row * wins[NHW_MESSAGE]->maxcols + col);
161 		    	pcolor = wins[NHW_MESSAGE]->color + offset;
162 		    	pch = wins[NHW_MESSAGE]->data + offset;
163 		    	color = *pcolor;
164 		    	SetTextColor(hdc,color);
165 		    	TextOut(hdc,
166 				 ps.rcPaint.left,
167 				 (row * wins[NHW_MESSAGE]->dwCharY),
168 				 pch, colcount);
169 		    }
170 		    break;
171 		case NHW_TEXT:
172 		    SelectObject(hdc,wins[idChild]->hFnt);
173 		    SetBkColor(hdc,wins[idChild]->BackGroundColor);
174 		    colcount = wins[idChild]->widest;
175 		    for (row = srow; row <= srow + rowcount; ++row) {
176 			for (col = scol; col <= scol + colcount; ++col) {
177 		    		offset = (row * wins[idChild]->maxcols) + col;
178 		    		pch = wins[idChild]->data + offset;
179 		    		pcolor = wins[idChild]->color + offset;
180 		    		ch = *pch;
181 		    		color = *pcolor;
182 		    		SetTextColor(hdc,color);
183 		    		TextOut(hdc,
184 	       			(col * wins[idChild]->dwCharX),
185 	       			(row * wins[idChild]->dwCharY),
186 				 &ch, 1);
187 			}
188 		     }
189 		     break;
190 		default:
191 		    SelectObject(hdc,wins[idChild]->hFnt);
192 		    SetBkColor(hdc,wins[idChild]->BackGroundColor);
193 		    colcount = wins[idChild]->maxcols;
194 		    for (row = srow; row <= srow + rowcount; ++row) {
195 			for (col = scol; col <= scol + colcount; ++col) {
196 		    		offset = (row * wins[idChild]->maxcols) + col;
197 		    		pch = wins[idChild]->data + offset;
198 		    		pcolor = wins[idChild]->color + offset;
199 		    		ch = *pch;
200 		    		color = *pcolor;
201 		    		SetTextColor(hdc,color);
202 		    		TextOut(hdc,
203 	       			(col * wins[idChild]->dwCharX),
204 	       			(row * wins[idChild]->dwCharY),
205 				 &ch, 1);
206 			}
207 		     }
208 	    }
209 	    EndPaint(hWnd,&ps);
210 	    ShowCaret(hWnd);
211 	    break;
212 
213 	  case WM_SETFOCUS:
214 	    if (idChild == WIN_MAP) {
215 	    	CreateCaret(hWnd,(HBITMAP)1,0,0);
216 		SetCaretPos(wins[idChild]->nCaretPosX,
217 			    wins[idChild]->nCaretPosY * wins[idChild]->dwCharY);
218 		ShowCaret(hWnd);
219 	    } else {
220 		SetFocus(wins[WIN_MAP]->hWnd);
221 	    }
222 	    break;
223 
224 	  case WM_KILLFOCUS:
225 	    if (idChild == WIN_MAP) {
226 	    	HideCaret(hWnd);
227 		DestroyCaret();
228 	    }
229 	    break;
230 
231 	  case WM_CHAR:
232 	    switch(wParam) {
233 		default:
234 			ch = (unsigned char) wParam;
235 			if (pchPut >= pchBuf + (RINGBUFSIZE - 1)) {
236 				pchPut = pchBuf;		/* wrap it */
237 			}
238 			*pchPut++ = ch;
239 			++pchCount;
240 	    }
241 #ifdef DEBUG_FULL
242 	    sprintf(debugbuf,"Message = %X, wParam = %d, pchCount = %d",
243 				messg, wParam, pchCount);
244 	    DEBUG_MSG(debugbuf);
245 #endif
246 	    break;
247 
248 	  case WM_DESTROY:
249 	    PostQuitMessage(0);
250 	    break;
251 
252 	  case WM_VSCROLL:
253 	    switch(wParam) {
254 		case SB_LINEUP:
255 			break;
256 	    }
257 	    break;
258 	  case WM_HSCROLL:
259 	  default:
260 	    return(DefWindowProc(hWnd,messg,wParam,lParam));
261 	}
262 	return(0L);
263 }
264 
PopupWndProc(HWND hWnd,UINT messg,UINT wParam,LONG lParam)265 LONG WINAPI PopupWndProc(HWND hWnd,UINT messg,UINT wParam,LONG lParam)
266 {
267 	int idPopup;
268 	HDC hdc;
269 	PAINTSTRUCT ps;
270 	static int xClientView,yClientView;
271 	static HWND hInst;
272 	static FARPROC fpfnAboutDiaProc;
273 
274 	idPopup = GetWindowLong(hWnd, GWL_ID);
275 	switch (messg)
276 	{
277 
278           case WM_CREATE:
279 	    hdc =GetDC(hWnd);
280 	    GetTextMetrics(hdc, &tm);
281 	    ReleaseDC(hWnd,hdc);
282 	    wins[idPopup]->dwCharX = tm.tmAveCharWidth;
283 	    wins[idPopup]->dwCharY = tm.tmHeight;
284 	    return 0;
285 
286 	  case WM_PAINT:
287 	    hdc=BeginPaint(hWnd,&ps);
288 
289 	    ValidateRect(hWnd,0);
290 	    EndPaint(hWnd,&ps);
291 	    break;
292 
293 	  case WM_DESTROY:
294 	    PostQuitMessage(0);
295 	    break;
296 
297 	  case WM_VSCROLL:
298 	  case WM_HSCROLL:
299 	  default:
300 	    return(DefWindowProc(hWnd,messg,wParam,lParam));
301 	}
302 	return(0L);
303 }
304 
ListboxWndProc(HWND hWnd,UINT messg,UINT wParam,LONG lParam)305 LONG WINAPI ListboxWndProc(HWND hWnd,UINT messg,UINT wParam,LONG lParam)
306 {
307 	int idListbox;
308 	HDC hdc;
309 	static int xClientView,yClientView;
310 	static HWND hInst;
311 
312 	idListbox = GetWindowLong(hWnd, GWL_ID);
313 	switch (messg)
314 	{
315 
316           case WM_CREATE:
317 	    hdc =GetDC(hWnd);
318 	    GetTextMetrics(hdc, &tm);
319 	    ReleaseDC(hWnd,hdc);
320 	    return 0;
321 
322 	  case WM_SETFOCUS:
323 #if 0
324 	    CreateCaret(hWnd,(HBITMAP)1,0,0);
325 	    SetCaretPos(wins[idListbox]->nCaretPosX,
326 		wins[idListbox]->nCaretPosY * wins[idListbox]->dwCharY);
327 	    ShowCaret(hWnd);
328 	    break;
329 #endif
330 #if 0
331 	  case WM_KILLFOCUS:
332 	    HideCaret(hWnd);
333 	    DestroyCaret();
334 	    break;
335 #endif
336 
337 	  case WM_DESTROY:
338 	    PostQuitMessage(0);
339 	    break;
340 
341 	  case WM_COMMAND:
342 	    switch (HIWORD(wParam)) {
343 	     case LBN_DBLCLK:
344 		DEBUG_MSG("Got LBN_DBLCLK");
345 	        return(DefWindowProc(hWnd,messg,wParam,lParam));
346 		break;
347 	     case LBN_KILLFOCUS:
348 		DEBUG_MSG("Got LBN_KILLFOCUS");
349 	        return(DefWindowProc(hWnd,messg,wParam,lParam));
350 		break;
351 	     case LBN_SELCANCEL:
352 		DEBUG_MSG("Got LBN_SELCANCEL");
353 	        return(DefWindowProc(hWnd,messg,wParam,lParam));
354 		break;
355 	     case LBN_SELCHANGE:
356 		DEBUG_MSG("Got LBN_SELCHANGE");
357 	        return(DefWindowProc(hWnd,messg,wParam,lParam));
358 		break;
359 	     case LBN_SETFOCUS:
360 		DEBUG_MSG("Got LBN_SETFOCUS");
361 	        return(DefWindowProc(hWnd,messg,wParam,lParam));
362 		break;
363 	     case WM_VKEYTOITEM:
364 		DEBUG_MSG("Got LBN_VKEYTOITEM");
365 	        return(DefWindowProc(hWnd,messg,wParam,lParam));
366 		break;
367 	     default:
368 	        return(DefWindowProc(hWnd,messg,wParam,lParam));
369 	    }
370 	    break;
371 	  case WM_VSCROLL:
372 	  case WM_HSCROLL:
373 	  default:
374 	    return(DefWindowProc(hWnd,messg,wParam,lParam));
375 	}
376 	return(0L);
377 }
378 
MenuDialogProc(HWND hdlg,UINT messg,UINT wParam,LONG lParam)379 LRESULT CALLBACK MenuDialogProc(HWND hdlg,UINT messg,UINT wParam,LONG lParam)
380 {
381 	switch(messg) {
382 		case WM_INITDIALOG:
383 			break;
384 		case WM_COMMAND:
385 			switch(LOWORD(wParam)) {
386 				case IDOK:
387 					EndDialog(hdlg,0);
388 					break;
389 				default:
390 					return FALSE;
391 			}
392 			break;
393 		default:
394 			return FALSE;
395 		}
396 	return TRUE;
397 }
398 
AskNameProc(HWND hDlg,UINT messg,UINT wParam,LONG lParam)399 BOOL WINAPI AskNameProc(HWND hDlg, UINT messg, UINT wParam, LONG lParam)
400 {
401 	char buf[BUFSZ];
402 	HWND hEditBox;
403 	WPARAM maxsize;
404 
405 	switch(messg) {
406 	    case WM_INITDIALOG:
407 		SendMessage(hDlg, DM_SETDEFID, (WPARAM)IDD_NAME, (LPARAM)0);
408 
409 		maxsize = (WPARAM)((sizeof plname) - 1);
410 		hEditBox = GetDlgItem(hDlg, IDD_NAME);
411 		SendMessage(hEditBox, EM_LIMITTEXT, maxsize, (LPARAM)0);
412 		return TRUE;
413 	    case WM_COMMAND:
414 		switch(LOWORD(wParam)) {
415 		    case IDOK:
416 			/* Get number of characters */
417 			input_text_size = (int)SendDlgItemMessage(
418 					hDlg,
419 					IDD_NAME,
420 					EM_LINELENGTH,
421 					(WPARAM)0,
422 					(LPARAM)0);
423 			Sprintf(buf, "input_text_size = %d", input_text_size);
424 			/* Get the characters */
425 			if (input_text_size != 0) {
426 				*((LPWORD)input_text) = input_text_size;
427 				SendDlgItemMessage(hDlg,
428 					IDD_NAME,
429 					EM_GETLINE,
430 					(WPARAM)0,
431 					(LPARAM)(LPCSTR)input_text);
432 			}
433 			EndDialog(hDlg, TRUE);
434 			return TRUE;
435 		    case IDCANCEL:
436 			EndDialog(hDlg, 0);
437 			return TRUE;
438 		}
439 		return 0;
440 	}
441 	return FALSE;
442 }
443 static int nCurrentChar;
444 
PlayerSelectProc(HWND hDlg,UINT messg,UINT wParam,LONG lParam)445 BOOL WINAPI PlayerSelectProc(HWND hDlg, UINT messg, UINT wParam, LONG lParam)
446 {
447 	int i;
448 
449 	switch (messg) {
450 		case WM_INITDIALOG:
451 			CheckRadioButton(hDlg,IDD_ARCH,IDD_RAND,IDD_RAND);
452 			nCurrentChar = IDD_RAND;
453 			return TRUE;
454 		case WM_COMMAND:
455 			switch (wParam) {
456 			   case IDOK:
457 				if (nCurrentChar == IDD_RAND) {
458 					i = rn2((int)strlen(pl_classes));
459 					pl_character[0] = pl_classes[i];
460 				} else	{
461 					pl_character[0] =
462 					   pl_classes[nCurrentChar-IDD_ARCH];
463 				}
464 				EndDialog(hDlg,TRUE);
465 				return TRUE;
466 				break;
467 			   case IDCANCEL:
468 				pl_character[0] = 0;
469 				EndDialog(hDlg,FALSE);
470 				return TRUE;
471 				break;
472 			   case IDD_ARCH:
473 			   case IDD_BARB:
474 			   case IDD_CAVEMAN:
475 			   case IDD_ELF:
476 			   case IDD_HEAL:
477 			   case IDD_KNIGHT:
478 			   case IDD_PRIEST:
479 			   case IDD_ROGUE:
480 			   case IDD_SAM:
481 			   case IDD_TOUR:
482 			   case IDD_VAL:
483 			   case IDD_WIZ:
484 			   case IDD_RAND:
485 				nCurrentChar = wParam;
486 				CheckRadioButton(hDlg,IDD_ARCH,
487 						 IDD_RAND,wParam);
488 				return TRUE;
489 				break;
490 		}
491 	}
492 	return FALSE;
493 }
494 
CopyrightProc(HWND hDlg,UINT messg,UINT wParam,LONG lParam)495 BOOL WINAPI CopyrightProc(HWND hDlg, UINT messg, UINT wParam, LONG lParam)
496 {
497 	switch (messg)
498 	{
499 		case WM_COMMAND:
500 			switch (wParam)
501 			{
502 			   case IDOK:
503 				EndDialog(hDlg,TRUE);
504 				return TRUE;
505 				break;
506 			}
507 			break;
508 
509 		default:
510 			return FALSE;
511 	}
512 	return FALSE;
513 }
514 
EnumChildProc(hwndChild,lParam)515 BOOL CALLBACK EnumChildProc(hwndChild, lParam)
516 HWND hwndChild;
517 LPARAM lParam;
518 {
519 	LPRECT rcParent;
520 	int idChild;
521 
522 	idChild = GetWindowLong(hwndChild, GWL_ID);
523 	rcParent = (LPRECT) lParam;
524 
525 	switch(idChild) {
526 	   case NHW_MESSAGE:
527 			MoveWindow(hwndChild,
528 				   MessageX, MessageY,
529 				   MessageWidth, MessageHeight, TRUE);
530 			wins[NHW_MESSAGE]->WindowWidth = MessageWidth;
531 			wins[NHW_MESSAGE]->WindowHeight = MessageHeight;
532 			wins[NHW_MESSAGE]->nWindowX = MessageX;
533 			wins[NHW_MESSAGE]->nWindowY = MessageY;
534 			break;
535 
536 	   case NHW_MAP:
537 			MoveWindow(hwndChild,
538 				   MapX, MapY,
539 				   MapWidth, MapHeight, TRUE);
540 			wins[NHW_MAP]->WindowWidth = MapWidth;
541 			wins[NHW_MAP]->WindowHeight = MapHeight;
542 			wins[NHW_MAP]->nWindowX = MapX;
543 			wins[NHW_MAP]->nWindowY = MapY;
544 			break;
545 
546 	   case NHW_STATUS:
547 			MoveWindow(hwndChild,
548 				   0, StatusY,
549 				   StatusWidth, StatusHeight, TRUE);
550 			wins[NHW_STATUS]->WindowWidth = StatusWidth;
551 			wins[NHW_STATUS]->WindowHeight = StatusHeight;
552 			wins[NHW_STATUS]->nWindowX = 0;
553 			wins[NHW_STATUS]->nWindowY = StatusY;
554 			break;
555 	}
556 	ShowWindow(hwndChild, SW_SHOW);
557 	return TRUE;
558 }
559 
AboutDiaProc(HWND hdlg,UINT messg,UINT wParam,LONG lParam)560 BOOL WINAPI AboutDiaProc(HWND hdlg,UINT messg,UINT wParam,LONG lParam)
561 {
562 	switch(messg) {
563 		case WM_INITDIALOG:
564 			break;
565 		case WM_COMMAND:
566 			switch(LOWORD(wParam)) {
567 				case IDOK:
568 					EndDialog(hdlg,0);
569 					break;
570 				default:
571 					return FALSE;
572 			}
573 			break;
574 		default:
575 			return FALSE;
576 		}
577 	return TRUE;
578 }
579 
580 
581 #endif /* WIN32_GRAPHICS */
582 
583 /* win32msg.c */
584