用SetParent重设父窗体后,如何触发事件

Alzzl 2006-10-10 01:13:02
我用setparent更改了一个按钮的父窗体,但是更改以后无法触发按钮的事件
用什么方法解决?
...全文
444 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
清晨曦月 2006-10-10
  • 打赏
  • 举报
回复
。。。。。。。。。。
触发事件?你直接点点试试就知道了。
happy_sea 2006-10-10
  • 打赏
  • 举报
回复
SetParent是一个API函数,它的作用是为一个物体指定一个新的父窗体。(父窗体严格来说应该是容器,我是这么理解的).也就是把一个物体转到另一个物体上去

Setparent 的用法相当简单

语法是:
Setparent 物体句柄,目标句柄

不过要想使它真正有实用价值却需要一定的知识及技巧.

比如你把一个按钮放到另一个窗体上(另一个窗体可以是其他程序中的):

setparent command1.hwnd,&hxxxxx'( 假设&hxxxxx是另一个窗体的句柄值)


那么你会发现,你点击那个放在桌面上的按钮将不会执行原本command_click事件中的任何代码了!

要解决的方法是多种多样的

假如你只是想让它执行代码,并不想进一步了解WIN的消息运作机制,那么我建议你把这个按钮放进一个容器,比如picturebox,或是farme,再把这个容器转到另一个窗体上去.而不是把按钮转到窗体上.那么这个按钮就会执行原本clic中的代码了.只要调整容器的大小与按钮大小一样,那么感觉外观上是看不出来有容器存在的.

假如你想了解WIN的消息运作机制,那么我建议你使用子类来解决这一问题.
在这得先说简单说明一下WIN的消息机制运作,简单的说就是"以事件为基础,以消息驱动"

其实WIN是不认事件的.所谓的"事件"只是一些开发环境为了简化开发者的代码编写量而把一大堆系列的消息封装而成的.作个形象的比喻:假如存在一个"吃饭"的事件.那么其中就应该包括"端碗"\"拿筷子"\"把饭挑进嘴里"\"放碗"\"放筷子"等几个消息.我们就会处理这一系列的消息而把它归结为一个事件的完成.

我先简单说明一下一个按钮单击事件发生时会发生哪些消息:(因为发生的消息太多,只说出重要的几条:)
首先,鼠标向按钮点下时,系统就向按钮发送一个鼠标左键点下的消息,同时再向它发送一条物体风格改变的消息(使按钮的状态为凹下).再发送一条重画物体的消息(改变原有的凸起外观,使按钮画成凹下的外观).这样我们就看到了按钮被鼠标左键点下时的样子。然后再发送鼠标左键抬起的消息,(中间可能会发生鼠标移动的消息,但是我们可以不管它),继续接着发送物体风格改变的消息(使按钮状态为凸起,也就是回复正常),再接着发送一个按钮重画的消息。到最后,按钮再向所在的容器发送一条命令消息作为点击事件的终结,即点击成功。(在其中鼠标被抬起的消息中,有一些消息带的参数是用以判断鼠标是否正处于按钮区域坐标内的。这个我们暂时也可以不必理会)

在上面的消息中,你可以随意截取一个消息作为判断按钮是否被点下,比如截下鼠标左键点下wm_lbuttondown消息,也可以截下wm_lbuttonup弹起消息,其中再用API来取得弹起时的鼠标坐标,就能知道它是否被点击了。

不过直接判断按钮在最后点击完毕时发送出去的那条消息却可以直接判断出按钮是否被点击!即wm_command消息
但这条消息因为不是系统发送给按钮的,而是由按钮发送给系统的,所以许多人会忽略,因为许多人都已经习惯于控制按钮只对按钮拦截消息,但因为子类只能拦截物体得到的消息而不能拦截物体发送的消息,所以这条wm_command消息用得并不是很多。

所以我们只需要对它的容器进行这条消息的拦截就能得知它是否被点击了!

如:setparent command1.hwnd,&hxxxxx'( 假设&hxxxxx是另一个窗体的句柄值)

那我们只需要对“&hxxxxx”进行消息拦截,当发现得到wm_command消息时,判断它的wprarm参数及lprarm参数,假如wprarm参数不为0,且lprarm为command1.hwnd时,那我们就知道,command1被点击了.通过判断lprarm还可以判断其他的按钮是否被点击!这样我们就能一次性放上多个按钮了,再对多个按钮进行判断是哪个被点击.



注意:按钮结束后发送的消息不是发送给它的窗体,而是发送给它的容器!
我曾见过一个高手因为不知道这一点而只对它的窗体进行这条消息的拦截,结果抱怨说老是拦不到而造成一个功能无法实现.
所以应该先判断这个按钮所处的容器.一般情况下,指定的新父窗体就是容器了.


还有,向物体的容器拦截一些命令消息如wm_command消息应用得很广泛.
比如说用API新添了一些菜单,需要让这些菜单执行操作,就需要拦截窗体的wm_syscmd(我一下也忘了这个还是wm_syscommand).再通过判断它后面的两个参数值就可以让它执行相应的操作了.因为菜单不可能放入PICTUREBOX之类的容器里,所以一般只截窗体的消息即可.

1,486

社区成员

发帖
与我相关
我的任务
社区描述
VB API
社区管理员
  • API
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧