问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

知道了位图数据和指针,怎么样将其保存在电脑上?

发布网友 发布时间:2022-08-24 18:30

我来回答

1个回答

热心网友 时间:2024-01-28 18:19

下面是关于mouse_event的示例代码:

POINT lpPoint;
GetCursorPos(&lpPoint);
SetCursorPos(lpPoint.x, lpPoint.y);
mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);

  上面的代码表示鼠标的双击,若要表示单击,用两个mouse_event即可(一次放下,一次松开)。  
  注意,不管是模拟键盘还是鼠标事件,都要注意还原,即按完键要松开,一个keydown对应一个keyup;鼠标单击完也要松开, 不然可能影响程序的功能 远程截取屏幕显示

服务端在接收到客户端的屏幕数据请求后,通过使用当前屏幕设备的句柄,开始向开辟的内存区域复制屏幕数据,得到与设备相关的GDI位图;然后再通过设置位图信息头、调色板等,最后得到与设备无关的DIB位图。

2.1获取当前屏幕的设备相关位图[3](DDB)

设备相关位图(DDB)也称为图形设备接口(GDI)位图,在MFC库中用CBitmap类来存储。该对象包含与设备相关的GDI模块数据结构。应用程序在截获屏幕显示数据的时候,将数据填充到开辟的相容性内存区域中,并与CBitmap对象的句柄建立关联,从而得到GDI位图数据的备份。但由于GDI位图中关于位的安排完全依赖于显示设备,在不同类型计算机间传递GDI位图是没有意义的。所以还需要进一步转化,得到设备无关位图DIB。

(1)得到当前屏幕的分辨率,从而确定截取屏幕的范围;
ScreenX=GetSystemMetrics(SM_CXSCREEN);
ScreenY=GetSystemMetrics(SM_CYSCREEN);

(2)得到屏幕HDC,并开辟相容性内存区域,建立相容性的HBITMAP;
HDC hdcmy=CreateDC("DISPLAY",NULL,NULL, NULL);
HDC hbufdc=CreateCompatibleDC(hdcmy);
HBITMAP hBit=CreateCompatibleBitmap(hdcmy, ScreenX,ScreenY);

(3)将当前屏幕内容复制到之前开辟的内存区域中,得到当前屏幕的GDI位图;
HBITMAP hOldBitmap=(HBITMAP)SelectObject(hbufdc,hBit);
StretchBlt(hbufdc,0,0,ScreenX,ScreenY,hdcmy,0,0,ScreenX,ScreenY,SRCCOPY);
hBit=(HBITMAP)SelectObject(hbufdc,hOldBitmap);

2.2转化设备相关位图(DDB)至设备无关位图[3](DIB)

DIB自带颜色信息,可以实现调色板管理,任何运行Windows的计算机中都可以处理这种标准的位图格式,BMP文件中就包含了一个DIB,主要由位图文件头、位图信息头、调色板和DIB图像数据4个部分组成,DDB向DIB的转化实际上就是利用DDB中包含的图像信息,填充DIB除位图文件头的另外3个部分,从而得到与设备无关的位图数据。最后可再通过添加位图文件头,构成一幅标准的BMP图像。

(1)通过BITMAP句柄hBit,得到位图信息,随后填充BITMAPINFOHEADER结构,计算InfoHeader长度,初始化调色板,最后分配存储空间存放上述信息头与调色板数据;
GetObject(hBit,sizeof(bitmap),(LPSTR)&bitmap);
int ncolors=1<<(bitmap.bmPlanes*bitmap.bmBitsPixel);
DWORD dwLen=sizeof(BITMAPINFOHEADER)+ncolors*sizeof (RGBQUAD);
HANDLE hDib=GlobalAlloc(GMEM_FIXED,dwLen);

(2)计算位图数据实际占用的字节数,使其宽度大于或者等于离4最近的整数倍,修正原biSizeImage数值,然后重新计算并分配空间用于存储信息头,调色板和实际图像数据;
bi.biSizeImage=((((bi.biWidth*bi.biBitCount)+31)&~31)/8)*bi.biHeight;
dwLen += bi.biSizeImage;
if(handle=GlobalReAlloc(hDib,dwLen,GMEM_MOVEABLE)) hDib=handle;
(3)向开辟的指定存储区域中复制上述信息头、调色板以及实际图像信息3部分数据,最后返回该存储区域的句柄,得到最终的DIB位图;
LPBITMAPINFOHEADER lpbi=(LPBITMAPINFOHEADER)hDib;
GetDIBits( hdc, bitmap,0L,(DWORD)bi.biHeight,(LPBYTE)lpbi +(bi.biSize+ncolors
*sizeof(RGBQUAD)),(LPBITMAPINFO)lpbi,(DWORD)DIB_RGB_COLORS);

3 屏幕数据传送控制

屏幕数据的传送控制主要在如何确认服务端与客户端之间的连接,服务端如何定时分块发送屏幕数据,客户端如何拼接屏幕数据并显示图像,服务端如何响应客户端的鼠标事件等几个方面。

3.1服务端与客户端的连接确认
双方连接可以由客户端指定服务端IP地址,或者在子网段内发送通信对方标识,服务端接收到该标识后,向客户端发送确认标识,客户端收到确认信息后,表明双方实现连接。
以下代码为客户端程序片断,服务端程序将发送和接收函数的顺序对调即可。

char cFlag[8]="CopyScr\0";
send(sktClient,cFlag,8,0);//发送client端标志
recv(sktClient,cFlag,8,0);//接收server端标志

3.2服务端定时分块发送屏幕数据
客户端以某一定时器设定为间隔,向服务端请求屏幕数据,服务端收到请求后,首先获取当前屏幕的GDI位图数据,并转化为DIB位图数据,随后采用分块传送的方式,向客户端发送屏幕的位图数据,分块过程如下所示:

(1)发送屏幕位图数据的相关信息,诸如尺寸、长度、高度等信息至客户端;
send(sktClient,(char*)&ScrInfo,sizeof(ScrInfo)+1,0);

(2)分块发送DIB位图数据,以SENDBLOCK为分块尺寸,同时调整当前数据指针位置;
LPBYTE plmagePoint=(LPBYTE)hDib;
for(WORD i=0;i<(ScrInfo.dwSize/SENDBLOCK);i++){
send(sktClient,(char*)plmagePoint,sizeof(BYTE)*SENDBLOCK,0);
plmagePoint=plmagePoint + SENDBLOCK;
recv(sktClient,(char*)&StopFlag,sizeof(int)+1,0);}

(3)当屏幕位图数据不是刚好等于分块尺寸倍数的时候,用于处理余下的数据传送;
if (ScrInfo.dwSize %SENDBLOCK)
send(sktClient,(char*)plmagePoint,ScrInfo.dwSize%SENDBLOCK,0);

3.3客户端拼接屏幕数据并显示图像
客户端的屏幕数据拼接程序,刚好与服务端的屏幕数据切分程序相对应,首先是接收屏幕位图相关信息,然后按照指定的分块大小接收屏幕数据,最后将小于分块尺寸的屏幕数据单独进行接收处理,得到服务端完整的一次屏幕数据,位图采用StretchDIBits函数显示。
StretchDIBits(dc,0,0,rect.right,rect.bottom,0,0,
((LPBITMAPINFOHEADER)SvrData)->biWidth,
((LPBITMAPINFOHEADER)SvrData)->biHeight,
(LPBYTE)SvrData+(sizeof(BITMAPINFOHEADER)+color*sizeof(RGBQUAD)),
(LPBITMAPINFO)SvrData,DIB_RGB_COLORS,SRCCOPY);

3.4服务端响应客户端的鼠标事件
当使用鼠标点击客户端中显示服务端当前屏幕的区域,客户端程序将会记录下具体的左/右键,单/双击,X/Y坐标位置等信息,作为鼠标事件发送给服务端,服务端随后进行解析,并作出相应的响应,从而实现客户端得到服务端屏幕并加以控制的功能。
mouse_event(MOUSEEVENTF_LEFTDOWN ,0,0,0,GetMessageExtraInfo());
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
山外面包一个病旁是什么字 我的笔记本电脑显示电源的灯一直在绿色和橘红色之间闪烁,这是怎么回事... 笔记本电脑3个灯笔记本电脑这几个指示灯分别是啥意思 ...我的y470.第3个指示灯是橘红色的,开不了机,不知道怎么了?就开不了... QQ空间皮肤的代码是怎么放进去的啊. 为什么我在地址栏中输入皮肤代码按回车键,但一按空间就没有了 请教个问题哈~关于qq空间背景代码的,我在IE栏里输了代码,为啥每次弹出 ... win10删除多余的输入法 win10怎么删除多余的输入法 win10输入法怎么删除 win10输入法删除方法 如何做出爽口不腻、口味纯正的孟和尚粉肠? 广东的GDP破10万亿了吗? 广东和江苏同为经济大省,为何生育率两省天差地别? 吃什么能有助于大腿减肥? 吃什么水果能帮助大腿减肥 红宝石如何鉴定? 红宝石的特征?怎么区分鉴别 红宝石是什么 整数“1&quot;里有多少个0、01 1里面有几个0.1,几个0.01,几个0.001? 2022年即便收入再低,有哪些保险也必须要买呢? 五谷杂粮加山楂丸能减肥吗 泰康人寿祥云康顺b款意外伤害险出险后赔付医疗费吗?怎么赔法?_百度知 ... 如何将excel中的数据截取删除 华泰康顺无忧保宫角孕住院报销吗? 华泰康顺无忧怎么样 水泵安装合同范本 弱电工程安装合同范本 为什么楚轩被叫成小叮当? 《小叮当:拯救精灵大作战》在线免费观看百度云资源,求下载 小叮当百万医疗险推不推荐? 小叮当百万医疗险的优势在哪里 如何把控件显示的位图保存为图片文件? coreldraw里位图的保存 昨晚梦见自已把自行车推到了开追悼会的单间,但没看到尸体? 复仇者联盟3标志怎么画 怎样把自己的照片p在复仇者联盟人物身上 努力赚钱的励志句子100句 花椒水对开水烫伤留下的疤痕有什么作用 大象金服 微盘宝的几位交易员分析师 王琼 王通 高慧 浦云儒 谁知道他们... 微盘宝和大象贵金属手机交易行情软件有什么区别么 微盘宝的官网是什么? win7怎么查看CPU几核 如果你的工作压力很大,你会怎么办? 你觉得工作压力大应该怎么做? 总感觉工作压力大怎么办? 长沙约克空调售后服务电话 卖废品的收电饭锅吗? 我有个电饭锅不用了现在想卖了 社保补充团体医疗保险生效日期怎么追溯? 小学生应该看什么动漫? 用once ,on another occasion造句 不得用原文