📄 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_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 + -