www.pudn.com > GOS.rar > GWnd.cpp


// GWnd.cpp: implementation of the GWnd class. 
// 
////////////////////////////////////////////////////////////////////// 
 
#include "..\StdAfx.h" 
#include "GWnd.h" 
 
 
GWnd* GWnd::m_pFocus=NULL; 
int GWnd::m_nWndCount=0; 
MSG* GWnd::m_aMsg=NULL; 
GWnd** GWnd::m_aWnd=NULL; 
int GWnd::m_nMsgStart=0; 
int GWnd::m_nMsgCount=0; 
const int GWnd::m_aColor16Palette[16]= 
{ 
	RGB(0,0,0),RGB(128,0,0),RGB(0,128,0),RGB(128,128,0), 
	RGB(0,0,128),RGB(128,0,128),RGB(0,128,128),RGB(192,192,192), 
	RGB(128,128,128),RGB(255,0,0),RGB(0,255,0),RGB(255,255,0), 
	RGB(0,0,255),RGB(255,0,255),RGB(0,255,255),RGB(255,255,255) 
}; 
////////////////////////////////////////////////////////////////////// 
// Construction/Destruction 
////////////////////////////////////////////////////////////////////// 
 
 
GWnd::GWnd() 
{ 
 
} 
 
GWnd::~GWnd() 
{ 
 
} 
 
BOOL GWnd::PtInRect(int x, int y, RECT &rect) 
{ 
	return x>=rect.left && x<=rect.right && y>=rect.top && y<=rect.bottom; 
} 
 
void GWnd::WM_Click(int x, int y,BOOL bDown) 
{ 
	static GWnd* pWnd=NULL; 
	int i; 
 
	if(bDown) 
	{ 
		if(pWnd) 
		{ 
			pWnd->PostMessage(WM_LBUTTONUP,POINT_INVALID,POINT_INVALID); 
			pWnd=NULL; 
		} 
		i=m_nWndCount; 
		while(i--) 
		{ 
			if(m_aWnd[i]->m_pParent) 
			{ 
				if(PtInRect(x,y,m_aWnd[i]->m_rectWndClip)) 
				{ 
					pWnd=m_aWnd[i]; 
					if(!(pWnd->m_nStyle & WS_NOFOCUS)) 
					{ 
						if(m_pFocus && m_pFocus!=pWnd) 
						{ 
							m_pFocus->m_nState &= ~ODS_FOCUS; 
							m_pFocus->PostMessage(WM_PAINT,ODA_FOCUS,-1); 
						} 
						m_pFocus=pWnd; 
						m_pFocus->m_nState |= ODS_FOCUS; 
					} 
					break; 
				} 
			} 
			else 
			{ 
				pWnd=m_aWnd[i]; 
				break; 
			} 
		} 
		if(pWnd)pWnd->PostMessage(WM_LBUTTONDOWN,x,y); 
	} 
	else 
	{ 
		if(pWnd) 
		{ 
			pWnd->PostMessage(WM_LBUTTONUP,x,y); 
			pWnd=NULL; 
		} 
	} 
} 
 
void GWnd::WndProc(int nMessage,int wParam,int lParam) 
{ 
	nMessage=0; 
	wParam=0; 
	lParam=0; 
} 
 
 
void GWnd::PostMessage(int nMessage,int wParam, int lParam) 
{ 
	MSG msg; 
	int i; 
	if(m_nMsgCount0?m_nMsgStart:GUI_MAXMSG-1; 
			m_nMsgStart=i; 
			nMessage=-nMessage; 
		} 
		else 
		{ 
			i=m_nMsgStart+m_nMsgCount; 
			if(i>=GUI_MAXMSG)i-=GUI_MAXMSG; 
		} 
		msg.hwnd=(HWND)this; 
		msg.message=nMessage; 
		msg.wParam=wParam; 
		msg.lParam=lParam; 
		m_aMsg[i]=msg; 
		m_nMsgCount++; 
	} 
} 
 
void GWnd::DoEvents() 
{ 
	MSG msg; 
	GWnd* pWnd; 
	if(m_nMsgCount>0) 
	{ 
		do 
		{ 
			m_nMsgCount--; 
			msg=m_aMsg[m_nMsgStart++]; 
			if(m_nMsgStart>=GUI_MAXMSG)m_nMsgStart=0; 
			{ 
				 
				pWnd=(GWnd*)msg.hwnd; 
				pWnd->WndProc(msg.message,msg.wParam,msg.lParam); 
			} 
		}while(m_nMsgCount>0); 
	} 
	else OS_OnIdle(); 
} 
 
RECT GWnd::MakeRect(int x, int y, int nWidth, int nHeight) 
{ 
	RECT rect; 
	rect.left=x;rect.right=x+nWidth-1; 
	rect.top=y;rect.bottom=y+nHeight-1; 
	return rect; 
} 
 
 
POINT GWnd::GetLocation() 
{ 
	POINT point; 
	point.x=m_rectWnd.left; 
	point.y=m_rectWnd.top; 
	if(m_pParent) 
	{ 
		point.x-=m_pParent->m_Rect.left; 
		point.y-=m_pParent->m_Rect.top; 
	} 
	return point; 
} 
 
SIZE GWnd::GetSize(BOOL bClient) 
{ 
	SIZE size; 
	if(bClient) 
	{ 
		size.cx=m_Rect.right-m_Rect.left+1; 
		size.cy=m_Rect.bottom-m_Rect.top+1; 
	} 
	else 
	{ 
		size.cx=m_rectWnd.right-m_rectWnd.left+1; 
		size.cy=m_rectWnd.bottom-m_rectWnd.top+1; 
	} 
	return size; 
} 
 
void GWnd::MoveWindow(RECT rect) 
{ 
	if(m_pParent) 
	{ 
		rect.left+=m_pParent->m_Rect.left; 
		rect.top+=m_pParent->m_Rect.top; 
		rect.right+=m_pParent->m_Rect.left; 
		rect.bottom+=m_pParent->m_Rect.top; 
		m_rectWnd=rect; 
 
		WndProc(WM_MOVE,rect.left,rect.right); 
 
		rect=m_pParent->m_rectClip; 
 
	} 
	else 
	{ 
		m_rectWnd=rect; 
 
		WndProc(WM_MOVE,rect.left,rect.bottom); 
 
		rect.left=0;rect.top=0; 
		rect.right=GUI_CXSCREEN-1; 
		rect.bottom=GUI_CYSCREEN-1; 
 
	} 
	m_rectClip.left=max(m_Rect.left,rect.left); 
	m_rectClip.top=max(m_Rect.top,rect.top); 
	m_rectClip.right=min(m_Rect.right,rect.right); 
	m_rectClip.bottom=min(m_Rect.bottom,rect.bottom); 
 
	m_rectWndClip.left=max(m_rectWnd.left,rect.left); 
	m_rectWndClip.top=max(m_rectWnd.top,rect.top); 
	m_rectWndClip.right=min(m_rectWnd.right,rect.right); 
	m_rectWndClip.bottom=min(m_rectWnd.bottom,rect.bottom); 
} 
 
void GWnd::MoveWindow(int x, int y, int nWidth, int nHeight) 
{ 
	RECT rect; 
	rect.left=x;rect.right=x+nWidth-1; 
	rect.top=y;rect.bottom=y+nHeight-1; 
	MoveWindow(rect); 
} 
 
//»æÖƺ¯Êý 
void GWnd::Line(int x1,int y1,int x2,int y2) 
{ 
	int i,c,s; 
	int left,right,top,bottom; 
	int cLeft,cRight,cTop,cBottom; 
 
	c=m_nForeColor; 
	s=1+((m_nForeColor>>24) & 0x03); 
	cLeft=m_rectClip.left; 
	cRight=m_rectClip.right; 
	cTop=m_rectClip.top; 
	cBottom=m_rectClip.bottom; 
 
	if(y1==y2) 
	{ 
		if(y1>=cTop && y1<=cBottom) 
		{ 
			if(x1=x2;x1-=s)GUI_PIXEL(x1,y1,c); 
			} 
		} 
	} 
	else if(x1==x2) 
	{ 
		if(x1>=cLeft && x1<=cRight) 
		{ 
			if(y1=y2;y1-=s)GUI_PIXEL(x1,y1,c); 
			} 
		} 
	} 
	else 
	{ 
		left=x1;top=y1; 
		right=x2;bottom=y2; 
		x2=right-left;y2=bottom-top; 
		if(ABS(y2)=0;i-=s) 
			{ 
				x1=left+i; 
				y1=top+(i*y2)/x2; 
				if(x1>=cLeft && x1<=cRight && y1>=cTop && y1<=cBottom)GUI_PIXEL(x1,y1,c); 
			} 
		} 
		else 
		{ 
			if(y2<0){left=right;top=bottom;} 
			for(i=ABS(y2);i>=0;i-=s) 
			{ 
				y1=top+i; 
				x1=left+(i*x2)/y2; 
				if(x1>=cLeft && x1<=cRight && y1>=cTop && y1<=cBottom)GUI_PIXEL(x1,y1,c); 
			} 
		} 
	} 
} 
 
void GWnd::Rectangle(RECT rect) 
{ 
	int x1,y1,x2,y2,x,y; 
	int c,s; 
 
	c=m_nForeColor; 
	s=1+((m_nForeColor>>24) & 0x03); 
	x1=max(rect.left,m_rectClip.left); 
	y1=max(rect.top,m_rectClip.top); 
	x2=min(rect.right,m_rectClip.right); 
	y2=min(rect.bottom,m_rectClip.bottom); 
	 
	y=rect.top; 
	if(y>=y1 && yx1 && x<=x2) 
	{ 
		for(y=y1;yy1 && y<=y2) 
	{ 
		for(x=x2;x>x1;x-=s)GUI_PIXEL(x,y,c); 
	} 
	x=rect.left; 
	if(x>=x1 && xy1;y-=s)GUI_PIXEL(x,y,c); 
	} 
} 
 
void GWnd::FillRect(RECT rect,int nColor) 
{ 
	int x1,y1,x2,y2; 
 
	x1=max(rect.left,m_rectClip.left); 
	y1=max(rect.top,m_rectClip.top); 
	x2=min(rect.right,m_rectClip.right); 
	y2=min(rect.bottom,m_rectClip.bottom); 
	GUI_FILLRECT(x1,y1,x2,y2,nColor); 
} 
 
void GWnd::FillRect(RECT rect, int c1, int c2) 
{ 
	int x,y,x1,y1,x2,y2; 
 
	x1=max(rect.left,m_rectClip.left); 
	y1=max(rect.top,m_rectClip.top); 
	x2=min(rect.right,m_rectClip.right); 
	y2=min(rect.bottom,m_rectClip.bottom); 
 
	for(y=y1;y<=y2;y++) 
	{ 
		for(x=x1;x<=x2;x++) 
		{ 
			if((y+x) & 0x01) 
			{ 
				GUI_PIXEL(x,y,c1); 
			} 
			else 
			{ 
				GUI_PIXEL(x,y,c2); 
			} 
		} 
	} 
} 
 
 
void GWnd::DrawBitmap(const BITMAP *bm, RECT rect) 
{ 
	int w,i,x,y,x0,y0,nWidth,nHeight,bmW,bmH; 
	int nXDest,nYDest,nRows,nCols,nXSrc,nYSrc; 
	int crTrans=bm->bmPlanes; 
	PBYTE aData=(PBYTE)bm->bmBits; 
	 
	w=bm->bmWidth*bm->bmBitsPixel; 
	w=(w & 0x07)?(w>>3)+1:(w>>3); 
	nWidth=rect.right-rect.left+1; 
	nHeight=rect.bottom-rect.top+1; 
	bmW=bm->bmWidth; 
	bmH=bm->bmHeight; 
	nXDest=max(rect.left,m_rectClip.left); 
	nYDest=max(rect.top,m_rectClip.top); 
	nCols=min(rect.right,m_rectClip.right)-nXDest+1; 
	nRows=min(rect.bottom,m_rectClip.bottom)-nYDest+1; 
	nXSrc=nXDest-rect.left; 
	nYSrc=nYDest-rect.top; 
 
	if(bm->bmBitsPixel==4) 
	{ 
		nCols=((nCols & 0x01) && nCols==bm->bmWidth)?nCols-1:nCols; 
		for(y=0;y>1)]; 
				i=(x0 & 0x01)?(i>>4):(i & 0x0f); 
				x0=x+nXDest;y0=y+nYDest; 
				if(i!=crTrans)GUI_PIXEL(x0,y0, m_aColor16Palette[i]); 
			} 
		} 
	} 
	else if(bm->bmBitsPixel==8) 
	{ 
		for(y=0;ybmBitsPixel==1) 
	{ 
		crTrans=m_nForeColor; 
		for(y=0;y>3)]; 
				if(i & (1<<(x0 & 07)))GUI_PIXEL(x0,y0,crTrans); 
			} 
		} 
	} 
} 
 
SIZE GWnd::GetTextExtent(int nCount) 
{ 
	SIZE size; 
	int s=1+((m_nForeColor>>26) & 0x03); 
	size.cx=s*m_pFont->nWidth*nCount; 
	size.cy=s*m_pFont->nHeight; 
	return size; 
} 
void GWnd::DrawText(LPCTSTR szString, RECT rect, int nFormat) 
{ 
	int i,c,fh,fw,x,y,x0,y0,x1,y1,x2,y2; 
	int nXSrc,nYSrc,nCharWidth,nWidth,nHeight; 
	const FONT* pFont; 
	PBYTE pData; 
	LPCTSTR str=szString; 
	if(!szString)return; 
 
	i=1+((m_nForeColor>>26) & 0x03); 
	nCharWidth=i*m_pFont->nWidth; 
	nHeight=i*m_pFont->nHeight; 
	while(*str++);i=str-szString-1; 
	nWidth=i*nCharWidth; 
 
	if(nFormat & DT_CENTER)x1=(rect.left+rect.right+1-nWidth)/2; 
	else if(nFormat & DT_RIGHT)x1=rect.right-nWidth+1; 
	else x1=rect.left; 
 
	if(nFormat & DT_VCENTER)y1=(rect.top+rect.bottom+1-nHeight)/2; 
	else if(nFormat & DT_BOTTOM)y1=rect.bottom-nHeight+1; 
	else y1=rect.top; 
 
	rect.left=max(rect.left,m_rectClip.left); 
	rect.top=max(rect.top,m_rectClip.top); 
	rect.right=min(rect.right,m_rectClip.right); 
	rect.bottom=min(rect.bottom,m_rectClip.bottom); 
	 
	y2=y1+nHeight-1; 
	if(y1>=rect.top)nYSrc=0; 
	else {nYSrc=rect.top-y1;y1=rect.top;} 
	if(y2>rect.bottom)y2=rect.bottom;  
 
	str=szString; 
	c=m_nForeColor; 
	while(*str) 
	{ 
		i=GUI_CHARCODE(str); 
		if(i>0xff) 
		{ 
			pFont=&GUI_MBCSFONT; 
			nWidth=nCharWidth<<1; 
			str+=2; 
		} 
		else 
		{ 
			pFont=m_pFont; 
			nWidth=nCharWidth; 
			str++; 
		} 
		x2=x1+nWidth-1; 
		if(x1>=rect.left)nXSrc=0; 
		else {nXSrc=rect.left-x1;x1=rect.left;} 
		if(x2>rect.right)x2=rect.right; 
		 
		i-=pFont->nFirstChar; 
		if(i>=0 && i<=pFont->nLastChar) 
		{ 
 
			fw=pFont->nWidth; 
			fh=pFont->nHeight; 
			pData=(PBYTE)pFont->pData; 
			pData+=(fh*fw/8)*i; 
			for(y=y2-y1;y>=0;y--) 
			{ 
				for(x=x2-x1;x>=0;x--) 
				{ 
					x0=(x+nXSrc)*fw/nWidth; 
					y0=(y+nYSrc)*fh/nHeight; 
					i=y0*fw+x0; 
					if(pData[i>>3] & (1<<(i & 0x07))) 
					{ 
						x0=x+x1; 
						y0=y+y1; 
						GUI_PIXEL(x0,y0,c); 
					} 
				} 
			} 
		} 
		x1=x2+1; 
	} 
} 
 
int GWnd::EdgeRGB(int r, int g, int b) 
{ 
	r=(r>128?r-1:r)>>6; 
	g=(g>128?g-1:g)>>6; 
	b=(b>128?b-1:b)>>6; 
	return (r+(g<<2)+(b<<4))<<24; 
} 
 
int GWnd::EdgeRGB(int c) 
{ 
	int r,g,b; 
 
	r=(m_nBackColor >>24) & 0x03; 
	g=(m_nBackColor >>26) & 0x03; 
	b=(m_nBackColor >>28) & 0x03; 
 
	r=r*c/3; 
	g=g*c/3; 
	b=b*c/3; 
	return RGB(r,g,b); 
} 
 
void GWnd::Draw3dRect(RECT& rect, int crTopLeft, int crBottomRight) 
{ 
	m_nForeColor=crTopLeft; 
	Line(rect.left,rect.top,rect.right-1,rect.top); 
	Line(rect.left,rect.top+1,rect.left,rect.bottom-1); 
	m_nForeColor=crBottomRight; 
	Line(rect.left,rect.bottom,rect.right,rect.bottom); 
	Line(rect.right,rect.top,rect.right,rect.bottom); 
} 
 
void GWnd::DrawEdge(RECT& rect, int nEdge) 
{ 
	RECT r2=rect; 
	r2.left+=1;r2.right-=1; 
	r2.top+=1;r2.bottom-=1; 
	switch(nEdge) 
	{ 
	case EDGE_RAISED: 
		Draw3dRect(rect,EdgeRGB(255),EdgeRGB(64)); 
		Draw3dRect(r2,EdgeRGB(192),EdgeRGB(128)); 
		break; 
	case EDGE_SUNKEN: 
		Draw3dRect(rect,EdgeRGB(128),EdgeRGB(255)); 
		Draw3dRect(r2,EdgeRGB(0),EdgeRGB(192)); 
		break; 
	case EDGE_ETCHED: 
		Draw3dRect(rect,EdgeRGB(128),EdgeRGB(192)); 
		Draw3dRect(r2,EdgeRGB(192),EdgeRGB(128)); 
		break; 
	case EDGE_BUMP: 
		Draw3dRect(rect,EdgeRGB(192),EdgeRGB(0)); 
		Draw3dRect(r2,EdgeRGB(0),EdgeRGB(0)); 
		break; 
	} 
} 
 
 
 
void GWnd::OnMove() 
{ 
	int nBorder; 
	 
	if(m_nStyle & WS_FLAT)nBorder=(m_nStyle & WS_CAPTION)?1:0; 
	else if(m_nStyle & WS_DLGFRAME)nBorder=2; 
	else if(m_nStyle & WS_BORDER)nBorder=1; 
	else nBorder=0; 
	if(m_nStyle & WS_CLIENT)nBorder+=2; 
 
	m_Rect=m_rectWnd; 
	m_Rect.left+=nBorder; 
	m_Rect.right-=nBorder; 
	m_Rect.top+=nBorder; 
	m_Rect.bottom-=nBorder; 
} 
 
void GWnd::OnNcPaint() 
{ 
	int c=m_nForeColor; 
	RECT r0=m_rectClip; 
 
	int nBorder; 
	RECT r=m_rectWnd; 
	 
	m_rectClip=m_rectWndClip; 
 
	if(m_nStyle & WS_FLAT) 
	{ 
		if(m_nStyle & WS_CAPTION) 
		{ 
			m_nForeColor=EdgeRGB(255); 
			Rectangle(r); 
			nBorder=1; 
		} 
	} 
	else if(m_nStyle & WS_DLGFRAME) 
	{ 
		DrawEdge(r,EDGE_RAISED); 
		nBorder=2; 
	} 
	else if(m_nStyle & WS_BORDER) 
	{ 
		Draw3dRect(r,EdgeRGB(255),EdgeRGB(64)); 
		nBorder=1; 
	} 
	if(m_nStyle& WS_CLIENT) 
	{ 
		r=m_Rect; 
		r.left-=2;r.top-=2; 
		r.right+=2;r.bottom+=2; 
		DrawEdge(r,EDGE_SUNKEN); 
	} 
 
	m_rectClip=r0; 
	m_nForeColor=c; 
}