So I have a working HBITMAP which can be set to the clipboard using SetClipboardData
. What I'm trying to do is send the HBITMAP to another application (without writing anything to disk) which will receive it and be able set it to the clipboard just as the original application could do. I know that you can't just send the handle so I used GetObject
and GetDIBits
and sent the collected data across. I've looked at all the other people's stackoverflow questions about sending hbitmaps over a network but none of the answers given have worked for me.
UPDATE: Code still not working after updated.
This is now what it shows as when I paste the clipboard into mspaint
Here's what my code looks like now:
Client:
#include <WinSock2.h>
#include <Windows.h>
#include <stdio.h>
#pragma comment(lib, "Ws2_32.lib")
#define Port 6000
SOCKET Socket, Sub;
WSADATA Winsock;
sockaddr_in Addr;
sockaddr_in IncomingAddress;
int AddressLen = sizeof(IncomingAddress);
BOOL send_function(BYTE* dib, int dib_size) {
WSAStartup(MAKEWORD(2, 2), &Winsock); // Start Winsock
if (LOBYTE(Winsock.wVersion) != 2 || HIBYTE(Winsock.wVersion) != 2) // Check version
{
WSACleanup();
return 0;
}
Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
ZeroMemory(&Addr, sizeof(Addr));
Addr.sin_family = AF_INET;
Addr.sin_port = htons(Port);
bind(Socket, (sockaddr*)&Addr, sizeof(Addr));
if (listen(Socket, 1) == SOCKET_ERROR)
{
printf("listening error\n");
}
else
{
printf("listening ok\n");
}
if (Sub = accept(Socket, (sockaddr*)&IncomingAddress, &AddressLen))
{
char* ClientIP = inet_ntoa(IncomingAddress.sin_addr);
int ClientPort = ntohs(IncomingAddress.sin_port);
printf("Client conncted!\n");
printf("IP: %s:%d\n", ClientIP, ClientPort);
printf("Sending data .. \n");
char bufsize[10];
sprintf(bufsize, "%d", dib_size);
send(Sub, (char*)bufsize, 10, 0);
send(Sub, (char*)dib, dib_size, 0);
closesocket(Sub);
closesocket(Socket);
WSACleanup();
}
}
int main()
{
HWND hwnd = GetWindow(GetForegroundWindow(), GW_HWNDLAST);
RECT rc;
GetWindowRect(hwnd, &rc);
HDC hdcScreen = GetDC(NULL);
HDC hdc = CreateCompatibleDC(hdcScreen);
HBITMAP hbmp = CreateCompatibleBitmap(hdcScreen,
rc.right - rc.left, rc.bottom - rc.top);
SelectObject(hdc, hbmp);
//Print to memory hdc
PrintWindow(hwnd, hdc, NULL);
auto hcopy = (HBITMAP)CopyImage(hbmp, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
BITMAP bm;
GetObject(hcopy, sizeof(bm), &bm);
BITMAPINFOHEADER bi = { sizeof(bi) };
bi.biWidth = bm.bmWidth;
bi.biHeight = bm.bmHeight;
bi.biBitCount = bm.bmBitsPixel;
bi.biPlanes = bm.bmPlanes;
bi.biSizeImage = bm.bmWidthBytes * bm.bmHeight;
int dib_size = sizeof(bi) + bi.biSizeImage;
BYTE* dib = new BYTE[dib_size];
memcpy(dib, &bi, sizeof(bi));
memcpy(dib + sizeof(bi), bm.bmBits, bi.biSizeImage);
send_function(dib, dib_size);
//cleanup
DeleteObject(hcopy);
delete[]dib;
getchar();
return 0;
}
Server:
#include <WinSock2.h>
#include <Windows.h>
#include <stdio.h>
#pragma comment(lib, "Ws2_32.lib")
SOCKET Socket;
WSADATA Winsock;
sockaddr_in Addr;
int Addrlen = sizeof(Addr);
void receive_function(BYTE* dib, int dib_size)
{
BITMAPINFOHEADER* bi = (BITMAPINFOHEADER*)dib;
BYTE* bits = dib + sizeof(bi);
HBITMAP hbitmap = CreateBitmap(bi->biWidth, bi->biHeight, bi->biPlanes, bi->biBitCount, bits);
OpenClipboard(NULL);
EmptyClipboard();
SetClipboardData(CF_BITMAP, hbitmap);
CloseClipboard();
printf("Clipboard set!");
getchar();
}
int main()
{
WSAStartup(MAKEWORD(2, 2), &Winsock); // Start Winsock
if (LOBYTE(Winsock.wVersion) != 2 || HIBYTE(Winsock.wVersion) != 2) // Check version
{
WSACleanup();
return 0;
}
Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
ZeroMemory(&Addr, sizeof(Addr)); // clear the struct
Addr.sin_family = AF_INET; // set the address family
Addr.sin_addr.s_addr = inet_addr("127.0.0.1");
Addr.sin_port = htons(6000); // set the port
if (connect(Socket, (sockaddr*)&Addr, sizeof(Addr)) < 0)
{
printf("Connection failed !\n");
getchar();
return 0;
}
printf("Connection successful !\n");
printf("Receiving data .. \n");
int dib_size = 0;
char Filesize[10];
if (recv(Socket, Filesize, 10, 0)) // File size
{
dib_size = atoi(Filesize);
}
printf("File size: %d\n", dib_size);
BYTE* dib = new BYTE[dib_size];
if (recv(Socket, (char*)dib, dib_size, 0))
{
receive_function(dib, dib_size);
}
getchar();
return 0;
}
Any and all help appreciated!