Geting "hwnds" without FindWindow

This is a discussion on Geting "hwnds" without FindWindow within the Windows Programming forums, part of the Platform Specific Boards category; I'm about to start my version of taskmanager and I would like to know how the real taskmanager finds the ...

  1. #1
    the magic penguim
    Join Date
    Jul 2005
    Posts
    91

    Geting "hwnds" without FindWindow

    I'm about to start my version of taskmanager and I would like to know how the real taskmanager finds the files/proccesses, I'm pretty sure it dosen't use FindWindow but how... Also MSDN b*tches a lot about the TerminateProcess function saying that I shouldn't use it because it dosen't let the program know it's being closed and bla bla bla... Is there any real problem?

  2. #2
    Skunkmeister Stoned_Coder's Avatar
    Join Date
    Aug 2001
    Posts
    2,572
    TerminateProcess is a last resort, using it simply says I cant kill this proggy in any other way. The process terminated has no clue that its about to die and doesnt get any chance to flush caches to disk or anything like that. This can be a real problem.
    As for taskmanager I suspect it uses EnumProcesses or maybe the Process32First and Process32Next toolhelp api.
    Free the weed!! Class B to class C is not good enough!!
    And the FAQ is here :- http://faq.cprogramming.com/cgi-bin/smartfaq.cgi

  3. #3
    the magic penguim
    Join Date
    Jul 2005
    Posts
    91
    Ok, so far I have managed to list the processes with Process32First and Process32Next and add each one to a listbox with it's PID asigned to it. But I just discovered that I know jacks**t about listboxes, first I set a timer to update the list every second but instead of updating it, it just adds more processes to the end of the list. I also would like to know how do I add those "tabs" to a listbox, and finally how do I asign more than one value to a listbox's item.

    code:

    taskmgr.c
    Code:
    #define WIN32_LEAN_AND_MEAN
    #include <windows.h>
    #include <tlhelp32.h>
    #include "resource.h"
    
    BOOL CALLBACK DlgProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
    {
        switch(Message)
        {
            case WM_INITDIALOG:
                SetTimer(hwnd, TIMER1, 1000, (TIMERPROC) NULL);
    	break;
            case WM_TIMER:
            {
                HANDLE hProcessSnap;
                PROCESSENTRY32 pe32;
    
                hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
                if (hProcessSnap == INVALID_HANDLE_VALUE)
                {
                    KillTimer(hwnd, TIMER1);
                    MessageBox(hwnd, "Dam CreateToolhelp32Snapshot!", "Error",
                               MB_OK | MB_ICONEXCLAMATION);
                }
                
                pe32.dwSize = sizeof(PROCESSENTRY32);
    
                if (!Process32First(hProcessSnap, &pe32))
                {
                    KillTimer(hwnd, TIMER1);
                    CloseHandle(hProcessSnap);
                    MessageBox(hwnd, "Dam Process32First!", "Error", 
                               MB_OK | MB_ICONEXCLAMATION);
                }
    
                do
                {
                    int index = SendDlgItemMessage(hwnd, IDC_LIST, LB_ADDSTRING, 
                                                   0, (LPARAM)pe32.szExeFile);
                    SendDlgItemMessage(hwnd, IDC_LIST, LB_SETITEMDATA,
                                      (WPARAM)index, (LPARAM)pe32.th32ProcessID);
                } while(Process32Next(hProcessSnap, &pe32));
                
                CloseHandle(hProcessSnap);
            }
            break;
            case WM_CLOSE:
                KillTimer(hwnd, TIMER1);
                EndDialog(hwnd, 0);
            break;
            default:
                return FALSE;
        }
        return TRUE;
    }
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    	           LPSTR lpCmdLine, int nCmdShow)
    {
        return DialogBox(hInstance, MAKEINTRESOURCE(IDD_MAIN), NULL, DlgProc);
    }
    resource.rc
    Code:
    #include "resource.h"
    #include "windows.h"
    
    IDD_MAIN DIALOG DISCARDABLE  0, 0, 264, 260
    STYLE WS_OVERLAPPEDWINDOW
    CAPTION "Gerenciador de Tarefas"
    FONT 9, "MS Sans Serif"
    BEGIN
        LISTBOX         IDC_LIST,14,38,236,178,LBS_NOINTEGRALHEIGHT | 
                        LBS_EXTENDEDSEL | WS_VSCROLL | WS_TABSTOP
    END
    Last edited by lala123; 08-05-2005 at 04:00 PM.

  4. #4
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    You may find the list-view control to be a better choice. You can clear a list-view with the ListView_DeleteAllItems macro.

  5. #5
    the magic penguim
    Join Date
    Jul 2005
    Posts
    91
    Ok, I tried to implement a list-view but mine is not showing up, why?

    Code:
    #define WIN32_LEAN_AND_MEAN
    #define _WIN32_IE 0x300
    #include <windows.h>
    #include <tlhelp32.h>
    #include <commctrl.h>
    #include "resource.h"
    
    #pragma comment(lib, "gdi32.lib")
    #pragma comment(lib, "comctl32.lib")
    
    BOOL CALLBACK DlgProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
    {
        HWND hListView;
    
        switch(Message)
        {
            case WM_INITDIALOG:
            {
                HINSTANCE hInstance;
                LVCOLUMN lvc = { 0 };
    
                hListView = CreateWindow(WC_LISTVIEW, NULL, WS_CHILD | WS_VISIBLE | LVS_REPORT,
                                         14,38,236,178, hwnd, (HMENU) 500, hInstance, NULL);
    
                ListView_SetExtendedListViewStyle(hListView, LVS_EX_FULLROWSELECT | LVS_EX_HEADERDRAGDROP);
    
                lvc.mask = LVCF_TEXT | LVCF_SUBITEM | LVCF_WIDTH  | LVCF_FMT;
                lvc.fmt  = LVCFMT_LEFT;
    
                // Adding three columns to the list-view
                lvc.iSubItem = 0;
                lvc.cx       = 100;
                lvc.pszText  = TEXT("Process Name");
                ListView_InsertColumn(hListView, 0, &lvc);
    
                lvc.iSubItem = 1;
                lvc.cx       = 75;
                lvc.pszText  = TEXT("User name");
                ListView_InsertColumn(hListView, 1, &lvc);
    
                lvc.iSubItem = 2;
                lvc.cx       = 50;
                lvc.pszText  = TEXT("PID");
                ListView_InsertColumn(hListView, 2, &lvc);
    
                lvc.iSubItem = 3;
                lvc.cx       = 70;
                lvc.pszText  = TEXT("Memory use");
                ListView_InsertColumn(hListView, 3, &lvc);
    
                // SetTimer(hwnd, TIMER1, 1000, (TIMERPROC) NULL);
            }
    		break;
            case WM_TIMER:
            {
                HANDLE hProcessSnap;
                PROCESSENTRY32 pe32;
    
                hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
                if (hProcessSnap == INVALID_HANDLE_VALUE)
                {
                    KillTimer(hwnd, TIMER1);
                    MessageBox(hwnd, TEXT("Dam CreateToolhelp32Snapshot!"), TEXT("Error"), 
                               MB_OK | MB_ICONEXCLAMATION);
                }
                
                pe32.dwSize = sizeof(PROCESSENTRY32);
    
                if (!Process32First(hProcessSnap, &pe32))
                {
                    KillTimer(hwnd, TIMER1);
                    CloseHandle(hProcessSnap);
                    MessageBox(hwnd, TEXT("Dam Process32First!"), TEXT("Error"), 
                               MB_OK | MB_ICONEXCLAMATION);
                }
    
                while(Process32Next(hProcessSnap, &pe32))
                {
                    // Add the items when I manage to make the list show up
                }
                
                CloseHandle(hProcessSnap);
            }
            break;
            case WM_CLOSE:
                KillTimer(hwnd, TIMER1);
                EndDialog(hwnd, 0);
            break;
            default:
                return FALSE;
        }
        return TRUE;
    }
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    	LPSTR lpCmdLine, int nCmdShow)
    {
    	return DialogBox(hInstance, MAKEINTRESOURCE(IDD_MAIN), NULL, DlgProc);
    }

  6. #6
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    You need to call InitCommonControlsEx before creating a common control.

  7. #7
    the magic penguim
    Join Date
    Jul 2005
    Posts
    91
    Thanks It's working now.
    Last edited by lala123; 08-05-2005 at 08:56 PM.

  8. #8
    the magic penguim
    Join Date
    Jul 2005
    Posts
    91
    One more problem Now I'm sending the data, but... blank list....

    Code:
                i = 0;
                while(Process32Next(hProcessSnap, &pe32))
                {
                    lv.iItem = i;
                    ListView_InsertItem(hListView, &lv);
                    ListView_SetItemText(hListView, i, 0, pe32.szExeFile);
                    ListView_SetItemText(hListView, i, 1, TEXT("Test"));
                    ListView_SetItemText(hListView, i, 2, pe32.th32ProcessID);
                    ListView_SetItemText(hListView, i, 3, TEXT("Test"));
                    i++;
                }
    Last edited by lala123; 08-05-2005 at 09:29 PM.

  9. #9
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    Code:
    BOOL CALLBACK DlgProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
    {
        HWND hListView;
    
        switch(Message)
        {
    hListView is an auto variable and its value will be lost each time DlgProc is called. You could make it static, or a global, or you could get its value each time with GetDlgItem:
    Code:
            case WM_TIMER:
            {
                HANDLE hProcessSnap;
                PROCESSENTRY32 pe32;
    
                hListView = GetDlgItem(hwnd, 500);
    Also, have you removed the // before your SetTimer call?

  10. #10
    the magic penguim
    Join Date
    Jul 2005
    Posts
    91
    Thanks. Now I used the ListView_DeleteAllItems before that while loop to clean the list and then update it, but the resuslts weren't like I expected... Each time it "updated" you loose your selection and position in the scrollbar not like taskmanager...

    Also I checked that site http://www.foosyerdoos.fsnet.co.uk/ and find handling the WM_SIZE message quite interesting to update the list size, I'm trying to leave a margin on each side, but only managed to do it on top and left, how about right and bottom?

    Code:
            case WM_SIZE:
            {
                HWND hListView = GetDlgItem(hwnd, 500);
    
                MoveWindow(hListView,20,30,LOWORD(lParam)-10,HIWORD(lParam),TRUE);
                SendMessage(hListView,LVM_ARRANGE,LVA_ALIGNTOP,0);
            }
    Edit: Also how would I send the th32ProcessID (a DWORD) to the list?
    Last edited by lala123; 08-06-2005 at 11:53 AM.

  11. #11
    the magic penguim
    Join Date
    Jul 2005
    Posts
    91
    Hum...

  12. #12
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    >> I'm trying to leave a margin on each side, but only managed to do it on top and left, how about right and bottom? <<

    You have tot take into account the left/top margin when you set the width/height. For example, if you want a 10 pixel margin:
    Code:
                MoveWindow(hListView, 10, 10, LOWORD(lParam) - 20, HIWORD(lParam) - 20,TRUE);
    >> Also how would I send the th32ProcessID (a DWORD) to the list? <<

    You will need to format it to a string. You can do this with wsprintf:
    Code:
    TCHAR buf[100];
    wsprintf(buf, TEXT("%lu"), th32ProcessID);
    >> Now I used the ListView_DeleteAllItems before that while loop to clean the list and then update it, but the resuslts weren't like I expected... Each time it "updated" you loose your selection and position in the scrollbar not like taskmanager. <<

    You could only add/delete the items that have changed to avoid that behaviour. Alternatively, you could record which item is selected (using ListView_GetSelectionMark) and restore it (using ListView_SetSelectionMark) after the update.

  13. #13
    the magic penguim
    Join Date
    Jul 2005
    Posts
    91
    Once again thanks

    All but one solution worked finely, I'm getting undefined reference to ListView_GetSelectionMark and ListView_SetSelectionMark, I even tried sending the LVM_GETSELECTIONMARK and the LVM_SETSELECTIONMARK but they were undefined as well...

    I'm including commctrl.h, and linking to libcomctl32.a

  14. #14
    Even death may die... Dante Shamest's Avatar
    Join Date
    Apr 2003
    Location
    Malaysia
    Posts
    970
    Those constants are defined only if __WIN32_IE is at least 0x0400.

    So I believe to solve the problem, you have to define __WIN32_IE before including the windows headers.

    Code:
    #define _WIN32_IE 0x0400
    #include <windows.h>
    #include <commctrl.h>

  15. #15
    the magic penguim
    Join Date
    Jul 2005
    Posts
    91
    Thanks... It worked, but there was no difference, you still loose your selection and scrollbar position... How would I realise the second option: "You could only add/delete the items that have changed to avoid that behaviour.". My code so far:

    Code:
                 int mark = ListView_GetSelectionMark(hListView);
                ListView_DeleteAllItems(hListView);
    
                unsigned int i = 0;
                TCHAR buf[100];
                while(Process32Next(hProcessSnap, &pe32))
                {
                    wsprintf(buf, TEXT("%lu"), pe32.th32ProcessID);
    
                    lv.iItem = i;
                    ListView_InsertItem(hListView, &lv);
                    ListView_SetItemText(hListView, i, 0, pe32.szExeFile);
                    ListView_SetItemText(hListView, i, 1, TEXT("Test"));
                    ListView_SetItemText(hListView, i, 2, buf);
                    ListView_SetItemText(hListView, i, 3, TEXT("Test"));
                    i++;
                }
                ListView_SetSelectionMark(hListView, mark);
                CloseHandle(hProcessSnap);

Page 1 of 2 12 LastLast
Popular pages Recent additions subscribe to a feed

Similar Threads

  1. geting ipv4 and ipv6 interfaces with ioclt
    By wwwnuwan in forum Networking/Device Communication
    Replies: 0
    Last Post: 04-21-2009, 12:38 AM
  2. geting input in C, problem in getting input
    By BujarM in forum C Programming
    Replies: 3
    Last Post: 04-17-2009, 09:38 PM
  3. FindWindow inconsistency
    By CondorMan in forum C++ Programming
    Replies: 7
    Last Post: 06-22-2006, 04:35 AM
  4. Findwindow Sendmessage Help
    By Coder87C in forum Windows Programming
    Replies: 26
    Last Post: 08-12-2003, 01:28 AM
  5. FindWindow()
    By face_master in forum Windows Programming
    Replies: 2
    Last Post: 05-27-2002, 11:53 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21