|
When hooking the dialog in newer IE versions - things have changed - and trying to do it the original way this article outlines no longer works.
After 2 days of banging my head with the new "DirectUIHWND" - I finally managed to "force feed" the filename edit control and the combobox for the save as file type as follows:
<b>1. Change the following enum:</b>
typedef enum _SaveType
{
SAVETYPE_HTMLPAGE = 0,
SAVETYPE_ARCHIVE <b>= 1</b>,
SAVETYPE_HTMLONLY<b> = 2</b>,
SAVETYPE_TXTONLY <b>= 3</b>
} SaveType;
2. With newer versions of IE - you can no longer count on:
HWND hSaveTypeComboWnd = GetDlgItem(hwnd, 0x0470);
Therefore:
<b>a) change the UpdateSaveAs method as follows:</b>
bool CSaveAsWebbrowser::UpdateSaveAs(HWND hwnd){
// editbox : filepath (control id = 0x047c) NOTE (on older IEs)
// dropdown combo : filetypes (options=complete page;archive;html only;txt) (control id = 0x0470)
// save button : control id = 0x0001
// cancel button : control id = 0x0002
try {
if( hwnd )
m_bUpdateUI = TRUE;
// select right item in the combobox
HWND hSaveTypeComboWnd = GetDlgItem(hwnd, 0x0470);
if( IsWindow(hSaveTypeComboWnd ) ){
// Old Style
SendMessage(hSaveTypeComboWnd, CB_SETCURSEL, (WPARAM) m_nSaveType, 0);
SendMessage(hwnd, WM_COMMAND, MAKEWPARAM(0x0470,CBN_CLOSEUP), (LPARAM) hSaveTypeComboWnd);
HWND hFileNameEditCtrl = GetDlgItem(hwnd, 0x047c);
if( !hFileNameEditCtrl || !IsWindow(hFileNameEditCtrl) ){
hFileNameEditCtrl = GetDlgItem(hwnd, 0x03e9);
}
// set output filename
if( hFileNameEditCtrl && IsWindow(hFileNameEditCtrl) ){
ExchangeEditText(hFileNameEditCtrl, (LPSTR)&m_szFilename);
}
} else {
HWND hWnd1 = FindWindowEx(hwnd,0,"DUIViewWndClassName","");
if( hWnd1 ){
HWND hWnd2 = FindWindowEx(hWnd1,0,"DirectUIHWND","");
if( hWnd2 ){
EnumChildWindows (hWnd2, FloatNotifySinkChildEnumProc, (LPARAM)this) ;
}
}
}
if (m_bUpdateUI)
SendMessage(GetDlgItem(hwnd, 0x0001), BM_CLICK, 0, 0); // Invoke Save button
else
SendMessage(GetDlgItem(hwnd, 0x0002), BM_CLICK, 0, 0); // Invoke Cancel button
} catch(...){;}
return true;
}
<b>b) add the following new callback function (for the child window enum)</b>
BOOL CALLBACK FloatNotifySinkChildEnumProc (HWND hwnd, LPARAM lParam){
if (GetWindow (hwnd, GW_OWNER)) // Check for icon title
return TRUE ;
CSaveAsWebbrowser * saWb = (CSaveAsWebbrowser *) lParam;
if( saWb ){
// 1st, check to see if this window is of ComboBox class
char szWndClassName[MAX_PATH];
memset(&szWndClassName,0,MAX_PATH);
GetClassNameA(hwnd,(LPSTR)&szWndClassName,MAX_PATH);
if( lstrcmp( (LPCSTR)&szWndClassName, "FloatNotifySink" ) == 0 ){
HWND hChildControl = (HWND) GetWindow(hwnd,GW_CHILD);
if( hChildControl ){
char szChildClassName[MAX_PATH];
memset(&szChildClassName,0,MAX_PATH);
GetClassName(hChildControl,(LPSTR)&szChildClassName,MAX_PATH);
string_to_upper((LPSTR)&szChildClassName);
if( lstrcmp("COMBOBOX",(LPSTR)&szChildClassName) == 0 ){
// if it is a combobox - see if it has a "Edit" child winodw, if it does - it's the filename window, otherwise - it's the file type window.
HWND hFileNameEditWnd = FindWindowEx(hChildControl, 0, "Edit", "");
if( hFileNameEditWnd ){
saWb->AssignFileName(hFileNameEditWnd);
} else {
/* Uncomment to peek at the current combobox's selection and selected text
int iSelected = 0 ;
iSelected = (int) SendMessage(hChildControl,CB_GETCURSEL,0,0);
if( iSelected != CB_ERR ){
int iBufLen = SendMessage(hChildControl,CB_GETLBTEXTLEN,0,0);
int iMallocLen = (iBufLen * 2) + 2 ;
char * szBuffer = (char *) malloc( iMallocLen );
if( szBuffer ){
memset(szBuffer,0, iMallocLen );
SendMessage(hChildControl,CB_GETLBTEXT,(WPARAM)iSelected,(LPARAM)(LPSTR)szBuffer);
free(szBuffer);
}
}
*/
saWb->AssignFileType(hChildControl);
}
}
}
}
}
return TRUE ;
}
<b>c) and finally - add these 2 new methods to the class: </b>
void CSaveAsWebbrowser::AssignFileName(HWND hwnd){
ExchangeEditText(hwnd, (LPSTR)&m_szFilename);
}
void CSaveAsWebbrowser::AssignFileType(HWND hwnd){
SendMessage(hwnd, CB_SETCURSEL, (WPARAM) 1, 0);
SendMessage(GetParent(hwnd), WM_COMMAND, MAKEWPARAM(GetWindowLong(hwnd, GWL_ID),CBN_CLOSEUP), (LPARAM) hwnd);
}
Regards,
Rene Pilon
-- Modified Friday, July 29, 2011 6:09 PM
|
|
|
|
|
Thanks for the work!
Here are some notes and pitfalls I encountered while trying this out:
string_to_upper((LPSTR) &szChildClassName);
if(lstrcmp("COMBOBOX",(LPSTR) &szChildClassName) == 0){...}
string_to_upper() was unknown to my VS 2008 package, so I deleted that line and used the case insensitive version of lstrcmp() named lstrcmpi() in the following line.
void CSaveAsWebbrowser::AssignFileName(HWND hwnd){
ExchangeEditText(hwnd, (LPSTR) &m_szFilename);
}
"ExchangeEditText()" expects type "CString &" as second argument, "m_szFilename" is already of type CString therefore the cast to "(LPSTR) &" is erroneous.
Same goes for
if( hFileNameEditCtrl && IsWindow(hFileNameEditCtrl) ){
ExchangeEditText(hFileNameEditCtrl, (LPSTR) &m_szFilename);
in "CSaveAsWebbrowser::UpdateSaveAs()"
By mistake I defined the new callback function
BOOL CALLBACK FloatNotifySinkChildEnumProc()
as a member function of CSaveAsWebbrowser.
Problem you get is that it never resolves to the required type in the call to
EnumChildWindows(hWnd2, FloatNotifySinkChildEnumProc, (LPARAM)this);
Therefore "FloatNotifySinkChildEnumProc()" should be defined as global function.
When doing so, one should be aware though, that it perfoms calls to
"CSaveAsWebbrowser::AssignFileName()"
and
"CSaveAsWebbrowser::AssignFileType()"
hence these 2 new methods must be declared as public members of class CSaveAsWebbrowser.
Last thing:
In
void CSaveAsWebbrowser::AssignFileType(HWND hwnd){
SendMessage(hwnd, CB_SETCURSEL, (WPARAM) 1, 0);
SendMessage(GetParent(hwnd), WM_COMMAND, MAKEWPARAM(GetWindowLong(hwnd, GWL_ID),CBN_CLOSEUP), (LPARAM) hwnd);
}
I don't see any access to the file type stored in "m_nSaveType".
The type does change from "complete web page" but it always saves as archive.
Am I missing something?
In this context I also noticed one major drawback of the presented solution:
As it looks, flicking through the child windows of the "Save As" dialog box using EnumChildWindows() always finds the edit control for the filename first and then the combo box for file type. This way IE will always dictate you its file extension no matter what you specify in "m_wbSaveAs.Config("filename","filetype")".
|
|
|
|
|
Good stuff.
I posted the sample code to show how I managed to get it working before I modded it further for my needs. You are correct about the CB_SETCURSEL - it's selecting the 2nd choice in the save type combobox - and this is very dependent in IE always having MHT as the 2nd option in the combobox. As well - I should have put the enum value instead of the 1 directly.
Rene.
|
|
|
|
|
Having taken a second look at this I have now solved my requests to a satisfactory degree.
1. In
void CSaveAsWebbrowser::AssignFileType(HWND hwnd)
{
SendMessage(hwnd, CB_SETCURSEL, (WPARAM) 1, 0);
SendMessage(GetParent(hwnd), WM_COMMAND, MAKEWPARAM(GetWindowLong(hwnd, GWL_ID),CBN_CLOSEUP), (LPARAM) hwnd);
}
The first SendMessage() should read
SendMessage(hwnd, CB_SETCURSEL, (WPARAM) m_nSaveType, 0);
if you want your website to be saved in a format other than an archive.
2. As regards the order of the selection of the controls the Save as dialog box turned out to be rather bitchy.
Say you want your website to be saved under the name "Source.txt" with save type HTMLONLY then the program would fill in "Source.txt" under filename and then select "HTML only" from the combobox, thus changing the filename to "Source.htm".
So I tried to reverse the order by storing the windows handle for the edit control in a variable and performing the selection of the save type first. The filename gets filled in correctly but the dialog box doesn't use it and reverts to the default name "yahoo.htm" ("yahoo.com" being the website of the example code).
Second approach: Performing the EnumChildWindows() function twice, first for the combobox (works) then for the edit control (didn't do anything). Resulting filename: "yahoo.htm"
Back to method 1: Filling in the edit control twice: "Source.txt" (first edit) -> "Source.htm" (after combobox selection) -> "Source.txt" (second edit) -> "Source.htm" (resulting filename).
Obviously the edit control needs something else before accepting the submitted string (like the combobox needing a CBN_CLOSEUP message) but I haven't figured out what this might be.
I did find out however, that performing a "Select All" (Ctrl+A) on the edit control does the trick.
Well, maybe not the most elegant solution by someone who knows what he is doing and what is going on in the internals of MS Windows, but here are the code changes:
Add the variable m_hFileNameEditWnd of type HWND as a public member to the class CSaveAsWebbrowser .
Add 3 lines to UpdateSaveAs()
bool CSaveAsWebbrowser::UpdateSaveAs(HWND hwnd)
{
try
{
if(hwnd)
m_bUpdateUI = TRUE;
HWND hSaveTypeComboWnd = GetDlgItem(hwnd, 0x0470);
if(IsWindow(hSaveTypeComboWnd))
{
SendMessage(hSaveTypeComboWnd, CB_SETCURSEL, (WPARAM) m_nSaveType, 0);
SendMessage(hwnd, WM_COMMAND, MAKEWPARAM(0x0470, CBN_CLOSEUP), (LPARAM) hSaveTypeComboWnd);
HWND hFileNameEditCtrl = GetDlgItem(hwnd, 0x047c);
if(!hFileNameEditCtrl || !IsWindow(hFileNameEditCtrl))
hFileNameEditCtrl = GetDlgItem(hwnd, 0x03e9);
if(hFileNameEditCtrl && IsWindow(hFileNameEditCtrl))
ExchangeEditText(hFileNameEditCtrl, m_szFilename);
}
else
{
HWND hWnd1 = FindWindowEx(hwnd,0,"DUIViewWndClassName","");
if(hWnd1)
{
HWND hWnd2 = FindWindowEx(hWnd1,0,"DirectUIHWND","");
if(hWnd2)
{
m_hFileNameEditWnd = NULL;
EnumChildWindows(hWnd2, FloatNotifySinkChildEnumProc, (LPARAM) this);
if(m_hFileNameEditWnd)
AssignFileName(m_hFileNameEditWnd);
}
}
}
if (m_bUpdateUI)
SendMessage(GetDlgItem(hwnd, 0x0001), BM_CLICK, 0, 0); else
SendMessage(GetDlgItem(hwnd, 0x0002), BM_CLICK, 0, 0); }
catch(...){;}
return true;
}
Change 1 line of FloatNotifySinkChildEnumProc()
BOOL CALLBACK FloatNotifySinkChildEnumProc(HWND hwnd, LPARAM lParam)
{
if (GetWindow(hwnd, GW_OWNER)) return TRUE;
CSaveAsWebbrowser *saWb = (CSaveAsWebbrowser *) lParam;
if(saWb)
{
char szWndClassName[MAX_PATH];
memset(&szWndClassName, 0, MAX_PATH);
GetClassNameA(hwnd, (LPSTR)&szWndClassName, MAX_PATH);
if(lstrcmp((LPCSTR)&szWndClassName, "FloatNotifySink") == 0)
{
HWND hChildControl = (HWND) GetWindow(hwnd, GW_CHILD);
if(hChildControl)
{
char szChildClassName[MAX_PATH];
memset(&szChildClassName, 0, MAX_PATH);
GetClassName(hChildControl, (LPSTR) &szChildClassName, MAX_PATH);
if(lstrcmpi("COMBOBOX", (LPSTR)&szChildClassName) == 0)
{
HWND hFileNameEditWnd = FindWindowEx(hChildControl, 0, "Edit", "");
if(hFileNameEditWnd)
saWb->m_hFileNameEditWnd = hFileNameEditWnd;
else
{
saWb->AssignFileType(hChildControl);
}
}
}
}
}
return TRUE;
}
Finally to get AssignFileName() to send Ctrl+A:
void CSaveAsWebbrowser::AssignFileName(HWND hwnd)
{
ExchangeEditText(hwnd, m_szFilename);
SendMessage(hwnd, WM_KEYDOWN, 0x00000011, 0x001D0001); SendMessage(hwnd, WM_KEYDOWN, 0x00000041, 0x001E0001); SendMessage(hwnd, WM_CHAR, 0x00000001, 0x001E0001);
SendMessage(hwnd, WM_KEYUP, 0x00000041, 0xC01E0001);
SendMessage(hwnd, WM_KEYUP, 0x00000011, 0xC01D0001);
}
|
|
|
|
|
I am navigating to a secure website and i need to click on a file to save it as and I am trying to interact with the dialog box to save as a certain file
Any help would be greatly appreciated
Thanks
|
|
|
|
|
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
|
|
|
|
|
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
|
|
|
|
|
Hello!
I use this code to run success on Windows Xp (whith IE8) but can't exact on Windows 7 (with IE8).
Help me!
|
|
|
|
|
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 !
|
|
|
|
|
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
|
|
|
|
|
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
|
|
|
|
|
Is this possible? I am also a VB.net user but any info or sample would be very helpfull. thanks
|
|
|
|
|
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?
|
|
|
|
|
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
|
|
|
|
|
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
|
|
|
|
|
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.
|
|
|
|
|
What has this to do with the article?
|
|
|
|
|
Ofcourse it is not related but some one working with printers may respond.
|
|
|
|
|
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
|
|
|
|
|
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
|
|
|
|
|
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!!!
Some idea??
thanks.
Great and Excellent job!
|
|
|
|
|
http://www.codeproject.com/shell/iesaveas.asp?msg=483194#xx483194xx
|
|
|
|
|
Thanks.
What about the flickering prob?
|
|
|
|
|
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
|
|
|
|
|
How can I save the modified HTML page to local using C++?
|
|
|
|
|