微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何获取embedded的资源pipe理器IShellView是可浏览的即触发BrowseObject事件

我是“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 (与IContextMenuIExtractIcon相对 ),我们现在想通过调用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] 举报,一经查实,本站将立刻删除。

相关推荐