My FAQ,最新最全的IT技术教程
最新100篇 | 推荐100篇 | 专题100篇 | 排行榜 | 搜索 | 在线API文档
首 页 | 程序开发 | 操作系统 | 软件应用 | 图形图象 | 网络应用 | 精文荟萃 | 教育认证 | 硬件维护 | 未整理篇 | 站长教程
ASP JS PHP工程 ASP.NET 网站建设 UML J2EESUN .NET VC VB VFP 网络维护 数据库 DB2 SQL2000 Oracle Mysql
服务器 Win2000 Office C DreamWeaver FireWorks Flash PhotoShop 上网宝典 CorelDraw 协议大全 网络安全 微软认证
硬件维护  CPU  主板  硬盘  内存  显卡  显示器  键盘鼠标  声卡音箱  打印机  机箱电源  BIOS  网卡  C#  Java  Delphi  vs.net2005
  当前位置:> 程序开发 > 编程语言 > Visual C++ > WINDOWS窗口视图
椭圆窗体的实现
作者:未知 时间:2005-07-20 14:13 出处:VC知识库 责编:MyFAQ
              摘要:椭圆窗体的实现

椭圆窗体的实现
作者:张建明

下载本文示例源代码

代码运行效果图如下:


我将分三部分介绍这一程序的实现过程:
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文件。
选择“文件”、“新建”,在“文件”选项卡中选中“c\c++ 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);
}
编译程序,完成应用程序。

备注:如果出现问题,请仔细阅读源代码或参照MSDN。不当之处或改进的地方敬请指点,如怎样除去颜色渐变过程中的闪烁问题,请发mail到jianming_zhang@163.com,谢谢。

关闭本页
 
首页 | 投资与合作 | 服务条款 | 隐私政策 | 收藏本站 | 设为首页 | 新用户注册 | 免责声明 | 使用帮助
Copyright ©2005-2008 myfaq.com.cn All rights reserved. www.myfaq.com.cn 版权所有