Thread: Hung up on GetWindowText

  1. #1
    Registered User
    Join Date
    Jun 2008
    Posts
    161

    Hung up on GetWindowText

    I can't figure this one out. I get all the other module information as expected, but I can't get GetWindowText to give me the window title of each process. The code below just spits out "Notification Area" repeatedly. I tried using aProcesses[i] instead and got a bunch of the wrong window titles. I don't get it. I'm also curious how to determine the user running each process. I specifically want to know which ones are SYSTEM processes in order to exclude them from the list.

    Code:
    int ListProcesses(HWND hProcessList) {
        HANDLE hProcess;
        DWORD aProcesses[1024], cbNeeded, cProcesses;
        unsigned int i;
        char szProcessName[500];
        char szProcessPath[500];
        char szProcessID[20];
        char szProcessSize[20];
        char szProcessTitle[1024];
        PROCESS_MEMORY_COUNTERS szProcessMemory;
        SendMessage(hProcessList, LVM_DELETEALLITEMS, 0, 0);
        if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) )
            return 1;
    
        cProcesses = cbNeeded / 4;
    
        for ( i = 0; i < cProcesses; i++ ) {
            if( aProcesses[i] != 0 ) hProcess = OpenProcess( PROCESS_QUERY_INFORMATION|PROCESS_VM_READ, FALSE, aProcesses[i] );
            if (NULL != hProcess )
            {
                GetModuleBaseName( hProcess, NULL, szProcessName, 500 );
                GetModuleFileNameEx( hProcess, NULL, szProcessPath, 500 );
                memset(&szProcessMemory,0,sizeof(PROCESS_MEMORY_COUNTERS));
                szProcessMemory.cb = sizeof(PROCESS_MEMORY_COUNTERS);
                GetProcessMemoryInfo(hProcess, &szProcessMemory, sizeof(PROCESS_MEMORY_COUNTERS));
                sprintf(szProcessSize, "&#37;.2f", (float)szProcessMemory.WorkingSetSize / 1024 / 1024);
                szProcessTitle[0] = '\0';
                GetWindowText(hProcess, szProcessTitle, sizeof(szProcessTitle));
                sprintf(szProcessID, "%u", aProcesses[i]);
                ListViewAddRow(hProcessList, 5, szProcessName, szProcessTitle, szProcessID, szProcessSize, szProcessPath);
            }
            CloseHandle( hProcess );
        }
    	return 0;
    }
    Last edited by Viper187; 08-31-2008 at 01:16 PM.

  2. #2
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    Check the return of GetWindowText (the length of the text returned).

    I don't think GetWindowText works with process HANDLEs (even though a HANDLE is the same as a HWND).
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

  3. #3
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Indeed, see: http://msdn.microsoft.com/en-us/libr...20(VS.85).aspx

    Edit: To expand: A HANDLE or HWND may be the same TYPE OF DATA, but they refer to different things - the simplification made by the API designers to make them all void pointers is only there to avoid some of the API functions that take generic handles from having to use casts to form the same type of handle for all types.

    For certain, a HWND will not be the same value (or point to the same address) as a process HANDLE. The underlying data will be different too.

    --
    Mats
    Last edited by matsp; 09-02-2008 at 03:25 AM.
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  4. #4
    Registered User
    Join Date
    Jun 2008
    Posts
    161
    ...so how do I get an HWND from this instead of the HANDLE?

  5. #5
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Look up EnumWindows (to enumerate all windows) and GetWindowTreadProcessId() (to get identifier of thread or process that created a given window).

  6. #6
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by Viper187 View Post
    ...so how do I get an HWND from this instead of the HANDLE?
    If you have glas of water and salt inside, that's like asking - how can I get the handle of salt when I have the handle for the water?
    In other words, WHICH salt particle do you refer to?

    A process can have MANY windows. You need to choose one!
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  7. #7
    Registered User
    Join Date
    Jun 2008
    Posts
    161
    Quote Originally Posted by grumpy View Post
    Look up EnumWindows (to enumerate all windows) and GetWindowTreadProcessId() (to get identifier of thread or process that created a given window).
    Can't I do this somehow with EnumProcesses? I can't find any decent examples of EnumWindows/EnumWindowsProc that just list them all. Do you simply check if the HWND != NULL in order to determine when to return TRUE/FALSE or what?

  8. #8
    Banned master5001's Avatar
    Join Date
    Aug 2001
    Location
    Visalia, CA, USA
    Posts
    3,685
    Its not the best way... I have had EnumProcesses() attempt to do stuff with processes other than mine for whatever reason. MSDN at one point had a good example of the EnumWindows/EnumWindowsProc method of doing this. In my experience its the only accurate way to accomplish the task you are attempting.

  9. #9
    Registered User
    Join Date
    Jun 2008
    Posts
    161
    Quote Originally Posted by master5001 View Post
    Its not the best way... I have had EnumProcesses() attempt to do stuff with processes other than mine for whatever reason. MSDN at one point had a good example of the EnumWindows/EnumWindowsProc method of doing this. In my experience its the only accurate way to accomplish the task you are attempting.
    Well, I'm willing to try it the other way, but the only example I've seen of EnumWindows/EnumWindowsProc ends the EnumWindowsProc when it finds a specific process by window name. I need to know how to stop it after it grabs them all to make a complete list. Or does it just stop on its own after the last HWND?

  10. #10
    Banned master5001's Avatar
    Join Date
    Aug 2001
    Location
    Visalia, CA, USA
    Posts
    3,685
    Your EnumWindowsProc() is a callback function defined by you. You return TRUE until you get the handle you were seeking and FALSE to stop the enumeration cycle. You will only need to call EnumWindows() in order to get the window handle. You shouldn't need to be calling it frequently since you can always store the value of the handle in a global variable or something.

    Example:
    Code:
    BOOL CALLBACK MyWindowsProc(HWND hwnd, LPARAM lParam)
    {
        TCHAR buffer[MAX_PATH];
    
        GetWindowModuleFileName(hwnd, buffer, MAX_PATH);
    
        if(CompareString(LOCALE_USER_DEFAULT, NORM_IGNORECASE, (LPTSTR)lParam, -1, buffer, -1) == CSTR_EQUAL))
        {
            myGlobalHwnd = hwnd;
            return FALSE;
        }
    
        return TRUE;
    }
    
    /* elsewhere in your code... */
    EnumWindows(MyWindowsProc, (LPARAM)TEXT("program.exe"));
    I know that is the worst example in the world and I appologize... I just hope it gets you started.

  11. #11
    Registered User
    Join Date
    Jun 2008
    Posts
    161
    That's another example of exactly what I don't get. I want to print a list of ALL windows running, NOT find a specific one. I don't get how to test if the callback has run out of handles or if it just stops on it's own. I'd rather not cause an infinite loop to find out I'm wrong.

  12. #12
    Banned master5001's Avatar
    Join Date
    Aug 2001
    Location
    Visalia, CA, USA
    Posts
    3,685
    There won't be any sort of infinite loop here, bud. It will go through every handle until all have been enumerated. Its kind of an either/or thing on this function. Either it runs out of windows to enumerate, or you tell it to stop enumerating them.

  13. #13
    Registered User
    Join Date
    Jun 2008
    Posts
    161
    Quote Originally Posted by master5001 View Post
    There won't be any sort of infinite loop here, bud. It will go through every handle until all have been enumerated. Its kind of an either/or thing on this function. Either it runs out of windows to enumerate, or you tell it to stop enumerating them.
    Thanks. That's good, but I'm still not getting the result I want. I think I liked EnumProcesses better. There was less junk on the list. Here's my problem. I want process IDs and window titles for ONLY the main/parent window of each process. (i.e, only listing each process once) How to I determine what I'm getting when I EnumWindows? Maybe I'll just stick with EnumProcesses and list file names if this is gonna be that much of a pain.

  14. #14
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by Viper187 View Post
    Maybe I'll just stick with EnumProcesses and list file names if this is gonna be that much of a pain.
    That's what we're telling you - a process can hold MANY windows. How can the API determine WHICH window among them all you mean when you toss it a process handle? It's impossible to do that.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  15. #15
    Banned master5001's Avatar
    Join Date
    Aug 2001
    Location
    Visalia, CA, USA
    Posts
    3,685
    I didn't know you were wanting only root level windows. You can always query a handle to see if its a parent or child. You sound like your code was on track prior to the question. Where did you go wrong exactly?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. GetWindowText() not working with Vista???
    By Abda92 in forum Windows Programming
    Replies: 10
    Last Post: 04-07-2008, 01:29 PM
  2. GetwindowText problem
    By spanker in forum Windows Programming
    Replies: 4
    Last Post: 03-27-2008, 10:25 AM
  3. GetWindowText doesn't return the text
    By Rune Hunter in forum Windows Programming
    Replies: 16
    Last Post: 09-23-2005, 04:49 PM
  4. GetWindowText -> string?
    By XSquared in forum Windows Programming
    Replies: 3
    Last Post: 08-27-2003, 03:58 PM
  5. Using GetWindowText
    By ColdFire in forum Windows Programming
    Replies: 9
    Last Post: 05-26-2002, 10:24 PM