如何将此类位图复制到 DC
How to copy such bitmap to a DC?
我正在编写一个带有GUI的远程控制程序。下面是服务器代码的一部分:
HDC desktopHdc = GetDC(NULL);
int bm_x = GetDeviceCaps(desktopHdc, HORZRES);
int bm_y = GetDeviceCaps(desktopHdc, VERTRES);
DWORD bmSize = ((bm_x * 32 + 31) / 32) * bm_y * 4;
HDC memHdc = CreateCompatibleDC(desktopHdc);
HBITMAP bitmap = CreateCompatibleBitmap(desktopHdc, bm_x, bm_y);
while(TRUE)
{
SelectObject(memHdc, (HGDIOBJ)bitmap);
HANDLE hDIB = GlobalAlloc(GHND, bmSize);
char* bmbits = (char*)GlobalLock(hDIB);
BitBlt(memHdc, 0, 0, bm_x, bm_y, desktopHdc, 0, 0, SRCCOPY);
GetBitmapBits(bitmap, bmSize, bmbits);
int bytes = send(secondarySocket, bmbits, bmSize, 0);
if(bytes == 0 || bytes == -1)
{
MessageBox(NULL, "disconnected", "", 0);
break;
}
GlobalUnlock(hDIB);
GlobalFree(hDIB);
Sleep(1000);
}
下面是一些客户端代码:
HDC windowHdc = GetDC(hwnd);
HDC memHdc = CreateCompatibleDC(windowHdc);
// bm_x and bm_y are sent by the server and received by the client
DWORD bmSize = ((bm_x * 32 + 31) / 32) * bm_y * 4;
while(TRUE)
{
HANDLE hDIB = GlobalAlloc(GHND, bmSize);
char* buf = (char*)GlobalLock(hDIB);
int bytes = recv(mainSocket, buf, bmSize, 0);
if(bytes == 0 || bytes == -1)
{
MessageBox(NULL, "disconnected", "", 0);
break;
}
else
{
buf[bytes] = ' ';
HBITMAP bmp = CreateCompatibleBitmap(memHdc, bm_x, bm_y);
SetBitmapBits(bmp, bmSize, buf);
SelectObject(memHdc, bmp);
BitBlt(windowHdc, 0, 0, bm_x, bm_y, memHdc, 0, 0, SRCCOPY); // should copy received bitmap to the window DC
}
GlobalUnlock(hDIB);
GlobalFree(hDIB);
}
我在客户端中正确接收了整个缓冲区。我用它制作了一个位图。然后我只是无法将其复制到窗口 DC - 什么也没出现。我该怎么做?
编辑
这是我的新代码:
DWORD thServerSend(LPVOID param)
{
HDC memHdc = CreateCompatibleDC(desktopHdc);
HBITMAP bitmap;
while(TRUE)
{
BITMAPINFO bmi;
ZeroMemory(&bmi,sizeof(BITMAPINFO));
bmi.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biWidth=bm_x;
bmi.bmiHeader.biHeight=bm_y;
bmi.bmiHeader.biPlanes=1;
bmi.bmiHeader.biBitCount=32;
char* bmbits;
bitmap = CreateDIBSection(memHdc, &bmi, DIB_RGB_COLORS, (void**)&bmbits, NULL, 0);
HBITMAP restore = (HBITMAP)SelectObject(memHdc, (HGDIOBJ)bitmap);
BitBlt(memHdc, 0, 0, bm_x, bm_y, desktopHdc, 0, 0, SRCCOPY);
int bytes = send(secondarySocket, bmbits, bmSize, 0);
if(bytes == 0 || bytes == -1)
{
MessageBox(NULL, "disconnected", "", 0);
break;
}
std::cout << "bmsize: " << bmSize << " bytes: " << bytes << " bmbits: " << bmbits << std::endl; // for debugging
SelectObject(memHdc, restore);
DeleteObject(bitmap);
Sleep(1000);
}
DeleteDC(memHdc);
DeleteObject(bitmap);
shutdown(mainSocket, SD_BOTH);
shutdown(secondarySocket, SD_BOTH);
return 0;
}
DWORD thClient(LPVOID param) // window handle is passed through "param" parameter
{
HDC windowHdc = GetDC((HWND)param);
HDC memHdc = CreateCompatibleDC(windowHdc);
HBITMAP restore;
while(TRUE)
{
BITMAPINFO bmi;
ZeroMemory(&bmi,sizeof(BITMAPINFO));
bmi.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biWidth=bm_x;
bmi.bmiHeader.biHeight=bm_y;
bmi.bmiHeader.biPlanes=1;
bmi.bmiHeader.biBitCount=32;
char* buffer;
HBITMAP bitmap = CreateDIBSection(windowHdc, &bmi, DIB_RGB_COLORS, (void**)&buffer, NULL, 0);
int bytes = recv(mainSocket, buffer, bmSize, 0);
if(bytes == 0 || bytes == -1)
{
MessageBox(NULL, "Disconnected.", "", 0);
break;
}
else
{
restore = (HBITMAP)SelectObject(memHdc,bitmap);
BitBlt(windowHdc, 0, 0, bm_x, bm_y, memHdc, 0, 0, SRCCOPY);
std::cout << "bmsize: " << bmSize << " bytes: " << bytes << " bmbits: " << buffer << std::endl; // for debugging
SelectObject(memHdc, restore);
}
}
DeleteDC(memHdc);
return 0;
}
编辑 2
已解决的问题:
也就是说,我如何调用线程:
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)thClient, (PVOID)&hwnd, 0, NULL);
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)thServerSend, (PVOID)hwnd, 0, NULL);
如您所见,我在线程调用函数的参数中使用了对窗口句柄的引用。这秘密地造成了愚蠢的错误。没有完整的代码,没有人能解决它。
不要创建兼容的位图。创建 DIB 部分:http://msdn.microsoft.com/en-us/library/windows/desktop/dd183494%28v=vs.85%29.aspx
BITMAPINFO bi;
ZeroMemory(&bi,sizeof(BITMAPINFO));
bi.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
bi.bmiHeader.biWidth=Width;
bi.bmiHeader.biHeight=Height;
bi.bmiHeader.biPlanes=1;
bi.bmiHeader.biBitCount=32;
char* buffer;
HBITMAP bitmap=CreateDIBSection(dc,&bi,DIB_RGB_COLORS,&buffer,NULL,0);
// copy pixels to buffer
SelectObject(dc,bitmap);
BitBlt(....
相关文章:
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 在C++程序中输入的文本文件将不起作用,除非文本被复制和粘贴
- 使用strcpy将char数组的元素复制到另一个数组
- 是否可以初始化不可复制类型的成员变量(或基类)
- 为什么在C++中使用私有复制构造函数与删除复制构造函数
- C++ Windows 驱动程序MSB3030无法复制该文件,因为它找不到
- 复制列表初始化的隐式转换的等级是多少
- 当从函数参数中的临时值调用复制构造函数时
- 有可能在Armadillo中复制MATLAB circshift方法吗
- 复制几乎为空的数组的最快方法
- 以下示例中如何避免代码复制?C++/库达
- 如果有一个模板构造函数只有一个泛型参数,为什么我必须有一个复制构造函数
- 为什么需要复制构造函数,在哪些情况下它们非常有用
- 不能将复制初始化与隐式转换的多个步骤一起使用
- 当有分配器意识的容器被复制/移动时,反弹分配器是否被复制/移走
- 为什么复制而不是移动数据元素?
- 文件系统:复制功能的速度秘诀是什么
- 使用仅使用一次的变量调用的复制构造函数.这可能是通过调用move构造函数进行编译器优化的情况吗
- 为什么类中的ostringstream类型的成员会导致";调用隐含删除复制构造函数";错误
- 如何将此类位图复制到 DC