How to create a graphical application where the list of active processes is displayed in a list












-2















So I have this school assignment that goes like this:



Create a graphical application where the list of active processes in the system is displayed in a list box. For the selected process from the list, the following information will be specified:




  1. The appropriate PID

  2. The name of the executable file on which the process was launched


I've made this, which show me if task manager is opened and if its opened it displays memory address:



#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");
}


Can you guys help me by pointing in a direction or give some information to fulfill my asignment? Thanks in advance










share|improve this question

























  • You don't need the process id of a maybe open task manager but a list of processes running on the system and a window containing a listbox to display it.

    – Swordfish
    Nov 14 '18 at 15:11






  • 1





    Some info: Process Enumeration Also, don't think you've failed because you can't display all information about all processes. Some you don't have permissions to examine. You can run your final program as administrator to get some more info, but some will be really hard to find out.

    – Ted Lyngmo
    Nov 14 '18 at 15:11













  • Is going with WIndows API to create the GUI a requirement? If it is not, I'd urge you not to go down this route and use a framework.

    – YSC
    Nov 14 '18 at 15:22











  • Otoh, there are some pretty short and simple examples on MSDN for doing this. The Enumerating All Processes example could be used as a base.

    – Ted Lyngmo
    Nov 14 '18 at 15:35
















-2















So I have this school assignment that goes like this:



Create a graphical application where the list of active processes in the system is displayed in a list box. For the selected process from the list, the following information will be specified:




  1. The appropriate PID

  2. The name of the executable file on which the process was launched


I've made this, which show me if task manager is opened and if its opened it displays memory address:



#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");
}


Can you guys help me by pointing in a direction or give some information to fulfill my asignment? Thanks in advance










share|improve this question

























  • You don't need the process id of a maybe open task manager but a list of processes running on the system and a window containing a listbox to display it.

    – Swordfish
    Nov 14 '18 at 15:11






  • 1





    Some info: Process Enumeration Also, don't think you've failed because you can't display all information about all processes. Some you don't have permissions to examine. You can run your final program as administrator to get some more info, but some will be really hard to find out.

    – Ted Lyngmo
    Nov 14 '18 at 15:11













  • Is going with WIndows API to create the GUI a requirement? If it is not, I'd urge you not to go down this route and use a framework.

    – YSC
    Nov 14 '18 at 15:22











  • Otoh, there are some pretty short and simple examples on MSDN for doing this. The Enumerating All Processes example could be used as a base.

    – Ted Lyngmo
    Nov 14 '18 at 15:35














-2












-2








-2








So I have this school assignment that goes like this:



Create a graphical application where the list of active processes in the system is displayed in a list box. For the selected process from the list, the following information will be specified:




  1. The appropriate PID

  2. The name of the executable file on which the process was launched


I've made this, which show me if task manager is opened and if its opened it displays memory address:



#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");
}


Can you guys help me by pointing in a direction or give some information to fulfill my asignment? Thanks in advance










share|improve this question
















So I have this school assignment that goes like this:



Create a graphical application where the list of active processes in the system is displayed in a list box. For the selected process from the list, the following information will be specified:




  1. The appropriate PID

  2. The name of the executable file on which the process was launched


I've made this, which show me if task manager is opened and if its opened it displays memory address:



#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");
}


Can you guys help me by pointing in a direction or give some information to fulfill my asignment? Thanks in advance







c++ windows user-interface winapi






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 14 '18 at 18:37









Swordfish

9,50711436




9,50711436










asked Nov 14 '18 at 15:06









AlexandraAlexandra

1




1













  • You don't need the process id of a maybe open task manager but a list of processes running on the system and a window containing a listbox to display it.

    – Swordfish
    Nov 14 '18 at 15:11






  • 1





    Some info: Process Enumeration Also, don't think you've failed because you can't display all information about all processes. Some you don't have permissions to examine. You can run your final program as administrator to get some more info, but some will be really hard to find out.

    – Ted Lyngmo
    Nov 14 '18 at 15:11













  • Is going with WIndows API to create the GUI a requirement? If it is not, I'd urge you not to go down this route and use a framework.

    – YSC
    Nov 14 '18 at 15:22











  • Otoh, there are some pretty short and simple examples on MSDN for doing this. The Enumerating All Processes example could be used as a base.

    – Ted Lyngmo
    Nov 14 '18 at 15:35



















  • You don't need the process id of a maybe open task manager but a list of processes running on the system and a window containing a listbox to display it.

    – Swordfish
    Nov 14 '18 at 15:11






  • 1





    Some info: Process Enumeration Also, don't think you've failed because you can't display all information about all processes. Some you don't have permissions to examine. You can run your final program as administrator to get some more info, but some will be really hard to find out.

    – Ted Lyngmo
    Nov 14 '18 at 15:11













  • Is going with WIndows API to create the GUI a requirement? If it is not, I'd urge you not to go down this route and use a framework.

    – YSC
    Nov 14 '18 at 15:22











  • Otoh, there are some pretty short and simple examples on MSDN for doing this. The Enumerating All Processes example could be used as a base.

    – Ted Lyngmo
    Nov 14 '18 at 15:35

















You don't need the process id of a maybe open task manager but a list of processes running on the system and a window containing a listbox to display it.

– Swordfish
Nov 14 '18 at 15:11





You don't need the process id of a maybe open task manager but a list of processes running on the system and a window containing a listbox to display it.

– Swordfish
Nov 14 '18 at 15:11




1




1





Some info: Process Enumeration Also, don't think you've failed because you can't display all information about all processes. Some you don't have permissions to examine. You can run your final program as administrator to get some more info, but some will be really hard to find out.

– Ted Lyngmo
Nov 14 '18 at 15:11







Some info: Process Enumeration Also, don't think you've failed because you can't display all information about all processes. Some you don't have permissions to examine. You can run your final program as administrator to get some more info, but some will be really hard to find out.

– Ted Lyngmo
Nov 14 '18 at 15:11















Is going with WIndows API to create the GUI a requirement? If it is not, I'd urge you not to go down this route and use a framework.

– YSC
Nov 14 '18 at 15:22





Is going with WIndows API to create the GUI a requirement? If it is not, I'd urge you not to go down this route and use a framework.

– YSC
Nov 14 '18 at 15:22













Otoh, there are some pretty short and simple examples on MSDN for doing this. The Enumerating All Processes example could be used as a base.

– Ted Lyngmo
Nov 14 '18 at 15:35





Otoh, there are some pretty short and simple examples on MSDN for doing this. The Enumerating All Processes example could be used as a base.

– Ted Lyngmo
Nov 14 '18 at 15:35












1 Answer
1






active

oldest

votes


















-1














I wouldn't use psapi. And it isn't toooo hard:



#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;
}





share|improve this answer


























  • Can you explain to me a bit what's going on in there? I kinda lost myself a bit

    – Alexandra
    Nov 15 '18 at 4:25











  • @Alexandra I'll add comments as soon as I have time.

    – Swordfish
    Nov 15 '18 at 4:33













  • @Alexandra Done. If you have further questions feel free to ask away.

    – Swordfish
    Nov 15 '18 at 8:01











  • Don't think we should be doing homework projects in this way. This question should be closed rather than answered.

    – David Heffernan
    Nov 15 '18 at 8:24











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53303231%2fhow-to-create-a-graphical-application-where-the-list-of-active-processes-is-disp%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









-1














I wouldn't use psapi. And it isn't toooo hard:



#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;
}





share|improve this answer


























  • Can you explain to me a bit what's going on in there? I kinda lost myself a bit

    – Alexandra
    Nov 15 '18 at 4:25











  • @Alexandra I'll add comments as soon as I have time.

    – Swordfish
    Nov 15 '18 at 4:33













  • @Alexandra Done. If you have further questions feel free to ask away.

    – Swordfish
    Nov 15 '18 at 8:01











  • Don't think we should be doing homework projects in this way. This question should be closed rather than answered.

    – David Heffernan
    Nov 15 '18 at 8:24
















-1














I wouldn't use psapi. And it isn't toooo hard:



#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;
}





share|improve this answer


























  • Can you explain to me a bit what's going on in there? I kinda lost myself a bit

    – Alexandra
    Nov 15 '18 at 4:25











  • @Alexandra I'll add comments as soon as I have time.

    – Swordfish
    Nov 15 '18 at 4:33













  • @Alexandra Done. If you have further questions feel free to ask away.

    – Swordfish
    Nov 15 '18 at 8:01











  • Don't think we should be doing homework projects in this way. This question should be closed rather than answered.

    – David Heffernan
    Nov 15 '18 at 8:24














-1












-1








-1







I wouldn't use psapi. And it isn't toooo hard:



#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;
}





share|improve this answer















I wouldn't use psapi. And it isn't toooo hard:



#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;
}






share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 15 '18 at 8:00

























answered Nov 14 '18 at 18:28









SwordfishSwordfish

9,50711436




9,50711436













  • Can you explain to me a bit what's going on in there? I kinda lost myself a bit

    – Alexandra
    Nov 15 '18 at 4:25











  • @Alexandra I'll add comments as soon as I have time.

    – Swordfish
    Nov 15 '18 at 4:33













  • @Alexandra Done. If you have further questions feel free to ask away.

    – Swordfish
    Nov 15 '18 at 8:01











  • Don't think we should be doing homework projects in this way. This question should be closed rather than answered.

    – David Heffernan
    Nov 15 '18 at 8:24



















  • Can you explain to me a bit what's going on in there? I kinda lost myself a bit

    – Alexandra
    Nov 15 '18 at 4:25











  • @Alexandra I'll add comments as soon as I have time.

    – Swordfish
    Nov 15 '18 at 4:33













  • @Alexandra Done. If you have further questions feel free to ask away.

    – Swordfish
    Nov 15 '18 at 8:01











  • Don't think we should be doing homework projects in this way. This question should be closed rather than answered.

    – David Heffernan
    Nov 15 '18 at 8:24

















Can you explain to me a bit what's going on in there? I kinda lost myself a bit

– Alexandra
Nov 15 '18 at 4:25





Can you explain to me a bit what's going on in there? I kinda lost myself a bit

– Alexandra
Nov 15 '18 at 4:25













@Alexandra I'll add comments as soon as I have time.

– Swordfish
Nov 15 '18 at 4:33







@Alexandra I'll add comments as soon as I have time.

– Swordfish
Nov 15 '18 at 4:33















@Alexandra Done. If you have further questions feel free to ask away.

– Swordfish
Nov 15 '18 at 8:01





@Alexandra Done. If you have further questions feel free to ask away.

– Swordfish
Nov 15 '18 at 8:01













Don't think we should be doing homework projects in this way. This question should be closed rather than answered.

– David Heffernan
Nov 15 '18 at 8:24





Don't think we should be doing homework projects in this way. This question should be closed rather than answered.

– David Heffernan
Nov 15 '18 at 8:24




















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53303231%2fhow-to-create-a-graphical-application-where-the-list-of-active-processes-is-disp%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

List item for chat from Array inside array React Native

Thiostrepton

Caerphilly