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

📄 wnd.cpp

📁 一个更为先进的嵌入式操作系统.采用RMS线程调度算法,具有信号量等同步对象.亦包括GUI. 通过该系统您可以极大知道Windows的内部秘密.
💻 CPP
字号:
// Wnd.cpp: implementation of the CWnd class.
//
//////////////////////////////////////////////////////////////////////

#include "gos.h"
#include "Wnd.h"

#ifdef _DEBUG
CWnd::CWnd()
{
	m_pParent=NULL;
	m_pData=NULL;
}
CWnd::~CWnd()
{
	ASSERT(!m_pParent);
	ASSERT(!m_pData);
}
#endif //_DEBUG

BOOL CWnd::Create(DWORD nStyle, LPCRECT pRect, CPWnd *pParent,int nID)
{
	ASSERT(!m_pParent);
	m_nStyle=nStyle;
	m_pData=NULL;
	m_nCtrlID=nID;
	if(pRect)
	{
		m_rclWnd=pRect;
		m_rclWnd.OffsetRect(pParent->m_rclClient.TopLeft());
		m_rclInv=m_rclWnd;
		m_rclClient=m_rclWnd;
	}
	pParent->AddControl(this);
	PostMessage(WM_CREATE,0,0);
	PostMessage(WM_MOVE,0,0);
	return TRUE;
}

BOOL CWnd::Create(LPCTSTR pszText,DWORD nStyle,LPCRECT pRect,CPWnd* pParent,int nID)
{
	ASSERT(!(nStyle&WS_OWNERDATA));
	Create(nStyle,pRect,pParent);

	m_pData=(PVOID)CString::StrAllocEx(pszText);

	return TRUE;
}

CWnd* CWnd::GetWindow(UINT nCmd)
{
	PWND pWnd;
	switch(nCmd)
	{
	case GW_CHILD:
		pWnd=(m_nStyle&WS_PARENT)?PPWND(this)->GetChild():NULL;
		break;
	case GW_PARENT:
		pWnd=m_pParent;
		break;
	case GW_DESKTOP:
		pWnd=GetDesktopWindow();
		break;
	case GW_FOCUS:
		pWnd=m_pParent->GetActiveControl();
		break;
	case GW_HWNDFIRST:
		pWnd=m_pParent->GetChild();
		break;
	case GW_HWNDLAST:
		pWnd=m_pParent->GetChild()->m_pPrev;
		break;
	case GW_HWNDNEXT:
		pWnd=m_pNext;
		break;
	case GW_HWNDPREV:
		pWnd=m_pPrev;
		break;
	default:
		pWnd=NULL;
	}
	return pWnd;
}

CDesktop* CWnd::GetDesktopWindow()
{
	PWND pWnd=this;
	while(pWnd->m_pParent)
		pWnd=pWnd->m_pParent;
	return (CDesktop*)pWnd;
}

int CWnd::GetChildHierarchy(CWnd* pParent)
{
	CWnd* pWnd=this;
	int nLevel=-1;
	do
	{
		nLevel++;
		if(pWnd==pParent)break;
		pWnd=pWnd->m_pParent;
	}while(pWnd);
	return pWnd?nLevel:-1;
}

CWnd* CWnd::WindowFromPoint(POINT pt)
{
	PWND pChild,pWnd,pTmp;
	if(!m_rclWnd.PtInRect(pt))
		return NULL;
	pTmp=this;
	do
	{
		pWnd=pTmp;
		if(!(pWnd->m_nStyle&WS_PARENT))
			break;
		if(!pWnd->m_rclClient.PtInRect(pt))
			break;
		pChild=PPWND(pWnd)->GetChild();
		if(!pChild)
			break;
		pTmp=pChild->m_pPrev;
		for(;;)
		{
			if(pTmp->m_rclWnd.PtInRect(pt))
				break;
			if(pTmp==pChild)
			{
				pTmp=NULL;
				break;
			}
			pTmp=pTmp->m_pPrev;
		}
	}while(pTmp);
	return pWnd;
}

void CWnd::MoveWindow(LPCRECT pRect)
{
	ASSERT(m_pParent);
	CRect r(m_rclWnd);

	r.IntersectRect(pRect);
	if(r.IsRectEmpty())
		m_pParent->Invalidate(m_rclWnd);
	else
	{
		r=m_rclWnd;
		r.UnionRect(pRect);
		m_pParent->Invalidate(r);
	}
	m_rclWnd=pRect;
	PrvOffsetWindow(m_pParent->m_rclClient.TopLeft());
	m_rclClient=m_rclWnd;
	PostMessage(WM_MOVE,0,0);
	if(r.IsRectEmpty())Invalidate(m_rclWnd);
}

CDC* CWnd::GetDC()
{
	PWND pDCWnd=this;
	while(!(pDCWnd->m_nStyle & WS_OWNERDC))
	{
		pDCWnd=pDCWnd->m_pParent;
		ASSERT(pDCWnd);
	}
	return (PDC)pDCWnd->MsgProc(WM_GETOWNDC,WPARAM(this),0);
}

void CWnd::Invalidate(LPCRECT pRect)
{
	CRect r;
	if(!pRect)
		r=m_rclClient;
	else
	{
		r=pRect;
		r.IntersectRect(m_rclWnd);
	}

	if(m_nStyle & WS_INVALIDATE)
		m_rclInv.UnionRect(r);
	else
	{
		m_nStyle |= WS_INVALIDATE;
		m_rclInv=r;
	}

	PostMessage(WM_INVALIDATE,0,0);
}

void CWnd::SetWindowText(CString &string)
{
	ASSERT(!(m_nStyle&WS_OWNERDATA));
	int nLen=string.GetLength();
	LPCTSTR pNew=nLen>0?LPCTSTR(string):NULL;
	m_pData=(PVOID)CString::StrReAllocEx(
		LPCTSTR(m_pData),pNew,nLen);
	Invalidate(NULL);
}

void CWnd::SetWindowText(LPCTSTR pszString)
{ 
	ASSERT(!(m_nStyle&WS_OWNERDATA));
	int nLen;
	if(IsWritablePtr(pszString))
	{
		nLen=strlen(pszString);
		if(nLen<=0)pszString=NULL;
	}
	else
		nLen=0;
	m_pData=(PVOID)CString::StrReAllocEx(
		LPCTSTR(m_pData),pszString,nLen);
	Invalidate(NULL);
}

int CWnd::GetWindowText(LPTSTR pszStringBuf,int nMaxCount)
{
	ASSERT(!(m_nStyle&WS_OWNERDATA));
	int nCount=GetWindowTextLength()+1;
	if(nCount>=nMaxCount)
		nCount=nMaxCount;
	CopyMemory(pszStringBuf,m_pData,nCount*sizeof(TCHAR));
	return nCount-1;
}

int CWnd::GetScrollRange(int nBar,PINT pMinPos,PINT pMaxPos)
{
	DWORD nVal;
	MsgProc(WM_GETSCROLLRANGE,nBar,LPARAM(&nVal));
	if(pMinPos)
		*pMinPos=(short)LOWORD(nVal);
	if(pMaxPos)
		*pMaxPos=(short)HIWORD(nVal);
	return short(HIWORD(nVal))-short(LOWORD(nVal));
}

void CWnd::SetScrollRange(int nBar,int nMinPos,int nMaxPos)
{
	DWORD nVal=MAKELONG(nMinPos,nMaxPos);
	MsgProc(WM_SETSCROLLRANGE,nBar,nVal);
}


LRESULT CWnd::MsgProc(UINT message, WPARAM wParam, LPARAM lParam)
{
	switch(message)
	{
	case WM_PAINTING:
		PrvOnPainting(wParam,lParam);
		break;
	case WM_ERASEBKGND:
		OnEraseBkgnd(PDC(wParam));
		break;
	case WM_NCPAINT:
		OnNcPaint(PDC(wParam));
		break;
	case WM_INVALIDATE:
		PrvOnInvalidate();
		break;
	case WM_MOVE:
		OnMove();
		break;
	case WM_QUERYMOUSECURSOR:
		wParam=(WPARAM)OnQueryMouseCursor();
		break;
	case WM_DESTROY:
		OnDestroy();
		break;
	case msgGetMQThread:
		wParam=m_pParent->MsgProc(msgGetMQThread,0,0);
		break;
	case WM_CTLCOLOR:
		wParam=m_pParent->MsgProc(WM_CTLCOLOR,wParam,lParam);
		break;
	case WM_GETFONT:
		wParam=m_pParent->MsgProc(WM_GETFONT,wParam,lParam);
		break;
	case WM_DRAWITEM:
		m_pParent->MsgProc(WM_DRAWITEM,wParam,lParam);
		break;
	default:
		wParam=0;
	}
	return wParam;
}

void CWnd::OnDestroy()
{
	if(!(m_nStyle&WS_OWNERDATA))
		CString::StrFreeEx(LPCTSTR(m_pData));
	DEBUG_ONLY(m_pData=NULL);
}

void CWnd::OnMove()
{
	int nBorder=0;
	if(m_nStyle & WS_STATICEDGE)
		nBorder++;
	if(m_nStyle & WS_BORDER)
		nBorder++;
	if(m_nStyle & WS_CLIENTEDGE)
		nBorder+=2;
	if(nBorder)
		m_rclClient.DeflateRect(nBorder);
}

void CWnd::OnNcPaint(CDC* pDC)
{
	CRect r(m_rclWnd);
	DWORD nStyle=m_nStyle;
	if(nStyle & WS_STATICEDGE)
	{
		if(nStyle & WS_BORDER) //WS_DLGMODALFRAME
		{
			pDC->Draw3dRect(r,GetCtlColor(COLOR_3DLIGHT),GetCtlColor(COLOR_3DDKSHADOW));
			r.DeflateRect(1);
			pDC->Draw3dRect(r,GetCtlColor(COLOR_3DHLIGHT),GetCtlColor(COLOR_3DSHADOW));
			r.DeflateRect(1);
		}
		else
		{
			pDC->Draw3dRect(r,GetCtlColor(COLOR_3DHLIGHT),GetCtlColor(COLOR_3DSHADOW));
			r.DeflateRect(1);
		}
	}
	else if(nStyle & WS_BORDER)
	{
		pDC->DrawRect(r,GetCtlColor(COLOR_WINDOWTEXT),PS_SOLID);
	}
	if(m_nStyle & WS_CLIENTEDGE)
	{
		pDC->Draw3dRect(r,GetCtlColor(COLOR_3DSHADOW),GetCtlColor(COLOR_3DHLIGHT));
		r.DeflateRect(1);
		pDC->Draw3dRect(r,GetCtlColor(COLOR_3DDKSHADOW),GetCtlColor(COLOR_3DLIGHT));
	}
}

void CWnd::OnEraseBkgnd(CDC* pDC)
{
	DWORD nStyle=GetStyle();
	COLORREF clr;
	
	if(nStyle&WS_SCRBKGND)
		GetDesktopWindow()->OnEraseBkgnd(pDC);
	if(!(nStyle&WS_NOBKGND) == !(nStyle&WS_SCRBKGND))
	{
		clr=GetCtlColor(COLOR_WINDOW);
		if(nStyle&WS_NOBKGND)
		{
			clr &= ~(255<<24);
			clr |= 128<<24;
		}
		pDC->FillSolidRect(GetClientRect(),clr);
	}
}

void CWnd::PrvOffsetWindow(POINT pt)
{
	m_rclWnd.OffsetRect(pt);
	if(m_nStyle&WS_PARENT)
	{
		PWND pWnd,pChild=PPWND(this)->GetChild();
		if(pChild)
		{
			pWnd=pChild;
			do
			{
				pWnd->m_rclClient.OffsetRect(pt);
				pWnd->PrvOffsetWindow(pt);
				pWnd=pWnd->m_pNext;
			}while(pWnd!=pChild);
		}
	}
}

HANDLE CWnd::PrvAddPaintMessage(CThread* pThread,HANDLE hRefMsg,LPCRECT pRect)
{
	CRect r(m_rclWnd);
	r.IntersectRect(pRect);
	if(!r.IsRectEmpty())
	{
		PWND pWnd,pChild;
		DWORD pt1=MAKELONG(r.left,r.top);
		DWORD pt2=MAKELONG(r.right,r.bottom);
		if(!(m_nStyle & WS_PRVINVALID) && (m_nStyle & WS_OWNERDC))
			hRefMsg=pThread->InsertMessage(this,hRefMsg,pt2,pt1);
		else
		{
			hRefMsg=pThread->InsertMessage(this,hRefMsg,pt1,pt2);
			if(m_nStyle&WS_PARENT)
			{
				pChild=PPWND(this)->GetChild();
				if(pChild)
				{
					r=m_rclClient;
					r.IntersectRect(pRect);
					pWnd=pChild;
					do
					{
						hRefMsg=pWnd->PrvAddPaintMessage(pThread,hRefMsg,r);
						pWnd=pWnd->m_pNext;
					}while(pWnd!=pChild);
				}
			}
		}
	}
	return hRefMsg;
}

void CWnd::PrvOnInvalidate()
{
	HANDLE hMsg1,hMsg2;
	PTHREAD pThread;
	PWND pDCWnd,pTop,pTmp;
	PPWND pEnd=PPWND(this);
	CRect rclClip(m_rclInv);

	//查找最后一个需要更新的窗体
	pEnd->m_nStyle |= WS_PRVINVALID;
	for(;;)
	{
		if(!(pEnd->m_nStyle & WS_TRANSPARENT))
			break;
		if(pEnd->m_nStyle & WS_OWNERDC)
			break;
		pTmp=pEnd;
		pEnd=pEnd->m_pParent;
		ASSERT(pEnd);
		rclClip.IntersectRect(pEnd->m_rclClient);
		if(pEnd->m_nStyle & WS_CLIPSIBLINGS)
		{
			pTop=pEnd->GetChild()->m_pPrev;
			for(pTmp=pTmp->m_pPrev;pTmp!=pTop;pTmp=pTmp->m_pPrev)
			{
				if(!(pTmp->m_nStyle & WS_TRANSPARENT) &&
					pTmp->m_rclWnd.IncludeRect(rclClip))
				{
					pEnd=PPWND(pTmp);
					break;
				}
			}
			if(pEnd==pTmp)break;
		}
		pEnd->m_nStyle |= WS_PRVINVALID;
		if(!(pEnd->m_nStyle & WS_TRANSPARENT))
			break;
		if(pEnd->m_nStyle & WS_OWNERDC)
			break;
	}
	//向需要更新的窗体发送缓图消息
	pDCWnd=pTmp=pEnd;
	pEnd=pEnd->m_pParent;
	while(!(pDCWnd->m_nStyle & WS_OWNERDC))
	{
		pDCWnd=pDCWnd->m_pParent;
		ASSERT(pDCWnd);
		pDCWnd->m_nStyle |= WS_PRVINVALID;
		rclClip.IntersectRect(pDCWnd->m_rclClient);
	}
	pThread=pDCWnd->GetMQThread();
	hMsg1=pThread->InsertMessage(pDCWnd,WM_PAINTING,WM_PAINTSTART,LPARAM(this));
	hMsg2=pTmp->PrvAddPaintMessage(pThread,hMsg1,&rclClip);
	while(pEnd)
	{
		if(pEnd->m_nStyle & WS_CLIPSIBLINGS)
		{
			pTop=pEnd->GetChild();
			for(pTmp=pTmp->m_pNext;pTmp!=pTop;pTmp=pTmp->m_pNext)
			{
				if(!(pTmp->m_nStyle & WS_TRANSPARENT) &&
					pTmp->m_rclWnd.IncludeRect(rclClip))
				{
					pTmp=NULL;
					break;
				}
				hMsg2=pTmp->PrvAddPaintMessage(pThread,hMsg2,&rclClip);
			}
			if(!pTmp)break;
		}
		pTmp=pEnd;
		pEnd=pEnd->m_pParent;
	}
	if(pTmp)
	{
		pThread->InsertMessage(pDCWnd,hMsg2,WM_PAINTOVER,LPARAM(this));
		pDCWnd->MsgProc(WM_SETPAINTCLIP,WPARAM(&rclClip),LPARAM(this));
	}
	else
		pThread->RemoveMessage(hMsg1,hMsg2);
	pTmp=this;
	do
	{
		pTmp->m_nStyle &= ~WS_PRVINVALID;
		pTmp=pTmp->m_pParent;
	}while(pTmp && (pTmp->m_nStyle&WS_PRVINVALID)); 
}

void CWnd::PrvOnPainting(WPARAM wParam,LPARAM lParam)
{
	PDC pDC=GetDC();
	CRect r,r2(m_rclClient);
	r.SetRect(CPoint(wParam),CPoint(lParam));
	if(r.IncludeRect(m_rclInv))
		m_nStyle &= ~WS_INVALIDATE;
	if(!r2.IncludeRect(r))
	{
		pDC->SetClipRect(r);
		MsgProc(WM_NCPAINT,WPARAM(pDC),0);
	}
	r.IntersectRect(r2);
	if(!r.IsRectEmpty())
	{
		pDC->SetClipRect(r);
		MsgProc(WM_ERASEBKGND,WPARAM(pDC),0);
		MsgProc(WM_PAINT,WPARAM(pDC),0);
	}
}

⌨️ 快捷键说明

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