PrintPreviewControl

G

Guest

I am using a PrintPreviewControl to show report output. I would like there to
be a way for the user to select a portion of the output, then right click and
choose an option which would trigger an event in my program. Is there a way
to do this?

I gather that PrintPreviewControl is closed and not able to be extended, is
this so? Is there a better way of showing a report prior to printing? Thanks.
 
J

Jeffrey Tan[MSFT]

Hi Richard,

Based on my understanding, your winform application is using
PrintPreviewControl. Now, you want to allow the user to select portion of
the preview image and pop up a context menu for other customized functions.
If I have misunderstood you, please feel free to tell me, thanks.

Yes, there is no build-in support for this feature. PrintPreviewControl
internally uses a MetaFile to capture the real printing output, then it
will paint the MetaFile on the control interface based on the Zoom
property.

However, PrintPreviewControl is not sealed, which means we can inherit from
this class and provide some customized function ourselves. For example, to
implement the selection function, the normal algorithm is recording the
selection start point in OnMouseDown method of PrintPreviewControl, then in
OnMouseUp method, we can record the end point. In the OnPaint method, we
can use these 2 points to draw the selection rectangle. This logic is not
hard to implement.

I have written a little sample project to demonstrate the algorithm:

internal MyPrintPreviewControl MyPrintPreviewControl1;
private System.Drawing.Printing.PrintDocument docToPrint =
new System.Drawing.Printing.PrintDocument();

private void button1_Click(object sender, System.EventArgs e)
{
// Construct the MyPrintPreviewControl.
this.MyPrintPreviewControl1 = new MyPrintPreviewControl();

// Set location, name, and dock style for MyPrintPreviewControl1.
this.MyPrintPreviewControl1.Location = new Point(88, 80);
this.MyPrintPreviewControl1.Name = "MyPrintPreviewControl1";
this.MyPrintPreviewControl1.Dock = DockStyle.Fill;

// Set the Document property to the PrintDocument
// for which the PrintPage event has been handled.
this.MyPrintPreviewControl1.Document = docToPrint;

// Set the zoom to 25 percent.
this.MyPrintPreviewControl1.Zoom = 1;

// Set the UseAntiAlias property to true so fonts are smoothed
// by the operating system.
this.MyPrintPreviewControl1.UseAntiAlias = true;

// Add the control to the form.
this.Controls.Add(this.MyPrintPreviewControl1);

// Associate the event-handling method with the
// document's PrintPage event.
this.docToPrint.PrintPage +=
new System.Drawing.Printing.PrintPageEventHandler(
docToPrint_PrintPage);
}

// The MyPrintPreviewControl will display the document
// by handling the documents PrintPage event
private void docToPrint_PrintPage(
object sender, System.Drawing.Printing.PrintPageEventArgs e)
{

// Insert code to render the page here.
// This code will be called when the control is drawn.

// The following code will render a simple
// message on the document in the control.
string text = "In docToPrint_PrintPage method.";
System.Drawing.Font printFont =
new Font("Arial", 35, FontStyle.Regular);

e.Graphics.DrawString(text, printFont,
Brushes.Black, 10, 10);
}

public class MyPrintPreviewControl: PrintPreviewControl
{
Point pt_start;
Point pt_end;
bool drawSelection=false;
protected override void OnMouseDown(MouseEventArgs e)
{
if(Control.MouseButtons==MouseButtons.Left)
{
drawSelection=true;
pt_start=new Point(e.X, e.Y);
}
else
{
drawSelection=false;
}

base.OnMouseDown (e);
}

protected override void OnMouseUp(MouseEventArgs e)
{
pt_end=new Point(e.X, e.Y);
base.OnMouseUp (e);
this.Invalidate();
}

protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint (e);
if(drawSelection)
{
e.Graphics.DrawRectangle(new Pen(new SolidBrush(Color.Red)),
new Rectangle(pt_start, new Size(pt_end.X-pt_start.X,
pt_end.Y-pt_start.Y)));
}
}
}

You may customize my sample code snippet and fit in your application.

To implement the right click context menu function, you may add the
ContextMenu component in the winform project and associate it with the
PrintPreviewControl(set PrintPreviewControl.ContextMenu property).

Hope this helps.

Best regards,
Jeffrey Tan
Microsoft Online Community Support
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 
G

Guest

That's great, thanks, I will try it.

"Jeffrey Tan[MSFT]" said:
Hi Richard,

Based on my understanding, your winform application is using
PrintPreviewControl. Now, you want to allow the user to select portion of
the preview image and pop up a context menu for other customized functions.
If I have misunderstood you, please feel free to tell me, thanks.

Yes, there is no build-in support for this feature. PrintPreviewControl
internally uses a MetaFile to capture the real printing output, then it
will paint the MetaFile on the control interface based on the Zoom
property.

However, PrintPreviewControl is not sealed, which means we can inherit from
this class and provide some customized function ourselves. For example, to
implement the selection function, the normal algorithm is recording the
selection start point in OnMouseDown method of PrintPreviewControl, then in
OnMouseUp method, we can record the end point. In the OnPaint method, we
can use these 2 points to draw the selection rectangle. This logic is not
hard to implement.

I have written a little sample project to demonstrate the algorithm:

internal MyPrintPreviewControl MyPrintPreviewControl1;
private System.Drawing.Printing.PrintDocument docToPrint =
new System.Drawing.Printing.PrintDocument();

private void button1_Click(object sender, System.EventArgs e)
{
// Construct the MyPrintPreviewControl.
this.MyPrintPreviewControl1 = new MyPrintPreviewControl();

// Set location, name, and dock style for MyPrintPreviewControl1.
this.MyPrintPreviewControl1.Location = new Point(88, 80);
this.MyPrintPreviewControl1.Name = "MyPrintPreviewControl1";
this.MyPrintPreviewControl1.Dock = DockStyle.Fill;

// Set the Document property to the PrintDocument
// for which the PrintPage event has been handled.
this.MyPrintPreviewControl1.Document = docToPrint;

// Set the zoom to 25 percent.
this.MyPrintPreviewControl1.Zoom = 1;

// Set the UseAntiAlias property to true so fonts are smoothed
// by the operating system.
this.MyPrintPreviewControl1.UseAntiAlias = true;

// Add the control to the form.
this.Controls.Add(this.MyPrintPreviewControl1);

// Associate the event-handling method with the
// document's PrintPage event.
this.docToPrint.PrintPage +=
new System.Drawing.Printing.PrintPageEventHandler(
docToPrint_PrintPage);
}

// The MyPrintPreviewControl will display the document
// by handling the documents PrintPage event
private void docToPrint_PrintPage(
object sender, System.Drawing.Printing.PrintPageEventArgs e)
{

// Insert code to render the page here.
// This code will be called when the control is drawn.

// The following code will render a simple
// message on the document in the control.
string text = "In docToPrint_PrintPage method.";
System.Drawing.Font printFont =
new Font("Arial", 35, FontStyle.Regular);

e.Graphics.DrawString(text, printFont,
Brushes.Black, 10, 10);
}

public class MyPrintPreviewControl: PrintPreviewControl
{
Point pt_start;
Point pt_end;
bool drawSelection=false;
protected override void OnMouseDown(MouseEventArgs e)
{
if(Control.MouseButtons==MouseButtons.Left)
{
drawSelection=true;
pt_start=new Point(e.X, e.Y);
}
else
{
drawSelection=false;
}

base.OnMouseDown (e);
}

protected override void OnMouseUp(MouseEventArgs e)
{
pt_end=new Point(e.X, e.Y);
base.OnMouseUp (e);
this.Invalidate();
}

protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint (e);
if(drawSelection)
{
e.Graphics.DrawRectangle(new Pen(new SolidBrush(Color.Red)),
new Rectangle(pt_start, new Size(pt_end.X-pt_start.X,
pt_end.Y-pt_start.Y)));
}
}
}

You may customize my sample code snippet and fit in your application.

To implement the right click context menu function, you may add the
ContextMenu component in the winform project and associate it with the
PrintPreviewControl(set PrintPreviewControl.ContextMenu property).

Hope this helps.

Best regards,
Jeffrey Tan
Microsoft Online Community Support
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 
J

Jeffrey Tan[MSFT]

Hi Richard,

Glad to see my reply can help you. I will still monitor this issue for 2
days for your further test result. Please feel free to feedback any concern
or further question, thanks.

Best regards,
Jeffrey Tan
Microsoft Online Community Support
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 
G

Guest

Hello Jeffery,

It has been a while since I have worked on this. Your example was helpful, I
can draw the box, and right-click to activate the other call. What I can not
do so far is know what text was in the box. I have the location of the box,
but how do I know what the text in it is? I want the user to be able to draw
the box around a word, then when they right-click, I can call a function, and
send that word. Do you know how to do this? Thanks.
 
J

Jeffrey Tan[MSFT]

Hi Richard,

Thank you for the feedback.

Since PrintPreviewControl internally will use MetaFile to record the
printing output and paint the output as images on the control surface,
there is actually no words on the control surface. The text you say on the
control surface is actually a portion of a printed image.

Since there is no real text word in your selection box, it is very hard for
us to get the "selected text word" from the selection box. If you really
wanted to get this done, we have to use some type of technology to
recognize the text word in the image. This technology is called OCR
software, but it is a bit complex and is not always 100% accurate. Also,
since Microsoft did not provide managed class library for OCR technology,
we have to resort to some 3rd party libraries for OCR.

Hope my comment makes sense to you, thanks.

Best regards,
Jeffrey Tan
Microsoft Online Community Support
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.
 
G

Guest

Thanks. Yes, that is what I thought, that it is no longer text, so I can't
use it. So there is really no benefit to me in being able to draw the box,
since I can't figure out what is inside it. So then there is no way that I
can use the PrintPreviewControl at all, because there is no way that I can
allow the user to choose some text in it, is this not so? So then I am back
to my original position, where I must write my own PrintPreviewControl, or
get some source code to adapt. Or did I miss something, and there is a way to
use the existing PrintPreviewControl? Thanks.
 
J

Jeffrey Tan[MSFT]

Hi Richard,

Thanks for your feedback.

If your requirement is be able to select any text on the form, I do not
know of any controls for this task. Actually, this is not a trivial task.
The displayed texts on the from are drawn by different controls on the
form. For example, the text in TextBox is drawn by TextBox control window
procedure. Any code may invoke DrawText/TextOut win32 GDI APIs to draw text
on the form. There is no single simple way to grab all the text on the
form.

If you really wanted to achieve this task, it is very complex. I know one
type of screen word translation software will use low-level Win32 API
hooking technology to intercept any DrawText/TextOut win32 GDI API calling
and grab the text in these APIs parameter. I think we still have to hook
the GDI+ text drawing APIs. This type of API hooking technology is complex
to implement and .Net has no support for it, you have to implement it in
Win32 C/C++ code. If you are curious regarding API hooking, please refer to
the article below:
http://www.codeproject.com/system/hooksys.asp

Anyway, this type of requirement has gone out of .Net Framework support
ability. Thanks for your understanding.

Best regards,
Jeffrey Tan
Microsoft Online Community Support
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.
 
G

Guest

Thanks again. In the end I wrote my own PrintPreviewControl, and it was not
too hard, I did not need all the capabilities of the .NET version. I record
what I have written where, so that when the user selects the text, I can look
up and see what I wrote there, it seems to work fine. Thanks for all the help.
 
J

Jeffrey Tan[MSFT]

Hi Richard,

Glad to see you have implemented what you want. If you need further help,
please feel free to post, thanks.

Best regards,
Jeffrey Tan
Microsoft Online Community Support
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================

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