360网盘的资源管理器插件怎么做的?

该用户不懒但没有名字 2012-11-10 12:11:09
是Com?如下图,一直在那里不消失,Explore启动的时候就有。
说明原理30分,给出实现代码50分,给出完整代码100分,给出C#实现追加100分。

...全文
728 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
luhifeng 2015-05-18
  • 打赏
  • 举报
回复
资源管理器嵌入插件实现说明 一. 核心思想 添加子窗口,使插件窗口与资源管理器的文件列表窗口共同拆分右侧窗口。 二. 技术实现 1. 创建程序 新建ATL程序,去除attributed选项(如果有)。 2. 添加方法 添加简单ATL对象MyBar,勾选IobjectWithSite。 .h文件中添加成员变量。 CComQIPtr<IWebBrowser2> mWebBrowser2; CComPtr<IConnectionPoint> m_spWebBrowser; DWORD mCookie; IDispatch *m_pdisp; HWND m_hWndShellView;//文件列表控件指针 HWND m_hWndShellViewParent;//文件列表控件父窗口指针 TCHAR m_CurrDir[MAX_PATH];//当前文件夹路径 HWND m_hOldWndShellViewParent; // 记录上一次父窗口句柄 为MyBar对象添加SetSite方法:STDMETHOD(SetSite)(IUnknown *pUnkSite); 该方法在BHO对象载入的时候会调用一次,这里可以保存Iunknown指针、判断是不是资源管理器在载入、建立事件响应连接点(用于接收浏览器消息)。 STDMETHODIMP CMyBar::SetSite(IUnknown *pUnkSite) { if (pUnkSite) { pUnkSite->QueryInterface(IID_IDispatch,(void**)&m_pdisp); pUnkSite->QueryInterface(IID_IWebBrowser2, (void **)&mWebBrowser2); // Receives the connection point for WebBrowser events CComQIPtr<IConnectionPointContainer, &IID_IConnectionPointContainer> spCPC(mWebBrowser2); spCPC->FindConnectionPoint(DIID_DWebBrowserEvents2, &m_spWebBrowser); // Pass the event handlers to the container m_spWebBrowser->Advise(reinterpret_cast<IDispatch*>(this), &mCookie); return S_OK; } return E_FAIL; } 添加invoke响应 STDMETHOD (Invoke)(DISPID dispidMember,REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS * pDispParams, VARIANT * pvarResult,EXCEPINFO * pexcepinfo, UINT * puArgErr); STDMETHODIMP CHello::Invoke(DISPID dispidMember,REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS * pDispParams, VARIANT * pvarResult,EXCEPINFO * pexcepinfo, UINT * puArgErr) { USES_CONVERSION; if (!pDispParams) return E_INVALIDARG; switch (dispidMember) { case DISPID_BEFORENAVIGATE2 : break; case DISPID_NAVIGATECOMPLETE2: break; case DISPID_DOCUMENTCOMPLETE: //完成打开文件夹时收到的消息,注意会收到2次 break; case DISPID_DOWNLOADBEGIN: break; case DISPID_DOWNLOADCOMPLETE: break; case DISPID_NEWWINDOW2: break; case DISPID_WINDOWREGISTERED: break; case DISPID_ONQUIT: //关闭浏览器收到的消息 break; default: break; } return S_OK; } 获取资源管理器窗口信息 添加一个成员函数,来实现资源管理器窗口信息的获取工作。 这个函数,最好在收到DISPID_DOCUMENTCOMPLETE消息时调用。 小提示:每次点击文件夹,进入不同路径时,都会响应DISPID_DOCUMENTCOMPLETE消息,且之前的窗口被销毁(资源管理器右侧文件列表窗口及其父窗口),创建新的窗口。 通过左侧导航窗口,反复点击同一个节点,即反复显示同一个路径,也会响应DISPID_DOCUMENTCOMPLETE消息,但窗口不被销毁。 void HwDISPID_DOCUMENTCOMPLETE(); void CMyBar::HwDISPID_DOCUMENTCOMPLETE() { // DISPID_DOCUMENTCOMPLETE: 完成打开文件夹时收到的消息,注意会收到二次 // 我们在第二次消息时做处理,如果第一次消息时做处理,会导致explorer闪退(原因暂时不明,可能和父窗口句柄有关). …… // 添加条件处理,不满足条件的,则返回。 IWebBrowserApp *pwba; if (SUCCEEDED(m_pdisp->QueryInterface(IID_IWebBrowserApp, (void**)&pwba))) { IServiceProvider *psp; if (SUCCEEDED(pwba->QueryInterface(IID_IServiceProvider, (void**)&psp))) { IShellBrowser *psb; if (SUCCEEDED(psp->QueryService(SID_STopLevelBrowser, IID_IShellBrowser, (void**)&psb))) { IShellView *psv; if (SUCCEEDED(psb->QueryActiveShellView(&psv))) { psv->GetWindow(&m_hWndShellView);//保存shellview句柄 m_hWndShellViewParent = GetParent(m_hWndShellView);//保存shellview父窗口句柄 IFolderView *pfv; if (SUCCEEDED(psv->QueryInterface(IID_IFolderView, (void**)&pfv))) { IPersistFolder2 *ppf2; if (SUCCEEDED(pfv->GetFolder(IID_IPersistFolder2, (void**)&ppf2))) { LPITEMIDLIST pidlFolder; if (SUCCEEDED(ppf2->GetCurFolder(&pidlFolder))) { if (SHGetPathFromIDList(pidlFolder, m_CurrDir)) //保存当前窗口路径 { } CoTaskMemFree(pidlFolder); } ppf2->Release(); } pfv->Release(); } psv->Release(); } psb->Release(); } psp->Release(); } pwba->Release(); } // 窗口切换或新打开一个explorer时,才创建插件窗口,反复显示同一个路径窗口时,不创建,否则会闪退。 // 窗口切换或新打开explorer时,句柄会变化。 if(m_hWndShellViewParent != m_hOldWndShellViewParent) { …….//调用创建插件窗口函数,也可自行添加条件,设定某些路径下才创建显示插件。 m_hOldWndShellViewParent = m_hWndShellViewParent; } } 创建插件窗口 在ATL项目中,添加dlg资源,设置style为child,其它属性根据需求进行设定,我都设置为false。 添加成员函数创建窗口。 小提示:如果创建的dlg类,是继承自CDialog,在使用时,先调用一句AFX_MANAGE_STATE(AfxGetStaticModuleState( ));防止出错。 void InitBar(); void CMyBar::InitBar() { AFX_MANAGE_STATE(AfxGetStaticModuleState( )); //以m_hWndShellView的父窗口作为父窗口,当切换目录时会自动销毁窗口 m_InfoBar = new CMyBarDlg; m_InfoBar->Create(IDD_MyBarDlg,CWnd::FromHandle(m_hWndShellViewParent)); // 可以调用movewindow调整我们的插件与资源管理器文件列表窗口的位置关系。 CRect ParentRect; GetWindowRect(m_hWndShellViewParent,ParentRect); MoveWindow(m_hWndShellView,0,30,abs(ParentRect.Width()),abs(ParentRect.Height()),TRUE); MoveWindow(m_InfoBar->GetSafeHwnd(),0,0,abs(ParentRect.Width()),30,TRUE); ExchangeWndProc(); } 使插件响应资源管理器窗口的变化 我们可以通过函数替换的方法,替换窗口过程函数,使得插件窗口可以响应到资源管理器窗口的变化,从而跟随改变窗口大小。 添加成员函数: void ExchangeWndProc(); void CHwDocBar::ExchangeWndProc() { // 替换窗口过程函数 SetProp(m_hWndShellView,_T("MyBarObj"), m_InfoBar);//保存对话框句柄到文件列表控件的属性表中 WNDPROC oldWndProc = (WNDPROC)::GetWindowLong(m_hWndShellView, GWL_WNDPROC);//获取原窗口过程 SetProp(m_hWndShellView, _T("MyPROPNAME_OLDPROC"), oldWndProc);//保存原窗口过程到文件列表控件的属性表中 SetWindowLong((HWND)m_hWndShellView, GWL_WNDPROC, (LONG)BrowserWndProc);//替换窗口过程 } 实现我们的窗口过程函数: static LRESULT CALLBACK BrowserWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); LRESULT CALLBACK CHwDocBar::BrowserWndProc(HWND hWnd, // handle to window UINT uMsg, // message identifier WPARAM wParam, // first message parameter LPARAM lParam) // second message parameter { LRESULT result = NULL; WNDPROC pfnOldWndProc = (WNDPROC)::GetProp(hWnd,_T("MyPROPNAME_OLDPROC"));//读出原窗口过程 CHwDocBarDlg *dlg = (CHwDocBarDlg *)::GetProp(hWnd,_T("MyBarObj"));//读出对话框句柄 switch(uMsg) { case WM_SIZE: { if (dlg != NULL) { ::MoveWindow(dlg->m_hWnd, 0, 0, LOWORD(lParam), 30, TRUE);//控制对话框宽度 } CallWindowProc(pfnOldWndProc, hWnd, uMsg, wParam, lParam);//调用原窗口过程 } break; case WM_WINDOWPOSCHANGED: case WM_WINDOWPOSCHANGING: { LPWINDOWPOS pPos = (LPWINDOWPOS)lParam; pPos->cy -= 30; CallWindowProc(pfnOldWndProc, hWnd, uMsg, wParam, (LPARAM)pPos);//调用原窗口过程 } break; default: return CallWindowProc(pfnOldWndProc, hWnd, uMsg, wParam, lParam);//调用原窗口过程 } return result; } 3. 注册 打开我们创建的ATL对象MyBar的rgs文件。 在后面加上BHO的注册信息。 其中的ForceRemove后的一串编号,换成自己插件的CLSID。 HKLM { NoRemove SOFTWARE { NoRemove Microsoft { NoRemove Windows { NoRemove CurrentVersion { NoRemove Explorer { NoRemove 'Browser Helper Objects' { ForceRemove '{1B69C6B6-01E4-443B-8F18-F8DB9AEC6D65}' } } } } } } }
chaoa888 2014-10-30
  • 打赏
  • 举报
回复
楼主 求解决方法 cboke@qq.com
l594381236 2013-11-28
  • 打赏
  • 举报
回复
我最近也有这样一个需求,找了很久的资料都没有找到。求楼主分享,谢谢。594381236@qq.com 麻烦楼主可以发个帖子,给大家都分享一下。 谢谢楼主了
caoyucsh 2013-08-21
  • 打赏
  • 举报
回复
求方案啊,楼主,多谢啊,22191665@qq.com
qingshuiyimu 2013-05-07
  • 打赏
  • 举报
回复
楼主,求真像!
blueideas 2013-03-06
  • 打赏
  • 举报
回复
求方案,谢谢。343800118@qq.com
abc_lewis 2012-11-27
  • 打赏
  • 举报
回复
求方案,谢谢。471439499@qq.com
  • 打赏
  • 举报
回复
引用 9 楼 wyx100 的回复:
怎么做到的。。。
模仿360做到的~。你可以用VS打开360的扩展DLL看看
wyx100 2012-11-13
  • 打赏
  • 举报
回复
怎么做到的。。。
  • 打赏
  • 举报
回复
没人恢复了,我用笨方法加了条上去,测试了,除了切换目录有点闪,还行,还得加宽度变化的代码。

没人回复结贴了。。
  • 打赏
  • 举报
回复
引用 1 楼 CometNet 的回复:
建议搜索"Windows Shell 外壳编程" ShellExView可以帮助你详细了解系统插件
Visual C++ Windows Shell Programming 大致看了下目录,没有找到答案
邓学彬 2012-11-10
  • 打赏
  • 举报
回复
建议搜索"Windows Shell 外壳编程"

ShellExView可以帮助你详细了解系统插件







  • 打赏
  • 举报
回复
引用 6 楼 wyx100 的回复:
Shell Extention。COM方式的插件
Copy无效
wyx100 2012-11-10
  • 打赏
  • 举报
回复
Shell Extention。COM方式的插件
  • 打赏
  • 举报
回复
没接触过Shell编程,但是我找到了那些自己扩展右键菜单啊、图标的文章,像 《The Complete Idiot's Guide to Writing Shell Extensions 》 还有Visual C++ Windows Shell Programming 还看了看MSDN,但 就是不知道这个类似工具条的东西是什么,难道是必须要深入看看动手写写才知道?望各位大侠赐教!
  • 打赏
  • 举报
回复
引用 3 楼 oyljerry 的回复:
Shell Extention。COM方式的插件
那他是怎么放到这个特殊的位置的呢?用CometNet给的工具我发现这个是个BHO,但是在IE里却没有启用哈,判断了?
oyljerry 2012-11-10
  • 打赏
  • 举报
回复
Shell Extention。COM方式的插件

3,245

社区成员

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

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