Click here to Skip to main content
Email Password   helpLost your password?

Introduction

The purpose of this article is to show how to automate the fully fledged Save As HTML feature from Internet Explorer, which is normally hidden to those using the Internet Explorer API. Saving the current document as MHTML format is just one of the options available, including:

Saving Silently as HTML Using the Internet Explorer API

In fact, the ability to save the current web page for storage without showing a single dialog box is already available to everyone under C++, using the following code, with an important restriction:

LPDISPATCH lpDispatch = NULL;
IPersistFile *lpPersistFile = NULL;

// m_ctrl is an instance of the Web Browser control

lpDispatch = m_ctrl.get_Document();
lpDispatch->QueryInterface(IID_IPersistFile, (void**)&lpPersistFile);

lpPersistFile->Save(L"c:\\htmlpage.html",0);
lpPersistFile->Release();
lpDispatch->Release();

(caption for code above) Saving HTML code only, without dialog boxes

The restriction is that we are talking about the HTML code only, not the web page. Of course, what is interesting is to gain access to full HTML archives with images and so on.

Because there is no "public" or known way to ask for this feature without showing one or more dialog boxes from Internet Explorer, what we are going to do is hook the operating system to listen all window creations, including the dialog boxes. Then we'll ask Internet Explorer for the feature and override the file path from the dialog boxes without being seen. Finally, we'll mimic the user clicking on the Save button to validate the dialog box and unhook ourselves. That's done!

Hooking Internet Explorer to Save As HTML without popping the dialog boxes

This was the short workflow, but there are a few tricks to get along and this article is a unique opportunity to go into detail. By the way, the code is rooted by an article from MS about how to customize Internet Explorer Printing by hooking the Print dialog boxes; see here or here. In our app, we have our own Save As feature:

m_wbSaveAs.Config( CString("c:\\htmlpage.mhtml"), SAVETYPE_ARCHIVE );
m_wbSaveAs.SaveAs();

// where the second parameter is the type of HTML needed :

typedef enum _SaveType
{
    SAVETYPE_HTMLPAGE = 0,
    SAVETYPE_ARCHIVE,
    SAVETYPE_HTMLONLY,
    SAVETYPE_TXTONLY
} SaveType;

We start the SaveAs() implementation by installing the hook:

// prepare SaveAs Dialog hook

//

g_hHook = SetWindowsHookEx(WH_CBT, CbtProc, NULL, GetCurrentThreadId());
if (!g_hHook)
    return false;

// make SaveAs Dialog appear

//

// cmd = OLECMDID_SAVEAS (see ./include/docobj.h)

g_bSuccess = false;
g_pWebBrowserSaveAs = this;
HRESULT hr = m_pWebBrowser->ExecWB(OLECMDID_SAVEAS, 
    OLECMDEXECOPT_PROMPTUSER, NULL, NULL);

// remove hook

UnhookWindowsHookEx(g_hHook);
g_pWebBrowserSaveAs = NULL;
g_hHook = NULL;

The hook callback procedure is just hardcore code; see for yourself:

LRESULT CALLBACK CSaveAsWebbrowser::CbtProc(int nCode, 
    WPARAM wParam, LPARAM lParam) 
{  
    // the windows hook sees for each new window being created :

    // - HCBT_CREATEWND : when the window is about to be created

    //      we check out if it is a dialog box (classid = 0x00008002, 

    //      see Spy++)

    //      and we hide it, likely to be the IE SaveAs dialog

    // - HCBT_ACTIVATE : when the window itself gets activited

    //      we run a separate thread, and let IE do his own init steps in 

    //      the mean time

    switch (nCode)
    {
        case HCBT_CREATEWND:
        {
            HWND hWnd = (HWND)wParam;
            LPCBT_CREATEWND pcbt = (LPCBT_CREATEWND)lParam;
            LPCREATESTRUCT pcs = pcbt->lpcs;
            if ((DWORD)pcs->lpszClass == 0x00008002)
            {
                g_hWnd = hWnd;          // Get hwnd of SaveAs dialog

                pcs->x = -2 * pcs->cx;  // Move dialog off screen

            }
            break;
        }    
        case HCBT_ACTIVATE:
        {
            HWND hwnd = (HWND)wParam;
            if (hwnd == g_hWnd)
            {
                g_hWnd = NULL;
                g_bSuccess = true;

                if (g_pWebBrowserSaveAs->IsSaveAsEnabled())
                {
                    g_pWebBrowserSaveAs->SaveAsDisable();

                    CSaveAsThread *newthread = new CSaveAsThread();
                    newthread->SetKeyWnd(hwnd);
                    newthread->Config( g_pWebBrowserSaveAs->GetFilename(), 
                        g_pWebBrowserSaveAs->GetSaveAsType() );
                    newthread->StartThread();
                }
            }
            break;
        }
    }
    return CallNextHookEx(g_hHook, nCode, wParam, lParam); 
}

In our thread, we wait until the Internet Explorer Save As dialog is ready with filled data:

switch(    ::WaitForSingleObject( m_hComponentReadyEvent, m_WaitTime) )
{
     ...
     if ( ::IsWindowVisible(m_keyhwnd) )
     {
         bSignaled = TRUE;
         bContinue = FALSE;
     }

     MSG msg ;
     while( PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) )
     {
         if (msg.message == WM_QUIT)
         {
              bContinue = FALSE ;
              break ;
         }
         TranslateMessage(&msg);
         DispatchMessage(&msg);
     }
     ...
}

// relaunch our SaveAs class, but now everything is ready to play with

if (bSignaled)
{
    CSaveAsWebbrowser surrenderNow;
    surrenderNow.Config( GetFilename(), GetSaveAsType() );
    surrenderNow.UpdateSaveAs( m_keyhwnd );
}

// kill the thread, we don't care anymore about it

delete this;

We can now override the appropriate data:

void CSaveAsWebbrowser::UpdateSaveAs(HWND hwnd)
{
    // editbox : filepath (control id = 0x047c)

    // dropdown combo : filetypes (options=complete page;

    //     archive;html only;txt) (control id = 0x0470)

    // save button : control id = 0x0001

    // cancel button : control id = 0x0002



    // select right item in the combobox

    SendMessage(GetDlgItem(hwnd, 0x0470), CB_SETCURSEL, 
        (WPARAM) m_nSaveType, 0);
    SendMessage(hwnd, WM_COMMAND, MAKEWPARAM(0x0470,CBN_CLOSEUP), 
        (LPARAM) GetDlgItem(hwnd, 0x0470));

    // set output filename

    SetWindowText(GetDlgItem(hwnd, 0x047c), m_szFilename);

    // Invoke Save button

    SendMessage(GetDlgItem(hwnd, 0x0001), BM_CLICK, 0, 0);  
}

In the code above, it is funny to remark that to select the kind of HTML we want (full HTML, archive, code only or text format), we not only select the adequate entry in the combo-box, we also send Internet Explorer a combo-box CloseUp notification. This is because that's what Internet Explorer has subscribed for to know we want this kind of HTML. This behavior is known by hints-and-trials.

Conclusion

This article describes a technique to gain access to the fully fledged Save As HTML feature exposed by Internet Explorer. I have never seen an article about this topic on the 'net, whereas it's easy to figure out that it is a compelling feature for developers building web applications. Files you may use from the source code provided are:

The application is just a simple MFC-based CHtmlView application embedding the web browser control.

You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
GeneralHere is perfectly working C# code
Madhava maydipalle
5:05 19 Nov '09  
Thanks for all the people on this thread. here is working example..

Usage :
To use from IE plugin :

SHDocVw.IWebBrowser2 browser = GetCurrentBrowser();
MHTHelper mhtHelper = new MHTHelper();
bool bMhtFile = mhtHelper.SaveAs(browser, filePath, EnumBrowserFileSaveType.SAVETYPE_ARCHIVE);



#region ---- EnumBrowserFileSaveType ----
public enum EnumBrowserFileSaveType
{
SAVETYPE_HTMLPAGE = 0,
SAVETYPE_ARCHIVE,
SAVETYPE_HTMLONLY,
SAVETYPE_TXTONLY
}
#endregion

public class MHTHelper
{
#region ---- Constructor ----
public MHTHelper()
{
}
#endregion
#region ---- Private Attributes ----
private IWebBrowser2 webBrowser;
private string filePath;
private EnumBrowserFileSaveType saveType;
private WindowHookProc HookProcedure;
private int windowHook = 0;
private IntPtr hwndSaveAsDlg = (IntPtr)0;
private MHTHelper saveAsMht = null;

#endregion
#region ---- Public Attributes ----
public IWebBrowser2 WebBrowser
{
get { return webBrowser; }
set { webBrowser = value; }
}

public string FilePath
{
get { return filePath; }
set { filePath = value; }
}
public EnumBrowserFileSaveType SaveType
{
get { return saveType; }
set { saveType = value; }
}
#endregion
#region ---- SaveAs ----
/// <summary>
/// In this function we are automating the following functionality.
/// 1.Select 'File->Save AS' menu item on IE
/// 2.Take SaveAS dialog out of screen so that user cannot interact with it.(we cannot hide it, because of IE security policy.)
/// 3.Set the required file path to the save as dialog.
/// 4.Click on save button.
/// 5.IE automatically display the status bar to show the extraction process of currently displayed web page into mht file.
/// </summary>
/// <param name="webBrowser"></param>
/// <param name="pathFile"></param>
/// <param name="saveType"></param>
/// <returns></returns>
public bool SaveAs(IWebBrowser2 webBrowser, string pathFile, EnumBrowserFileSaveType saveType)
{
try
{
this.WebBrowser = webBrowser;
this.FilePath = pathFile;
this.SaveType = saveType;
//If no path is supplied or file already exists then it prompts for user action.
if (0 == pathFile.Length)
pathFile = "untitled";
if ((null == webBrowser) || (0 != windowHook))
return false;

this.HookProcedure = new WindowHookProc(this.SaveAsHookProc);
// prepare SaveAs dialog hook and activate it.
this.windowHook = SetWindowsHookEx(5 /*WH_CBT*/, HookProcedure, (IntPtr)0, AppDomain.GetCurrentThreadId());
if (this.windowHook == 0)
return false;
try
{
// This following code shows the save as dialog
this.saveAsMht = this;
object o = null;
webBrowser.ExecWB(SHDocVw.OLECMDID.OLECMDID_SAVEAS, SHDocVw.OLECMDEXECOPT.OLECMDEXECOPT_PROMPTUSER, ref o, ref o);
this.saveAsMht = null;
return true;
}
finally
{
//Here we took out our hook .
UnhookWindowsHookEx(this.windowHook);
this.windowHook =0;
}
}
catch (Exception ex)
{
ExceptionHandler.Display(ex);
return false;
}
}

#endregion
#region ---- SaveAsHookProc ----
/// <summary>
/// This proc is required to handle Window messages and do appropriate action for our requirements.
/// </summary>
/// <param name="nCode"></param>
/// <param name="wParam"></param>
/// <param name="lParam"></param>
/// <returns></returns>
public int SaveAsHookProc(int nCode, IntPtr wParam, IntPtr lParam)
{
switch (nCode)
{
case 3: // HCBT_CREATEWND
CBT_CREATEWND cw = (CBT_CREATEWND)Marshal.PtrToStructure(lParam, typeof(CBT_CREATEWND));
CREATESTRUCT cs = (CREATESTRUCT)Marshal.PtrToStructure(cw.lpcs, typeof(CREATESTRUCT));
if (cs.lpszClass == 0x00008002)
{
this.hwndSaveAsDlg = (IntPtr)wParam; // Get hwnd of SaveAs dialog
cs.x = -2 * cs.cx; // Move dialog off screen
}
break;
case 5: // HCBT_ACTIVATE
IntPtr hwnd = (IntPtr)wParam;
//Here we get Save as dialog handle
if (hwnd == this.hwndSaveAsDlg && this.hwndSaveAsDlg != (IntPtr)0)
{
//Prepare a thread to act as required messages source.Also set File path and its save type.
ThreadPressOk tpok = new ThreadPressOk(hwnd, this.saveAsMht.FilePath, this.saveAsMht.SaveType);
this.hwndSaveAsDlg = (IntPtr)0;
// Create a thread to execute the task, and then
// start the thread.
new Thread((new ThreadStart(tpok.ThreadProc))).Start();
}
break;
}
//This is required to pass control to next hook if exists on this process.
return CallNextHookEx(this.windowHook, nCode, wParam, lParam);
}

#endregion
#region ---- Win32APIs ----
//Import for SetWindowsHookEx.
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
public static extern int SetWindowsHookEx(int idHook, WindowHookProc lpfn, IntPtr hInstance, int threadId);

//Import for UnhookWindowsHookEx.
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
public static extern bool UnhookWindowsHookEx(int idHook);

//Import for CallNextHookEx.
//Use this function to pass the hook information to next hook procedure in chain.
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
public static extern int CallNextHookEx(int idHook, int nCode, IntPtr wParam, IntPtr lParam);
//This delegate is required to fetch our function to the thread.
public delegate int WindowHookProc(int nCode, IntPtr wParam, IntPtr lParam);

//These Win32 structures are requred to handle windows messages/state
[StructLayout(LayoutKind.Sequential)]
public struct CBT_CREATEWND
{
public IntPtr lpcs;
int hwndInsertAfter;
};
[StructLayout(LayoutKind.Sequential)]
public struct CREATESTRUCT
{
int lpCreateParams;
int hInstance;
int hMenu;
int hwndParent;
int cy;
public int cx;
int y;
public int x;
int style;
int lpszName;
public int lpszClass;
int dwExStyle;
}
#endregion
#region ---- Thread Requirements ----
//The following class is defined here because it is used in the above class only.
//It sends all required thread messages to IE's save as dialog.
class ThreadPressOk
{
public ThreadPressOk(IntPtr hwnd, string pathFile, EnumBrowserFileSaveType saveType)
{
this.hwndDialog = hwnd;
this.pathFile = pathFile;
this.saveType = saveType;
}

IntPtr hwndDialog;
string pathFile;
EnumBrowserFileSaveType saveType;

// Imports of the User32 DLL.
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, int lParam);

[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr GetDlgItem(IntPtr hWnd, int nIDDlgItem);

[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern private bool SetWindowText(IntPtr hWnd, string lpString);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool IsWindowVisible(IntPtr hWnd);

// The thread procedure performs the message loop and place the data
public void ThreadProc()
{
//To avoid race condition, we are forcing this thread to wait until Saveas dialog is displayed.
while (!IsWindowVisible(hwndDialog))
{
Thread.Sleep(100);
Application.DoEvents();
}
Application.DoEvents();
//Get the handle to SaveType combo box on the save as dialog.
IntPtr typeB = GetDlgItem(hwndDialog, 0x0470);
//Get the handle to file path on the saveas dialog.
IntPtr nameB = GetDlgItem(hwndDialog, 0x047c);
//Get the handle to saveas on the saveas dialog.
IntPtr saveBtn = GetDlgItem(hwndDialog, 0x0001);

if (((IntPtr)0 != typeB) && ((IntPtr)0 != nameB) && ((IntPtr)0 != saveBtn) && IsWindowVisible(hwndDialog))
{
//select save type
SendMessage(typeB, 0x014E /*CB_SETCURSEL*/, (int)saveType, 0);
SendMessage(hwndDialog, 0x0111 /*WM_COMMAND*/, 0x80470/*MAKEWPARAM(0x0470, CBN_CLOSEUP)*/, (int)typeB);
// set save as filepath
SetWindowText(nameB, pathFile);
// Invoke Save button click.
SendMessage(saveBtn, 0x00F5 /*BM_CLICK*/, 0, 0);
}
// Clean up GUI - we have clicked save button.
//GC is going to do that cleanup job, so we are OK
Application.DoEvents();
//Terminate the thread.
return;
}
}
#endregion
}

Thanks
Maydipalle

GeneralProblem with code in Windows Vista and Windows 7
Nguyễn Đức Thiện
19:29 24 Oct '09  
Hi to all, it been a long time since my last time I write/ask in the forum.
I have the problem I hope you can help me:
I’m using the guide:
http://www.codeproject.com/KB/shell/iesaveas.aspx
(Automated IE SaveAs MHTML)
I have the problem when I’m running the code in Windows Vista
In the method:
void CSaveAsWebbrowser::UpdateSaveAs(HWND hwnd)
{
// editbox : filepath (control id = 0x047c)
// dropdown combo : filetypes (options=complete page;
// archive;html only;txt) (control id = 0x0470)
// save button : control id = 0x0001
// cancel button : control id = 0x0002


// select right item in the combobox
SendMessage(GetDlgItem(hwnd, 0x0470), CB_SETCURSEL,
(WPARAM) m_nSaveType, 0);
SendMessage(hwnd, WM_COMMAND, MAKEWPARAM(0x0470,CBN_CLOSEUP),
(LPARAM) GetDlgItem(hwnd, 0x0470));

// set output filename
SetWindowText(GetDlgItem(hwnd, 0x047c), m_szFilename);

// Invoke Save button
SendMessage(GetDlgItem(hwnd, 0x0001), BM_CLICK, 0, 0);
}
The problem is that we send the control id ‘0x047c’,(for the combo box and the output file), I noticed that the method GetDlgItem(hwnd, 0x047c), return 0, I’m thinking the problem is that the code id '0x047c' in Vista is not relevant, I found out that for NT, Windows 98 and 95 the combobox and output file has different ID ‘0x0480’, I was wandering I someone know where I can found the id’s for Vista, or someone have another idea why this is not working.
Thanks
GeneralThis can't run on windows 7
Nguyễn Đức Thiện
7:09 24 Oct '09  
Hello!
I use this code to run success on Windows Xp (whith IE8) but can't exact on Windows 7 (with IE8).
Help me!
GeneralDo you know what would be the libraries use for C# ?
Battosaiii
7:31 10 Aug '09  
I would like to use custom dialog to save as webpages from internet explorer. It would be done in C#.
Do you know the libraries for C# ? I have been looking for libraries in c# but i cant find anything !
GeneralPages with big sizes are not being able to saved in IE explorer itself
HMLGUY
22:19 28 Jun '09  
Hi

I am using your application for programmatically saving file from IE
Automated IE SaveAs MHTML
Well only one small change I have made.
In your application
1)You create a separate browser control
2)Navigate it to web page
3)And then Save the file using
HRESULT hr = m_pWebBrowser->ExecWB(cmdid, OLECMDEXECOPT_PROMPTUSER, NULL, NULL);


I have included SaveAsThread.cpp and SaveAsWebBrowser.cpp in my application.
Only change I have made is in your SetWebBrowser method,
Instead of setting your application's browser control,
I get an instance of currently running IE(IE version 8) and set it in SetWebBrowser method
Then I have added one button on IE toolbar and on click of it I call

m_wbSaveAs.Config( CString(finalFilePath), SAVETYPE_ARCHIVE );
m_wbSaveAs.SaveAs()

where finalFilePath is path of file to be saved

Now when ever I surf lighter pages or pages with small size, I am able to Save pages and your program runs amazing.
But when ever i surf heavy pages for example home page of http://indiatimes.com my instance of IE gets hanged and page is not being able to saved.

Same heavy page when I surf in your application and in your web browser control instead of IE itself, application works absolutely fine and is able to save page.
Do you have any idea, why IE itself is not able to perform the same.

Any clues or help would be of great help

Thanks in advance
GeneralCan we use SetWindowsHookEx for hooking printer dialogs?
Member 3728841
18:18 10 Dec '08  
hi

Can we in any way use SetWindowsHookEx in hooking printer dialogs using printHookProc()??plz tell me otherwise how to do so?if somebody can explain giving sample code that will be more helpful to me as i'm a newbie in this..
thanks and regards
Rm
Generalcan you use the hook for retriveing the address bar content?
rerb
10:47 26 Jul '07  
Is this possible? I am also a VB.net user but any info or sample would be very helpfull. Smile thanks
GeneralExcellent! Can this be done in VB.Net?
saab340b
7:36 6 Apr '07  
I have spend days looking for this information. Now that I've finally found it, it is NOT in vb.net. Ever thought of converting it?
GeneralHow can I save HTML from IE
kallol kumar
1:47 1 Aug '06  
Hello,

cool...Its a nice work.I have a problem of saving HTML.I developed a project which is load url into Internet Explorer(shell Executing iexplore.exe). But I cann't save that Url automatically. I want to save it without showing its saveAs Dialog.I am trying it with your project. But I cann't. Can you please give me any ideas.

Thanks
Kallol

GeneralSave as xls file
xgnitesh
1:15 15 Feb '06  
Hi,
First of all I would like to thank the author for the excellent article. This works perfectly for HTML pages.
Now I have a requirement where the URL link may point to a excel file or a pdf file or any other kind of binay file. When I use the program for excel file, the save as dialog box does popup but the BM_CLICK message does not work to invoke the save button. I noticed that this is because there is another kind of save as dialog that appears when we try to save the excel file (different from the one that appears when you try to do save as for HTML pages). I thought that the resource id for save button must have changed and tried 1 to 100 all ids not just 1. But no success. Then I tried to use Spy++ drag and drop feature to identify the save button window, but unfortunately even Spy++ does not identify this save button as an independent window.

Possible questions:
How can I indentify the right button resource id?
How can invoke the save button in this new kind of save as dialog?

Any help is appreciated.

Thanks & regards,
Nitesh
QuestionHow to know whether a printer is connected or not
vijay kumar T
8:50 17 Jan '06  
I have a problem with the printer. I want to know whether a printer is physically connected and then I want to issue a print command. If any one can help me I would be greatful.

AnswerRe: How to know whether a printer is connected or not
Stephane Rodriguez.
0:00 18 Jan '06  

What has this to do with the article?

GeneralRe: How to know whether a printer is connected or not
vijay kumar T
6:35 19 Jan '06  
Ofcourse it is not related but some one working with printers may respond.
GeneralProblem in Release version
Roland Liu
18:09 15 Jan '06  
Your code is very good in debug version, but in release version, I can't save any .mhtml file. This is a big bug, I hope you find why the Problem occur only in Release version.

Zjroland from http://www.outsourcexp.com
GeneralHow to save web page silently just from the url?
Tcpip2005
18:21 6 May '05  
I mean how to save a web page without navigate to the page just from the url ?
also the save as dialog box should not be shown.

Thank you sir
Generaldesktop flickering problem and realese problem
Libi1234
21:33 19 Mar '05  
Hi,
I used your code in order to save several pages in a loop.
The problem acuur, while its in prosses. The desktop is flickering, assume when the hidden dialog being closed.
Have someone an idea how to resolve it?


--UPDATE--

In realese mode there is a problem in varibal m_bUpdateUI that somehow is always false!!!Confused
Some idea??

thanks.
Great and Excellent job!
GeneralRe: desktop flickering problem and realese problem
Stephane Rodriguez.
23:59 17 Jan '06  

http://www.codeproject.com/shell/iesaveas.asp?msg=483194#xx483194xx

GeneralRe: desktop flickering problem and realese problem
Libi1234
0:06 18 Jan '06  
Thanks.
What about the flickering prob?
GeneralHelp to without prompt dialogbox to user
baskarchinnu
0:21 28 Feb '05  
Hi
I am working in Win32 API SDK, at my program, I am hooking IE window and I am using my own BHO dll (whenever IE is open, dll will attach with IE browser) through this dll I want to save the complete web page without prompting the save as dialogbox. With your example help, I tried by using as follows

HRESULT hr = m_pWebBrowser->ExecWB(OLECMDID_SAVEAS,
MSOCMDEXECOPT_DONTPROMPTUSER, NULL, NULL);

I used MSOCMDEXECOPT_DONTPROMPTUSER options, even though I am getting dialog box and even if try to save the web page through save as dialog box also, page is not saving. I am getting the error msg "This Web page could not be saved".

Can you please help me to save the complete web page without prompting save..as dialog box.

Thanks in Advance


Baskar
GeneralSave the modified page
Berkeley Wong
8:15 20 Nov '04  
How can I save the modified HTML page to local using C++?
GeneralRe: Save the modified page
Stephane Rodriguez.
10:04 20 Nov '04  

You have to switch IE in edit mode first. There are numerous articles available out there (even a few on codeproject if I remember well).

GeneralRe: Save the modified page
Berkeley Wong
19:48 20 Nov '04  
I need to modify the HTML form's value (say one entry field Name) and then save this HTML page with the given name to the local machine. I tried to use this example to save the HTML page to local, it is OK , but the page does not contain modified value (name) in the entry field. Could you explain more and any alternative to do this in C++?
GeneralRe: Save the modified page
mcbain
11:18 3 May '07  
Did you (anyone?) ever find a solution how to save the modified html page to mht? I would be interested to know.

Regards, Fredrik
Generalwin98
NorrieTaylor
21:02 29 Aug '04  
I can't get this to work with Win98 even if use the tip mentioned in the previous thread. It seems to hang before it even gets to that point. If anyone can help I would greatly appreciate it.

Best regards,

Norrie Taylor
GeneralWin98 Different DialogID
TDK900000
6:16 10 May '04  
Great article but it fails for me using IE6 on Win98. I think the reason is that the dialog IDS are different. For example GetDlgItem(hwnd, 0x47c) returns NULL for me in UpdateSaveAs.

Does anyone know either
1. What the correct dialog IDS for win 98
2. Which dll the resource is in so I can try to find out the dialog ID
3. A way around this problem.

Cheers



Last Updated 5 Sep 2002 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2010