重现问题步骤:
1. 新建一个form,放一个 button. button.Onclick写如下代码:
procedure TForm1.Button1Click(Sender: TObject);
var
bmp: TBitmap;
dc: HDC;
begin
bmp := TBitmap.Create;
bmp.PixelFormat := pf24Bit;
bmp.Width := Width;
bmp.Height := Height;
dc := GetWindowDC(Handle);
BitBlt(bmp.Canvas.Handle, 0, 0, Width, Height, dc, 0, 0, SRCCOPY);
ReleaseDC(Handle, dc);
bmp.SaveToFile(ExtractFilePath(ParamStr(0))+'temp.bmp');
bmp.Free;
end;
很简单的程序吧, 作用就是截取整个form的图片保存到temp.bmp中.
2. 编译后在win7(with Aero Theme, 也就是毛玻璃效果)下运行(估计vista+Aero Theme也一样的毛病), 点击button. 不要退出程序,用explorer察看生成的bmp, 一切正常. 删除这个bmp.
3. 回到程序中,把窗口拖大点,再次点击button. 再看看生成的bmp。惊奇吗?
经过测试,发觉只有form最大/最小或者隐藏再显示后才可以再次得到正确的bmp, 如果只是简单改变窗口大小后用GetWindowDC获得的DC中保存的边框图案永远是第一次得到的。
很头疼,不知道有什么办法可以绕过这个缺陷。而更头疼的是如果用SetLayeredWindowAttributes设置了Alpha值的窗口用GetWindowDC获取的DC中根本就没有frame的图案了,即使给窗口发WM_PRINT也打不出frame。
那么,有什么办法可以在这种情况下获取正确的窗口图案呢? 用DrawThemeBackground自己画?怎么画?