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

📄 gwnd.cpp

📁 一个简单而又高效的嵌入式操作系统.包括GUI及文件系统.仿Windows设计,类似于MFC风格
💻 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_nMsgCount<GUI_MAXMSG)
	{
		if(nMessage<0)
		{
			i=m_nMsgStart>0?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=max(x1,cLeft);x2=min(x2,cRight);
				for(;x1<=x2;x1+=s)GUI_PIXEL(x1,y1,c);
			}
			else
			{
				x1=min(x1,cRight);x2=max(x2,cLeft);
				for(;x1>=x2;x1-=s)GUI_PIXEL(x1,y1,c);
			}
		}
	}
	else if(x1==x2)
	{
		if(x1>=cLeft && x1<=cRight)
		{
			if(y1<y2)
			{
				y1=max(y1,cTop);y2=min(y2,cBottom);
				for(;y1<=y2;y1+=s)GUI_PIXEL(x1,y1,c);
			}
			else
			{
				y1=min(y1,cBottom);y2=max(y2,cTop);
				for(;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)<ABS(x2))
		{
			if(x2<0){left=right;top=bottom;}
			for(i=ABS(x2);i>=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 && y<y2)
	{
		for(x=x1;x<x2;x+=s)GUI_PIXEL(x,y,c);
	}
	x=rect.right;
	if(x>x1 && x<=x2)
	{
		for(y=y1;y<y2;y+=s)GUI_PIXEL(x,y,c);
	}
	y=rect.bottom;
	if(y>y1 && y<=y2)
	{
		for(x=x2;x>x1;x-=s)GUI_PIXEL(x,y,c);
	}
	x=rect.left;
	if(x>=x1 && x<x2)
	{
		for(y=y2;y>y1;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<nRows;y++)
		{
			for(x=0;x<nCols;x++)
			{
				x0=(x+nXSrc)*bmW/nWidth;
				y0=(y+nYSrc)*bmH/nHeight;
				i=aData[y0*w+(x0>>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;y<nRows;y++)
		{
			for(x=0;x<nCols;x++)
			{
				x0=(x+nXSrc)*bmW/nWidth;
				y0=(y+nYSrc)*bmH/nHeight;
				i=aData[y0*w+x0];
				x0=x+nXDest;y0=y+nYDest;
				if(i!=crTrans)GUI_PIXEL(x0,y0,i);
			}
		}
	}
	else if(bm->bmBitsPixel==1)
	{
		crTrans=m_nForeColor;
		for(y=0;y<nRows;y++)
		{
			for(x=0;x<nCols;x++)
			{
				x0=(x+nXSrc)*bmW/nWidth;
				y0=(y+nYSrc)*bmH/nHeight;
				i=aData[y0*w+(x0>>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;
}

⌨️ 快捷键说明

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