竟然给这个问题难住了……

yulinlover 2010-01-19 01:54:25
不好意思,标题是为了让大仙们关注一下:同时也借助这个论坛的热度,希望能最快的得到解决方案。

我先描述一下我在项目中遇到的这个问题的情况:
环境:windows 2003+VB6.0+SQL Server 2005.
项目产品结构是这样的,程序启动后有个主窗体,然后可以通过点击各种菜单在弹出各个子窗体(说穿了就是MS的word那样的东西,新建就会弹出一个非模态的窗体,这个窗体上的菜单是用MenuEditor+ToolBar做的,现在我们看来他是贼落后的架构,因为上述组件基本只能在design阶段来添加好各类菜单,不利于在插件里操作。)

我现在的任务就是要重构这个结构,使得在插件里可以动态创建菜单和ToolBar的按钮。菜单的重构用一堆API结合subclass子类化技术已经搞定了,现在在搞ToolBar的过程中出现问题了。具体代码如下:


Dim lRetCode As Long
Dim tButton(0) As TBBUTTON
Dim bytCaption() As Byte
Dim strCaption As String
Dim lButtonCount As Long

Dim oToolBar As MSComctlLib.ToolBar

'取得form窗体上的ToolBar控件实例
Set oToolBar = GetFormToolBar(Me)

'ToolBarMsgHwnd函数就是一个获取ToolBar真正的窗体句柄(就是一个FindWindow语句)
lButtonCount = SendMessage(ToolBarMsgHwnd(oToolBar), TB_BUTTONCOUNT, 0, 0)

With tButton(0)
.dwData = 0
.fsState = Enu_ToolButtonStateConst.TBSTATE_ENABLED
.fsStyle = Enu_ToolButtonStyleConst.BTNS_BUTTON
.idCommand = 10 ^ 3 + lButtonCount
bytCaption = "Button" & lButtonCount
strCaption = "Button" & lButtonCount
'这句有时有问题。
.iString = StrPtr(StrConv(strCaption, vbFromUnicode))
End With
'WM_USER+20=TB_ADDBUTTONS 添加一个按钮
lRetCode = SendMessage(ToolBarMsgHwnd(oToolBar), WM_USER + 20, 1, tButton(0))





1、当ToolBar在Standard Exe工程里的时候,上面代码老正常了,没有问题!生成的按钮的文本也是“Button”+数字的形式
2、当ToolBar在ActiveX dll工程里的时候,就不正常了,按钮也能生成,但是其文本变成了这样的形式:36639386#1044C,不知道为啥?
3、当ToolBar传递到另外一个ActiveX DLL工程里的一个类里,然后这个类再把ToolBar传递到另外一个类,就会出现上面那句SendMessage的返回值为1(也就是消息发送成功了),但是ToolBar上却并没有增加按钮。

上面罗罗嗦嗦的可能并不一定描述清楚了问题:下面用自然语言结构给大家描述一下:

'/* MainForm.frm

private sub command1_Click(...)
dim frmChild as new ChildForm
frmchild.show vbmodaless
end sub


'/* ChildForm.frm
private withevents m_oSubClassObject as TlSubClass.CSubClass
private objPlugInDelegate as PlugInDelegate

private sub ChildForm_Load(...)
set m_oSubClassObject =new TLSubClass.CSubClass
'/* 把本窗体传进去进行子类化,并且对当前Form上的菜单及按钮进行元数据建立
m_oSubClassObject.HostForm=me

'/* 初始化插件代理
set objPlugInDelegate=CreateObject....

'/* 这里会创建一个插件实例
set objPlugIn=CreateObject("PlugInList.Item1")
objPlugIn.show objPlugInDelegate
end sub

private sub m_oSubClassObject_MenuBarClick(tool as string,bCancel as boolean)
objPlugInDelegate.FireMenuBarClick tool,bCancel
end sub

'/* TlSubClass.CSubClass
private m_oHostForm as object
public property Let HostForm(frmParent as object)
set m_oHostForm=frmParent
'/* 子类化的代码及菜单按钮的元数据建立代码,这里就省略了。
end property


情况就是这样的,希望有人能帮上忙~~
而且个人感觉这个在不同情况下执行成功,但是结果却不一样,到底是MS问题了,还是我使用API的问题呢?希望大仙们解释一下~3ks
...全文
245 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
Tiger_Zhao 2010-01-25
  • 打赏
  • 举报
回复
既然能用ToolBar自己的方法为什么还要用 API?
多此一举!还以为你有特殊需求呢。
yulinlover 2010-01-24
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 tiger_zhao 的回复:]
可以改在 Form_Activate 中调用,只要做个标志记录一下,只在第一次时调用。
[/Quote]
没有用,我在Form_Activate里发消息依然创建不成功,如果在此做标记,然后在timer里去搞,可能是可能,但是那结果是我无法预料的,不知道什么时候创建成功,如果一打开窗口看不到按钮,但是稍等一下,突然冒出好多个按钮,用户有点无法接收。看来这个ToolBar真是够难搞的,现在我准备放弃用API来增删改按钮了,还是用ToolBar自己的方法吧。这样只需要把按钮与后台元数据包对应起来就可以了。然后只需要截获WM_COMMAND消息来处理按钮点击事件就好了,目前已经实现了。现遗留问题:
1、如果ToolBar上有下拉按钮,还没办法取得那个下拉按钮的句柄,所以也就没办法截获那个下拉后的菜单的点击消息,因此也就没办法向插件里抛事件。

目前也只能重构到此程度了,看到vbAccelerator里的代码后,发现它的ToolBar全是自己重写的,那个下拉菜单也是自己创建的(CreatePopupMenu),然后在弹出时,进行HOOK,还是蛮麻烦的,所以放弃了那个方法。在此多谢各位的顶力帮助。
leftxp 2010-01-24
  • 打赏
  • 举报
回复
帮顶。
舉杯邀明月 2010-01-20
  • 打赏
  • 举报
回复
友情顶贴………………
Tiger_Zhao 2010-01-20
  • 打赏
  • 举报
回复
可以改在 Form_Activate 中调用,只要做个标志记录一下,只在第一次时调用。
stayor 2010-01-20
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 wiki14 的回复:]
帮顶~
[/Quote]
继续帮顶。
king06 2010-01-20
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 yulinlover 的回复:]
感谢顶贴的兄弟姐妹们。
我是初步找到原因了,就是只要上述代码在ToolBar不可见时,执行是成功的,但是没效果。
现在重现此现象的条件是:
有个Form上面有个ToolBar,然后你把上面的那个创建按钮的代码放在Form_Load里执行就看不到添加的按钮。如果是放在按钮里执行(Form已经显示出来了),就可以。

继续等待大虾。
[/Quote]
Form_Load里面ToolBar还没真正加载,当然上面添加按钮没反应.
可以在form_activate里面添加(定义一个变量作标识,已经添加了按钮就不再添加)
guyehanxinlei 2010-01-20
  • 打赏
  • 举报
回复
可以尝试将菜单项存储在数据库的表中,窗体加载时从数据库中读取绑定到某些控件上来实现.
赵4老师 2010-01-20
  • 打赏
  • 举报
回复
改用Codejock.Xtreme.Suite.Pro.ActiveX ?
嗷嗷叫的老马 2010-01-19
  • 打赏
  • 举报
回复
帮顶一下

猜测:

有些消息需要窗体完全建立后再发送才是有效的,因此在窗体未完全创建完成前,有可能消息循环收到了消息并处理了(SendMessage=1),却因为有些条件未达成而无法完成想要的效果.

具体细节需要分析才能得到确定的结论,并尝试相应的解决方案.
liguicd 2010-01-19
  • 打赏
  • 举报
回复
只负责帮顶
yulinlover 2010-01-19
  • 打赏
  • 举报
回复
在.net版未能找到解决方案,特移来此处寻求高人帮忙。

有力出力,无力顶帖~~多谢各位XDJM来捧场。
yulinlover 2010-01-19
  • 打赏
  • 举报
回复
这不是看到此版面热情吗?所以就发到这里了。
我经常活动的版面也就是这了。所以就发到这里了。
看来我的转移一下了。
qldsrx 2010-01-19
  • 打赏
  • 举报
回复
是不是发错区了,既不是C#,又不是.NET,怎么跑这里来问了?
yulinlover 2010-01-19
  • 打赏
  • 举报
回复
感谢顶贴的兄弟姐妹们。
我是初步找到原因了,就是只要上述代码在ToolBar不可见时,执行是成功的,但是没效果。
现在重现此现象的条件是:
有个Form上面有个ToolBar,然后你把上面的那个创建按钮的代码放在Form_Load里执行就看不到添加的按钮。如果是放在按钮里执行(Form已经显示出来了),就可以。

继续等待大虾。
kkkkkkmn 2010-01-19
  • 打赏
  • 举报
回复
菜鸟 帮你顶一下
希望你解决问题
liuyu520hong 2010-01-19
  • 打赏
  • 举报
回复
不懂VB,看不明白.
wen1512 2010-01-19
  • 打赏
  • 举报
回复
没看明白
tzs2304 2010-01-19
  • 打赏
  • 举报
回复
up
yulinlover 2010-01-19
  • 打赏
  • 举报
回复
有星星哥帮顶了,估计能很快解决,我先回办公室了,在去想象其他办法,晚上回家上来看下结果。大家努力啊。不懂的帮顶也行啊。呵呵。
加载更多回复(1)

1,486

社区成员

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

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