Как создать графическое приложение, в котором список активных процессов отображается в виде списка - PullRequest
0 голосов
/ 14 ноября 2018

Итак, у меня есть школьное задание, которое выглядит следующим образом:

Создайте графическое приложение, в котором список активных процессов в системе отображается в списке.Для выбранного процесса из списка будет указана следующая информация:

  1. Соответствующий PID
  2. Имя исполняемого файла, для которого был запущен процесс

Я сделал это, которое показывает мне, если диспетчер задач открыт и если он открыт, он отображает адрес памяти:

#include <iostream>
#include <Windows.h>
#include <string>
#include <TlHelp32.h>
#include <stdio.h>

using namespace std;

DWORD ProcessID;

int main()
{
    HWND hwnd = FindWindowA(0, ("Task Manager"));

    GetWindowThreadProcessId(hwnd, &ProcessID);

    if (hwnd) {
        cout << ProcessID << endl;
    }
    else
    {
        cout << "Windows Not Found" << endl;
    }

    system("pause");
}

Можете ли вы, ребята, помочь мне, указав направление или дать некоторую информациювыполнить мое назначение?Заранее спасибо

1 Ответ

0 голосов
/ 14 ноября 2018

Я бы не использовал Псапи. И это не слишком сложно:

#include <cstddef>  // std::size_t
#include <vector>   // std::vector<>
#include <string>   // std::wstring
#include <sstream>  // std::wostringstream

#include <windows.h>
#include <tlhelp32.h>  // CreateToolhelp32Snapshot(), Process32FirstW(),
                       // Process32NextW(),
#include <commctrl.h>  // InitCommonControlsEx(), ICC_LISTVIEW_CLASSES, WC_LISTVIEWW
#pragma comment(lib, "comctl32.lib")  // tell Linker to link against the
                                      // Windows Common Controls Library

struct process_data_t {  // datastructure to represent a process
    std::wstring pid;    // number as string for convenience
    std::wstring name;   // the name of the executable
};

// function to get the current processes running on the system
void update_process_data(std::vector<process_data_t> &process_data)
{
                   // take a snapshot of the running processes
    auto snapshot{ CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0) };

    if (snapshot == INVALID_HANDLE_VALUE) {  // validate the result
        MessageBoxW(nullptr, L"CreateToolhelp32Snapshot() failed :(", L"Error:", MB_ICONEXCLAMATION);
        return;
    }

    // Process32FirstW() and Process32NextW() will fill a structure of type
    PROCESSENTRY32W pe{ sizeof pe };       // with info about one process at 
    if (!Process32FirstW(snapshot, &pe)) { // a time from the snapshot
        MessageBoxW(nullptr, L"Process32FirstW() failed :(", L"Error:", MB_ICONEXCLAMATION);
        CloseHandle(snapshot);
        return;
    }

    BOOL result{ true };   // result of Process32NextW()
    process_data.clear();  // discard the old data

    for (std::size_t i{}; result; result = Process32NextW(snapshot, &pe), ++i) {
        if (i + 1 > process_data.capacity())  // if we come close to the vectors
            process_data.reserve(process_data.capacity() + 100); // capacity, increase it

        std::wostringstream woss;  // a stream to convert the process-id
        woss << pe.th32ProcessID;  // to a std::wstring

        // add the data to our vector:
        process_data.push_back({ woss.str(), pe.szExeFile });
    }

    // don't forget to close the handle opened by CreateToolhelp32Snapshot()
    CloseHandle(snapshot);  // better solution: use a `std::unique_ptr<>` with
};                          // a custom deleter. Sorry, was to lazy to do so.

// Window procedure that will get called when our application receives messages
LRESULT APIENTRY window_proc(HWND window, UINT message, WPARAM wparam, LPARAM lparam)
{
    static HWND list_view;  // a handle to the listview we'll create in WM_CREATE
    static std::vector<process_data_t> process_data;  // data about processes
                                                      // to display in the
                                                      // listview

    switch (message) {
        case WM_CREATE:  // create child-windows when the parent gets created:
        {
            CREATESTRUCTW *create_struct{ reinterpret_cast<CREATESTRUCTW*>(lparam) };
            list_view = CreateWindowW(WC_LISTVIEWW, L"", WS_CHILD | WS_VISIBLE | LVS_REPORT | LVS_OWNERDATA,
                                      5, 5, create_struct->cx - 10, create_struct->cy - 10,
                                      window, (HMENU)100, create_struct->hInstance, nullptr);
            if (!list_view)  // abort window creation if
                return -1;   // creation of the listview child failed

            LVCOLUMNW columns[2];  // to add 2 columns to our listview
            columns[0].mask = columns[1].mask = LVCF_TEXT | LVCF_WIDTH;
            columns[0].pszText = const_cast<wchar_t*>(L"PID");
            columns[0].cx = 200;  // width of the column
            columns[1].pszText = const_cast<wchar_t*>(L"Name");
            columns[1].cx = 800;  // dito
            for (std::size_t i{}; i < std::size(columns); ++i) {
                // insert the column to the listview:
                if (SendMessageW(list_view, LVM_INSERTCOLUMN, i, reinterpret_cast<LPARAM>(&columns[i])) == -1)
                    return -1;
            }

            update_process_data(process_data);  // populate our process data

            // tell the listview how many items to display:
            SendMessageW(list_view, LVM_SETITEMCOUNT, process_data.size(), LVSICF_NOSCROLL);

            // have Windows send us a message (WM_TIMER) every 250 ms
            SetTimer(window, 0, 250, nullptr);

            return 0;  // all went well.
        }

        case WM_TIMER:  // message we receive every 250 ms to update
            update_process_data(process_data);  // the process data

            // and inform the listview about changes in the item count
            SendMessageW(list_view, LVM_SETITEMCOUNT, process_data.size(), LVSICF_NOSCROLL);
            return 0;

        case WM_NOTIFY:  // we will be notified when the listview wants us
                         // to provide data to display
            if (reinterpret_cast<NMHDR*>(lparam)->code == LVN_GETDISPINFO) {
                NMLVDISPINFO *dispinfo{ reinterpret_cast<NMLVDISPINFO*>(lparam) };
                if (dispinfo->item.iSubItem) {  // if the listview wants subitem
                                                // at index dispinfo->item.iItem
                    dispinfo->item.pszText = const_cast<wchar_t*>(process_data[dispinfo->item.iItem].name.c_str());  // give it the process' name
                }
                else {
                    dispinfo->item.pszText = const_cast<wchar_t*>(process_data[dispinfo->item.iItem].pid.c_str());   // give it the pid
                }
                return TRUE;
            }
            return 0;

        case WM_SIZE:
            // resize our child-window along with its parent:
            MoveWindow(list_view, 5, 5, LOWORD(lparam) - 10, HIWORD(lparam) - 10, TRUE);
            return 0;

        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
    }

    return DefWindowProcW(window, message, wparam, lparam);
}

int WINAPI WinMain(HINSTANCE instance, HINSTANCE prev_instance, char*, int show_state)
{
    // initialize the Windows Common Controls library to use a listview
    INITCOMMONCONTROLSEX iccex{ sizeof iccex, ICC_LISTVIEW_CLASSES };
    if (!InitCommonControlsEx(&iccex)) {
        MessageBoxW(nullptr, L"Initializing common windows controls library failed :(", L"Error", MB_ICONEXCLAMATION);
        return 0;
    }

    // prepare the window class for our window:
    WNDCLASSW wc{};
    wc.lpfnWndProc = window_proc;
    wc.lpszClassName = L"Poor Mans TaskMan Window Class";
    wc.hbrBackground = reinterpret_cast<HBRUSH>(COLOR_WINDOW + 1);
    wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
    wc.style = CS_HREDRAW | CS_VREDRAW | CS_PARENTDC;

    // register the window class and check for possible error:
    ATOM window_class{ RegisterClass(&wc) };
    if (!window_class) {
        MessageBoxW(nullptr, L"Registering window class failed :(", L"Error", MB_ICONEXCLAMATION);
        return 0;
    }

    // create a window of our now registered window class and handle possible error:
    HWND window{ CreateWindowW(reinterpret_cast<LPCWSTR>(window_class), L"Poor Mans TaskMan", WS_OVERLAPPEDWINDOW,
                               CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, nullptr, nullptr, instance,
                               nullptr)
    };
    if (!window) {
        MessageBoxW(nullptr, L"Creating window failed :(", L"Error:", MB_ICONEXCLAMATION);
        return 0;
    }

    // update and show the window:
    UpdateWindow(window);
    ShowWindow(window, show_state);

    // message-pump:
    MSG msg;
    BOOL result;
    while (result = GetMessageW(&msg, nullptr, 0, 0)) {
        if (result == -1)
            return msg.wParam;
        TranslateMessage(&msg);
        DispatchMessageW(&msg);
    }

    return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...