【MFC】tab控件 仿任务管理器 枚举窗口和进程

界面和关联变量设置

创建一个基于对话框的MFC项目,给主对话框添加一个tab控件(设置关联变量 类型:CTabCtrl 名称:m_tab),添加两个子对话框(IDC_PAGE1和IDC_PAGE2),给子对话框添加一个list control控件(设置关联变量 类型:CListCtrl 名称:m_list),并将子对话框的边框属性设置为None,窗口样式设为child
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在资源视图界面右击对话框给IDC_PAGE1和IDC_PAGE2添加对话框类,类名分别为CPage1,CPage2。
在这里插入图片描述

CTabCtrl类

主窗口界面

C任务管理器Dlg类中添加CPage1和CPage2类型的变量page1和page2。
要通过这两成员来创建子窗口。不要忘记在pch.h中包含"CPage1.h","CPage2.h"头文件。
这个时候运行程序,结果如下
在这里插入图片描述

tab添加选项卡

C任务管理器Dlg类的OnInitDialog()方法中添加如下代码

m_tab.InsertItem(0, L"窗口名");
m_tab.InsertItem(1, L"进程");

这个时候运行程序tab控件上就有选项卡了
在这里插入图片描述

添加子窗口

	CRect rect;
	m_tab.GetClientRect(&rect);
	//Create函数通过资源ID和所属的父窗口对象创建一个无模式对话框
	//创建的对话框如果要显示需要通过ShowWindow(SW_SHOW)显示
	page1.Create(IDD_PAGE1, &m_tab);
	page2.Create(IDD_PAGE2, &m_tab);
	rect.top += 22;
	rect.left += 1;
	rect.right -= 3;
	rect.bottom -= 2;

	page1.MoveWindow(&rect);
	page2.MoveWindow(&rect);

	page1.ShowWindow(SW_SHOW);
	page2.ShowWindow(SW_HIDE);

获取tab控件的窗口大小并把子对话框显示在tab控件合适的位置。
运行效果如下
在这里插入图片描述
这个时候tab的选项卡还不能切换显示对应的对话框。需要通过类向导添加TCN_SELCHANGE消息的响应函数

TCN_SELCHANGE消息

在这里插入图片描述

void C任务管理器Dlg::OnSelchangeTab1(NMHDR* pNMHDR, LRESULT* pResult)
{
	// TODO: 在此添加控件通知处理程序代码
	int sel = m_tab.GetCurSel();
	switch (sel)
	{
	case 0:
		page1.ShowWindow(SW_SHOW);
		page2.ShowWindow(SW_HIDE);
		break;
	case 1:
		page2.ShowWindow(SW_SHOW);
		page1.ShowWindow(SW_HIDE);
		break;
	}

	*pResult = 0;
}

注意
这里有两个命令TCN_SELCHANGE和TCN_SELCHANGING,选项卡改变是先执行TCN_SELCHANGING,后执行TCN_SELCHANGE,在执行TCN_SELCHANGING的时候,选项卡还未最终完成切换,在这个时候m_tab.GetCurSel()得到的是原来那个选项卡。所以在进行选项卡切换的时候响应的是TCN_SELCHANGE消息

可以在TCN_SELCHANGING的响应函数中加入这段代码简单的验证一下

int sel = m_tab.GetCurSel();
CString str;
str.Format(L"%d", sel);
MessageBox(str);

运行程序发现实现了选项卡切换的功能,但是如果拉大主窗口,tab控件和子对话框的大小不会变。这个时候要响应WM_SIZE消息使主窗口在变化的时候对话框和tab控件也进行相应的变化。在子对话框中的list control控件也要如此
在这里插入图片描述

控件和子对话框适应主窗口的大小变化

	//GetSafeHwnd()用来判断...是否存在
	CRect rect;
	if (m_tab.GetSafeHwnd())
	{
		m_tab.MoveWindow(0, 0, cx, cy);
		m_tab.GetClientRect(&rect);
	}
	rect.top += 22;
	rect.left += 1;
	rect.right -= 3;
	rect.bottom -= 2;
	if (page1.GetSafeHwnd() && page2.GetSafeHwnd())
	{
		page1.MoveWindow(&rect);
		page2.MoveWindow(&rect);
	}

子对话框界面

CPage1

通过类向导添加OnInitDialog()

BOOL CPage1::OnInitDialog()
{
	CDialogEx::OnInitDialog();
	m_list.ModifyStyle(0,
		LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | 
		LVS_ALIGNLEFT | WS_VSCROLL | WS_BORDER);
	m_list.InsertColumn(0, L"序号", LVCFMT_LEFT, 50);
	m_list.InsertColumn(1, L"窗口标题", LVCFMT_LEFT,200);
	m_list.InsertColumn(2, L"窗口句柄", LVCFMT_LEFT, 200);
	m_list.InsertColumn(3, L"窗口类", LVCFMT_LEFT, 200);

	int i = 0;
	CWnd*pwnd=AfxGetMainWnd()->GetWindow(GW_HWNDFIRST);
	while (pwnd)
	{
		CString str;
		str.Format(L"%d", i + 1);
		m_list.InsertItem(i,str);

		pwnd->GetWindowTextW(str);//获取窗口标题
		m_list.SetItemText(i, 1, str);

		str.Format(L"%x", pwnd->m_hWnd);//获取窗口句柄
		m_list.SetItemText(i, 2, str);

		TCHAR name[256];
		GetClassName(pwnd->m_hWnd, name, 256);//获取窗口类名
		m_list.SetItemText(i, 3, name);

		pwnd = pwnd->GetWindow(GW_HWNDNEXT);
		i++;
	}




	return TRUE;  // return TRUE unless you set the focus to a control
}

在OnInitDialog()中实现枚举所有的窗口并显示,枚举窗口的流程是
获取主窗口(AfxGetMainWnd())-》获取和主窗口平级的第一个窗口(GetWindow(GW_HWNDFIRST))-》循环获取下一个窗口(GetWindow(GW_HWNDNEXT))

添加WM_SIZE消息响应

if (m_list.GetSafeHwnd())
		m_list.MoveWindow(0, 0, cx, cy);

在这里插入图片描述

CPage2

通过类向导添加OnInitDialog()

枚举进程要在CPage2类中加上头文件#include <tlhelp32.h>

BOOL CPage2::OnInitDialog()
{
	CDialogEx::OnInitDialog();
	m_list.ModifyStyle(0,
		LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | 
		LVS_ALIGNLEFT | WS_VSCROLL | WS_BORDER);
	m_list.InsertColumn(0, L"进程名", LVCFMT_LEFT, 300);
	m_list.InsertColumn(1, L"进程ID", LVCFMT_LEFT, 100);

	//枚举进程
	//获取当前进程的快照
	HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
	PROCESSENTRY32 pe = { 0 };
	pe.dwSize = sizeof(pe);
	//获取快照中的第一个进程
	bool b=Process32First(hSnapshot, &pe);
	int i = 0;
	while (b)
	{
		m_list.InsertItem(i, pe.szExeFile);

		DWORD id=pe.th32ProcessID;
		CString str;
		str.Format(L"%d", id);
		m_list.SetItemText(i, 1, str);
		//获取快照中的下一个进程
		b = Process32Next(hSnapshot, &pe);
		i++;
	}

	return TRUE;  // return TRUE unless you set the focus to a control

}

枚举进程的流程,获取系统快照-》获取快照中第一个进程-》循环获取下一个进程

添加WM_SIZE消息响应

void CPage2::OnSize(UINT nType, int cx, int cy)
{
	CDialogEx::OnSize(nType, cx, cy);

	if (m_list.GetSafeHwnd())
	{
		m_list.MoveWindow(0, 0, cx, cy);
	}
}

运行效果
在这里插入图片描述

源码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值