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