(高分)自己写的一个程序,需要实现拖放到window的一个目录,程序中我怎么知道拖到的是那个目录?

天限天空 2005-10-31 10:55:55
自己写的一个程序,需要实现拖放到window的一个目录,程序中我怎么知道拖到的是那个目录?
...全文
359 16 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
wen9010 2005-12-24
  • 打赏
  • 举报
回复
TCHAR* FileName =L"C:\\o.txt";
UINT uBufferSize = wcslen(FileName)*2;
uBufferSize = sizeof(DROPFILES) + uBufferSize + 4;
HGLOBAL hMemData = GlobalAlloc(GPTR,uBufferSize); //分配全局内存
ASSERT(hMemData != NULL);
LPDROPFILES lpDropFiles = (LPDROPFILES)GlobalLock(hMemData); //锁定之,并设置相关成员
//LPDROPFILES是DROPFILES结构
ASSERT(lpDropFiles != NULL);
lpDropFiles->pFiles = sizeof(DROPFILES);
lpDropFiles->fWide = TRUE;
//把选中的所有文件名依次复制到DROPFILES结构体后面(全局内存中)
LPTSTR pszStart = (LPTSTR)((LPBYTE)lpDropFiles + sizeof(DROPFILES));
//LPCTSTR 如果是_UNICODE:const wchar_t *,否则const char *
lstrcpy(pszStart, FileName); //lstrcpy是windows API:拷贝字符串
GlobalUnlock(hMemData); //解锁内存
m_oleDataSource.Empty(); //清空数据
m_oleDataSource.CacheGlobalData(CF_HDROP, hMemData,lpFormatEtc); //根据句柄为指定格式提供数据,即时方式,适用小数据量
m_oleDataSource.DoDragDrop(DROPEFFECT_COPY); //开始拖放
maqian 2005-12-05
  • 打赏
  • 举报
回复
mark
会思考的草 2005-11-08
  • 打赏
  • 举报
回复
你想拦截拖放操作,自己决定是否要进行此次操作?
binjuny 2005-11-08
  • 打赏
  • 举报
回复
http://www.vckbase.com/document/viewdoc/?id=258

扩展COleDropTarget类来支持任意窗口拖放
天限天空 2005-11-07
  • 打赏
  • 举报
回复
SHChangeNotifyRegister 没有对拖放事件进行截获

我只是想一个正规的做法,hook api当然能做到,但要考虑到系统兼容性,以及window升级后,程序还可以使用



会思考的草 2005-11-06
  • 打赏
  • 举报
回复
CListCtrlEx:一个支持文件拖放和实时监视的列表控件——用未公开API函数实现Shell实时监视
一、需求
无论何时,当你在Explorer窗口中创建、删除或重命名一个文件夹/文件,或者插入拔除移动存储器时,Windows总是能非常快速地更新它所有的视图。有时候我们的程序中也需要这样的功能,以便当用户在Shell中作出创建、删除、重命名或其他动作时,我们的应用程序也能快速地随之更新。
二、原理
Windows内部有两个未公开的函数(注:在最新的MSDN中,已经公开了这两个函数),分别叫做SHChangeNotifyRegister和SHChangeNotifyDeregister,可以实现以上的功能。这两个函数位于Shell32.dll中,是用序号方式导出的。这就是为什么我们用VC自带的Depends工具察看Shell32.dll时,找不到这两个函数的原因。SHChangeNotifyRegister的导出序号是2;而SHChangeNotifyDeregister的导出序号是4。
SHChangeNotifyRegister可以把指定的窗口添加到系统的消息监视链中,这样窗口就能接收到来自文件系统或者Shell的通知了。而对应的另一个函数,SHChangeNotifyDeregister,则用来取消监视钩挂。SHChangeNotifyRegister的原型和相关参数如下:
ULONG SHChangeNotifyRegister
(
HWND hwnd,
int fSources,
LONG fEvents,
UINT wMsg,
Int cEntries,
SHChangeNotifyEntry *pfsne
);
其中:
hwnd
将要接收改变或通知消息的窗口的句柄。
fSource
指示接收消息的事件类型,将是下列值的一个或多个(注:这些标志没有被包括在任何头文件中,使用者须在自己的程序中加以定义或者直接使用其对应的数值)
SHCNRF_InterruptLevel
0x0001。接收来自文件系统的中断级别通知消息。
SHCNRF_ShellLevel
0x0002。接收来自Shell的Shell级别通知消息。
SHCNRF_RecursiveInterrupt
0x1000。接收目录下所有子目录的中断事件。此标志必须和SHCNRF_InterruptLevel 标志合在一起使用。当使用该标志时,必须同时设置对应的SHChangeNotifyEntry结构体中的fRecursive成员为TRUE(此结构体由函数的最后一个参数pfsne指向),这样通知消息在目录树上是递归的。
SHCNRF_NewDelivery
0x8000。接收到的消息使用共享内存。必须先调用SHChangeNotification_Lock,然后才能存取实际的数据,完成后调用SHChangeNotification_Unlock函数释放内存。
fEvents
要捕捉的事件,其所有可能的值请参见MSDN中关于SHChangeNotify函数的注解。
wMsg
产生对应的事件后,发往窗口的消息。
cEntries
pfsne指向的数组的成员的个数。
pfsne
SHChangeNotifyEntry结构体数组的起始指针。此结构体承载通知消息,其成员个数必须设置成1,否则SHChangeNotifyRegister或者SHChangeNotifyDeregister将不能正常工作(但是据我试验,如果cEntries设为大于1的值,依然可以注册成功,不知何故)。
如果函数调用成功,则返回一个整型注册标志号,否则将返回0。同时系统就会将hwnd指定的窗口加入到操作监视链中,当有文件操作发生时,系统会向hwnd标识的窗口发送wMsg指定的消息,我们只要在程序中加入对该消息的处理函数就可以实现对系统操作的监视了。
如果要退出程序监视,就要调用另外一个未公开得函数SHChangeNotifyDeregister来取消程序监视。该函数的原型如下:
BOOL SHChangeNotifyDeregister(ULONG ulID);
其中ulID指定了要注销的监视注册标志号,如果卸载成功,返回TRUE,否则返回FALSE。
三、实例
在前一文中,我们派生了一个支持文件拖放的列表控件CListCtrlEx,但它还有一个小小的缺憾,就是当用户把一个文件拖放进来之后,如果用户在Shell中对该文件进行移动、删除、重命名等操作时,CListCtrlEx将不能保证实时更新。经过上面的讨论,现在就让我们为CListCtrlEx加上实时文件监控功能。
在使用这两个函数之前,必须要先声明它们的原型,同时还要添加一些宏和结构定义。我们在原工程中添加一个ShellDef.h头文件,然后加入如下声明:
#define SHCNRF_InterruptLevel 0x0001 //Interrupt level notifications from the file system
#define SHCNRF_ShellLevel 0x0002 //Shell-level notifications from the shell
#define SHCNRF_RecursiveInterrupt 0x1000 //Interrupt events on the whole subtree
#define SHCNRF_NewDelivery 0x8000 //Messages received use shared memory

typedef struct
{
LPCITEMIDLIST pidl; //Pointer to an item identifier list (PIDL) for which to receive notifications
BOOL fRecursive; //Flag indicating whether to post notifications for children of this PIDL
}SHChangeNotifyEntry;

typedef struct
{
DWORD dwItem1; // dwItem1 contains the previous PIDL or name of the folder.
DWORD dwItem2; // dwItem2 contains the new PIDL or name of the folder.
}SHNotifyInfo;

typedef ULONG
(WINAPI* pfnSHChangeNotifyRegister)
(
HWND hWnd,
int fSource,
LONG fEvents,
UINT wMsg,
int cEntries,
SHChangeNotifyEntry* pfsne
);

typedef BOOL (WINAPI* pfnSHChangeNotifyDeregister)(ULONG ulID);
这些宏和函数的声明,以及参数含义,如前所述。下面我们要在CListCtrlEx体内添加两个函数指针和一个ULONG型的成员变量,以保存函数地址和返回的注册号。
接下来我们为CListCtrlEx类添加一个公有成员函数Initialize,在其中,我们首先进行加载Shell32.dll以及初始化函数指针动作,接着调用注册函数向Shell注册。用户在使用我们提供的CListCtrlEx类时,应当在CListCtrlEx创建完毕后跟着调用Initialize函数以确保注册了消息监视钩子。否则将失去实时监视功能。初始化函数如下(已略去涉及OLE初始化的部分):
BOOL CListCtrlEx::Initialize()
{
…………
//加载Shell32.dll
m_hShell32 = LoadLibrary("Shell32.dll");
if(m_hShell32 == NULL)
{
return FALSE;
}

//取函数地址
m_pfnDeregister = NULL;
m_pfnRegister = NULL;
m_pfnRegister = (pfnSHChangeNotifyRegister)GetProcAddress(m_hShell32,MAKEINTRESOURCE(2));
m_pfnDeregister = (pfnSHChangeNotifyDeregister)GetProcAddress(m_hShell32,MAKEINTRESOURCE(4));
if(m_pfnRegister==NULL || m_pfnDeregister==NULL)
{
return FALSE;
}

SHChangeNotifyEntry shEntry = {0};
shEntry.fRecursive = TRUE;
shEntry.pidl = 0;
m_ulNotifyId = 0;

//注册Shell监视函数
m_ulNotifyId = m_pfnRegister(
GetSafeHwnd(),
SHCNRF_InterruptLevel|SHCNRF_ShellLevel,
SHCNE_ALLEVENTS,
WM_USERDEF_FILECHANGED, //自定义消息
1,
&shEntry
);
if(m_ulNotifyId == 0)
{
MessageBox("Register failed!","ERROR",MB_OK|MB_ICONERROR);
return FALSE;
}
return TRUE;
}
在CListCtrlEx类中再添加如下函数。该函数的作用是从PIDL中解出实际字符路径。
CString CListCtrlEx::GetPathFromPIDL(DWORD pidl)
{
char szPath[MAX_PATH];
CString strTemp = _T("");
if(SHGetPathFromIDList((struct _ITEMIDLIST *)pidl, szPath))
{
strTemp = szPath;
}
return strTemp;
}
现在我们的程序就可以接收到来自Shell或文件系统的通知消息了,只要编写一个处理自定义消息的函数,就可以对系统范围内的更改动作作出我们希望的响应动作。这里lParam参数中存放的是当前发生的事件(譬如SHCNE_CREATE),wParam参数中存放的是SHNotifyInfo结构。下面是一段框架代码:
LRESULT CListCtrlEx::OnFileChanged(WPARAM wParam, LPARAM lParam)
{
CString strOriginal = _T("");
CString strCurrent = _T("");
SHNotifyInfo* pShellInfo = (SHNotifyInfo*)wParam;

strOriginal = GetPathFromPIDL(pShellInfo->dwItem1);
if(strOriginal.IsEmpty())
{
return NULL;
}

switch(lParam)
{
case SHCNE_CREATE:
break;

case SHCNE_DELETE:
break;
case SHCNE_RENAMEITEM:
break;
}
return NULL;
}
四、总结
至此我们完成了对CListCtrlEx的扩充工作,通过这两个未公开的API函数,编写一个文件夹/文件监视器不再是一件难事。当然同样的功能也可以通过编写设备驱动程序来,但这种方法来实现,难度大,周期长,开发上也有不少困难。
会思考的草 2005-11-06
  • 打赏
  • 举报
回复
看我的blog里的文章:
http://blog.csdn.net/codewarrior/archive/2004/06/15/12038.aspx
rageliu 2005-11-04
  • 打赏
  • 举报
回复
拖也就是复制!hook api行不?

呵呵!来学习的
kongguangming 2005-11-04
  • 打赏
  • 举报
回复
copy hook
everandforever 2005-11-03
  • 打赏
  • 举报
回复
IDropSource 里面有个 Drop
loveghb 2005-11-03
  • 打赏
  • 举报
回复
老大,问题还没解决呢?
天限天空 2005-11-02
  • 打赏
  • 举报
回复
TO:jiangsheng

我看了相关资料,都不能实现,DropTarget都是 拖动自己App上
而不是自己的App拖到系统目录
蒋晟 2005-11-01
  • 打赏
  • 举报
回复
generally don't know where the data object will be dropped. You can try a Drop Handler.

http://msdn.microsoft.com/library/en-us/shellcc/platform/shell/programmersguide/shell_int/shell_int_extending/extensionhandlers/drophandlers.asp
djfu 2005-11-01
  • 打赏
  • 举报
回复

COleDropTarget
1073X 2005-11-01
  • 打赏
  • 举报
回复
你把着眼点放在目录上,在那里获得drop的东东更方便。
你是用TreeCtrl吗?
天限天空 2005-10-31
  • 打赏
  • 举报
回复
分不够,可以再加
【资源介绍】 基于C++独立编译的文和英文语音合成项目源码+项目说明+模型.zip 该项目是一个独立编译的语音合成程序(TTS)。可以本地运行不需要网络,而且没有额外的依赖,一键编译完成即可用于文和英文的语音合成。 该项目的底层计算库使用Eigen,Eigen是一套模板定义的函数,大部分情况下,只需要包含头文件即可,所以本项目没有其他依赖,在C++环境下可以独立编译和运行。 本项目使用Eigen提供的矩阵库实现了神经网络的算子,不需要依赖例如pytorch,tensorflow, ncnn 等其他NN运行环境。 本项目在 Ubuntu 上编译运行通过,其他类Linux平台,如Android,树莓派等,也应该没啥大问题,在Window上没有测试过,可能需要少许改动。 本项目的模型基于语音合成算法 vits, 在其基础上进行了基于C++的工程化 将本项目下载到本地,最好是Ubuntu Linux 环境 从以下的百度网盘地址下载模型,放入本项目的model目录: 链接: https://pan.baidu.com/s/1rYhtznOYQH7m8g-xZ_2VVQ?pwd=2d5h 提取码: 2d5h 模型文件放入后,models目录结构如下: models/ ├── multi_speakers.bin ├── single_speaker_mid.bin ├── single_speaker_english.bin ├── single_speaker_english_fast.bin └── single_speaker_fast.bin 进入Build 目录,执行以下命令: cmake .. make 编译完成后,会在Build 目录生成 tts_test 执行程序 运行下列命令,测试文语音合成(TTS): ./tts_test ../test.txt ../models/single_speaker_fast.bin out.wav 运行下列命令,测试英文语音合成(TTS): ./tts_test ../test_eng.txt ../models/single_speaker_english.bin out_eng.wav 【备注】 该项目是个人毕设/课设/大作业项目,代码都经过本地调试测试,功能ok才上传,高分作品,可快速上手运行!欢迎下载使用,可用于小白学习、进阶。 该资源主要针对计算机、通信、人工智能、自动化等相关专业的学生、老师或从业者下载使用,亦可作为期末课程设计、课程大作业、毕业设计等。 项目整体具有较高的学习借鉴价值!基础能力强的可以在此基础上修改调整,以实现不同的功能。 欢迎下载使用,也欢迎交流学习!

3,248

社区成员

发帖
与我相关
我的任务
社区描述
ATL,Active Template Library活动(动态)模板库,是一种微软程序库,支持利用C++语言编写ASP代码以及其它ActiveX程序。
社区管理员
  • ATL/ActiveX/COM社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧