一、概念

1 MFC的入口在哪里??

CWinApp的InitInstance里面。

编写MFC程序,需要做的事情是实现一个CWinApp的派生类,然后实现一个InitInstance这个虚函数。

在InitInstance这个函数,去创建一个窗口,并将窗口的对象的指针赋值给m_pMainWnd这个指针。

需要定义一个CWinApp的派生类的全局对象。

2 MFC有几种编程模型?单文档,多文档,对话框。我们的课程主要讲解的是对话框编程。

3 如何创建一个对话框。

3.1 首先要有一个对话框资源。

3.2 有一个CDialog类的对象objDlg。

3.3.1 调用objDlg的DoModal函数创建模态对话框

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <afxwin.h>
#include <afxdialogex.h>
#include "resource.h"
class CMyApp :public CWinApp
{
public:
virtual BOOL InitInstance();
};
BOOL CMyApp::InitInstance()
{
// TODO: 在此添加专用代码和/或调用基类
CDialogEx obj(IDD_DIALOG1);
obj.DoModal();
return CWinApp::InitInstance();
}
CMyApp g_obj;

调用objDlg的Create函数创建非模态对话框

1

4 MFC程序的窗口是如何处理消息的??

4.1 MFC是通过消息映射机制去处理消息的。

​ 消息是我们自己程序员写代码处理的。我们实现窗口处理消息,实际上就是在给CDialogEx去添加功能。那么给CDialogEx增加功能,应该用什么机制实现呢?

​ 使用继承的方式。

4.2 假如你已经有了一个继承自CDialogEx的类了,怎么实现消息映射呢?

​ 4.2.1 在类的声明中加一个 DECLARE_MESSAGE_MAP()

​ 4.2.2 在类外加一个

​ BEGIN_MESSAGE_MAP(类名,父类名)

​ //。。。要处理什么消息,就添加对应消息的处理宏

​ END_MESSAGE_MAP()

二、MFC控件详解

注意:请绑定控件后操作

标准控件

按钮

在工具箱中拖拽到对话框中后,双击拖拽的控件会自动跳转到编译器生成的函数(单机响应)

在该函数了面可以写单机按钮后想要响应的消息

复选框

绑定变量(右击拖拽的控件选择添加变量,输入变量名确定即可),之后使用UpdateData函数就可以获取

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void CMy01StdControlsTestDlg::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
//1 更新
UpdateData(TRUE);
//2 测试
if (m_bCheck1==TRUE)
{
MessageBox(_T("记住密码"));
}
if (m_bCheck2 == TRUE)
{
MessageBox(_T("记住账号"));
}
if (m_bCheck3 == TRUE)
{
MessageBox(_T("自动换IP"));
}
}

单选框

注意分组

绑定的时候,只能绑定到Group属性为true的那个控件上。

1
2
3
4
5
6
7
8
void CMy01StdControlsTestDlg::OnBnClickedButton4()
{
// TODO: 在此添加控件通知处理程序代码
UpdateData(TRUE);
CString strInfo;
strInfo.Format(_T("Group1:%d Group2:%d "), m_bRadioGroup1, m_bRadioGroup2);
MessageBox(strInfo);
}

编辑框

编辑框中有一个字段是Multiline是可以多行显示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void CMy01StdControlsTestDlg::OnBnClickedButton7()
{
// TODO: 在此添加控件通知处理程序代码
CString str ;
UpdateData(TRUE);
static int nNum = 0;

str.Format(_T("测试文本%d\r\n"), nNum);
nNum++;
/*str+=m_objEdit2;
m_objEdit2 = str;*/
m_strEdit2 += str;
UpdateData(FALSE);
DWORD dwCount = m_objEdit.GetLineCount();
m_objEdit.LineScroll(dwCount);
}

静态文本框

绑定变量之后,可以方便的去更改内容。

例子:动态刷新鼠标坐标

1
2
3
4
5
6
7
8
void CMy01StdControlsTestDlg::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值

m_strStatic.Format(_T("x坐标为%d,y坐标为%d"),point.x, point.y);
UpdateData(FALSE);
CDialogEx::OnMouseMove(nFlags, point);
}

图片控件与计时器

计时器:能够让咱们程序,每间隔一个固定的时间,去处理一个事情。

SDK:响应这个WM_TIMER消息 SetTimer()

MFC: 在窗口初始化的时候,去调用一下SetTimer这个函数

要手动在initDialog初始化函数中设置计时器

1
2
3
4
5
6
7
// 设置计时器
SetTimer(
1, //自定义的Timer的ID
500, //间隔的毫秒数
NULL //回调函数,如果设置了,每隔500毫秒调这个回调函数
//如果没有设置,就是给主窗口发WM_TIMER消息
);

响应计时器OnTimer函数可在类向导中添加

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
void CMy01StdControlsTestDlg::OnTimer(UINT_PTR nIDEvent)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
if (nIDEvent == 1)
{
CString str;
UpdateData(TRUE);
static int nNum = 0;
str.Format(_T("测试文本%d\r\n"), nNum);
nNum++;
/*str+=m_objEdit2;
m_objEdit2 = str;*/
m_strEdit2 += str;
UpdateData(FALSE);
DWORD dwCount = m_objEdit.GetLineCount();
m_objEdit.LineScroll(dwCount);
}
else if(nIDEvent == 2)
{
static BOOL bSign = 0;
//1 加载位图资源
CBitmap Bit1;
Bit1.LoadBitmapW(IDB_BITMAP1);
CBitmap Bit2;
Bit2.LoadBitmapW(IDB_BITMAP2);
if (bSign == 0)
{
m_objPic.SetBitmap(Bit1);
bSign = 1;
}
else
{
m_objPic.SetBitmap(Bit2);
bSign = 0;
}
}
CDialogEx::OnTimer(nIDEvent);
}

下拉框

1
2
3
4
5
6
7
8
9
10

static int nNum = 0;
CString str;
str.Format(L"测试文本%d", nNum);
nNum++;
m_strComBox1 = str;
m_ComBox1.AddString(str);

UpdateData(FALSE);

菜单

下拉菜单

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
void CMy03MenuDlg::OnRButtonDown(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值

//1 需要将客户区坐标转换为屏幕坐标

ClientToScreen(&point);


//2 需要载入菜单资源
CMenu obj;

obj.LoadMenuW(IDR_MENU2);

//3 获取一个下拉菜单
CMenu * pSubMenu1 = obj.GetSubMenu(0);
pSubMenu1->AppendMenuW(MF_ENABLED, 32783, _T("添加线程"));
//4 弹出菜单
pSubMenu1->TrackPopupMenu(TPM_LEFTALIGN, point.x, point.y, this);

CDialogEx::OnRButtonDown(nFlags, point);
}

弹出菜单

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
//右击列表框(进程选项下的列表框)弹出菜单
void CMyDlg1::OnRclickList1(NMHDR* pNMHDR, LRESULT* pResult)
{
LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
// TODO: 在此添加控件通知处理程序代码;

// 需要载入菜单资源
CMenu obj;
obj.LoadMenuW(IDR_MENU1);
//坐标转换
POINT pt = { pNMItemActivate->ptAction.x,pNMItemActivate->ptAction.y };
ClientToScreen(&pt);

// 获取一个下拉菜单
CMenu* pSubMenu1 = obj.GetSubMenu(0);

// 弹出菜单
pSubMenu1->TrackPopupMenu(TPM_LEFTALIGN,pt.x, pt.y, this);
//获取ID(选择的进程)
int item = pNMItemActivate->iItem; //LPNMITEMACTIVATF 这个结构体 iItem 有列表框记录的信息
CString strPid = m_ProcessList.GetItemText(item, 1); //获取文本框
nID = _wtoi(strPid);//转换为整型并保存
const char* cs = { "右击了进程!!!" };
SendDiyMessage(cs);
*pResult = 0;
}

//进程列表框下右击响应菜单
void CMyDlg1::OnRangeCmds1(UINT nMenuID)
{
const char* cs;
// 使用 PID 获取到进程的句柄
HANDLE Process = OpenProcess(PROCESS_TERMINATE, FALSE, nID);
switch (nMenuID)
{
case ID_32771://创建进程

break;
case ID_32772://结束进程
// 通过句柄来结束一个指定进程
TerminateProcess(Process, -1);
cs = { "结束了一个进程!!!" };
SendDiyMessage(cs);
break;
default:
break;
}
}

通用控件(复杂控件)

滑块

1
2
3
4
5
6
7
8
9
10
11
12
//移动滑块把值显示在下方静态文本
void CMFCAppTestDlg::OnNMCustomdrawSlider1(NMHDR* pNMHDR, LRESULT* pResult)
{
LPNMCUSTOMDRAW pNMCD = reinterpret_cast<LPNMCUSTOMDRAW>(pNMHDR);
// TODO: 在此添加控件通知处理程序代码
UpdateData(TRUE);
CString str;
str.Format(L"滑块的值为:%d", m_Huakuai1);
m_strStaticText2.SetString(str);
UpdateData(FALSE);
//*pResult = 0;
}

进度条

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//增加进度条进度
void CMFCAppTestDlg::OnBnClickedButton6()
{
// TODO: 在此添加控件通知处理程序代码

static int addProess = 0;
addProess=m_objProgress2.GetPos();
addProess += 10;
m_objProgress2.SetPos(addProess);
if (addProess == 100)
addProess = 0;
}

//减少进度条进度
void CMFCAppTestDlg::OnBnClickedButton7()
{
// TODO: 在此添加控件通知处理程序代码
UpdateData(TRUE);
static int delProcess = 0;
delProcess=m_objProgress2.GetPos();
delProcess -= 10;
m_objProgress2.SetPos(delProcess);

}

列表框

1
2
3
4
5
6
7
8
9
10
11
12
13
//初始化列表框的列
//初始化列表框LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_CHECKBOXES
m_objCtrlList1.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_CHECKBOXES);//更改风格
m_objCtrlList1.InsertColumn(0, L"姓名", 0, 90);
m_objCtrlList1.InsertColumn(1, L"年龄", 0, 90);
m_objCtrlList1.InsertColumn(2, L"身高", 0, 90);
m_objCtrlList1.InsertColumn(3, L"体重", 0, 90);
//添加行
m_objCtrlList1.InsertItem( 0, L"");//
m_objCtrlList1.SetItemText(0,0,L"小米");
m_objCtrlList1.SetItemText(0, 1, L"14");
m_objCtrlList1.SetItemText(0, 2, L"122");
m_objCtrlList1.SetItemText(0, 3, L"23");

Tab控件

封装函数拿走

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
void CMyTabCtrl::InitTab(int nCount, ...)
{
va_list vl;
va_start(vl, nCount);

for (int i = 0; i < nCount; i++)
{
//1 获取这一个选项,需要的数据
wchar_t* szTabItemName = va_arg(vl, wchar_t*);
CDialogEx* pDlg = va_arg(vl, CDialogEx*);
DWORD dwId = va_arg(vl, DWORD);
//2 创建选项,创建子窗口
InsertItem(i, szTabItemName);
pDlg->Create(dwId, this);
//3 将子窗口移动合适的位置上
CRect rc = {};
GetClientRect(&rc);
//4 将矩形框,缩小一下,能够把Tab的表头 显示出来
rc.DeflateRect(1, 23, 1, 1);
//5 移动
pDlg->MoveWindow(rc);
m_vecDlg.push_back(pDlg);
}

m_vecDlg[0]->ShowWindow(SW_SHOW);
va_end(vl);
}



//初始化tab控件中的窗口
m_MainTabCtrl.InitTab(4, L"进程", new CMyDlg1(), IDD_DIALOG1,
L"VS清理", new CMyDlg2(), IDD_DIALOG2,
L"窗口", new CMyDlg3(),IDD_DIALOGWND,
L"计算机总览", new CMyTreeDlg(), IDD_DIALOGTREE
);

树控件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
HTREEITEM hBj = m_objTree.InsertItem(_T("北京"));//添加一个信息之后,会得到此结点的句柄
m_objTree.InsertItem(_T("昌平区"), hBj);
m_objTree.InsertItem(_T("朝阳区"), hBj);
m_objTree.InsertItem(_T("海淀区"), hBj);
m_objTree.InsertItem(_T("东城区"), hBj);
m_objTree.InsertItem(_T("西城区"), hBj);


HTREEITEM hTj = m_objTree.InsertItem(_T("天津"));
HTREEITEM hDl = m_objTree.InsertItem(_T("东丽区"), hTj);
m_objTree.InsertItem(_T("天安象屿智慧城"), hDl);

m_objTree.InsertItem(_T("南开区"), hTj);
m_objTree.InsertItem(_T("河西区"), hTj);
m_objTree.InsertItem(_T("河东区"), hTj);
m_objTree.InsertItem(_T("北辰区"), hTj);
m_objTree.InsertItem(_T("和平区"), hTj);

HTREEITEM hHb = m_objTree.InsertItem(_T("河北"));
m_objTree.InsertItem(_T("石家庄"), hHb);
m_objTree.InsertItem(_T("廊坊"), hHb);
m_objTree.InsertItem(_T("雄安新区"), hHb);

使用案例-遍历硬盘

.h头文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include <vector>
#include <string.h>
#include "CMyFilePopDlg.h"
using std::vector;
// CMyTreeDlg 对话框
typedef struct _MYDISKHEADINFO
{
CString csDiskHead; //盘符
UINT uAllSize; //盘符总大小
UINT uAbouleSize; //盘符可用大小
UINT uUsed; //已经用了多少
CString attribute; //盘符属性

}MyDiskHeadInfo,*pDisk;


class CMyTreeDlg : public CDialogEx
{
DECLARE_DYNAMIC(CMyTreeDlg)

public:
CMyTreeDlg(CWnd* pParent = nullptr); // 标准构造函数
virtual ~CMyTreeDlg();

// 对话框数据
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_DIALOGTREE };
#endif

protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持

DECLARE_MESSAGE_MAP()
public:
CTreeCtrl m_objTree;

CImageList m_ImageList;
vector<_MYDISKHEADINFO *>Disk;

virtual BOOL OnInitDialog();
void GetDistHeadInfo();//遍历盘符
HTREEITEM m_Root;
CString GetFullPath(HTREEITEM hCurrent);
void AddSubDir(HTREEITEM hParent);
;
afx_msg void OnDblclkTree1(NMHDR* pNMHDR, LRESULT* pResult);

afx_msg void OnSelchangedTree1(NMHDR* pNMHDR, LRESULT* pResult);
protected:
CListCtrl m_objList;
HTREEITEM hOldTree;//记录最后一次的树节点
CMyFilePopDlg m_objFilePopDlg;
public:
afx_msg void OnDblclkList1(NMHDR* pNMHDR, LRESULT* pResult);
};

.cpp文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
BOOL CMyTreeDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();



DWORD dwStyle = GetWindowLong(m_objTree.m_hWnd, GWL_STYLE);
dwStyle |= TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT;
SetWindowLong(m_objTree.m_hWnd, GWL_STYLE, dwStyle);
////HICON hIcon = theApp.LoadIcon(IDB_BITMAP1); //图标句柄
//图标添加到图像序列
GetDistHeadInfo();

m_Root = m_objTree.InsertItem(L"我的电脑");
for (unsigned int i = 0; i < Disk.size(); i++)
{
HTREEITEM hDiskHead = m_objTree.InsertItem(Disk[i]->csDiskHead, m_Root);
}

//HICON hIcon = LoadIcon(AfxGetApp()->m_hInstance, MAKEINTRESOURCE(IDR_MAINFRAME));//加载本地自己的图标

//m_ImageList.Add(hIcon);
//初始化列表框LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_CHECKBOXES
m_objList.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_CHECKBOXES);//更改风格
m_objList.InsertColumn(0, L"文件名", 0, 300);
m_objList.InsertColumn(1, L"文件大小", 0, 100);
m_objList.InsertColumn(2, L"文件大小", 0, 100);
m_objList.InsertColumn(3, L"文件大小", 0, 100);
return TRUE;
}


//遍历盘符
void CMyTreeDlg::GetDistHeadInfo()
{

//1. 获取驱动器名称
TCHAR buf[100] = {};
TCHAR* pTemp = buf;

DWORD 总容量;
DWORD 空闲容量;
GetLogicalDriveStrings(100, buf);
// 把语言设置为中文
setlocale(LC_ALL, "chs");
int Flag = 0;


while (pTemp[0] != 0)
{
MyDiskHeadInfo* pds = new MyDiskHeadInfo;
//2. 获取驱动器类型
DWORD dwType = GetDriveType(pTemp);
switch (dwType)
{
case DRIVE_REMOVABLE:
//..ListView_SetItemText(hListCtrl, Flag, 1, (TCHAR*)_T("可移动设备"));
pds->attribute = L"可移动设备";

break;
case DRIVE_FIXED:
//ListView_SetItemText(hListCtrl, Flag, 1, (TCHAR*)_T("硬盘"));
pds->attribute = L"硬盘";

break;
case DRIVE_REMOTE:
//ListView_SetItemText(hListCtrl, Flag, 1, (TCHAR*)_T("远程设备"));
pds->attribute = L"远程设备";

break;
case DRIVE_CDROM:
// ListView_SetItemText(hListCtrl, Flag, 1, (TCHAR*)_T("光驱"));
pds->attribute = L"光驱";

break;
default:
break;
}
//3. 驱动器的空间信息
DWORD 每簇的扇区数量 = 0;
DWORD 每个扇区的容量 = 0;
DWORD 空闲簇的总量 = 0;
DWORD 全部簇的总量 = 0;
GetDiskFreeSpace(pTemp,
&每簇的扇区数量,
&每个扇区的容量,
&空闲簇的总量,
&全部簇的总量
);

pds->uAllSize = (((全部簇的总量 / 1024.0) * 每簇的扇区数量 * 每个扇区的容量) / 1024) / 1024;
pds->uAbouleSize = (((空闲簇的总量 / 1024.0) * 每簇的扇区数量 * 每个扇区的容量) / 1024) / 1024;
pds->uUsed = pds->uAllSize - pds->uAbouleSize;


pds->csDiskHead = pTemp;
Disk.push_back(pds);
pTemp += wcslen(buf) + 1;

Flag++;

}

}



//函数功能:获取树项目全根路径
CString CMyTreeDlg::GetFullPath(HTREEITEM hCurrent)
{
CString strTemp;
CString strReturn = L"";
while (hCurrent != m_Root)
{
strTemp = m_objTree.GetItemText(hCurrent); //检索列表中项目文字
if (strTemp.Right(1) != "\\")
strTemp += "\\";
strReturn = strTemp + strReturn;
hCurrent = m_objTree.GetParentItem(hCurrent); //返回父项目句柄
}
return strReturn;
}


//函数功能:添加子目录
void CMyTreeDlg::AddSubDir(HTREEITEM hParent)
{
CString strPath = GetFullPath(hParent); //获取全路径
if (strPath.Right(1) != "\\")
strPath += "\\";
strPath += "*.*";
CFileFind file;
BOOL bContinue = file.FindFile(strPath); //查找包含字符串的文件
while (bContinue)
{
bContinue = file.FindNextFile(); //查找下一个文件
if (file.IsDirectory() && !file.IsDots())
m_objTree.InsertItem(file.GetFileName(), hParent);
}
}



//双击树控件节点响应
void CMyTreeDlg::OnDblclkTree1(NMHDR* pNMHDR, LRESULT* pResult)
{

//LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);
//LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
CPoint point;
GetCursorPos(&point); //获取鼠标点击的坐标
m_objTree.ScreenToClient(&point); //屏幕坐标转为客户区坐标
UINT uFlags = 0;
HTREEITEM hCurItem;
hCurItem = m_objTree.HitTest(point, &uFlags);//获得当前点击节点的ITEM
hOldTree = hCurItem;

if (hCurItem == m_Root)
{
return;
}
AddSubDir(hCurItem);

*pResult = 0;
}

//遍历文件并插入到列表
void CMyTreeDlg::OnSelchangedTree1(NMHDR* pNMHDR, LRESULT* pResult)
{
// LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);
// TODO: 在此添加控件通知处理程序代码
m_objList.DeleteAllItems();
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
TVITEM item = pNMTreeView->itemNew;
if (item.hItem == m_Root)
return;
CString str = GetFullPath(item.hItem);
if (str.Right(1) != "\\")
str += "\\";
str += "*.*";
CFileFind file;
BOOL bContinue = file.FindFile(str);
while (bContinue)
{
bContinue = file.FindNextFile();
if (!file.IsDirectory() && !file.IsDots())
{

m_objList.InsertItem(0,file.GetFileName());

}
}
*pResult = 0;
}



void CMyTreeDlg::OnDblclkList1(NMHDR* pNMHDR, LRESULT* pResult)
{
LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
// TODO: 在此添加控件通知处理程序代码
int item = pNMItemActivate->iItem; //LPNMITEMACTIVATF 这个结构体 iItem 有列表框记录的信息
CString strFileName = m_objList.GetItemText(item, 0);


if (strFileName.GetLength())//在这里直接弹Messagebox不知道为什么只要为空就会卡死,所以为空选择跳过
{
CString cs;
cs.Format(L"%s%s", GetFullPath(hOldTree), strFileName);
MessageBox(cs);
}


//CMyFilePopDlg* d_pm = new CMyFilePopDlg;
//d_pm->Create(IDD_DIALOG3, this);
//d_pm->ShowWindow(SW_SHOW);
//
//WCHAR* pBuf = T2W((LPTSTR)(LPCTSTR)cs);
//m_objFilePopDlg.EnumFileInfo(pBuf);


*pResult = 0;
}

工具栏

添加资源后创建

1
2
3
4
5
6
7
8
9
10
11

//1. 创建工具栏
m_objToolBar.Create(this);

//2. 载入资源
m_objToolBar.LoadToolBar(IDR_TOOLBAR1);
//3. 显示出来
RepositionBars(AFX_IDW_CONTROLBAR_FIRST, AFX_IDW_CONTROLBAR_LAST, 0);


return TRUE; // 除非将焦点设置到控件,否则返回 TRUE

响应工具栏消息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//消息映射中
//ON_COMMAND_RANGE(ID头值,ID尾值,&响应的回调函数);
ON_COMMAND_RANGE(ID_BUTTON32771,ID_BUTTON32774,&CMToolBarDlg::OnRangeCmds);


//回调函数
void CMToolBarDlg::OnRangeCmds(UINT nID)
{
switch(nID)
{
case ID_BUTTON32771:
break;
case ID_BUTTON32772:
break;
case ID_BUTTON32773:
break;
case ID_BUTTON32774:
break;
default:
break;
}
}

窗口的枚举与图标

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
//枚举窗口
BOOL CALLBACK EnumWindowsProc(HWND hWnd ,LPARAM lParam)
{
static int i = 0;
CMyDlg3* t = (CMyDlg3*)lParam;
TCHAR buff[200];
GetWindowText(hWnd, buff, 200);

//HICON hIcon = (HICON)GetClassLongPtr(hWnd, GCLP_HICON);
static HICON hIcon = LoadIcon(AfxGetApp()->m_hInstance, MAKEINTRESOURCE(IDR_MAINFRAME));//加载本地自己的图标

if (hIcon != 0)
{
t->m_vecIcon.push_back(hIcon);
}

if (IsWindowVisible(hWnd) == TRUE && wcslen(buff) != 0)
{
CString cs;
cs.Format(L"%s", buff);
t->m_objWndList.InsertItem(i, cs,i);
}
i++;
return TRUE;
}

//初始化中 OnInitDialog()

EnumWindows(EnumWindowsProc, (LPARAM)this);
m_objIma.Create(32, 32, ILC_COLOR32, 4, 1);
//3 将咱们的图标都加入进去

for (int i = 0; i < m_vecIcon.size(); i++)
{
m_objIma.Add(m_vecIcon[i]);
}
//4 需要将列表框和图标列表关联到一起
m_objWndList.SetImageList(&m_objIma, LVSIL_SMALL);