Bitmap-Übertragung mit Winsock, GetDIBits und SetDiBits [closed]

Ich habe angefangen, an etwas ähnlichem wie einer Fernsteuerungsanwendung in c ++ zu arbeiten. Ich möchte den Screenshot eines bestimmten Fensters auf einen anderen PC übertragen und in einem Fenster anzeigen. Sowohl GetDIBits- als auch SetDIBits-Funktionen sind erfolgreich, die Verbindung wird hergestellt, die Daten werden gesendet, das Bild wird jedoch nicht auf der anderen Seite angezeigt, sondern nur in der Schwärze.

Hier ist mein Sendecode:

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);
    }
  }
}

Und hier ist die empfangende Seite:

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;
      }
    }
  }
}

Der Code, den ich hier vorgestellt habe, ist etwas lang, weil ich mir nicht sicher war, was von Nutzen sein könnte. Danke im Voraus

Antworten auf die Frage(4)

Ihre Antwort auf die Frage