[转载]椭圆窗体的实现

转载留名!
原文地址:椭圆窗体的实现作者:永不言敗

代码运行效果图如下:

我将分三部分介绍这一程序的实现过程:

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);
}

编译程序,完成应用程序。

posted @ 2010-06-21 22:30  潜龙9527  阅读(226)  评论(0编辑  收藏  举报