一个进程查看器的sdk实现

进程查看器,改自《delphi下深入Windows核心编程》74页。

用sdk编程时主要注意几点:
1.用属性表作主界面,可调用PropertySheet函数,该函数只有一个参数:指向PROPSHEETHEADER结构的指针。它的作用相当于创建模态对话框函数DialogBox。调用PropertySheet函数会生成一个属性表对话框,不过它没有对话框过程,只有一个回调函数。一般不用定义该回调函数,除非你要做一些初始化工作,比如这里就为属性表添加一个最小化按钮(属性表默认只有一个关闭按钮和帮助按钮)。属性表中每个属性页通过定义PROPSHEETPAGE来实现。每个属性页相当于一个无模态对话框,都有各自的对话框过程,编程方法同一般的对话框是一样的。我们主要的工作都是在这些对话框过程中完成的。
下面的典型代码就创建了一个标题名为“进程管理器”的属性表,有一个SheetProc回调函数;它里面有两个属性表,分别名为“进程”和“窗口”,分别对应ProcessPageDlgProc对话框过程和WindowPageDlgProc对话框过程。

    PROPSHEETPAGE psp[2];
    PROPSHEETHEADER psh;

    psp[0].dwSize = sizeof(PROPSHEETPAGE);
    psp[0].dwFlags = PSP_USEICONID | PSP_USETITLE;//|PSP_USECALLBACK;
    psp[0].hInstance = g_hinst;
    psp[0].pszTemplate = MAKEINTRESOURCE(IDD_TABSHEET1);
    psp[0].pszIcon = 0;//MAKEINTRESOURCE(IDI_FONT);
    psp[0].pfnDlgProc =(DLGPROC)ProcessPageDlgProc;//进程页的对话框过程
    psp[0].pszTitle = "进程";
    psp[0].lParam = 0;
    psp[0].pfnCallback = NULL;

    psp[1].dwSize = sizeof(PROPSHEETPAGE);
    psp[1].dwFlags = PSP_USEICONID | PSP_USETITLE;//|PSP_USECALLBACK;
    psp[1].hInstance = g_hinst;
    psp[1].pszTemplate = MAKEINTRESOURCE(IDD_TABSHEET2);
    psp[1].pszIcon =0;// MAKEINTRESOURCE(IDI_BORDER);
    psp[1].pfnDlgProc = (DLGPROC)WindowPageDlgProc;//窗口页的对话框过程
    psp[1].pszTitle ="窗口";
    psp[1].lParam = 0;
    psp[1].pfnCallback = NULL;

    psh.dwSize = sizeof(PROPSHEETHEADER);
    psh.dwFlags = PSH_USEICONID | PSH_PROPSHEETPAGE|PSH_USECALLBACK;
    psh.hwndParent = hwndOwner;
    psh.hInstance = g_hinst;
    psh.pszIcon =0;// MAKEINTRESOURCE(IDI_CELL_PROPERTIES);
    psh.pszCaption = (LPSTR) "进程管理器";
    psh.nPages = sizeof(psp) / sizeof(PROPSHEETPAGE);
    psh.nStartPage = 0;
    psh.ppsp = (LPCPROPSHEETPAGE) &psp;
    psh.pfnCallback =(PFNPROPSHEETCALLBACK)SheetProc;//属性表的回调函数

    PropertySheet((LPCPROPSHEETHEADER)&psh);

2.查看系统的进程可以调用CreateToolhelp32Snapshot创建进程快照,再分别调用Process32First和Process32Next就可以遍历所有的系统进程。一般我们把找到的进程信息先保存到我们自己定义的一个结构中,再把该结构的指针放到一个链表里,组成一个指针动态链表,以后我们就可以从该链表取得把我们想要的进程的部分或全部信息,如进程名字等,再显示到列表框。Delphi中有一个现成的TList类(其实它应该是个动态数组),mfc也有现成的类可用,可是我们现在只能用sdk,一种解决的方法是使用std标准库的std::list,可惜我还不懂:(。难道要我自己编码实现一个链表?那就头大了,好像也不值得阿。不过且慢,不是有一个listbox控件吗,其实我们也可以把它当作链表来用的。具体见代码。
另外还要注意一点,listbox不能通过只添加WS_HSCROLL风格来增加水平滚动条,还要发送一条LB_SETHORIZONTALEXTENT消息才行,该消息的WPARAM参数是水平滚动条的像素宽度。

源代码:

//ProceeVier.cpp
//改自《delphi下深入Windows核心编程》74页
//作者 hlq
//2005年8月23日

#include <windows.h>
#include <windowsx.h>
#include "CmnHdr.h"
#include <commdlg.h>
//#include <commctrl.h>

#include "resource.h"
#include <Tlhelp32.h>
#include "prsht.h"

//属性表是通用控件,必须告诉linker链接comctl32.lib
#pragma comment(lib,"comctl32.lib")

LRESULT CALLBACK SheetProc(HWND hwnd, UINT uMsg, LPARAM lParam);
LRESULT CALLBACK ProcessPageDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam,

LPARAM lParam);
LRESULT CALLBACK WindowPageDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam,

LPARAM lParam);

HINSTANCE g_hinst;

///
//
//对话框模版结构
//
//用于SheetProc回调函数改变属性表对话框的风格。这里只是给属性表
//加上最小化按钮
///
//
#pragma pack (push, 1)
typedef struct DLGTEMPLATEEX
{
    WORD dlgVer;
    WORD signature;
    DWORD helpID;
    DWORD exStyle;
    DWORD style;
    WORD cDlgItems;
    short x;
    short y;
    short cx;
    short cy;
} DLGTEMPLATEEX, *LPDLGTEMPLATEEX;
#pragma pack (pop)


/
//
//进程信息结构
//

//
typedef struct TProcessInfo
{
 char* ExeFile;
 DWORD ProcessID;
} TProcessInfo,*ProcessInfo;

//
//
//函数名:DoPropertySheet
//功能:创建属性表
//入口参数:
//        hwndOwner:属性表的拥有者窗口。NULL表示桌面
//出口参数:无
/
//
void DoPropertySheet(HWND hwndOwner)
{
    PROPSHEETPAGE psp[2];
    PROPSHEETHEADER psh;

    psp[0].dwSize = sizeof(PROPSHEETPAGE);
    psp[0].dwFlags = PSP_USEICONID | PSP_USETITLE;//|PSP_USECALLBACK;
    psp[0].hInstance = g_hinst;
    psp[0].pszTemplate = MAKEINTRESOURCE(IDD_TABSHEET1);
    psp[0].pszIcon = 0;//MAKEINTRESOURCE(IDI_FONT);
    psp[0].pfnDlgProc =(DLGPROC)ProcessPageDlgProc;//进程页的对话框过程
    psp[0].pszTitle = "进程";
    psp[0].lParam = 0;
    psp[0].pfnCallback = NULL;

    psp[1].dwSize = sizeof(PROPSHEETPAGE);
    psp[1].dwFlags = PSP_USEICONID | PSP_USETITLE;//|PSP_USECALLBACK;
    psp[1].hInstance = g_hinst;
    psp[1].pszTemplate = MAKEINTRESOURCE(IDD_TABSHEET2);
    psp[1].pszIcon =0;// MAKEINTRESOURCE(IDI_BORDER);
    psp[1].pfnDlgProc = (DLGPROC)WindowPageDlgProc;//窗口页的对话框过程
    psp[1].pszTitle ="窗口";
    psp[1].lParam = 0;
    psp[1].pfnCallback = NULL;

    psh.dwSize = sizeof(PROPSHEETHEADER);
    psh.dwFlags = PSH_USEICONID | PSH_PROPSHEETPAGE|PSH_USECALLBACK;
    psh.hwndParent = hwndOwner;
    psh.hInstance = g_hinst;
    psh.pszIcon =0;// MAKEINTRESOURCE(IDI_CELL_PROPERTIES);
    psh.pszCaption = (LPSTR) "进程管理器";
    psh.nPages = sizeof(psp) / sizeof(PROPSHEETPAGE);
    psh.nStartPage = 0;
    psh.ppsp = (LPCPROPSHEETPAGE) &psp;
    psh.pfnCallback =(PFNPROPSHEETCALLBACK)SheetProc;//属性表的回调函数

    PropertySheet((LPCPROPSHEETHEADER)&psh);
    return;
}

//
//
//函数:My_RunFileScan
//功能:将进程名显示在列表框上
//入口参数:
//        hwndListbox 列表框句柄
//出口参数:无
//
//
void My_RunFileScan(HWND hwndListbox)
{
    ProcessInfo p;
    HANDLE ProcessListHandle;
    PROCESSENTRY32 ProcessStruct;
 BOOL ok;
 //清列表框
 ListBox_ResetContent(hwndListbox);

 //创建进程快照
 ProcessListHandle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);

 ProcessStruct.dwSize = sizeof(PROCESSENTRY32);
 ok = Process32First(ProcessListHandle,&ProcessStruct);
 for(int i=0; ok!=0; i++)
 {
  p= (ProcessInfo)malloc(sizeof(TProcessInfo));

  p->ExeFile = ProcessStruct.szExeFile;
  p->ProcessID = ProcessStruct.th32ProcessID;
  int n=ListBox_AddString(hwndListbox,ProcessStruct.szExeFile);
  //listbox的sort属性已改为false
  //MessageBox(0,"请观察是如何加入列表框的","~00~",0);
       
  //将p附加到列表框第n项(从0开始)
  ListBox_SetItemData(hwndListbox,n,p);

     //下面这段代码是调试时用来验证指针确实附加在列表项上
  //ProcessInfo p2 = (ProcessInfo)ListBox_GetItemData

(hwndListbox,n);
  //char buffer[100];
  //wsprinf(buffer,"%p",p2);
  //MessageBox(0,buffer,"~00~",0);
  
  ok = Process32Next(ProcessListHandle,&ProcessStruct);  
 } 
 CloseHandle(ProcessListHandle);     
}


//
//  Process WM_INITDIALOG message for window/dialog: ProcessPageDlg
//
BOOL ProcessPageDlg_OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam)
{
 // TODO: Add your message processing code here...
 SendMessage(GetDlgItem(hwnd, IDC_LIST1), LB_SETHORIZONTALEXTENT, 500,

0);
 return TRUE;
}

//
//  Process WM_COMMAND message for  window/dialog: ProcessPageDlg
//
void ProcessPageDlg_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
{
 // TODO: Add your message processing code here...
 HWND hwndListbox1;
 switch(id)
 {
 case IDCANCEL://关闭进程
  HANDLE h;
  INT b;
  DWORD a;
  ProcessInfo p2;
   
  //取得列表框的句柄
     hwndListbox1 = GetDlgItem(hwnd,IDC_LIST1); 
        //取得列表框当前所选项
  b = ListBox_GetCurSel(hwndListbox1);
  //如果选中任一项
  if(b>=0)
  {
     //取得列表框对应项附加的指针
     p2 = (ProcessInfo)ListBox_GetItemData(hwndListbox1,b);
  
     if(p2!=0)
     {
        h = OpenProcess(PROCESS_ALL_ACCESS,TRUE,p2->ProcessID);
     if(h==0)
     MessageBox(0,"打开进程失败","~00~",0);
     else
     {
        free(p2);
           GetExitCodeProcess(h,&a);
           if(TerminateProcess(h,a)!=0)
        {
           MessageBox(0,"成功关闭进程","~00~",0);
           My_RunFileScan(hwndListbox1);
         }
         else
           MessageBox(0,"关闭进程失败","~00~",0);
      }
      }
     else
      MessageBox(0,"进程ID得不到","~00~",0);
         }
   else
            MessageBox(0,"请选择一个进程","~00~",0);
   break;

 case IDOK://刷新进程  
  //取得列表框的句柄,并清空列表框的内容
     hwndListbox1 = GetDlgItem(hwnd,IDC_LIST1); 
  //显示进程名
  My_RunFileScan(hwndListbox1);    
 }
}

// Dialog proc for page 1
LRESULT CALLBACK ProcessPageDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam,

LPARAM lParam)
{
 switch(uMsg)
 {
  chHANDLE_DLGMSG (hwnd, WM_INITDIALOG,

ProcessPageDlg_OnInitDialog);
     chHANDLE_DLGMSG (hwnd, WM_COMMAND, ProcessPageDlg_OnCommand);
    }
 return FALSE;
}


//
//  Process WM_COMMAND message for window/dialog: WindowPageDlg
//
void WindowPageDlg_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
{
 // TODO: Add your message processing code here...
 switch(id)
 {
 case IDOK://更新按钮
  HWND hCurrentWindow;
  TCHAR szText[255];
  //取得列表框的句柄
     HWND hwndListbox2 = GetDlgItem(hwnd,IDC_LIST2); 
  //取得父窗口(即属性表)的句柄
  HWND hwndPropertySheet = GetParent(hwnd);
        //MessageBox(0,"ok","0",0);
  //清列表框
     ListBox_ResetContent(hwndListbox2);
  //获取第一个窗口
  hCurrentWindow = GetWindow(hwndPropertySheet,GW_HWNDFIRST);
  chASSERT(hCurrentWindow);
  //枚举所有的窗口
  while(hCurrentWindow != 0)
  {
   if(GetWindowText(hCurrentWindow,szText,255) > 0)
    ListBox_AddString(hwndListbox2,szText);
   //取下一个窗口
   hCurrentWindow = GetWindow

(hCurrentWindow,GW_HWNDNEXT);
   szText[0]='/0';
  }
  //break;
 }
}

//
//  Process WM_INITDIALOG message for window/dialog: WindowPageDlg
//
BOOL WindowPageDlg_OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam)
{
 // TODO: Add your message processing code here...
 //为列表框添加水平滚动条
    SendMessage(GetDlgItem(hwnd, IDC_LIST2), LB_SETHORIZONTALEXTENT, 1000, 0);
 return TRUE;
}

 

// Dialog proc for page 2
LRESULT CALLBACK WindowPageDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam,

LPARAM lParam)
{
 switch(uMsg)
 {
  chHANDLE_DLGMSG (hwnd, WM_INITDIALOG,

WindowPageDlg_OnInitDialog);
     chHANDLE_DLGMSG (hwnd, WM_COMMAND,

WindowPageDlg_OnCommand);
    }
 return FALSE;
}

// callback function for property sheet
LRESULT CALLBACK SheetProc(HWND hwnd, UINT uMsg, LPARAM lParam)
{
 switch(uMsg)
 {
   
      case PSCB_PRECREATE:
  //这里只是给属性表加上最小化按钮
        if (LPDLGTEMPLATEEX(lParam)->signature ==  0xFFFF)
            LPDLGTEMPLATEEX(lParam)->style |=  WS_MINIMIZEBOX;
         else
            LPDLGTEMPLATE(lParam)->style |=  WS_MINIMIZEBOX;
         break;        
 }
 return FALSE;

}

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
    // InitCommonControls();
 g_hinst =hInstance;
    DoPropertySheet(NULL);
    return 0;
}

ProcessViewer.rc
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"

#define APSTUDIO_READONLY_SYMBOLS
/
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"

/
#undef APSTUDIO_READONLY_SYMBOLS

/
// 中文(中华人民共和国) resources

#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
#ifdef _WIN32
LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
#pragma code_page(936)
#endif //_WIN32

#ifdef APSTUDIO_INVOKED
/
//
// TEXTINCLUDE
//

1 TEXTINCLUDE
BEGIN
    "resource.h/0"
END

2 TEXTINCLUDE
BEGIN
    "#include ""afxres.h""/r/n"
    "/0"
END

3 TEXTINCLUDE
BEGIN
    "/r/n"
    "/0"
END

#endif    // APSTUDIO_INVOKED

/
//
// Dialog
//

IDD_TABSHEET1 DIALOGEX 0, 0, 257, 225
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_MINIMIZEBOX |

WS_POPUP |
    WS_CAPTION | WS_SYSMENU
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
    LISTBOX         IDC_LIST1,2,9,185,203,LBS_NOINTEGRALHEIGHT | WS_VSCROLL |
                    WS_HSCROLL | WS_TABSTOP
    PUSHBUTTON      "刷新进程",IDOK,192,46,50,14
    PUSHBUTTON      "关闭进程",IDCANCEL,191,82,50,14
END

IDD_TABSHEET2 DIALOGEX 0, 0, 257, 225
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION |
    WS_SYSMENU
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
    DEFPUSHBUTTON   "更新",IDOK,192,48,50,14
    LISTBOX         IDC_LIST2,2,9,185,203,LBS_SORT | WS_VSCROLL | WS_HSCROLL |
                    WS_TABSTOP
END

/
//
// DESIGNINFO
//

#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
    IDD_TABSHEET1, DIALOG
    BEGIN
        RIGHTMARGIN, 249
        TOPMARGIN, 6
        BOTTOMMARGIN, 216
    END

    IDD_TABSHEET2, DIALOG
    BEGIN
        LEFTMARGIN, 2
        RIGHTMARGIN, 248
        TOPMARGIN, 7
        BOTTOMMARGIN, 219
    END
END
#endif    // APSTUDIO_INVOKED
#endif    // 中文(中华人民共和国) resources
/

#ifndef APSTUDIO_INVOKED
/
//
// Generated from the TEXTINCLUDE 3 resource.
//
/
#endif    // not APSTUDIO_INVOKED

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值