Library tutorials & articles

Enum Windows & SendMessage API

EnumWindows

EnumWindows enumerate (returns) handles of all the top-level windows. Now most of the times the enumeration, whether its of parent windows or child windows or fonts etc, is done with the help of a ‘callback’ function. You need not overwhelm yourself with the word ‘callback’, its not a big thing actually. It’s like this: the EnumWindows will pass the handles of all the top-level windows that it’ll find to the callback function which ‘you’ will write yourself. Its easy, in fact its declaration already is available to you in the API documentation in the MSDN library. Your program can have several callback functions, but how does EnumWindows know which callback function to pass the handles to? You manage it yourself by giving it the ‘address’ of the callback function that you want to use with EnumWindows, and you get the address of the function with the help of a especial operator called ‘AddressOf’ operator (it was first time introduced in VB5). Following is the declaration of EnumWindows as given in the API viewer:

Public Declare Function EnumWindows Lib "user32" (ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long

The parameter ‘lpEnumFunc’ requires the address of the function that you’ll will be using as a callback.

The parameter ‘lParam’ is an application-defined value. This value is of no use to EnumWindows and it is just there for you to pass any value you want to the callback function. Although it is of type long here but it can be of any type you want, you’ll have to change the type in the declaration likewise, like I wanted to pass a listview control to the callback so I changed the type to ‘Any”, this will be explained later on.

Now the callback function. It is not declared with the ‘Declare’ statement, you would write it like any other function but you’ll have to observe the number of arguments it can receive which is also given in the MSDN library. It’s normally defined as:

Public Function WndEnumProc(ByVal hwnd As Long, ByVal lParam As Long) As Long
End Sub

hwnd is the handle of the window that EnumWindow passes it.

lParam is the user-defined value, but because I was passing it a ListView control so I changed the lParam type as ‘ListView’ so that it could accept a ListView object.

Note: you must place the callback function in the ‘Module’ i.e. the *.bas file because it’s a condition of the AddressOf operator that the function whose address is passed should be located in the *Bas file.

Also AddressOf can only be used as argument of any function like:

x = somefunction(AddressOf anyuserdefinedfunction)

you cant write it as:

x = addressof(anyvariableoruserdefinedfunction) ‘ this is illegal

Once you’ve called the EnumWindows function and given it the address of the callback function, it will start passing the handles of all the windows that it’ll find. When the execution reaches inside the callback function you can do whatever you want with the passed on data but in the last line of the function you must ‘tell’ the EnumWindows whether it should continue passing the handles or not. If you want EnumWindows to keep on passing you the handles you return 1 else you return 0. In EnumerationX I wanted EnumWindows to pass me all the handles it found so I kept returning 1 until it stopped itself.

In EnumerationX, when inside the WndEnumProc (callback) I took the handle, got the caption of the window through GetWindowText and filled the listview control with the window names.

EnumChildWindows is exactly the same function as EnumWindows except that it enumerates child window handles. I hope that through the explanation of EnumWindows you’ll be easily able to understand the working of EnumChildWindows.

Comments

  1. 24 Feb 2009 at 06:29
    Hi all ! I am developing an application in Visual C# to retrieve data from textboxes, listboxes, statusbars,... etc of open windows in any system... Currently i am using winndows api **Sendmessage **to pass handle of the window and passing its parameter **message ** as WM_COPY (to copy data from textboxes, listboxes, statusbars,... etc ) but its value &H301 is not recognized... What shoulf i do to get the correct output ??? Can anyone help ??? Regards, Ayesha
  2. 27 Jul 2007 at 10:07
    Hi All,

    I wanna ask about the equivalent of SendKey if I will use SendMessage:

    Ex.

        If ctr2 <= length Then
            myKeys(ctr2) = Mid$(myString, ctr2, 1)
            SendKeys myKeys(ctr2)
            ctr2 = ctr2 + 1
        Else

    I tried converting SendKey with SendMessage but nothing happens:

    myHWnd is the handle I got from Finding the window. What I want to do is to send specific keys to the specified application (myKeys(ctr2)) as if I am using sendKeys.

    SendMessage myHWnd, WM_KEYDOWN, 0, myKeys(ctr2)


    It didn't send keys to notepad.


    I really cannot understand SendMessage and I really need your help guys... I am only a newbie in VB.

    Thank you,

    Gwapo



























  3. 13 Jul 2007 at 08:21
    you said you can't get selected text from html file..etc ,may be you havn't find the right handle of area which can be edit.
  4. 10 Jul 2007 at 00:06

    Hi,

    About this subject, I´m trying to define the size of an image captured from a generic camera.

    I'm using the SendMessage and SetWindowPos functions with the following instructions:

    To initialize the camera:

    Private Sub PreviewVideo(ByVal pbCtrl As PictureBox)

    On Error GoTo treaterror:

                               
            mHwnd = capCreateCaptureWindowA("Teste", WS_VISIBLE Or WS_CHILD, 0, 0, 100, 100, pbCtrl.hwnd, 0)
           
            If SendMessage(mHwnd, WM_CAP_DRIVER_CONNECT, 0, 0) Then
                 SendMessage mHwnd, WM_CAP_SET_SCALE, False, 0
                '---set the preview rate (ms)---
                SendMessage mHwnd, WM_CAP_SET_PREVIEWRATE, 30, 0
                '---start previewing the image---
                SendMessage mHwnd, WM_CAP_SET_PREVIEW, True, 0
                '---resize window to fit in PictureBox control---
                SetWindowPos mHwnd, HWND_BOTTOM, 0, 0, pbCtrl.ScaleWidth, pbCtrl.ScaleHeight, SWP_NOMOVE Or SWP_NOZORDER
               
                    
            Else
                '--error connecting to video source---
                MsgBox "Problema na conexão com a câmera. Contate o suporte!! - " & Err.Description
                DestroyWindow mHwnd
            End If
















            Exit Sub
           
    treaterror:

    MsgBox "Problema na conexão com a câmera. Contate suporte!!!" & Err.Description

       
    End Sub

    To capture the image:

    Private Sub cmdCapturar_Click()

    SendMessage mHwnd, GET_FRAME, 0, 0
    SendMessage mHwnd, COPY, 0, 0
    Picture1.Picture = Clipboard.GetData
    Clipboard.Clear
    'Timer1.Enabled = False



    End Sub

    Please note that I don't want just want to fit the image to the window. I need its real size to be the window's size. (What is happenning is that I see one image on the PictureBox passed as a parameter the sub PreviewVideo but the captured image is much larger than it.)

    Thank you in advance,

  5. 21 Jan 2006 at 17:15
    i'm doing something similar to this thread starter. below is my code:

    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick

           prevWindow = 0

           Call GetCursorPos(mousePT)
           X = mousePT.X
           Y = mousePT.Y
           Label2.Text = "(" & X & "," & Y & ")"
           hWnd = WindowFromPoint(X, Y)

           className = Space(255) ' Make room in the string to receive the information.
           retValue = GetClassName(hWnd, className, 255)

           windowText = Space(255)
           GetWindowText(hWnd, windowText, 255)

           Label1.Text = hWnd

       End Sub

    this is a function which will constantly called by timer, and i have 2 labels on my form which is label 1 and and label2
    you can see that i print the handle number (hWnd) using label1, but when i run the program no matter where i point the mouse to but the hwnd value is still the same, why?
  6. 09 Jun 2005 at 11:27

    Quote:
    [1]Posted by arshad on 29 Jun 2004 12:18 PM[/1]
    Hi Riaz,
    Could you plz explain me how did u fetch data from MS-Word.
    I can able to get typed text from notepad using sendmessage API.
    Same API Could not work for MS-word.
    Thanks,
    Arshad.
    Quote:
    [1]Posted by riyazfarz on 3 Sep 2003 02:33 AM[/1]
    Hi,


    Yes I could fetch data from MS- word, Notepad etc. But I am not able to fetch from HTML file. Any idea for getting from this.


    Anyway thanks for your valuable help.


    Regards


    Riaz




    I used SendMessage(hwnd, WM_COPY, 0, 0). And I meet the above problem, too!
    I cann't get selected text for HTML file/VC/PDF file/SourceInsight File......

  7. 13 Oct 2004 at 02:35
    hi, Have u got the solution?
    i m also looking for the same...
    Can you help me some how more ?
    I have developed a dictionary & now I want let user use it with a very simple way.
    I wish to have a word under mouse cursor from any other windows application. my program will search definition for that word & will show at mouse cursor when user press Ctrl key or in any other special window automatically.
    For the same I was searching for, I come across you. I want just any children of any window ( like..notepad, wordpad, word, or explorer or just any edit control.)
    Hopes u got my requirement. Simply I have a definition dictionary & want to synchronize it with text under mouse cursor.
    althogh u have given a nice idea that how to go for it but can u pls show it with a code pls.
    I 'll. be greatly thankful to you, if you can illustrate it with few sample source code (Visual Basic only).

    if u got it pls help me.
    Thanks & have a nice time.

    Sunil.

  8. 13 Oct 2004 at 02:28
    Hi there !
    how are u?

     Can you help me some how more ?
    I have developed a dictionary & now I want let user use it with a very simple way.
    I wish to have a word under mouse cursor from any other windows application. my program will search definition for that word & will show at mouse cursor when user press Ctrl key or in any other special window automatically.
    For the same I was searching for, I come across you. I want just any children of any window ( like..notepad, wordpad, word, or explorer or just any edit control.)
    Hopes u got my requirement. Simply I have a definition dictionary & want to synchronize it with text under mouse cursor.
    althogh u have given a nice idea that how to go for it but can u pls show it with a code pls.
    I 'll. be greatly thankful to you, if you can illustrate it with few sample source code (Visual Basic only).

    Thanks & have a nice time.
    Sunil.
  9. 29 Jun 2004 at 12:18

    Hi Riaz,
    Could you plz explain me how did u fetch data from MS-Word.
    I can able to get typed text from notepad using sendmessage API.
    Same API Could not work for MS-word.
    Thanks,
    Arshad.

    Quote:
    [1]Posted by riyazfarz on 3 Sep 2003 02:33 AM[/1]
    Hi,


    Yes I could fetch data from MS- word, Notepad etc. But I am not able to fetch from HTML file. Any idea for getting from this.


    Anyway thanks for your valuable help.


    Regards


    Riaz

  10. 03 Sep 2003 at 02:33

    Hi,


    Yes I could fetch data from MS- word, Notepad etc. But I am not able to fetch from HTML file. Any idea for getting from this.


    Anyway thanks for your valuable help.


    Regards


    Riaz

  11. 21 Aug 2003 at 15:58

    Quote:
    [1]Posted by koo9 on 11 Jul 2003 03:10 PM[/1]
    like the Gator client, it allow user the hold down a key e.g. ctrl and click on any text in any windows, it will pop up a definition for the clicked text, how do they do it? does it use the WM_GETTEXT as well?


    I was able to do that using the SENDMESSAGE, GETCURSORPOS and WINDOWFROMPOINT functions.
    Basicly what you need to do is first get the cursor's position using GETCURSORPOS which will return the x and y location. Pass those coordibates to WINDOWFROMPOINT and it will return the window handle in which the cursor is currently highlighting the text. Since you now have the correct handle of the window (this window can be anything...notepad...explorer...etc...) you then use the SENDMESSAGE function as such:
    SENDMESSAGE FoundWindow.hWnd, WM_COPY, 0, 0 where 'FoundWindow' is the handle returned by WINDOWFROMPOINT.


    NOTE: This method needs a constant loop to keep checking the mouse cursor position (using a timer control).
    This works when a text is highlighted and the mouse cursor is still above it. If you want to do this using the CTRL key you might have to resort to GETASYNCKEYSTATE also.


    If you succeed in developing a better code i'd be glad to see it

  12. 11 Jul 2003 at 15:10

    like the Gator client, it allow user the hold down a key e.g. ctrl and click on any text in any windows, it will pop up a definition for the clicked text, how do they do it? does it use the WM_GETTEXT as well?

  13. 14 Apr 2003 at 04:28

    I'm using this api to send a custom message between 2 VB exe's.  The called exe is subclassed to listen to the custom message.  In the calling exe, I'm trying to pass a string in the 4th parameter.  At this stage the 2nd exe is already running.  The api call keeps crashing the 2nd exe.  Can it be done across exe's or only within the same exe, thanks.

  14. 15 Mar 2002 at 18:02
    I have the following code:
    The PostMessage function works, while the SendMessage function does not..WHY???

    //*********************************
       PROCESS_INFORMATION* pi;
       pi = (PROCESS_INFORMATION*)malloc(sizeof(PROCESS_INFORMATION));
       STARTUPINFO si;
       si.cb=sizeof(si);
       si.lpReserved=NULL;
       si.lpDesktop=NULL;
       si.lpTitle=NULL,
       si.dwFlags=STARTF_FORCEONFEEDBACK;
       si.cbReserved2=0;
       si.lpReserved2=NULL;
       BOOL bres = CreateProcess(NULL, "calc.exe", NULL,NULL,NULL,
                                 CREATE_NEW_CONSOLE | NORMAL_PRIORITY_CLASS,
                                 NULL,NULL,&si,pi);
       if(!bres)
       {
           return;
       }

       HWND hWnd;
       EnumThreadWindows(pi->dwThreadId, EnumProc, (LPARAM)&hWnd);
       SetFocus(hWnd);
       //LRESULT lr1 = SendMessage(hWnd, WM_KEYDOWN, 38, 0);
       //LRESULT lr2 = SendMessage(hWnd, WM_KEYUP, 38, 1);
       
       BOOL bp = PostMessage(hWnd, 256, 53, 393217);
       LRESULT lr1 = SendMessage(hWnd, 256, 53, 393217);
    //*************************************************
  15. 01 Jan 1999 at 00:00

    This thread is for discussions of Enum Windows & SendMessage API.

Leave a comment

Sign in or Join us (it's free).

Muhammad Abubakar Nothing to say anything about me yet.

Related discussion

Related podcasts

  • Christian Beauclair

    14 mai 2008 (�mission #0074) ::.Christian Beauclair: Stratégies de migration VB6 vers .NET Nous discutons avec Christian Beauclair des stratégies de migration VB6 vers .NET. Entre autres, nous discutons comment utiliser le "VB 6 Code Advisor" et le "Interop Forms Toolkit" pour ajouter la puiss...

We'd love to hear what you think! Submit ideas or give us feedback