NHDT->ANH, nethack->anethack, nhdat->anhdat
[aNetHack.git] / win / win32 / mhdlg.c
blob5b81fe4bffca69a6097c1fb7c24df98c59b23126
1 /* aNetHack 0.0.1 mhdlg.c $ANH-Date: 1432512812 2015/05/25 00:13:32 $ $ANH-Branch: master $:$ANH-Revision: 1.25 $ */
2 /* Copyright (C) 2001 by Alex Kompel */
3 /* aNetHack may be freely redistributed. See license for details. */
5 /* various dialog boxes are defined here */
7 #include "winMS.h"
8 #include "hack.h"
9 #include "func_tab.h"
10 #include "resource.h"
11 #include "mhdlg.h"
13 /*---------------------------------------------------------------*/
14 /* data for getlin dialog */
15 struct getlin_data {
16 const char *question;
17 char *result;
18 size_t result_size;
21 INT_PTR CALLBACK GetlinDlgProc(HWND, UINT, WPARAM, LPARAM);
23 int
24 mswin_getlin_window(const char *question, char *result, size_t result_size)
26 INT_PTR ret;
27 struct getlin_data data;
29 /* initilize dialog data */
30 ZeroMemory(&data, sizeof(data));
31 data.question = question;
32 data.result = result;
33 data.result_size = result_size;
35 /* create modal dialog window */
36 ret = DialogBoxParam(GetNHApp()->hApp, MAKEINTRESOURCE(IDD_GETLIN),
37 GetNHApp()->hMainWnd, GetlinDlgProc, (LPARAM) &data);
38 if (ret == -1)
39 panic("Cannot create getlin window");
41 return (int) ret;
44 INT_PTR CALLBACK
45 GetlinDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
47 struct getlin_data *data;
48 RECT main_rt, dlg_rt;
49 SIZE dlg_sz;
50 TCHAR wbuf[BUFSZ];
51 HDC WindowDC;
52 HWND ControlHWND;
53 SIZE WindowExtents;
54 SIZE ViewPortExtents;
55 RECT ControlRect;
56 RECT ClientRect;
57 LONG Division;
58 LONG ButtonOffset;
60 switch (message) {
61 case WM_INITDIALOG:
62 data = (struct getlin_data *) lParam;
63 SetWindowText(hWnd, NH_A2W(data->question, wbuf, sizeof(wbuf)));
64 SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR) data);
66 /* center dialog in the main window */
67 GetWindowRect(hWnd, &dlg_rt);
68 GetWindowRect(GetNHApp()->hMainWnd, &main_rt);
69 WindowDC = GetWindowDC(hWnd);
71 if (!GetWindowExtEx(WindowDC, &WindowExtents)
72 || !GetViewportExtEx(WindowDC, &ViewPortExtents)
73 || !GetTextExtentPoint32(GetWindowDC(hWnd), wbuf, _tcslen(wbuf),
74 &dlg_sz)) {
75 dlg_sz.cx = 0;
76 } else {
77 /* I think we need to do the following scaling */
78 dlg_sz.cx *= ViewPortExtents.cx;
79 dlg_sz.cx /= WindowExtents.cx;
80 /* Add the size of the various items in the caption bar */
81 dlg_sz.cx += GetSystemMetrics(SM_CXSIZE)
82 + 2 * (GetSystemMetrics(SM_CXBORDER)
83 + GetSystemMetrics(SM_CXFRAME));
86 if (dlg_sz.cx < dlg_rt.right - dlg_rt.left)
87 dlg_sz.cx = dlg_rt.right - dlg_rt.left;
88 dlg_sz.cy = dlg_rt.bottom - dlg_rt.top;
89 dlg_rt.left = (main_rt.left + main_rt.right - dlg_sz.cx) / 2;
90 dlg_rt.right = dlg_rt.left + dlg_sz.cx;
91 dlg_rt.top = (main_rt.top + main_rt.bottom - dlg_sz.cy) / 2;
92 dlg_rt.bottom = dlg_rt.top + dlg_sz.cy;
93 MoveWindow(hWnd, (main_rt.left + main_rt.right - dlg_sz.cx) / 2,
94 (main_rt.top + main_rt.bottom - dlg_sz.cy) / 2, dlg_sz.cx,
95 dlg_sz.cy, TRUE);
97 /* set focus and size of the edit control */
98 ControlHWND = GetDlgItem(hWnd, IDC_GETLIN_EDIT);
99 SetFocus(ControlHWND);
100 GetClientRect(hWnd, &ClientRect);
101 GetWindowRect(ControlHWND, &ControlRect);
102 MoveWindow(ControlHWND, 0, 0, ClientRect.right - ClientRect.left,
103 ControlRect.bottom - ControlRect.top, TRUE);
104 ButtonOffset = ControlRect.bottom - ControlRect.top;
106 /* Now get the OK and CANCEL buttons */
107 ControlHWND = GetDlgItem(hWnd, IDOK);
108 GetWindowRect(ControlHWND, &ControlRect);
109 Division = ((ClientRect.right - ClientRect.left)
110 - 2 * (ControlRect.right - ControlRect.left)) / 3;
111 MoveWindow(ControlHWND, Division, ButtonOffset,
112 ControlRect.right - ControlRect.left,
113 ControlRect.bottom - ControlRect.top, TRUE);
114 ControlHWND = GetDlgItem(hWnd, IDCANCEL);
115 MoveWindow(ControlHWND,
116 Division * 2 + ControlRect.right - ControlRect.left,
117 ButtonOffset, ControlRect.right - ControlRect.left,
118 ControlRect.bottom - ControlRect.top, TRUE);
120 /* tell windows that we've set the focus */
121 return FALSE;
122 break;
124 case WM_COMMAND: {
125 TCHAR wbuf[BUFSZ];
127 switch (LOWORD(wParam)) {
128 /* OK button was pressed */
129 case IDOK:
130 data =
131 (struct getlin_data *) GetWindowLongPtr(hWnd, GWLP_USERDATA);
132 SendDlgItemMessage(hWnd, IDC_GETLIN_EDIT, WM_GETTEXT,
133 (WPARAM) sizeof(wbuf), (LPARAM) wbuf);
134 NH_W2A(wbuf, data->result, data->result_size);
136 /* Fall through. */
138 /* cancel button was pressed */
139 case IDCANCEL:
140 EndDialog(hWnd, wParam);
141 return TRUE;
143 } break;
145 } /* end switch (message) */
146 return FALSE;
149 /*---------------------------------------------------------------*/
150 /* dialog data for the list of extended commands */
151 struct extcmd_data {
152 int *selection;
155 INT_PTR CALLBACK ExtCmdDlgProc(HWND, UINT, WPARAM, LPARAM);
158 mswin_ext_cmd_window(int *selection)
160 INT_PTR ret;
161 struct extcmd_data data;
163 /* init dialog data */
164 ZeroMemory(&data, sizeof(data));
165 *selection = -1;
166 data.selection = selection;
168 /* create modal dialog window */
169 ret = DialogBoxParam(GetNHApp()->hApp, MAKEINTRESOURCE(IDD_EXTCMD),
170 GetNHApp()->hMainWnd, ExtCmdDlgProc, (LPARAM) &data);
171 if (ret == -1)
172 panic("Cannot create extcmd window");
173 return (int) ret;
176 INT_PTR CALLBACK
177 ExtCmdDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
179 struct extcmd_data *data;
180 RECT main_rt, dlg_rt;
181 SIZE dlg_sz;
182 int i;
183 TCHAR wbuf[255];
185 switch (message) {
186 case WM_INITDIALOG:
187 data = (struct extcmd_data *) lParam;
188 SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR) data);
190 /* center dialog in the main window */
191 GetWindowRect(GetNHApp()->hMainWnd, &main_rt);
192 GetWindowRect(hWnd, &dlg_rt);
193 dlg_sz.cx = dlg_rt.right - dlg_rt.left;
194 dlg_sz.cy = dlg_rt.bottom - dlg_rt.top;
196 dlg_rt.left = (main_rt.left + main_rt.right - dlg_sz.cx) / 2;
197 dlg_rt.right = dlg_rt.left + dlg_sz.cx;
198 dlg_rt.top = (main_rt.top + main_rt.bottom - dlg_sz.cy) / 2;
199 dlg_rt.bottom = dlg_rt.top + dlg_sz.cy;
200 MoveWindow(hWnd, (main_rt.left + main_rt.right - dlg_sz.cx) / 2,
201 (main_rt.top + main_rt.bottom - dlg_sz.cy) / 2, dlg_sz.cx,
202 dlg_sz.cy, TRUE);
204 /* fill combobox with extended commands */
205 for (i = 0; extcmdlist[i].ef_txt; i++) {
206 SendDlgItemMessage(
207 hWnd, IDC_EXTCMD_LIST, LB_ADDSTRING, (WPARAM) 0,
208 (LPARAM) NH_A2W(extcmdlist[i].ef_txt, wbuf, sizeof(wbuf)));
211 /* set focus to the list control */
212 SetFocus(GetDlgItem(hWnd, IDC_EXTCMD_LIST));
214 /* tell windows we set the focus */
215 return FALSE;
216 break;
218 case WM_COMMAND:
219 data = (struct extcmd_data *) GetWindowLongPtr(hWnd, GWLP_USERDATA);
220 switch (LOWORD(wParam)) {
221 /* OK button ws clicked */
222 case IDOK:
223 *data->selection = (int) SendDlgItemMessage(
224 hWnd, IDC_EXTCMD_LIST, LB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);
225 if (*data->selection == LB_ERR)
226 *data->selection = -1;
227 /* Fall through. */
229 /* CANCEL button ws clicked */
230 case IDCANCEL:
231 EndDialog(hWnd, wParam);
232 return TRUE;
234 /* list control events */
235 case IDC_EXTCMD_LIST:
236 switch (HIWORD(wParam)) {
237 case LBN_DBLCLK:
238 /* double click within the list
239 wParam
240 The low-order word is the list box identifier.
241 The high-order word is the notification message.
242 lParam
243 Handle to the list box
245 *data->selection = (int) SendMessage(
246 (HWND) lParam, LB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);
247 if (*data->selection == LB_ERR)
248 *data->selection = -1;
249 EndDialog(hWnd, IDOK);
250 return TRUE;
252 break;
255 return FALSE;
258 /*---------------------------------------------------------------*/
259 /* player selector dialog data */
260 struct plsel_data {
261 int *selection;
264 INT_PTR CALLBACK PlayerSelectorDlgProc(HWND, UINT, WPARAM, LPARAM);
265 static void plselInitDialog(HWND hWnd);
266 static void plselAdjustLists(HWND hWnd, int changed_opt);
267 static int plselFinalSelection(HWND hWnd, int *selection);
270 mswin_player_selection_window(int *selection)
272 INT_PTR ret;
273 struct plsel_data data;
275 /* init dialog data */
276 ZeroMemory(&data, sizeof(data));
277 data.selection = selection;
279 /* create modal dialog */
280 ret = DialogBoxParam(
281 GetNHApp()->hApp, MAKEINTRESOURCE(IDD_PLAYER_SELECTOR),
282 GetNHApp()->hMainWnd, PlayerSelectorDlgProc, (LPARAM) &data);
283 if (ret == -1)
284 panic("Cannot create getlin window");
286 return (int) ret;
289 INT_PTR CALLBACK
290 PlayerSelectorDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
292 struct plsel_data *data;
293 RECT main_rt, dlg_rt;
294 SIZE dlg_sz;
296 switch (message) {
297 case WM_INITDIALOG:
298 data = (struct plsel_data *) lParam;
299 SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR) data);
301 /* center dialog in the main window */
302 GetWindowRect(GetNHApp()->hMainWnd, &main_rt);
303 GetWindowRect(hWnd, &dlg_rt);
304 dlg_sz.cx = dlg_rt.right - dlg_rt.left;
305 dlg_sz.cy = dlg_rt.bottom - dlg_rt.top;
307 dlg_rt.left = (main_rt.left + main_rt.right - dlg_sz.cx) / 2;
308 dlg_rt.right = dlg_rt.left + dlg_sz.cx;
309 dlg_rt.top = (main_rt.top + main_rt.bottom - dlg_sz.cy) / 2;
310 dlg_rt.bottom = dlg_rt.top + dlg_sz.cy;
311 MoveWindow(hWnd, (main_rt.left + main_rt.right - dlg_sz.cx) / 2,
312 (main_rt.top + main_rt.bottom - dlg_sz.cy) / 2, dlg_sz.cx,
313 dlg_sz.cy, TRUE);
315 /* init dialog */
316 plselInitDialog(hWnd);
318 /* set focus on the role checkbox (random) field */
319 SetFocus(GetDlgItem(hWnd, IDC_PLSEL_ROLE_RANDOM));
321 /* tell windows we set the focus */
322 return FALSE;
323 break;
325 case WM_COMMAND:
326 data = (struct plsel_data *) GetWindowLongPtr(hWnd, GWLP_USERDATA);
327 switch (LOWORD(wParam)) {
328 /* OK button was clicked */
329 case IDOK:
330 if (plselFinalSelection(hWnd, data->selection)) {
331 EndDialog(hWnd, wParam);
332 } else {
333 NHMessageBox(
334 hWnd, TEXT("Cannot match this role. Try something else."),
335 MB_ICONSTOP | MB_OK);
337 return TRUE;
339 /* CANCEL button was clicked */
340 case IDCANCEL:
341 *data->selection = -1;
342 EndDialog(hWnd, wParam);
343 return TRUE;
345 /* following are events from dialog controls:
346 "random" checkboxes send BN_CLICKED messages;
347 role/race/... combo-boxes send CBN_SELENDOK
348 if something was selected;
350 case IDC_PLSEL_ROLE_RANDOM:
351 if (HIWORD(wParam) == BN_CLICKED) {
352 /* enable corresponding list window if "random"
353 checkbox was "unchecked" */
354 EnableWindow(GetDlgItem(hWnd, IDC_PLSEL_ROLE_LIST),
355 SendMessage((HWND) lParam, BM_GETCHECK, 0, 0)
356 == BST_UNCHECKED);
358 break;
360 case IDC_PLSEL_RACE_RANDOM:
361 if (HIWORD(wParam) == BN_CLICKED) {
362 EnableWindow(GetDlgItem(hWnd, IDC_PLSEL_RACE_LIST),
363 SendMessage((HWND) lParam, BM_GETCHECK, 0, 0)
364 == BST_UNCHECKED);
366 break;
368 case IDC_PLSEL_GENDER_RANDOM:
369 if (HIWORD(wParam) == BN_CLICKED) {
370 EnableWindow(GetDlgItem(hWnd, IDC_PLSEL_GENDER_LIST),
371 SendMessage((HWND) lParam, BM_GETCHECK, 0, 0)
372 == BST_UNCHECKED);
374 break;
376 case IDC_PLSEL_ALIGN_RANDOM:
377 if (HIWORD(wParam) == BN_CLICKED) {
378 EnableWindow(GetDlgItem(hWnd, IDC_PLSEL_ALIGN_LIST),
379 SendMessage((HWND) lParam, BM_GETCHECK, 0, 0)
380 == BST_UNCHECKED);
382 break;
384 case IDC_PLSEL_ROLE_LIST:
385 if (HIWORD(wParam) == CBN_SELENDOK) {
386 /* filter out invalid options if
387 the selection was made */
388 plselAdjustLists(hWnd, LOWORD(wParam));
390 break;
392 case IDC_PLSEL_RACE_LIST:
393 if (HIWORD(wParam) == CBN_SELENDOK) {
394 plselAdjustLists(hWnd, LOWORD(wParam));
396 break;
398 case IDC_PLSEL_GENDER_LIST:
399 if (HIWORD(wParam) == CBN_SELENDOK) {
400 plselAdjustLists(hWnd, LOWORD(wParam));
402 break;
404 case IDC_PLSEL_ALIGN_LIST:
405 if (HIWORD(wParam) == CBN_SELENDOK) {
406 plselAdjustLists(hWnd, LOWORD(wParam));
408 break;
410 break;
412 return FALSE;
415 void
416 setComboBoxValue(HWND hWnd, int combo_box, int value)
418 int index_max =
419 (int) SendDlgItemMessage(hWnd, combo_box, CB_GETCOUNT, 0, 0);
420 int index;
421 int value_to_set = LB_ERR;
422 for (index = 0; index < index_max; index++) {
423 if (SendDlgItemMessage(hWnd, combo_box, CB_GETITEMDATA,
424 (WPARAM) index, 0) == value) {
425 value_to_set = index;
426 break;
429 SendDlgItemMessage(hWnd, combo_box, CB_SETCURSEL, (WPARAM) value_to_set,
433 /* initialize player selector dialog */
434 void
435 plselInitDialog(HWND hWnd)
437 TCHAR wbuf[BUFSZ];
439 /* set player name */
440 SetDlgItemText(hWnd, IDC_PLSEL_NAME, NH_A2W(plname, wbuf, sizeof(wbuf)));
442 /* check flags for consistency */
443 if (flags.initrole >= 0) {
444 if (flags.initrace >= 0
445 && !validrace(flags.initrole, flags.initrace)) {
446 flags.initrace = ROLE_NONE;
449 if (flags.initgend >= 0
450 && !validgend(flags.initrole, flags.initrace, flags.initgend)) {
451 flags.initgend = ROLE_NONE;
454 if (flags.initalign >= 0
455 && !validalign(flags.initrole, flags.initrace, flags.initalign)) {
456 flags.initalign = ROLE_NONE;
460 /* populate select boxes */
461 plselAdjustLists(hWnd, -1);
463 /* intialize roles list */
464 if (flags.initrole < 0
465 || !ok_role(flags.initrole, ROLE_NONE, ROLE_NONE, ROLE_NONE)) {
466 CheckDlgButton(hWnd, IDC_PLSEL_ROLE_RANDOM, BST_CHECKED);
467 EnableWindow(GetDlgItem(hWnd, IDC_PLSEL_ROLE_LIST), FALSE);
468 } else {
469 CheckDlgButton(hWnd, IDC_PLSEL_ROLE_RANDOM, BST_UNCHECKED);
470 EnableWindow(GetDlgItem(hWnd, IDC_PLSEL_ROLE_LIST), TRUE);
471 setComboBoxValue(hWnd, IDC_PLSEL_ROLE_LIST, flags.initrole);
474 /* intialize races list */
475 if (flags.initrace < 0
476 || !ok_race(flags.initrole, flags.initrace, ROLE_NONE, ROLE_NONE)) {
477 CheckDlgButton(hWnd, IDC_PLSEL_RACE_RANDOM, BST_CHECKED);
478 EnableWindow(GetDlgItem(hWnd, IDC_PLSEL_RACE_LIST), FALSE);
479 } else {
480 CheckDlgButton(hWnd, IDC_PLSEL_RACE_RANDOM, BST_UNCHECKED);
481 EnableWindow(GetDlgItem(hWnd, IDC_PLSEL_RACE_LIST), TRUE);
482 setComboBoxValue(hWnd, IDC_PLSEL_RACE_LIST, flags.initrace);
485 /* intialize genders list */
486 if (flags.initgend < 0
487 || !ok_gend(flags.initrole, flags.initrace, flags.initgend,
488 ROLE_NONE)) {
489 CheckDlgButton(hWnd, IDC_PLSEL_GENDER_RANDOM, BST_CHECKED);
490 EnableWindow(GetDlgItem(hWnd, IDC_PLSEL_GENDER_LIST), FALSE);
491 } else {
492 CheckDlgButton(hWnd, IDC_PLSEL_GENDER_RANDOM, BST_UNCHECKED);
493 EnableWindow(GetDlgItem(hWnd, IDC_PLSEL_GENDER_LIST), TRUE);
494 setComboBoxValue(hWnd, IDC_PLSEL_GENDER_LIST, flags.initgend);
497 /* intialize alignments list */
498 if (flags.initalign < 0
499 || !ok_align(flags.initrole, flags.initrace, flags.initgend,
500 flags.initalign)) {
501 CheckDlgButton(hWnd, IDC_PLSEL_ALIGN_RANDOM, BST_CHECKED);
502 EnableWindow(GetDlgItem(hWnd, IDC_PLSEL_ALIGN_LIST), FALSE);
503 } else {
504 CheckDlgButton(hWnd, IDC_PLSEL_ALIGN_RANDOM, BST_UNCHECKED);
505 EnableWindow(GetDlgItem(hWnd, IDC_PLSEL_ALIGN_LIST), TRUE);
506 setComboBoxValue(hWnd, IDC_PLSEL_ALIGN_LIST, flags.initalign);
510 /* adjust role/race/alignment/gender list - filter out
511 invalid combinations
512 changed_sel points to the list where selection occurred
513 (-1 if unknown)
515 void
516 plselAdjustLists(HWND hWnd, int changed_sel)
518 HWND control_role, control_race, control_gender, control_align;
519 int initrole, initrace, initgend, initalign;
520 int i;
521 LRESULT ind;
522 int valid_opt;
523 TCHAR wbuf[255];
525 /* get control handles */
526 control_role = GetDlgItem(hWnd, IDC_PLSEL_ROLE_LIST);
527 control_race = GetDlgItem(hWnd, IDC_PLSEL_RACE_LIST);
528 control_gender = GetDlgItem(hWnd, IDC_PLSEL_GENDER_LIST);
529 control_align = GetDlgItem(hWnd, IDC_PLSEL_ALIGN_LIST);
531 /* get current selections */
532 ind = SendMessage(control_role, CB_GETCURSEL, 0, 0);
533 initrole = (ind == LB_ERR)
534 ? flags.initrole
535 : (int) SendMessage(control_role, CB_GETITEMDATA, ind, 0);
537 ind = SendMessage(control_race, CB_GETCURSEL, 0, 0);
538 initrace = (ind == LB_ERR)
539 ? flags.initrace
540 : (int) SendMessage(control_race, CB_GETITEMDATA, ind, 0);
542 ind = SendMessage(control_gender, CB_GETCURSEL, 0, 0);
543 initgend = (ind == LB_ERR) ? flags.initgend
544 : (int) SendMessage(control_gender,
545 CB_GETITEMDATA, ind, 0);
547 ind = SendMessage(control_align, CB_GETCURSEL, 0, 0);
548 initalign = (ind == LB_ERR) ? flags.initalign
549 : (int) SendMessage(control_align,
550 CB_GETITEMDATA, ind, 0);
552 /* intialize roles list */
553 if (changed_sel == -1) {
554 valid_opt = 0;
556 /* reset content and populate the list */
557 SendMessage(control_role, CB_RESETCONTENT, 0, 0);
558 for (i = 0; roles[i].name.m; i++) {
559 if (initgend >= 0 && flags.female && roles[i].name.f)
560 ind = SendMessage(
561 control_role, CB_ADDSTRING, (WPARAM) 0,
562 (LPARAM) NH_A2W(roles[i].name.f, wbuf, sizeof(wbuf)));
563 else
564 ind = SendMessage(
565 control_role, CB_ADDSTRING, (WPARAM) 0,
566 (LPARAM) NH_A2W(roles[i].name.m, wbuf, sizeof(wbuf)));
568 SendMessage(control_role, CB_SETITEMDATA, (WPARAM) ind,
569 (LPARAM) i);
570 if (i == initrole) {
571 SendMessage(control_role, CB_SETCURSEL, (WPARAM) ind,
572 (LPARAM) 0);
573 valid_opt = 1;
577 /* set selection to the previously selected role
578 if it is still valid */
579 if (!valid_opt) {
580 initrole = ROLE_NONE;
581 initrace = ROLE_NONE;
582 initgend = ROLE_NONE;
583 initalign = ROLE_NONE;
584 SendMessage(control_role, CB_SETCURSEL, (WPARAM) -1, (LPARAM) 0);
587 /* trigger change of the races list */
588 changed_sel = IDC_PLSEL_ROLE_LIST;
591 /* intialize races list */
592 if (changed_sel == IDC_PLSEL_ROLE_LIST) {
593 valid_opt = 0;
595 /* reset content and populate the list */
596 SendMessage(control_race, CB_RESETCONTENT, 0, 0);
597 for (i = 0; races[i].noun; i++)
598 if (ok_race(initrole, i, ROLE_NONE, ROLE_NONE)) {
599 ind = SendMessage(
600 control_race, CB_ADDSTRING, (WPARAM) 0,
601 (LPARAM) NH_A2W(races[i].noun, wbuf, sizeof(wbuf)));
602 SendMessage(control_race, CB_SETITEMDATA, (WPARAM) ind,
603 (LPARAM) i);
604 if (i == initrace) {
605 SendMessage(control_race, CB_SETCURSEL, (WPARAM) ind,
606 (LPARAM) 0);
607 valid_opt = 1;
611 /* set selection to the previously selected race
612 if it is still valid */
613 if (!valid_opt) {
614 initrace = ROLE_NONE;
615 initgend = ROLE_NONE;
616 initalign = ROLE_NONE;
617 SendMessage(control_race, CB_SETCURSEL, (WPARAM) -1, (LPARAM) 0);
620 /* trigger change of the genders list */
621 changed_sel = IDC_PLSEL_RACE_LIST;
624 /* intialize genders list */
625 if (changed_sel == IDC_PLSEL_RACE_LIST) {
626 valid_opt = 0;
628 /* reset content and populate the list */
629 SendMessage(control_gender, CB_RESETCONTENT, 0, 0);
630 for (i = 0; i < ROLE_GENDERS; i++)
631 if (ok_gend(initrole, initrace, i, ROLE_NONE)) {
632 ind = SendMessage(
633 control_gender, CB_ADDSTRING, (WPARAM) 0,
634 (LPARAM) NH_A2W(genders[i].adj, wbuf, sizeof(wbuf)));
635 SendMessage(control_gender, CB_SETITEMDATA, (WPARAM) ind,
636 (LPARAM) i);
637 if (i == initgend) {
638 SendMessage(control_gender, CB_SETCURSEL, (WPARAM) ind,
639 (LPARAM) 0);
640 valid_opt = 1;
644 /* set selection to the previously selected gender
645 if it is still valid */
646 if (!valid_opt) {
647 initgend = ROLE_NONE;
648 initalign = ROLE_NONE;
649 SendMessage(control_gender, CB_SETCURSEL, (WPARAM) -1,
650 (LPARAM) 0);
653 /* trigger change of the alignments list */
654 changed_sel = IDC_PLSEL_GENDER_LIST;
657 /* intialize alignments list */
658 if (changed_sel == IDC_PLSEL_GENDER_LIST) {
659 valid_opt = 0;
661 /* reset content and populate the list */
662 SendMessage(control_align, CB_RESETCONTENT, 0, 0);
663 for (i = 0; i < ROLE_ALIGNS; i++)
664 if (ok_align(initrole, initrace, initgend, i)) {
665 ind = SendMessage(
666 control_align, CB_ADDSTRING, (WPARAM) 0,
667 (LPARAM) NH_A2W(aligns[i].adj, wbuf, sizeof(wbuf)));
668 SendMessage(control_align, CB_SETITEMDATA, (WPARAM) ind,
669 (LPARAM) i);
670 if (i == initalign) {
671 SendMessage(control_align, CB_SETCURSEL, (WPARAM) ind,
672 (LPARAM) 0);
673 valid_opt = 1;
677 /* set selection to the previously selected alignment
678 if it is still valid */
679 if (!valid_opt) {
680 initalign = ROLE_NONE;
681 SendMessage(control_align, CB_SETCURSEL, (WPARAM) -1, (LPARAM) 0);
686 /* player made up his mind - get final selection here */
688 plselFinalSelection(HWND hWnd, int *selection)
690 LRESULT ind;
692 UNREFERENCED_PARAMETER(selection);
694 /* get current selections */
695 if (SendDlgItemMessage(hWnd, IDC_PLSEL_ROLE_RANDOM, BM_GETCHECK, 0, 0)
696 == BST_CHECKED) {
697 flags.initrole = ROLE_RANDOM;
698 } else {
699 ind =
700 SendDlgItemMessage(hWnd, IDC_PLSEL_ROLE_LIST, CB_GETCURSEL, 0, 0);
701 flags.initrole =
702 (ind == LB_ERR)
703 ? ROLE_RANDOM
704 : (int) SendDlgItemMessage(hWnd, IDC_PLSEL_ROLE_LIST,
705 CB_GETITEMDATA, ind, 0);
708 if (SendDlgItemMessage(hWnd, IDC_PLSEL_RACE_RANDOM, BM_GETCHECK, 0, 0)
709 == BST_CHECKED) {
710 flags.initrace = ROLE_RANDOM;
711 } else {
712 ind =
713 SendDlgItemMessage(hWnd, IDC_PLSEL_RACE_LIST, CB_GETCURSEL, 0, 0);
714 flags.initrace =
715 (ind == LB_ERR)
716 ? ROLE_RANDOM
717 : (int) SendDlgItemMessage(hWnd, IDC_PLSEL_RACE_LIST,
718 CB_GETITEMDATA, ind, 0);
721 if (SendDlgItemMessage(hWnd, IDC_PLSEL_GENDER_RANDOM, BM_GETCHECK, 0, 0)
722 == BST_CHECKED) {
723 flags.initgend = ROLE_RANDOM;
724 } else {
725 ind = SendDlgItemMessage(hWnd, IDC_PLSEL_GENDER_LIST, CB_GETCURSEL, 0,
727 flags.initgend =
728 (ind == LB_ERR)
729 ? ROLE_RANDOM
730 : (int) SendDlgItemMessage(hWnd, IDC_PLSEL_GENDER_LIST,
731 CB_GETITEMDATA, ind, 0);
734 if (SendDlgItemMessage(hWnd, IDC_PLSEL_ALIGN_RANDOM, BM_GETCHECK, 0, 0)
735 == BST_CHECKED) {
736 flags.initalign = ROLE_RANDOM;
737 } else {
738 ind = SendDlgItemMessage(hWnd, IDC_PLSEL_ALIGN_LIST, CB_GETCURSEL, 0,
740 flags.initalign =
741 (ind == LB_ERR)
742 ? ROLE_RANDOM
743 : (int) SendDlgItemMessage(hWnd, IDC_PLSEL_ALIGN_LIST,
744 CB_GETITEMDATA, ind, 0);
747 /* check the role */
748 if (flags.initrole == ROLE_RANDOM) {
749 flags.initrole = pick_role(flags.initrace, flags.initgend,
750 flags.initalign, PICK_RANDOM);
751 if (flags.initrole < 0) {
752 NHMessageBox(hWnd, TEXT("Incompatible role!"),
753 MB_ICONSTOP | MB_OK);
754 return FALSE;
758 /* Select a race, if necessary */
759 /* force compatibility with role */
760 if (flags.initrace == ROLE_RANDOM
761 || !validrace(flags.initrole, flags.initrace)) {
762 /* pre-selected race not valid */
763 if (flags.initrace == ROLE_RANDOM) {
764 flags.initrace = pick_race(flags.initrole, flags.initgend,
765 flags.initalign, PICK_RANDOM);
768 if (flags.initrace < 0) {
769 NHMessageBox(hWnd, TEXT("Incompatible race!"),
770 MB_ICONSTOP | MB_OK);
771 return FALSE;
775 /* Select a gender, if necessary */
776 /* force compatibility with role/race, try for compatibility with
777 * pre-selected alignment */
778 if (flags.initgend < 0
779 || !validgend(flags.initrole, flags.initrace, flags.initgend)) {
780 /* pre-selected gender not valid */
781 if (flags.initgend == ROLE_RANDOM) {
782 flags.initgend = pick_gend(flags.initrole, flags.initrace,
783 flags.initalign, PICK_RANDOM);
786 if (flags.initgend < 0) {
787 NHMessageBox(hWnd, TEXT("Incompatible gender!"),
788 MB_ICONSTOP | MB_OK);
789 return FALSE;
793 /* Select an alignment, if necessary */
794 /* force compatibility with role/race/gender */
795 if (flags.initalign < 0
796 || !validalign(flags.initrole, flags.initrace, flags.initalign)) {
797 /* pre-selected alignment not valid */
798 if (flags.initalign == ROLE_RANDOM) {
799 flags.initalign = pick_align(flags.initrole, flags.initrace,
800 flags.initgend, PICK_RANDOM);
801 } else {
802 NHMessageBox(hWnd, TEXT("Incompatible alignment!"),
803 MB_ICONSTOP | MB_OK);
804 return FALSE;
808 return TRUE;