代码运行效果图如下:
我将分三部分介绍这一程序的实现过程:
1.生成椭圆形图形界面,并在上面写斜体带颜色的子和鼠标拖动功能。
2.增加鼠标右键菜单,并实现总在前面和其他程序自动覆盖的功能。
3.生成鼠标的全局钩子,截获鼠标事件,返回****的值。
1.生成椭圆形图形界面,并在上面写斜体带颜色的子。
在VC集成编译环境中,选择“文件”,“新建”,然后选择“工程”选项卡。在左侧的工程选择项中选取“MFC AppWizard[exe]”,在右侧工程标题下的编辑框中输入“EllipseWindow”。
单击“确定”按钮,进入“MFC AppWizard step-1”选择页,选中“D基本对话框”左侧的单选按钮,将应用程序的类型设为基本对话框,然后点击“完成”按钮后点击“确定”即可。
在自动生成的“IDD_ELLIPSEWINDOW_DIALOG”对话框资源中删除“取消”,“确定”按钮和标题为“TODO:在这里设置对话框”的文本框。此时,编译运行这个程序,应该能在窗口弹出一个空的对话框。
椭圆窗体的实现主要是靠CRgn类来实现的。
1.1 生成椭圆窗体
在类CEllipseWindowDlg的定义中填加CRgn m_rgnWnd的protected型变量。在CEllipseWindowDlg::OnInitDialog()中加入如下代码:
CRect rc;
GetClientRect(rc);
m_rgnWnd.CreateEllipticRgn(rc.left+32,rc.top+32,rc.Width()-64,rc.Height()-20);
SetWindowRgn((HRGN)m_rgnWnd,TRUE);
此时运行这个程序,将出现一个灰色的椭圆窗体。如果不能关闭这个应用程序,可用Alt+F4关闭这个程序。
1.2 按下鼠标左键后,用鼠标拖动椭圆的实现方法。
使用类向导,添加CEllipseWindowDlg的WM_MOUSEMOVE的处理函数CEllipseWindowDlg::OnMouseMove(UINT nFlags, CPoint point),代码如下:
static CPoint p;
ClientToScreen(&point);
if(nFlags & MK_LBUTTON)
{
SetCursor(LoadCursor(NULL,IDC_CROSS));
CRect rc;
GetWindowRect(rc);
MoveWindow(rc.left+point.x-p.x,rc.top+point.y-p.y,rc.Width(),rc.Height());
}
p=point;
此时运行程序,按下鼠标左键,就可以拖动椭圆窗体了。
1.3 为这个窗体添加渐变的背景颜色。
在CEllipseWindowApp增加public成员函数void CEllipseWindowApp::SetBkColor(),代码为:
static BYTE x=80,y=40,z=30;
static BOOL flagx=TRUE,flagy=FALSE,flagz=TRUE;
if(flagx)
{
x++;
if(x>120)
flagx=FALSE;
}
else
{
x--;
if(x<10)
flagx=TRUE;
}
if(flagy)
{
y+=2;
if(y>100)
flagy=FALSE;
}
else
{
y-=2;
if(y<20)
flagy=TRUE;
}
if(flagz)
{
z+=3;
if(z>80)
flagz=FALSE;
}
else
{
z-=3;
if(z<20)
flagz=TRUE;
}
SetDialogBkColor(RGB(x,y,z),RGB(x+100,y+120,140));
此时运行程序,椭圆界面的颜色就会自动发生渐变。
在EllipseWindowDlg.cpp中加入代码:
extern CEllipseWindowApp theApp;
在CEllipseWindosDlg中加入定时器void CEllipseWindowDlg::OnTimer(UINT nIDEvent),其中的实现代码为:
theApp.SetBkColor();
Invalidate();
在BOOL CEllipseWindowDlg::OnInitDialog()中加入对初始化定时器代码:
SetTimer(1,20,NULL);
1.4 在窗体上显示欢迎词“enjoy!!!”
添加CEllipseWindowDlg的protected数据成员 CFont m_font;
在BOOL CEllipseWindowDlg::OnInitDialog()中创建字体,代码如下:
LOGFONT lf;
SystemParametersInfo(SPI_GETICONTITLELOGFONT,sizeof(LOGFONT),&lf,SPIF_SENDWININICHANGE);
lf.lfHeight=60;
lf.lfEscapement=100;
lf.lfItalic=TRUE;
lf.lfQuality=DRAFT_QUALITY;
m_font.CreateFontIndirect(&lf);
在void CEllipseWindowDlg::OnPaint()中加入显示代码:
CPaintDC dc(this);
dc.SetBkMode(TRANSPARENT);
dc.SetTextAlign(TA_BASELINE|TA_CENTER);
CRect rc;
GetClientRect(rc);
CFont *oldfont=dc.SelectObject(&m_font);
dc.TextOut(rc.Width()/2,rc.Height()/2,"enjoy!!!");
dc.SelectObject(oldfont);
好了,第一步完成了,也累了,have a rest :-)
检查一下我们的成果:程序运行,显示椭圆窗体,显示 “enjoy!!!”,并且背景颜色在不停的改变,按下鼠标左键后可以拖动。
2.增加鼠标右键菜单,并实现总在前面和其他程序自动覆盖的功能。
2.1 增加鼠标右键菜单
添加资源中添加菜单资源,添加后的结果如下:
MENUITEM "关闭", IDCANCEL
MENUITEM "关于...", ID_APP_ABOUT
MENUITEM SEPARATOR
MENUITEM "开始识别密码", ID_START
MENUITEM "终止识别密码", ID_STOP, GRAYED
MENUITEM SEPARATOR
MENUITEM "总在前面", ID_TOPMOST
MENUITEM "自动隐藏", ID_ZORDER, GRAYED
在CEllipseWindowDlg中加入鼠标右键按下的处理,是按下鼠标左键后弹出异彩单,实现代码为:
ClientToScreen(&point);
pMenu->TrackPopupMenu(TPM_LEFTBUTTON,point.x,point.y,this);
2.2 加入椭圆窗口界面总在前面和自动隐藏的处理。
在BOOL CEllipseWindowDlg::OnInitDialog()中加在菜单项,代码如下:
m_menu.LoadMenu(IDR_RIGHT_CLICK);
pMenu=m_menu.GetSubMenu(0);
使用类向导生成菜单项的处理函数,对于ID_TOPMOST中的处理世界面总是显示在最前面,而且是该菜单选项变灰,处理代码为:
CRect rc;
GetWindowRect(rc);
SetWindowPos(&wndTopMost,rc.left,rc.top,rc.Width(),rc.Height(),SWP_SHOWWINDOW);
pMenu->EnableMenuItem(ID_TOPMOST,MF_BYCOMMAND|MF_GRAYED);
pMenu->EnableMenuItem(ID_ZORDER,MF_BYCOMMAND|MF_ENABLED);
相应的,自动隐藏的代码为:
CRect rc;
GetWindowRect(rc);
SetWindowPos(&wndBottom,rc.left,rc.top,rc.Width(),rc.Height(),SWP_SHOWWINDOW);
SetWindowPos(&wndTop,rc.left,rc.top,rc.Width(),rc.Height(),SWP_SHOWWINDOW); pMenu->EnableMenuItem(ID_ZORDER,MF_BYCOMMAND|MF_GRAYED);
pMenu->EnableMenuItem(ID_TOPMOST,MF_BYCOMMAND|MF_ENABLED);
3.生成鼠标的全局钩子,截获鼠标事件,返回****的值
在VC集成开发环境中,选择“文件”、“新建”,选中“工程”选项卡中的“Win32 Dynamic-link Library”选项。工程的名称为“finder”,点击“下一步”按钮。 在“win32 Dynamic-Link Library step 1 of 1”中,选择创建“A simple Dll project”,然后单击“完成”按钮。
3.1 创建finder.h文件。
选择“文件”、“新建”,在“文件”选项卡中选中“cc++ header file”选项,文件名为finder。
#ifndef __FINDER_H__
#define __FINDER_H__
#ifdef FINDER_EXPORTS
#define FINDER_API __declspec(dllexport)
#else
#define FINDER_API __declspec(dllimport)
#endif
HHOOK FINDER_API start();
#endif __FINDER_H__
3.2 在finder.cpp中加入鼠标处理代码,详见finder.cpp文件。
编译程序,生成finder.dll动态连接软件。将finder.h和编译生成的finder.dll,finder.lib程序拷贝到EllipseWindow文件夹。
3.3 在EllipseWindow的EllipseWindowDlg.cpp中加入开始和终止鼠标钩子的代码(使用想到,可简化操作),代码如下。
void CEllipseWindowDlg::OnStart()
{
// TODO: Add your command handler code here
m_hMouse=start();
pMenu->EnableMenuItem(ID_START,MF_BYCOMMAND|MF_GRAYED);
pMenu->EnableMenuItem(ID_STOP,MF_BYCOMMAND|MF_ENABLED);
}
void CEllipseWindowDlg::OnStop()
{
// TODO: Add your command handler code here
CloseHandle(m_hMouse);
pMenu->EnableMenuItem(ID_STOP,MF_BYCOMMAND|MF_GRAYED);
pMenu->EnableMenuItem(ID_START,MF_BYCOMMAND|MF_ENABLED);
}
编译程序,完成应用程序。