📄 window.c
字号:
{
/* skip to end of string or to color prefix character */
pchT = pch;
while (cchT < cch && *pchT != chColorPrefix)
{
cchT++;
pchT++;
}
TextOutAbs(ax, ay, pch, cchT, di);
if (cchT == cch)
break; /* done */
ax += (BYTE) cchT;
Assert(*pchT == chColorPrefix);
if (pchT[1] < '0' || pchT[1] > '9')
{
/* revert to original color */
di = diOrig;
}
else
{
/* set to specified user color */
di = (diOrig & 0xff00) | (isaUserMin + pchT[1] - '0');
}
pch = pchT+2; /* after color magic */
}
}
#endif /*EXTRAS*/
PUBLIC VOID FARPUBLIC
TextOut(pwnd, rx, ry, pch, cch, di)
/*
-- output a line of text to the specified window
-- (rx, ry) specify the relative position to start output
-- cch is the number of characters to display, -1 indicates sz string
-- di is the display info
-- MERGE ABS/REL
*/
REGISTER PWND pwnd;
RX rx;
RY ry;
char * pch;
short cch;
WORD di;
{
StartPublic();
AX ax;
AY ay;
if (cch == -1)
cch = CchRealLenSz(pch);
DrawThisWnd(pwnd);
if (pwnd == NULL)
{
#ifdef EXTRAS
TextOutColor((AX) rx, (AY) ry, pch, cch, di);
#else
TextOutAbs((AX) rx, (AY) ry, pch, cch, di);
#endif
StopPublic();
return;
}
ax = pwnd->arcClipping.axLeft+rx;
ay = pwnd->arcClipping.ayTop+ry;
if ((ax < pwnd->arcClipping.axRight) && (ay < pwnd->arcClipping.ayBottom) && (ry >= 0))
{
if ((ax+cch) > pwnd->arcClipping.axRight)
cch = (pwnd->arcClipping.axRight-ax);
#ifdef EXTRAS
TextOutColor(ax, ay, pch, cch, di);
#else
TextOutAbs(ax, ay, pch, cch, di);
#endif
}
StopPublic();
}
PUBLIC VOID FARPUBLIC
FillRrc(pwnd, prrc, ch, di)
/*
-- fill a rectangle with a given character
-- MERGE ABS/REL
*/
PWND pwnd;
PRRC prrc;
ACHAR ch;
WORD di;
{
StartPublic();
ARC arc;
if (FArcFromRrc(pwnd, prrc, &arc))
{
DrawThisWnd(pwnd);
FillArc(arc.axLeft, arc.ayTop, arc.axRight, arc.ayBottom,
ch, di);
}
StopPublic();
}
PRIVATE BOOL FARPRIVATE
FArcFromRrc(pwnd, prrc, parc)
/*
-- convert a relative rectangle into an absolute rectangle
-- return TRUE if rectangle within client area
*/
PWND pwnd;
PRRC prrc;
REGISTER PARC parc;
{
if (pwnd == NULL)
{
*parc = *(PARC)prrc;
return TRUE;
}
parc->axLeft = prrc->rxLeft+pwnd->arcClipping.axLeft;
parc->axRight = prrc->rxRight+pwnd->arcClipping.axLeft;
parc->ayTop = prrc->ryTop+pwnd->arcClipping.ayTop;
parc->ayBottom = prrc->ryBottom+pwnd->arcClipping.ayTop;
return(IntersectRect((PRRC) parc, (PRRC) &(pwnd->arcClipping), (PRRC) parc));
}
PUBLIC VOID FARPUBLIC
BltRrc(pwnd, rxDest, ryDest, drx, dry, rxSrc, rySrc)
/*
-- moves source rectangle to destination
*/
REGISTER PWND pwnd;
RX rxDest, rxSrc;
RY ryDest, rySrc;
BYTE drx, dry;
{
StartPublic();
if (pwnd != NULL)
{
/* convert Relative to Absolute */
rxSrc += pwnd->arcClipping.axLeft;
rySrc += pwnd->arcClipping.ayTop;
rxDest += pwnd->arcClipping.axLeft;
ryDest += pwnd->arcClipping.ayTop;
/* from this point on rx & ry are really ax & ay */
if ((rxSrc >= pwnd->arcClipping.axRight) ||
(rxDest >= pwnd->arcClipping.axRight) ||
(rySrc >= pwnd->arcClipping.ayBottom) ||
(ryDest >= pwnd->arcClipping.ayBottom))
{
/* outside range */
StopPublic();
return;
}
if ((rxSrc+drx) >= pwnd->arcClipping.axRight)
drx = pwnd->arcClipping.axRight - rxSrc;
if ((rxDest+drx) >= pwnd->arcClipping.axRight)
drx = pwnd->arcClipping.axRight - rxDest;
if ((rySrc+dry) >= pwnd->arcClipping.ayBottom)
dry = pwnd->arcClipping.ayBottom - rySrc;
if ((ryDest+dry) >= pwnd->arcClipping.ayBottom)
dry = pwnd->arcClipping.ayBottom - ryDest;
}
DrawThisWnd(pwnd); /* this one is tricky */
BltArc((AX) rxDest, (AY) ryDest, drx, dry, (AX) rxSrc, (AY) rySrc);
}
PUBLIC VOID FARPUBLIC
DrawBox(pwnd, prrc, pbox, di)
/*
-- draws a box specified by the rectangle prrc using the characters
defined by pbox.
-- note : the entire rectangle must be contained in the window
-- MERGE ABS/REL
*/
PWND pwnd;
REGISTER PRRC prrc;
BOX *pbox;
WORD di;
{
StartPublic();
ARC arc;
AssertCorrectRrc(prrc)
if (FArcFromRrc(pwnd, prrc, &arc))
{
DrawThisWnd(pwnd);
DrawBoxArc(pbox, &arc, di, TRUE, TRUE, NULL);
}
StopPublic();
}
#ifdef WINDOW_OVERLAP
STATIC VOID
MoveCursorClipped(pwnd)
REGISTER PWND pwnd;
{
if (pwnd->style & WS_CLIPOUT)
{
if (((pwnd->axCursor >= pwnd->arcClipping.axRight) ||
(pwnd->ayCursor >= pwnd->arcClipping.ayBottom)) ||
((psOverlap) &&
(pwnd != *((PWND FAR *)
MAKELONG( sizeof(PWND) *
(pwnd->ayCursor*axMac + pwnd->axCursor),
psOverlap
))) ))
MoveHardwareCursor(0, 0, FALSE);
else
{
MoveHardwareCursor(pwnd->axCursor, pwnd->ayCursor,
pwnd->fCursorOn ? fBlockCursor : FALSE);
}
}
else
{
MoveHardwareCursor(pwnd->axCursor, pwnd->ayCursor,
pwnd->fCursorOn ? fBlockCursor : FALSE);
}
}
#endif /*WINDOW_OVERLAP*/
PUBLIC VOID FARPUBLIC
MoveCursor(pwnd, rx, ry)
/*
-- move the character cursor to the appropriate position within the window
-- only changes the hardware cursor for the window in focus
*/
REGISTER PWND pwnd;
RX rx;
RY ry;
{
StartPublic();
RRC rrc;
GetClientRrc(pwnd,&rrc);
AssertSz((rx <= rrc.rxRight) && (ry <= rrc.ryBottom),
"Attempt to Move Cursor Outside of Rectangle");
pwnd->axCursor = pwnd->arcClipping.axLeft + rx;
pwnd->ayCursor = pwnd->arcClipping.ayTop + ry;
if (pwnd == pwndFocus)
#ifdef WINDOW_OVERLAP
MoveCursorClipped(pwnd);
#else
{
MoveHardwareCursor(pwnd->axCursor, pwnd->ayCursor,
pwnd->fCursorOn ? fBlockCursor : FALSE);
}
#endif /*WINDOW_OVERLAP*/
StopPublic();
}
PRIVATE VOID FARPRIVATE
UpdateCursor()
/*
-- call this to update the state of the hardware cursor
*/
{
REGISTER PWND pwnd;
if ((pwnd = pwndFocus) != NULL)
{
DrawThisWnd(pwnd);
#ifdef WINDOW_OVERLAP
MoveCursorClipped(pwnd);
#else
MoveHardwareCursor(pwnd->axCursor, pwnd->ayCursor,
pwnd->fCursorOn ? fBlockCursor : FALSE);
#endif /*WINDOW_OVERLAP*/
}
else
{
/* no window with focus */
MoveHardwareCursor(0, 0, FALSE);
}
}
PUBLIC VOID FARPUBLIC
EnableCursor(pwnd, fOn)
/*
-- enable/disable cursor in given window
*/
REGISTER PWND pwnd;
BOOL fOn; /* TRUE => turn on */
{
StartPublic();
pwnd->fCursorOn = (fOn != FALSE);
if (pwnd == pwndFocus)
{
DrawThisWnd(pwnd);
#ifdef WINDOW_OVERLAP
MoveCursorClipped(pwnd);
#else
MoveHardwareCursor(pwnd->axCursor, pwnd->ayCursor,
pwnd->fCursorOn ? fBlockCursor : FALSE);
#endif /*WINDOW_OVERLAP*/
}
StopPublic();
}
PUBLIC VOID FARPUBLIC
SetCursorBlock(fBlock)
/*
-- set cursor size
*/
BOOL fBlock; /* 0-underline, 1-block */
{
fBlockCursor = fBlock ? 2 : 1;
UpdateCursor();
}
PUBLIC VOID FARPUBLIC
MoveWindow(pwnd, ax, ay)
/*
-- move the window to absolute coordinates (ax, ay).
-- update all absolute position items in the WND structure
*/
REGISTER PWND pwnd;
AX ax;
AY ay;
{
StartPublic();
BYTE dax = ax - pwnd->arcWindow.axLeft;
BYTE day = ay - pwnd->arcWindow.ayTop;
/* Note : following explicit & 0xff is needed due to Cmerge 4.0
bug with LOBYTE() */
#ifndef WINDOW_OVERLAP
AssertSz(((pwnd->arcWindow.ayBottom + day) & 0xff) <= ayMac &&
((pwnd->arcWindow.axRight + dax) & 0xff) <= axMac,
"Moving rectangle off the screen");
#endif
pwnd->arcWindow.axLeft = ax;
pwnd->arcWindow.ayTop = ay;
pwnd->arcWindow.axRight += dax;
pwnd->arcWindow.ayBottom += day;
pwnd->axCursor += dax;
pwnd->ayCursor += day;
if (pwnd == pwndFocus)
{
#ifdef WINDOW_OVERLAP
MoveCursorClipped(pwnd);
#else
MoveHardwareCursor(pwnd->axCursor, pwnd->ayCursor,
pwnd->fCursorOn ? fBlockCursor : FALSE);
#endif /*WINDOW_OVERLAP*/
}
#ifdef WINDOW_OVERLAP
MoveWindowAndSiblings(pwnd->pwndChild, dax, day);
#endif /*WINDOW_OVERLAP*/
ValidateWindow(pwnd);
StopPublic();
}
#ifdef WINDOW_OVERLAP
STATIC VOID
MoveWindowAndSiblings(pwnd, dax, day)
/*
-- move the window to absolute coordinates (ax, ay).
-- update all absolute position items in the WND structure
*/
REGISTER PWND pwnd;
BYTE dax;
BYTE day;
{
while (pwnd != NULL)
{
pwnd->arcWindow.axLeft += dax;
pwnd->arcWindow.ayTop += day;
pwnd->arcWindow.axRight += dax;
pwnd->arcWindow.ayBottom += day;
pwnd->axCursor += dax;
pwnd->ayCursor += day;
if (pwnd == pwndFocus)
{
MoveCursorClipped(pwnd);
}
MoveWindowAndSiblings(pwnd->pwndChild, dax, day);
pwnd = pwnd->pwndSibling;
}
}
#endif /*WINDOW_OVERLAP*/
PUBLIC VOID FARPUBLIC
SaveRrc(pwnd, prrc, lpbBuf)
/*
-- restores the relative rectangle prrc in the near buffer pbBuf
-- MERGE ABS/REL
*/
PWND pwnd;
PRRC prrc;
BYTE FAR * lpbBuf;
{
StartPublic();
ARC arc;
AssertCorrectRrc(prrc);
if (FArcFromRrc(pwnd, prrc, &arc))
{
DrawThisWnd(pwnd); /* this is sort of stupid */
SaveArc(arc.axLeft, arc.ayTop, arc.axRight, arc.ayBottom,
lpbBuf);
}
StopPublic();
}
PUBLIC VOID FARPUBLIC
RestoreRrc(pwnd, prrc, lpbBuf)
/*
-- restores the relative rectangle prrc in the near buffer pbBuf
-- MERGE ABS/REL
*/
PWND pwnd;
PRRC prrc;
BYTE FAR * lpbBuf;
{
StartPublic();
ARC arc;
AssertCorrectRrc(prrc);
if (FArcFromRrc(pwnd, prrc, &arc))
{
DrawThisWnd(pwnd);
RestoreArc(arc.axLeft, arc.ayTop, arc.axRight, arc.ayBottom,
lpbBuf);
}
StopPublic();
}
PUBLIC VOID FARPUBLIC
CharOut(pwnd, rx, ry, ch, di)
/*
-- put single character in window
-- MERGE ABS/REL
*/
REGISTER PWND pwnd;
RX rx;
RY ry;
ACHAR ch;
WORD di;
{
if (pwnd != NULL)
{
rx += pwnd->arcClipping.axLeft;
ry += pwnd->arcClipping.ayTop;
if (rx >= pwnd->arcClipping.axRight ||
ry >= pwnd->arcClipping.ayBottom)
return; /* clip that character */
}
DrawThisWnd(pwnd);
CharOutAbs((AX) rx, (AY) ry, ch, di);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -