mirror of
https://github.com/reactos/reactos.git
synced 2024-08-18 17:37:02 +00:00
1086 lines
31 KiB
C
1086 lines
31 KiB
C
/* ------------- normal.c ------------ */
|
|
|
|
#include "dflat.h"
|
|
|
|
#ifdef INCLUDE_MULTI_WINDOWS
|
|
static void PaintOverLappers(DFWINDOW wnd);
|
|
static void PaintUnderLappers(DFWINDOW wnd);
|
|
#endif
|
|
|
|
static BOOL InsideWindow(DFWINDOW, int, int);
|
|
static void TerminateMoveSize(void);
|
|
static void SaveBorder(DFRECT);
|
|
static void RestoreBorder(DFRECT);
|
|
static void GetVideoBuffer(DFWINDOW);
|
|
static void PutVideoBuffer(DFWINDOW);
|
|
#ifdef INCLUDE_MINIMIZE
|
|
static DFRECT PositionIcon(DFWINDOW);
|
|
#endif
|
|
static void dragborder(DFWINDOW, int, int);
|
|
static void sizeborder(DFWINDOW, int, int);
|
|
static int px = -1, py = -1;
|
|
static int diff;
|
|
static struct DfWindow dwnd = {DF_DUMMY, NULL, DfNormalProc,
|
|
{{-1},{-1},{-1},{-1}}};
|
|
static PCHAR_INFO Bsave;
|
|
static int Bht, Bwd;
|
|
BOOL DfWindowMoving;
|
|
BOOL DfWindowSizing;
|
|
/* -------- array of class definitions -------- */
|
|
DFCLASSDEFS DfClassDefs[] = {
|
|
#undef DfClassDef
|
|
#define DfClassDef(c,b,p,a) {b,p,a},
|
|
#include "classes.h"
|
|
};
|
|
DFWINDOW HiddenWindow;
|
|
|
|
/* --------- DFM_CREATE_WINDOW Message ---------- */
|
|
static void CreateWindowMsg(DFWINDOW wnd)
|
|
{
|
|
DfAppendWindow(wnd);
|
|
// DfClearAttribute(wnd, DF_VSCROLLBAR | DF_HSCROLLBAR);
|
|
if (DfTestAttribute(wnd, DF_SAVESELF) && DfIsVisible(wnd))
|
|
GetVideoBuffer(wnd);
|
|
}
|
|
|
|
/* --------- DFM_SHOW_WINDOW Message ---------- */
|
|
static void ShowWindowMsg(DFWINDOW wnd, DF_PARAM p1, DF_PARAM p2)
|
|
{
|
|
if (DfGetParent(wnd) == NULL || DfIsVisible(DfGetParent(wnd)))
|
|
{
|
|
DFWINDOW cwnd;
|
|
|
|
if (DfTestAttribute(wnd, DF_SAVESELF) && wnd->videosave == NULL)
|
|
GetVideoBuffer(wnd);
|
|
DfSetVisible(wnd);
|
|
DfSendMessage(wnd, DFM_PAINT, 0, TRUE);
|
|
DfSendMessage(wnd, DFM_BORDER, 0, 0);
|
|
/* --- show the children of this window --- */
|
|
cwnd = DfFirstWindow(wnd);
|
|
while (cwnd != NULL)
|
|
{
|
|
if (cwnd->condition != DF_ISCLOSING)
|
|
DfSendMessage(cwnd, DFM_SHOW_WINDOW, p1, p2);
|
|
cwnd = DfNextWindow(cwnd);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* --------- HIDE_WINDOW Message ---------- */
|
|
static void HideWindowMsg(DFWINDOW wnd)
|
|
{
|
|
if (DfIsVisible(wnd))
|
|
{
|
|
DfClearVisible(wnd);
|
|
/* --- paint what this window covered --- */
|
|
if (DfTestAttribute(wnd, DF_SAVESELF))
|
|
PutVideoBuffer(wnd);
|
|
#ifdef INCLUDE_MULTI_WINDOWS
|
|
else
|
|
PaintOverLappers(wnd);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
/* --------- DFM_KEYBOARD Message ---------- */
|
|
static BOOL KeyboardMsg(DFWINDOW wnd, DF_PARAM p1, DF_PARAM p2)
|
|
{
|
|
if (DfWindowMoving || DfWindowSizing) {
|
|
/* -- move or size a window with keyboard -- */
|
|
int x, y;
|
|
x=DfWindowMoving?DfGetLeft(&dwnd):DfGetRight(&dwnd);
|
|
y=DfWindowMoving?DfGetTop(&dwnd):DfGetBottom(&dwnd);
|
|
switch ((int)p1) {
|
|
case DF_ESC:
|
|
TerminateMoveSize();
|
|
return TRUE;
|
|
case DF_UP:
|
|
if (y)
|
|
--y;
|
|
break;
|
|
case DF_DN:
|
|
if (y < DfGetScreenHeight()-1)
|
|
y++;
|
|
break;
|
|
case DF_FWD:
|
|
if (x < DfGetScreenWidth()-1)
|
|
x++;
|
|
break;
|
|
case DF_BS:
|
|
if (x)
|
|
--x;
|
|
break;
|
|
case '\r':
|
|
DfSendMessage(wnd, DFM_BUTTON_RELEASED,x,y);
|
|
default:
|
|
return TRUE;
|
|
}
|
|
/* -- use the mouse functions to move/size - */
|
|
DfSendMessage(wnd, MOUSE_MOVED, x, y);
|
|
return TRUE;
|
|
}
|
|
|
|
switch ((int)p1)
|
|
{
|
|
case DF_F1:
|
|
DfSendMessage(wnd, DFM_COMMAND, DF_ID_HELP, 0);
|
|
return TRUE;
|
|
|
|
case ' ':
|
|
if ((int)p2 & DF_ALTKEY)
|
|
if (DfTestAttribute(wnd, DF_HASTITLEBAR))
|
|
if (DfTestAttribute(wnd, DF_CONTROLBOX))
|
|
DfBuildSystemMenu(wnd);
|
|
return TRUE;
|
|
|
|
case DF_CTRL_F4:
|
|
if (DfTestAttribute(wnd, DF_CONTROLBOX))
|
|
{
|
|
DfSendMessage(wnd, DFM_CLOSE_WINDOW, 0, 0);
|
|
DfSkipApplicationControls();
|
|
return TRUE;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
/* --------- COMMAND Message ---------- */
|
|
static void CommandMsg(DFWINDOW wnd, DF_PARAM p1)
|
|
{
|
|
switch ((int)p1) {
|
|
case DF_ID_HELP:
|
|
DfDisplayHelp(wnd,DfClassNames[DfGetClass(wnd)]);
|
|
break;
|
|
#ifdef INCLUDE_RESTORE
|
|
case DF_ID_SYSRESTORE:
|
|
DfSendMessage(wnd, DFM_RESTORE, 0, 0);
|
|
break;
|
|
#endif
|
|
case DF_ID_SYSMOVE:
|
|
DfSendMessage(wnd, DFM_CAPTURE_MOUSE, TRUE,
|
|
(DF_PARAM) &dwnd);
|
|
DfSendMessage(wnd, DFM_CAPTURE_KEYBOARD, TRUE,
|
|
(DF_PARAM) &dwnd);
|
|
DfWindowMoving = TRUE;
|
|
dragborder(wnd, DfGetLeft(wnd), DfGetTop(wnd));
|
|
break;
|
|
case DF_ID_SYSSIZE:
|
|
DfSendMessage(wnd, DFM_CAPTURE_MOUSE, TRUE,
|
|
(DF_PARAM) &dwnd);
|
|
DfSendMessage(wnd, DFM_CAPTURE_KEYBOARD, TRUE,
|
|
(DF_PARAM) &dwnd);
|
|
DfWindowSizing = TRUE;
|
|
dragborder(wnd, DfGetLeft(wnd), DfGetTop(wnd));
|
|
break;
|
|
#ifdef INCLUDE_MINIMIZE
|
|
case DF_ID_SYSMINIMIZE:
|
|
DfSendMessage(wnd, DFM_MINIMIZE, 0, 0);
|
|
break;
|
|
#endif
|
|
#ifdef INCLUDE_MAXIMIZE
|
|
case DF_ID_SYSMAXIMIZE:
|
|
DfSendMessage(wnd, DFM_MAXIMIZE, 0, 0);
|
|
break;
|
|
#endif
|
|
case DF_ID_SYSCLOSE:
|
|
DfSendMessage(wnd, DFM_CLOSE_WINDOW, 0, 0);
|
|
DfSkipApplicationControls();
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* --------- DFM_SETFOCUS Message ---------- */
|
|
static void SetFocusMsg(DFWINDOW wnd, DF_PARAM p1)
|
|
{
|
|
DFRECT rc = {0,0,0,0};
|
|
|
|
if (p1 && wnd != NULL && DfInFocus != wnd)
|
|
{
|
|
DFWINDOW this, thispar;
|
|
DFWINDOW that = NULL, thatpar = NULL;
|
|
|
|
DFWINDOW cwnd = wnd, fwnd = DfGetParent(wnd);
|
|
/* ---- post focus in ancestors ---- */
|
|
while (fwnd != NULL)
|
|
{
|
|
fwnd->childfocus = cwnd;
|
|
cwnd = fwnd;
|
|
fwnd = DfGetParent(fwnd);
|
|
}
|
|
/* ---- de-post focus in self and children ---- */
|
|
fwnd = wnd;
|
|
while (fwnd != NULL)
|
|
{
|
|
cwnd = fwnd->childfocus;
|
|
fwnd->childfocus = NULL;
|
|
fwnd = cwnd;
|
|
}
|
|
|
|
this = wnd;
|
|
that = thatpar = DfInFocus;
|
|
|
|
/* ---- find common ancestor of prev focus and this window --- */
|
|
while (thatpar != NULL)
|
|
{
|
|
thispar = wnd;
|
|
while (thispar != NULL)
|
|
{
|
|
if (this == DfCaptureMouse || this == DfCaptureKeyboard)
|
|
{
|
|
/* ---- don't repaint if this window has capture ---- */
|
|
that = thatpar = NULL;
|
|
break;
|
|
}
|
|
if (thispar == thatpar)
|
|
{
|
|
/* ---- don't repaint if DF_SAVESELF window had focus ---- */
|
|
if (this != that && DfTestAttribute(that, DF_SAVESELF))
|
|
that = thatpar = NULL;
|
|
break;
|
|
}
|
|
this = thispar;
|
|
thispar = DfGetParent(thispar);
|
|
}
|
|
if (thispar != NULL)
|
|
break;
|
|
that = thatpar;
|
|
thatpar = DfGetParent(thatpar);
|
|
}
|
|
if (DfInFocus != NULL)
|
|
DfSendMessage(DfInFocus, DFM_SETFOCUS, FALSE, 0);
|
|
DfInFocus = wnd;
|
|
if (that != NULL && DfIsVisible(wnd))
|
|
{
|
|
rc = DfSubRectangle(DfWindowRect(that), DfWindowRect(this));
|
|
if (!DfValidRect(rc))
|
|
{
|
|
if (DfApplicationWindow != NULL)
|
|
{
|
|
DFWINDOW fwnd = DfFirstWindow(DfApplicationWindow);
|
|
while (fwnd != NULL)
|
|
{
|
|
if (!DfIsAncestor(wnd, fwnd))
|
|
{
|
|
rc = DfSubRectangle(DfWindowRect(wnd),DfWindowRect(fwnd));
|
|
if (DfValidRect(rc))
|
|
break;
|
|
}
|
|
fwnd = DfNextWindow(fwnd);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (that != NULL && !DfValidRect(rc) && DfIsVisible(wnd))
|
|
{
|
|
DfSendMessage(wnd, DFM_BORDER, 0, 0);
|
|
this = NULL;
|
|
}
|
|
DfReFocus(wnd);
|
|
if (this != NULL)
|
|
DfSendMessage(this, DFM_SHOW_WINDOW, 0, 0);
|
|
}
|
|
else if (!p1 && DfInFocus == wnd)
|
|
{
|
|
/* clearing focus */
|
|
DfInFocus = NULL;
|
|
DfSendMessage(wnd, DFM_BORDER, 0, 0);
|
|
}
|
|
}
|
|
|
|
/* --------- DOUBLE_CLICK Message ---------- */
|
|
static void DoubleClickMsg(DFWINDOW wnd, DF_PARAM p1, DF_PARAM p2)
|
|
{
|
|
int mx = (int) p1 - DfGetLeft(wnd);
|
|
int my = (int) p2 - DfGetTop(wnd);
|
|
if (!DfWindowSizing && !DfWindowMoving) {
|
|
if (DfHitControlBox(wnd, mx, my)) {
|
|
DfPostMessage(wnd, DFM_CLOSE_WINDOW, 0, 0);
|
|
DfSkipApplicationControls();
|
|
}
|
|
}
|
|
}
|
|
|
|
/* --------- DFM_LEFT_BUTTON Message ---------- */
|
|
static void LeftButtonMsg(DFWINDOW wnd, DF_PARAM p1, DF_PARAM p2)
|
|
{
|
|
int mx = (int) p1 - DfGetLeft(wnd);
|
|
int my = (int) p2 - DfGetTop(wnd);
|
|
if (DfWindowSizing || DfWindowMoving)
|
|
return;
|
|
if (DfHitControlBox(wnd, mx, my)) {
|
|
DfBuildSystemMenu(wnd);
|
|
return;
|
|
}
|
|
if (my == 0 && mx > -1 && mx < DfWindowWidth(wnd)) {
|
|
/* ---------- hit the top border -------- */
|
|
if (DfTestAttribute(wnd, DF_MINMAXBOX) &&
|
|
DfTestAttribute(wnd, DF_HASTITLEBAR)) {
|
|
if (mx == DfWindowWidth(wnd)-2) {
|
|
if (wnd->condition != DF_SRESTORED)
|
|
/* --- hit the restore box --- */
|
|
DfSendMessage(wnd, DFM_RESTORE, 0, 0);
|
|
#ifdef INCLUDE_MAXIMIZE
|
|
else
|
|
/* --- hit the maximize box --- */
|
|
DfSendMessage(wnd, DFM_MAXIMIZE, 0, 0);
|
|
#endif
|
|
return;
|
|
}
|
|
#ifdef INCLUDE_MINIMIZE
|
|
if (mx == DfWindowWidth(wnd)-3) {
|
|
/* --- hit the minimize box --- */
|
|
if (wnd->condition != DF_ISMINIMIZED)
|
|
DfSendMessage(wnd, DFM_MINIMIZE, 0, 0);
|
|
return;
|
|
}
|
|
#endif
|
|
}
|
|
#ifdef INCLUDE_MAXIMIZE
|
|
if (wnd->condition == DF_ISMAXIMIZED)
|
|
return;
|
|
#endif
|
|
if (DfTestAttribute(wnd, DF_MOVEABLE)) {
|
|
DfWindowMoving = TRUE;
|
|
px = mx;
|
|
py = my;
|
|
diff = (int) mx;
|
|
DfSendMessage(wnd, DFM_CAPTURE_MOUSE, TRUE,
|
|
(DF_PARAM) &dwnd);
|
|
dragborder(wnd, DfGetLeft(wnd), DfGetTop(wnd));
|
|
}
|
|
return;
|
|
}
|
|
if (mx == DfWindowWidth(wnd)-1 &&
|
|
my == DfWindowHeight(wnd)-1) {
|
|
/* ------- hit the resize corner ------- */
|
|
#ifdef INCLUDE_MINIMIZE
|
|
if (wnd->condition == DF_ISMINIMIZED)
|
|
return;
|
|
#endif
|
|
if (!DfTestAttribute(wnd, DF_SIZEABLE))
|
|
return;
|
|
#ifdef INCLUDE_MAXIMIZE
|
|
if (wnd->condition == DF_ISMAXIMIZED) {
|
|
if (DfGetParent(wnd) == NULL)
|
|
return;
|
|
if (DfTestAttribute(DfGetParent(wnd),DF_HASBORDER))
|
|
return;
|
|
/* ----- resizing a maximized window over a
|
|
borderless parent ----- */
|
|
wnd = DfGetParent(wnd);
|
|
}
|
|
#endif
|
|
DfWindowSizing = TRUE;
|
|
DfSendMessage(wnd, DFM_CAPTURE_MOUSE,
|
|
TRUE, (DF_PARAM) &dwnd);
|
|
dragborder(wnd, DfGetLeft(wnd), DfGetTop(wnd));
|
|
}
|
|
}
|
|
|
|
/* --------- MOUSE_MOVED Message ---------- */
|
|
static BOOL MouseMovedMsg(DFWINDOW wnd, DF_PARAM p1, DF_PARAM p2)
|
|
{
|
|
if (DfWindowMoving) {
|
|
int leftmost = 0, topmost = 0,
|
|
bottommost = DfGetScreenHeight()-2,
|
|
rightmost = DfGetScreenWidth()-2;
|
|
int x = (int) p1 - diff;
|
|
int y = (int) p2;
|
|
if (DfGetParent(wnd) != NULL &&
|
|
!DfTestAttribute(wnd, DF_NOCLIP)) {
|
|
DFWINDOW wnd1 = DfGetParent(wnd);
|
|
topmost = DfGetClientTop(wnd1);
|
|
leftmost = DfGetClientLeft(wnd1);
|
|
bottommost = DfGetClientBottom(wnd1);
|
|
rightmost = DfGetClientRight(wnd1);
|
|
}
|
|
if (x < leftmost || x > rightmost ||
|
|
y < topmost || y > bottommost) {
|
|
x = max(x, leftmost);
|
|
x = min(x, rightmost);
|
|
y = max(y, topmost);
|
|
y = min(y, bottommost);
|
|
}
|
|
|
|
if (x != px || y != py) {
|
|
px = x;
|
|
py = y;
|
|
dragborder(wnd, x, y);
|
|
}
|
|
return TRUE;
|
|
}
|
|
if (DfWindowSizing) {
|
|
sizeborder(wnd, (int) p1, (int) p2);
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
#ifdef INCLUDE_MAXIMIZE
|
|
/* --------- DFM_MAXIMIZE Message ---------- */
|
|
static void MaximizeMsg(DFWINDOW wnd)
|
|
{
|
|
DFRECT rc = {0, 0, 0, 0};
|
|
DFRECT holdrc;
|
|
holdrc = wnd->RestoredRC;
|
|
rc.rt = DfGetScreenWidth()-1;
|
|
rc.bt = DfGetScreenHeight()-1;
|
|
if (DfGetParent(wnd))
|
|
rc = DfClientRect(DfGetParent(wnd));
|
|
wnd->oldcondition = wnd->condition;
|
|
wnd->condition = DF_ISMAXIMIZED;
|
|
DfSendMessage(wnd, DFM_HIDE_WINDOW, 0, 0);
|
|
DfSendMessage(wnd, DFM_MOVE,
|
|
DfRectLeft(rc), DfRectTop(rc));
|
|
DfSendMessage(wnd, DFM_DFM_SIZE,
|
|
DfRectRight(rc), DfRectBottom(rc));
|
|
if (wnd->restored_attrib == 0)
|
|
wnd->restored_attrib = wnd->attrib;
|
|
DfClearAttribute(wnd, DF_SHADOW);
|
|
DfSendMessage(wnd, DFM_SHOW_WINDOW, 0, 0);
|
|
wnd->RestoredRC = holdrc;
|
|
}
|
|
#endif
|
|
|
|
#ifdef INCLUDE_MINIMIZE
|
|
/* --------- DFM_MINIMIZE Message ---------- */
|
|
static void MinimizeMsg(DFWINDOW wnd)
|
|
{
|
|
DFRECT rc;
|
|
DFRECT holdrc;
|
|
|
|
holdrc = wnd->RestoredRC;
|
|
rc = PositionIcon(wnd);
|
|
wnd->oldcondition = wnd->condition;
|
|
wnd->condition = DF_ISMINIMIZED;
|
|
DfSendMessage(wnd, DFM_HIDE_WINDOW, 0, 0);
|
|
DfSendMessage(wnd, DFM_MOVE,
|
|
DfRectLeft(rc), DfRectTop(rc));
|
|
DfSendMessage(wnd, DFM_DFM_SIZE,
|
|
DfRectRight(rc), DfRectBottom(rc));
|
|
if (wnd == DfInFocus)
|
|
DfSetNextFocus();
|
|
if (wnd->restored_attrib == 0)
|
|
wnd->restored_attrib = wnd->attrib;
|
|
DfClearAttribute(wnd,
|
|
DF_SHADOW | DF_SIZEABLE | DF_HASMENUBAR |
|
|
DF_VSCROLLBAR | DF_HSCROLLBAR);
|
|
DfSendMessage(wnd, DFM_SHOW_WINDOW, 0, 0);
|
|
wnd->RestoredRC = holdrc;
|
|
}
|
|
#endif
|
|
|
|
#ifdef INCLUDE_RESTORE
|
|
/* --------- DFM_RESTORE Message ---------- */
|
|
static void RestoreMsg(DFWINDOW wnd)
|
|
{
|
|
DFRECT holdrc;
|
|
holdrc = wnd->RestoredRC;
|
|
wnd->oldcondition = wnd->condition;
|
|
wnd->condition = DF_SRESTORED;
|
|
DfSendMessage(wnd, DFM_HIDE_WINDOW, 0, 0);
|
|
wnd->attrib = wnd->restored_attrib;
|
|
wnd->restored_attrib = 0;
|
|
DfSendMessage(wnd, DFM_MOVE, wnd->RestoredRC.lf,
|
|
wnd->RestoredRC.tp);
|
|
wnd->RestoredRC = holdrc;
|
|
DfSendMessage(wnd, DFM_DFM_SIZE, wnd->RestoredRC.rt,
|
|
wnd->RestoredRC.bt);
|
|
if (wnd != DfInFocus)
|
|
DfSendMessage(wnd, DFM_SETFOCUS, TRUE, 0);
|
|
else
|
|
DfSendMessage(wnd, DFM_SHOW_WINDOW, 0, 0);
|
|
}
|
|
#endif
|
|
|
|
/* --------- DFM_MOVE Message ---------- */
|
|
static void MoveMsg(DFWINDOW wnd, DF_PARAM p1, DF_PARAM p2)
|
|
{
|
|
DFWINDOW cwnd;
|
|
BOOL wasVisible = DfIsVisible(wnd);
|
|
int xdif = (int) p1 - wnd->rc.lf;
|
|
int ydif = (int) p2 - wnd->rc.tp;
|
|
|
|
if (xdif == 0 && ydif == 0)
|
|
return;
|
|
if (wasVisible)
|
|
DfSendMessage(wnd, DFM_HIDE_WINDOW, 0, 0);
|
|
wnd->rc.lf = (int) p1;
|
|
wnd->rc.tp = (int) p2;
|
|
wnd->rc.rt = DfGetLeft(wnd)+DfWindowWidth(wnd)-1;
|
|
wnd->rc.bt = DfGetTop(wnd)+DfWindowHeight(wnd)-1;
|
|
if (wnd->condition == DF_SRESTORED)
|
|
wnd->RestoredRC = wnd->rc;
|
|
|
|
cwnd = DfFirstWindow(wnd);
|
|
while (cwnd != NULL) {
|
|
DfSendMessage(cwnd, DFM_MOVE, cwnd->rc.lf+xdif, cwnd->rc.tp+ydif);
|
|
cwnd = DfNextWindow(cwnd);
|
|
}
|
|
if (wasVisible)
|
|
DfSendMessage(wnd, DFM_SHOW_WINDOW, 0, 0);
|
|
}
|
|
|
|
/* --------- SIZE Message ---------- */
|
|
static void SizeMsg(DFWINDOW wnd, DF_PARAM p1, DF_PARAM p2)
|
|
{
|
|
BOOL wasVisible = DfIsVisible(wnd);
|
|
DFWINDOW cwnd;
|
|
DFRECT rc;
|
|
int xdif = (int) p1 - wnd->rc.rt;
|
|
int ydif = (int) p2 - wnd->rc.bt;
|
|
|
|
if (xdif == 0 && ydif == 0)
|
|
return;
|
|
if (wasVisible)
|
|
DfSendMessage(wnd, DFM_HIDE_WINDOW, 0, 0);
|
|
wnd->rc.rt = (int) p1;
|
|
wnd->rc.bt = (int) p2;
|
|
wnd->ht = DfGetBottom(wnd)-DfGetTop(wnd)+1;
|
|
wnd->wd = DfGetRight(wnd)-DfGetLeft(wnd)+1;
|
|
|
|
if (wnd->condition == DF_SRESTORED)
|
|
wnd->RestoredRC = DfWindowRect(wnd);
|
|
|
|
#ifdef INCLUDE_MAXIMIZE
|
|
rc = DfClientRect(wnd);
|
|
|
|
cwnd = DfFirstWindow(wnd);
|
|
while (cwnd != NULL) {
|
|
if (cwnd->condition == DF_ISMAXIMIZED)
|
|
DfSendMessage(cwnd, DFM_DFM_SIZE, DfRectRight(rc), DfRectBottom(rc));
|
|
cwnd = DfNextWindow(cwnd);
|
|
}
|
|
|
|
#endif
|
|
if (wasVisible)
|
|
DfSendMessage(wnd, DFM_SHOW_WINDOW, 0, 0);
|
|
}
|
|
|
|
/* --------- DFM_CLOSE_WINDOW Message ---------- */
|
|
static void CloseWindowMsg(DFWINDOW wnd)
|
|
{
|
|
DFWINDOW cwnd;
|
|
wnd->condition = DF_ISCLOSING;
|
|
if (wnd->PrevMouse != NULL)
|
|
DfSendMessage(wnd, DFM_RELEASE_MOUSE, 0, 0);
|
|
if (wnd->PrevKeyboard != NULL)
|
|
DfSendMessage(wnd, DFM_RELEASE_KEYBOARD, 0, 0);
|
|
/* ----------- hide this window ------------ */
|
|
DfSendMessage(wnd, DFM_HIDE_WINDOW, 0, 0);
|
|
/* --- close the children of this window --- */
|
|
|
|
cwnd = DfLastWindow(wnd);
|
|
while (cwnd != NULL) {
|
|
if (DfInFocus == cwnd)
|
|
DfInFocus = wnd;
|
|
DfSendMessage(cwnd,DFM_CLOSE_WINDOW,0,0);
|
|
cwnd = DfLastWindow(wnd);
|
|
}
|
|
|
|
/* --- change focus if this window had it -- */
|
|
if (wnd == DfInFocus)
|
|
DfSetPrevFocus();
|
|
/* -- free memory allocated to this window - */
|
|
if (wnd->title != NULL)
|
|
free(wnd->title);
|
|
if (wnd->videosave != NULL)
|
|
free(wnd->videosave);
|
|
/* -- remove window from parent's list of children -- */
|
|
DfRemoveWindow(wnd);
|
|
if (wnd == DfInFocus)
|
|
DfInFocus = NULL;
|
|
free(wnd);
|
|
}
|
|
|
|
/* ---- Window-processing module for DF_NORMAL window class ---- */
|
|
int DfNormalProc(DFWINDOW wnd, DFMESSAGE msg, DF_PARAM p1, DF_PARAM p2)
|
|
{
|
|
switch (msg) {
|
|
case DFM_CREATE_WINDOW:
|
|
CreateWindowMsg(wnd);
|
|
break;
|
|
case DFM_SHOW_WINDOW:
|
|
ShowWindowMsg(wnd, p1, p2);
|
|
break;
|
|
case DFM_HIDE_WINDOW:
|
|
HideWindowMsg(wnd);
|
|
break;
|
|
case DFM_DISPLAY_HELP:
|
|
DfDisplayHelp(wnd, (char *)p1);
|
|
break;
|
|
case DFM_INSIDE_WINDOW:
|
|
return InsideWindow(wnd, (int) p1, (int) p2);
|
|
case DFM_KEYBOARD:
|
|
if (KeyboardMsg(wnd, p1, p2))
|
|
return TRUE;
|
|
/* ------- fall through ------- */
|
|
case DFM_ADDSTATUS:
|
|
case DFM_SHIFT_CHANGED:
|
|
if (DfGetParent(wnd) != NULL)
|
|
DfPostMessage(DfGetParent(wnd), msg, p1, p2);
|
|
break;
|
|
case DFM_PAINT:
|
|
if (DfIsVisible(wnd))
|
|
DfClearWindow(wnd, (DFRECT *)p1, ' ');
|
|
break;
|
|
case DFM_BORDER:
|
|
if (DfIsVisible(wnd))
|
|
{
|
|
if (DfTestAttribute(wnd, DF_HASBORDER))
|
|
DfRepaintBorder(wnd, (DFRECT *)p1);
|
|
else if (DfTestAttribute(wnd, DF_HASTITLEBAR))
|
|
DfDisplayTitle(wnd, (DFRECT *)p1);
|
|
}
|
|
break;
|
|
case DFM_COMMAND:
|
|
CommandMsg(wnd, p1);
|
|
break;
|
|
case DFM_SETFOCUS:
|
|
SetFocusMsg(wnd, p1);
|
|
break;
|
|
case DFM_DOUBLE_CLICK:
|
|
DoubleClickMsg(wnd, p1, p2);
|
|
break;
|
|
case DFM_LEFT_BUTTON:
|
|
LeftButtonMsg(wnd, p1, p2);
|
|
break;
|
|
case MOUSE_MOVED:
|
|
if (MouseMovedMsg(wnd, p1, p2))
|
|
return TRUE;
|
|
break;
|
|
case DFM_BUTTON_RELEASED:
|
|
if (DfWindowMoving || DfWindowSizing)
|
|
{
|
|
if (DfWindowMoving)
|
|
DfPostMessage(wnd,DFM_MOVE,dwnd.rc.lf,dwnd.rc.tp);
|
|
else
|
|
DfPostMessage(wnd, DFM_DFM_SIZE,dwnd.rc.rt,dwnd.rc.bt);
|
|
TerminateMoveSize();
|
|
}
|
|
break;
|
|
#ifdef INCLUDE_MAXIMIZE
|
|
case DFM_MAXIMIZE:
|
|
if (wnd->condition != DF_ISMAXIMIZED)
|
|
MaximizeMsg(wnd);
|
|
break;
|
|
#endif
|
|
#ifdef INCLUDE_MINIMIZE
|
|
case DFM_MINIMIZE:
|
|
if (wnd->condition != DF_ISMINIMIZED)
|
|
MinimizeMsg(wnd);
|
|
break;
|
|
#endif
|
|
#ifdef INCLUDE_RESTORE
|
|
case DFM_RESTORE:
|
|
if (wnd->condition != DF_SRESTORED) {
|
|
#ifdef INCLUDE_MAXIMIZE
|
|
if (wnd->oldcondition == DF_ISMAXIMIZED)
|
|
DfSendMessage(wnd, DFM_MAXIMIZE, 0, 0);
|
|
else
|
|
#endif
|
|
RestoreMsg(wnd);
|
|
}
|
|
break;
|
|
#endif
|
|
case DFM_MOVE:
|
|
MoveMsg(wnd, p1, p2);
|
|
break;
|
|
case DFM_DFM_SIZE: {
|
|
SizeMsg(wnd, p1, p2);
|
|
break;
|
|
}
|
|
case DFM_CLOSE_WINDOW:
|
|
CloseWindowMsg(wnd);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return TRUE;
|
|
}
|
|
#ifdef INCLUDE_MINIMIZE
|
|
/* ---- compute lower right icon space in a rectangle ---- */
|
|
static DFRECT LowerRight(DFRECT prc)
|
|
{
|
|
DFRECT rc;
|
|
DfRectLeft(rc) = DfRectRight(prc) - DF_ICONWIDTH;
|
|
DfRectTop(rc) = DfRectBottom(prc) - DF_ICONHEIGHT;
|
|
DfRectRight(rc) = DfRectLeft(rc)+DF_ICONWIDTH-1;
|
|
DfRectBottom(rc) = DfRectTop(rc)+DF_ICONHEIGHT-1;
|
|
return rc;
|
|
}
|
|
/* ----- compute a position for a minimized window icon ---- */
|
|
static DFRECT PositionIcon(DFWINDOW wnd)
|
|
{
|
|
DFWINDOW pwnd = DfGetParent(wnd);
|
|
DFRECT rc;
|
|
DfRectLeft(rc) = DfGetScreenWidth()-DF_ICONWIDTH;
|
|
DfRectTop(rc) = DfGetScreenHeight()-DF_ICONHEIGHT;
|
|
DfRectRight(rc) = DfGetScreenWidth()-1;
|
|
DfRectBottom(rc) = DfGetScreenHeight()-1;
|
|
if (pwnd != NULL) {
|
|
DFRECT prc = DfWindowRect(pwnd);
|
|
DFWINDOW cwnd = DfFirstWindow(pwnd);
|
|
rc = LowerRight(prc);
|
|
/* - search for icon available location - */
|
|
while (cwnd != NULL) {
|
|
if (cwnd->condition == DF_ISMINIMIZED) {
|
|
DFRECT rc1;
|
|
rc1 = DfWindowRect(cwnd);
|
|
if (DfRectLeft(rc1) == DfRectLeft(rc) &&
|
|
DfRectTop(rc1) == DfRectTop(rc)) {
|
|
DfRectLeft(rc) -= DF_ICONWIDTH;
|
|
DfRectRight(rc) -= DF_ICONWIDTH;
|
|
if (DfRectLeft(rc) < DfRectLeft(prc)+1) {
|
|
DfRectLeft(rc) =
|
|
DfRectRight(prc)-DF_ICONWIDTH;
|
|
DfRectRight(rc) =
|
|
DfRectLeft(rc)+DF_ICONWIDTH-1;
|
|
DfRectTop(rc) -= DF_ICONHEIGHT;
|
|
DfRectBottom(rc) -= DF_ICONHEIGHT;
|
|
if (DfRectTop(rc) < DfRectTop(prc)+1)
|
|
return LowerRight(prc);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
cwnd = DfNextWindow(cwnd);
|
|
}
|
|
}
|
|
return rc;
|
|
}
|
|
#endif
|
|
/* ----- terminate the move or size operation ----- */
|
|
static void TerminateMoveSize(void)
|
|
{
|
|
px = py = -1;
|
|
diff = 0;
|
|
DfSendMessage(&dwnd, DFM_RELEASE_MOUSE, TRUE, 0);
|
|
DfSendMessage(&dwnd, DFM_RELEASE_KEYBOARD, TRUE, 0);
|
|
RestoreBorder(dwnd.rc);
|
|
DfWindowMoving = DfWindowSizing = FALSE;
|
|
}
|
|
/* ---- build a dummy window border for moving or sizing --- */
|
|
static void dragborder(DFWINDOW wnd, int x, int y)
|
|
{
|
|
RestoreBorder(dwnd.rc);
|
|
/* ------- build the dummy window -------- */
|
|
dwnd.rc.lf = x;
|
|
dwnd.rc.tp = y;
|
|
dwnd.rc.rt = dwnd.rc.lf+DfWindowWidth(wnd)-1;
|
|
dwnd.rc.bt = dwnd.rc.tp+DfWindowHeight(wnd)-1;
|
|
dwnd.ht = DfWindowHeight(wnd);
|
|
dwnd.wd = DfWindowWidth(wnd);
|
|
dwnd.parent = DfGetParent(wnd);
|
|
dwnd.attrib = DF_VISIBLE | DF_HASBORDER | DF_NOCLIP;
|
|
DfInitWindowColors(&dwnd);
|
|
SaveBorder(dwnd.rc);
|
|
DfRepaintBorder(&dwnd, NULL);
|
|
}
|
|
/* ---- write the dummy window border for sizing ---- */
|
|
static void sizeborder(DFWINDOW wnd, int rt, int bt)
|
|
{
|
|
int leftmost = DfGetLeft(wnd)+10;
|
|
int topmost = DfGetTop(wnd)+3;
|
|
int bottommost = DfGetScreenHeight()-1;
|
|
int rightmost = DfGetScreenWidth()-1;
|
|
if (DfGetParent(wnd)) {
|
|
bottommost = min(bottommost,
|
|
DfGetClientBottom(DfGetParent(wnd)));
|
|
rightmost = min(rightmost,
|
|
DfGetClientRight(DfGetParent(wnd)));
|
|
}
|
|
rt = min(rt, rightmost);
|
|
bt = min(bt, bottommost);
|
|
rt = max(rt, leftmost);
|
|
bt = max(bt, topmost);
|
|
|
|
if (rt != px || bt != py)
|
|
RestoreBorder(dwnd.rc);
|
|
|
|
/* ------- change the dummy window -------- */
|
|
dwnd.ht = bt-dwnd.rc.tp+1;
|
|
dwnd.wd = rt-dwnd.rc.lf+1;
|
|
dwnd.rc.rt = rt;
|
|
dwnd.rc.bt = bt;
|
|
if (rt != px || bt != py) {
|
|
px = rt;
|
|
py = bt;
|
|
SaveBorder(dwnd.rc);
|
|
DfRepaintBorder(&dwnd, NULL);
|
|
}
|
|
}
|
|
#ifdef INCLUDE_MULTI_WINDOWS
|
|
/* ----- adjust a rectangle to include the shadow ----- */
|
|
static DFRECT adjShadow(DFWINDOW wnd)
|
|
{
|
|
DFRECT rc;
|
|
rc = wnd->rc;
|
|
if (DfTestAttribute(wnd, DF_SHADOW)) {
|
|
if (DfRectRight(rc) < DfGetScreenWidth()-1)
|
|
DfRectRight(rc)++;
|
|
if (DfRectBottom(rc) < DfGetScreenHeight()-1)
|
|
DfRectBottom(rc)++;
|
|
}
|
|
return rc;
|
|
}
|
|
/* --- repaint a rectangular subsection of a window --- */
|
|
static void PaintOverLap(DFWINDOW wnd, DFRECT rc)
|
|
{
|
|
if (DfIsVisible(wnd)) {
|
|
int isBorder, isTitle, isData;
|
|
isBorder = isTitle = FALSE;
|
|
isData = TRUE;
|
|
if (DfTestAttribute(wnd, DF_HASBORDER)) {
|
|
isBorder = DfRectLeft(rc) == 0 &&
|
|
DfRectTop(rc) < DfWindowHeight(wnd);
|
|
isBorder |= DfRectLeft(rc) < DfWindowWidth(wnd) &&
|
|
DfRectRight(rc) >= DfWindowWidth(wnd)-1 &&
|
|
DfRectTop(rc) < DfWindowHeight(wnd);
|
|
isBorder |= DfRectTop(rc) == 0 &&
|
|
DfRectLeft(rc) < DfWindowWidth(wnd);
|
|
isBorder |= DfRectTop(rc) < DfWindowHeight(wnd) &&
|
|
DfRectBottom(rc) >= DfWindowHeight(wnd)-1 &&
|
|
DfRectLeft(rc) < DfWindowWidth(wnd);
|
|
}
|
|
else if (DfTestAttribute(wnd, DF_HASTITLEBAR))
|
|
isTitle = DfRectTop(rc) == 0 &&
|
|
DfRectRight(rc) > 0 &&
|
|
DfRectLeft(rc)<DfWindowWidth(wnd)-DfBorderAdj(wnd);
|
|
|
|
if (DfRectLeft(rc) >= DfWindowWidth(wnd)-DfBorderAdj(wnd))
|
|
isData = FALSE;
|
|
if (DfRectTop(rc) >= DfWindowHeight(wnd)-DfBottomBorderAdj(wnd))
|
|
isData = FALSE;
|
|
if (DfTestAttribute(wnd, DF_HASBORDER)) {
|
|
if (DfRectRight(rc) == 0)
|
|
isData = FALSE;
|
|
if (DfRectBottom(rc) == 0)
|
|
isData = FALSE;
|
|
}
|
|
if (DfTestAttribute(wnd, DF_SHADOW))
|
|
isBorder |= DfRectRight(rc) == DfWindowWidth(wnd) ||
|
|
DfRectBottom(rc) == DfWindowHeight(wnd);
|
|
if (isData)
|
|
DfSendMessage(wnd, DFM_PAINT, (DF_PARAM) &rc, TRUE);
|
|
if (isBorder)
|
|
DfSendMessage(wnd, DFM_BORDER, (DF_PARAM) &rc, 0);
|
|
else if (isTitle)
|
|
DfDisplayTitle(wnd, &rc);
|
|
}
|
|
}
|
|
/* ------ paint the part of a window that is overlapped
|
|
by another window that is being hidden ------- */
|
|
static void PaintOver(DFWINDOW wnd)
|
|
{
|
|
DFRECT wrc, rc;
|
|
wrc = adjShadow(HiddenWindow);
|
|
rc = adjShadow(wnd);
|
|
rc = DfSubRectangle(rc, wrc);
|
|
if (DfValidRect(rc))
|
|
PaintOverLap(wnd, DfRelativeWindowRect(wnd, rc));
|
|
}
|
|
/* --- paint the overlapped parts of all children --- */
|
|
static void PaintOverChildren(DFWINDOW pwnd)
|
|
{
|
|
DFWINDOW cwnd = DfFirstWindow(pwnd);
|
|
while (cwnd != NULL) {
|
|
if (cwnd != HiddenWindow) {
|
|
PaintOver(cwnd);
|
|
PaintOverChildren(cwnd);
|
|
}
|
|
cwnd = DfNextWindow(cwnd);
|
|
}
|
|
}
|
|
/* -- recursive overlapping paint of parents -- */
|
|
static void PaintOverParents(DFWINDOW wnd)
|
|
{
|
|
DFWINDOW pwnd = DfGetParent(wnd);
|
|
if (pwnd != NULL) {
|
|
PaintOverParents(pwnd);
|
|
PaintOver(pwnd);
|
|
PaintOverChildren(pwnd);
|
|
}
|
|
}
|
|
/* - paint the parts of all windows that a window is over - */
|
|
static void PaintOverLappers(DFWINDOW wnd)
|
|
{
|
|
HiddenWindow = wnd;
|
|
PaintOverParents(wnd);
|
|
}
|
|
/* --- paint those parts of a window that are overlapped --- */
|
|
static void PaintUnderLappers(DFWINDOW wnd)
|
|
{
|
|
DFWINDOW hwnd = DfNextWindow(wnd);
|
|
while (hwnd != NULL) {
|
|
/* ------- test only at document window level ------ */
|
|
DFWINDOW pwnd = DfGetParent(hwnd);
|
|
/* if (pwnd == NULL || DfGetClass(pwnd) == DF_APPLICATION) */ {
|
|
/* ---- don't bother testing self ----- */
|
|
if (DfIsVisible(hwnd) && hwnd != wnd) {
|
|
/* --- see if other window is descendent --- */
|
|
while (pwnd != NULL) {
|
|
if (pwnd == wnd)
|
|
break;
|
|
pwnd = DfGetParent(pwnd);
|
|
}
|
|
/* ----- don't test descendent overlaps ----- */
|
|
if (pwnd == NULL) {
|
|
/* -- see if other window is ancestor --- */
|
|
pwnd = DfGetParent(wnd);
|
|
while (pwnd != NULL) {
|
|
if (pwnd == hwnd)
|
|
break;
|
|
pwnd = DfGetParent(pwnd);
|
|
}
|
|
/* --- don't test ancestor overlaps --- */
|
|
if (pwnd == NULL) {
|
|
HiddenWindow = DfGetAncestor(hwnd);
|
|
DfClearVisible(HiddenWindow);
|
|
PaintOver(wnd);
|
|
DfSetVisible(HiddenWindow);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
hwnd = DfNextWindow(hwnd);
|
|
}
|
|
/* --------- repaint all children of this window
|
|
the same way ----------- */
|
|
hwnd = DfFirstWindow(wnd);
|
|
while (hwnd != NULL) {
|
|
PaintUnderLappers(hwnd);
|
|
hwnd = DfNextWindow(hwnd);
|
|
}
|
|
}
|
|
#endif /* #ifdef INCLUDE_MULTI_WINDOWS */
|
|
|
|
/* --- save video area to be used by dummy window border --- */
|
|
static void SaveBorder(DFRECT rc)
|
|
{
|
|
Bht = DfRectBottom(rc) - DfRectTop(rc) + 1;
|
|
Bwd = DfRectRight(rc) - DfRectLeft(rc) + 1;
|
|
Bsave = DfRealloc(Bsave, Bht * Bwd * sizeof(CHAR_INFO));
|
|
|
|
DfGetVideo(rc,Bsave);
|
|
}
|
|
/* ---- restore video area used by dummy window border ---- */
|
|
static void RestoreBorder(DFRECT rc)
|
|
{
|
|
if (Bsave != NULL)
|
|
{
|
|
DfStoreVideo(rc, Bsave);
|
|
free(Bsave);
|
|
Bsave = NULL;
|
|
}
|
|
}
|
|
/* ----- test if screen coordinates are in a window ---- */
|
|
static BOOL InsideWindow(DFWINDOW wnd, int x, int y)
|
|
{
|
|
DFRECT rc;
|
|
rc = DfWindowRect(wnd);
|
|
if (!DfTestAttribute(wnd, DF_NOCLIP))
|
|
{
|
|
DFWINDOW pwnd = DfGetParent(wnd);
|
|
while (pwnd != NULL)
|
|
{
|
|
rc = DfSubRectangle(rc, DfClientRect(pwnd));
|
|
pwnd = DfGetParent(pwnd);
|
|
}
|
|
}
|
|
return DfInsideRect(x, y, rc);
|
|
}
|
|
|
|
BOOL DfIsDerivedFrom(DFWINDOW wnd, DFCLASS class)
|
|
{
|
|
DFCLASS tclass = DfGetClass(wnd);
|
|
while (tclass != -1) {
|
|
if (tclass == class)
|
|
return TRUE;
|
|
tclass = (DfClassDefs[tclass].base);
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
/* -- find the oldest document window ancestor of a window -- */
|
|
DFWINDOW DfGetAncestor(DFWINDOW wnd)
|
|
{
|
|
if (wnd != NULL) {
|
|
while (DfGetParent(wnd) != NULL) {
|
|
if (DfGetClass(DfGetParent(wnd)) == DF_APPLICATION)
|
|
break;
|
|
wnd = DfGetParent(wnd);
|
|
}
|
|
}
|
|
return wnd;
|
|
}
|
|
|
|
BOOL DfIsVisible(DFWINDOW wnd)
|
|
{
|
|
while (wnd != NULL) {
|
|
if (isHidden(wnd))
|
|
return FALSE;
|
|
wnd = DfGetParent(wnd);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
/* -- adjust a window's rectangle to clip it to its parent - */
|
|
static DFRECT ClipRect(DFWINDOW wnd)
|
|
{
|
|
DFRECT rc;
|
|
rc = DfWindowRect(wnd);
|
|
if (DfTestAttribute(wnd, DF_SHADOW)) {
|
|
DfRectBottom(rc)++;
|
|
DfRectRight(rc)++;
|
|
}
|
|
return DfClipRectangle(wnd, rc);
|
|
}
|
|
|
|
/* -- get the video memory that is to be used by a window -- */
|
|
static void GetVideoBuffer(DFWINDOW wnd)
|
|
{
|
|
DFRECT rc;
|
|
int ht;
|
|
int wd;
|
|
|
|
rc = ClipRect(wnd);
|
|
ht = DfRectBottom(rc) - DfRectTop(rc) + 1;
|
|
wd = DfRectRight(rc) - DfRectLeft(rc) + 1;
|
|
wnd->videosave = DfRealloc(wnd->videosave, (ht * wd * sizeof(CHAR_INFO)));
|
|
DfGetVideo(rc, wnd->videosave);
|
|
}
|
|
|
|
/* -- put the video memory that is used by a window -- */
|
|
static void PutVideoBuffer(DFWINDOW wnd)
|
|
{
|
|
if (wnd->videosave != NULL)
|
|
{
|
|
DFRECT rc;
|
|
rc = ClipRect(wnd);
|
|
DfStoreVideo(rc, wnd->videosave);
|
|
free(wnd->videosave);
|
|
wnd->videosave = NULL;
|
|
}
|
|
}
|
|
|
|
/* ------- return TRUE if awnd is an ancestor of wnd ------- */
|
|
BOOL DfIsAncestor(DFWINDOW wnd, DFWINDOW awnd)
|
|
{
|
|
while (wnd != NULL) {
|
|
if (wnd == awnd)
|
|
return TRUE;
|
|
wnd = DfGetParent(wnd);
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
/* EOF */
|