By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
460,022 Members | 1,372 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 460,022 IT Pros & Developers. It's quick & easy.

Problem with SHDocVW Internetexplorer PlugIn - Cancel Event

P: n/a
Hello,

I'm currently working on some printing stuff:
I have to print out several .xml files using a stylesheet.
Therefor I choose the Internetexplorer PlugIn via SHDocVW.
My problem:
After sending the print command via ExecWB for the
first .xml document either
the preview or the printer selection window occurs
(depending on the passed parameter). This behaviour is ok.
But: If the user cancels I do not know how to get this
event, so that I will no continue with the other documents
to print.
Someone has an idea!?

My implementation is based on the article:
http://msdn.microsoft.com/library/default.asp?
URL=/library/en-us/dnie55/html/wb_print.asp
(Printing with the Internet Explorer WebBrowser Control)

Jul 21 '05 #1
Share this Question
Share on Google+
10 Replies


P: n/a
Hello,

Thanks for posting in the group.

Based on my understanding, now the question is: You use Web browser control
in a Windows form to print a web page. Now you use ExecWB to print a xml
file. However, if the user clicks cancel button when in printer
selection/preview window, you want to track this event in the program so
that you won't continue print other xml files, right? Please post here if I
have misunderstood anything here.

In order to make sure how you code works, could you please post your main
code slice on creating web browser control and calling ExecWB here? After
getting it, we will perform research and reply with more information here.

Best regards,
Yanhong Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.

Jul 21 '05 #2

P: n/a
Hello Huang,
yes, that's correct.
Here you've got part of the code (C#):

private void CFrmPrint_Activated(object sender,
System.EventArgs e)
{
object nullObject = null;
this.Visible = false;
this.m_ieBrowser.Navigate(m_sDocument, ref nullObject,
ref nullObject, ref nullObject, ref nullObject);

}

private void m_ieBrowser_DocumentComplete(object sender,
AxSHDocVw.DWebBrowserEvents2_DocumentCompleteEvent e)
{
timCheckBrowser_Tick(null, null);
}

private void timCheckBrowser_Tick(object sender,
System.EventArgs e)
{
object nullObject = null;
this.timCheckBrowser.Enabled = false;

while (m_ieBrowser.Busy)
{
System.Windows.Forms.Application.DoEvents();
}

// Set the Header and the Footer
// tricky: has to be done via the Registry,
// see therefor the MSDN article:
// http://msdn.microsoft.com/library/default.asp?
URL=/library/en-us/dnie55/html/wb_print.asp

RegistryKey pRegKey = Registry.CurrentUser;

// Create: creates a new, or opens an existing key!
pRegKey = pRegKey.CreateSubKey
("Software\\Microsoft\\Internet Explorer\\PageSetup");

// store the actual header and footer for resetting
Object oHeader = pRegKey.GetValue("header");
Object oFooter = pRegKey.GetValue("footer");

pRegKey.SetValue("header", m_sHeader);
pRegKey.SetValue("footer", m_sFooter);

// PRINT METHOD
Exception ex = null;
try
{
SHDocVw.OLECMDEXECOPT opt =
SHDocVw.OLECMDEXECOPT.OLECMDEXECOPT_DODEFAULT;

//m_ieBrowser.ExecWB
(SHDocVw.OLECMDID.OLECMDID_HIDETOOLBARS,
// opt, ref nullObject, ref nullObject);

if (m_bPromptUser)
opt = SHDocVw.OLECMDEXECOPT.OLECMDEXECOPT_PROMPTUSER;
else
opt =
OHDocVw.OLECMDEXECOPT.OLECMDEXECOPT_DONTPROMPTUSER ;

if (m_bPreview)
{
m_ieBrowser.ExecWB
(SHDocVw.OLECMDID.OLECMDID_PRINTPREVIEW,
opt, ref nullObject, ref
nullObject);
}
else
{
m_ieBrowser.ExecWB(SHDocVw.OLECMDID.OLECMDID_PRINT ,
opt, ref nullObject, ref
nullObject);
}
System.Threading.Thread.Sleep(100); // because of
resetting Page layout!

/*
System.Diagnostics.PerformanceCounter PC
= new System.Diagnostics.PerformanceCounter();
PC.CategoryName = "Prozess";
PC.CounterName = "Threadanzahl";
PC.InstanceName = "FestoEngineeringTool";
m_ThreadCount = (int)PC.NextValue();
*/
}
catch (Exception ex1) { ex = ex1; }
finally
{
pRegKey.SetValue("header", oHeader);
pRegKey.SetValue("footer", oFooter);

System.Windows.Forms.Application.DoEvents
();
}
if (ex != null) throw(ex);

}
private void m_ieBrowser_PrintTemplateTeardown(object
sender,
AxSHDocVw.DWebBrowserEvents2_PrintTemplateTeardown Event e)
{
// HERE I SHOULD GET THE INFORMATION
// WETHER THE USER PUSHED CANCEL OR PRINT!!!!!!!!!!!!
this.Close();
}
-----Originalnachricht-----
Hello,

Thanks for posting in the group.

Based on my understanding, now the question is: You use Web browser controlin a Windows form to print a web page. Now you use ExecWB to print a xmlfile. However, if the user clicks cancel button when in printerselection/preview window, you want to track this event in the program sothat you won't continue print other xml files, right? Please post here if Ihave misunderstood anything here.

In order to make sure how you code works, could you please post your maincode slice on creating web browser control and calling ExecWB here? Aftergetting it, we will perform research and reply with more information here.
Best regards,
Yanhong Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
.

Jul 21 '05 #3

P: n/a
Hello,

I just reviewed the link that you mentioned in the first post. In that
artilce, we could see there is a part named "Printing Workarounds", which
introduces using CbtProcto track window messages in Page Setup dialog. I
think we may also make use of this function and the following two
parameters:

HCBT_CLICKSKIPPED
HCBT_KEYSKIPPED

http://msdn.microsoft.com/library/en...rinterface/win
dowing/hooks/hookreference/hookfunctions/cbtproc.asp?frame=true

However, as this article mentioned, this method is undocumented and
unsupported by Microsoft. There is no promise that any of these techniques
will continue to work in future versions of the product. So please use
caution when considering any of these techniques.

BTW, in the future, it would be best to post these questions in the
following newsgroup.
microsoft.public.windows.inetexplorer.ie5.programm ing.components.webbrowser_
ctl

All IE Web browser control issues, configuration and other questions are
posted in the newsgroup above.

The reason why we recommend posting appropriately is you will get the most
qualified pool of respondents, and other partners who the newsgroups
regularly can either share their knowledge or learn from your interaction
with us. Also, this is to make sure that the responders can better track
the problem. Thank you for your understanding.

Thanks again for using Microsoft MSDN Newsgroups.

Best regards,
Yanhong Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.

Jul 21 '05 #4

P: n/a
Hello,
ok ...
but how is it possible to hook messages within .NET and
C# ... I've never done this :-(

So could you please give a small example code
based on my problem!?

Thanks,
Martin

-----Originalnachricht-----
Hello,

I just reviewed the link that you mentioned in the first post. In thatartilce, we could see there is a part named "Printing Workarounds", whichintroduces using CbtProcto track window messages in Page Setup dialog. Ithink we may also make use of this function and the following twoparameters:

HCBT_CLICKSKIPPED
HCBT_KEYSKIPPED

http://msdn.microsoft.com/library/en- us/winui/winui/windowsuserinterface/windowing/hooks/hookreference/hookfunctions/cbtproc.asp? frame=true
However, as this article mentioned, this method is undocumented andunsupported by Microsoft. There is no promise that any of these techniqueswill continue to work in future versions of the product. So please usecaution when considering any of these techniques.

BTW, in the future, it would be best to post these questions in thefollowing newsgroup.
microsoft.public.windows.inetexplorer.ie5.program ming.com ponents.webbrowser_ctl

All IE Web browser control issues, configuration and other questions areposted in the newsgroup above.

The reason why we recommend posting appropriately is you will get the mostqualified pool of respondents, and other partners who the newsgroupsregularly can either share their knowledge or learn from your interactionwith us. Also, this is to make sure that the responders can better trackthe problem. Thank you for your understanding.

Thanks again for using Microsoft MSDN Newsgroups.

Best regards,
Yanhong Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
.

Jul 21 '05 #5

P: n/a
Hello Martin,

Thanks for the quick response.

In order to program Win32 Hook in a .NET Winform application, we need to
use PInvoke to call Win32 APIs. There is a good MSDN article in this area.
It introduces how to use Hook in .NET winform applications.
"Windows Hooks in the .NET Framework"
http://msdn.microsoft.com/msdnmag/is....ASP?frame=tru
e

This is a good link to start. There is no existing sample code specially on
this problem. If you want a code sample, I suggest you contact Microsoft
Product Support Service to have one engineer work with you on it.

To obtain the telephone numbers for specific technology, please review this
web site:
http://support.microsoft.com/default...S;PHONENUMBERS

If you are outside the US, you can find regional telephone support numbers
at http://support.microsoft.com.

Please post here if you have any more concerns. Thanks very much for your
understanding.

Best regards,
Yanhong Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.

Jul 21 '05 #6

P: n/a
Hello Yanhong Huang,
first thanks a lot for your succesfull help!

I do still post this question here, because now
my problems do not really relate to the IExplorer.

I installed now some hooks to get the messages from
the created windows and therefor I can catch now
wether the user prints or does not print.

BUT now I have a problem with operating system related
"features" ...

Information:
I do identify the user action via my own member:
DialogResult.
Therefor e.g. if the user pushes the "Print" button
within the Printer Dialog I do get this hook and know
now, that the user printed out some stuff.

FIRST PROBLEM:
==============
If the user opens the "Page Setup" I could not find out
a difference between the "Print" and "OK" button.
Therfor I took a look at the WindowTitle, BUT the title
is operating system language depended => therefor thats
BAD!

SECOND PROBLEM:
===============
The main point is, that I have to catch following actions:

1.) The user pushes the "Print" button.
2.) The user pushes the key <ALT>D.
3.) The user pushes <ENTER>.

ad. 1) The "Print" button can be identified via
ID = [OK-ID] ... therefor no language problem.
ad. 2) The <ALT> key kombination depends on the
operating system language ... !?
What can I do here?
ad. 3) If the user pushes <ENTER> it's the same
functionality as pushing the "Print" button.
... should be no problem.

How can I solve the above mentioned problems, so that
I can uniqually identify the difference between
printing and pagesetup dialog without taking care
of the operating system language?

Thanks in advance for your great help!!!

P.S.:
Here you have got my hook functionality:
private void HookEventHandler(object sender,
MsdnMag.HookEventArgs e)
{
StringBuilder sbHelper = new StringBuilder
();
string sWindowText = null;
sbHelper.Capacity = 256;

switch (e.HookCode)
{
case (int)HookEnumerations.HCBT_CREATEWND:
{
if (m_hWnd == (IntPtr)null)
{
m_hWnd = this.Handle; // e.wParam;
}
break;
}
case (int)
HookEnumerations.HCBT_DESTROYWND:
{
GetClassName(e.wParam, sbHelper, 256);
sWindowText = sbHelper.ToString();

/*
GetWindowText(e.wParam, sbHelper,
sbHelper.Capacity);
sWindowText = sbHelper.ToString();
if (sWindowText.CompareTo("Drucken")
== 0)
*/
// this is tricky ... hopefully it
works with
// ALL operating system languages :-(
if (sWindowText.CompareTo
("tooltips_class32") == 0)
{
m_bResultValid = true;
}
//else if (sWindowText.CompareTo
("Seite einrichten") == 0)
else if (sWindowText.CompareTo
("ComboLBox") == 0)
{
m_bResultValid = false;
}
break;
}

case (int)HookEnumerations.HCBT_SETFOCUS:
m_hWndFocusWindow = e.wParam;
//Console.WriteLine("SetFocus: " +
e.wParam.ToString());
break;

case (int)
HookEnumerations.HCBT_KEYSKIPPED:
{
int iKey = (int)e.wParam;

switch (iKey)
{
case (int)Keys.Enter:
GetWindowText
(m_hWndFocusWindow, sbHelper, sbHelper.Capacity);
sWindowText =
sbHelper.ToString();

//if (sWindowText.CompareTo
("Drucken") == 0)
{
int iCtrlID = GetDlgCtrlID
(m_hWndFocusWindow);
if (iCtrlID == (int)
ButtonEnumeration.IDD_CANCEL)
{
m_DialogResult =
DialogResult.Cancel;
}
else if (iCtrlID == (int)
ButtonEnumeration.IDD_PRINT)
{
m_DialogResult =
DialogResult.OK;
}
}
break;

case (int)18: // KeyCode for ALT
int iUp = ( (int)e.lParam >>
31 ) & 1;
if (iUp == 1) m_bAltPressed =
false;
else m_bAltPressed = true;
break;

case (int)Keys.P:
case (int)Keys.D:
// English: Print (ALT-P),
// German: Drucken (ALT-D)
if (m_bAltPressed == true)
m_DialogResult =
DialogResult.OK;
break;

default:
Console.WriteLine("Key: " +
e.wParam.ToString());
break;
}
break;
}

case (int)
HookEnumerations.HCBT_CLICKSKIPPED:
{
MOUSEHOOKSTRUCT msStruct = new
MOUSEHOOKSTRUCT();

Marshal.PtrToStructure(e.lParam,
msStruct);

GetWindowText(m_hWndFocusWindow,
sbHelper, sbHelper.Capacity);
sWindowText = sbHelper.ToString();

//if (sWindowText.CompareTo
("Drucken") == 0)
{
if ((int)e.wParam == (int)
MouseEnumerations.WM_LBUTTONUP)
{
int iCtrlID = GetDlgCtrlID
(msStruct.hwnd);
if (iCtrlID == (int)
ButtonEnumeration.IDD_CANCEL)
{
m_DialogResult =
DialogResult.Cancel;
}
else if (iCtrlID == (int)
ButtonEnumeration.IDD_PRINT)
{
m_DialogResult =
DialogResult.OK;
}

// Get the static window with
the text and the text
/*
StringBuilder sb = new
StringBuilder();
sb.Capacity = 256;
GetWindowText(msStruct.hwnd,
sb, 256);
string text = sb.ToString();
Console.WriteLine(e.ToString
() + " Code:" + e.HookCode.ToString() + " WindowText: " +
text + " wParam: " + e.wParam.ToString());
*/
}
}

break;
}

default:
break;
}
}
-----Originalnachricht-----
Hello Martin,

Thanks for the quick response.

In order to program Win32 Hook in a .NET Winform application, we need touse PInvoke to call Win32 APIs. There is a good MSDN article in this area.It introduces how to use Hook in .NET winform applications."Windows Hooks in the .NET Framework"
http://msdn.microsoft.com/msdnmag/is.../11/CuttingEdg e/TOC.ASP?frame=true

This is a good link to start. There is no existing sample code specially onthis problem. If you want a code sample, I suggest you contact MicrosoftProduct Support Service to have one engineer work with you on it.
To obtain the telephone numbers for specific technology, please review thisweb site:
http://support.microsoft.com/default.aspx?scid=fh;EN- US;PHONENUMBERS
If you are outside the US, you can find regional telephone support numbersat http://support.microsoft.com.

Please post here if you have any more concerns. Thanks very much for yourunderstanding.

Best regards,
Yanhong Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
.

Jul 21 '05 #7

P: n/a
Hello Hautzendorfer,

I am glad that we have made so much progress now. :)

For the new problem, I know that the title of each window is different on
different language version of OSs. However, the ID of the buttion should be
the same. We could get more from this clue. Please use Spy++ tool to get
the ID of the button on different systems and compare it to see if you
could get the correct ID to work on. (In the first tab of button properties
in SPY++, there is a editbox named Control ID).

For the Alt D question, you could also track message in SPY++ to see if
there is any special message sent.

However, the above method is more like a hack since the ID of the button is
not public. They may be changed. So I think defining some global strings
first to find the proper window is also a good idea.

Does that answer your question?

Best regards,
Yanhong Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.

Jul 21 '05 #8

P: n/a

Also, thanks very much for sharing your code and experience in the group.
It could help other developers much. :)

Best regards,
Yanhong Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.

Jul 21 '05 #9

P: n/a
Hello Huang,
:-( ... hopefully this is my last question!

How do I modify (setting) the Default printer
with .NET and C#?

Thanks,
Martin

P.S.:
The ID searching did not really help
(I did this before).
Actually I solved the problem as sent
in the code-part (getting the classname).
-----Originalnachricht-----
Hello Hautzendorfer,

I am glad that we have made so much progress now. :)

For the new problem, I know that the title of each window is different ondifferent language version of OSs. However, the ID of the buttion should bethe same. We could get more from this clue. Please use Spy++ tool to getthe ID of the button on different systems and compare it to see if youcould get the correct ID to work on. (In the first tab of button propertiesin SPY++, there is a editbox named Control ID).

For the Alt D question, you could also track message in SPY++ to see ifthere is any special message sent.

However, the above method is more like a hack since the ID of the button isnot public. They may be changed. So I think defining some global stringsfirst to find the proper window is also a good idea.

Does that answer your question?

Best regards,
Yanhong Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
.

Jul 21 '05 #10

P: n/a
Hello,

You are welcome. :)

.NET framework class library provides PrinterSettings class, whcih
specifies information about how a document is printed, including the
printer that prints it. However, it doesn't incude the function of setting
default printer.

To set default printer, we will have to call the SetDefaultPrinter method
through the P/Invoke layer. Also, we could use the classes in the
System.Management namespace to get the Win32_Printer WMI instance that
represents the printer, and call the SetDefaultPrinter on that WMI class.

If there are any more questions, please feel free to post in the group.
Also, a useful tip is to post new questions in a new thread. So many other
community memberts could notice it. You may get much quicker resonse from
community in that way. Surely, if the question is quite related to the
original one, posting in the same thread is much clearer.

Best regards,
Yanhong Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.

Jul 21 '05 #11

This discussion thread is closed

Replies have been disabled for this discussion.