0

鉴于我在 GDI 中实现双缓冲:

static HDC hdc;
static HDC backDC;
static HBITMAP backBuffer;
static HGDIOBJ oldBitmap;
static RECT client;

case WM_CREATE:     
     hdc=GetDC(hWnd);
    GetClientRect(hWnd, &client);
    backDC=CreateCompatibleDC(hdc);         
    backBuffer=CreateCompatibleBitmap(hdc,client.right,client.bottom);
    oldBitmap=SelectObject(backDC,backBuffer);
    ReleaseDC(hWnd,hdc);

case WM_PAINT:


Rectangle(backDC, 0, 0,client.right,client.bottom); // displays rectangle the
 size of client to draw on it
      hdc = BeginPaint(hWnd, &ps);  
      BitBlt(hdc,0,0,client.right,client.bottom,backDC,0,0,SRCCOPY);
    // TODO: Add any drawing code here...
       EndPaint(hWnd, &ps);

如何处理调整大小?我试图做的一件事是

case WM_SIZE:   
client.right=LOWORD(lParam);
client.bottom=HIWORD(lParam);
    SendMessage(hWnd,WM_CREATE,NULL,NULL);

它的作用是,一旦我收到带有新客户端坐标的 resize 消息,它就会将消息发送到 WM_CREATE 并且它实际上可以工作....但是!它会造成大量泄漏,因为我基本上每次都会创建一个新位图而不会破坏它。有人可以告诉我是否有更好的方法吗?谢谢

4

2 回答 2

1

保留后台缓冲区是一种并不总是需要的优化。您可以在 WM_PAINT 处理程序中创建它(到 GetClientRect 的大小),对其进行绘制,从它blit 到实际的窗口 DC,然后进行清理。没有泄漏。所有消息处理程序之间没有功能分布。没有全局变量。干净整洁。

如果您确实想保留一个,我会上课。构造函数采用大小。析构函数清理一切。在 WM_SIZE 上,构造一个新的作为本地堆栈变量,与旧的交换,并让临时堆栈的析构函数清理一。

于 2012-10-31T17:15:23.500 回答
0

我建议将后台缓冲区设置为固定大小(通常是屏幕大小),然后使用StretchBlt(或者StretchDIBits如果您使用的是 DIB)在显示表面上以适当的大小呈现它。

这样,您就不必担心重新分配后台缓冲区。

于 2012-10-31T17:50:06.770 回答