用MFC实现文件拖放到编辑框
如图1和图2所示,这是两个支持将文件拖放到编辑框功能的对话框应用,这是一种实用性很强的功能,细心的读者还会发现这两个对话框是有一些区别的,其实这两个对话框无论是程序结构还是功能实现难易程度都有很大的区别。就从MFC编程角度看,这两个程序都很精彩,现分别介绍给读者。考虑到读者应该是比较熟练地使用VC++的,我对基本问题的实现只一带而过。
如图1是用CFormView实现的对话框,这是一个文档-视图结构的应用程序,它有一个主框架。
(一)运行AppWizard产生名为Drag1的项目
单击Visual C++File菜单中的New命令,选择Project选项中的MFC AppWizard(exe)图标,键入Drag1作为项目名字。步骤1中选择Single Document按钮,步骤4中取消工具栏、打印等设置,步骤6中将基类CView改成CFormView,这一步是必须的,否则就做不到支持文件拖放功能。其余均采用默认设置项。
(二)我们不需要显示菜单,因此,利用菜单编辑器将全部菜单去掉。
(三)利用对话框编辑器来修改IDD_DRAG1_FROM对话框,如图1示样式。
(四)利用ClassWizard为CDrag1View类加入消息控制
单击View菜单中的ClassWizard命令,在MFC ClassWizard的Message框中选择OnUpDate,并单击Add Function按钮。
(五)类似第4步,利用ClassWizard为CMainFrame类加入OnDropFile函数。这一步就使程序具有了文件拖放功能。
(六)编辑工程
1、显示文件名
void CDrag1View::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint)
{
// TODO: Add your specialized code here and/or call the base class
CDragDoc *pDoc=GetDocument();
SetDlgItemText(IDC_EDIT1,pDoc->GetPathName());
}
2、实现拖放功能
BOOL CDrag1App::InitInstance()
{
……
// Enable drag/drop open
m_pMainWnd->DragAcceptFiles();
return TRUE;
}
好了,就这么简单,你几乎没做什么代码输入工作程序就完成了。可如果我们现在建立一个基于对话框的应用程序,由于没有了主框架结构,这时要实现同样的功能,上述方法是行不通的,只好自己来做了。
二、基于对话框的应用
(一)建立基于对话框的应用程序Drag2
从File菜单选择New对话,键入Drag2作为项目名并单击OK。在第一步中选中Dialog Based单选按钮,其它接受所有默认选项。
(二)利用对话框编辑器来修改IDD_DRAG2_GIALOG对话框,如图2示样式。注意,property中选“Accept Files”。
(三)利用ClassWizard创建CDropEdit新类,然后再添加OnCreate、OnDropFiles函数,并编辑如下:
1、DropEdit.h文件
BOOL m_bUseDir;
……
2、DropEdit.cpp文件
……
#include <sys/types.h>
#include <sys/stat.h>
CDropEdit::CDropEdit()
{
m_bUseDir=FALSE;
}
……
int CDropEdit::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CEdit::OnCreate(lpCreateStruct) == -1)
return -1;
DragAcceptFiles(TRUE);
return 0;
}
void CDropEdit::OnDropFiles(HDROP dropInfo)
{
WORD wNumFilesDropped = DragQueryFile(dropInfo, -1, NULL, 0);
CString firstFile=”";
for (WORD x = 0 ; x < wNumFilesDropped; x++) {
WORD wPathnameSize = DragQueryFile(dropInfo, x, NULL, 0);
char * npszFile = (char *) LocalAlloc(LPTR, wPathnameSize += 1);
if (npszFile == NULL) continue;
DragQueryFile(dropInfo, x, npszFile, wPathnameSize);
if (firstFile==”")
firstFile=npszFile;
LocalFree(npszFile);
}
DragFinish(dropInfo);
CString expandedFile = ExpandShortcut(firstFile);
if (expandedFile!=”")
firstFile=expandedFile;
struct _stat buf;
int result = _stat( firstFile, &buf );
if( result == 0 ) {
if ((buf.st_mode & _S_IFDIR) == _S_IFDIR) {
if (m_bUseDir)
SetWindowText(firstFile);
} else if ((buf.st_mode & _S_IFREG) == _S_IFREG) {
if (!m_bUseDir)
SetWindowText(firstFile);
}
}
}
CString CDropEdit::ExpandShortcut(CString &inFile)
{
CString outFile = “”;
ASSERT(inFile != _T(“”));
IShellLink* psl;
HRESULT hres;
LPTSTR lpsz = inFile.GetBuffer(MAX_PATH);
hres = ::CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
IID_IShellLink, (LPVOID*) &psl);
if (SUCCEEDED(hres))
{
IPersistFile* ppf;
hres = psl->QueryInterface(IID_IPersistFile, (LPVOID*) &ppf);
if (SUCCEEDED(hres))
{
WORD wsz[MAX_PATH];
::MultiByteToWideChar(CP_ACP, 0, lpsz, -1, wsz, MAX_PATH);
hres = ppf->Load(wsz, STGM_READ);
if (SUCCEEDED(hres)) {
WIN32_FIND_DATA wfd;
// find the path from that
HRESULT hres = psl->GetPath(outFile.GetBuffer(MAX_PATH),
MAX_PATH,
&wfd,
SLGP_UNCPRIORITY);
outFile.ReleaseBuffer();
}
ppf->Release();
}
psl->Release();
}
inFile.ReleaseBuffer();
return outFile;
}
(四)将#include <afxole.h>加到stdafx.h文件中
(五)在CDrag2App的InitInstance中加入
::CoInitialize(NULL);
(六)在CDrag2App的ExitInstance中加入
::CoUninitialize();
(七)将#include “DropEdit.h”加入Drag2Dlg.h中
(八)在CDrag2Dlg构造函数中加入
CdropEdit m_dropEdit;
在OnInitDialog中加入
m_dropEdit.SubclassDlgItem(IDC__EDIT1, this);
现在大功告成,可以运行程序了,本程序拖动文件时必须将文件拖到对话框的编辑框中,这一点不同于Drag1应用只要将文件拖到对话框中即行,有读者能对此改进的请赐教。
本文程序均在VC6.0下通过。
>> 本文固定链接: http://www.vcgood.com/archives/474