不好意思,标题是为了让大仙们关注一下:同时也借助这个论坛的热度,希望能最快的得到解决方案。我先描述一下我在项目中遇到的这个问题的情况:
环境: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.frmprivate 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 PlugInDelegateprivate 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 subprivate 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

解决方案 »

  1.   

    感谢顶贴的兄弟姐妹们。
    我是初步找到原因了,就是只要上述代码在ToolBar不可见时,执行是成功的,但是没效果。
    现在重现此现象的条件是:
    有个Form上面有个ToolBar,然后你把上面的那个创建按钮的代码放在Form_Load里执行就看不到添加的按钮。如果是放在按钮里执行(Form已经显示出来了),就可以。继续等待大虾。
      

  2.   

    是不是发错区了,既不是C#,又不是.NET,怎么跑这里来问了?
      

  3.   

    在.net版未能找到解决方案,特移来此处寻求高人帮忙。有力出力,无力顶帖~~多谢各位XDJM来捧场。
      

  4.   

    Form_Load里面ToolBar还没真正加载,当然上面添加按钮没反应.
    可以在form_activate里面添加(定义一个变量作标识,已经添加了按钮就不再添加)
      

  5.   

    可以改在 Form_Activate 中调用,只要做个标志记录一下,只在第一次时调用。
      

  6.   

    改用Codejock.Xtreme.Suite.Pro.ActiveX ?
      

  7.   

    没有用,我在Form_Activate里发消息依然创建不成功,如果在此做标记,然后在timer里去搞,可能是可能,但是那结果是我无法预料的,不知道什么时候创建成功,如果一打开窗口看不到按钮,但是稍等一下,突然冒出好多个按钮,用户有点无法接收。看来这个ToolBar真是够难搞的,现在我准备放弃用API来增删改按钮了,还是用ToolBar自己的方法吧。这样只需要把按钮与后台元数据包对应起来就可以了。然后只需要截获WM_COMMAND消息来处理按钮点击事件就好了,目前已经实现了。现遗留问题:
    1、如果ToolBar上有下拉按钮,还没办法取得那个下拉按钮的句柄,所以也就没办法截获那个下拉后的菜单的点击消息,因此也就没办法向插件里抛事件。目前也只能重构到此程度了,看到vbAccelerator里的代码后,发现它的ToolBar全是自己重写的,那个下拉菜单也是自己创建的(CreatePopupMenu),然后在弹出时,进行HOOK,还是蛮麻烦的,所以放弃了那个方法。在此多谢各位的顶力帮助。
      

  8.   

    既然能用ToolBar自己的方法为什么还要用 API?
    多此一举!还以为你有特殊需求呢。