//observer.h
#ifndef OBSERVER_H
#define OBSERVER_H
#include <QWidget>
#include <QObject>
#include <windows.h>
#include <Wtsapi32.h>
#include <QTreeWidget>
#include <QTreeWidgetItem>
#include <tlhelp32.h>
#include <QDebug>
class ProcessData;
class Observer
{
public:
virtual ~Observer(){}
virtual void Update(QVector<QString>* ProcessName,QVector<DWORD>* ProcessId)=0;
};
class DisplayData
{
public:
virtual ~DisplayData(){}
virtual void Display(QWidget* widget)=0;
};
class Subject
{
public:
virtual ~Subject(){}
virtual void Register(Observer*) =0;
virtual void Remove(Observer*)=0;
virtual void Notify() const =0;
};
class ProcessData : public Subject
{
private:
QVector<Observer*>observers;
QVector<QString>* ProcessName;
QVector<DWORD>* ProcessId;
public:
ProcessData()
:ProcessName(new QVector<QString>),
ProcessId(new QVector<DWORD>)
{}
virtual ~ProcessData()
{
if(ProcessName != nullptr)
{
delete ProcessName;
ProcessName = nullptr;
}
if(ProcessId != nullptr)
{
delete ProcessId;
ProcessId = nullptr;
}
}
//프로세스 이름과 ID를 구한다.
void GetProcessInfo()
{
ProcessName->clear();
ProcessId->clear();
HANDLE h_snap_shot = ::CreateToolhelp32Snapshot(TH32CS_SNAPALL,NULL);
if(h_snap_shot == INVALID_HANDLE_VALUE)
{
CloseHandle(h_snap_shot);
return;
}
PROCESSENTRY32 pe;
pe.dwSize = sizeof(pe);
bool continue_flag = ::Process32First(h_snap_shot,&pe);
while(continue_flag)
{
ProcessName->push_back(QString::fromWCharArray(pe.szExeFile));
ProcessId->push_back(pe.th32ProcessID);
continue_flag = ::Process32Next(h_snap_shot,&pe);
}
::CloseHandle(h_snap_shot);
Notify();
//아 ㅋㅋ WTSEnumerateProcesses이 함수 못쓰더라
/* WTS_PROCESS_INFO *ps_info=nullptr;
DWORD pCount=0;
if(WTSEnumerateProcesses(WTS_CURRENT_SERVER_HANDLE,NULL,1,&ps_info,&pCount))
{
for(int i=0;i<(int)pCount;i++)
{
ProcessName->push_back(QString::fromWCharArray(ps_info[i].pProcessName));
ProcessId->push_back(ps_info[i].ProcessId);
}
}
if(ps_info)
WTSFreeMemory(ps_info);*/
}
//추가한다.
virtual void Register(Observer *observer)
{
observers.push_back(observer);
}
//삭제한다.
virtual void Remove(Observer* observer)
{
observers.removeOne(observer);
}
//값을 변경할 때 쓰인다.
virtual void Notify() const
{
for(auto iter = observers.begin();
iter != observers.end();
iter++)
{
(*iter)->Update(ProcessName,ProcessId);
}
}
};
class ProcessList : public Observer , public DisplayData
{
private:
QVector<QString>*ProcessName;
QVector<DWORD>*ProcessId;
ProcessData* process_data;
QTreeWidget tree_widget;
//QTreeWidgetItem *header;
QSharedPointer<QTreeWidgetItem>header;
QTreeWidgetItem top_item[1024];
public:
ProcessList(){}
ProcessList(ProcessData* process_data)
:process_data(process_data)
//header(nullptr)
{
this->process_data->Register(this);
process_data->GetProcessInfo();
}
//이유를 알수없는 세그멘테이션에러............
virtual ~ProcessList()
{
//qDebug()<<"~ProcessList : "<<header;
/*if(header != nullptr)
{
delete header;
header = nullptr;
}*/
}
virtual void Update(QVector<QString>* ProcessName,QVector<DWORD>* ProcessId)
{
this->ProcessName = ProcessName;
this->ProcessId = ProcessId;
};
virtual void Display(QWidget* widget)
{
/*if(header != NULL)
{
qDebug()<<"delete header : "<<header;
delete header;
header=nullptr;
}*/
qDebug()<<"Befor : "<<header;
//header = new QTreeWidgetItem;
//header.reset(new QTreeWidgetItem);
tree_widget.setHeaderItem(nullptr);
header = QSharedPointer<QTreeWidgetItem>
(new QTreeWidgetItem);
qDebug()<<"After : "<<header;
tree_widget.setParent(widget);
header->setText(0,"ProcessName");
header->setText(1,"PID");
//tree_widget.setHeaderItem(header);
tree_widget.setHeaderItem(header.get());
tree_widget.setColumnWidth(0,300);
for(int i=0;i<ProcessName->size();i++)
{
tree_widget.addTopLevelItem(&top_item[i]);
top_item[i].setText(0,(*ProcessName)[i]);
top_item[i].setText(1,QString("%1").arg((*ProcessId)[i]));
}
tree_widget.resize(500,500);
tree_widget.setSortingEnabled(true);
};
};
#endif // OBSERVER_H
//widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include"observer.h"
#include <QTimer>
class Widget : public QWidget
{
Q_OBJECT
private:
ProcessData process_data;
QSharedPointer<ProcessList>process_list;
QSharedPointer<QTimer>timer;
public:
Widget(QWidget *parent = nullptr);
~Widget();
public slots:
void Process_List_Update();
};
#endif // WIDGET_H
//widget.cpp
#include "widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
process_list.reset(new ProcessList(&process_data));
process_data.GetProcessInfo();
process_list->Display(this);
timer.reset(new QTimer(this));
timer->start(2000);
connect(timer.get(),&QTimer::timeout,
this,&Widget::Process_List_Update);
}
//2초마다 갱신된다.
void Widget::Process_List_Update()
{
process_data.GetProcessInfo();
process_list->Display(this);
}
Widget::~Widget()
{
}
프로그램을 종료할 때 세그멘테이션 에러가 떠버리더라... 어떻게 해야할 지 몰르겠어 ㅠㅠㅠ