QQ 静态截图程序模拟实现



 

看到QQ这样的截图实在忍心不住想,是怎以实现的?想了许久想到一个实现法子,下面就让我给大家展示一下,模拟QQ静态模拟截图,我写的代码比较乱,是想到哪写到哪,我想肯实还有比这更简单的办法!!程序实现思路,程序是基于对话框,无标题栏,系统菜单,最小化框,最大化框,无边框....,程序初始化时,把整个桌面屏幕截图,保存下来,然后把对话框设置全屏顶层窗口,然后把保存下来的位图,在OnEraseBkgnd中把整个位图贴到对话框上,然后用像皮筋类选择截取范围,看起来就像操作屏幕一样 。

图一 示例

下面说说实现细节:

一、初始化程序,在CCatchScreenDlg构造函数中 初始化像皮筋类和保存全屏位图,

      //初始化像皮筋类m_rectTracker.m_nStyle=CRectTracker::resizeInside|CRectTracker::solidLine;  m_rectTracker.m_rect.SetRect(-1,-1,-1,-1);m_hCursor=AfxGetApp()->LoadCursor(IDC_CURSOR1);  m_bDraw=FALSE;m_bFirstDraw=FALSE;m_bQuit=FALSE;m_bShowMsg=FALSE;m_startPt=0;//获取屏幕分辩率m_xScreen = GetSystemMetrics(SM_CXSCREEN);m_yScreen = GetSystemMetrics(SM_CYSCREEN);//截取屏幕到位图中CRect rect(0, 0,m_xScreen,m_yScreen);m_pBitmap=CBitmap::FromHandle(CopyScreenToBitmap(&rect));//一定要初始化m_rgn,m_rgn.CreateRectRgn(0,0,50,50);

  然后在CCatchScreenDlg::OnInitDialog()中设置对话框成顶层窗口。在 CCatchScreenDlg::OnEraseBkgnd中 用整个桌面位图填充全屏对话框背景

二、从 CRectTracker中派生了一个CTrack 类在类中重载了DrawTrackerRect函数,在函数中直接 更新窗口,消除拖动和改变大小时的虚线框可能还有更简单的方法,本人能力有限想不出更简的!

三、从Edit类中派生一个CMyEdit类,用该类的实例对像显示操作提示信息,在 CMyEdit::OnEraseBkgnd中,用一位图填充背景,类中响应了WM_MOUSEMOVE消息,在CMyEdit::OnMouseMove(UINT nFlags, CPoint point) 中移动窗口在左上角和右上角之间来回移动.

 CRect rect;GetWindowRect(&rect);int xScreen = GetSystemMetrics(SM_CXSCREEN);//int ySCreen = GetSystemMetrics(SM_CYSCREEN);if(m_bMove){//移动到左上角MoveWindow(10,10,rect.Width(),rect.Height());m_bMove=FALSE;}else{//移动到右上角MoveWindow(xScreen-180,10,rect.Width(),rect.Height());m_bMove=TRUE;}

在主对话框上放置编缉框,然后关联一个CMyEdit的变量,在主对话显示时移动到左上角

    //把对化框设置成全屏顶层窗口SetWindowPos(&wndTopMost,0,0,m_xScreen,m_yScreen,SWP_SHOWWINDOW);//移动操作提示窗口CRect rect;m_tipEdit.GetWindowRect(&rect);m_tipEdit.MoveWindow(10,10,rect.Width(),rect.Height());//显示操作提示窗口文字DrawTip();//捕获按键消息窗口,将对话框的句柄传递到CCatchScreenApp中((CCatchScreenApp *)AfxGetApp())->m_hwndDlg=m_hWnd;

四、程序中有两个重要成员函数,一个是画截取矩形时的信息显示在鼠标右上角。

//显示截取矩形信息
void CCatchScreenDlg::DrawMessage(CRect &inRect)
{//截取矩形大小信息离鼠标间隔const int space=3;//设置字体颜色大小CClientDC dc(this);CPoint pt;CPen pen(PS_SOLID,1,RGB(147,147,147));dc.SetTextColor(RGB(147,147,147));CFont font;font.CreatePointFont(90,"宋体");dc.SelectObject(&font);//得到字体宽度和高度GetCursorPos(&pt);dc.SetBkMode(TRANSPARENT);TEXTMETRIC tm;int charHeight;CSize size;int  lineLength;dc.GetTextMetrics(&tm);charHeight = tm.tmHeight+tm.tmExternalLeading;size=dc.GetTextExtent("顶点位置  ",strlen("顶点位置  "));lineLength=size.cx;//初始化矩形, 以保证写下六行文字CRect rect(pt.x+space,pt.y-charHeight*6-space,pt.x+lineLength+space,pt.y-space);int x = GetDeviceCaps(dc, HORZRES);int y = GetDeviceCaps(dc, VERTRES);//创建临时矩形CRect rectTemp;//当矩形到达桌面边缘时调整方向和大小if((pt.x+rect.Width())>=x){//桌面上方显示不下矩形rectTemp=rect;rectTemp.left=rect.left-rect.Width()-space*2;rectTemp.right=rect.right-rect.Width()-space*2;;rect=rectTemp;}if((pt.y-rect.Height())<=0){//桌面右方显示不下矩形rectTemp=rect;rectTemp.top=rect.top+rect.Height()+space*2;;rectTemp.bottom=rect.bottom+rect.Height()+space*2;;rect=rectTemp;}//创建空画刷画矩形dc.SelectObject((HBRUSH)GetStockObject(NULL_BRUSH));dc.Rectangle(rect);//在矩形中显示文字CString string(" 顶点位置 ");dc.TextOut(rect.left,rect.top,string);string.Format(" (%d,%d)",inRect.left,inRect.top);dc.TextOut(rect.left,rect.top+charHeight,string);string=" 矩形大小 ";dc.TextOut(rect.left,rect.top+charHeight*2,string);string.Format(" (%d,%d)",inRect.Width(),inRect.Height());dc.TextOut(rect.left,rect.top+charHeight*3,string);string=" 光标坐标 ";dc.TextOut(rect.left,rect.top+charHeight*4,string);string.Format(" (%d,%d)",pt.x,pt.y);dc.TextOut(rect.left,rect.top+charHeight*5,string);}

  根据鼠标的位置和要显示的字的宽度各高度在鼠标左上角位置处构造一个CRect对像,在CRect中显示矩形信息,同时根据鼠标当前的位置,在左边和上边不能正常显示信息时动态度反转矩形,还有一个类是DrawTip()在鼠标按下、松下是显示相应的操作提示

//显示操作提示信息
void CCatchScreenDlg::DrawTip()
{//得当前坐标像素,CPoint pt;GetCursorPos(&pt);//当到当前R,G,B,各像素值COLORREF color;CClientDC dc(this);color=dc.GetPixel(pt);BYTE rValue,gValue,bValue;rValue=GetRValue(color);gValue=GetGValue(color);bValue=GetGValue(color);//按格式排放字符串CString string;CString strTemp;string.Format("\r\n\r\n\r\n ·当前像素RGB (%d,%d,%d)\r\n",rValue,gValue,bValue);if(!m_bDraw&&!m_bFirstDraw){strTemp="\r\n ·按下鼠标左键不放选择截取\r\n 范围\r\n\r\n ·按ESC键或鼠标右键退出";}elseif(m_bDraw&&m_bFirstDraw){strTemp="\r\n ·松开鼠标左键确定截取范围\r\n\r\n ·按ESC键退出";}elseif(m_bFirstDraw){strTemp="\r\n ·用鼠标左键调整截取范围的\r\n 大小和位置\r\n\r\n·截取范围内双击鼠标左键保存\r\n 图像,
结束操作\r\n\r\n·点击鼠标右键重新选择";}string+=strTemp;//显示到编缉框中,操作提示窗口m_tipEdit.SetWindowText(string);
}

程序有点乱,文字都是硬编码写上去的,整个字符串显示在一对话框的编辑出框中,用空格和回车换行来控制摆放格式。

五、由于对话框中有一个编辑框,并且背景是一张位图,由于程截图时要经常刷新窗口,如果刷新整个窗口的话,编辑框会有很大的闪烁,
所以只能更新编辑框以外的区域,函数PaintWindow()计算更新区域,并更新窗口

void CCatchScreenDlg::PaintWindow()
{//获取当全屏对话框窗口大小CRect rect1;GetWindowRect(rect1);//获取编辑框窗口大小CRect rect2;m_tipEdit.GetWindowRect(rect2);CRgn rgn1,rgn2;rgn1.CreateRectRgnIndirect(rect1);rgn2.CreateRectRgnIndirect(rect2);//获取更新区域,就是除了编辑框窗口不更新m_rgn.CombineRgn(&rgn1,&rgn2,RGN_DIFF);InvalidateRgn(&m_rgn);
}

六、当然不能忘了方向键来微调截取矩形大小和位置,由于是基于对话框的程序,按键消息,被Windows内部的对话框过程处理了(即在基类中完成了处理,读者可以查看MFC的源代码),或者被发送给子控件进行处理,所以在对话框类中可能利用
BOOLProcessMessageFilter(int code, LPMSG lpMsg)这个虚函数来过滤或响应菜单和对话框的特定Windows消息在头文件中增加一个类型为HWND,Public成员变量名m_hwndDlg,在构造函数中初始化为NULL;在 CCatchScreenDlg::OnInitDialog()中加入

((CWinSunApp*)AfxGetApp())->m_hwndDlg=m_hWnd; 

将对话框的句柄传递到CWinSunApp类中

//********************************************************************************
#define SHIFTED 0x8000
//********************************************************************************BOOL CCatchScreenApp::ProcessMessageFilter(int code, LPMSG lpMsg)
{// TODO: Add your specialized code here and/or call the base classif(m_hwndDlg!=NULL){   //判断消息,如果消息是从对话框发出的或者其子控件发出的,就进行处理if((lpMsg->hwnd==m_hwndDlg) || ::IsChild(m_hwndDlg,lpMsg->hwnd)){//如果消息是WM_KEYDOWN//用方向键调整位置if(lpMsg->message==WM_KEYDOWN){CRect rect(0,0,0,0);CCatchScreenDlg * pDlg=(CCatchScreenDlg *)AfxGetMainWnd();rect=pDlg->m_rectTracker.m_rect;if(pDlg->m_bFirstDraw){//如果Shift键按下则方向键调整大小BOOL isShifeDowm=FALSE;int nVirtKey;nVirtKey = GetKeyState(VK_SHIFT); if (nVirtKey & SHIFTED) isShifeDowm=TRUE;switch(lpMsg->wParam){case VK_UP://如果按下Shift,则只调整一边if(!isShifeDowm)rect.top-=1;rect.bottom-=1;pDlg->m_rectTracker.m_rect=rect;pDlg->PaintWindow();break;case VK_DOWN:rect.top+=1;if(!isShifeDowm)rect.bottom+=1;pDlg->m_rectTracker.m_rect=rect;pDlg->PaintWindow();break;case VK_LEFT:if(!isShifeDowm)rect.left-=1;rect.right-=1;pDlg->m_rectTracker.m_rect=rect;pDlg->PaintWindow();break;case VK_RIGHT:rect.left+=1;if(!isShifeDowm)rect.right+=1;pDlg->m_rectTracker.m_rect=rect;pDlg->PaintWindow();break;}}}}} return CWinApp::ProcessMessageFilter(code, lpMsg);
}

  程序中涉及到像皮筋类的使用,就不多说了,知识库中有许多文章,接着就双击选区保存图片到剪贴板中。就说到这。我嘴笨 , 详细的请参看源文件注释,,有什么问题或您有更好的建意请不要忘了和我联系哦,邮箱: jzlkcn@yahoo.com.cn

软件名称:  QQ 静态截图程序模拟实现
软件语言: 简体中文 整理时间:  
运行环境: windowsXP/2003/2000/98/95x 软件大小: 58KB
软件等级: ★★★ 授权方式: 免费
开 发 商:  
软件简介:  
下载地址: 本地下载一
 

转载于:https://www.cnblogs.com/wqj1212/archive/2009/04/03/1429237.html

QQ 静态截图程序模拟实现相关推荐

  1. python软件代码示例-用Python写一个模拟qq聊天小程序的代码实例

    Python 超简单的聊天程序 客户端: import socket, sys host = '10.248.27.23' # host = raw_input("Plz imput des ...

  2. 能不能用python开发qq_用Python写一个模拟qq聊天小程序的代码实例

    用Python写一个模拟qq聊天小程序的代码实例 发布时间:2020-09-09 07:49:29

  3. Java程序模拟QQ空间登录 - 并模拟刷说说的赞(图文) 注意:腾讯修改了加密算法,已失效(2015-01-31)

    Java程序模拟QQ空间登录 - 并模拟刷说说的赞 背景:在2013-10-25的一天,有个friend在QQ问我:"post登陆QQ空间抓取不到post的数据".于是故事就开始了 ...

  4. 用Python写一个模拟qq聊天小程序的代码实例

    前言 今天小编就为大家分享一篇关于用Python写一个模拟qq聊天小程序的代码实例,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧 Python 超简单的聊天 ...

  5. Java编写程序模拟两个村庄共用同一口井水,编写一个Village类,该类有一个静态的int型成员变量waterAmount, 用于模拟井水的水量。

    编写程序模拟两个村庄共用同一口井水,编写一个Village类,该类有一个静态的int型成员变量waterAmount, 用于模拟井水的水量.在主类的main()方法中创建两个村庄,一个村庄改变了wat ...

  6. C#高仿腾讯QQ截图程序

    最近把以前制作的截图程序重新写了一下 动了一个大手术 高质量仿照的TX的截图程序 源码下载1(2012-12-09) http://download.csdn.net/detail/crystal_l ...

  7. C#实现类似qq的屏幕截图程序

    因为近来想写个类似于远程桌面监控的程序,该程序中要用到屏幕捕捉.为实现该程序的一部分功能,做了个小DEMO.程序很简单,用到的技术也不多,只能实现类似qq的截图功能(方法虽然很笨) 程序流程如下: 1 ...

  8. 程序模拟电影院窗口卖票,多线程Demo

    某电影院目前正在上映国产大片,共有100张票,而它有3个窗口卖票,请设计一个程序模拟该电影院卖票 卖电影票Demo 实现步骤 1.SellTicket类 2.SellTicketDemo测试类 3.测 ...

  9. Java get set6_Java oop 的题与答案6:使用程序模拟英雄金币数,get与set知识,访问修饰符(有图)...

    //使用程序模拟英雄金币数,使用构造函数设置默认值为300,设置set方法可以给每个用户增进金币, //get获取每个用户的金币数,定义静态变量统计总金币数,创建5个对象,并赋值, //保存到数组了, ...

  10. c语言模仿atm源代码,C语言ATM程序模拟

    <C语言ATM程序模拟>由会员分享,可在线阅读,更多相关<C语言ATM程序模拟(18页珍藏版)>请在人人文库网上搜索. 1.一. 课题要求1. 当输入给定的卡号和密码(初始卡号 ...

最新文章

  1. C#中子类与父类的相互转换
  2. SpringBoot项目的几种创建方式,启动、和访问
  3. Spring AOP源码解析——AOP动态代理原理和实现方式
  4. 数据结构之图:无向图的介绍与功能实现,Python——22
  5. 王道计算机网络 传输层整理 超详细版
  6. iOS MJRefresh下拉刷新(上拉加载)使用详解
  7. iOS 内存泄漏的常见场景
  8. python支持向量机回归_Python机器学习之支持向量机——非线性SVC
  9. add php support,WordPress add_theme_support() 函数详解
  10. 威纶通触摸屏232脚位_触摸屏通讯口(USB、RS232、RS422/485)的正确使用
  11. 怎样有效整理碎片化信息,提高学习效率
  12. 【游记】CSP2021-试手记
  13. 全国计算机等级考试三级数据库技术(十)
  14. 荷兰量子生态联盟投资110万欧元开发超导量子处理器
  15. 奔腾服务器处理器性能,英特尔服务器出奇招 用奔腾M代替至强处理器
  16. ASUS华硕笔记本FN快捷键无法调节屏幕亮度
  17. Java毕业设计-流浪动物救助系统
  18. 四川SFSCB-A15/4PY智能浪涌后备保护器 遥信功能 上传防雷系统平台
  19. 拼多多将追回不当订单;微信公布2018年辟谣成果;“多闪”正式上线App Store | 雷锋早报...
  20. decltype操作符

热门文章

  1. 调用vba_VBA代码解决方案的第86讲内容:VBA代码的优化篇
  2. 单片机之串行通信接口遇到的问题
  3. 【渝粤教育】国家开放大学2018年秋季 0222-21T模拟电子电路 参考试题
  4. [渝粤教育] 中国地质大学 事故应急救援 复习题 (2)
  5. 少样本学习系列(一)【Metrics-Based Methods】
  6. 矩阵分析 (六) 矩阵的函数
  7. Lecture 1:强化学习简介
  8. 如何调用npm已经安装在全局位置的模块
  9. 【转】CString 操作指南
  10. Day13 - Ruby比一比: instance_eval 和 class_eval方法