Internet Explorer programming Overview (4) "add to Favorites" dialog box

Source: Internet
Author: User

Keywords: "Add to Favorites" dialog box, modal window, ishelluihelper, doaddtofavdlg, doorganizefavdlg

1. Overview

Calling the "add to Favorites" dialog box (as shown below) is different from calling the "Sort favorites" dialog box. The former is more complex than the latter. In addition to saving links, adding links to favorites may also have offline access settings. From IE 4.0 to IE 5.0, the processing method has also changed.

 

2. ishelluihelper Interface

Microsoft provides an interface ishelluihelper to access some functions of Windows Shell APIs. Adding a link to favorites is also one of them, which is the following AddFavorite function.

Hresult ishelluihelper: AddFavorite (bstr url, variant * Title );

InstanceCodeAs follows:

Void cmyhtmlview: onaddtofavorites ()
{
Ishelluihelper * pshelluihelper;
Hresult hR = cocreateinstance (clsid_shelluihelper, null,
Clsctx_inproc_server, iid_ishelluihelper, (lpvoid *) & pshelluihelper );

If (succeeded (HR ))
{
_ Variant_t vttitle (gettitle (). allocsysstring ());
Cstring strurl = m_webbrowser.getlocationurl ();

Pshelluihelper-> AddFavorite (strurl. allocsysstring (), & vttitle );
Pshelluihelper-> release ();
}
}

We noticed that the "AddFavorite" function does not need a parent window handle as "doorganizefavdlg" does. This also leads to a difference from opening it in IE. The "add to Favorites" dialog box displayed through the ishelluihelper interface is "non-modal" and has an independent application.ProgramThe taskbar button, which makes our browser very unprofessional (I am a perfect person, which is also one of the reasons why my browser cannot be released ).
So we naturally think of "shdocvw. in DLL, apart from doorganizefavdlg, there should be a similar function that can be passed into a parent window handle to display the modal window, maybe like this:

Typedef uint (callback * lpfnaddfav) (hwnd, lptstr, lptstr );

In fact, such a function exists in "shdocvw. dll", that is, "doaddtofavdlg ".

3. doaddtofavdlg Function

The "doaddtofavdlg" function is also one of the functions exposed by "shdocvw. dll". Its prototype is as follows:

Typedef bool (callback * lpfnaddfav) (hwnd, tchar *, uint, tchar *, uint, lpitemidlist );

The first parameter is the parent window handle we want. The second and fourth parameters are the initial directory (generally the favorites directory) and the name of the link to be added (such as the title of the webpage ), the third and fifth parameters are the buffer lengths of the second and fourth respectively, and the last parameter is the pointer (pidl) pointing to the item identifier list related to the second parameter directory ). But the most strange thing is that there is no link URL like the "AddFavorite" function. How does one add the link? The answer is "manual creation ".
The second parameter will contain the complete link path name (for example, "X:/XXX/mylink) selected or created by the user in the" add to Favorites "dialog box after the function is returned. URL), we will create a link based on the path and the URL of the webpage. The Code is as follows (to simplify it, check "shdocvw" is skipped here. DLL "indicates whether the code is in memory. For details, see Internet Explorer programming Overview (3)" organizing favorites "dialog box):

Void cmyhtmlview: onfavaddtofav ()
{
Typedef bool (callback * lpfnaddfav) (hwnd, tchar *, uint, tchar *, uint, lpitemidlist );

Hmodule hmod = (hmodule) loadlibrary ("shdocvw. dll ");
If (hmod)
{
Lpfnaddfav lpfndoaddtofavdlg = (lpfnaddfav) getprocaddress (hmod, "doaddtofavdlg ");
If (lpfndoaddtofavdlg)
{
Tchar szpath [max_path];
Lpitemidlist pidlfavorites;

If (shgetspecialfolderpath (null, szpath, csidl_favorites, true )&&
(Succeeded (shgetspecialfolderlocation (null, csidl_favorites, & pidlfavorites ))))
{
Tchar sztitle [max_path];
Strcpy (sztitle, getlocationname ());

Tchar szurl [max_path];
Strcpy (szurl, getlocationurl ());

Bool Bok = lpfndoaddtofavdlg (m_hwnd, szpath,
Sizeof (szpath)/sizeof (szpath [0]), sztitle,
Sizeof (sztitle)/sizeof (sztitle [0]), pidlfavorites );
Cotaskmemfree (pidlfavorites );

If (Bok)
Createinternetshortcut (szurl, szpath, ""); // create an Internet shortcut
}
}
Freelibrary (hmod );
}
Return;
}

The createinternetshortcut function can be used to create an Internet shortcut. You can use the INIFILE read/write method, but the iuniformresourcelocator interface is better used.

Hresult cmyhtmlview: createinternetshortcut (lpcstr pszurl, lpcstr pszurlfilename,
Lpcstr szdescription, lpctstr sziconfile, int nindex)
{
Hresult hres;

Coinitialize (null );

Iuniformresourcelocator * phook;

Hres = cocreateinstance (clsid_internetshortcut, null, clsctx_inproc_server,
Iid_iuniformresourcelocator, (void **) & phook );

If (succeeded (hres ))
{
Ipersistfile * PPF;
Ishelllink * PSL;

// Query ishelllink for the ipersistfile interface
Hres = phook-> QueryInterface (iid_ipersistfile, (void **) & PPF );
Hres = phook-> QueryInterface (iid_ishelllink, (void **) & PSL );

If (succeeded (hres ))
{
Word wsz [max_path]; // buffer for Unicode string

// Set the path to the specified cut target.
Phook-> seturl (pszurl, 0 );

Hres = PSL-> seticonlocation (sziconfile, nindex );

If (succeeded (hres ))
{
// Set the description of the specified cut.
Hres = PSL-> setdescription (szdescription );

If (succeeded (hres ))
{
// Ensure that the string consists of ANSI characters.
Multibytetowidechar (cp_acp, 0, pszurlfilename,-1, wsz, max_path );

// Save the specified cut via the ipersistfile: Save member function.
Hres = PPF-> Save (wsz, true );
}
}

// Release the pointer to ipersistfile.
PPF-> release ();
Psl-> release ();
}

// Release the pointer to ishelllink.
Phook-> release ();

}
Return hres;
}

Well, although the above method is a little troublesome, it finally solves the "Modal window" problem, so that our program will not let users despise it. However, the problem arises again, and we find that "allow offline use" is disabled, so "Custom" cannot be mentioned, even though 90% of users have never used offline browsing provided by IE.

Will our hopes be shattered? Just like calling the "AddFavorite" function, you don't have to manually create a link. On the other hand, you have to display the window in a modal mode. Just like IE, you can also customize offline browsing.

4. Script Mode

Many Web pages have a button or link "add this page to Favorites". In fact, the "add to Favorites" dialog box is displayed in the following script to add the web page to favorites.

Window. External. AddFavorite (location. href, document. Title );

The external object here is the built-in COM automation object of webbrowser to implement extension of the Document Object Model (DOM) (we can also implement our own extension through idochostuihandler ). after reading msdn, we can see that the external object method is the same as that provided by the ishelluihelper interface. We have reason to believe that ishelluihelper provides access to the external object built in webbrowser. If you create an ishelluihelper interface instance in a proper place, you may call the AddFavorite function to display the modal dialog box. The problem is that we have not found such a place.

From the above script, we naturally think of another method. If the above script can be executed on a webpage, isn't it a problem? Do the following:

Void cmyhtmlview: onfavaddtofav ()
{
Cstring strurl = getlocationurl ();
Cstring strtitle = getlocationname ();
Cstring strjs = "javascript: window. External. AddFavorite ('" + strurl + "'," + "'" + strtitle + "');";
ExecScript (strjs );
}

void cmieview: execScript (cstring strjs)
{< br> ccomqiptr Phtmldoc = (ihtmldocument2 *) gethtmldocument ();
If (phtmldoc! = NULL)
{
ccomqiptr Phtmlwnd;
phtmldoc-> get_parentwindow (& phtmlwnd );
If (phtmlwnd! = NULL)
{
ccombstr bstrjs = strjs. allocsysstring ();
ccombstr bstrlan = sysallocstring (L "JavaScript ");
variant varret;
phtmlwnd-> execScript (bstrjs, bstrlan, & varret );
}
}
}

Obtain the pointer of the window object of the parent window of the document from chtmlview, and then call its method execScript to execute the script (in fact, any script can be executed ). The experiment found that this method is very effective, not only the window is modal, but also the link does not need to be manually created, more importantly, the "allow offline use" and "Custom" buttons can also be used.

5. the problem persists.

The script execution method seems effective. Once our program implements the idochostuihandler interface to perform advanced control over webbrowser, it will find that once the executed script contains calls to the "external" object, there will be a script error of "missing objects. The reason is that when the mshtml parsing engine (not webbrowser) checks that the host has implemented the idochostuihandler interface, it will call its getexternal method to obtain reference to an automated interface for Dom extension.

Hresult idochostuihandler: getexternal (idispatch ** ppdispatch)

But sometimes we don't want to extend the Dom, and we also want webbrowser to use its own Dom extension. The bad thing is that in this case, ppdispatch must be set to null in the getexternal method document. In other words, webbrowser does not even use its built-in external object, so our window. external. addFavorite becomes home.

I tried to find out the built-in External Object in webbrowser. Although none of them succeeded, I found the solution to the problem.

6. Perfect solution

Although we cannot find the built-in External Object in webbrowser, it certainly exists. We only need to find a way for webbrowser to call it by itself. The implementation is very simple. Find the handle of the "Internet assumer_server" window contained in webbrowser and send a message. In the following code, assume that m_hwndie is the handle of the "Internet assumer_server" window.

# Define id_ie_id_addfav 2261
: Sendmessage (m_hwndie, wm_command, makewparam (loword (id_ie_id_addfav), 0x0), 0 );

The result is the same as selecting "add to Favorites" in Internet Explorer.

As for why, follow-upArticleBesides.

References:
Msdn: adding Internet Explorer favorites to your application
Msdn: ishelluihelper Interface
Msdn: External Object
Msdn: idochostuihandler Interface

Reference address: Internet Explorer programming Overview (4) "add to Favorites" dialog box

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.