让你的控件也具有拖拽(drag-and-drop)功能
来源:互联网 发布:卖数据是什么意思啊 编辑:程序博客网 时间:2024/04/29 22:04
现在有很多软件都支持拖拽功能,就是用鼠标拖着文件放到软件窗口中某个位置,软件就可以做出相应的反应。比如,Windows自带的播放软件Windows Media Player,你可以拖着一个媒体文件放到它的主窗口中,它就会开始播放这个文件。
怎么让自己的软件也有这个功能呢?
其实,并不是很难,只要让你需要有拖拽功能的控件响应WM_DROPFILES消息就行了。下面以Edit控件和ListBox控件为例子来说明。
首先,从CEdit继承,自定义一个Edit控件。在头文件添加如下的消息响应函数:
afx_msg void OnDropFiles(HDROP hDropInfo);
然后,在cpp文件中的消息映射中添加:
ON_WM_DROPFILES()
最后,在cpp文件中添加OnDropFiles函数的实现,对拖拽的文件进行处理。下面是完整的代码:
// lxEdit.h
class ClxEdit : public CEdit
{
DECLARE_DYNAMIC(ClxEdit)
public:
ClxEdit();
virtual ~ClxEdit();
afx_msg void OnDropFiles(HDROP hDropInfo);
protected:
DECLARE_MESSAGE_MAP()
};
// lxEdit.cpp
#include "stdafx.h"
#include "lxEdit.h"
IMPLEMENT_DYNAMIC(ClxEdit, CEdit)
ClxEdit::ClxEdit()
{ }
ClxEdit::~ClxEdit()
{ }
BEGIN_MESSAGE_MAP(ClxEdit, CEdit)
ON_WM_DROPFILES()
END_MESSAGE_MAP()
void ClxEdit::OnDropFiles(HDROP hDropInfo)
{
// 被拖拽的文件的文件名
char szFileName[MAX_PATH + 1];
// 得到被拖拽的文件名
DragQueryFile(hDropInfo, 0, szFileName, MAX_PATH);
// 把文件名显示出来
SetWindowText(szFileName);
CEdit::OnDropFiles(hDropInfo);
}
class ClxEdit : public CEdit
{
DECLARE_DYNAMIC(ClxEdit)
public:
ClxEdit();
virtual ~ClxEdit();
afx_msg void OnDropFiles(HDROP hDropInfo);
protected:
DECLARE_MESSAGE_MAP()
};
// lxEdit.cpp
#include "stdafx.h"
#include "lxEdit.h"
IMPLEMENT_DYNAMIC(ClxEdit, CEdit)
ClxEdit::ClxEdit()
{ }
ClxEdit::~ClxEdit()
{ }
BEGIN_MESSAGE_MAP(ClxEdit, CEdit)
ON_WM_DROPFILES()
END_MESSAGE_MAP()
void ClxEdit::OnDropFiles(HDROP hDropInfo)
{
// 被拖拽的文件的文件名
char szFileName[MAX_PATH + 1];
// 得到被拖拽的文件名
DragQueryFile(hDropInfo, 0, szFileName, MAX_PATH);
// 把文件名显示出来
SetWindowText(szFileName);
CEdit::OnDropFiles(hDropInfo);
}
可以看到,在上面的代码中,得到拖拽文件名的是函数DragQueryFile。这是Windows提供的一个API函数,用来得到一次成功的拖拽操作中的文件名。下面是该函数的原型:
// 参数说明:
// hDrop 句柄,由消息传入。
// iFile 文件索引。
// 如果该参数值为0xFFFFFFFF,函数返回拖拽操作中的文件数量。
// 如果该参数值为0到拖拽文件数量之间的数值,函数将对应索引的文件名拷贝到参数lpszFile所指的字符串内。
// lpszFile 存放文件名的字符串。如果该参数为NULL,函数返回需要的字符串长度。
// cch 存放文件名的字符串的长度。
UINT DragQueryFile(HDROP hDrop, UINT iFile, LPTSTR lpszFile, UINT cch);
// hDrop 句柄,由消息传入。
// iFile 文件索引。
// 如果该参数值为0xFFFFFFFF,函数返回拖拽操作中的文件数量。
// 如果该参数值为0到拖拽文件数量之间的数值,函数将对应索引的文件名拷贝到参数lpszFile所指的字符串内。
// lpszFile 存放文件名的字符串。如果该参数为NULL,函数返回需要的字符串长度。
// cch 存放文件名的字符串的长度。
UINT DragQueryFile(HDROP hDrop, UINT iFile, LPTSTR lpszFile, UINT cch);
从上面对函数参数的说明可以看出,该函数支持一次多选多个文件。就像Windows Media Player一样,一次多选好几个文件拖拽到它的窗口中,它就会按顺序播放文件。下面我就用一个有拖拽功能的ListBox为例,说明怎么处理一次拖拽多个文件。
// lxListBox.h
class ClxListBox : public CListBox
{
DECLARE_DYNAMIC(ClxListBox)
public:
ClxListBox();
virtual ~ClxListBox();
afx_msg void OnDropFiles(HDROP hDropInfo);
protected:
DECLARE_MESSAGE_MAP()
};
// lxListBox.cpp
#include "stdafx.h"
#include "lxListBox.h"
IMPLEMENT_DYNAMIC(ClxListBox, CListBox)
ClxListBox::ClxListBox()
{ }
ClxListBox::~ClxListBox()
{ }
BEGIN_MESSAGE_MAP(ClxListBox, CListBox)
ON_WM_DROPFILES()
END_MESSAGE_MAP()
void ClxListBox::OnDropFiles(HDROP hDropInfo)
{
char szFileName[MAX_PATH];
int iFileNumber;
// 得到拖拽操作中的文件个数
iFileNumber = DragQueryFile(hDropInfo, 0xFFFFFFFF, NULL, 0);
for (int i = 0; i < iFileNumber; i++)
{
// 得到每个文件名
DragQueryFile(hDropInfo, i, szFileName, MAX_PATH);
if (FindString(0, szFileName) != LB_ERR)
continue;
// 把文件名添加到list中
AddString(szFileName);
}
CListBox::OnDropFiles(hDropInfo);
}
class ClxListBox : public CListBox
{
DECLARE_DYNAMIC(ClxListBox)
public:
ClxListBox();
virtual ~ClxListBox();
afx_msg void OnDropFiles(HDROP hDropInfo);
protected:
DECLARE_MESSAGE_MAP()
};
// lxListBox.cpp
#include "stdafx.h"
#include "lxListBox.h"
IMPLEMENT_DYNAMIC(ClxListBox, CListBox)
ClxListBox::ClxListBox()
{ }
ClxListBox::~ClxListBox()
{ }
BEGIN_MESSAGE_MAP(ClxListBox, CListBox)
ON_WM_DROPFILES()
END_MESSAGE_MAP()
void ClxListBox::OnDropFiles(HDROP hDropInfo)
{
char szFileName[MAX_PATH];
int iFileNumber;
// 得到拖拽操作中的文件个数
iFileNumber = DragQueryFile(hDropInfo, 0xFFFFFFFF, NULL, 0);
for (int i = 0; i < iFileNumber; i++)
{
// 得到每个文件名
DragQueryFile(hDropInfo, i, szFileName, MAX_PATH);
if (FindString(0, szFileName) != LB_ERR)
continue;
// 把文件名添加到list中
AddString(szFileName);
}
CListBox::OnDropFiles(hDropInfo);
}
补充一下,函数DragQueryFile得到的文件名,是带完整路径的文件名。
最后,提醒一下:要想你的控件具有拖拽功能,一定要把它的Accept Files属性设置为True!要不,上面写的那些代码是不起作用的!
- 让你的控件也具有拖拽(drag-and-drop)功能
- 让你的控件也具有拖拽(drag-and-drop)功能
- 让你的控件也具有拖拽(drag-and-drop)功能
- 让你的控件也具有拖拽(drag-and-drop)功能
- 【自定义控件】让你的控件也具有拖拽(drag-and-drop)功能 详细版
- Eclipse 拖拽功能(Drag and Drop)
- 组件的拖拽功能(Drag and Drop)
- 在.NET中实现窗体控件的内容拖拽效果(Drag-and-Drop)
- AsWing中自定义拖拽功能(Drag And Drop)
- Unity3D-UGUI-drag and drop实现拖拽放下功能
- 让你的输入文本框也具有记忆功能
- 让你的输入文本框也具有记忆功能
- Drop and Drag面板控件
- EasyUI-treegrid-拖拽的实现(drag and drop)
- VC实现文件管理器拖拽(Drag-and-Drop)
- VC实现文件管理器拖拽(Drag-and-Drop)
- [SWT] 拖和拽(Drag and Drop)
- 通用的控件之间的拖放方法(Drag and Drop)
- 061数据库设计说明书(GB8567——88)
- 继续
- 062数据要求说明书(GB856T——88)
- DataGrid简单连接Oracle
- 11用户手册(GB8567——88)
- 让你的控件也具有拖拽(drag-and-drop)功能
- 2007/01/03 星期三 晴
- 設定小數位數
- 《鲁棒的数据库持久层设计》读书笔记-开篇
- 2007年,记录我读过的书和看过的电影
- 新年元旦假期将过
- 2007/01/03 星期三 晴——2
- asp.net2.0入门经典(VB/C#双版本)下载
- 用存储过程处理插入值重复时(如果插入id值存在时,在存在id值增1后再插入)