📄 xpdialog.cpp
字号:
int bNcActive; //指示窗体激活状态
SCLASSXP *p; //链表指针
::GetWindowRect(hWnd, &wndrt);
hdc = ::GetWindowDC(hWnd);
hMemdc = ::CreateCompatibleDC(hdc);
windowStyle=GetWindowLong(hWnd, GWL_STYLE);
windowExStyle=GetWindowLong(hWnd, GWL_EXSTYLE);
frame=( windowStyle & WS_THICKFRAME )? //得到边框宽度,不同的窗体风格有不同的边框宽度
::GetSystemMetrics(SM_CXFRAME) : ::GetSystemMetrics(SM_CYFIXEDFRAME);
captionHi=::GetSystemMetrics(SM_CYCAPTION)+frame; //得到标题栏高度
p=s_pThis->Find(hWnd);
bNcActive=p->bNcActive; //得到当前窗体的活动状态
//开始在缓冲区中画标题栏
rt.SetRect(0, 0, wndrt.Width(), captionHi);
hBmp=::CreateCompatibleBitmap(hdc, rt.right, rt.bottom);
::SelectObject(hMemdc, hBmp);
this->DrawCaption(hWnd, hMemdc, rt, bNcActive);
//开始在缓冲区中画按钮
if ( windowStyle & WS_SYSMENU )
{
CPoint mousePt;
::GetCursorPos(&mousePt);
mousePt.Offset(-wndrt.left, -wndrt.top);//调整鼠标相对位置
BOOL bMouseOn=FALSE;
//画关闭按钮
int btW=captionHi-8;
rt.SetRect(wndrt.Width()-7-btW, 4, wndrt.Width()-7, 4+btW);
this->DrawButton(hWnd, hMemdc, rt, EXIT, bNcActive, TRUE, rt.PtInRect(mousePt));
if ( (windowStyle & WS_MAXIMIZEBOX) || (windowStyle & WS_MINIMIZEBOX) )
{
rt.left -= 18;
rt.right -= 18;
//画最大化按钮
if ( !::IsZoomed(hWnd) ) //没有最大化
this->DrawButton(hWnd, hMemdc, rt, MAX, bNcActive, windowStyle & WS_MAXIMIZEBOX, rt.PtInRect(mousePt));
else
this->DrawButton(hWnd, hMemdc, rt, RESTORE, bNcActive, windowStyle & WS_MAXIMIZEBOX, rt.PtInRect(mousePt));
//画最小化按钮
rt.left -= 18;
rt.right -= 18;
if ( !::IsIconic(hWnd) ) //没有最小化
this->DrawButton(hWnd, hMemdc, rt, MIN, bNcActive, windowStyle & WS_MINIMIZEBOX, rt.PtInRect(mousePt));
else
this->DrawButton(hWnd, hMemdc, rt, RESTORE, bNcActive, windowStyle & WS_MINIMIZEBOX, rt.PtInRect(mousePt));
}
//有帮助按钮
if ( windowExStyle & WS_EX_CONTEXTHELP )
{
rt.left -= 18;
rt.right -= 18;
this->DrawButton(hWnd, hMemdc, rt, HELP, bNcActive, TRUE, rt.PtInRect(mousePt));
}
}
//从缓冲区传到窗体
::BitBlt(hdc, 0, 0, wndrt.Width(), captionHi, hMemdc, 0, 0, SRCCOPY);
//画另外三个边框
//左
COLORREF colors[2];
colors[0]=bNcActive? WndColor[1]:WndColorUnAct[1];
colors[1]=bNcActive? WndColor[3]:WndColorUnAct[3];
GradientFill(hdc, CRect(0, 0, 2, wndrt.Height()), colors, FALSE);//左最边
colors[0]=bNcActive? WndColor[3]:WndColorUnAct[3];
colors[1]=bNcActive? WndColor[3]:WndColorUnAct[3];
GradientFill(hdc, CRect(2, 0, frame-1, wndrt.Height()), colors, FALSE);//左中
colors[0]=bNcActive? WndColor[1]:WndColorUnAct[1];
colors[1]=bNcActive? WndColor[1]:WndColorUnAct[1];
GradientFill(hdc, CRect(frame-1, captionHi, frame, wndrt.Height()), colors, FALSE);//左最内
//右
colors[0]=bNcActive? WndColor[3]:WndColorUnAct[3];
colors[1]=bNcActive? WndColor[4]:WndColorUnAct[4];
GradientFill(hdc, CRect(wndrt.Width()-frame, captionHi, wndrt.Width()-2, wndrt.Height()), colors, FALSE);
colors[0]=bNcActive? WndColor[1]:WndColorUnAct[1];
colors[1]=bNcActive? WndColor[0]:WndColorUnAct[0];
GradientFill(hdc, CRect(wndrt.Width()-2, 0, wndrt.Width(), wndrt.Height()), colors, FALSE);
//下
colors[0]=bNcActive? WndColor[4]:WndColorUnAct[4];
colors[1]=bNcActive? WndColor[1]:WndColorUnAct[1];
GradientFill(hdc, CRect(2, wndrt.Height()-frame, wndrt.Width()-2, wndrt.Height()-1), colors, TRUE);
colors[0]=bNcActive? WndColor[0]:WndColorUnAct[0];
colors[1]=bNcActive? WndColor[0]:WndColorUnAct[0];
GradientFill(hdc, CRect(0, wndrt.Height()-1, wndrt.Width(), wndrt.Height()), colors, TRUE);
::DeleteObject(hBmp);
::DeleteDC(hMemdc);
::ReleaseDC(hWnd, hdc);
}
//画标题栏
void CXPDialog::DrawCaption(HWND hWnd, HDC hdc, CRect &rt, BOOL bNcActive)
{
COLORREF colors[4];
colors[0]=bNcActive? WndColor[1]:WndColorUnAct[1];
colors[1]=bNcActive? WndColor[4]:WndColorUnAct[4];
GradientFill(hdc, CRect(0, 0, rt.right, rt.bottom-4), colors, GRADIENT_FILL_RECT_V);
colors[0]=bNcActive? WndColor[3]:WndColorUnAct[3];
colors[1]=bNcActive? WndColor[1]:WndColorUnAct[1];
GradientFill(hdc, CRect(2, 1, rt.right-4, 5), colors, GRADIENT_FILL_RECT_V);
colors[0]=bNcActive? WndColor[4]:WndColorUnAct[4];
colors[1]=bNcActive? WndColor[1]:WndColorUnAct[1];
GradientFill(hdc, CRect(0, rt.bottom-4, rt.right, rt.bottom), colors, GRADIENT_FILL_RECT_V);
int XofText=4; //标题栏上文字的启始位置
int mid=rt.Height()/2;
int windowStyle=GetWindowLong(hWnd, GWL_STYLE);
if ( windowStyle & WS_SYSMENU )
{
HICON hIcon=(HICON)::SendMessage(hWnd, WM_QUERYDRAGICON, 0, 0);
if ( hIcon != NULL )
{
//画小图标,并将文字启始位置右移
::DrawIconEx(hdc, 4, mid-8, hIcon, 16, 16, 0, NULL, DI_NORMAL);
XofText += 3+16;
}
}
//写标题
int textlength=::GetWindowTextLength(hWnd);
if ( textlength>0 )
{
char *text=new char[textlength+1];
::GetWindowText(hWnd, text, textlength+1);
::SetTextColor(hdc, RGB(255,255,255));
::SetBkMode(hdc, TRANSPARENT);
::TextOut(hdc, XofText, mid-8, text, textlength);
delete text;
}
}
//画按钮
void CXPDialog::DrawButton(HWND hWnd, HDC hdc, const CRect &rt, ButtonType iType, BOOL bActive, BOOL bAble, BOOL bMouseOn)
{
CRect rttmp;
CPen pen;
COLORREF colors[4];
COLORREF Pencolor=RGB(255,255,255);
//画按钮边框
pen.CreatePen(PS_SOLID, 1, Pencolor);
::SelectObject(hdc, pen.m_hObject);
::MoveToEx(hdc, rt.left+1, rt.top, NULL);
::LineTo(hdc, rt.right, rt.top);
::MoveToEx(hdc, rt.right, rt.top+1, NULL);
::LineTo(hdc, rt.right, rt.bottom);
::MoveToEx(hdc, rt.right-1, rt.bottom, NULL);
::LineTo(hdc, rt.left, rt.bottom);
::MoveToEx(hdc, rt.left, rt.bottom-1, NULL);
::LineTo(hdc, rt.left, rt.top);
//给按钮填充平滑颜色
if ( iType == EXIT )
{
if ( bActive && bAble && bMouseOn )
{
colors[0]=ExitBTColorMsOn[0];
colors[1]=ExitBTColorMsOn[1];
colors[2]=ExitBTColorMsOn[1];
colors[3]=ExitBTColorMsOn[1];
}
else
{
colors[0]=bActive? ExitBTColorAct[0]:ExitBTColor[0];
colors[1]=bActive? ExitBTColorAct[1]:ExitBTColor[1];
colors[2]=bActive? ExitBTColorAct[1]:ExitBTColor[1];
colors[3]=bActive? ExitBTColorAct[1]:ExitBTColor[1];
}
}
else
{
if ( bActive && bAble && bMouseOn )
{
colors[0]=MinMaxBTColorMsOn[0];
colors[1]=MinMaxBTColorMsOn[1];
colors[2]=MinMaxBTColorMsOn[1];
colors[3]=MinMaxBTColorMsOn[1];
}
else
{
colors[0]=bActive? MinMaxBTColorAct[0]:MinMaxBTColor[0];
colors[1]=bActive? MinMaxBTColorAct[1]:MinMaxBTColor[1];
colors[2]=bActive? MinMaxBTColorAct[1]:MinMaxBTColor[1];
colors[3]=bActive? MinMaxBTColorAct[1]:MinMaxBTColor[1];
}
}
rttmp.SetRect(rt.left+1, rt.top+1, rt.right, rt.bottom);
this->GradientFill( hdc, rttmp, colors, GRADIENT_FILL_TRIANGLE );
Pencolor = bAble? RGB(255,255,255):RGB(200,200,200);
//画按扭内部图型
switch( iType )
{
case EXIT:
pen.DeleteObject();
pen.CreatePen(PS_SOLID, 2, Pencolor);
::SelectObject(hdc, pen.m_hObject);
::MoveToEx(hdc, rt.left+4, rt.top+4, NULL);
::LineTo(hdc, rt.right-4, rt.bottom-4);
::MoveToEx(hdc, rt.right-4, rt.top+4, NULL);
::LineTo(hdc, rt.left+4, rt.bottom-4);
break;
case MAX:
pen.DeleteObject();
pen.CreatePen(PS_SOLID, 1, Pencolor);
::SelectObject(hdc, pen.m_hObject);
::MoveToEx(hdc, rt.left+3, rt.top+4, NULL);
::LineTo(hdc, rt.right-3, rt.top+4);
::MoveToEx(hdc, rt.left+3, rt.top+5, NULL);
::LineTo(hdc, rt.right-4, rt.top+5);
::LineTo(hdc, rt.right-4, rt.bottom-4);
::LineTo(hdc, rt.left+3, rt.bottom-4);
::LineTo(hdc, rt.left+3, rt.top+5);
break;
case RESTORE:
pen.DeleteObject();
pen.CreatePen(PS_SOLID, 1, Pencolor);
::SelectObject(hdc, pen.m_hObject);
::MoveToEx(hdc, rt.left+6, rt.top+4, NULL);
::LineTo(hdc, rt.right-4, rt.top+4);
::LineTo(hdc, rt.right-4, rt.bottom-6);
::LineTo(hdc, rt.left+6, rt.bottom-6);
::LineTo(hdc, rt.left+6, rt.top+4);
::MoveToEx(hdc, rt.left+4, rt.top+6, NULL);
::LineTo(hdc, rt.right-6, rt.top+6);
::LineTo(hdc, rt.right-6, rt.bottom-4);
::LineTo(hdc, rt.left+4, rt.bottom-4);
::LineTo(hdc, rt.left+4, rt.top+6);
break;
case MIN:
pen.DeleteObject();
pen.CreatePen(PS_SOLID,2,Pencolor);
::SelectObject(hdc, HPEN(pen));
::MoveToEx(hdc, rt.left+3, rt.bottom-5, NULL);
::LineTo(hdc, rt.right-6, rt.bottom-5);
break;
case HELP:
::SetTextColor(hdc, RGB(255,255,255));
::SetBkMode(hdc, TRANSPARENT);
rttmp = rt;
::DrawText(hdc, "?", 1, &rttmp, DT_VCENTER|DT_CENTER);
break;
default:break;
}
}
//设定窗体上边框是否为圆角
void CXPDialog::SetRoundWindow(HWND hWnd, BOOL bSet, BOOL bRedraw)
{
CRect rt;
CRgn rgn;
::GetWindowRect(hWnd, &rt);
//设定窗体上边角为圆角
if ( bSet )
{
CRgn rgn1;
rgn.CreateRoundRectRgn(0, 0, rt.Width()+1, 30, 7, 7);
rgn1.CreateRectRgn(0, 20, rt.Width(), rt.Height());
rgn.CombineRgn(&rgn, &rgn1, RGN_OR);
}
else
{
::GetWindowRect(hWnd, &rt);
rgn.CreateRectRgn(0, 0, rt.Width(), rt.Height());
}
::SetWindowRgn(hWnd, HRGN(rgn), bRedraw);
}
//平滑绘图
void CXPDialog::GradientFill(HDC hdc, const CRect &rt, COLORREF crColor[], int fillType)
{
TRIVERTEX vert[4] ;
GRADIENT_RECT gRect;
vert[0].x = rt.left;
vert[0].y = rt.top;
vert[0].Red = (GetRValue(crColor[0]))<<8;
vert[0].Green = (GetGValue(crColor[0]))<<8;
vert[0].Blue = (GetBValue(crColor[0]))<<8;
vert[0].Alpha = 0x0000;
vert[1].Red = (GetRValue(crColor[1]))<<8;
vert[1].Green = (GetGValue(crColor[1]))<<8;
vert[1].Blue = (GetBValue(crColor[1]))<<8;
vert[1].Alpha = 0x0000;
if ( fillType != GRADIENT_FILL_TRIANGLE )
{
vert[1].x = rt.right;
vert[1].y = rt.bottom;
gRect.UpperLeft = 0;
gRect.LowerRight = 1;
::GradientFill(hdc,vert,2,&gRect,1,fillType);
return ;
}
vert[1].x = rt.right;
vert[1].y = rt.top;
vert[2].x = rt.left;
vert[2].y = rt.bottom;
vert[2].Red = (GetRValue(crColor[2]))<<8;
vert[2].Green = (GetGValue(crColor[2]))<<8;
vert[2].Blue = (GetBValue(crColor[2]))<<8;
vert[2].Alpha = 0x0000;
vert[3].x = rt.right;
vert[3].y = rt.bottom;
vert[3].Red = (GetRValue(crColor[3]))<<8;
vert[3].Green = (GetGValue(crColor[3]))<<8;
vert[3].Blue = (GetBValue(crColor[3]))<<8;
vert[3].Alpha = 0x0000;
GRADIENT_TRIANGLE GTrg;
GTrg.Vertex1=0;
GTrg.Vertex2=1;
GTrg.Vertex3=2;
::GradientFill(hdc,vert,4,>rg,1,fillType);
GTrg.Vertex1=1;
GTrg.Vertex2=2;
GTrg.Vertex3=3;
::GradientFill(hdc,vert,4,>rg,1,fillType);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -