效果演示
当前这个例程通过从CEdit派生一个CDragEdit,实现文件名或者文件夹拖放到编辑框,参见下图。
上位机MFC文件夹拖拽编辑框实例
默认单选框选中识别文件,可 以将文件拖拽到编辑框中,
也可以选择识别文件夹,将文件夹拖拽到编辑框中,
这样编辑框可以识别出文件或文件夹名称,
使用获得的名称进行下一步处理。
当然在实际应用中,可以将两功能融合为自动识别拖拽类型。
涉及的文件代码可以在帖子尾部复制使用,或下载例程学习:
实现过程。
1.新建一基于对话框工程,将根目录两文件DROPEDIT.CPP,DROPEDIT.H复制到工程根目录。
并导入到工程中,这样工程中就多了个集成类CDropEdit
上位机MFC文件夹拖拽编辑框实例
2.在主对话框中包含类的头文件,并添加一编辑框控件,如例程界面,添加类实例
#include "DropEdit.h"
CDropEdit m_Edit;
编辑框控件属性,扩展样式设置,开启文件拖拽功能。
如例程界面,再添加两单选框,双击添加其点击函数,并初始化插件
- m_Edit.SetUseDir(FALSE);
- CheckRadioButton(IDC_RADIO1, IDC_RADIO2, IDC_RADIO1);
- void CCTestDlg::OnRadio1() //识别文件
- {
- m_Edit.SetUseDir(FALSE);
- m_Edit.SetWindowText("");
- }
- void CCTestDlg::OnRadio2() //识别文件夹
- {
- m_Edit.SetUseDir(TRUE);
- m_Edit.SetWindowText("");
- }
复制代码
3.编译运行程序,这样就可以将文件,或文件夹拖拽到编辑框中识别了。
下面是集成类两文件源代码
- #if !defined(AFX_DROPEDIT_H__1D8BBDC1_784C_11D1_8159_444553540000__INCLUDED_)
- #define AFX_DROPEDIT_H__1D8BBDC1_784C_11D1_8159_444553540000__INCLUDED_
- #if _MSC_VER >= 1000
- #pragma once
- #endif // _MSC_VER >= 1000
- // DropEdit.h : header file
- //
- #include <shlobj.h>
- /////////////////////////////////////////////////////////////////////////////
- // CDropEdit window
- class CDropEdit : public CEdit
- {
- // Construction
- public:
- CDropEdit();
- // Attributes
- public:
- // Operations
- public:
- inline void SetUseDir(BOOL u) {m_bUseDir=u;}
- inline BOOL IsUseDir() const {return m_bUseDir;}
- // Overrides
- // ClassWizard generated virtual function overrides
- //{{AFX_VIRTUAL(CDropEdit)
- //}}AFX_VIRTUAL
- // Implementation
- public:
- virtual ~CDropEdit();
- protected:
- CString ExpandShortcut(CString &inFile);
- // Generated message map functions
- protected:
- //{{AFX_MSG(CDropEdit)
- afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
- afx_msg void OnDropFiles(HDROP dropInfo);
- //}}AFX_MSG
- DECLARE_MESSAGE_MAP()
- BOOL m_bUseDir;
- };
- /////////////////////////////////////////////////////////////////////////////
- //{{AFX_INSERT_LOCATION}}
- // Microsoft Developer Studio will insert additional declarations immediately before the previous line.
- #endif // !defined(AFX_DROPEDIT_H__1D8BBDC1_784C_11D1_8159_444553540000__INCLUDED_)
复制代码
- #include "stdafx.h"
- #include "resource.h"
- #include "DropEdit.h"
- #include <sys/types.h>
- #include <sys/stat.h>
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- /////////////////////////////////////////////////////////////////////////////
- // CDropEdit
- CDropEdit::CDropEdit()
- {
- m_bUseDir=FALSE;
- }
- CDropEdit::~CDropEdit()
- {
- }
- BEGIN_MESSAGE_MAP(CDropEdit, CEdit)
- //{{AFX_MSG_MAP(CDropEdit)
- ON_WM_CREATE()
- ON_WM_DROPFILES()
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
- /////////////////////////////////////////////////////////////////////////////
- // CDropEdit message handlers
- int CDropEdit::OnCreate(LPCREATESTRUCT lpCreateStruct)
- {
- if (CEdit::OnCreate(lpCreateStruct) == -1)
- return -1;
-
- DragAcceptFiles(TRUE);
-
- return 0;
- }
- //
- // handle WM_DROPFILES
- //
- void CDropEdit::OnDropFiles(HDROP dropInfo)
- {
- // Get the number of pathnames that have been dropped
- WORD wNumFilesDropped = DragQueryFile(dropInfo, -1, NULL, 0);
- CString firstFile="";
- // get all file names. but we'll only need the first one.
- for (WORD x = 0 ; x < wNumFilesDropped; x++) {
- // Get the number of bytes required by the file's full pathname
- WORD wPathnameSize = DragQueryFile(dropInfo, x, NULL, 0);
- // Allocate memory to contain full pathname & zero byte
- char * npszFile = (char *) LocalAlloc(LPTR, wPathnameSize += 1);
- // If not enough memory, skip this one
- if (npszFile == NULL) continue;
- // Copy the pathname into the buffer
- DragQueryFile(dropInfo, x, npszFile, wPathnameSize);
- // we only care about the first
- if (firstFile=="")
- firstFile=npszFile;
- // clean up
- LocalFree(npszFile);
- }
- // Free the memory block containing the dropped-file information
- DragFinish(dropInfo);
- // if this was a shortcut, we need to expand it to the target path
- CString expandedFile = ExpandShortcut(firstFile);
- // if that worked, we should have a real file name
- if (expandedFile!="")
- firstFile=expandedFile;
-
- struct _stat buf;
- // get some info about that file
- int result = _stat( firstFile, &buf );
- if( result == 0 ) {
- // verify that we have a dir (if we want dirs)
- if ((buf.st_mode & _S_IFDIR) == _S_IFDIR) {
- if (m_bUseDir)
- SetWindowText(firstFile);
- // verify that we have a file (if we want files)
- } else if ((buf.st_mode & _S_IFREG) == _S_IFREG) {
- if (!m_bUseDir)
- SetWindowText(firstFile);
- }
- }
- }
- //////////////////////////////////////////////////////////////////
- // use IShellLink to expand the shortcut
- // returns the expanded file, or "" on error
- //
- // original code was part of CShortcut
- // 1996 by Rob Warner
- // rhwarner@southeast.net
- // http://users.southeast.net/~rhwarner
- CString CDropEdit::ExpandShortcut(CString &inFile)
- {
- CString outFile = "";
- // Make sure we have a path
- ASSERT(inFile != _T(""));
- IShellLink* psl;
- HRESULT hres;
- LPTSTR lpsz = inFile.GetBuffer(MAX_PATH);
- // Create instance for shell link
- hres = ::CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
- IID_IShellLink, (LPVOID*) &psl);
- if (SUCCEEDED(hres))
- {
- // Get a pointer to the persist file interface
- IPersistFile* ppf;
- hres = psl->QueryInterface(IID_IPersistFile, (LPVOID*) &ppf);
- if (SUCCEEDED(hres))
- {
- // Make sure it's ANSI
- WORD wsz[MAX_PATH];
- ::MultiByteToWideChar(CP_ACP, 0, lpsz, -1, wsz, MAX_PATH);
- // Load shortcut
- 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();
- // if this fails, outFile == ""
- return outFile;
- }
复制代码
|