地址: http://blog.csdn.net/hujkay
作者:Jekkay Hu([email protected])
关键词:MFC, 编写异行窗体,自定义UI控件,VC++,异形控件,高仿QQ登陆界面, 截取QQ密码,QQ钓鱼
时间: 2014/4/12
a. 创建一个矩形的区域
CRgn rgn;
rgn.CreateRectRgn(0, 0, nWidth,nHeight);
b. 在当前的区域中添加一块的区域
rcXor.SetRect(0, 0, 1, 2);
rgn_xor.CreateRectRgn(0, y, border_offset[y], y + 1);
rgn.CombineRgn(&rgn, &rgn_xor, RGN_OR);
c. 在当前的区域中只取共同区域
rcXor.SetRect(0, 0, 1, 2);
rgn_xor.CreateRectRgn(0, y, border_offset[y], y + 1);
rgn.CombineRgn(&rgn, &rgn_xor, RGN_AND);
d. 在当前的区域中异或一块的区域
rcXor.SetRect(0, 0, 1, 2);
rgn_xor.CreateRectRgn(0, y, border_offset[y], y + 1);
rgn.CombineRgn(&rgn, &rgn_xor, RGN_XOR);
SetWindowRgn((HRGN)rgn, TRUE);
下面一段完整的代码,供大家参考一下:
CDC* pDC = GetDC();
CRect rc;
GetWindowRect(rc);
rc.OffsetRect(-rc.left, -rc.top);
CRgn rgn;
rgn.CreateRectRgn(0, 0, rc.Width(), rc.Height());
CRgn rgn_xor;
CRect rcXor;
for (int y = 0; y < nSize; ++y)
{
rcXor.SetRect(0, y, border_offset[y], y + 1);
rgn_xor.CreateRectRgn(0, y, border_offset[y], y + 1);
rgn.CombineRgn(&rgn, &rgn_xor, RGN_XOR);
rgn_xor.DeleteObject();
}
for (int y = 0; y < nSize; ++y)
{
rcXor.SetRect(rc.right - border_offset[y], y, rc.right, y + 1);
rgn_xor.CreateRectRgn(rc.right - border_offset[y], y, rc.right, y + 1);
rgn.CombineRgn(&rgn, &rgn_xor, RGN_XOR);
rgn_xor.DeleteObject();
}
for (int y = 0; y < nSize; ++y)
{
rcXor.SetRect(0, rc.bottom - y - 1, border_offset[y], rc.bottom - y);
rgn_xor.CreateRectRgn(0, rc.bottom - y - 1, border_offset[y], rc.bottom - y);
rgn.CombineRgn(&rgn, &rgn_xor, RGN_XOR);
rgn_xor.DeleteObject();
}
for (int y = 0; y < nSize; ++y)
{
rcXor.SetRect(rc.right - border_offset[y], rc.bottom - y - 1, rc.right, rc.bottom - y);
rgn_xor.CreateRectRgn(rc.right - border_offset[y], rc.bottom - y - 1, rc.right,rc.bottom - y);
rgn.CombineRgn(&rgn, &rgn_xor, RGN_XOR);
rgn_xor.DeleteObject();
}
SetWindowRgn((HRGN)rgn, TRUE);
m_Rgn.DeleteObject();
m_Rgn.Attach(rgn.Detach());
ReleaseDC(pDC);
#include
using namespace Gdiplus;
#pragma comment(lib, "gdiplus.lib")
自定义绘制界面需要重载一下主要下面的几个函数:
绘制客户区域的函数:ON_WM_PAINT()
绘制非客户区域的函数:ON_WM_NCPAINT()
背景擦除函数:ON_WM_ERASEBKGND()
限定窗体大小的函数:ON_WM_GETMINMAXINFO()
一般来说,自绘窗体控件最主要的就是ON_WM_PAINT()方法,大部分时间都耗在就是在里面,这个活比较细致,像素一个一个地调,没有耐心的人估计会砸电脑。 CRect rcClient;
GetClientRect(&rcClient);
CPaintDC dc(this);
CDC MemDC;
MemDC.CreateCompatibleDC(&dc);
CBitmap memBmp;
memBmp.CreateCompatibleBitmap(&dc, rcClient.Width(), rcClient.Height());
CBitmap *pOldmap = MemDC.SelectObject(&memBmp);
DrawImageStyle(MemDC, rcClient);
dc.BitBlt(0, 0, rcClient.Width(), rcClient.Height(), &MemDC, 0, 0, SRCCOPY);
MemDC.SelectObject(pOldmap);
MemDC.DeleteDC();
ON_WM_MOUSEMOVE()
ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave)
ON_MESSAGE(WM_MOUSEHOVER, OnMouseHover)
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_LBUTTONDBLCLK()
事件和窗体绘制有着紧密的关系,比如一个按钮,用户鼠标移入时是一种状态,按下时又是一种状态,弹起式又是一状态。因此,在绘制窗体时,要根据当前的用于的交互状态绘制不同的形态,非常考验一个人的变成能力。
绘制自定义UI插件是个细活,必须如加工艺术品一样有耐心,所以我但凡见到做UI插件的同仁,都心生佩服。周末闲来无事,根据其他高手的一些代码,高仿了一下QQ的登陆界面,很酷吧,呵呵。
高仿的QQ 2014登陆程序的下载地址:http://download.csdn.net/user/hujkay
别干坏事啊~~~
胡杨, Jekkay Hu
2014/4/12