取得panel后面的背景很简单哦
两种方法:
1. panel.visible := false; get the background; panel.visible := true;
2. 稍微麻烦点(使panel自身变成透明):
如果自己做个控件继承自TPanel的话比较容易:
1. override createparams方法:
procedure CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(params);
Params.exstyles := Params.exstyles or WS_EX_TRANSPARENT; // 设置为透明窗
end;
2. 截取WM_ERASEBKGND消息.
procedure WMEraseBkgnd(var Message: TMessage);
begin
Message.result := 1; // 什么都不做既返回. panel默认的erasebkgnd将
// fillrect, 所以需要去掉它
end;
3. 最重要的一步: 需要通过SetWindowLong修改parent control的style:
procedure SetParentStyle;
begin
SetWindowLong(Parent.Handle, GWL_STYLE,
GetWindowLong(Parent.Handle, GWL_STYLE) and
not WS_CLIPCHILDREN);
// 如果没有这步, parent在repaint时不会画上被当前panel遮住的部分. 不过在
// 第一次建立时也能取到背景, 不过不是parent的图案, 而是透明到Desktop上去了,
// 显示的是当前Desktop上的图案, 效果就象在你的form上挖了个洞.
RecreateWnd; // 重建当前panel的handle, 系统将自动重画, 这时panel的
// 背景已经是原先被遮住的部分了
end;
以上各步是建立透明TWinControl类可视控件的必备步骤.
如果想在外界实现也是可行的(不继承), 完全可以在程序运行过程中将一个标准panel变成透明.
主要思路和上面一样, 只是需用SetWindowLong(Panel.handle, GWL_EXSTYLE, ....)
替换上述override CreateParams步骤, 然后替换panel的windowproc(需要保存原来的
windowproc地址), 用如下代码:
SetWindowLong(Panel.handle, GWL_WNDPROC, integer(@NewWindowProc));
在NewWindowProc过程中判断接受的消息是否是WM_ERASEBKGND, 如果是, 则直接返回, 否
则用CallWindowProc调用原来panel的windowproc处理)
最后RecreateWnd, 重建整个form, 你就会发觉原来不透明的panel变透明了(对其他控件没有
影响)