I started working on something similar to a remote control application in c++. I wish to transfer a particular window's screenshot to another PC and display it in a window. Both GetDIBits and SetDIBits functions succeed, the connection is established, the data is sent, yet the image does not appear on the other side, just blackness.
Here's my sending code:
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);
}
}
}
And here is the receiving side:
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;
}
}
}
}
The code I presented here is a bit long, because I wasn't sure what might be of use. Thank you in advance.