当前位置: 首页 > 图文教程 > 开发语言 > VC++ > 《电子尺》V1.02程序开发实例

VC++
在类VC的界面实现中加入目录树
软件换肤技术在 BCB 中的实现
利用非模窗口生成MDI介面
报表输出轻松搞定
Windows 中不规则窗体的编程实现
解说Win32的窗口子类化
使用测试优先方法开发用户界面
一个简单的登录对话框的实现
一个简单的日记本程序
从资源中加载皮肤
一个在RichEdit中添加表情图象的类
ActiveSkin 4.3 软件换肤在VC中的实现
一种另类“关于(About)”对话框的动态显示方法
对话框打印预览及打印
关于如何换肤、子类化的解决方案
制作 MSN、QQ 的消息提示窗口
如何对 BCGControlBarPro 进行换肤
定制个性化的对话框窗口类
改变窗口中的光标形状
更新MFC中的视图,跟踪.NET Framework中的事件

VC++ 中的 《电子尺》V1.02程序开发实例


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-10-30   浏览: 78 ::
收藏到网摘: n/a

《电子尺》V1.02程序开发实例
作者:电脑驿站 hcl

下载本文源程序

程序功能
有时在制作网页或一些多媒体时,需要插入一些自制的图片和flash动画,在制作之前一定需要先确定图片的高和宽,用这个软件就可以轻松的量出你所需要的高和宽。

总体介绍
程序在开始测量时要锁定整个屏幕,包括任务栏等。原先计划利用钩子(Hook)来截取所有的鼠标消息,实现屏幕的锁定。但是无论使用WH_MOUSE或WH_GETMESSGAE都无法完全截获所有消息。所以我就利用了一个占据整个屏幕的透明窗口来实现。虽然是透明的窗口,但是一旦窗口创建以后,实际屏幕的更新就不会再对窗口中显示的内容进行影响了。

在开始测量时,有一个跨这个屏幕的大十字随着鼠标移动,来辅助定位。在单击第一个点后,会出现一个小的红十字来做标记,如下图所示:


代码分析
首先要创建一个透明的窗口,因此我从CWnd继承了一个类Target。在Target类中自定义了一个创建透明窗口的方法:

void Target::CreateTarget(LPCTSTR lpTitle, CWnd* pWnd){//取得屏幕的高和宽,用于创建跨整个屏幕的窗口cxScreen=::GetSystemMetrics(SM_CXSCREEN);cyScreen=::GetSystemMetrics(SM_CYSCREEN);//用CWnd::CreateEx创建一个透明的窗口,WS_EX_TOPMOST使窗口总是在最顶层CreateEx(WS_EX_TOPMOST,AfxRegisterWndClass(0,AfxGetApp()->LoadStandardCursor(IDC_ARROW)),"Target", WS_POPUP, 0, 0, cxScreen, cyScreen,NULL, NULL, NULL );//pDC用于开始测量时绘制辅助标志pDC=GetDC();//bSecond用于标识是否已经点击了一次bSecond=FALSE;//pWndParent保存父窗口的指针pWndParent=pWnd;//创建一个MemDC临时存放整个屏幕的画面,用于刷新屏幕MemDC.CreateCompatibleDC(pDC);CBitmap Bitmap;Bitmap.CreateCompatibleBitmap(pDC,cxScreen,cyScreen);//确定MemDC的大小MemDC.SelectObject(&Bitmap);//将这个屏幕的都存入MemDCMemDC.BitBlt(0,0,cxScreen,cyScreen,pDC,0,0,SRCCOPY);//将临时图片删除::DeleteObject(Bitmap.m_hObject);}
重载Target类的鼠标移动的消息处理函数,使鼠标移动时,有一个十字跟随移动,并且在已经点击了第一个点以后,会有一条链接起点与终点的线。
void Target::OnMouseMove(UINT nFlags, CPoint point) {//首先将MemDC中的图片复制到当前窗口,将原有的辅助线都掩盖掉pDC->BitBlt(0,0,cxScreen,cyScreen,&MemDC,0,0,SRCCOPY);//画一个新的十字pDC->MoveTo(0,point.y);pDC->LineTo(cxScreen,point.y);pDC->MoveTo(point.x,0);pDC->LineTo(point.x,cyScreen);//如果已经点击过一次,再画一条从起点到终点的辅助线if(bSecond){pDC->MoveTo(startPos.x,startPos.y);pDC->LineTo(point.x,point.y);}CWnd::OnMouseMove(nFlags, point);}
重载鼠标左击的消息处理函数,两次单击后向父窗口发送一个自定义的消息WM_ENDCLICK
void Target::OnLButtonDown(UINT nFlags, CPoint point) {//如果第一次按左击if(bSecond==FALSE){//记录按下的坐标startPos=point;//改变标记bSecond=TRUE;//恢复原来的屏幕pDC->BitBlt(0,0,cxScreen,cyScreen,&MemDC,0,0,SRCCOPY);//定义一个红色的笔CPen pen(PS_SOLID,2,RGB(255,0,0));CPen* pOldPen;//选入红色的笔,并且记录原来的笔pOldPen=pDC->SelectObject(&pen);//画一个红色的标记pDC->MoveTo(point.x-10,point.y);pDC->LineTo(point.x+10,point.y);pDC->MoveTo(point.x,point.y-10);pDC->LineTo(point.x,point.y+10);//装入原来的笔,用于在其他辅助线pDC->SelectObject(pOldPen);//删除红色的笔::DeleteObject(pen.m_hObject);//将带有红色标记的屏幕图片保存到MemDC中MemDC.BitBlt(0,0,cxScreen,cyScreen,pDC,0,0,SRCCOPY);}else//如果第二次单击{//记录终点坐标endPos=point;//调用计算长度的函数Calculate();//将当前DC和临时内存DC删除pDC->DeleteDC();MemDC.DeleteDC();//撤销窗口DestroyWindow();//向父窗口发送一个自定义的WM_ENDCLICKpWndParent->PostMessage(WM_ENDCLICK);}CWnd::OnLButtonDown(nFlags, point);}
重载鼠标右击的消息处理函数,测量时按下右键就取消测量,向父窗口发送WM_CANCELCLICK自定义消息。