问题是这样的,我在vb中引用一个外部的ocx,在这个ocx中有2个外部程序,2个外部消息,我需要用sendmessage发送其中的一个外部消息,如何实现。总是提示我那个外部消息如DeleteData没有定义,我确实不知道这个消息的定义是什么,在帮助中没有提到。是不是sendmessage只能发送那些msdn中有的消息。急求!!

解决方案 »

  1.   

    sendmessage可以发送用户自定义的消息.
      

  2.   

    SendMessage, SendMessageBynum, SendMessageByString VB声明 
    Declare Function SendMessage& Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any)
    Declare Function SendMessageBynum& Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long)
    Declare Function SendMessageByString& Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As String) 
    说明 
    调用一个窗口的窗口函数,将一条消息发给那个窗口。除非消息处理完毕,否则该函数不会返回。SendMessageBynum, SendMessageByString是该函数的“类型安全”声明形式 
    返回值 
    Long,由具体的消息决定 
    参数表 
    参数 类型及说明 
    hwnd Long,要接收消息的那个窗口的句柄 
    wMsg Long,消息的标识符 
    wParam Long,具体取决于消息 
    lParam Any,具体取决于消息 
      

  3.   

    以下内容节选自《Visual Basic编程晋级:ActiveX控件》: 
        要发送消息,我们就需要使用API函数SendMessage。这个函数的定义如下: 
        Declare Function SendMessage Lib "user32" _ 
         Alias "SendMessageA" (ByVal hwnd As Long, _ 
         ByVal wMsg As Long, ByVal wParam As Long, _ 
         lParam As Any) As Long 
        这个函数有四个参数,它们的含义如下: 
        第一个参数hwnd是窗口句柄,是一个长整型数。Windows给每个控件一个编号,这个编号就称为窗口句柄。有了这个句柄,我们就可以告诉Windows我们要控制哪个控件,所以这个句柄在API调用中至关重要。Visual Basic的大多数控件都包括hwnd属性,如下拉框、TreeView等,窗体也有这个属性。但也有一些控件没有这个属性,如标签控件。没有这个属性就无法利用Windows API函数,但可以节省系统资源。 
        第二个参数是要传递的消息。API文档中包括了所有消息的含义和用法,而每个消息所定义的常数在Win32api.txt中有可以找到。使用SendMessage传递消息,大多是为了完成以下几个工作: 
        1、设置控件的一些选项,象我们要使用的CB_SETDROPPEDWIDTH的就属于这种情况。尽管Visual Basic的每个控件都提供了许多属性,但仍然有许多控件的选项没有包括在其中。而这些选项中的大多数都可以利用SendMessage进行设置。 
        2、获得控件的一些设置。同上一种情况相反,有时我们需要获得控件的一些设置,这相当于读取属性。例如,如果想知道一个下拉框的下拉部分的宽度是多少,就可以向控件发送CB_GETDROPPEDWIDTH消息。对于这种情况,SendMessage函数的返回值就是结果。 
        3、执行一定的操作。例如,我们要在下拉框中寻找是否"ABC"这个字符串。当然,我们可以编写一个循环,逐条比较看是否存在这样的字符串。如果使用API,我们只需要向下拉框发送CB_FINDSTRING消息,这条消息就会自动进行查找工作并返回结果。 
        4、模拟用户操作。我们有时希望模拟用户的操作,比如关闭其他应用程序的窗口。其实只要我们能知道那个窗口的句柄,我们就可以发送WM_CLOSE消息给那个窗口,窗口接受到这条消息就会关闭,如同用户关闭窗口一样。 
        API消息的妙用很多,我们这里只是介绍如何使用SendMessage来发送消息,更进一步的应用就留给读者继续探索了。 
        SendMessage还有两个参数wParam和lParam。每个消息都具有这两个参数,它们可能包括一些其他信息,其含义由具体的消息来决定的。比如,我们要调用的CB_SETDROPPEDWIDTH消息,其wParam 表示要设置下拉部分的宽度是多少,以象素为单位;而lParam参数没有使用,必须设置为0。 
        可能你已经注意到了,这里SendMessage中的lParam定义为Any类型。前面我们已经提到,指定 Any类型禁止Visual Basic进行类型检查,从而允许将任意数据类型传递给该过程。由于每条消息对参数的类型和传递方式的要求都不同:有的可能要求为Long型,有的可能要求为自定义类型;大多数要求按传值方式传递,但也有一些要求按传地址方式。为了满足各种要求,我们将这个参数定义为Any类型。比如,我们要传递一个Long型变量lData。如果消息要求传地址方式传递,可以使用: 
        SendMessage ……, lData 
        而如果要求传值方式传递,则使用 
        SendMessage ……, ByVal lData 
        如果传递常数,我们则需要使用类型后缀来指定常数的类型,比如"0&",表示Long型的常数0,如 
        SendMessage ……, ByVal 0& 
        我们也可以使用类型转换函数CLng将常数指定为Long型,如CLng(0)。 
      

  4.   

    http://www.cnblogs.com/huqingyu/archive/2004/09/08.aspx
      

  5.   

    sendmessage不是只能发送MSDN里的消息的啊.不知道你有没有发送过自定义的消息呢~~
    你说的问题应该是同一回事吧
      

  6.   

    看看,以前别人发的一个消息在Moduel中加入以下代码,
    Option ExplicitPrivate Const GWL_WNDPROC = -4
    Public Const GWL_USERDATA = (-21)Public Const WM_SIZE = &H5Public Const WM_USER = &H400Private Declare Function CallWindowProc Lib "user32" Alias _
      "CallWindowProcA" (ByVal lpPrevWndFunc As Long, _
       ByVal hwnd As Long, ByVal Msg As Long, _
       ByVal wParam As Long, ByVal lParam As Long) As Long
     
    Public Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" _
    (ByVal hwnd As Long, ByVal nIndex As Long) As LongPrivate Declare Function SetWindowLong Lib "user32" Alias _
      "SetWindowLongA" (ByVal hwnd As Long, _
       ByVal nIndex As Long, ByVal dwNewLong As Long) As LongPublic Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As LongPublic Function Hook(ByVal hwnd As Long) As Long   Dim pOld As Long
    ‘指定自定义的窗口过程
       pOld = SetWindowLong(hwnd, GWL_WNDPROC, _
           AddressOf WindowProc)                                    
    ‘保存原来默认的窗口过程指针
       SetWindowLong hwnd, GWL_USERDATA, pOld
       Hook = pOldEnd FunctionPublic Sub Unhook(ByVal hwnd As Long, ByVal lpWndProc As Long)   Dim temp As Long
       'Cease subclassing.
       temp = SetWindowLong(hwnd, GWL_WNDPROC, lpWndProc)End SubFunction WindowProc(ByVal hw As Long, ByVal uMsg As Long, _
       ByVal wParam As Long, ByVal lParam As Long) As Long  If uMsg = WM_SIZE Then
    ‘处理WM_SIZE消息
            MsgBox "SIZE"
        End If
    If uMsg = WM_USER + 1 Then
             MsgBox wParam
        End If
       Dim lpPrevWndProc As Long
                     ‘查询原来默认的窗口过程指针
      lpPrevWndProc = GetWindowLong(hw, GWL_USERDATA)‘调用原来的窗口过程
      WindowProc = CallWindowProc(lpPrevWndProc, hw, uMsg, _
               wParam, lParam)
    End Function在Form中加入以下代码:
    Dim wParam As Long
    Dim lParam As Long
    Dim lResult As LongPrivate Sub Command1_Click()
    wParam = 12345
    lResult = SendMessage(Me.hwnd, WM_USER + 1, wParam, lParam)
    End Sub
    Private Sub Form_Load()
       Me.Tag = Hook(Me.hwnd)
    End SubPrivate Sub Form_Unload(Cancel As Integer)
       Unhook Me.hwnd, Me.Tag
    End Sub
    在VB中用自定义过程捕获并处理消息的详细信息和例子请参考:
    Q170570 HOWTO: Build a Windows Message Handler with AddressOf in Visual
    http://support.microsoft.com/support/kb/articles/q170/5/70.asp
    Q168795 HOWTO: Hook Into a Window's Messages Using AddressOf
    http://support.microsoft.com/support/kb/articles/q168/7/95.asp
      

  7.   

    确切的说,我调用的是GetS.ocx,然后用GetS.ocx里面提供的DeleteData消息,该消息的参数是0,那么请大家给我一个完整的过程sendmessage调用DeleteData消息,从定义开始。谢谢!对于sendmessage我有一些了解,但不是非常的清楚。
      

  8.   

    自己定义消息
    Public Const WM_USER = &H400
    Public Const WM_MY_MESSAGE= WM_USER +1&
    然后使用
    Call SendMessage(lngHWnd, WM_MY_MESSAGE, bnull, vbnull)'lngHWnd窗口的句柄
    那个窗口就可以在 自定义的windowproc函数里可以接收消息了
      

  9.   

    请教,现在DeleteData这个消息是GetS.ocx中的消息,也可以这样定义吗?这样,程序是不是能完成这个消息的功能呢?
      

  10.   

    可以啊 不过DeleteData 消息要在发送和接收端都要定义 而且大于WM_USER,
      

  11.   

    我试了,发送消息没有出错,可是我要的结果没有出来,也就那个消息没有起作用,我想是不是因为我不知道DeleteData这个消息的值的原因,所以正确地消息实际上没有发送过去。另外请教一个问题,一个ocx的外部消息,是指这个ocx所发出的消息,还是它能接受到的消息。多谢!
      

  12.   

    不只为什么,我总感觉你的思路不对,既然封装成了ocx,为什么不把消息的发送也封装起来呢?不过在看到你的ocx文件以前我还不敢肯定这一点。所以,我要看看你的ocx文件,给个下载地址吧:)
      

  13.   

    找个ocx不是我自己做的,是我们的一个业务软件中带的,在它的说明里写了有DeleteData这样一个外部消息,并且给出了这个消息的参数,就一个,要么是0,要么大于0。所以我才有这样的问题:一个ocx的外部消息,是指这个ocx所发出的消息,还是它能接受到的消息。非常感谢,麻烦你们帮我好好的想想。