我是“embeddedWindows资源pipe理器”在我的Win32应用程序。 (从技术上讲,我正在我的应用程序中托pipe一个文件夹的ShellView ,这是Windows资源pipe理器所做的)。
问题是该视图永远不会调用IShellbrowser.browSEObject。 而不是要求我导航到一个新的位置(通过browSEObject事件),shell视图正在启动Windows资源pipe理器的副本来查看该文件夹。
我想要默认的shell视图(俗称DefView)是可浏览的。
示例代码教程
首先,我们需要获取我想要显示的某个文件夹的IShellFolder 。 最简单的文件夹是Desktop文件夹,因为它有一个SHGetDesktopFolder API :
字体unicode字形映射到实际字符
微软推荐什么本地API来渲染2Dgraphics?
是否有可能使用不同的凭据读取/写入远程计算机的registry?
如何检查是否可以在MS XP / Vista的给定目录内创build一个文件?
如何使用win32 API将位图复制到剪贴板?
folder: IShellFolder; SHGetDesktopFolder({out} folder);
接下来我们要求桌面文件夹把它的IShellView提交给我们:
view: IShellView; folder.CreateViewObject(Self.Handle,IID_IShellView,{out}view);
现在我们有文件夹的IShellView (与IContextMenu或IExtractIcon相对 ),我们现在想通过调用IShellView.CreateViewWindow来显示shell视图:
hostRect: TRect; //where the view is to display itself folderSettings: TFolderSettings; //display settings for the view hwndView: HWND; //the newly created view's window handle folderSettings.viewmode := FVM_DETAILS; //details mode please,rather than icon/list/etc folderSettings.fFlags := 0; hostRect := Rect(20,20,660,500); //the view can position itself there view.CreateViewWindow(nil,folderSettings,shellbrowser,{var}hostRect,{out}hView); view.UIActivate(SVUIA_ACTIVATE_NOFOCUS);
等瞧,可识别的shell列表视图,显示我的桌面:
完整的上下文菜单处理程序:
除了当我单击打开 ,而不是通过我提供的IShellbrowser接口向我发送browSEObject事件,它将打开一个新的窗口:
当我双击时也是如此。
我怎样才能让微软的DefView可浏览?
更新 Shellbrowser实现
创build一个IShellView你必须给它一个实现IShellbrowser的对象。 这个Shellbrowser对象是视图如何传回主机容器。
在15个方法中,我只仔细看了四个 – 其余的可以返回E_NOTIMPL (这当然可能是问题):
{IShellbrowser}
browSEObject(PCUIDLIST_RELATIVE pidl,UINT wFlags);
//Informs Windows Explorer to browse to another folder. //This is the notification i want! Result := browsetoAnotherFolder(pidl,wFlags);
GetControlWindow(UINT id,HWND *lphwnd);
//Gets the window handle to a browser control. //Since i don't have a toolbar,tree,status or progress windows,return 0 lphwnd := 0; Result := S_OK;
SendControlMsg(UINT id,UINT uMsg,WParaM wParam,LParaM lParam,LRESULT *pret);
//Sends control messages to either the toolbar or the status bar in a Windows //From MSDN: Notes to Implementers // If your Windows Explorer does not have these controls,you can return E_NOTIMPL. Result := E_NOTIMPL;
GetViewStateStream(DWORD grfMode,IStream **ppStrm);
//Gets an IStream interface that can be used for storage of view-specific state @R_987_4045@ion. Result := E_NOTIMPL; //i'm don't have a stream to give you
TranslateAcceleratorSB(LPMSG lpmsg,WORD wID);
//Translates accelerator keystrokes intended for the browser's frame // while the view is active. Result := E_NOTIMPL; //i won't be doing any translating
OnViewWindowActive(IShellView *ppshv);
//Called by the Shell view when the view window or one of its child // windows gets the focus or becomes active. Result := S_OK; //i got the notification,thanks
QueryActiveShellView(IShellView **ppshv);
//Retrieves the currently active (displayed) Shell view object. ppshv := view; Result := S_OK; //i would never view another,you kNow that
EnableModelessSB(BOOL fEnable);
//Tells Windows Explorer to enable or disable its modeless dialog Boxes. Result := S_OK; //You want to enable modeless dialog Boxes? Interesting.
InsertMenusSB(HMENU hmenuShared,LPOLEMENUGROUPWIDTHS lpMenuWidths);
//Allows the container to insert its menu groups into the composite // menu that is displayed when an extended namespace is being viewed or used. Result := E_NOTIMPL; //i no has menus
RemoveMenusSB(HMENU hmenuShared);
//Permits the container to remove any of its menu elements // from the in-place composite menu and to free all associated resources. Result := E_NOTIMPL; //i no has menus
SetMenuSB(HMENU hmenuShared,HOLEMENU holemenuRes,HWND hwndActiveObject);
//Installs the composite menu in the view window. Result := E_NOTIMPL; //i no has menus
SetStatusTextSB
//Sets and displays status text about the in-place object //in the container's frame-window status bar. Result := E_NOTIMPL; //i no has status bar
Settoolbaritems(LPTBBUTTONSB lpButtons,UINT nButtons,UINT uFlags);
//Adds toolbar items to Windows Explorer's toolbar. Result := E_NOTIMPL; //i no has toolbar
那么祖先IOleWindow :
Getwindow([out] HWND *phwnd);
//Retrieves a handle to one of the windows participating in // in-place activation (frame,document,parent,or in-place object window). phwnd := Self.Handle; //here's the handle,again,of your parent Result := S_OK;
ContextSensitiveHelp([in] BOOL fEnterMode);
//Determines whether context-sensitive help mode should be entered //during an in-place activation session. Result := S_OK; //Ok,thanks,i'll make a note of it
的IServiceProvider
function TShellbrowser.QueryService(const rsid,iid: TGuid; out Obj): HResult; var sb: IShellbrowser; s: string; const SID_SInPlacebrowser: TGUID = '{1D2AE02B-3655-46CC-B63A-285988153BCA}'; SID_IShellbrowser: TGUID = '{000214E2-0000-0000-C000-000000000046}'; begin { This code is executed when you double click a folder. It's needed to implement inline browsing. If you double click a folder the default action of IShellbrowser is to open a new Windows Explorer. To open the folder in the current window you must implement IServiceProvider. http://blogs.msdn.com/b/ieinternals/archive/2009/12/30/windows-7-web-browser-control-will-not-browse-file-system.aspx } Result := E_NOINTERFACE; //Return $E_NOINTERFACE OutputDebugString(PChar('TShellbrowser.QueryService: '+IIDToString(rsid))); { Make a small change to your application to enable the filesystem object to navigate in-place within the WebOC when running on Windows 7. To do so,your hosting application will implement the IServiceProvider interface,and hand back the Webbrowser control's SID_SShellbrowser when asked for SID_SInPlacebrowser } if IsEqualGUID(rsid,SID_SInPlacebrowser) then begin sb := Self as IShellbrowser; Pointer(Obj) := Pointer(sb); sb._AddRef; Result := S_OK; end; end;
奖金阅读
前微软的Eric Law将这种行为logging为Windows 7中的一个实例性变化,以及如何解决这个问题 。 (除非不行)
雾比特有相同的问题
更多的谈谈如何实现IServiceProvider响应SID_SInPlacebrowser
也可以看看
实现IShellbrowser来托pipeIShellView
C#环境variables值不会被添加
我有什么select在Windows上存储信息? 我应该如何阅读这些信息?
监视你自己进程中的内存使用情况
从C的Windows内核驱动读取registry
为什么没有InterlockedExchangeSubtract64?
在Vista或更高版本中,您可以切换到托管Explorerbrowser,从中您可以QI IObjectWithSite并传递实现IServiceProvier与SID_SShellbrowser或SID_SInPlacebrowser服务的对象。
在XP上,您可能需要处理源自您的进程的DDE消息,因为当时的默认文件夹关联是DDE。
一些遗漏的代码,我用来重现这个例子。
TForm1 = class(TForm,IShellbrowser)
之后,实现IShellbrowser接口,并获得FShellbrowser变量。
self.GetInterface(IID_IShellbrowser,FShellbrowser)
使用FShellbrowser :
FShellView.CreateViewWindow(FPrevIoUsView,FFolderSettings,FShellbrowser,FHostRect,FViewHandle)
点击一个目录只会产生:
OnViewWindowActive GetControlWindow
此代码的另一个问题是:如何与资源管理器进行通信,调整表单的大小并调整托管的资源管理器的大小。 Explorer浏览器具有SetRect方法。
我同意使用IExplorerbrowser。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。