Win32 通用控件_VM_NOTIFY

1.标准控件与通用控件

标准控件:是指常用的一些控件,在使用的时候可以直接拿来用

例如:Static、Group Box、Button、Check Box、Edit、ComboBox等

通用控件:是指一些不是太常用的控件,因为如果把所有的控件都存储在一个EXE程序中的话,就会显得很臃肿,因此微软就将不常用的一些控件放进一个dll中,因此我们在使用通用控件的时候不能直接使用,要将dll导入之后才能使用
#include <commctrl.h>			
#pragma comment(lib,"comctl32.lib")			

这里我们导入dll之后,只是表示我们能够使用这些控件了,还不能完全能够使用

此时我们需要在WinMain函数中定义该结构体的变量,如下:

INITCOMMONCONTROLSEX control;                 //声明一个对象
control.dwSize=sizeof(INITCOMMONCONTROLSEX);  //结构体的大小,以字节为单位
control.dwICC=ICC_WIN95_CLASSES;              //指示将从DLL加载哪些公共控制类的位标志集,     
                                              //ICC_WIN95_CLASSES是所有的集合
InitCommonControlsEx(&control);               //该函数和该结构体搭配使用

此时我们已经创建好对话框中的控件

接下来需要初始化控件中的名字和数据

2.ListView的使用 

 初始化List控件的名字
LV_COLUMN lv;			
                //包含有关报表视图中某列的信息。此结构可用于创建和操作列
                //创建这个结构体,里面为了存储一些信息					
HWND hListProcess;								
								
//初始化								
memset(&lv,0,sizeof(LV_COLUMN));								
//获取IDC_LIST_PROCESS句柄								
hListProcess = GetDlgItem(hDlg,IDC_LIST_PROCESS);								
//设置整行选中								
SendMessage(hListProcess,LVM_SETEXTENDEDLISTVIEWSTYLE,LVS_EX_FULLROWSELECT,LVS_EX_FULLROWSELECT);								
								
//第一列								
lv.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;
								
lv.pszText = TEXT("进程");				//列标题				
lv.cx = 200;								//列宽
lv.iSubItem = 0;								
//ListView_InsertColumn(hListProcess, 0, &lv);								
SendMessage(hListProcess,LVM_INSERTCOLUMN,0,(DWORD)&lv);								
//第二列								
lv.pszText = TEXT("PID");								
lv.cx = 100;								
lv.iSubItem = 1;								
//ListView_InsertColumn(hListProcess, 1, &lv);								
SendMessage(hListProcess,LVM_INSERTCOLUMN,1,(DWORD)&lv);								
//第三列								
lv.pszText = TEXT("镜像基址");								
lv.cx = 100;								
lv.iSubItem = 2;								
ListView_InsertColumn(hListProcess, 2, &lv);								
//第四列								
lv.pszText = TEXT("镜像大小");								
lv.cx = 100;								
lv.iSubItem = 3;								
ListView_InsertColumn(hListProcess, 3, &lv);								
								
添加数据到List控件
LV_ITEM vitem;			//指定或接收列表视图项的属性		
							
//初始化							
memset(&vitem,0,sizeof(LV_ITEM));							
vitem.mask = LVIF_TEXT;							
							
vitem.pszText = "csrss.exe";							
vitem.iItem = 0;					//行数		
vitem.iSubItem = 0;					//列数		
//ListView_InsertItem(hListProcess, &vitem);							
SendMessage(hListProcess, LVM_INSERTITEM,0,(DWORD)&vitem);
                                    //这里只有第一行的事件叫LVM_INSERTITEM
							
vitem.pszText = TEXT("448");							
vitem.iItem = 0;							
vitem.iSubItem = 1;							
ListView_SetItem(hListProcess, &vitem);
                                    //剩下的事件叫LVM_SetItem							
							
vitem.pszText = TEXT("56590000");							
vitem.iItem = 0;							
vitem.iSubItem = 2;							
ListView_SetItem(hListProcess, &vitem);							
							
vitem.pszText = TEXT("000F0000");							
vitem.iItem = 0;							
vitem.iSubItem = 3;							
ListView_SetItem(hListProcess, &vitem);							
							
vitem.pszText = TEXT("winlogon.exe");							
vitem.iItem = 1;							
vitem.iSubItem = 0;							
//ListView_InsertItem(hListProcess, &vitem);							
SendMessage(hListProcess, LVM_INSERTITEM,0,(DWORD)&vitem);							
							
vitem.pszText = TEXT("456");							
vitem.iSubItem = 1;							
ListView_SetItem(hListProcess, &vitem);							
							
vitem.pszText = TEXT("10000000");							
vitem.iSubItem = 2;							
ListView_SetItem(hListProcess, &vitem);							
							
vitem.pszText = TEXT("000045800");							
vitem.iSubItem = 3;							
ListView_SetItem(hListProcess, &vitem);							

3.WM_NOTIFY消息类型

前面我们使用按钮子窗口的时候,消息处理函数中对于按钮的消息类型是WM_COMMAND

但是在这里,我们想要发送对于List控件的消息时,明显无法实现许多参数的传参

因此这里我们使用WM_NOTIFY消息类型

WM_NOTIFY消息类型特点:

1.该消息类型与WM_COMMAND类型相似,都是由子窗口向父窗口发送的消息。

2.WM_NOTIFY可以包含比WM_COMMAND更丰富的信息

3.Windows通用组件中有很多消息,都是通过WM_NOTIFY来描述的.

4.作业

画出PETools的第一个界面

// LordPE.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#include "resource.h"

#include <commctrl.h>				
#pragma comment(lib,"comctl32.lib")				

void EnumProcess(HWND hListProcess)
{
	LV_ITEM vitem;					
					
	//初始化					
	memset(&vitem,0,sizeof(LV_ITEM));					
	vitem.mask = LVIF_TEXT;					
						
	vitem.pszText = "csrss.exe";					
	vitem.iItem = 0;					
	vitem.iSubItem = 0;					
	//ListView_InsertItem(hListProcess, &vitem);					
	SendMessage(hListProcess, LVM_INSERTITEM,0,(DWORD)&vitem);					
						
	vitem.pszText = TEXT("448");					
	vitem.iItem = 0;					
	vitem.iSubItem = 1;					
	ListView_SetItem(hListProcess, &vitem);					
						
	vitem.pszText = TEXT("56590000");					
	vitem.iItem = 0;					
	vitem.iSubItem = 2;					
	ListView_SetItem(hListProcess, &vitem);					
						
	vitem.pszText = TEXT("000F0000");					
	vitem.iItem = 0;					
	vitem.iSubItem = 3;					
	ListView_SetItem(hListProcess, &vitem);	
	
	vitem.pszText = TEXT("winlogon.exe");						
	vitem.iItem = 1;						
	vitem.iSubItem = 0;						
	//ListView_InsertItem(hListProcess, &vitem);						
	SendMessage(hListProcess, LVM_INSERTITEM,0,(DWORD)&vitem);						
							
	vitem.pszText = TEXT("456");
	vitem.iItem = 1;
	vitem.iSubItem = 1;						
	ListView_SetItem(hListProcess, &vitem);						
							
	vitem.pszText = TEXT("10000000");
	vitem.iItem = 1;
	vitem.iSubItem = 2;						
	ListView_SetItem(hListProcess, &vitem);						
							
	vitem.pszText = TEXT("000045800");
	vitem.iItem = 1;
	vitem.iSubItem = 3;						
	ListView_SetItem(hListProcess, &vitem);		

}
void EnumModule(HWND hListProcess,HWND hListModule,WPARAM wParam,LPARAM lParam)
{
	DWORD row;
	LV_ITEM item;
	TCHAR szName[0x20];
	TCHAR szImageBase[0x20];

	memset(&item,0,sizeof(LV_ITEM));
	memset(szName,0,0x20);
	row=SendMessage(hListProcess,LVM_GETNEXTITEM,-1,LVNI_SELECTED);
	
	if(row<0)
	{
		MessageBox(NULL,TEXT("请选择进程"),TEXT("ERROR"),MB_OK);
		return ;
	}
	item.iSubItem=0;     //这部分我们将数据存入szName中  0表示第一列
	item.pszText=szName;
	item.cchTextMax=0x20;
	SendMessage(hListProcess,LVM_GETITEMTEXT,row,(DWORD)&item);

	item.iSubItem=2;     //这部分是将数据存入szImageBse中   2表示第3列
	item.pszText=szImageBase;
	item.cchTextMax=0x20;
	SendMessage(hListProcess,LVM_GETITEMTEXT,row,(DWORD)&item);
    
	item.mask = LVIF_TEXT;	
	
	item.pszText =szName;	//这部分是将数据新增入表				
	item.iItem = 0;			//代表行数		
	item.iSubItem = 0;		//代表列数			
	//ListView_InsertItem(hListProcess, &vitem);					
	SendMessage(hListModule, LVM_INSERTITEM,0,(DWORD)&item);
	//这里我们要注意,只有第一列的消息类型用LVM_INSERTITEM	
	
	item.pszText =szImageBase;    //这部分是将数据新增入表			
	item.iItem = 0;					
	item.iSubItem = 1;					
	//ListView_InsertItem(hListProcess, &vitem);					
	ListView_SetItem(hListModule, &item);	
	
	

}
void InitProcess(HWND hwndDlg)
{
	LV_COLUMN lv;
	HWND hListProcess;

	memset(&lv,0,sizeof(LV_COLUMN));//
	hListProcess=GetDlgItem(hwndDlg,IDC_LIST_PROCESS);
	SendMessage(hListProcess,LVM_SETEXTENDEDLISTVIEWSTYLE,LVS_EX_FULLROWSELECT,LVS_EX_FULLROWSELECT);

	lv.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;
	lv.pszText = TEXT("进程");				//列标题				
	lv.cx = 200;								//列宽
	lv.iSubItem = 0;								
	//ListView_InsertColumn(hListProcess, 0, &lv);								
	SendMessage(hListProcess,LVM_INSERTCOLUMN,0,(DWORD)&lv);								
	//第二列								
	lv.pszText = TEXT("PID");								
	lv.cx = 100;								
	lv.iSubItem = 1;								
	//ListView_InsertColumn(hListProcess, 1, &lv);								
	SendMessage(hListProcess,LVM_INSERTCOLUMN,1,(DWORD)&lv);								
	//第三列								
	lv.pszText = TEXT("镜像基址");								
	lv.cx = 100;								
	lv.iSubItem = 2;								
	ListView_InsertColumn(hListProcess, 2, &lv);								
	//第四列								
	lv.pszText = TEXT("镜像大小");								
	lv.cx = 100;								
	lv.iSubItem = 3;								
	ListView_InsertColumn(hListProcess, 3, &lv);	

	EnumProcess(hListProcess);
}
void InitModule(HWND hwndDlg)
{
	LV_COLUMN lv;
	HWND hListModule;

	memset(&lv,0,sizeof(LV_COLUMN));
	hListModule=GetDlgItem(hwndDlg,IDC_LIST_MODULE);
	SendMessage(hListModule,LVM_SETEXTENDEDLISTVIEWSTYLE,LVS_EX_FULLROWSELECT,LVS_EX_FULLROWSELECT);

	lv.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;
	lv.pszText = TEXT("模块名称");				//列标题				
	lv.cx = 300;								//列宽
	lv.iSubItem = 0;								
	//ListView_InsertColumn(hListProcess, 0, &lv);								
	SendMessage(hListModule,LVM_INSERTCOLUMN,0,(DWORD)&lv);								
	//第二列																
	lv.pszText = TEXT("模块位置");								
	lv.cx = 300;								
	lv.iSubItem = 1;								
	ListView_InsertColumn(hListModule, 2, &lv);								

	
}


BOOL CALLBACK DialogProc(									
						 HWND hwndDlg,  // handle to dialog box			
						 UINT uMsg,     // message			
						 WPARAM wParam, // first message parameter			
						 LPARAM lParam  // second message parameter			
						 )			
{									

	switch(uMsg)								
	{	
	case WM_NOTIFY:
		{
			NMHDR* pHMHRD=(NMHDR*)lParam;
			if(wParam==IDC_LIST_PROCESS && pHMHRD->code==NM_CLICK)
			{
				EnumModule(GetDlgItem(hwndDlg,IDC_LIST_PROCESS),GetDlgItem(hwndDlg,IDC_LIST_MODULE),wParam,lParam);
			}
			break;
		}
	case  WM_CLOSE:
		{
			EndDialog(hwndDlg,0);
			break;
		}
	case  WM_INITDIALOG :								
		{							
							
			InitProcess(hwndDlg);
			InitModule(hwndDlg);

			return TRUE;							
		}							
	case  WM_COMMAND :								
								
		switch (LOWORD (wParam))							
		{							
		case   IDC_BUTTON_ABOUT:							
									
							
					
			return TRUE;						
									
		case   IDC_BUTTON_EXIT:							
									
								
								
			EndDialog(hwndDlg, 0);						
									
			return TRUE;						
		}							
		break;							
    }									
									
	return FALSE;	
						
 
}
								
									
							

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
 	INITCOMMONCONTROLSEX control;
	control.dwSize=sizeof(INITCOMMONCONTROLSEX);
	control.dwICC=ICC_WIN95_CLASSES;
	InitCommonControlsEx(&control);

	DialogBox(hInstance, MAKEINTRESOURCE (IDD_DIALOG_MAIN),NULL,DialogProc);

	return 0;
}






思路:

我们此时已经创建好了对话框和通用组建

首先我们定义对于Process和Module的类型名称初始化函数

初始化类型名称时使用LV_COLUMN结构体,此结构用于创建和操作列

向列表中添加数据时,我们使用LV_ITEM结构体,指定或接收列表视图项的属性

在case WM_INITDIALOG:中调用这两个函数

我们使用WM_NOTIFY消息类型来处理对于List通用控件的操作(因为该消息类型能够传递更多参数)

WM_NOTIFY中,回调函数的两个附带参数:wParam、lParam

wParam:表示控件ID

lParam:指向一个结构体

WM_COMMAND中,回调函数的参数:wParam

wParam:低两位表示控件ID

在case WM_NOTIFY中,我们可以根据这两个参数进行操作的判断

如果符合,就调用遍历Process并在Module上显示的函数

此时我们定义函数EnumModule,需要使用的参数先不确定,后面需要时我们再添加

1.首先我们定义两个数组,用来存储待会需要保存的进程名和imageBase
2.row=SendMessage(hListProcess,LVM_GETNEXTITEM,-1,LVNI_SELECTED);告诉编译器我们操作的是哪行
3.

这个代码是将我们鼠标操作的位置的内容存入我们创建的空间中

这里通过实验发现,我们想通过改变item(行数)来选择其他行数是无法实现的,

大概猜测是前面使用了SendMessage函数的缘故,编译器知道我们所选的行数

这里我们通过iSubItem来选择不同的列数 进行存储

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值