1 /* ----------------- dialbox.c -------------- */
5 static int inFocusCommand(DBOX
*);
6 static void dbShortcutKeys(DBOX
*, int);
7 static int ControlProc(DFWINDOW
, DFMESSAGE
, PARAM
, PARAM
);
8 static void FirstFocus(DBOX
*db
);
9 static void NextFocus(DBOX
*db
);
10 static void PrevFocus(DBOX
*db
);
11 static CTLWINDOW
*AssociatedControl(DBOX
*, enum commands
);
13 static BOOL SysMenuOpen
;
15 static DBOX
**dbs
= NULL
;
18 /* --- clear all heap allocations to control text fields --- */
19 void ClearDialogBoxes(void)
23 for (i
= 0; i
< dbct
; i
++)
25 CTLWINDOW
*ct
= (*(dbs
+i
))->ctl
;
29 if ((ct
->class == EDITBOX
||
30 ct
->class == COMBOBOX
) &&
48 /* -------- CREATE_WINDOW Message --------- */
49 static int CreateWindowMsg(DFWINDOW wnd
, PARAM p1
, PARAM p2
)
51 DBOX
*db
= wnd
->extension
;
52 CTLWINDOW
*ct
= db
->ctl
;
55 /* ---- build a table of processed dialog boxes ---- */
56 for (i
= 0; i
< dbct
; i
++)
60 dbs
= DFrealloc(dbs
, sizeof(DBOX
*) * (dbct
+1));
63 rtn
= BaseWndProc(DIALOG
, wnd
, CREATE_WINDOW
, p1
, p2
);
67 if (TestAttribute(wnd
, NOCLIP
))
71 ct
->setting
= ct
->isetting
;
72 if (ct
->class == EDITBOX
&& ct
->dwnd
.h
> 1)
73 attrib
|= (MULTILINE
| HASBORDER
);
74 else if ((ct
->class == LISTBOX
|| ct
->class == TEXTBOX
) &&
77 cwnd
= DfCreateWindow(ct
->class,
79 ct
->dwnd
.x
+GetClientLeft(wnd
),
80 ct
->dwnd
.y
+GetClientTop(wnd
),
87 if ((ct
->class == EDITBOX
||
88 ct
->class == COMBOBOX
) &&
90 DfSendMessage(cwnd
, SETTEXT
, (PARAM
) ct
->itext
, 0);
96 /* -------- LEFT_BUTTON Message --------- */
97 static BOOL
LeftButtonMsg(DFWINDOW wnd
, PARAM p1
, PARAM p2
)
99 DBOX
*db
= wnd
->extension
;
100 CTLWINDOW
*ct
= db
->ctl
;
101 if (WindowSizing
|| WindowMoving
)
103 if (HitControlBox(wnd
, p1
-GetLeft(wnd
), p2
-GetTop(wnd
))) {
104 DfPostMessage(wnd
, KEYBOARD
, ' ', ALTKEY
);
108 DFWINDOW cwnd
= ct
->wnd
;
109 if (ct
->class == COMBOBOX
) {
110 if (p2
== GetTop(cwnd
)) {
111 if (p1
== GetRight(cwnd
)+1) {
112 DfSendMessage(cwnd
, LEFT_BUTTON
, p1
, p2
);
116 if (GetClass(inFocus
) == LISTBOX
)
117 DfSendMessage(wnd
, SETFOCUS
, TRUE
, 0);
119 else if (ct
->class == SPINBUTTON
) {
120 if (p2
== GetTop(cwnd
)) {
121 if (p1
== GetRight(cwnd
)+1 ||
122 p1
== GetRight(cwnd
)+2) {
123 DfSendMessage(cwnd
, LEFT_BUTTON
, p1
, p2
);
133 /* -------- KEYBOARD Message --------- */
134 static BOOL
KeyboardMsg(DFWINDOW wnd
, PARAM p1
, PARAM p2
)
136 DBOX
*db
= wnd
->extension
;
139 if (WindowMoving
|| WindowSizing
)
143 ct
= GetControl(inFocus
);
145 if (DisplayHelp(wnd
, ct
->help
))
160 if (((int)p2
& ALTKEY
) &&
161 TestAttribute(wnd
, CONTROLBOX
)) {
163 BuildSystemMenu(wnd
);
168 DfSendMessage(wnd
, DFM_COMMAND
, ID_CANCEL
, 0);
171 /* ------ search all the shortcut keys ----- */
172 dbShortcutKeys(db
, (int) p1
);
178 /* -------- COMMAND Message --------- */
179 static BOOL
CommandMsg(DFWINDOW wnd
, PARAM p1
, PARAM p2
)
181 DBOX
*db
= wnd
->extension
;
187 wnd
->ReturnCode
= (int) p1
;
189 DfPostMessage(wnd
, ENDDIALOG
, 0, 0);
191 DfSendMessage(wnd
, CLOSE_WINDOW
, TRUE
, 0);
196 return DisplayHelp(wnd
, db
->HelpName
);
203 /* ----- window-processing module, DIALOG window class ----- */
204 int DialogProc(DFWINDOW wnd
, DFMESSAGE msg
, PARAM p1
, PARAM p2
)
207 DBOX
*db
= wnd
->extension
;
211 return CreateWindowMsg(wnd
, p1
, p2
);
217 if (LeftButtonMsg(wnd
, p1
, p2
))
221 if (KeyboardMsg(wnd
, p1
, p2
))
231 DfSendMessage(wnd
, DFM_COMMAND
, inFocusCommand(db
), msg
);
234 if (CommandMsg(wnd
, p1
, p2
))
242 rtn
= BaseWndProc(DIALOG
, wnd
, msg
, p1
, p2
);
243 if (wnd
->dfocus
!= NULL
)
244 DfSendMessage(wnd
->dfocus
, SETFOCUS
, TRUE
, 0);
250 DfSendMessage(wnd
, DFM_COMMAND
, ID_CANCEL
, 0);
258 return BaseWndProc(DIALOG
, wnd
, msg
, p1
, p2
);
261 /* ------- create and execute a dialog box ---------- */
262 BOOL
DfDialogBox(DFWINDOW wnd
, DBOX
*db
, BOOL Modal
,
263 int (*wndproc
)(struct window
*, enum messages
, PARAM
, PARAM
))
266 int x
= db
->dwnd
.x
, y
= db
->dwnd
.y
;
269 if (!Modal
&& wnd
!= NULL
)
274 DialogWnd
= DfCreateWindow(DIALOG
,
282 Modal
? SAVESELF
: 0);
283 DialogWnd
->Modal
= Modal
;
285 DfPostMessage(DialogWnd
, INITIATE_DIALOG
, 0, 0);
288 DfSendMessage(DialogWnd
, CAPTURE_MOUSE
, 0, 0);
289 DfSendMessage(DialogWnd
, CAPTURE_KEYBOARD
, 0, 0);
290 while (DfDispatchMessage ())
292 rtn
= DialogWnd
->ReturnCode
== ID_OK
;
293 DfSendMessage(DialogWnd
, RELEASE_MOUSE
, 0, 0);
294 DfSendMessage(DialogWnd
, RELEASE_KEYBOARD
, 0, 0);
295 DfSendMessage(DialogWnd
, CLOSE_WINDOW
, TRUE
, 0);
301 /* ----- return command code of in-focus control window ---- */
302 static int inFocusCommand(DBOX
*db
)
304 CTLWINDOW
*ct
= db
->ctl
;
306 if (ct
->wnd
== inFocus
)
313 /* -------- find a specified control structure ------- */
314 CTLWINDOW
*FindCommand(DBOX
*db
, enum commands cmd
, int class)
316 CTLWINDOW
*ct
= db
->ctl
;
319 if (ct
->class == class)
320 if (cmd
== ct
->command
)
327 /* ---- return the window handle of a specified command ---- */
328 DFWINDOW
ControlWindow(DBOX
*db
, enum commands cmd
)
330 CTLWINDOW
*ct
= db
->ctl
;
333 if (ct
->class != TEXT
&& cmd
== ct
->command
)
340 /* --- return a pointer to the control structure that matches a window --- */
341 CTLWINDOW
*WindowControl(DBOX
*db
, DFWINDOW wnd
)
343 CTLWINDOW
*ct
= db
->ctl
;
353 /* ---- set a control ON or OFF ----- */
354 void ControlSetting(DBOX
*db
, enum commands cmd
,
355 int class, int setting
)
357 CTLWINDOW
*ct
= FindCommand(db
, cmd
, class);
359 ct
->isetting
= setting
;
361 ct
->setting
= setting
;
365 /* ---- return pointer to the text of a control window ---- */
366 char *GetDlgTextString(DBOX
*db
,enum commands cmd
,DFCLASS
class)
368 CTLWINDOW
*ct
= FindCommand(db
, cmd
, class);
375 /* ------- set the text of a control specification ------ */
376 void SetDlgTextString(DBOX
*db
, enum commands cmd
,
377 char *text
, DFCLASS
class)
379 CTLWINDOW
*ct
= FindCommand(db
, cmd
, class);
381 ct
->itext
= DFrealloc(ct
->itext
, strlen(text
)+1);
382 strcpy(ct
->itext
, text
);
386 /* ------- set the text of a control window ------ */
387 void PutItemText(DFWINDOW wnd
, enum commands cmd
, char *text
)
389 CTLWINDOW
*ct
= FindCommand(wnd
->extension
, cmd
, EDITBOX
);
392 ct
= FindCommand(wnd
->extension
, cmd
, TEXTBOX
);
394 ct
= FindCommand(wnd
->extension
, cmd
, COMBOBOX
);
396 ct
= FindCommand(wnd
->extension
, cmd
, LISTBOX
);
398 ct
= FindCommand(wnd
->extension
, cmd
, SPINBUTTON
);
400 ct
= FindCommand(wnd
->extension
, cmd
, TEXT
);
402 DFWINDOW cwnd
= (DFWINDOW
) (ct
->wnd
);
406 DfSendMessage(cwnd
, CLEARTEXT
, 0, 0);
407 DfSendMessage(cwnd
, ADDTEXT
, (PARAM
) text
, 0);
408 if (!isMultiLine(cwnd
))
409 DfSendMessage(cwnd
, PAINT
, 0, 0);
414 DfSendMessage(cwnd
, ADDTEXT
, (PARAM
) text
, 0);
417 DfSendMessage(cwnd
, CLEARTEXT
, 0, 0);
418 DfSendMessage(cwnd
, ADDTEXT
, (PARAM
) text
, 0);
419 DfSendMessage(cwnd
, PAINT
, 0, 0);
428 /* ------- get the text of a control window ------ */
429 void GetItemText(DFWINDOW wnd
, enum commands cmd
,
432 CTLWINDOW
*ct
= FindCommand(wnd
->extension
, cmd
, EDITBOX
);
436 ct
= FindCommand(wnd
->extension
, cmd
, COMBOBOX
);
438 ct
= FindCommand(wnd
->extension
, cmd
, TEXTBOX
);
440 ct
= FindCommand(wnd
->extension
, cmd
, TEXT
);
442 DFWINDOW cwnd
= (DFWINDOW
) (ct
->wnd
);
446 if (GetText(cwnd
) != NULL
) {
447 cp
= strchr(GetText(cwnd
), '\n');
449 len
= (int) (cp
- GetText(cwnd
));
450 strncpy(text
, GetText(cwnd
), len
);
455 if (GetText(cwnd
) != NULL
)
456 strncpy(text
, GetText(cwnd
), len
);
460 DfSendMessage(cwnd
,GETTEXT
,(PARAM
)text
,len
);
469 /* ------- set the text of a listbox control window ------ */
470 void GetDlgListText(DFWINDOW wnd
, char *text
, enum commands cmd
)
472 CTLWINDOW
*ct
= FindCommand(wnd
->extension
, cmd
, LISTBOX
);
473 int sel
= DfSendMessage(ct
->wnd
, LB_CURRENTSELECTION
, 0, 0);
474 DfSendMessage(ct
->wnd
, DFM_LB_GETTEXT
, (PARAM
) text
, sel
);
477 /* -- find control structure associated with text control -- */
478 static CTLWINDOW
*AssociatedControl(DBOX
*db
,enum commands Tcmd
)
480 CTLWINDOW
*ct
= db
->ctl
;
482 if (ct
->class != TEXT
)
483 if (ct
->command
== Tcmd
)
490 /* --- process dialog box shortcut keys --- */
491 static void dbShortcutKeys(DBOX
*db
, int ky
)
494 int ch
= AltConvert(ky
);
499 char *cp
= ct
->itext
;
501 if (*cp
== SHORTCUTCHAR
&&
502 tolower(*(cp
+1)) == ch
) {
503 if (ct
->class == TEXT
)
504 ct
= AssociatedControl(db
, ct
->command
);
505 if (ct
->class == RADIOBUTTON
)
506 SetRadioButton(db
, ct
);
507 else if (ct
->class == CHECKBOX
) {
509 DfSendMessage(ct
->wnd
, PAINT
, 0, 0);
511 else if (ct
->class) {
512 DfSendMessage(ct
->wnd
, SETFOCUS
, TRUE
, 0);
513 if (ct
->class == BUTTON
)
514 DfSendMessage(ct
->wnd
,KEYBOARD
,'\r',0);
525 /* --- dynamically add or remove scroll bars
526 from a control window ---- */
527 void SetScrollBars(DFWINDOW wnd
)
529 int oldattr
= GetAttribute(wnd
);
530 if (wnd
->wlines
> ClientHeight(wnd
))
531 AddAttribute(wnd
, VSCROLLBAR
);
533 ClearAttribute(wnd
, VSCROLLBAR
);
534 if (wnd
->textwidth
> ClientWidth(wnd
))
535 AddAttribute(wnd
, HSCROLLBAR
);
537 ClearAttribute(wnd
, HSCROLLBAR
);
538 if (GetAttribute(wnd
) != oldattr
)
539 DfSendMessage(wnd
, BORDER
, 0, 0);
542 /* ------- CREATE_WINDOW Message (Control) ----- */
543 static void CtlCreateWindowMsg(DFWINDOW wnd
)
546 ct
= wnd
->ct
= wnd
->extension
;
547 wnd
->extension
= NULL
;
552 /* ------- KEYBOARD Message (Control) ----- */
553 static BOOL
CtlKeyboardMsg(DFWINDOW wnd
, PARAM p1
, PARAM p2
)
555 CTLWINDOW
*ct
= GetControl(wnd
);
558 if (WindowMoving
|| WindowSizing
)
560 if (!DisplayHelp(wnd
, ct
->help
))
561 DfSendMessage(GetParent(wnd
),DFM_COMMAND
,ID_HELP
,0);
564 if (!((int)p2
& ALTKEY
))
569 DfPostMessage(GetParent(wnd
), KEYBOARD
, p1
, p2
);
574 if (GetClass(wnd
) == EDITBOX
)
575 if (isMultiLine(wnd
))
579 if (!isDerivedFrom(wnd
, LISTBOX
)) {
585 if (!isDerivedFrom(wnd
, EDITBOX
)) {
591 if (!isDerivedFrom(wnd
, LISTBOX
) &&
592 !isDerivedFrom(wnd
, COMBOBOX
))
596 if (!isDerivedFrom(wnd
, EDITBOX
))
600 if (isDerivedFrom(wnd
, EDITBOX
))
601 if (isMultiLine(wnd
))
603 if (isDerivedFrom(wnd
, BUTTON
))
605 DfSendMessage(GetParent(wnd
), DFM_COMMAND
, ID_OK
, 0);
613 /* ------- CLOSE_WINDOW Message (Control) ----- */
614 static void CtlCloseWindowMsg(DFWINDOW wnd
)
616 CTLWINDOW
*ct
= GetControl(wnd
);
619 if (GetParent(wnd
)->ReturnCode
== ID_OK
) {
620 if (ct
->class == EDITBOX
|| ct
->class == COMBOBOX
) {
621 if (wnd
->TextChanged
) {
622 ct
->itext
=DFrealloc(ct
->itext
,strlen(wnd
->text
)+1);
623 strcpy(ct
->itext
, wnd
->text
);
624 if (!isMultiLine(wnd
)) {
625 char *cp
= ct
->itext
+strlen(ct
->itext
)-1;
631 else if (ct
->class == RADIOBUTTON
|| ct
->class == CHECKBOX
)
632 ct
->isetting
= ct
->setting
;
638 static void FixColors(DFWINDOW wnd
)
640 CTLWINDOW
*ct
= wnd
->ct
;
642 if (ct
->class != BUTTON
)
644 if (ct
->class != SPINBUTTON
&& ct
->class != COMBOBOX
)
646 wnd
->WindowColors
[FRAME_COLOR
][FG
] =
647 GetParent(wnd
)->WindowColors
[FRAME_COLOR
][FG
];
648 wnd
->WindowColors
[FRAME_COLOR
][BG
] =
649 GetParent(wnd
)->WindowColors
[FRAME_COLOR
][BG
];
650 if (ct
->class != EDITBOX
&& ct
->class != LISTBOX
)
652 wnd
->WindowColors
[STD_COLOR
][FG
] =
653 GetParent(wnd
)->WindowColors
[STD_COLOR
][FG
];
654 wnd
->WindowColors
[STD_COLOR
][BG
] =
655 GetParent(wnd
)->WindowColors
[STD_COLOR
][BG
];
662 /* -- generic window processor used by dialog box controls -- */
663 static int ControlProc(DFWINDOW wnd
,DFMESSAGE msg
,PARAM p1
,PARAM p2
)
669 db
= GetParent(wnd
) ? GetParent(wnd
)->extension
: NULL
;
673 CtlCreateWindowMsg(wnd
);
676 if (CtlKeyboardMsg(wnd
, p1
, p2
))
681 if (GetClass(wnd
) == EDITBOX
||
682 GetClass(wnd
) == LISTBOX
||
683 GetClass(wnd
) == TEXTBOX
)
688 if (GetClass(wnd
) == EDITBOX
) {
689 DFWINDOW oldFocus
= inFocus
;
691 DefaultWndProc(wnd
, msg
, p1
, p2
);
697 DFWINDOW pwnd
= GetParent(wnd
);
700 DefaultWndProc(wnd
, msg
, p1
, p2
);
704 DfSendMessage(pwnd
, DFM_COMMAND
,
705 inFocusCommand(db
), ENTERFOCUS
);
710 DfSendMessage(pwnd
, DFM_COMMAND
,
711 inFocusCommand(db
), LEAVEFOCUS
);
715 CtlCloseWindowMsg(wnd
);
720 return DefaultWndProc(wnd
, msg
, p1
, p2
);
723 /* ---- change the focus to the first control --- */
724 static void FirstFocus(DBOX
*db
)
726 CTLWINDOW
*ct
= db
->ctl
;
729 while (ct
->class == TEXT
|| ct
->class == BOX
) {
734 DfSendMessage(ct
->wnd
, SETFOCUS
, TRUE
, 0);
738 /* ---- change the focus to the next control --- */
739 static void NextFocus(DBOX
*db
)
741 CTLWINDOW
*ct
= WindowControl(db
, inFocus
);
755 } while (ct
->class == TEXT
|| ct
->class == BOX
);
756 DfSendMessage(ct
->wnd
, SETFOCUS
, TRUE
, 0);
760 /* ---- change the focus to the previous control --- */
761 static void PrevFocus(DBOX
*db
)
763 CTLWINDOW
*ct
= WindowControl(db
, inFocus
);
778 } while (ct
->class == TEXT
|| ct
->class == BOX
);
779 DfSendMessage(ct
->wnd
, SETFOCUS
, TRUE
, 0);
783 void SetFocusCursor(DFWINDOW wnd
)
787 DfSendMessage(NULL
, SHOW_CURSOR
, 0, 0);
788 DfSendMessage(wnd
, KEYBOARD_CURSOR
, 1, 0);