写个入门教程吧,因为我自己也算是个新手,从这个过程摸索过来知道新人是多么的不容易!
一.建立工程
设置如上面图片所述,到这一步,可以点击Finish,进入到工程。(VisualStudio2010基础上修改)
二. 进入工程
在Toolbox界面给对话框拖动MFC ShellList Control和MFC ShelTree Control,至此可以看到类似于资源管理器一样的界面出来了
此时运行工程,没有任何错误,即拖动该两个控件,不需要添加任何代码,会保留基本功能。
三. 添加关联代码
利用类向导给控件添加变量,会在该位置自动生成以下代码。
也可以手动添加代码
//在头文件中加入以下代码
CMFCShellTreeCtrl m_mfcshelltree;
CMFCShellListCtrl m_mfcshelllist;
//cpp文件
//DoDataExchange(CDataExchange* pDX)
DDX_Control(pDX, IDC_MFCSHELLLIST1, m_mfcshelllist);
DDX_Control(pDX, IDC_MFCSHELLTREE1, m_mfcshelltree);
//在OnInitDialog()加入关联
m_mfcshelltree.Expand(m_mfcshelltree.GetRootItem(), TVE_EXPAND);
m_mfcshelltree.SetRelatedList(&m_mfcshelllist);
至此,运行工程,Tree和List已经建立起关联
进行到这一步,会发现,在List这个对话框中针对文件右键没有任何针对文件的选项
m_mfcshelllist.EnableShellContextMenu(TRUE); //TRUE启用右键菜单,FALSE禁用右键菜单
增加该功能会发现右键菜单多了很多东西
//打开的效果是显示发现Tree控件显示的是之前List菜单显示的东西,即从桌面的文件夹显示转成文件
m_mfcshelltree.SetFlags((SHCONTF)(SHCONTF_FOLDERS | SHCONTF_NONFOLDERS));
四 . 文件拖动
文件拖动这一块,我搜索了很多资料,但是能实现功能的不是很多,或者是有很多代码,但是拉过来以后发现了各式各样的错误。
我的想法是想做一个从外部拖一个文件到Edit Control控件中显示其路径的操作,但是目前来说实现的不是那么回事。
目前实现的是拖到MFC这个Dialog中,然后在指定的文本框中显示路径。
直接上代码吧
//TestMFCShellListandTreeDlg.h
afx_msg void OnRclickMfcshelllist1(NMHDR *pNMHDR, LRESULT *pResult);
//TestMFCShellListandTreeDlg.cpp
BEGIN_MESSAGE_MAP(CTestMFCShellListandTreeDlg, CDialogEx)
ON_NOTIFY(NM_RCLICK, IDC_MFCSHELLLIST1,&CTestMFCShellListandTreeDlg::OnRclickMfcshelllist1)
END_MESSAGE_MAP()
//TestMFCShellListandTreeDlg.cpp
//List控件中右键获取当前链接并显示在指定Edit Control中
//右键点击获取文件路径
void CTestMFCShellListandTreeDlg::OnRclickMfcshelllist1(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
// TODO: Add your control notification handler code here
CString Filename;
for(int i=0; i<m_mfcshelllist.GetItemCount(); i++)
{
if( m_mfcshelllist.GetItemState(i, LVIS_SELECTED) == LVIS_SELECTED )
{
m_mfcshelllist.GetItemPath(Filename,i);
SetDlgItemText(IDC_MFCEDITBROWSE2,Filename); //将路径设置在指定显示框
//AfxMessageBox(Filename); //路径以对话框形式显示
}
}
*pResult = 0;
}
效果如下,点击右键可以显示文件路径,当然,也可以换成左键什么的?
测试从外部拖入文件到对话框显示路径操作,添加以下代码
//TestMFCShellListandTreeDlg.h
afx_msg void OnDropFiles(HDROP hDropInfo);
//TestMFCShellListandTreeDlg.cpp
BEGIN_MESSAGE_MAP(CTestMFCShellListandTreeDlg, CDialogEx)
ON_WM_DROPFILES()
END_MESSAGE_MAP()
//TestMFCShellListandTreeDlg.cpp
void CTestMFCShellListandTreeDlg::OnDropFiles(HDROP hDropInfo)
{
int DropCount = DragQueryFile(hDropInfo,-1,NULL,0);
for(int i=0; i<DropCount; i++)
{
WCHAR filePath[MAX_PATH];
DragQueryFile(hDropInfo, i,filePath,MAX_PATH);
SetDlgItemTextW(IDC_EDIT1,filePath);
}
DragFinish(hDropInfo);
CDialogEx::OnDropFiles(hDropInfo);
}
至此,将文件拖进Dialog,会在控件IDC_EDIT1位置显示文件路径。
另外对于对话框属性必须要设置:Behavior->Accept Files ->TRUE
至此,本次学习基本上都到这里了,还有很多功能还没有实现,等后期有学习再更新吧
本文再次编辑于20200710,接上次未解决的Edit拖动文件显示路径问题
可能理解的不全面啊
CEDIT类需要重载
即另外自己写一个派生类,继承父类CEDIT
推荐使用类向导添加类,这样会省去很多麻烦
废话不多说,上图
加载以后,系统会生成两个文件.cpp 和 .h文件
再次利用类向导,在CDragEdit类中重载他的WM_CREATE和WM_DROPFILES
//CDragEdit.h
//利用类向导添加的话该代码是自动生成的
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnDropFiles(HDROP hDropInfo);
//CDragEdit.cpp
//重载WM_CREATE
int CDragEdit::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CEdit::OnCreate(lpCreateStruct) == -1)
return -1;
DragAcceptFiles(TRUE); //其余都是类向导自己生成的,只需要添加这一句
// TODO: Add your specialized creation code here
return 0;
}
//CDragEdit.cpp
//重载WM_DROPFILES
void CDragEdit::OnDropFiles(HDROP hDropInfo)
{
// TODO: 拖拽文件的响应函数
int DropCount=DragQueryFile(hDropInfo,-1,NULL,0);//取得被拖动文件的数目
// 定义一个缓冲区来存放读取的文件名信息
TCHAR filePath[MAX_PATH];
// 循环依次取得拖动文件的File Name信息
for(int i=0;i<DropCount;i++)
{
DragQueryFile(hDropInfo,i,filePath,MAX_PATH);//获得拖曳的第i个文件的文件名
//此时 filePath已经获取到了文件路径
}
DragFinish(hDropInfo);
SetWindowText(filePath);
UpdateData(FALSE);
CEdit::OnDropFiles(hDropInfo);
}
至此,对于CEDIT类的重载基本上已经完成
想要在对话框中展现效果
比如说我有一个IDD_EDITDlg的对话框,那么只需要用类向导对Edit Control控件添加关联变量即可
在该位置添加变量,选择Type时候只能选CEDIT,先添加,然后去代码里面将该类型换成我们重载后的类型即可,别忘记添加重载时候的头文件,否则识别不到该类型.
//DialogEx 头文件
#pragma once
#include "DragEdit.h" //需要在使用的DialogEx头文件中添加
// CEditDlg dialog
class CEditDlg : public CDialogEx
{
DECLARE_DYNAMIC(CEditDlg)
public:
CEditDlg(CWnd* pParent = NULL); // standard constructor
virtual ~CEditDlg();
// Dialog Data
enum { IDD = IDD_EDITDlg };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
DECLARE_MESSAGE_MAP()
public:
CDragEdit m_DragEdit; // 更改该类型为重载后的类,我这边是CDragEdit,仅作为参考
};
//Dialog cpp文件
void CEditDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_EDIT1, m_DragEdit); //利用类向导添加该位置自动生成
}
现在可以运行你的工程,将文件拖动进来试试了!!!
文章每个字每个图都是自己写好的,代码很多借鉴了不能用,然后自己又改了改跑起来后写下了这篇文章,希望可以帮助很多新入手的朋友,互相学习。 [Damogu]