好久没提问了!关于SDK ---by zx(50分)

  • 主题发起人 主题发起人 zx
  • 开始时间 开始时间
Z

zx

Unregistered / Unconfirmed
GUEST, unregistred user!
透明窗口的wm_Panit消息响应怎么处理不好!
一个SDK程序:
program Project1;
uses
Windows,
Messages;
const
AppName='Window1';
function WindowProc(Window:HWnd;
AMessage,WParam,LParam:Longint)
:Longint;stdcall;export;
var
PRgn: hRgn;
lpPaint :PaintStruct;
DC1,DC2 :HDC ;
begin
WindowProc:=0;
case AMessage of
wm_Destroy: begin
PostQuitMessage(0);
Exit;
end;
wm_Paint : begin
//这儿应该怎么写才好呢? 移动窗口是保持背景透明!
//每次只有最小化,最大化以后才刷新。
{ DC1:=begin
Paint(window,lpPaint);
PRgn:=CreateRoundRectRgn(10,10,100,100,10,10);
InvalidateRgn(window,PRgn,false);
UpdateWindow(window);
EndPaint(window,lpPaint);}
end;
end;

windowProc:=DefWindowProc(Window,AMessage,WParam,LParam);
end;

function WinRegister:Boolean;
var
WndClass:TWndClass;
begin
WndClass.style:=0;
WndClass.lpfnWndProc:=@WindowProc;
WndClass.cbClsExtra:=0;
WndClass.cbWndExtra:=0;
WndClass.hInstance:=Hinstance;
WndClass.hIcon:=LoadIcon(0,idi_winlogo);
WndClass.hCursor:=LoadCursor(0,idc_arrow);
WndClass.hbrBackground:=0;//HBrush(Color_Window);这样透明...
WndClass.lpszMenuName:=nil;
WndClass.lpszClassName:=AppName;
Result:= ( RegisterClass(WndClass)<>0 );
end;


function WinCreate:HWnd;
var
hWindow: HWnd;
begin
hWindow:= CreateWindow(AppName, 'object pascal window', ws_OverlappedWindow,
cw_UseDefault,cw_UseDefault,cw_UseDefault,cw_UseDefault,
0,0,HInstance,nil);
if hWindow<>0 then
begin
ShowWindow(hWindow,CmdShow);
UpdateWindow(hWindow);
end;

Result:= hWindow;
end;

var
AMessage: TMsg;
hWindow: HWnd;
begin
if not WinRegister then
begin
MessageBox(0,'Registerfailed',nil,mb_OK);
Exit;
end;

hWindow:=WinCreate;
if hWindow=0 then
begin
MessageBox(0,'window create failed',nil,mb_OK);
Exit;
end;

while GetMessage(AMessage,0,0,0)do
begin
TranslateMessage(AMessage);
DispatchMessage(AMessage);
end;
Halt(Amessage.WParam);
end.
 
spy以后看见一堆wm_paint,但是
就是没重画!
 
呵呵, 又是窗口透明...., 给你浇点凉水:
想通过取得form遮住的背景图象以实现透明(或半透明)并且能平滑移动的话, 不幸的消息:
1. 只有通过invisible->sleep->visible取到背景
2. sleep长短不在你的控制之下(只能通过猜一个最安全的长度实现), 一般在300-1500(极端
情况比如在delphi启动或关闭时, 2000也不一定够)之间.
3. 或者在你的窗口显示前保存所有desktop画面, 以后取保存的部分画面做为背景,
限制: 在你的form成为topmost window之后desktop上其他窗口不能有任何变化
deactive之后如果上面的窗口移动时还是只能通过invisible->sleep->visible
方法刷新form.
请教过M$中国公司上海首席VC技术支持, 他也无法解决该问题(窗口半透明并能平滑移动).
移动效果非常惨的一个半透明form控件(不过也想不出更好的算法了), 可以在深度历险找到, 带
源码, 你可以看看它里面的wndproc.
另: 无法跟踪WM_PAINT, 或WM_ERASEBKGND, 或paint等画窗口的消息. 在paint程序中
单步执行, 系统就会在delphi调试环境和被调试程序间来回切换输入焦点, 也就不断产生wm_paint, 所以你永远只能无法跟踪断点之后的语句.
 
Another_eYes: 首先谢谢!
如果是这样的话,我就对窗口
重画的机制不懂了!
它到底有没有重画?
wm_paint消息到底有没有响应?
 
当然有响应
不幸的是wm_paint是通过sendmessage发送的, 在消息处理完之前不返回调用者, 所以:
跟踪时:
断点->系统wm_paint->delphi IDE->delphi画编辑窗口->等待->单步->系统WM_PAINT->
被调试程序->被调试程序处理WM_PAINT消息->停于断点(第二个WM_PAINT消息里的)->.....
->死循环.
 
但是我好象看见书上写
用invaildRect(),updatewindow()
函数或其他某些
函数产生的wm_paint消息是直
接发送到窗口的,对吗?
它重化的时候为什么不用背景色刷新?
你说这个跟放大镜程序是一回事吗?
放大镜是如何实现平滑移动的呢?
 
1. 是的.
2. >>>它重化的时候为什么不用背景色刷新?
不懂什么意思.
3. 如果是显示整个desktop的放大镜都是在一个固定form里显示鼠标位置的放大图象
它没法去掉这个form.
如果是显示自己窗口里的放大图象那简单, 生成一个透明的TWinControl类控件(怎么产生透明
twincontrol我在其他问题里详细介绍过, 不多说了)就解决了.
 
谢谢eyes!xixi....
让我再研究研究!分数没问题!
xixi...
找找已答问题....
 
case AMessage of
wm_Destroy: begin
PostQuitMessage(0);
Exit;
end;
wm_Paint : begin
{ DC1:=begin
Paint(window,lpPaint);
PRgn:=CreateRoundRectRgn(10,10,100,100,10,10);
InvalidateRgn(window,PRgn,false);
UpdateWindow(window);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^问题出在这里。
EndPaint(window,lpPaint);}
end;

你在WM_PAINT消息的处理过程中通过UpdateWindow又引发了另外一个WM_PAINT,
所以你的应用程序不是死机,而是一直在拼命的处理WM_PAINT消息。
另外,UpdateWindow不是往消息队列里放消息,而是直接用SengMessage来调用
WndProc,可不就死循环了呗。
至于透明窗口,我不太懂你的意思,你说详细点看看。
 
George: 那一段我已经注释掉了,我是不知到怎么写好..
是这个意思:
我把WndClass.hbrBackground:=0;//HBrush(Color_Window);这样透明...
这样窗口的背景是透明的!
可是他只是窗口生成,或者是由最小化到最大化的时候才透明一下(显示出
窗口下面的图象),而我希望的是当我改变窗口大小,或者移动窗口时,他都能
透明!

谢谢!
 
我试过用SetWindowRgn的方法,把不透明的部分构造成Rgn, 刷新是没有问题的。。。
 
你把背景刷设为空只是在不画背景而已,若要真正的实现在移动时也透明恐怕你的
窗口扩展风格要设为WS_EX_TRANSPARENT,可以通过SetWindowLong(hWnd,
GWL_EXSTYLE, GetWindowLong(hWnd, GWL_EXSTYLE) or WS_EX_TRANSPARENT)
只有这样,窗口得到WM_PAINT消息时,它的下层窗口才完全绘制完成。
你再试试吧。不过我觉得是可以实现的。
抱歉,我现在活忙的紧,有问题咱们再讨论。
 
george, 怎么设都没用, 我都试过无数回了.
除非sleep.
另外, 为以后你少走弯路, 告诉你个窍门: 光设ws_es_transparent没用处, 还得设parent
window的style, 去掉ws_clipchildren才能取到背景图案, 不然windows会clip掉被这个
window遮住的部分不画, 即使你设了ws_ex_transparent, 也只能得到一个清空的框(第一次
调用例外).
而且不幸的是, form(除了mdi窗)没有parent.
另外: 我发觉redrawwindow和updatewindow时, desktop处理wm_paint好象是通过后台
进程(而且级别极低)来实现的, 所以发送给desktop window的wm_paint会马上返回, 这时桌面还什么都没变化呢, 不sleep根本无法得到正确的背景.
 
是不是进了死胡同?
把需要透明的部分从窗口的区域中排除出去,SetWindowRgn之后根本就不用操心
重画下面别的窗口里的东西或者桌面背景(也是桌面窗口里的东西):它们自己会画的呀!
 
pegasus 是不是写段程序,
我有点糊涂了!
xiexie!
 
zx呀,听eYes的吧,<<怎么设都没用>>呵呵。如果是peg的方法,那么什么消息都漏下去了,呵呵,
 

Similar threads

I
回复
0
查看
534
import
I
I
回复
0
查看
742
import
I
I
回复
0
查看
572
import
I
I
回复
0
查看
759
import
I
后退
顶部