`
soboer
  • 浏览: 1307604 次
文章分类
社区版块
存档分类
最新评论

让你的控件也具有拖拽(drag-and-drop)功能

阅读更多

现在有很多软件都支持拖拽功能,就是用鼠标拖着文件放到软件窗口中某个位置,软件就可以做出相应的反应。比如,Windows自带的播放软件Windows Media Player,你可以拖着一个媒体文件放到它的主窗口中,它就会开始播放这个文件。
怎么让自己的软件也有这个功能呢?
其实,并不是很难,只要让你需要有拖拽功能的控件响应WM_DROPFILES消息就行了。下面以Edit控件和ListBox控件为例子来说明。
首先,从CEdit继承,自定义一个Edit控件。在头文件添加如下的消息响应函数:

afx_msgvoidOnDropFiles(HDROPhDropInfo);

然后,在cpp文件中的消息映射中添加:

ON_WM_DROPFILES()

最后,在cpp文件中添加OnDropFiles函数的实现,对拖拽的文件进行处理。下面是完整的代码:

//lxEdit.h

classClxEdit:publicCEdit
{
DECLARE_DYNAMIC(ClxEdit)

public:
ClxEdit();
virtual~ClxEdit();

afx_msg
voidOnDropFiles(HDROPhDropInfo);

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()

voidClxEdit::OnDropFiles(HDROPhDropInfo)
{
//被拖拽的文件的文件名
charszFileName[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存放文件名的字符串的长度。

UINTDragQueryFile(HDROPhDrop,UINTiFile,LPTSTRlpszFile,UINTcch);

从上面对函数参数的说明可以看出,该函数支持一次多选多个文件。就像Windows Media Player一样,一次多选好几个文件拖拽到它的窗口中,它就会按顺序播放文件。下面我就用一个有拖拽功能的ListBox为例,说明怎么处理一次拖拽多个文件。

//lxListBox.h

classClxListBox:publicCListBox
{
DECLARE_DYNAMIC(ClxListBox)

public:
ClxListBox();
virtual~ClxListBox();

afx_msg
voidOnDropFiles(HDROPhDropInfo);

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()

voidClxListBox::OnDropFiles(HDROPhDropInfo)
{
charszFileName[MAX_PATH];
intiFileNumber;

//得到拖拽操作中的文件个数
iFileNumber=DragQueryFile(hDropInfo,0xFFFFFFFF,NULL,0);
for(inti=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!要不,上面写的那些代码是不起作用的!

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics