⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 window.c

📁 Microsoft MS-DOS6.0 完整源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
	COW : Character Oriented Windows

	window.c  : Window Support

	This module contains the window relative output routines
        as well as routines for accessing and changing the window
        data structure.
*/

#define COW
#include <cow.h>

#define WINDOW
#include <uwindow.h>
#include <uevent.h>
#include <umenu.h>
#include <uscreen.h>
#include <uisa.h>

#include "event.h"
#include "screen.h"
#include "util.h"
#include "overlap.h"

#include "window.h"


#ifdef EXTRAS
#define	chColorPrefix	((char) 0xfe)		/* => special color prefix */
#endif

STATIC WORD	fBlockCursor = 1;		/* see SetCursorBlock() */

#ifdef WINDOW_OVERLAP
extern PWND pwndClip;
#endif /*WINDOW_OVERLAP*/

/* forward declarations for STATIC procedures */
STATIC VOID EnableWindowAndSiblings(PWND, BOOL);
STATIC VOID DrawWindowAndSiblings(PWND);
STATIC VOID TextOutColor(AX, AY, char *, WORD, WORD);
#ifdef WINDOW_OVERLAP
STATIC VOID MoveWindowAndSiblings(PWND, BYTE, BYTE);
STATIC VOID ValidateAWindow(PWND);
STATIC VOID ValidateWindowAndSiblings(PWND);
STATIC VOID ValidateWindowAndParents(PWND);
STATIC VOID MoveCursorClipped(PWND);
#endif /*WINDOW_OVERLAP*/



PUBLIC VOID FARPUBLIC
AddChild(pwndParent, pwndChild)
PWND pwndParent, pwndChild;
/* AddChild adds a child to the specified window.  If pwndParent is
   null then a child is added to the root directory.  Child is added
   to the end of the sibling chain. */
	{
	StartPublic();
	PWND pwndCur, pwndPrev;
	if (pwndParent)
		{
		if ((pwndPrev = pwndParent->pwndChild) == NULL)
			pwndParent->pwndChild = pwndChild;
		else
			{
			while ((pwndCur = pwndPrev->pwndSibling) != NULL)
				pwndPrev = pwndCur;
			pwndPrev->pwndSibling = pwndChild;
			}
		pwndChild->pwndSibling = NULL;
		EnableWindow(pwndChild, pwndParent->fEnabled);
#ifdef WINDOW_OVERLAP
		if (pwndParent->style & WS_CLIPOUT)
			{
			pwndChild->style |= WS_CLIPOUT;
			ClipoutWindowAndSiblings(pwndChild->pwndChild);
			}
#endif /*WINDOW_OVERLAP*/
		}
	else
		{
		pwndChild->pwndSibling = pwndRoot;
		pwndRoot = pwndChild;
		EnableWindow(pwndChild, TRUE);
		}
	pwndChild->pwndParent = pwndParent;
	StopPublic();
	}



PUBLIC VOID FARPUBLIC
EnableWindow(pwnd, fEnabled)
PWND pwnd;
BOOL fEnabled;
/* Enable or disable a window.  All children are enabled or disabled as well */
	{
	StartPublic();
	pwnd->fEnabled = (fEnabled != FALSE);
	EnableWindowAndSiblings(pwnd->pwndChild, fEnabled);
	StopPublic();
	}



STATIC VOID
EnableWindowAndSiblings(pwnd, fEnabled)
REGISTER PWND pwnd;
BOOL fEnabled;
	{
	while (pwnd)
		{
		pwnd->fEnabled = (fEnabled != FALSE);
		EnableWindowAndSiblings(pwnd->pwndChild, fEnabled);
		pwnd = pwnd->pwndSibling;
		}
	}



PUBLIC VOID FARPUBLIC
RemoveChild(pwndChild)
/*
  -- removes a child from its parent window
  -- special case allows removal of root windows
*/
REGISTER PWND pwndChild;
	{
	StartPublic();
	PWND pwndParent = pwndChild->pwndParent;
	REGISTER PWND pwnd;

	AssertSz(pwndChild, "RemoveChild(NULL)");

	if (pwndParent == NULL)
		{
		/* should be a root window */
		if (pwndChild == pwndRoot)
			{
			/* remove first root */
			pwndRoot = pwndChild->pwndSibling;
			}
		else
			{
			pwnd = pwndRoot;
			goto scan_sibling;
			}
		}
	else if ((pwnd = pwndParent->pwndChild) == pwndChild)
		{
		/* remove first child */
		pwndParent->pwndChild = pwndChild->pwndSibling;
		}
	else
		{
scan_sibling:
		while (pwnd->pwndSibling != pwndChild)
			{
			pwnd = pwnd->pwndSibling;
			AssertSz(pwnd != NULL, "child window not found");
			}
		pwnd->pwndSibling = pwndChild->pwndSibling;
		}
	pwndChild->pwndParent = NULL;
	pwndChild->pwndSibling = NULL;
	StopPublic();
	}



PUBLIC VOID FARPUBLIC
GetClientRrc(pwnd, prrc)
/*
  -- create a rectangle that composes the entire clent area.
  -- Note that the top left hand corner of the client rrc is
	always 0,0 since all output is relative to this point.
*/
REGISTER PWND pwnd;
REGISTER PRRC prrc;
	{
	StartPublic();
	prrc->ryTop = 0;
	prrc->rxLeft = 0;
	prrc->ryBottom = (pwnd->arcWindow.ayBottom)-(pwnd->arcWindow.ayTop);
	prrc->rxRight = (pwnd->arcWindow.axRight)-(pwnd->arcWindow.axLeft);
	if (pwnd->style & WS_BORDER)
		{
		/* border around window */
		prrc->ryBottom -= 2 * dayBorder;
		prrc->rxRight -= 2 * daxBorder;
#ifdef WINDOW_OVERLAP
		if (pwnd->style & WS_OVERLAP)
			{
			if (pwnd->style & WS_HSCROLL)
				prrc->ryBottom -= dayBorder;
			if (pwnd->style & WS_VSCROLL)
				prrc->rxRight -= daxBorder;
			}
#endif /*WINDOW_OVERLAP*/
		}
	else
		{
		if (pwnd->style & WS_HSCROLL)
			prrc->ryBottom -= dayBorder;
		if (pwnd->style & WS_VSCROLL)
			prrc->rxRight -= daxBorder;
		}
	StopPublic();
	}



PUBLIC VOID FARPUBLIC
SetWindowSize(pwnd, drx, dry)
/*
  -- changes the size of a window to be (drx, dry).
  -- Actual window and client window are adjusted appropriately
*/
REGISTER PWND pwnd;
BYTE drx, dry;
	{
	StartPublic();
	pwnd->arcWindow.axRight = pwnd->arcWindow.axLeft+drx;
	pwnd->arcWindow.ayBottom = pwnd->arcWindow.ayTop+dry;
	ValidateWindow(pwnd);
	StopPublic();
	}



PUBLIC VOID FARPUBLIC
SetWindowStyle(pwnd, style)
/*
  -- change the style of the window.
*/
PWND pwnd;
WORD style;
	{
	StartPublic();
	pwnd->style = style;
	ValidateWindow(pwnd);
	StopPublic();
	}


#ifdef WINDOW_OVERLAP

PRIVATE VOID FARPRIVATE
ValidateWindow(pwnd)
/*
  -- computes the clipping rectangle for a window and all of its children
*/
REGISTER PWND pwnd;
	{
	StartPublic();

	ValidateWindowAndParents(pwnd->pwndParent);
	ValidateAWindow(pwnd);
	ValidateWindowAndSiblings(pwnd->pwndChild);
	StopPublic();
	}

STATIC VOID
ValidateAWindow(pwnd)
/*
  -- computes the clipping rectangle for a window
*/
REGISTER PWND pwnd;
	{
	RRC	rrc;


	GetClientRrc(pwnd,&rrc);
	pwnd->arcClipping = pwnd->arcWindow;
	if (pwnd->style & WS_BORDER)
		{
		/* border around window */
		pwnd->arcClipping.axLeft += daxBorder;
		pwnd->arcClipping.ayTop += dayBorder;
		}
	pwnd->arcClipping.axRight = pwnd->arcClipping.axLeft + rrc.rxRight;
	pwnd->arcClipping.ayBottom = pwnd->arcClipping.ayTop + rrc.ryBottom;

	if ((pwnd->pwndParent != NULL) && (pwnd->style & WS_CLIPOUT))
		{
		if ((pwnd->style & WS_TYPE) == WS_SCROLL) 
			{
			if (pwnd->pwndParent->pwndParent != NULL)
				{
				pwnd->arcClipping.axRight =
				 min(pwnd->arcClipping.axRight,
			 pwnd->pwndParent->pwndParent->arcClipping.axRight);
				pwnd->arcClipping.ayBottom =
				 min(pwnd->arcClipping.ayBottom,
			 pwnd->pwndParent->pwndParent->arcClipping.ayBottom);
				}
			}
		else
			{
			pwnd->arcClipping.axRight =
				 min(pwnd->arcClipping.axRight,
				 pwnd->pwndParent->arcClipping.axRight);
			pwnd->arcClipping.ayBottom =
				 min(pwnd->arcClipping.ayBottom,
				 pwnd->pwndParent->arcClipping.ayBottom);
			}
		}

	StopPublic();
	}


STATIC VOID
ValidateWindowAndSiblings(pwnd)
/*
  -- computes the clipping rectangle for a window and all of its children
*/
REGISTER PWND pwnd;
	{
	while (pwnd != NULL)
		{
		ValidateAWindow(pwnd);
		ValidateWindowAndSiblings(pwnd->pwndChild);
		pwnd = pwnd->pwndSibling;
		}
	}


STATIC VOID
ValidateWindowAndParents(pwnd)
/*
  -- computes the clipping rectangle for a window and all of its children
*/
REGISTER PWND pwnd;
	{
	if (pwnd != NULL)
		{
		ValidateWindowAndParents(pwnd->pwndParent);
		ValidateAWindow(pwnd);
		}
	}

#else

/* No Overlapping windows to worry about */

PRIVATE VOID FARPRIVATE
ValidateWindow(pwnd)
/*
  -- computes the clipping rectangle for a window and all of its children
*/
REGISTER PWND pwnd;
	{
	StartPublic();
	RRC	rrc;


	GetClientRrc(pwnd,&rrc);
	pwnd->arcClipping = pwnd->arcWindow;
	if (pwnd->style & WS_BORDER)
		{
		/* border around window */
		pwnd->arcClipping.axLeft += daxBorder;
		pwnd->arcClipping.ayTop += dayBorder;
		}
	pwnd->arcClipping.axRight = pwnd->arcClipping.axLeft + rrc.rxRight;
	pwnd->arcClipping.ayBottom = pwnd->arcClipping.ayTop + rrc.ryBottom;

	StopPublic();
	}


#endif /*WINDOW_OVERLAP*/

PUBLIC VOID FARPUBLIC
DrawWindow(pwnd)
/*
  -- draw window and children
*/
PWND pwnd;
	{
	StartPublic();
	if (pwnd)
		{
		SendMessageShort(pwnd, WM_PAINT);
		DrawWindowAndSiblings(pwnd->pwndChild);
		}
	else if (pwndRoot)
		{
		DrawMenubar();
		DrawWindowAndSiblings(pwndRoot);
		}
	StopPublic();
	}



STATIC VOID
DrawWindowAndSiblings(pwnd)
PWND pwnd;
	{
	while (pwnd != NULL)
		{
		SendMessageShort(pwnd, WM_PAINT);
		DrawWindowAndSiblings(pwnd->pwndChild);
		pwnd = pwnd->pwndSibling;
		}
	}



PUBLIC VOID FARPUBLIC
DrawBorder(pwnd, pbox, di, szTitle)
/*
  -- draw a box around the window only if WS_STYLE includes WS_BORDER
  -- MERGE ABS/REL
*/
REGISTER PWND pwnd;
BOX *	pbox;
WORD	di;
char *	szTitle;
	{
	StartPublic();
	if (pwnd->style & WS_BORDER)
		{
#ifdef WINDOW_OVERLAP
		if (pwnd->style & WS_CLIPOUT)
			pwndClip = pwnd->pwndParent;
#endif /*WINDOW_OVERLAP*/
		DrawThisWnd(pwnd);
		DrawBoxArc(pbox, &pwnd->arcWindow, di,
			   !(pwnd->style & WS_VSCROLL),
			   !(pwnd->style & WS_HSCROLL),
			   szTitle);
#ifdef WINDOW_OVERLAP
		if (pwnd->style & WS_CLIPOUT)
			pwndClip = NULL;
#endif /*WINDOW_OVERLAP*/
		}
	StopPublic();
	}



#ifdef EXTRAS
PRIVATE int FARPRIVATE
CchRealLenSz(sz)
/*
  -- return string length (excluding special color characters)
*/
REG char * sz;
	{
	REG WORD cch;

	cch = 0;
	while (*sz != '\0')
		{
		if (*sz == chColorPrefix)
			{
			/* skip prefix and following character */
			Assert(sz[1] != '\0');
			sz += 2;
			}
		else
			{
			cch++;
			sz++;
			}
		}
	return cch;
	}



VOID FARPRIVATE
TextOutColor(ax, ay, pch, cch, diOrig)
AX	ax;
AY	ay;
char *	pch;
WORD	cch;
WORD	diOrig;
/*
  -- text out with special color check
*/
	{
	REG char * pchT;
	REG WORD cchT;
	WORD	di = diOrig;

	cchT = 0;

	while (1)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -