任何将一个激活窗口中的内容保存到一个位图文件(BMP)中?(20分)

  • 主题发起人 question
  • 开始时间
Q

question

Unregistered / Unconfirmed
GUEST, unregistred user!
需要将屏幕中所有的信息,包括按钮信息等。同时要考虑窗口在自动扩张的情况
下的问题。
 
下例保存当前form的client区域:

procedure SaveSceenToFile(Sender: TForm; filename: string);
var
bmp: TBitmap;
DC: HDC;
begin
bmp:=TBitmap.Create;
dc:=getDC(Sender.Handle);
bmp.Height:=Sender.ClientHeight;
bmp.Width:=Sender.ClientWidth;
bitblt(bmp.Canvas.Handle, 0,0, bmp.Width, bmp.Height, DC, 0,0);
bmp.SaveToFile(filename);
bmp.Free;
ReleaseDC(Sender.Handle, DC);
end;
 
有两个问题:
一:
bitblt(bmp.Canvas.Handle, 0,0, bmp.Width, bmp.Height, DC, 0,0);
少了一个参数。我写成
bitblt(bmp.Canvas.Handle, 0,0, bmp.Width, bmp.Height, DC, 0,0,SRCCOPY);
二:在 Form 出现滚动条后,无法保存滚动条里的信息。
 
上例是保存当前form的client区域的(不包括标题和边框和scrollbars)
要保存整个form可以用以下例子:
procedure SaveFormToFile(sender: TForm; Filename: string);
var
bmp: TBitmap;
DC,WDC: HDC;
rect: TRect;
begin
bmp:=TBitmap.Create;
WDC:=GetDC(GetDesktopWindow);
DC:=GetDC(Sender.Handle);
try
GetWindowRect(DC, rect);
bmp.Width:=Rect.Right-Rect.Left;
bmp.Height:=Rect.Bottom-Rect.Top;
BitBlt(bmp.Canvas.Handle, 0,0, width, height, WDC, Rect.Left, Rect.Right, SRCCOPY);
bmp.SaveToFile(Filename);
finally
bmp.Free;
ReleaseDC(Sender.Handle, DC);
ReleaseDC(GetDesktopWindow, WDC);
end;
end;
 
我想我没有能将我的问题讲明白,我要保存的就是客户区的数据,就是第一种方法那样,只是当窗口里的内容超过了窗口的定义大小,窗口就会出现滚动条,而此时如果
用第一种方法就无法保存滚动条里面遮住的信息。而我却想得到,如何解决?谢谢
PS:我并不要保存窗口标题和滚动条本身。烦劳您了。
 
想当然的方法如下: (未测试过)

procedure SaveFormToFile(Sender: TForm; Filename: string);
var
bmp: TBitmap;
H, W: integer;
i: integer;
begin
bmp:=TBitmap.Create;
H:=0;
W:=0;
for i:=0 to Sender.ControlCount-1 do
begin
H:=MaxIntValue(H, Sender.Controls.Top+Sender.Controls.Height);
W:=MaxIntValue(W, Sender.Controls.Left+Sender.Controls.Width);
end;
H:=MaxIntValue(H, Sender.ClientRect.Bottom);
W:=MaxIntValue(W, Sender.ClientRect.Right);
// Get Height & Width that should be painted
bmp.Height:=H;
bmp.Width:=W;
Sender.PaintTo(bmp.Canvas.Handle, 0, 0);
bmp.SaveToFile(Filename);
bmp.Free;
end;
 
>用第一种方法就无法保存滚动条里面遮住的信息。而我却想得到,如何解决?谢谢
>PS:我并不要保存窗口标题和滚动条本身。烦劳您了。
想把被裁减掉的部分抓出来,
这个,恐怕,很难。。。 :(
除非你修改VCL,给可视部件添加一个向任意输入的DC中Draw自己的方法

 
应该可以用WM_PAINT消息实现的.记得WM_PAINT有个参数是HDC,如果用
应该已生成Canvas的Handle替代原来的NULL(0),就可以了.

这种功能的软件我见过,猜测是用这个方法实现的.因为我读VCL的源码,见
很多响应WM_PAINT消息的函数都有判断HDC的代码,只有在消息中HDC为
NULL时才构造Canvas,然后设置裁剪区域,将边界和子窗口裁掉.

由于没有实验过所以不敢肯定.兄台若试通了,也告诉小第一声.
 
要保存数据形式为bmp如何恢复?
还是用文件流,把窗体控件写入!
 
new一个新TBitmap,并用该Bitmap生成一个基于Memory的Canvas,
如果在这个Canvas上画画,所有动作将反映到Bitmap上.用这个Canvas
的Handle作为WM_PAINT的WPARAM,就可以让窗口画到Bitmap上.
完成之后,就可以用Bitmap的存盘函数将内容存盘了.

用流将控件写到文件的方法感觉不太好,而且,如果窗口不在当前进程
的话,将无法实现.
 
question:
这个问题已经很长时间没有人参加讨论,为保持版面
整洁,节约网友时间,请提问者采取必要处理措施。
关于图形图象版管理细则,请参见<a href="http://www.gislab.ecnu.edu.cn/delphibbs/DispQ.asp?LID=111927">这个</a>问题。如两天
内提问者没有响应,我将采取强制措施。

如有管理建议,请到<a href="http://www.gislab.ecnu.edu.cn/delphibbs/DispQ.asp?LID=111927">这里</a>提出。谢谢!
 
接受答案了.
 
顶部