Results 1 to 17 of 17

Thread: SendMessage

  1. #1

    Thread Starter
    Lively Member
    Join Date
    Jun 2002
    Posts
    79

    SendMessage

    I need to send a windows message and I think the only way to do it is using the API function SendMessage (or not?).
    Does anyone have a simple example how to use it?

    Thx

  2. #2
    PowerPoster
    Join Date
    Aug 2000
    Location
    India
    Posts
    2,288
    I think it wold be more helpfuls if you could specify the exact message that you need to send:
    his is an example anyhow. If you need to send it to another application, you will have to get the particular window handle.

    VB Code:
    1. 'This project needs a ListBox, named List1 and a TextBox, named Text1
    2. Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Integer, ByVal lParam As Any) As Long
    3. Const LB_FINDSTRING = &H18F
    4. Private Sub Form_Load()
    5.     'KPD-Team 1998
    6.     'URL: [url]http://www.allapi.net/[/url]
    7.     'E-Mail: [email]KPDTeam@Allapi.net[/email]
    8.     'Add some items to the listbox
    9.     With List1
    10.         .AddItem "Computer"
    11.         .AddItem "Screen"
    12.         .AddItem "Modem"
    13.         .AddItem "Printer"
    14.         .AddItem "Scanner"
    15.         .AddItem "Sound Blaster"
    16.         .AddItem "Keyboard"
    17.         .AddItem "CD-Rom"
    18.         .AddItem "Mouse"
    19.     End With
    20. End Sub
    21. Private Sub Text1_Change()
    22.     'Retrieve the item's listindex
    23.     List1.ListIndex = SendMessage(List1.hwnd, LB_FINDSTRING, -1, ByVal CStr(Text1.Text))
    24. End Sub

  3. #3
    Frenzied Member
    Join Date
    Jul 2002
    Posts
    1,370
    You can also use PostMessage.

    SendMessage puts your message at the front of the message queue, PostMessage puts your message at the end of the queue.
    Code:
    'This project needs a ListBox, named List1 and a TextBox, named Text1
    Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Integer, ByVal lParam As Any) As Long
    Const LB_FINDSTRING = &H18F
    Private Sub Form_Load()
        'KPD-Team 1998
        'URL: http://www.allapi.net/
        'E-Mail: KPDTeam@Allapi.net
        'Add some items to the listbox
        With List1
            .AddItem "Computer"
            .AddItem "Screen"
            .AddItem "Modem"
            .AddItem "Printer"
            .AddItem "Scanner"
            .AddItem "Sound Blaster"
            .AddItem "Keyboard"
            .AddItem "CD-Rom"
            .AddItem "Mouse"
        End With
    End Sub
    Private Sub Text1_Change()
        'Retrieve the item's listindex
        List1.ListIndex = SendMessage(List1.hwnd, LB_FINDSTRING, -1, ByVal CStr(Text1.Text))
    End Sub

  4. #4

    Thread Starter
    Lively Member
    Join Date
    Jun 2002
    Posts
    79
    Thanks for the examples. But I am not really sure if they are what I need. Maybe I can explain my problem?

    At the moment I am developing an EXE using VB.NET. This EXE then is called by another program written in COOL:Plex. If something specific happens I need to "send a windows message with number 10001" (that's what the collegue who's doing the COOL:Plex told me) because then the view of the COOL:Plex program should be refreshed.

    What can or must I do???

    Thanks a lot.

  5. #5
    PowerPoster
    Join Date
    Aug 2000
    Location
    India
    Posts
    2,288
    I am sorry, but I can't help you out wiht .Net code, but in VB6 this is approximately how I would have done it:
    VB Code:
    1. Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Integer, ByVal lParam As Any) As Long
    2. Private Const My_Message as Long= 10001
    3.  
    4.  
    5.    SendMessage App_Hwnd, My_Message, 0&,0&

    Where App_Hwnd is the handle to your COOL:Plex Application

  6. #6
    PowerPoster
    Join Date
    Aug 2000
    Location
    India
    Posts
    2,288
    Originally posted by jim mcnamara
    You can also use PostMessage.

    SendMessage puts your message at the front of the message queue, PostMessage puts your message at the end of the queue.
    Jim, PostMessage doesn't seem to work when used for sending cross application messages.

  7. #7

    Thread Starter
    Lively Member
    Join Date
    Jun 2002
    Posts
    79
    Today seems to be a neverending API story.

    I just got my next problem: how to find the handle.

    I tried an example in VB6 and it did what I wanted to:

    Code:
    'Add this code to a form
    Private Sub Form_Load()
        'KPD-Team 2000
        'URL: http://www.allapi.net/
        'E-Mail: KPDTeam@Allapi.net
        'Set the form's graphics mode to persistent
        Me.AutoRedraw = True
        'call the Enumwindows-function
        EnumWindows AddressOf EnumWindowsProc, ByVal 0&
    End Sub
    'Add this code to a module
    Declare Function EnumWindows Lib "user32" (ByVal lpEnumFunc As Long, ByVal lParam As Long) As Boolean
    Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
    Declare Function GetWindowTextLength Lib "user32" Alias "GetWindowTextLengthA" (ByVal hwnd As Long) As Long
    Public Function EnumWindowsProc(ByVal hwnd As Long, ByVal lParam As Long) As Boolean
        Dim sSave As String, Ret As Long
        Ret = GetWindowTextLength(hwnd)
        sSave = Space(Ret)
        GetWindowText hwnd, sSave, Ret + 1
        Form1.Print Str$(hwnd) + " " + sSave
        'continue enumeration
        EnumWindowsProc = True
    End Function
    Then I tried to convert it to VB .NET and ... I'm going mad. What must the code look like instead of
    Code:
    EnumWindows AddressOf EnumWindowsProc, ByVal 0&
    The error is:
    'AddressOf' expression cannot be converted to 'Long' because 'Long' is not a delegate type.

    Maybe there is another solution, too. I only know the beginning of the title of the application I want to send the message to.

  8. #8
    Frenzied Member
    Join Date
    Jul 2002
    Posts
    1,370
    use EnumWindows and EnumChildWindows if the window you need is a child window.

    You found allapi.net, so you do not need an example.

  9. #9
    Frenzied Member
    Join Date
    Jul 2002
    Posts
    1,370
    Oh sorry - didn't see that red line 'till too late.

    Try posting in the VB.NET forum - in .NET all of the API resides as class methods and properties. Sometimes 8-10 api calls are embedded in a handy wrapper.

  10. #10

    Thread Starter
    Lively Member
    Join Date
    Jun 2002
    Posts
    79
    Thanks a lot.....
    I think I could just send my message :-)

    Though the COOL:Plex application seemed not to notice my message I think that's at least a beginning and maybe the error now is in COOL:Plex?!

  11. #11
    old fart Frans C's Avatar
    Join Date
    Oct 1999
    Location
    the Netherlands
    Posts
    2,926
    You could use Spy++ to find out if the message did arrive as espected.

  12. #12

    Thread Starter
    Lively Member
    Join Date
    Jun 2002
    Posts
    79
    Thank you, I will try it even though I did not work with SPY++ before....

  13. #13

    Thread Starter
    Lively Member
    Join Date
    Jun 2002
    Posts
    79
    Frans, can you tell me what options must be selected to find out if my message did arrive? As mentioned, I never worked with SPY++ before and using "Select All" in the message view seems to be an overhead.

  14. #14
    old fart Frans C's Avatar
    Join Date
    Oct 1999
    Location
    the Netherlands
    Posts
    2,926
    Because you want to check for message 10001 (&H2711) and messages between &H0400 and &H7FFF are considered user defined messages, Spy++ should show you the message if you select WM_USER. I haven't tested it though.

    Edit: Just tested it, it seems to work.

  15. #15

    Thread Starter
    Lively Member
    Join Date
    Jun 2002
    Posts
    79
    Thank you but still I'm not really sure what to do. This is what I did.

    I have a window (form of the .NET program, let's name it document-form) which itself calls a new form (let's name it info-form) and when this is closed (and something else is done like writing something into a database) my message should be sent. The call of the API function PostMessage is in the code of the documents-form.

    As you already know that documents-form is called by that COOL:Plex program (it's not so easy in fact COOL:Plex calls an EXE which starts word and an starts my AddIn (I developed in VB.NET). The documents-form belongs to my AddIn.

    Nevertheless...
    I think the window opened by COOL:Plex must receive my message (10001). In spy++ I can't see anything. Then I thought I can have a look at the sending form just to look if there is maybe an error but there I can't see my message being sent, either.

    I selected the documents-form window ("Find window") to see any message. Maybe that's already false?

    I'am very irritated......

  16. #16
    old fart Frans C's Avatar
    Join Date
    Oct 1999
    Location
    the Netherlands
    Posts
    2,926
    After you start Spy++, select the window you send the message to (the window in the Cool:Plex application). You can use find window (the binoculars button) to select the correct window. Spy++ shows you the window handle (in hex) so if you debug your code, you can check if you send the message to the correct window handle.
    In Spy++ right click the selected window (after you used find to find it, and pressed OK) and choose Messages in the context menu. Press the Logging options button, clear all messages on the messages tab, and check the WM_USER checkbox. Press OK, and now do whatever you have to do to make your application send the message.
    If all is well, you should see the message coming by in Spy++.

  17. #17

    Thread Starter
    Lively Member
    Join Date
    Jun 2002
    Posts
    79
    I'm sorry but it's me again....

    I did everything just like you said. I debugged my code and the handle I post my message to is identical to the handle shown in spy. The only difference is that in my code it is decimal and in spy it's hex. But still I can't see my message coming to the COOL:Plex application.

    What can it be???

    Here's my code:

    Code:
    Dim twnd As Integer
    Const IBSMSG = &H2711
    
    Win32API.EnumWindows(New Win32API.EnumWindowsCallback(AddressOf EnumWindowsProc), 0)
    
    twnd = Win32API.FindWindow(vbNullString, strAppTitle)
    Win32API.PostMessage(CLng(twnd), IBSMSG, 0L, 0L)
    and

    Code:
    Public strAppTitle As String
    Const STRING_BUFFER_LENGTH As Integer = 255
    Public Function EnumWindowsProc(ByVal hwnd As Integer, ByVal lParam As Integer) As Boolean
            Dim windowText As New StringBuilder(STRING_BUFFER_LENGTH)
            Dim className As New StringBuilder(STRING_BUFFER_LENGTH)
    
            ' Get the Window Caption and Class Name.  Notice that the definition of Win32API
            ' functions in the Win32API class are declared differently than in VB6.  All Longs
            ' have been replaced with Integers, and Strings by StringBuilders.
            Win32API.GetWindowText(hwnd, windowText, STRING_BUFFER_LENGTH)
    
            If windowText.ToString.StartsWith("Digitale") Then
                strAppTitle = windowText.ToString
            End If
    
            Return True
    End Function
    Do you think the error can be somewhere in the COOL:Plex application? My collegue mentioned that at the moment (where the part I am developing in .NET is in COOL:Plex, too) the message seems not to come, either.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width