Problem with SHDocVW Internetexplorer PlugIn - Cancel Event

H

Hautzendorfer

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)
 
Y

Yan-Hong Huang[MSFT]

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.
 
H

Hautzendorfer

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_PrintTemplateTeardownEvent e)
{
// HERE I SHOULD GET THE INFORMATION
// WETHER THE USER PUSHED CANCEL OR PRINT!!!!!!!!!!!!
this.Close();
}
 
Y

Yan-Hong Huang[MSFT]

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-us/winui/winui/windowsuserinterface/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.programming.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.
 
H

Hautzendorfer

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
 
Y

Yan-Hong Huang[MSFT]

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/issues/02/11/CuttingEdge/TOC.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.aspx?scid=fh;EN-US;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.
 
H

Hautzendorfer

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;
}
}
 
Y

Yan-Hong Huang[MSFT]

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.
 
Y

Yan-Hong Huang[MSFT]

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.
 
H

Hautzendorfer

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).
 
Y

Yan-Hong Huang[MSFT]

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top