0

我已经阅读了很多关于尝试对 Richedit 控件进行双缓冲的问题,但没有看到对这个特定问题的任何直接答案(如果有微软官方声明的引用/链接,那就太好了)。

这是我一直用于测试的一些代码(VCL/Delphi/Borland Builder 6.0):

if(Message.Msg == WM_PAINT)
  {
  HDC dc = GetDC(0);
  HBITMAP memBitmap = CreateCompatibleBitmap(dc,ClientRect.Right,ClientRect.Bottom);
  ReleaseDC(0,dc);
  HBITMAP memDC = CreateCompatibleDC(0);
  HBITMAP oldBitmap = SelectObject(memDC,memBitmap);
  try{
  //PAINTSTRUCT ps;
  //dc = BeginPaint(Handle,&ps);
  dc = GetDC(Handle);
  Message.WParam = (int)memDC;
  inherited::WndProc(Message);
  Message.WParam = 0;
  //BitBlt(dc,0,0,ClientRect.Right,ClientRect.Bottom,memDC,0,0,SRCCOPY);
  ReleaseDC(Handle,dc);
  //EndPaint(Handle,&ps);
  } __finally
     {
     SelectObject(memDC,oldBitmap);
     DeleteDC(memDC);
     DeleteObject(memBitmap);
     }
  return;
  }

如果我在继承::WndProc() 之前调用 BeginPaint() (将消息传递给那些不知道 VCL 的控件),那么控件不会在我的内存 DC 或实际窗口 DC 上绘制任何内容。如果我改为调用 GetDC(),控件仍然不会在内存 DC 上绘制,但它会直接在窗口 DC 上绘制。我通过注释掉我的 BitBlt() 调用来确认这一点。如果没有注释掉,客户区全黑(意味着控件根本没有在内存 DC 上绘制),如果我注释掉那行,控件正确绘制(这意味着它忽略了 WParam 内存 DC 并直接进入窗口 DC)。

虽然听起来我已经回答了我自己的问题,但我真正想要的是其他人的确认(链接到 MS KB 文章或 MSDN 会很棒,所以我可以向我的老板展示:),以及实现双缓冲的其他可能的想法? 我不能使用我发现的大多数技巧,比如将控件隐藏在屏幕外或使用 WM_PRINT,因为我需要这个控件才能真正用于用户输入和滚动条,它不仅仅是用于显示的只读。

此外,该控件使用的是 RichEdit 2.0,即使我使用的是 VCL.. 它已被修改为将窗口创建为“richedit20a”类。我还确认 VCL 层根本没有弄乱绘画,所以在纯 win32 代码中应该看到同样的行为。

4

1 回答 1

4

我真正想要的是其他人的确认(链接到 MS KB 文章或 MSDN 会很棒,所以我可以向我的老板展示 :)

明显的位置怎么样:消息的文档WM_PAINT,清楚地说明

参数

不使用此参数。

因此,没有理由期望修改wParam遗嘱会产生任何影响。

于 2012-03-01T16:55:58.547 回答