前兩天,為了做熟悉跨平台網絡交互。簡單的做了一個安卓手機往電腦發送命令的軟件,包含電腦服務端和手機客戶端,剛好這幾天都比較閑,想起前段時間用按鍵精靈時,大漠插件(哎,孤陋寡聞,居然最近才知道這東東是干什么用的),於是乎,動手寫了一個簡單的遠程控制。
其實做的事情很簡單:
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); }