⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 shell.html.primary

📁 Windows API Tutorials, Windows API编程最好的手册.文档格式专门制作成为各个章节相互关联的html格式,大家可以像查阅msdn一样方便使用.各个章节的内容如下: Wi
💻 PRIMARY
📖 第 1 页 / 共 2 页
字号:
    <font color="#009966">IMalloc</font> *  _malloc;
private:
    SShellPtr (SShellPtr const &amp; p) {}
    void operator = (SShellPtr const &amp; p) {}
};
</font></pre><!--End Code-->
		<td width=20>
	</table><!--End of yellow background-->
<hr><!--Text-->
Notice the same trick as before: the class SShellPtr is not directly usable. You have to subclass it and provide the appropriate constructor.
<p>Notice also that I wasn't sure if _shellMalloc couldn't be made a static member of SShellPtr. The problem is that static members are initialized before WinMain. At that time, the whole COM system might be unstable. On the other hand, the documentation says that you can safely call another API, CoGetMalloc, before the call to CoInitialize. It doesn't say whether SHGetMalloc, which does almost the same thing, can also be called anytime in your program. Like in many other cases with badly designed/documented systems, only experiment can answer such questions. <a href="mailto:bartoszm@relisoft.com">Feedback</a> will be very welcome.
<p>By the way, if you need a smart pointer that uses COM-specific malloc, the one obtained by calling CoGetMalloc, you can safely make its _malloc a static member and initialize it once in your program (here, SComMalloc::GetMalloc is static, too):
<hr>
	<!--Yellow background table.-->
         	<table cellpadding=10 cellspacing=0 width="100%">
         		<tr>
		<td width=20>
            		<td bgcolor="#e0e080">
<pre><font face="courier"><!--Code-->IMalloc * SComMalloc::_malloc = SComMalloc::GetMalloc ();

IMalloc * <font color="#cc0066"><b>SComMalloc::GetMalloc</b></font> ()
{
    <font color="#009966">IMalloc</font> * malloc = 0;
    if (<font color="#000099"><b>CoGetMalloc</b></font> (1, &amp; malloc) == S_OK)
        return malloc;
    else
        return 0;
}
</font></pre><!--End Code-->
		<td width=20>
	</table><!--End of yellow background-->
<hr>
That's all there is to know in order to start using Windows95 shell and its COM interfaces. Here's an example. Windows95 shell has this notion of a Desktop being the root of the "file" system. Did you notice how Windows95 applications let the user browse the file system starting at the desktop? This way you can, for instance, create files directly on your desktop, move between drives, browse a network drive, etc. It is, in effect, a poor man's Distributed File System (PMDFS). How can your application get access to PMDFS? Easy. For instance, let's write some code that will let the user pick a folder by browsing PMDFS. All we need to do is to get hold of the desktop, position ourselves with respect to it, start the built-in browser and retrieve the path that the user has chosen. 
<hr><!--End Text-->
	<!--Yellow background table.-->
         	<table cellpadding=10 cellspacing=0 width="100%">
         		<tr>
		<td width=20>
            		<td bgcolor="#e0e080">
<pre><font face="courier"><!--Code-->char path [MAX_PATH];
path [0] = '\0';
Desktop desktop;
ShPath browseRoot (desktop, unicodePath);
if (browseRoot.IsOK ())
{
    FolderBrowser browser (hwnd,
                          browseRoot,
                          BIF_RETURNONLYFSDIRS,
                          "Select folder of your choice");
    if (folder.IsOK ())
    {
        strcpy (path, browser.GetPath ());
    }
}
</font></pre><!--End Code-->
		<td width=20>
	</table><!--End of yellow background-->
<hr><!--Text-->
Let's start with the desktop object. It envelops the interface called IShellFolder. Notice how we conform to the First Rule of Acquisition--we allocate resources in the constructor by calling the API SHGetDesktopFolder. The smart interface pointer will take care of resource management (reference counting).
<hr><!--End Text-->
	<!--Yellow background table.-->
         	<table cellpadding=10 cellspacing=0 width="100%">
         		<tr>
		<td width=20>
            		<td bgcolor="#e0e080">
<pre><font face="courier"><!--Code-->
class <font color="#cc0066"><b>Desktop</b></font>: public <font color="#cc0066"><b>SIfacePtr</b></font>&lt;<font color="#cc0066"><b>IShellFolder</b></font>&gt;
{
public:
    Desktop ()
    {
        if (<font color="#000099"><b>SHGetDesktopFolder</b></font> (&amp; _p) != <font color="#009966">NOERROR</font>)
            throw "SHGetDesktopFolder failed";
    }
};
</font></pre><!--End Code-->
		<td width=20>
	</table><!--End of yellow background-->
<hr><!--Text-->
Once we have the desktop, we have to create a special kind of path that is used by PMDFS. The class ShPath encapsulates this "path." It is constructed from a regular Unicode path (use <i>mbstowcs</i> to convert ASCII path to Unicode: <font face="Courier">int mbstowcs(wchar_t *wchar, const char *mbchar, size_t count)</font>). The result of the conversion is a <i>generalized path</i> relative to the desktop. Notice that memory for the new path is allocated by the shell--we encapsulate it in SShellPtr to make sure it is correctly deallocated.
<hr><!--End Text-->
	<!--Yellow background table.-->
         	<table cellpadding=10 cellspacing=0 width="100%">
         		<tr>
		<td width=20>
            		<td bgcolor="#e0e080">
<pre><font face="courier"><!--Code-->
class <font color="#cc0066"><b>ShPath</b></font>: public <font color="#cc0066"><b>SShellPtr</b></font>&lt;<font color="#009966">ITEMIDLIST</font>&gt;
{
public:
    ShPath (SIfacePtr&lt;IShellFolder&gt; &amp; folder, wchar_t * path)
    {
        ULONG lenParsed = 0;
        _hresult = folder-&gt;<font color="#000099"><b>ParseDisplayName</b></font> (0, 0, path, &amp; lenParsed, &amp; _p, 0);
    }
    bool IsOK () const { return SUCCEEDED (_hresult); }
private:
    <font color="#009966">HRESULT</font> _hresult;
};
</font></pre><!--End Code-->
		<td width=20>
	</table><!--End of yellow background-->
	
<hr><!--Text-->
This shell path will become the root from which the browser will start its interaction with the user.
<p>From the client code's point of view, the browser <i>is</i> the path chosen by the user. That's why it inherits from SShellPtr&lt;ITEMIDLIST&gt;.
<p>By the way, ITEMIDLIST is the official name for this <i>generalized path</i>. It is a list of, and I'm not making this up, SHITEMID's. I shall refrain from making any further comments or jokes about shell naming conventions.
<hr><!--End Text-->

	<!--Yellow background table.-->
         	<table cellpadding=10 cellspacing=0 width="100%">
         		<tr>
		<td width=20>
            		<td bgcolor="#e0e080">
<pre><font face="courier"><!--Code-->
class <font color="#cc0066"><b>FolderBrowser</b></font>: public <font color="#cc0066"><b>SShellPtr</b></font>&lt;<font color="#009966">ITEMIDLIST</font>&gt;
{
public:
    FolderBrowser (
        HWND hwndOwner,
        SShellPtr&lt;ITEMIDLIST&gt; &amp; root,
        UINT browseForWhat,
        char const *title);

    char const * GetDisplayName () { return _displayName; }
    char const * GetPath ()        { return _fullPath; }
    bool IsOK() const              { return _p != 0; };

private:
    char       _displayName [MAX_PATH];
    char       _fullPath [MAX_PATH];
    <font color="#009966">BROWSEINFO</font> _browseInfo;
};

<font color="#cc0066"><b>FolderBrowser::FolderBrowser</b></font> (
    HWND hwndOwner,
    SShellPtr&lt;ITEMIDLIST&gt; &amp; root,
    UINT browseForWhat,
    char const *title)
{
    _displayName [0] = '\0';
    _fullPath [0] = '\0';
    _browseInfo.hwndOwner = hwndOwner;
    _browseInfo.pidlRoot = root; 
    _browseInfo.pszDisplayName = _displayName;
    _browseInfo.lpszTitle = title; 
    _browseInfo.ulFlags = browseForWhat; 
    _browseInfo.lpfn = 0; 
    _browseInfo.lParam = 0;
    _browseInfo.iImage = 0;
	 
    // Let the user do the browsing
    _p = <font color="#000099"><b>SHBrowseForFolder</b></font> (&amp; _browseInfo);
	 
    if (_p != 0)
        <font color="#000099"><b>SHGetPathFromIDList</b></font> (_p, _fullPath);
}

</font></pre><!--End Code-->
		<td width=20> <!-- right margin-->
	</table><!--End of yellow background-->
	
<hr><!--Text-->
That's it! Isn't it simple?
<p>Now, would you like to hear <a href="olerant.html">what I think about OLE</a>?
<hr><!--End Text-->

   </table> <!-- End central table -->

   <td width=10><!-- Right margin -->
</table> <!-- End main table -->

</body>
</html>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -