拖拽功能与剪贴板功能类似,也是一种在系统窗口间传递消息的方法。下面我们来实现拖拽监控功能。
拖拽监控功能控制
在SystemPanel的菜单资源编辑器中添加新的菜单项
在拖拽监控控制按钮响应函数中添加如下代码:
void SystemPanel::Onm_DragDropMonitorSelected(wxCommandEvent& event)
{
if(event.IsChecked())
{
wxTheApp->GetTopWindow()->DragAcceptFiles(true);
}
else
{
wxTheApp->GetTopWindow()->DragAcceptFiles(false);
}
}
监控拖拽消息
由于拖拽变化消息WM_DROPFILES属于系统级消息,目前只能在主窗口中获取,所以我们只能通过重载主窗口系统消息处理函数然后转发给SystemPanel中的处理函数来实现。
首先,我们在主窗口MSWWindowProc添加WM_DROPFILES处理,代码如下:
//处理系统消息和自定义消息
WXLRESULT SDKLearnFrame::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
{
switch (message)
{
//处理拖拽消息
case WM_DROPFILES:
{
m_SystemPanel->DoDropFiles(message,wParam,lParam);
}
break;
default:
break;
}
return wxFrame::MSWWindowProc(message, wParam, lParam);
}
剪贴板变化具体的处理过程将会放到SystemPanel的DoDropFiles函数中进行。
处理拖拽消息
在SystemPanel的DoDropFiles函数中添加如下代码:
//拖拽监控处理
void SystemPanel::DoDropFiles(WXUINT message,WXWPARAM wParam, WXLPARAM lParam)
{
cout<<_("message: 拖拽发生了!")<<message<<endl;
HDROP hdrop = (HDROP)wParam;
TCHAR sDropFilePath[MAX_PATH+1];
int iDropFileNums = 0;
//hDrop是一个文件名缓冲区句柄(存放所拖放文件名称的数据结构),需要从windows消息WM_DROPFILES中获得;
//iFile指明查询文件序号,取值0xFFFFFFFF时,函数返回值为所拖放文件数目,其他取值(0~文件拖放总数),对应文件名存放lpszFile缓冲区;
//lpszFile取值为NULL时,函数返回对应文件名的长度;
//cch决定缓冲区的长度;
iDropFileNums = DragQueryFile(hdrop, 0xFFFFFFFF, NULL,0);//获取拖放文件个数
for (int i=0; i<iDropFileNums; i++)//分别获取拖放文件名(针对多个文件操作)
{
DragQueryFile(hdrop, i, sDropFilePath, sizeof(sDropFilePath));
cout<<_("拖拽文件:")<<_(sDropFilePath)<<endl;
path file_path(sDropFilePath);
//判断file_path是否为文件夹
if(is_directory(file_path))//是文件夹
{
recursive_directory_iterator beg_iter(file_path);
recursive_directory_iterator end_iter;
for (; beg_iter != end_iter; ++beg_iter)
{
if (is_directory(beg_iter->path()))
{
continue;
}
else
{
if(m_FileList->FindItem(-1,beg_iter->path().wstring(),false)!=wxNOT_FOUND)
continue;
auto indexItem = m_FileList->InsertItem(m_FileList->GetItemCount(),_(""));
if(is_regular_file(beg_iter->path())) //推断是否为普通文件
{
auto sizefile = file_size(beg_iter->path()); //文件大小(字节)
m_FileList->SetItem(indexItem, 0, beg_iter->path().wstring());
m_FileList->SetItem(indexItem, 1,to_string(sizefile));
}
}
}
}
//是文件
else
{
if(exists(file_path)) //推断文件存在性
{
// cout<<file_path.wstring()<<endl;
if(m_FileList->FindItem(-1,file_path.wstring(),false)!=wxNOT_FOUND)
continue;
auto indexItem = m_FileList->InsertItem(m_FileList->GetItemCount(),_(""));
auto sizefile = file_size(file_path); //文件大小(字节)
m_FileList->SetItem(indexItem, 0, file_path.wstring());
m_FileList->SetItem(indexItem, 1,to_string(sizefile));
// cout<<"File:"<<file_path.string()<<" SIZE:"<<ss.str()<<endl;
}
}
}
cout<<"File Count:"<<m_FileList->GetItemCount()<<endl;
DragFinish(hdrop);//释放文件名缓冲区
}
编译运行,至此我们实现了文件拖拽监控功能。