前兩天,為了做熟悉跨平台網絡交互。簡單的做了一個安卓手機往電腦發送命令的軟件,包含電腦服務端和手機客戶端,剛好這幾天都比較閑,想起前段時間用按鍵精靈時,大漠插件(哎,孤陋寡聞,居然最近才知道這東東是干什么用的),於是乎,動手寫了一個簡單的遠程控制。
其實做的事情很簡單:
1、發送一張屏幕截圖到手機端,並在手機端顯示出來,並且可以處理放大,移動等。
2、點擊圖片中某一位置時,像服務端發送消息,服務端調用大漠插件,進行鼠標移動和點擊操作。
3、操作完成后,簡單的回復一個新的屏幕截圖。
好吧,似乎確實沒什么復雜的,主要是為了記錄一下大漠插件的注冊,以前沒有這樣使用過。
將大漠dll放到工作目錄下,然后添加代碼就行了。第一次運行后,他會自動生成相應的頭文件。
// 大漠插件注冊和初始化
#include "stdafx.h"
//大漠
#import "dm.dll"
using namespace Dm;
CLSID clsid; //COM對象類標示符
Idmsoft* dm; //定義一個指向COM對象接口地址的指針
void InitTLDm()
{
if (CLSIDFromProgID(OLESTR("dm.dmsoft"),&clsid)!=S_OK)
{
WinExec("regsvr32 dm.dll /s", SW_HIDE); //運行注冊插件命令
}
if (SUCCEEDED(CoInitialize(NULL))) //初始化COM庫
{
//根據給定的程序標示符從注冊表中找出對應的類標示符
//這里的"dm.dmsoft"是dll在注冊表里的鍵值,將類標示符賦給clsid
HRESULT hr=CLSIDFromProgID(OLESTR("dm.dmsoft"),&clsid);
//用指定的類標示符創建一個未初始化的COM對象
//Idmsoft:創建的com對象的接口標示符
//dm:用來接收指向com對象接口地址的指針變量
//CLSCTX_INPROC_SERVER 創建同一進程中運行的組件
HRESULT Hr=CoCreateInstance(clsid,NULL,CLSCTX_INPROC_SERVER,
__uuidof(Idmsoft),(LPVOID*)&dm);
if (SUCCEEDED(Hr))
{
CoFreeUnusedLibraries(); //卸載不用的COM服務
}
}
else
{
AfxMessageBox("初始化COM組件失敗!");
}
// dm->Release();
}
其他都是簡單通迅,大漠的相關接口也可以查看文檔。
這里還有就是屏幕截圖,原本看到網上很多都是保存為bmp,這對於我這里來說,有點太大,動不動就是20+M ,hold不住。
以下注釋掉部分是網上的保存bmp方法,完全自己寫文件的方式,我主要使用的CImage 提供了方便的接口
代碼如下:
#include <afxwin.h>
void Screen(const char* filename)
{
CDC *pDC;//屏幕DC
pDC = CDC::FromHandle(GetDC(NULL));//獲取當前整個屏幕DC
int BitPerPixel = pDC->GetDeviceCaps(BITSPIXEL);//獲得顏色模式
int Width = pDC->GetDeviceCaps(HORZRES);
int Height = pDC->GetDeviceCaps(VERTRES);
// printf("當前屏幕色彩模式為%d位色彩n", BitPerPixel);
// printf("屏幕寬度:%dn", Width);
// printf("屏幕高度:%dn", Height);
CDC memDC;//內存DC
memDC.CreateCompatibleDC(pDC);
CBitmap memBitmap, *oldmemBitmap;//建立和屏幕兼容的bitmap
memBitmap.CreateCompatibleBitmap(pDC, Width, Height);
CImage image;
image.Create(Width , Height,24);
memDC.SelectObject(image);
// oldmemBitmap = memDC.SelectObject(&memBitmap);//將memBitmap選入內存DC
memDC.BitBlt(0, 0, Width, Height, pDC, 0, 0, SRCCOPY);//復制屏幕圖像到內存DC
//以下代碼保存memDC中的位圖到文件
/* BITMAP bmp;
memBitmap.GetBitmap(&bmp);//獲得位圖信息
FILE *fp = fopen(filename, "w+b");
BITMAPINFOHEADER bih = { 0 };//位圖信息頭
bih.biBitCount = bmp.bmBitsPixel;//每個像素字節大小
bih.biCompression = BI_RGB;
bih.biHeight = bmp.bmHeight;//高度
bih.biPlanes = 1;
bih.biSize = sizeof(BITMAPINFOHEADER);
bih.biSizeImage = bmp.bmWidthBytes * bmp.bmHeight;//圖像數據大小
bih.biWidth = bmp.bmWidth;//寬度
BITMAPFILEHEADER bfh = { 0 };//位圖文件頭
bfh.bfOffBits = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);//到位圖數據的偏移量
bfh.bfSize = bfh.bfOffBits + bmp.bmWidthBytes * bmp.bmHeight;//文件總的大小
bfh.bfType = (WORD)0x4d42;
fwrite(&bfh, 1, sizeof(BITMAPFILEHEADER), fp);//寫入位圖文件頭
fwrite(&bih, 1, sizeof(BITMAPINFOHEADER), fp);//寫入位圖信息頭
byte * p = new byte[bmp.bmWidthBytes * bmp.bmHeight];//申請內存保存位圖數據
GetDIBits(memDC.m_hDC, (HBITMAP)memBitmap.m_hObject, 0, Height, p,
(LPBITMAPINFO)&bih, DIB_RGB_COLORS);//獲取位圖數據
fwrite(p, 1, bmp.bmWidthBytes * bmp.bmHeight, fp);//寫入位圖數據
delete[] p;
fclose(fp);
memDC.SelectObject(oldmemBitmap);
*/
image.Save(filename, Gdiplus::ImageFormatJPEG);
}
