请问各位大哥,如何截获浏览器上的链接单击事件(包括鼠标单击和回车键)

解决方案 »

  1.   

    SetWindowLong 和 GetParent 这两个函数结合使用。
      

  2.   

    1首先用FindWindow()得到浏览器的句柄
    2用GetWindowLong的到浏览器的窗口过程地址
    3用SetWindowLong来用你自己定义的窗口函数来处理浏览器的消息
    4加入你定义的窗口过程是 wndyouproc 就在这个函数里处理各个消息
    5最后退出的时候再用SetWindowLong把浏览器的窗口过程还原为自己的!
      

  3.   

    Browser Helper Objects: The Browser the Way You Want It
    Summary: Describes how to use BHOs to customize your browser. (16 printed pages) 
    Introduction
    There are sometimes circumstances in which you need a more or less specialized version of the browser. Sometimes you work around this by developing a completely custom module built on top of the WebBrowser control, complete with buttons, labels, and whatever else the user interface requires. In this case, you're free to add to that browser any new, nonstandard feature you want. But what you actually have is just a new, nonstandard browser. The WebBrowser control is just the parsing engine of the browser. This means there still remains a number of UI-related tasks for you to do: adding an address bar, toolbar, history, status bar, channels, and favorites, just to name a few. So, to create a custom browser you have to write two types of code: the code that transforms the WebBrowser control into a full-fledged browser like Microsoft® Internet Explorer, and the code that implements the new features you want it to support. Wouldn't it be nice if there was a straightforward way to customize Internet Explorer instead? Browser Helper Objects (BHO) do just that.Program Customization
    Historically speaking, the first way to customize the behavior of a program was through subclassing. By this means, you could change the way a given window in a program processed messages and actually obtain a different behavior. Although considered a brute-force approach, because the victim is largely unaware of what happens, it's been the only choice for a long time.With the advent of the Microsoft Win32® API, interprocess subclassing was discouraged and made a bit harder to code. If you're brave-hearted, however, pointers have never scared you; above all, if you're used to living in symbiosis with system-wide hooks, you might even find it too simple. But this is not always the case. Despite the cleverness of the programming, the point is that each Win32 process runs in its own address space and breaking the process boundaries is somewhat incorrect. On the other hand, there might be circumstances that require you to do this with the best of intentions. More often, customization might be a specific feature the program itself allows by design.In the latter case, the programs search for additional modules in well-known and prefixed disk zones, load, initialize, and then leave them free to do the job they have been designed to do. This is exactly what happens with the Internet Explorer browser and its helper objects.What Are Browser Helper Objects?
    From this point of view, Internet Explorer is just like any other Win32-based program with its own memory space to preserve. With Browser Helper Objects you can write components—specifically, in-process Component Object Model (COM) components—that Internet Explorer will load each time it starts up. Such objects run in the same memory context as the browser and can perform any action on the available windows and modules. For example, a BHO could detect the browser's typical events, such as GoBack, GoForward, and DocumentComplete; access the browser's menu and toolbar and make changes; create windows to display additional information on the currently viewed page; and install hooks to monitor messages and actions. In short, a BHO works as a spy we send to infiltrate the browser's land.Before going any further with the nitty-gritty details of BHO, there are a couple of points I need to illuminate further. First, the BHO is tied to the browser's main window. In practice, this means a new instance of the object is created as soon as a new browser window is created. Any instance of the BHO lives and dies with the browser's instance. Second, BHOs only exist in Internet Explorer, version 4.0 and later.If you're running the Microsoft Windows® 98, Windows 2000, Windows 95, or Windows NT® version 4.0 operating system with the Active Desktop™ Shell Update (shell version 4.71), BHOs are supported also by Windows Explorer. This has some implications that I'll talk more about later when making performance considerations and evaluating the impact of BHOs.In its simplest form, a BHO is a COM in-process server registered under a certain registry's key. Upon startup, Internet Explorer looks up that key and loads all the objects whose CLSID is stored there. The browser initializes the object and asks it for a certain interface. If that interface is found, Internet Explorer uses the methods provided to pass its IUnknown pointer down to the helper object. This process is illustrated in Figure 1.Figure 1. How Internet Explorer loads and initializes helper objects. The BHO site is the COM interface used to establish a communication.The browser may find a list of CLSIDs in the registry and create an in-process instance of each. As a result, such objects are loaded in the browser's context and can operate as if they were native components. Due to the COM-based nature of Internet Explorer, however, being loaded inside the process space doesn't help that much. Put another way, it's true that the BHO can do a number of potentially useful things, like subclassing constituent windows or installing thread-local hooks, but it is definitely left out from the browser's core activity. To hook on the browser's events or to automate it, the helper object needs to establish a privileged and COM-based channel of communication. For this reason, the BHO should implement an interface called IObjectWithSite. By means of IObjectWithSite, in fact, Internet Explorer will pass a pointer to its IUnknown interface. The BHO can, in turn, store it and query for more specific interfaces, such as IWebBrowser2, IDispatch, and IConnectionPointContainer.Another way to look at BHOs is in terms of Internet Explorer shell extensions. As you know, a Windows shell extension is a COM in-process server that Windows Explorer loads when it is about to perform a certain action on a document—for example, displaying its context menu. By writing a COM module that implements a few COM interfaces, you're given a chance to add new items to the context menu and then handle them properly. A shell extension must also be registered in such a way that Windows Explorer can find it. A Browser Helper Object follows the same pattern—the only changes are the interfaces to implement. Slightly different is the trigger that causes a BHO to be loaded. Despite the implementation differences, however, shell extensions and BHOs share a common nature, as the following table demonstrates.
      

  4.   


    Table 1. How Shell Extensions and Browser Helper Objects Implement Common FeaturesFeature Shell extension Browser Helper Object 
    Loaded by Windows Explorer. Internet Explorer (and Windows Explorer for shell version 4.71 and later). 
    Triggered by User's action on a document of a certain class (that is, right-click). Opening of the browser's window. 
    Unloaded when A few seconds later the reference count goes to 0. The browser window that caused it to load gets closed. 
    Implemented as  COM in-process DLL. COM in-process DLL 
    Registration requirements Usual entries for a COM server plus other entries, depending on the type of shell extension and the document type that it will apply to. Usual entries for a COM server plus one entry to qualify it as a BHO. 
    Interfaces needed Depends on the type of the shell extension. IObjectWithSite. 
    If you're interested in shell extensions, see the MSDN Library Online or CD documentation for a primer. For deeper coverage, check out my recently published book, Professional Shell Programming for Windows (Wrox Press, 1-861001-84-3).The Lifecycle of Helper Objects
    As I mentioned earlier, BHOs aren't just supported by Internet Explorer. Provided you're running at least shell version 4.71, your BHOs will also be loaded by Windows Explorer—meaning that a unique browser can navigate both the Web and local disks with a similar user experience. The next table provides a product-oriented view of the various shell versions available today. The shell version number depends on the version information stored in shell32.dll.Table 2. Browser Helper Objects Support for the Various Shell Versions
    Shell version Installed products BHOs supported by 
    4.00 Windows 95 and Windows NT 4.0 with or without Internet Explorer 4.0 or earlier. 
    Note   The Shell Update isn't installed.
     Internet Explorer 4.0 
    4.71 Windows 95 and Windows NT 4.0 with Internet Explorer 4.0 with the Active Desktop Shell Update release. Both Internet Explorer and Windows Explorer 
    4.72 Windows 98. Both Internet Explorer and Windows Explorer 
    5.00 Windows 2000 Both Internet Explorer and Windows Explorer 
    A Browser Helper Object is loaded when the main window of the browser is about to be displayed and is unloaded when that window is destroyed. If you open more copies of the browser window, more instances of the BHO will be created. The BHO is loaded despite the command line that launches the browser. For example, it gets loaded even if you simply want to see only a specific HTML page or a given folder. In general, the BHO is taken into account when either explorer.exe or iexplore.exe execute. If you set the "Open each folder in its own window" folder setting, the BHO will load each time you open a folder.Figure 2. With this setting, each time you open a folder, a separate instance of explorer.exe executes and loads the registered BHOs.Notice, however, that this applies only when you open folders starting from the My Computer icon on the desktop. In this case, the shell calls explorer.exe each time you move to another folder. The same won't occur if you start browsing from a two-paned view. In fact, when you change the folder the shell doesn't launch a new instance of the browser but simply creates another instance of the embedded view object. Curiously, if you change the folder by typing a new name in the Address bar, the browsing always takes place in the same window whether Window Explorer's view is single or two-paned.Things are far simpler with Internet Explorer. You have multiple copies of it only if you explicitly run iexplore.exe multiple times. When you open new windows from Internet Explorer, each window is duplicated in a new thread without originating a new process, and therefore without reloading BHOs.Above all, the most interesting feature of BHOs is that they are extremely dynamic. Each time Window Explorer's or Internet Explorer's window is opened, the loader reads the CLSID of the installed helper objects from the registry and deals with them. You can have different BHOs loaded by different copies of the browser if you edited the registry between instances of opening the browser. This means that now you have an excellent alternative to writing a new browser from scratch—you can embed WebBrowser in a Microsoft Visual Basic® or Microsoft Foundation Classes (MFC) frame window. At the same time, you're given a great opportunity to arrange very extensible browsing applications. You can rely on the full power of Internet Explorer and add as many add-ons as you want when it suits your needs.The IObjectWithSite Interface
    From this high-level overview of Browser Helper Objects one concept emerges clearly: A BHO is a dynamic-link library (DLL) capable of attaching itself to any new instance of Internet Explorer and, under certain circumstances, also Windows Explorer. Such a module can get in touch with the browser through the container's site.In general, a site is an intermediate object placed in the middle of the container and each contained object. Through it, the container manages the content of the contained object and, in return, makes the object's internal functionality available. The site-based relationship between containers and objects involves the implementation of interfaces like IOleClientSite on the container side, and IOleObject on the object side. By calling methods on IOleObject, the container makes the object aware of its host environment.When the container is Internet Explorer (or the Web-enabled version of Windows Explorer), performance issues reduce this communication pattern to the essential. The object is now required to implement a simpler and lighter interface called IObjectWithSite. It provides just two methods.Table 3. The IObjectWithSite Interface DefinitionMethod Description 
    HRESULT SetSite(
      IUnknown* pUnkSite) Receives the IUnknown pointer of the browser. The typical implementation will simply store such a pointer for further use. 
    HRESULT GetSite(
      REFIID riid,
      void** ppvSite) Retrieves and returns the specified interface from the last site set through SetSite(). The typical implementation will query the previously stored pUnkSite pointer for the specified interface. 
      The only strict requirement for a BHO is implementing this interface. Notice that you should avoid returning E_NOTIMPL from any of the preceding functions. Either you don't implement the interface or you should be able to code its methods properly.
      

  5.   

    Writing a Browser Helper Object
    A Browser Helper Object is a COM in-process server, so what's better than the Active Template Library (ATL) to build one? Another reason for choosing ATL is that it already provides a default and good enough implementation of the IObjectWithSite interface. Plus, among the predefined types of objects that the ATL COM Wizard natively supports, there's one, the Internet Explorer Object, that is just the type of object a BHO should be. An ATL Internet Explorer Object, in fact, is a simple object—that is, a COM server that supports IUnknown and self-registration—plus IObjectWithSite. If you add such an object to your ATL project, and call the corresponding class CViewSource, you get the following code from the wizard:class ATL_NO_VTABLE CViewSource : 
       public CComObjectRootEx<CComSingleThreadModel>,
       public CComCoClass<CViewSource, &CLSID_ViewSource>,
       public IObjectWithSiteImpl<CViewSource>,
       public IDispatchImpl<IViewSource, &IID_IViewSource, 
                            &LIBID_HTMLEDITLib>As you can see, the wizard already makes the class inherit from IObjectWithSiteImpl, which is an ATL template class that provides a basic implementation of IObjectWithSite. (See atlcom.h in the ATL\INCLUDE directory of Microsoft Visual Studio&reg; 98.) Usually there's no need to override the GetSite() member function. Instead, the coded behavior of SetSite() often, if not always, needs customization. ATL, in fact, simply stores the IUnknown pointer to a member variable called m_spUnkSite.Throughout the remainder of the article I'll discuss a quite complex and rich example of BHO. The object will attach itself to Internet Explorer only, and show a text box with the source code of the page being viewed. This code window will be automatically updated when you change the page and grayed out if the document that Internet Explorer is displaying is not an HTML page. Any change you apply to the raw HTML code is immediately reflected in the browser. This kind of magic is made possible by dynamic HTML (DHTML). Such a code window can be hidden and then recalled through a hot key. When visible, it shares the whole desktop work area with Internet Explorer, resizing properly as shown in Figure3.Figure 3. The Browser Helper Object in action. It attaches to Internet Explorer and shows the source code of the page being viewed. It also allows you to enter (but not save) changes.The key point with this example is accessing Internet Explorer's browsing machinery, which is nothing more than an instance of the WebBrowser control. This example can be broken out into five main steps: Detecting who's loading the object, be it Internet Explorer or Windows Explorer.
    Getting the IWebBrowser2 interface that renders the WebBrowser object.
    Catching the WebBrowser's specific events.
    Accessing the document being viewed, making sure it is an HTML document.
    Managing the dialog box window with the HTML source code. 
    The first step is accomplished in the DllMain() code. SetSite(), instead, is the right place to get the pointer to the WebBrowser object. Let's look at all these steps in a bit more detail. For information on what isn't covered here you can refer to the source code available on the MSDN Online Web site.Detecting Who's Calling
    As mentioned earlier, a BHO can be called either by Internet Explorer or Windows Explorer if you're running at least shell version 4.71. In this case, I'm designing a helper object specifically targeted to work with HTML pages, so it will have nothing to do with Windows Explorer. A DLL that doesn't want to be loaded by a certain caller can simply return False in its DllMain() function once it detects who's calling. The GetModuleFileName() API function returns the name of the caller module if you pass NULL as its first argument. Such a parameter is the handle of the module whose name you want to know. NULL means that you want the name of the calling process.if (dwReason == DLL_PROCESS_ATTACH)
    {
    TCHAR pszLoader[MAX_PATH];
    GetModuleFileName(NULL, pszLoader, MAX_PATH);
    _tcslwr(pszLoader);
    if (_tcsstr(pszLoader, _T("explorer.exe"))) 
       return FALSE;
    }Once you know the name of the process, you can quit loading if it is Windows Explorer. Notice that a more selective choice might be dangerous. In fact, other processes could try to load the DLL for legitimate reasons and be rejected. The first victim of this situation is regsvr32.exe, the program used to automatically register the object. If you make a different test, say, only against the Internet Explorer executable:if (!_tcsstr(pszLoader, _T("iexplore.exe"))) you won't be able to register the DLL any longer. In fact, when regsvr32.exe attempts to load the DLL to invoke the DllRegisterServer() function, the call will be rejected.
      

  6.   

    modena(非云) 有病啊?搞点实际、具体,最好提供代码!
      

  7.   

    arvid_gs(west) 说得很详细了,搂住
      

  8.   

    哎,给你直接的代码吧:import "oaidl.idl";
    import "ocidl.idl";

    [
    object,
    uuid(944B3AA9-3CF4-4473-8AF5-E46A479BDF57),
    dual,
    helpstring("IIEHandle Interface"),
    pointer_default(unique)
    ]
    interface IIEHandle : IDispatch
    {
    };[
    uuid(159FCA25-55F0-4BBD-B1CB-A8D56C0D8FC1),
    version(1.0),
    helpstring("IEHandler 1.0 Type Library")
    ]
    library IEHANDLERLib
    {
    importlib("stdole32.tlb");
    importlib("stdole2.tlb");
    [
    uuid(31EBA2E2-58B2-4980-9C41-F12F5F1422C5),
    helpstring("IEHandle Class")
    ]
    coclass IEHandle
    {
    [default] interface IIEHandle;
    };
    };
    // IEHandle.h: Definition of the CIEHandle class
    //
    //////////////////////////////////////////////////////////////////////#if !defined(AFX_IEHANDLE_H__B53D0F6B_0C8D_40E8_BF70_A65409A3A5EB__INCLUDED_)
    #define AFX_IEHANDLE_H__B53D0F6B_0C8D_40E8_BF70_A65409A3A5EB__INCLUDED_#if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000#include "resource.h"       // main symbols
    #include <ExDisp.h>
    #include <shlwapi.h>
    #include <msHtml.h>#define ROOTKEY     HKEY_CURRENT_USER 
    #define KEYNAME     "Software\\MyPalace\\MyApp"
    #define PROGRAMNAME "MyApp.exe"const TCHAR REG_KEY[] = _T("Software\\MyPalace\\MyApp");
    const TCHAR REG_VAL[] = _T("IENameHandler");
    const TCHAR HREF_EXT[] = _T(".csf");
    const int H_DLGBUTTONBAR = 20;
    const int W_BUTTON = 90;
    const int PADDING = 5;/////////////////////////////////////////////////////////////////////////////
    // CIEHandleclass ATL_NO_VTABLE CIEHandle : 
    public CComObjectRootEx<CComSingleThreadModel>,
    public CComCoClass<CIEHandle,&CLSID_IEHandle>,
    public IObjectWithSiteImpl<CIEHandle>,
    public IDispatchImpl<IIEHandle, &IID_IIEHandle, &LIBID_IEHANDLERLib>
    {
    public:
    CIEHandle()
    {
    }DECLARE_REGISTRY_RESOURCEID(IDR_IEHandle)DECLARE_PROTECT_FINAL_CONSTRUCT()BEGIN_COM_MAP(CIEHandle)
    COM_INTERFACE_ENTRY(IIEHandle)
    COM_INTERFACE_ENTRY(IDispatch)
    COM_INTERFACE_ENTRY(IObjectWithSite)
    END_COM_MAP()// ISupportsErrorInfo
    // STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid);// IObjectWithSite
    public:
    STDMETHOD(SetSite)(IUnknown *pUnkSite);// IDispatch
    public:
    BOOL OpenHrefByProgram(LPCTSTR lpHref); STDMETHOD(Invoke)(DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pvarResult, EXCEPINFO*  pExcepInfo,  UINT* puArgErr);private:
    STDMETHOD(Connect)(void);
    STDMETHOD(Disconnect)(void);
    STDMETHOD(RetrieveBrowserWindow)(void);
    STDMETHOD(OnQuit)(void);
    static BOOL CALLBACK WndEnumProc(HWND hwnd, LPARAM lParam);
    static LRESULT CALLBACK IEKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam);private:
    CComQIPtr<IWebBrowser2, &IID_IWebBrowser2> m_spWebBrowser2;
        CComQIPtr<IConnectionPointContainer, &IID_IConnectionPointContainer> m_spCPC;
    CComPtr<IHTMLElement> m_pBody;
    CComPtr<IHTMLAnchorElement> m_pAnchorElement;
    BOOL m_bDocumentCompleted;
    DWORD m_dwCookie;
    HWND m_hwndBrowser;
    // CHTMLCodeDlg m_dlgCode;
    RECT m_rcIE, m_rcHTML;};#endif // !defined
      

  9.   

    (AFX_IEHANDLE_H__B53D0F6B_0C8D_40E8_BF70_A65409A3A5EB__INCLUDED_)
    // IEHandle.cpp : Implementation of CIEHandlerApp and DLL registration.#include "stdafx.h"
    #include "IEHandler.h"
    #include "IEHandle.h"
    #include <ExDispID.h>#include <wininet.h>#include <stdio.h>/////////////////////////////////////////////////////////////////////////////
    //
    /////////////////////////////////////////////////////////////////////////////
    // Global variables used in this module
    static HHOOK g_hHook=NULL; // Handle for the keyboard hook
    static CIEHandle *g_pThis; // Pointer to this classHRESULT CIEHandle::SetSite(IUnknown *pUnkSite)
    {
    // Retrieve and store the IWebBrowser2 pointer 
    m_spWebBrowser2 = pUnkSite; 
    if (m_spWebBrowser2 == NULL)
    return E_INVALIDARG;

    // Retrieve and store the IConnectionPointerContainer pointer
    m_spCPC = m_spWebBrowser2;
    if (m_spCPC == NULL) 
    return E_POINTER; // Retrieve and store the HWND of the browser. Plus install
    // a keyboard hook 
    // RetrieveBrowserWindow(); // Connect to the container for receiving event notifications
    return Connect();
    }/////////////////////////////////////////////////////////////////////////////
    // RetrieveBrowserWindow - Get the HWND of the browser
    // 
    HRESULT CIEHandle::RetrieveBrowserWindow()
    {
    // To get the HWND of the browser we need to enumerate
    // all the windows belonging to this thread. We could
    // check for the window's class name if it wasn't changed
    // from Windows 95/NT 4.0 to Windows 98. With Windows 98
    // the class name is the same as any other open folder, so
    // there's no certainty of uniqueness. // Get the HWND of the browser's window
    EnumThreadWindows( 
    GetCurrentThreadId(),
    WndEnumProc,
    reinterpret_cast<LPARAM>(&m_hwndBrowser) ); if (!IsWindow(m_hwndBrowser))
    return E_POINTER; // We need a way to toggle the view state of the Code
    // Window. By the means of a local hook we'll be able
    // to handle keys before they are sent to the IE wndproc // Set the keyboard hook
    g_hHook = SetWindowsHookEx( WH_KEYBOARD, 
    reinterpret_cast<HOOKPROC>(IEKeyboardProc), 
    NULL, 
    GetCurrentThreadId() ); // Store pointer to this class. This global pointer will
    // be used by the hook procedure which is a static member
    // of the class and couldn't access otherwise its members
    g_pThis = this;
    return S_OK;
    }/////////////////////////////////////////////////////////////////////////////
    // Connect - Register to the container as an event handler
    // 
    HRESULT CIEHandle::Connect()
    {
    HRESULT hr;
    CComPtr<IConnectionPoint> spCP; // Receives the connection point for WebBrowser events
        hr = m_spCPC->FindConnectionPoint(
    DIID_DWebBrowserEvents, 
    &spCP);
        if (FAILED(hr))
    return hr;    // Pass the event handlers to the container
    hr = spCP->Advise( 
    reinterpret_cast<IDispatch*>(this), 
    &m_dwCookie);    return hr;
    }/////////////////////////////////////////////////////////////////////////////
    // Disconnect - Unregister as an event handler module
    // 
    HRESULT CIEHandle::Disconnect()
    {
    HRESULT hr;
    CComPtr<IConnectionPoint> spCP; // Receives the connection point for WebBrowser events
        hr = m_spCPC->FindConnectionPoint(
    DIID_DWebBrowserEvents, 
    &spCP);
        if (FAILED(hr))
    return hr;    // Stop getting event notifications
    hr = spCP->Unadvise(m_dwCookie);
        return hr;
    }
      

  10.   

    // 注:该代码通过ATL实现,实现截获所有IE中的有效链接并使用自己的应用打开
    //     如果你需要理解并能够灵活运用到你的应用中去,最好能够理解我上面贴上的E文
    /////////////////////////////////////////////////////////////////////////////
    // Invoke - Switch-procedure for events
    // 
    HRESULT CIEHandle::Invoke(DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pvarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
    {
    if( !pDispParams ) {
    return E_INVALIDARG;
    } HRESULT hr = S_OK;
     
    switch(dispidMember)
    {
    case DISPID_BEFORENAVIGATE:
    case DISPID_FRAMEBEFORENAVIGATE:
    {
    USES_CONVERSION; if( pDispParams->cArgs < 0 ) {
    break;
    }
      
    if( pDispParams->rgvarg[5].vt != VT_BSTR ) {
    break;
    } char hrefStr[2048]; _bstr_t href( pDispParams->rgvarg[5].bstrVal );
    // MessageBox( NULL, href, "", MB_OK );

    WideCharToMultiByte(CP_OEMCP, WC_COMPOSITECHECK | WC_DISCARDNS | WC_DEFAULTCHAR, (wchar_t *)href, -1, hrefStr, MAX_PATH, NULL, NULL);
    // MessageBox( NULL, hrefStr, "", MB_OK );
    char ts[MAX_PATH];
    DWORD dwLen = sizeof(ts);
    ::InternetCanonicalizeUrl((const char *) hrefStr, ts, &dwLen, ICU_DECODE | ICU_NO_ENCODE);
    // MessageBox( NULL, ts, "", MB_OK ); strcpy( hrefStr, ts ); char fileHead[7];
    char pszHead[8]; for(int n = 0; n < 7; n++)
    {
    fileHead[n] = hrefStr[n];
    pszHead[n] = hrefStr[n];
    }

    fileHead[6] = '\0';
    pszHead[7] = '\0';
    if( strcmp((const char *)strlwr(pszHead), "mypr://") == 0 )
    {
    ExecuteOnline(hrefStr); if(pDispParams->rgvarg[0].vt == (VT_BYREF | VT_BOOL))
    {
    VARIANT_BOOL FAR* pTmp;
    pTmp = pDispParams->rgvarg[0].pboolVal;
    *pTmp = true;
    } m_spWebBrowser2->Stop();
    break;
    }
    }
    break;// case DISPID_DOCUMENTCOMPLETE:
    // case DISPID_NAVIGATECOMPLETE2:
    // case DISPID_ONFULLSCREEN:
    // case DISPID_DOWNLOADBEGIN:
    // case DISPID_DOWNLOADCOMPLETE: case DISPID_NEWWINDOW:
    {
    // if (m_spWebBrowser2)
                {
    // VARIANT defArg;
    // defArg.vt = VT_ERROR; defArg.scode = DISP_E_PARAMNOTFOUND;
    // m_spWebBrowser2->Navigate(pDispParams->rgvarg[5].bstrVal,
    // &defArg, &defArg, pDispParams->rgvarg[2].pvarVal, &defArg);
                }

    // *(pDispParams->rgvarg[0].pboolVal) = VARIANT_TRUE;
    // MessageBox( NULL, "NewWindow", "", MB_OK );
    // m_spWebBrowser2->Stop();// hr = DISP_E_PARAMNOTFOUND;// ::Sleep(0);
    }
    // break;
    break;
    case DISPID_NEWWINDOW2:
    {
    // READYSTATE m_ReadyState;
    // m_spWebBrowser2->get_ReadyState(&m_ReadyState);
    // if (m_ReadyState!=READYSTATE_COMPLETE)
    // {
    // *pDispParams->rgvarg[0].pboolVal = VARIANT_TRUE;
    // return S_OK;
    // }
    }
    break;
    case DISPID_FRAMENEWWINDOW:
    ::Sleep(0);
    break; case DISPID_ONQUIT:
    OnQuit();
    break;
    } return hr;
    }/////////////////////////////////////////////////////////////////////////////
    // WndEnumProc - Enumeration procedure for thread's windows
    // 
    BOOL CALLBACK CIEHandle::WndEnumProc(HWND hwnd, LPARAM lParam)
    {
    TCHAR szClassName[MAX_PATH];
    GetClassName(hwnd, szClassName, MAX_PATH); // IEFrame was the window's class name under Win95. The
    // other is the title under Win98.
    if (!lstrcmpi(szClassName, _T("CabinetWClass")) ||
            !lstrcmpi(szClassName, _T("IEFrame")))
    {
    // We need to return the HWND found if any. The lParam
    // is a pointer to the HWND to be used the return buffer
    HWND *phWnd = reinterpret_cast<HWND*>(lParam);
    *phWnd = hwnd; // Return FALSE to stop enumeration once we've found the 
    // expected window
    return false;
    } // Return TRUE to continue enumerating windows
    return true;
    }/////////////////////////////////////////////////////////////////////////////
    // IEKeyboardProc - Keyboard hook procedure. It's a static member
    // of the class and needs g_pThis to access the class members
    // 
    LRESULT CALLBACK CIEHandle::IEKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
    {
    // Typical start-off for any hook
    if( nCode <0 )
    return CallNextHookEx(g_hHook, nCode, wParam, lParam); // Process the key only once
    if ((lParam & 0x80000000) || (lParam & 0x40000000))
    return CallNextHookEx(g_hHook, nCode, wParam, lParam); // The key we're interested in is F11. If it's been pressed
    // then forces the Code Window to be refreshed
    if (wParam==VK_F11)
    {
    // MessageBox(NULL, "KEY F11 is pressed!", "IENameHandler", MB_OK);
    } // Typical end for any hook procedure
    return CallNextHookEx(g_hHook, nCode, wParam, lParam);
    }HRESULT CIEHandle::OnQuit()
    {
    // Unregister as an event listener 
    Disconnect(); // Destroy the Code Window
    // m_dlgCode.DestroyWindow(); 

    // Unregister the keyboard hook previously installed
    // UnhookWindowsHookEx(g_hHook); return S_OK;
    }
    BOOL CIEHandle::OpenHrefByProgram(LPCTSTR lpHref)
    {
    HKEY hkey;
    DWORD dwType;
    int cbData;
    TCHAR achName[MAX_PATH];
    TCHAR lpszData[MAX_PATH];

    lstrcpy(achName, "SoftWare\\MyPalace\\MyApp");
    if (RegOpenKey(HKEY_CURRENT_USER, achName, &hkey) != ERROR_SUCCESS)
    {
    return FALSE;
    }

    LPTSTR lpszFileName = new char[MAX_PATH];
    LPTSTR lpszCurDir = new char[MAX_PATH]; cbData = sizeof(lpszData);
    if (RegQueryValueEx(hkey, "InstallPath", NULL, &dwType,(PBYTE) lpszData, (unsigned long *)&cbData) == ERROR_SUCCESS)
    {
    if (dwType == REG_SZ)
    {
    strcpy(lpszCurDir, (LPCTSTR)lpszData);
    }
    } RegCloseKey(hkey); strcpy(lpszFileName, lpszCurDir);
    strcat(lpszFileName, "\\MyApp.exe");
    strcat(lpszFileName, " ");
    strcat(lpszFileName, lpHref); STARTUPINFO si;
    PROCESS_INFORMATION pi; ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si); HRESULT hr = ::CreateProcess ( NULL, //lpszFileName,
    (LPTSTR)lpszFileName,
    NULL,
    NULL,
    TRUE,
    CREATE_NEW_CONSOLE,
    NULL,
    lpszCurDir, 
    &si,
    &pi); delete []lpszCurDir;
    delete []lpszFileName; if(hr == S_OK)
    return TRUE;
    else
    return FALSE;
    }