📄 dialbox.c
字号:
/* ----------------- dialbox.c -------------- */
#include "dflat.h"
static int inFocusCommand(DBOX *);
static BOOL dbShortcutKeys(DBOX *, int);
static int ControlProc(WINDOW, MESSAGE, PARAM, PARAM);
static void FirstFocus(DBOX *db);
static void NextFocus(DBOX *db);
static void PrevFocus(DBOX *db);
static CTLWINDOW *AssociatedControl(DBOX *, enum commands);
static BOOL SysMenuOpen;
static DBOX **dbs = NULL;
static int dbct = 0;
/* --- clear all heap allocations to control text fields --- */
void ClearDialogBoxes(void)
{
int i;
for (i=0;i<dbct;i++)
{
CTLWINDOW *ct = (*(dbs+i))->ctl;
while (ct->Class)
{
if ((ct->Class == EDITBOX || ct->Class == TEXTBOX || ct->Class == COMBOBOX) && ct->itext != NULL)
{
free(ct->itext);
ct->itext = NULL;
}
ct++;
}
}
if (dbs != NULL)
{
free(dbs);
dbs = NULL;
}
dbct = 0;
}
/* -------- CREATE_WINDOW Message --------- */
static int CreateWindowMsg(WINDOW wnd, PARAM p1, PARAM p2)
{
DBOX *db = wnd->extension;
CTLWINDOW *ct = db->ctl;
WINDOW cwnd;
int rtn, i;
/* ---- build a table of processed dialog boxes ---- */
for (i=0;i<dbct;i++)
if (db == dbs[i])
break;
if (i == dbct)
{
dbs = DFrealloc(dbs, sizeof(DBOX *) * (dbct+1));
*(dbs + dbct++) = db;
}
rtn = BaseWndProc(DIALOG, wnd, CREATE_WINDOW, p1, p2);
ct = db->ctl;
while (ct->Class)
{
int attrib = 0;
if (TestAttribute(wnd, NOCLIP))
attrib |= NOCLIP;
if (wnd->Modal)
attrib |= SAVESELF;
ct->setting = ct->isetting;
if (ct->Class == EDITBOX && ct->dwnd.h > 1)
attrib |= (MULTILINE | HASBORDER);
else if ((ct->Class == LISTBOX || ct->Class == TEXTBOX) && ct->dwnd.h > 2)
attrib |= HASBORDER;
cwnd = CreateWindow(ct->Class,
ct->dwnd.title,
ct->dwnd.x+GetClientLeft(wnd),
ct->dwnd.y+GetClientTop(wnd),
ct->dwnd.h,
ct->dwnd.w,
ct,
wnd,
ControlProc,
attrib);
if ((ct->Class == EDITBOX || ct->Class == TEXTBOX ||
ct->Class == COMBOBOX) && ct->itext != NULL)
SendMessage(cwnd, SETTEXT, (PARAM) ct->itext, 0);
ct++;
}
return rtn;
}
/* -------- LEFT_BUTTON Message --------- */
static BOOL LeftButtonMsg(WINDOW wnd, PARAM p1, PARAM p2)
{
DBOX *db = wnd->extension;
CTLWINDOW *ct = db->ctl;
if (WindowSizing || WindowMoving)
return TRUE;
if (HitControlBox(wnd, p1-GetLeft(wnd), p2-GetTop(wnd))) {
PostMessage(wnd, KEYBOARD, ' ', ALTKEY);
return TRUE;
}
while (ct->Class) {
WINDOW cwnd = ct->wnd;
if (ct->Class == COMBOBOX) {
if (p2 == GetTop(cwnd)) {
if (p1 == GetRight(cwnd)+1) {
SendMessage(cwnd, LEFT_BUTTON, p1, p2);
return TRUE;
}
}
if (GetClass(inFocus) == LISTBOX)
SendMessage(wnd, SETFOCUS, TRUE, 0);
}
else if (ct->Class == SPINBUTTON) {
if (p2 == GetTop(cwnd)) {
if (p1 == GetRight(cwnd)+1 ||
p1 == GetRight(cwnd)+2) {
SendMessage(cwnd, LEFT_BUTTON, p1, p2);
return TRUE;
}
}
}
ct++;
}
return FALSE;
}
/* -------- KEYBOARD Message --------- */
static BOOL KeyboardMsg(WINDOW wnd, PARAM p1, PARAM p2)
{
DBOX *db = wnd->extension;
CTLWINDOW *ct;
if (WindowMoving || WindowSizing)
return FALSE;
switch ((int)p1)
{
case F1:
ct = GetControl(inFocus);
if (ct != NULL)
if (DisplayHelp(wnd, ct->help))
return TRUE;
break;
case SHIFT_HT:
case LARROW:
case UP:
PrevFocus(db);
break;
case ALT_F6:
case '\t':
case FWD:
case DN:
NextFocus(db);
break;
case ' ':
if (((int)p2 & ALTKEY) && TestAttribute(wnd, CONTROLBOX))
{
SysMenuOpen = TRUE;
BuildSystemMenu(wnd);
return TRUE;
}
break;
case CTRL_F4:
case ESC:
SendMessage(wnd, COMMAND, ID_CANCEL, 0);
break;
default:
/* ------ search all the shortcut keys ----- */
if (dbShortcutKeys(db, (int) p1))
return TRUE;
break;
}
return wnd->Modal;
}
/* -------- COMMAND Message --------- */
static BOOL CommandMsg(WINDOW wnd, PARAM p1, PARAM p2)
{
DBOX *db = wnd->extension;
switch ((int) p1)
{
case ID_OK:
case ID_CANCEL:
if ((int)p2 != 0)
return TRUE;
wnd->ReturnCode = (int) p1;
if (wnd->Modal)
PostMessage(wnd, ENDDIALOG, 0, 0);
else
SendMessage(wnd, CLOSE_WINDOW, TRUE, 0);
return TRUE;
case ID_THREE:
if ((int)p2 != 0)
return FALSE;
wnd->ReturnCode = (int) p1;
PostMessage(wnd, ENDDIALOG, 0, 0);
SendMessage(wnd, PAINT, 0, 0);
return FALSE;
case ID_HELP:
if ((int)p2 != 0)
return TRUE;
return DisplayHelp(wnd, db->HelpName);
default:
break;
}
return FALSE;
}
/* ----- window-processing module, DIALOG window class ----- */
int DialogProc(WINDOW wnd, MESSAGE msg, PARAM p1, PARAM p2)
{
int rtn;
DBOX *db = wnd->extension;
switch (msg) {
case CREATE_WINDOW:
return CreateWindowMsg(wnd, p1, p2);
case SHIFT_CHANGED:
if (wnd->Modal)
return TRUE;
break;
case LEFT_BUTTON:
if (LeftButtonMsg(wnd, p1, p2))
return TRUE;
break;
case KEYBOARD:
if (KeyboardMsg(wnd, p1, p2))
return TRUE;
break;
case CLOSE_POPDOWN:
SysMenuOpen = FALSE;
break;
case LB_SELECTION:
case LB_CHOOSE:
if (SysMenuOpen)
return TRUE;
SendMessage(wnd, COMMAND, inFocusCommand(db), msg);
break;
case SETFOCUS:
if ((int)p1 && wnd->dfocus != NULL && isVisible(wnd))
return SendMessage(wnd->dfocus, SETFOCUS, TRUE, 0);
break;
case COMMAND:
if (CommandMsg(wnd, p1, p2))
return TRUE;
break;
case PAINT:
p2 = TRUE;
break;
case MOVE:
case SIZE:
rtn = BaseWndProc(DIALOG, wnd, msg, p1, p2);
if (wnd->dfocus != NULL && isVisible(wnd))
SendMessage(wnd->dfocus, SETFOCUS, TRUE, 0);
return rtn;
case CLOSE_WINDOW:
if (!p1) {
SendMessage(wnd, COMMAND, ID_CANCEL, 0);
return TRUE;
}
break;
default:
break;
}
return BaseWndProc(DIALOG, wnd, msg, p1, p2);
}
/* ------- create and execute a dialog box ---------- */
BOOL DialogBox(WINDOW wnd, DBOX *db, BOOL Modal,
int (*wndproc)(struct window *, enum messages, PARAM, PARAM))
{
BOOL rtn = FALSE;
int x = db->dwnd.x, y = db->dwnd.y;
WINDOW DialogWnd;
DialogWnd = CreateWindow(DIALOG,
db->dwnd.title,
x, y,
db->dwnd.h,
db->dwnd.w,
db,
wnd,
wndproc,
(Modal ? SAVESELF : 0));
SendMessage(DialogWnd, SETFOCUS, TRUE, 0);
DialogWnd->Modal = Modal;
FirstFocus(db);
PostMessage(DialogWnd, INITIATE_DIALOG, 0, 0);
if (Modal) {
SendMessage(DialogWnd, CAPTURE_MOUSE, 0, 0);
SendMessage(DialogWnd, CAPTURE_KEYBOARD, 0, 0);
while (dispatch_message())
;
rtn = DialogWnd->ReturnCode == ID_OK;
SendMessage(DialogWnd, RELEASE_MOUSE, 0, 0);
SendMessage(DialogWnd, RELEASE_KEYBOARD, 0, 0);
SendMessage(DialogWnd, CLOSE_WINDOW, TRUE, 0);
}
return rtn;
}
/* ----- return command code of in-focus control window ---- */
static int inFocusCommand(DBOX *db)
{
CTLWINDOW *ct = db->ctl;
while (ct->Class) {
if (ct->wnd == inFocus)
return ct->command;
ct++;
}
return -1;
}
/* -------- find a specified control structure ------- */
CTLWINDOW *FindCommand(DBOX *db, enum commands cmd, int Class)
{
CTLWINDOW *ct = db->ctl;
while (ct->Class) {
if (Class == -1 || ct->Class == Class)
if (cmd == ct->command)
return ct;
ct++;
}
return NULL;
}
/* ---- return the window handle of a specified command ---- */
WINDOW ControlWindow(const DBOX *db, enum commands cmd)
{
const CTLWINDOW *ct = db->ctl;
while (ct->Class) {
if (ct->Class != TEXT && cmd == ct->command)
return ct->wnd;
ct++;
}
return NULL;
}
/* --- return a pointer to the control structure that matches a window --- */
CTLWINDOW *WindowControl(DBOX *db, WINDOW wnd)
{
CTLWINDOW *ct = db->ctl;
while (ct->Class) {
if (ct->wnd == wnd)
return ct;
ct++;
}
return NULL;
}
/* ---- set a control ON or OFF ----- */
void ControlSetting(DBOX *db, enum commands cmd,
int Class, int setting)
{
CTLWINDOW *ct = FindCommand(db, cmd, Class);
if (ct != NULL) {
ct->isetting = setting;
if (ct->wnd != NULL)
ct->setting = setting;
}
}
/* ----- test if a control is on or off ----- */
BOOL isControlOn(DBOX *db, enum commands cmd, int Class)
{
const CTLWINDOW *ct = FindCommand(db, cmd, Class);
return ct ? (ct->wnd ? ct->setting : ct->isetting) : FALSE;
}
/* ---- return pointer to the text of a control window ---- */
char *GetDlgTextString(DBOX *db,enum commands cmd,CLASS Class)
{
CTLWINDOW *ct = FindCommand(db, cmd, Class);
if (ct != NULL)
return ct->itext;
else
return NULL;
}
/* ------- set the text of a control specification ------ */
void SetDlgTextString(DBOX *db, enum commands cmd,
char *text, CLASS Class)
{
CTLWINDOW *ct = FindCommand(db, cmd, Class);
if (ct != NULL) {
if (text != NULL) {
if (ct->Class == TEXT)
ct->itext = text; /* text may not go out of scope */
else {
ct->itext = DFrealloc(ct->itext, strlen(text)+1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -