122b00afd3d0eb6b18b38fdc858859e70ca44b81
1 /* ----------------- dialbox.c -------------- */
5 static int inFocusCommand(DF_DBOX
*);
6 static void dbShortcutKeys(DF_DBOX
*, int);
7 static int ControlProc(DFWINDOW
, DFMESSAGE
, DF_PARAM
, DF_PARAM
);
8 static void FirstFocus(DF_DBOX
*db
);
9 static void NextFocus(DF_DBOX
*db
);
10 static void PrevFocus(DF_DBOX
*db
);
11 static DF_CTLWINDOW
*AssociatedControl(DF_DBOX
*, enum DfCommands
);
13 static BOOL SysMenuOpen
;
15 static DF_DBOX
**dbs
= NULL
;
18 /* --- clear all heap allocations to control text fields --- */
19 void DfClearDialogBoxes(void)
23 for (i
= 0; i
< dbct
; i
++)
25 DF_CTLWINDOW
*ct
= (*(dbs
+i
))->ctl
;
29 if ((ct
->class == DF_EDITBOX
||
30 ct
->class == DF_COMBOBOX
) &&
48 /* -------- DFM_CREATE_WINDOW Message --------- */
49 static int CreateWindowMsg(DFWINDOW wnd
, DF_PARAM p1
, DF_PARAM p2
)
51 DF_DBOX
*db
= wnd
->extension
;
52 DF_CTLWINDOW
*ct
= db
->ctl
;
55 /* ---- build a table of processed dialog boxes ---- */
56 for (i
= 0; i
< dbct
; i
++)
60 dbs
= DfRealloc(dbs
, sizeof(DF_DBOX
*) * (dbct
+1));
63 rtn
= DfBaseWndProc(DF_DIALOG
, wnd
, DFM_CREATE_WINDOW
, p1
, p2
);
67 if (DfTestAttribute(wnd
, DF_NOCLIP
))
70 attrib
|= DF_SAVESELF
;
71 ct
->setting
= ct
->isetting
;
72 if (ct
->class == DF_EDITBOX
&& ct
->dwnd
.h
> 1)
73 attrib
|= (DF_MULTILINE
| DF_HASBORDER
);
74 else if ((ct
->class == DF_LISTBOX
|| ct
->class == DF_TEXTBOX
) &&
76 attrib
|= DF_HASBORDER
;
77 cwnd
= DfDfCreateWindow(ct
->class,
79 ct
->dwnd
.x
+DfGetClientLeft(wnd
),
80 ct
->dwnd
.y
+DfGetClientTop(wnd
),
87 if ((ct
->class == DF_EDITBOX
||
88 ct
->class == DF_COMBOBOX
) &&
90 DfSendMessage(cwnd
, DFM_SETTEXT
, (DF_PARAM
) ct
->itext
, 0);
96 /* -------- DFM_LEFT_BUTTON Message --------- */
97 static BOOL
LeftButtonMsg(DFWINDOW wnd
, DF_PARAM p1
, DF_PARAM p2
)
99 DF_DBOX
*db
= wnd
->extension
;
100 DF_CTLWINDOW
*ct
= db
->ctl
;
101 if (DfWindowSizing
|| DfWindowMoving
)
103 if (DfHitControlBox(wnd
, p1
-DfGetLeft(wnd
), p2
-DfGetTop(wnd
))) {
104 DfPostMessage(wnd
, DFM_KEYBOARD
, ' ', DF_ALTKEY
);
108 DFWINDOW cwnd
= ct
->wnd
;
109 if (ct
->class == DF_COMBOBOX
) {
110 if (p2
== DfGetTop(cwnd
)) {
111 if (p1
== DfGetRight(cwnd
)+1) {
112 DfSendMessage(cwnd
, DFM_LEFT_BUTTON
, p1
, p2
);
116 if (DfGetClass(DfInFocus
) == DF_LISTBOX
)
117 DfSendMessage(wnd
, DFM_SETFOCUS
, TRUE
, 0);
119 else if (ct
->class == DF_SPINBUTTON
) {
120 if (p2
== DfGetTop(cwnd
)) {
121 if (p1
== DfGetRight(cwnd
)+1 ||
122 p1
== DfGetRight(cwnd
)+2) {
123 DfSendMessage(cwnd
, DFM_LEFT_BUTTON
, p1
, p2
);
133 /* -------- DFM_KEYBOARD Message --------- */
134 static BOOL
KeyboardMsg(DFWINDOW wnd
, DF_PARAM p1
, DF_PARAM p2
)
136 DF_DBOX
*db
= wnd
->extension
;
139 if (DfWindowMoving
|| DfWindowSizing
)
143 ct
= DfGetControl(DfInFocus
);
145 if (DfDisplayHelp(wnd
, ct
->help
))
160 if (((int)p2
& DF_ALTKEY
) &&
161 DfTestAttribute(wnd
, DF_CONTROLBOX
)) {
163 DfBuildSystemMenu(wnd
);
168 DfSendMessage(wnd
, DFM_COMMAND
, DF_ID_CANCEL
, 0);
171 /* ------ search all the shortcut keys ----- */
172 dbShortcutKeys(db
, (int) p1
);
178 /* -------- COMMAND Message --------- */
179 static BOOL
CommandMsg(DFWINDOW wnd
, DF_PARAM p1
, DF_PARAM p2
)
181 DF_DBOX
*db
= wnd
->extension
;
187 wnd
->ReturnCode
= (int) p1
;
189 DfPostMessage(wnd
, DFM_ENDDIALOG
, 0, 0);
191 DfSendMessage(wnd
, DFM_CLOSE_WINDOW
, TRUE
, 0);
196 return DfDisplayHelp(wnd
, db
->HelpName
);
203 /* ----- window-processing module, DF_DIALOG window class ----- */
204 int DfDialogProc(DFWINDOW wnd
, DFMESSAGE msg
, DF_PARAM p1
, DF_PARAM p2
)
207 DF_DBOX
*db
= wnd
->extension
;
210 case DFM_CREATE_WINDOW
:
211 return CreateWindowMsg(wnd
, p1
, p2
);
212 case DFM_SHIFT_CHANGED
:
216 case DFM_LEFT_BUTTON
:
217 if (LeftButtonMsg(wnd
, p1
, p2
))
221 if (KeyboardMsg(wnd
, p1
, p2
))
224 case DFM_CLOSE_POPDOWN
:
227 case DFM_LB_SELECTION
:
231 DfSendMessage(wnd
, DFM_COMMAND
, inFocusCommand(db
), msg
);
234 if (CommandMsg(wnd
, p1
, p2
))
242 rtn
= DfBaseWndProc(DF_DIALOG
, wnd
, msg
, p1
, p2
);
243 if (wnd
->dfocus
!= NULL
)
244 DfSendMessage(wnd
->dfocus
, DFM_SETFOCUS
, TRUE
, 0);
247 case DFM_CLOSE_WINDOW
:
250 DfSendMessage(wnd
, DFM_COMMAND
, DF_ID_CANCEL
, 0);
258 return DfBaseWndProc(DF_DIALOG
, wnd
, msg
, p1
, p2
);
261 /* ------- create and execute a dialog box ---------- */
262 BOOL
DfDialogBox(DFWINDOW wnd
, DF_DBOX
*db
, BOOL Modal
,
263 int (*wndproc
)(struct DfWindow
*, enum DfMessages
, DF_PARAM
, DF_PARAM
))
266 int x
= db
->dwnd
.x
, y
= db
->dwnd
.y
;
269 if (!Modal
&& wnd
!= NULL
)
274 DialogWnd
= DfDfCreateWindow(DF_DIALOG
,
282 Modal
? DF_SAVESELF
: 0);
283 DialogWnd
->Modal
= Modal
;
285 DfPostMessage(DialogWnd
, DFM_INITIATE_DIALOG
, 0, 0);
288 DfSendMessage(DialogWnd
, DFM_CAPTURE_MOUSE
, 0, 0);
289 DfSendMessage(DialogWnd
, DFM_CAPTURE_KEYBOARD
, 0, 0);
290 while (DfDispatchMessage ())
292 rtn
= DialogWnd
->ReturnCode
== DF_ID_OK
;
293 DfSendMessage(DialogWnd
, DFM_RELEASE_MOUSE
, 0, 0);
294 DfSendMessage(DialogWnd
, DFM_RELEASE_KEYBOARD
, 0, 0);
295 DfSendMessage(DialogWnd
, DFM_CLOSE_WINDOW
, TRUE
, 0);
301 /* ----- return command code of in-focus control window ---- */
302 static int inFocusCommand(DF_DBOX
*db
)
304 DF_CTLWINDOW
*ct
= db
->ctl
;
306 if (ct
->wnd
== DfInFocus
)
313 /* -------- find a specified control structure ------- */
314 DF_CTLWINDOW
*DfFindCommand(DF_DBOX
*db
, enum DfCommands cmd
, int class)
316 DF_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
DfControlWindow(DF_DBOX
*db
, enum DfCommands cmd
)
330 DF_CTLWINDOW
*ct
= db
->ctl
;
333 if (ct
->class != DF_TEXT
&& cmd
== ct
->command
)
340 /* --- return a pointer to the control structure that matches a window --- */
341 DF_CTLWINDOW
*WindowControl(DF_DBOX
*db
, DFWINDOW wnd
)
343 DF_CTLWINDOW
*ct
= db
->ctl
;
353 /* ---- set a control DF_ON or DF_OFF ----- */
354 void DfControlSetting(DF_DBOX
*db
, enum DfCommands cmd
,
355 int class, int setting
)
357 DF_CTLWINDOW
*ct
= DfFindCommand(db
, cmd
, class);
359 ct
->isetting
= setting
;
361 ct
->setting
= setting
;
365 /* ---- return pointer to the text of a control window ---- */
366 char *DfGetDlgTextString(DF_DBOX
*db
,enum DfCommands cmd
,DFCLASS
class)
368 DF_CTLWINDOW
*ct
= DfFindCommand(db
, cmd
, class);
375 /* ------- set the text of a control specification ------ */
376 void DfSetDlgTextString(DF_DBOX
*db
, enum DfCommands cmd
,
377 char *text
, DFCLASS
class)
379 DF_CTLWINDOW
*ct
= DfFindCommand(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 DfPutItemText(DFWINDOW wnd
, enum DfCommands cmd
, char *text
)
389 DF_CTLWINDOW
*ct
= DfFindCommand(wnd
->extension
, cmd
, DF_EDITBOX
);
392 ct
= DfFindCommand(wnd
->extension
, cmd
, DF_TEXTBOX
);
394 ct
= DfFindCommand(wnd
->extension
, cmd
, DF_COMBOBOX
);
396 ct
= DfFindCommand(wnd
->extension
, cmd
, DF_LISTBOX
);
398 ct
= DfFindCommand(wnd
->extension
, cmd
, DF_SPINBUTTON
);
400 ct
= DfFindCommand(wnd
->extension
, cmd
, DF_TEXT
);
402 DFWINDOW cwnd
= (DFWINDOW
) (ct
->wnd
);
406 DfSendMessage(cwnd
, DFM_CLEARTEXT
, 0, 0);
407 DfSendMessage(cwnd
, DFM_ADDTEXT
, (DF_PARAM
) text
, 0);
408 if (!DfIsMultiLine(cwnd
))
409 DfSendMessage(cwnd
, DFM_PAINT
, 0, 0);
414 DfSendMessage(cwnd
, DFM_ADDTEXT
, (DF_PARAM
) text
, 0);
417 DfSendMessage(cwnd
, DFM_CLEARTEXT
, 0, 0);
418 DfSendMessage(cwnd
, DFM_ADDTEXT
, (DF_PARAM
) text
, 0);
419 DfSendMessage(cwnd
, DFM_PAINT
, 0, 0);
428 /* ------- get the text of a control window ------ */
429 void DfGetItemText(DFWINDOW wnd
, enum DfCommands cmd
,
432 DF_CTLWINDOW
*ct
= DfFindCommand(wnd
->extension
, cmd
, DF_EDITBOX
);
436 ct
= DfFindCommand(wnd
->extension
, cmd
, DF_COMBOBOX
);
438 ct
= DfFindCommand(wnd
->extension
, cmd
, DF_TEXTBOX
);
440 ct
= DfFindCommand(wnd
->extension
, cmd
, DF_TEXT
);
442 DFWINDOW cwnd
= (DFWINDOW
) (ct
->wnd
);
446 if (DfGetText(cwnd
) != NULL
) {
447 cp
= strchr(DfGetText(cwnd
), '\n');
449 len
= (int) (cp
- DfGetText(cwnd
));
450 strncpy(text
, DfGetText(cwnd
), len
);
455 if (DfGetText(cwnd
) != NULL
)
456 strncpy(text
, DfGetText(cwnd
), len
);
460 DfSendMessage(cwnd
,DFM_GETTEXT
,(DF_PARAM
)text
,len
);
469 /* ------- set the text of a listbox control window ------ */
470 void DfGetDlgListText(DFWINDOW wnd
, char *text
, enum DfCommands cmd
)
472 DF_CTLWINDOW
*ct
= DfFindCommand(wnd
->extension
, cmd
, DF_LISTBOX
);
473 int sel
= DfSendMessage(ct
->wnd
, DFM_LB_CURRENTSELECTION
, 0, 0);
474 DfSendMessage(ct
->wnd
, DFM_LB_GETTEXT
, (DF_PARAM
) text
, sel
);
477 /* -- find control structure associated with text control -- */
478 static DF_CTLWINDOW
*AssociatedControl(DF_DBOX
*db
,enum DfCommands Tcmd
)
480 DF_CTLWINDOW
*ct
= db
->ctl
;
482 if (ct
->class != DF_TEXT
)
483 if (ct
->command
== Tcmd
)
490 /* --- process dialog box shortcut keys --- */
491 static void dbShortcutKeys(DF_DBOX
*db
, int ky
)
494 int ch
= DfAltConvert(ky
);
499 char *cp
= ct
->itext
;
501 if (*cp
== DF_SHORTCUTCHAR
&&
502 tolower(*(cp
+1)) == ch
) {
503 if (ct
->class == DF_TEXT
)
504 ct
= AssociatedControl(db
, ct
->command
);
505 if (ct
->class == DF_RADIOBUTTON
)
506 DfSetRadioButton(db
, ct
);
507 else if (ct
->class == DF_CHECKBOX
) {
508 ct
->setting
^= DF_ON
;
509 DfSendMessage(ct
->wnd
, DFM_PAINT
, 0, 0);
511 else if (ct
->class) {
512 DfSendMessage(ct
->wnd
, DFM_SETFOCUS
, TRUE
, 0);
513 if (ct
->class == DF_BUTTON
)
514 DfSendMessage(ct
->wnd
,DFM_KEYBOARD
,'\r',0);
525 /* --- dynamically add or remove scroll bars
526 from a control window ---- */
527 void DfSetScrollBars(DFWINDOW wnd
)
529 int oldattr
= DfGetAttribute(wnd
);
530 if (wnd
->wlines
> DfClientHeight(wnd
))
531 DfAddAttribute(wnd
, DF_VSCROLLBAR
);
533 DfClearAttribute(wnd
, DF_VSCROLLBAR
);
534 if (wnd
->textwidth
> DfClientWidth(wnd
))
535 DfAddAttribute(wnd
, DF_HSCROLLBAR
);
537 DfClearAttribute(wnd
, DF_HSCROLLBAR
);
538 if (DfGetAttribute(wnd
) != oldattr
)
539 DfSendMessage(wnd
, DFM_BORDER
, 0, 0);
542 /* ------- DFM_CREATE_WINDOW Message (Control) ----- */
543 static void CtlCreateWindowMsg(DFWINDOW wnd
)
546 ct
= wnd
->ct
= wnd
->extension
;
547 wnd
->extension
= NULL
;
552 /* ------- DFM_KEYBOARD Message (Control) ----- */
553 static BOOL
CtlKeyboardMsg(DFWINDOW wnd
, DF_PARAM p1
, DF_PARAM p2
)
555 DF_CTLWINDOW
*ct
= DfGetControl(wnd
);
558 if (DfWindowMoving
|| DfWindowSizing
)
560 if (!DfDisplayHelp(wnd
, ct
->help
))
561 DfSendMessage(DfGetParent(wnd
),DFM_COMMAND
,DF_ID_HELP
,0);
564 if (!((int)p2
& DF_ALTKEY
))
569 DfPostMessage(DfGetParent(wnd
), DFM_KEYBOARD
, p1
, p2
);
574 if (DfGetClass(wnd
) == DF_EDITBOX
)
575 if (DfIsMultiLine(wnd
))
579 if (!DfIsDerivedFrom(wnd
, DF_LISTBOX
)) {
585 if (!DfIsDerivedFrom(wnd
, DF_EDITBOX
)) {
591 if (!DfIsDerivedFrom(wnd
, DF_LISTBOX
) &&
592 !DfIsDerivedFrom(wnd
, DF_COMBOBOX
))
596 if (!DfIsDerivedFrom(wnd
, DF_EDITBOX
))
600 if (DfIsDerivedFrom(wnd
, DF_EDITBOX
))
601 if (DfIsMultiLine(wnd
))
603 if (DfIsDerivedFrom(wnd
, DF_BUTTON
))
605 DfSendMessage(DfGetParent(wnd
), DFM_COMMAND
, DF_ID_OK
, 0);
613 /* ------- DFM_CLOSE_WINDOW Message (Control) ----- */
614 static void CtlCloseWindowMsg(DFWINDOW wnd
)
616 DF_CTLWINDOW
*ct
= DfGetControl(wnd
);
619 if (DfGetParent(wnd
)->ReturnCode
== DF_ID_OK
) {
620 if (ct
->class == DF_EDITBOX
|| ct
->class == DF_COMBOBOX
) {
621 if (wnd
->TextChanged
) {
622 ct
->itext
=DfRealloc(ct
->itext
,strlen(wnd
->text
)+1);
623 strcpy(ct
->itext
, wnd
->text
);
624 if (!DfIsMultiLine(wnd
)) {
625 char *cp
= ct
->itext
+strlen(ct
->itext
)-1;
631 else if (ct
->class == DF_RADIOBUTTON
|| ct
->class == DF_CHECKBOX
)
632 ct
->isetting
= ct
->setting
;
638 static void FixColors(DFWINDOW wnd
)
640 DF_CTLWINDOW
*ct
= wnd
->ct
;
642 if (ct
->class != DF_BUTTON
)
644 if (ct
->class != DF_SPINBUTTON
&& ct
->class != DF_COMBOBOX
)
646 wnd
->WindowColors
[DF_FRAME_COLOR
][DF_FG
] =
647 DfGetParent(wnd
)->WindowColors
[DF_FRAME_COLOR
][DF_FG
];
648 wnd
->WindowColors
[DF_FRAME_COLOR
][DF_BG
] =
649 DfGetParent(wnd
)->WindowColors
[DF_FRAME_COLOR
][DF_BG
];
650 if (ct
->class != DF_EDITBOX
&& ct
->class != DF_LISTBOX
)
652 wnd
->WindowColors
[DF_STD_COLOR
][DF_FG
] =
653 DfGetParent(wnd
)->WindowColors
[DF_STD_COLOR
][DF_FG
];
654 wnd
->WindowColors
[DF_STD_COLOR
][DF_BG
] =
655 DfGetParent(wnd
)->WindowColors
[DF_STD_COLOR
][DF_BG
];
662 /* -- generic window processor used by dialog box controls -- */
663 static int ControlProc(DFWINDOW wnd
,DFMESSAGE msg
,DF_PARAM p1
,DF_PARAM p2
)
669 db
= DfGetParent(wnd
) ? DfGetParent(wnd
)->extension
: NULL
;
672 case DFM_CREATE_WINDOW
:
673 CtlCreateWindowMsg(wnd
);
676 if (CtlKeyboardMsg(wnd
, p1
, p2
))
681 if (DfGetClass(wnd
) == DF_EDITBOX
||
682 DfGetClass(wnd
) == DF_LISTBOX
||
683 DfGetClass(wnd
) == DF_TEXTBOX
)
684 DfSetScrollBars(wnd
);
688 if (DfGetClass(wnd
) == DF_EDITBOX
) {
689 DFWINDOW oldFocus
= DfInFocus
;
691 DfDefaultWndProc(wnd
, msg
, p1
, p2
);
692 DfInFocus
= oldFocus
;
697 DFWINDOW pwnd
= DfGetParent(wnd
);
700 DfDefaultWndProc(wnd
, msg
, p1
, p2
);
704 DfSendMessage(pwnd
, DFM_COMMAND
,
705 inFocusCommand(db
), DFM_ENTERFOCUS
);
710 DfSendMessage(pwnd
, DFM_COMMAND
,
711 inFocusCommand(db
), DFM_LEAVEFOCUS
);
714 case DFM_CLOSE_WINDOW
:
715 CtlCloseWindowMsg(wnd
);
720 return DfDefaultWndProc(wnd
, msg
, p1
, p2
);
723 /* ---- change the focus to the first control --- */
724 static void FirstFocus(DF_DBOX
*db
)
726 DF_CTLWINDOW
*ct
= db
->ctl
;
729 while (ct
->class == DF_TEXT
|| ct
->class == DF_BOX
) {
734 DfSendMessage(ct
->wnd
, DFM_SETFOCUS
, TRUE
, 0);
738 /* ---- change the focus to the next control --- */
739 static void NextFocus(DF_DBOX
*db
)
741 DF_CTLWINDOW
*ct
= WindowControl(db
, DfInFocus
);
755 } while (ct
->class == DF_TEXT
|| ct
->class == DF_BOX
);
756 DfSendMessage(ct
->wnd
, DFM_SETFOCUS
, TRUE
, 0);
760 /* ---- change the focus to the previous control --- */
761 static void PrevFocus(DF_DBOX
*db
)
763 DF_CTLWINDOW
*ct
= WindowControl(db
, DfInFocus
);
778 } while (ct
->class == DF_TEXT
|| ct
->class == DF_BOX
);
779 DfSendMessage(ct
->wnd
, DFM_SETFOCUS
, TRUE
, 0);
783 void DfSetFocusCursor(DFWINDOW wnd
)
785 if (wnd
== DfInFocus
)
787 DfSendMessage(NULL
, DFM_SHOW_CURSOR
, 0, 0);
788 DfSendMessage(wnd
, DFM_KEYBOARD_CURSOR
, 1, 0);