【发布时间】:2015-01-25 11:25:41
【问题描述】:
我正在尝试在一个窗口内显示用户监视器,该窗口全部缩小到可能的最大尺寸。目前它不使用缓冲区,我不确定如何根据需要创建缓冲区。
当它动态绘制监视器时,不必再用 WM_ERASEBKGND 重新绘制整个窗口白色,当它被调整大小时,我认为,经过大量阅读后,将整个“虚拟桌面”的比例表示为内存 DIB 将是最好的方法:因此我可以填充监视器之间的空白区域,从而不必重新绘制它们。
一个多部分的问题。是否按照建议创建一个内存规模的虚拟桌面,可以将 BitBlt 用于显示器?为此,我会使用 CreateDIBSection 吗?
目前我的 WM_PAINT 如下所示:
hdc = BeginPaint(hwnd, &ps);
innerBorder = 2;
additional = 350;
ratio = (static_cast<double>(sA.getDesktop()->right - sA.getDesktop()->left) / (sA.getDesktop()->bottom - sA.getDesktop()->top));
cxMax = max((innerBorder * 2), min((cA.right - border), (((cA.bottom - border - additional) * ratio))));
cyMax = max((innerBorder * 2) , min((cA.bottom - border - additional), (((cA.right - border) / ratio))));
cxBorder = (cA.right - cxMax) / 2;
SelectObject(hdc, GetStockObject(DC_PEN));
SelectObject(hdc, GetStockObject(DC_BRUSH));
SetDCPenColor(hdc, RGB(255, 255, 255));
//Draw Borders around virtual desktop
Rectangle(hdc, cA.left, cA.top, cxBorder, cA.bottom);
Rectangle(hdc, cA.right - cxBorder, cA.top, cA.right, cA.bottom);
//Draw Borders around virtual desktop
Rectangle(hdc, cxBorder, cA.top, cA.right - cxBorder, (border / 2));
Rectangle(hdc, cxBorder, cyMax + (border / 2), cA.right - cxBorder, cA.bottom);
for (i = 0; i < sA.getNumberOfMonitors(); i++)
{
rT = {
((static_cast<float>(sA.getMonitor(i)->rcMonitor.left - sA.getDesktop()->left) / (sA.getDesktop()->right - sA.getDesktop()->left)) * cxMax) + cxBorder + innerBorder,
((static_cast<float>(sA.getMonitor(i)->rcMonitor.top - sA.getDesktop()->top) / (sA.getDesktop()->bottom - sA.getDesktop()->top)) * cyMax) + (border / 2) + innerBorder,
((static_cast<float>(sA.getMonitor(i)->rcMonitor.right - sA.getDesktop()->left) / (sA.getDesktop()->right - sA.getDesktop()->left)) * cxMax) + cxBorder - innerBorder,
((static_cast<float>(sA.getMonitor(i)->rcMonitor.bottom - sA.getDesktop()->top) / (sA.getDesktop()->bottom - sA.getDesktop()->top)) * cyMax) + (border / 2) - innerBorder,
};
SetDCPenColor(hdc, RGB(255, 255, 255));
//Draw Borders around Monitor RECT
Rectangle(hdc, rT.left - innerBorder, rT.top, rT.left, rT.bottom);
Rectangle(hdc, rT.right, rT.top, rT.right + innerBorder, rT.bottom);
Rectangle(hdc, rT.left - innerBorder, rT.bottom, rT.right + innerBorder, rT.bottom + innerBorder);
Rectangle(hdc, rT.left - innerBorder, rT.top - innerBorder, rT.right + innerBorder, rT.top);
//Draw Monitor RECT
SetDCPenColor(hdc, RGB(0, 0, 0));
Rectangle(hdc, rT.left, rT.top, rT.right, rT.bottom);
DrawText(hdc, sA.getMonitor(i)->szDevice, strlen(sA.getMonitor(i)->szDevice), &rT, DT_CENTER | DT_BOTTOM | DT_NOPREFIX | DT_SINGLELINE);
}
EndPaint(hwnd, &ps);
其中大部分只是计算显示器与窗口的相对大小,还很少绘制。我确实希望它从图像中加载填充和边框。我想我几乎撞到了一堵砖墙。我不确定如何继续创建内存缓冲区。
编辑:我创建内存缓冲区的众多尝试之一,这会产生单色位图。
hdcDisplay = BeginPaint(hwnd, &ps);
hdcBuffer = CreateCompatibleDC(hdcDisplay);
innerBorder = 2;
additional = 350;
ratio = (static_cast<double>(sA.getDesktop()->right - sA.getDesktop()->left) / (sA.getDesktop()->bottom - sA.getDesktop()->top));
cxMax = max((innerBorder * 2), min((cA.right - border), (((cA.bottom - border - additional) * ratio))));
cyMax = max((innerBorder * 2) , min((cA.bottom - border - additional), (((cA.right - border) / ratio))));
cxBorder = (cA.right - cxMax) / 2;
hBitmapDraw = CreateCompatibleBitmap(hdcDisplay, cxMax, cyMax);
hBitmapPrevious = static_cast<HBITMAP>(SelectObject(hdcBuffer, hBitmapDraw));
GetObject(hBitmapDraw, sizeof(BITMAP), &bmpDraw);
BITMAPINFOHEADER bmpInfo;
bmpInfo.biSize = sizeof(BITMAPINFOHEADER);
bmpInfo.biWidth = cxMax;
bmpInfo.biHeight = cyMax;
bmpInfo.biPlanes = 1;
bmpInfo.biBitCount = 32;
bmpInfo.biCompression = BI_RGB;
bmpInfo.biSizeImage = 0;
bmpInfo.biXPelsPerMeter = 0;
bmpInfo.biYPelsPerMeter = 0;
bmpInfo.biClrUsed = 0;
bmpInfo.biClrImportant = 0;
//pBitmapBits = (BYTE*)malloc(sizeof(BYTE)* cxMax * 3 * cyMax);
//hBitmapDraw = CreateDIBSection(hdcDisplay, (BITMAPINFO *)&bmpInfo, DIB_RGB_COLORS, NULL, NULL, 0);
SelectObject(hdcBuffer, hBitmapDraw);
SelectObject(hdcBuffer, GetStockObject(DC_PEN));
SelectObject(hdcBuffer, GetStockObject(DC_BRUSH));
SetDCPenColor(hdcBuffer, RGB(255, 255, 255));
for (i = 0; i < sA.getNumberOfMonitors(); i++)
{
rT = {
((static_cast<float>(sA.getMonitor(i)->rcMonitor.left - sA.getDesktop()->left) / (sA.getDesktop()->right - sA.getDesktop()->left)) * cxMax) + cxBorder + innerBorder,
((static_cast<float>(sA.getMonitor(i)->rcMonitor.top - sA.getDesktop()->top) / (sA.getDesktop()->bottom - sA.getDesktop()->top)) * cyMax) + (border / 2) + innerBorder,
((static_cast<float>(sA.getMonitor(i)->rcMonitor.right - sA.getDesktop()->left) / (sA.getDesktop()->right - sA.getDesktop()->left)) * cxMax) + cxBorder - innerBorder,
((static_cast<float>(sA.getMonitor(i)->rcMonitor.bottom - sA.getDesktop()->top) / (sA.getDesktop()->bottom - sA.getDesktop()->top)) * cyMax) + (border / 2) - innerBorder,
};
SetDCPenColor(hdcBuffer, RGB(255, 255, 255));
//Draw Borders
Rectangle(hdcBuffer, rT.left - innerBorder, rT.top, rT.left, rT.bottom);
Rectangle(hdcBuffer, rT.right, rT.top, rT.right + innerBorder, rT.bottom);
Rectangle(hdcBuffer, rT.left - innerBorder, rT.bottom, rT.right + innerBorder, rT.bottom + innerBorder);
Rectangle(hdcBuffer, rT.left - innerBorder, rT.top - innerBorder, rT.right + innerBorder, rT.top);
SetDCPenColor(hdcBuffer, RGB(0, 0, 0));
Rectangle(hdcBuffer, rT.left, rT.top, rT.right, rT.bottom);
DrawText(hdcBuffer, sA.getMonitor(i)->szDevice, strlen(sA.getMonitor(i)->szDevice), &rT, DT_CENTER | DT_BOTTOM | DT_NOPREFIX | DT_SINGLELINE);
}
BitBlt(hdcDisplay, cxBorder, (border / 2), cxMax - cxBorder, cyMax, hdcBuffer, cxBorder, border/2, SRCCOPY);
SelectObject(hdcBuffer, hBitmapPrevious);
DeleteDC(hdcBuffer);
EndPaint(hwnd, &ps);
【问题讨论】: