gpt4 book ai didi

c++ - 使用 Winsock、GetDIBits 和 SetDiBits 传输位图

转载 作者:太空狗 更新时间:2023-10-29 23:20:09 26 4
gpt4 key购买 nike

<分区>

我开始使用 C++ 开发类似于远程控制应用程序的东西。我想将特定窗口的屏幕截图传输到另一台 PC 并在窗口中显示。 GetDIBits 和 SetDIBits 函数都成功,建立连接,发送数据,但另一面没有图像,只是黑。

这是我的发送代码:

void GetScreenData(BITMAPINFO* bi, BYTE* buf) //gets the bitmap data
{
HBITMAP hBitmap;
BITMAP Bitmap;
RECT r;

HDC ActiveDC = GetDC(hActive);
HDC CopyDC = CreateCompatibleDC(ActiveDC);

GetWindowRect(hActive, &r);

int scrWidth = r.right-r.left;
int scrHeight = r.bottom-r.top;

hBitmap = CreateCompatibleBitmap(ActiveDC, scrWidth, scrHeight);
SelectObject(CopyDC, hBitmap);

BitBlt(CopyDC, 0, 0, scrWidth, scrHeight, ActiveDC, 0, 0, SRCCOPY);

GetObject(hBitmap, sizeof(BITMAP), &Bitmap);

int cClrBits = Bitmap.bmPlanes*Bitmap.bmBitsPixel;

memset(bi, 0, sizeof(BITMAPINFO));

bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bi->bmiHeader.biWidth = Bitmap.bmWidth;
bi->bmiHeader.biHeight = Bitmap.bmHeight;
bi->bmiHeader.biPlanes = Bitmap.bmPlanes;
bi->bmiHeader.biBitCount = Bitmap.bmBitsPixel;

if(cClrBits<24)
{
bi->bmiHeader.biClrUsed = (1<<cClrBits);
}

bi->bmiHeader.biCompression = BI_RGB;
bi->bmiHeader.biSizeImage = ((bi->bmiHeader.biWidth * cClrBits +31) & ~31)/8*bi->bmiHeader.biHeight;

int i = GetDIBits(CopyDC, hBitmap, 0, scrHeight, buf, bi, DIB_RGB_COLORS);

printf("GetDIBits returned %i\n", i);

ReleaseDC(hActive, ActiveDC);
DeleteDC(CopyDC);
}

DWORD WINAPI SendImage(LPVOID param) //sends the bitmap data
{
BITMAPINFO bi;
BYTE* data = new BYTE[256*256*256];
BYTE* buf = new BYTE[256*256*256];
BYTE *packetsize1, *packetsize2;
int biSize = sizeof(BITMAPINFO);
int i, clocks, oldclocks=0;

while(true)
{
clocks=clock();

if((clocks-oldclocks)*CLOCKS_PER_SEC<0.1)
{
continue;
}

oldclocks=clocks;

if(bConnected)
{
GetScreenData(&bi, buf);

i=0;

data[i++]=3;
packetsize1=&data[i++];
packetsize2=&data[i++];

memcpy(data+i, &bi, biSize);

i+=biSize;

memcpy(data+i, buf, bi.bmiHeader.biSizeImage);

printf("Sending image...\n");

i+=bi.bmiHeader.biSizeImage;

*packetsize1=int(i/256);
*packetsize2=int(i%256);

send(s, (char*)data, i, 0);
}
}
}

这是接收方:

void DrawScreen(HDC hdc) //called from windows message WM_PAINT
{
HGDIOBJ hobj;

hobj = SelectObject(RemoteDC, hRemoteBitmap);

BitBlt(hdc, 0, 0, scrWidth, scrHeight, RemoteDC, 0, 0, SRCCOPY);

SelectObject(hdc, hobj);
}

DWORD WINAPI RecvData(LPVOID param)
{
BYTE* data = new BYTE[256*256*256];
int packetsize, num;
int newWidth, newHeight;
int recvimgsize=0;

bool bAwaitingImage = false;

while(true)
{
if(bConnected)
{
num=recv(s, (char*)data, 3, 0);

if(num>0)
{
packetsize = data[1]*256+data[2];

num=recv(s, (char*)(data+3), packetsize-3, 0);
}

if(num>0)
{
switch(data[0])
{
case 2: //received information about window size (image size)
newWidth = data[3]*256+data[4];
newHeight = data[5]*256+data[6];

if(newHeight!=scrHeight || newWidth!=scrWidth)
{
scrWidth = newWidth;
scrHeight = newHeight;

RECT r;

GetWindowRect(hwnd, &r);
SetWindowPos(hwnd, NULL, r.left, r.top, scrWidth, scrHeight, 0);

HDC ThisDC = GetDC(hwnd);

DeleteDC(RemoteDC);
RemoteDC = CreateCompatibleDC(ThisDC);

DeleteObject(hRemoteBitmap);
hRemoteBitmap = CreateCompatibleBitmap(ThisDC, scrWidth, scrHeight);

SelectObject(RemoteDC, hRemoteBitmap);

ReleaseDC(hwnd, ThisDC);
}
break;
case 3:
{
BITMAPINFO bi;
HBITMAP hBitmap;

int biSize = sizeof(BITMAPINFO);
memcpy(&bi, data+3, biSize);
SetDIBits(RemoteDC, hRemoteBitmap, 0, scrHeight, data+biSize+3, &bi, DIB_RGB_COLORS);

InvalidateRect(hwnd, NULL, false);

break;
}
}

continue;
}

if(num==0)
{
//connection closed
bConnected=false;
}else{
//error
bConnected=false;
}
}
}
}

我在这里提供的代码有点长,因为我不确定有什么用。提前谢谢你。

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com