c# gdi+ failed to drawlines - c#

So I am trying to create a smart crosshair controlled by win 10 voice recognition engine for a game.
The form 1 is used to turn on and turn off voice recognition .If it hears my saying "slow", it will draw a line on another transparent overlaying form
public partial class Form1 : Form
{
formoverlay overlayform = new formoverlay();
SpeechRecognitionEngine dasSpeechEngine = new SpeechRecognitionEngine();
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
dasSpeechEngine.RecognizeAsync(RecognizeMode.Multiple);
btnDisable.Enabled = true;
}
private void Form1_Load(object sender, EventArgs e)//load event
{
Choices commands = new Choices();
commands.Add(new string[] { "slow", "medium", "fast","ultra","x"});
GrammarBuilder gbuilder = new GrammarBuilder();
gbuilder.Append(commands);
Grammar thegrammar = new Grammar(gbuilder);
dasSpeechEngine.LoadGrammarAsync(thegrammar);
dasSpeechEngine.SetInputToDefaultAudioDevice();
dasSpeechEngine.SpeechRecognized += dasSpeechEngine_SpeechRecognized;
overlayform.timestart = DateTime.Now.Second;
//MessageBox.Show(overlayform.timestart.ToString());
//for (si=1,si)
}
private void dasSpeechEngine_SpeechRecognized(object sender, SpeechRecognizedEventArgs e)
{
switch (e.Result.Text)
{
case "slow":
if (ModifierKeys.HasFlag(Keys.Control))//prevent accidentally sight change
{
//clear current canvas
//draw all the lines that has true bool flag
//draw all the marks
overlayform.theclearform();
overlayform.paintHorline(15, slowAimSet.lineStartY,slowAimSet.lineEndY,1);
break;
}
break;
}
}
}
On the overlay form, the code (not including the partial class declaration):
Graphics g;
Pen myPen = new Pen(Color.Green);
Pen smallPen = new Pen(Color.GreenYellow);
public formoverlay()
{
InitializeComponent();
}
private void formoverlay_Load(object sender, EventArgs e)
{
this.BackColor = Color.Wheat;
this.TransparencyKey = Color.Wheat;
this.TopMost = true;
this.FormBorderStyle = FormBorderStyle.None;
int initialStyle = GetWindowLong (this.Handle, -20);
SetWindowLong(this.Handle, -20, initialStyle | 0x80000 | 0x20);
//enable click through
//get wows window size;
GetWindowRect(handle, out rect);
this.Size = new Size(rect.right - rect.left, rect.bottom - rect.top);
this.Top = rect.top;
this.Left = rect.left;
smallPen.Width = 2.0f;
}
public void paintHorline(int theTgtSpd,int tStartY, int tEndY, int thisRngMarkerDir)
{
int rngMarkerOffset = 10;
//aimlineForSpeed[] thisAimLine = new aimlineForSpeed [4];
//g.DrawLine(myPen, 500,500, 600, 600);
g.DrawLine(myPen, 0,tStartY, 1920, tEndY);
}
public void theclearform()//everytime user say, re-draw everything
{
Invalidate();
}
When I run the program, when I say "slow", there us an errorenter image description here
saying system argument exception: {"Parameter is not valid."}
It does not make any difference if I write constant values in my draw calls, for example, g.DrawRectangle(myPen, 100, 100, 200,200);
Apparently, the program calls "painthorline" function, but it does not draw correctly.
If I create a new graphics in painthorline method, it won't cause this error, but it does not draw anything at all..
Where did I go wrong?
Did I need to create a sperate event in order to get the drawline/drawrectangle call works?

Related

Resize rectangle with form Size in real time?

Here is the following rectangle below:
When I resize the form, I need this rectangle to match the size of the form.
When changing the width of the rectangle, do not interfere with its visibility within the form.
I'm using the following:
Note:
I did the rectangle manually, but if you have rectangle ready, better yet!
public Form1()
{
InitializeComponent();
this.Paint += Form1_Paint;
this.rectangles = new Dictionary<string, Rectangle>();
this.sizeScreen = this.Size;
this.sizeRectangles = new Size(8, 8);
this.brush = new SolidBrush(Color.Red);
FillLeft();
FillRight();
FillUp();
FillDown();
}
private Size sizeScreen;
private Size sizeRectangles;
private SolidBrush brush;
private Dictionary<string, Rectangle> rectangles;
private void FillLeft()
{
Rectangle rectangle = new Rectangle()
{
Height = this.sizeScreen.Height,
Width = this.sizeRectangles.Width,
X = 0,
Y = this.sizeRectangles.Height
};
this.rectangles.Add("left", rectangle);
}
private void FillRight()
{
Rectangle rectangle = new Rectangle()
{
Height = this.sizeScreen.Height,
Width = this.sizeRectangles.Width,
X = this.sizeScreen.Width - (this.sizeRectangles.Width * 5),
Y = this.sizeRectangles.Height
};
this.rectangles.Add("right", rectangle);
}
private void FillUp()
{
Rectangle rectangle = new Rectangle()
{
Height = this.sizeRectangles.Height,
Width = this.sizeScreen.Width,
X = 0,
Y = this.sizeRectangles.Height
};
this.rectangles.Add("up", rectangle);
}
private void FillDown()
{
Rectangle rectangle = new Rectangle()
{
Height = this.sizeRectangles.Height,
Width = this.sizeScreen.Width,
X = 0,
Y = this.sizeScreen.Height - (this.sizeRectangles.Height * 11)
};
this.rectangles.Add("down", rectangle);
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
for (int i = 0; i < this.rectangles.Count; i++)
{
e.Graphics.FillRectangles(this.brush, this.rectangles.Values.ToArray());
}
}
I want to set the rectangle on the form when it is resized
This is the way I'm creating the rectangle, but it does not stay right on the screen, to resize it I do not know
I think this would simplify what you are trying to do:
const int PenWidth = 10;
private void Form1_Paint(object sender, PaintEventArgs e)
{
Rectangle r = this.ClientRectangle;
Pen pen = new Pen(Color.Red, PenWidth);
e.Graphics.DrawRectangle(pen, r);
}
You could even add a margin:
const int PenWidth = 10;
const int PenMargin = 10;
private void Form1_Paint(object sender, PaintEventArgs e)
{
Rectangle r = this.ClientRectangle;
r.Inflate(-PenMargin, -PenMargin);
Pen pen = new Pen(Color.Red, PenWidth);
e.Graphics.DrawRectangle(pen, r);
}
To prevent traces (suggested by Wyck):
private void Form1_Resize(object sender, EventArgs e)
{
Invalidate();
}
Handle the Resize event and call Invalidate in the handler. Create a Pen of the desired color and width and set its Alignment to Inset. Handle the Paint event and in the handler call DrawRectangle passing in the ClientRectangle of the form.
Here is an example.
const float borderWidth = 8.0f;
Pen borderPen = new Pen(Color.Red, borderWidth) { Alignment = System.Drawing.Drawing2D.PenAlignment.Inset };
public Form2()
{
InitializeComponent();
this.Paint += Form2_Paint;
this.Resize += Form2_Resize;
}
private void Form2_Resize(object sender, EventArgs e)
{
Invalidate();
}
private void Form2_Paint(object sender, PaintEventArgs e)
{
e.Graphics.DrawRectangle(borderPen, this.ClientRectangle);
}
Apply the following fixes to the code:
Set ResizeRedraw property of the form to true. It sets the underlying style for the form so by each resize it sends the paint message and you don't need to handle Resize event.
Use DrawRectangle and draw using wide pen. So you don't need to fill multiple rectangles.
Set the PenAlignment to Inset. So you don't need to calculate the location of rectangle.
Do dispose the pen when you don't need it.
Example
public Form1()
{
InitializeComponent();
ResizeRedraw = true;
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
using (var pen = new Pen(Color.Red, PenWidth))
{
pen.Alignment = System.Drawing.Drawing2D.PenAlignment.Inset;
e.Graphics.DrawRectangle(pen, ClientRectangle);
}
}
i have used this on my current project. when ever you resize the form, it will automatically resize all the object inside your form
i have class named clsResize and i call this on the form load.
1st you have to initialize the class inside the form then create 2 new method.
see example below
public partial class frmNewForm : Form
{
clsResize _form_resize;
public string selectedProd;
public frmNewForm()
{
InitializeComponent();
_form_resize = new clsResize(this);
this.Load += _Load;
this.Resize += _Resize;
}
private void _Load(object sender, EventArgs e)
{
_form_resize._get_initial_size();
}
private void _Resize(object sender, EventArgs e)
{
_form_resize._resize();
}
}
and here is the class that i used.
public class clsResize
{
List<System.Drawing.Rectangle> _arr_control_storage = new List<System.Drawing.Rectangle>();
private bool showRowHeader = false;
public clsResize(Form _form_)
{
form = _form_; //the calling form
_formSize = _form_.ClientSize; //Save initial form size
_fontsize = _form_.Font.Size; //Font size
}
private float _fontsize { get; set; }
private System.Drawing.SizeF _formSize {get;set; }
private Form form { get; set; }
public void _get_initial_size() //get initial size//
{
var _controls = _get_all_controls(form);//call the enumerator
foreach (Control control in _controls) //Loop through the controls
{
_arr_control_storage.Add(control.Bounds); //saves control bounds/dimension
//If you have datagridview
if (control.GetType() == typeof(DataGridView))
_dgv_Column_Adjust(((DataGridView)control), showRowHeader);
}
}
public void _resize() //Set the resize
{
double _form_ratio_width = (double)form.ClientSize.Width /(double)_formSize.Width; //ratio could be greater or less than 1
double _form_ratio_height = (double)form.ClientSize.Height / (double)_formSize.Height; // this one too
var _controls = _get_all_controls(form); //reenumerate the control collection
int _pos = -1;//do not change this value unless you know what you are doing
try
{
foreach (Control control in _controls)
{
// do some math calc
_pos += 1;//increment by 1;
System.Drawing.Size _controlSize = new System.Drawing.Size((int)(_arr_control_storage[_pos].Width * _form_ratio_width),
(int)(_arr_control_storage[_pos].Height * _form_ratio_height)); //use for sizing
System.Drawing.Point _controlposition = new System.Drawing.Point((int)
(_arr_control_storage[_pos].X * _form_ratio_width), (int)(_arr_control_storage[_pos].Y * _form_ratio_height));//use for location
//set bounds
control.Bounds = new System.Drawing.Rectangle(_controlposition, _controlSize); //Put together
//Assuming you have a datagridview inside a form()
//if you want to show the row header, replace the false statement of
//showRowHeader on top/public declaration to true;
if (control.GetType() == typeof(DataGridView))
_dgv_Column_Adjust(((DataGridView)control), showRowHeader);
//Font AutoSize
control.Font = new System.Drawing.Font(form.Font.FontFamily,
(float)(((Convert.ToDouble(_fontsize) * _form_ratio_width) / 2) +
((Convert.ToDouble(_fontsize) * _form_ratio_height) / 2)));
}
}
catch(Exception e)
{
MessageBox.Show(e.Message);
return;
}
}
private void _dgv_Column_Adjust(DataGridView dgv, bool _showRowHeader) //if you have Datagridview
//and want to resize the column base on its dimension.
{
int intRowHeader = 0;
const int Hscrollbarwidth = 5;
if (_showRowHeader)
intRowHeader = dgv.RowHeadersWidth;
else
dgv.RowHeadersVisible = false;
for (int i = 0; i < dgv.ColumnCount; i++)
{
if (dgv.Dock == DockStyle.Fill) //in case the datagridview is docked
dgv.Columns[i].Width = ((dgv.Width - intRowHeader) / dgv.ColumnCount);
else
dgv.Columns[i].Width = ((dgv.Width - intRowHeader - Hscrollbarwidth) / dgv.ColumnCount);
}
}
private static IEnumerable<Control> _get_all_controls(Control c)
{
return c.Controls.Cast<Control>().SelectMany(item =>
_get_all_controls(item)).Concat(c.Controls.Cast<Control>()).Where(control =>
control.Name != string.Empty);
}
}

Can I draw shapes within buttons?

I've been reading stackoverflow for a while now just to learn, and I've come across a situation where I can finally ask a question. I'm making a Simon Says type memory game, where I flash shapes at the user, and the user has to click a button in the same order the shapes were shown to them. I want to draw the shape that I'm drawing on the screen within the button that they are clicking because it's much easier to remember and compare shapes to shapes rather than shapes to a button that says the shapes name.
Hopefully my question is clear, and thanks for taking a look!
Yes, you can set the Image property of Button. Alternatively, you can draw non-rectangular buttons, that is, buttons of any shape. The following code demonstrates both techniques:
using System;
using System.Drawing;
using System.Windows.Forms;
class ShapeButton : Button {
public Action<PaintEventArgs> DoPaint { get; set; }
protected override void OnPaint(PaintEventArgs e) {
if (DoPaint != null) { DoPaint(e); }
}
}
static class Program {
static void Main() {
// Ellipse button
ShapeButton ellipseButton = new ShapeButton();
ellipseButton.Location = new Point(10, 10);
ellipseButton.Size = new Size(80, 80);
ellipseButton.DoPaint = delegate(PaintEventArgs e) {
Graphics graphics = e.Graphics;
SolidBrush brush1 = new SolidBrush(SystemColors.ButtonFace);
graphics.FillRectangle(brush1, 0, 0, ellipseButton.Width, ellipseButton.Height);
SolidBrush brush2 = new SolidBrush(Color.Red);
graphics.FillEllipse(brush2, 0, 0, ellipseButton.Width, ellipseButton.Height);
};
ellipseButton.Click += delegate(object sender, EventArgs e) {
MessageBox.Show("Ellipse!");
};
// Triangle button
ShapeButton triangleButton = new ShapeButton();
triangleButton.Location = new Point(100, 10);
triangleButton.Size = new Size(80, 80);
triangleButton.DoPaint = delegate(PaintEventArgs e) {
Graphics graphics = e.Graphics;
SolidBrush brush1 = new SolidBrush(SystemColors.ButtonFace);
graphics.FillRectangle(brush1, 0, 0, triangleButton.Width, triangleButton.Height);
SolidBrush brush2 = new SolidBrush(Color.Green);
Point[] points = {
new Point(triangleButton.Width / 2, 0),
new Point(0, triangleButton.Height),
new Point(triangleButton.Width, triangleButton.Height)
};
graphics.FillPolygon(brush2, points);
};
triangleButton.Click += delegate(object sender, EventArgs e) {
MessageBox.Show("Triangle!");
};
// Star button (using image)
Button starButton = new Button();
starButton.Location = new Point(190, 10);
starButton.Size = new Size(80, 80);
starButton.Image = new Bitmap("Star.png");
starButton.Click += delegate(object sender, EventArgs e) {
MessageBox.Show("Star!");
};
// The form
Form form = new Form();
form.Text = "Shape Button Test";
form.ClientSize = new Size(280, 100);
form.Controls.Add(ellipseButton);
form.Controls.Add(triangleButton);
form.Controls.Add(starButton);
form.ShowDialog();
}
}
Result (after clicking on the triangle button):
In winforms to change the button's image at runtime you can use something like this:
button1.Image = new Bitmap(Image.FromFile(#"Pictures\Koala.jpg"));
It should be added to event handler. For example if you want to show the image when the button is clicked you subscribe to Click event of the button and add the code into the handler method:
private void button1_Click(object sender, EventArgs e)
{
button1.Image = new Bitmap(Image.FromFile(#"Pictures\Koala.jpg"));
}
In my example,
I have a pictureBox to show, two buttons, one to control, one to be drawn.
//odd display, even draw
int count = 0;
Image storePicture;
//whenever the background image changed,store it
private void pictureBoxShow_BackgroundImageChanged(object sender, EventArgs e)
{
//you can stored to a Image array if you have series pictures to show
storePicture = pictureBoxShow.BackgroundImage;
}
private void buttonControl_Click(object sender, EventArgs e)
{
count++;
//odd show picture, even draw picture on button
if (count % 2 == 1)
pictureBoxShow.BackgroundImage = new Bitmap("shapes.JPG");
else
{
//in case you want to clear text on the button
buttonDrawn.Text = null;
//recreate the picture so that it fit the button size
buttonDrawn.Image = new Bitmap(storePicture, new Size(buttonDrawn.Width, buttonDrawn.Height));
}
}
Please remember to attach the handlers to corresponding events. ^^
Why not using PictureBox instead of Buttons.
you have just to add your task to its event/OnClick
Of course you can load any Image to any PictureBox in runtime
The code above is great, however you can click outside the circle within a square containing the circle and get the click event.
If you want to capture the click only if the user clicks inside the shape you have to set the region property with something like this
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
GraphicsPath gp = new GraphicsPath();
gp.AddEllipse(0, 0, 100, 100);
Button1.Region = new Region(gp);
}
}

Printing a Form/UserControl in C#

My Program: Contains a form with few textboxes and one button. 'Default Printer' is set as Adobe PDF on my computer.
My Goal: Want to take a screenshot of a form/usercontrol when the user clicks 'Print' button. The screenshot is then saved on the desktop in .pdf format.
My Problem: I have following two problems with the code:
Size of Screenshot: The size of the screenshot is too big and it does not fit the size of the page (default page size) when printed/converted to .pdf. Please refer the two images below. I want the entire screenshot to fit inside the page.
Asks twice where to convert and save: When I click on 'Print Form' button, programs asks me TWICE where to print/convert and save the file. I want the program to ask me only Once, where to print and save the file.
Problem 1: The screenshot captured by the program does not fit the page when printed.
I want the screenshot image to fit like this on one page of .pdf:
Code:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
button1.Text = "Print Form";
button1.Click += new EventHandler(button1_Click);
printDocument1.PrintPage += new PrintPageEventHandler(printDocument1_PrintPage);
this.Controls.Add(button1);
}
private void button1_Click(object sender, EventArgs e)
{
CaptureScreen();
printDocument1.Print();
}
Bitmap memoryImage;
private void CaptureScreen()
{
Graphics myGraphics = this.CreateGraphics();
Size s = this.Size;
memoryImage = new Bitmap(s.Width, s.Height, myGraphics);
Graphics memoryGraphics = Graphics.FromImage(memoryImage);
memoryGraphics.CopyFromScreen(this.Location.X, this.Location.Y, 0, 0, s);
}
private void printDocument1_PrintPage(System.Object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
e.Graphics.DrawImage(memoryImage, 0, 0);
}
}
Thanks for your help in advance. I am a newbie, learning c# language and your help will be much appreciated. :)
Ok, check this out, and the modified printDocument1_PrintPage in particular:
private void printDocument1_PrintPage(object sender, PrintPageEventArgs e)
{
// calculate width and height scalings taking page margins into account
var wScale = e.MarginBounds.Width / (float)_memoryImage.Width;
var hScale = e.MarginBounds.Height / (float)_memoryImage.Height;
// choose the smaller of the two scales
var scale = wScale < hScale ? wScale : hScale;
// apply scaling to the image
e.Graphics.ScaleTransform(scale, scale);
// print to default printer's page
e.Graphics.DrawImage(_memoryImage, 0, 0);
}
I moved all the event wireup into InitializeComponent where it's usually supposed to go but it's more involved code:
using System;
using System.Drawing;
using System.Drawing.Printing;
using System.Windows.Forms;
namespace testScreenCapScale
{
public partial class Form1 : Form
{
public Form1() { InitializeComponent(); }
private void button1_Click(object sender, EventArgs e)
{
CaptureScreen();
printDocument1.Print();
}
private Bitmap _memoryImage;
private void CaptureScreen()
{
// put into using construct because Graphics objects do not
// get automatically disposed when leaving method scope
using (var myGraphics = CreateGraphics())
{
var s = Size;
_memoryImage = new Bitmap(s.Width, s.Height, myGraphics);
using (var memoryGraphics = Graphics.FromImage(_memoryImage))
{
memoryGraphics.CopyFromScreen(Location.X, Location.Y, 0, 0, s);
}
}
}
private void printDocument1_PrintPage(object sender, PrintPageEventArgs e)
{
// calculate width and height scalings taking page margins into account
var wScale = e.MarginBounds.Width / (float)_memoryImage.Width;
var hScale = e.MarginBounds.Height / (float)_memoryImage.Height;
// choose the smaller of the two scales
var scale = wScale < hScale ? wScale : hScale;
// apply scaling to the image
e.Graphics.ScaleTransform(scale, scale);
// print to default printer's page
e.Graphics.DrawImage(_memoryImage, 0, 0);
}
}
}
Form1.Designer.cs
namespace testScreenCapScale
{
partial class Form1
{
private System.ComponentModel.IContainer components = null;
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
components.Dispose();
base.Dispose(disposing);
}
private void InitializeComponent()
{
this.printDocument1 = new System.Drawing.Printing.PrintDocument();
this.button1 = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// printDocument1
//
this.printDocument1.PrintPage += new System.Drawing.Printing.PrintPageEventHandler(this.printDocument1_PrintPage);
//
// button1
//
this.button1.Location = new System.Drawing.Point(64, 220);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(75, 23);
this.button1.TabIndex = 0;
this.button1.Text = "button1";
this.button1.UseVisualStyleBackColor = true;
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(384, 377);
this.Controls.Add(this.button1);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
}
private System.Drawing.Printing.PrintDocument printDocument1;
private System.Windows.Forms.Button button1;
}
}

c# how to print window form without window form borders

I have a window form. I want to print the contents of the form without the window appearance. I mean I want to print it like a receipt, without window borders. How do I do this?
You can take the MSDN example on how to Print to a Windows Form, Change the Surface being printed from the Form to a Panel Control, which will enable you to print without Borders. Your Contents will have to be added to the Panel instead of the Form but it will work. Here is a modified example of the MSDN example.
public class Form1 : Form
{
private Panel printPanel = new Panel();
private Button printButton = new Button();
private PrintDocument printDocument1 = new PrintDocument();
public Form1()
{
printPanel.Size = this.ClientSize;
this.Controls.Add(printPanel);
printButton.Text = "Print Form";
printButton.Click += new EventHandler(printButton_Click);
printDocument1.PrintPage += new PrintPageEventHandler(printDocument1_PrintPage);
printPanel.Controls.Add(printButton);
}
void printButton_Click(object sender, EventArgs e)
{
CaptureScreen();
printDocument1.Print();
}
Bitmap memoryImage;
private void CaptureScreen()
{
Graphics myGraphics = printPanel.CreateGraphics();
Size s = printPanel.Size;
memoryImage = new Bitmap(s.Width, s.Height, myGraphics);
Graphics memoryGraphics = Graphics.FromImage(memoryImage);
Point screenLoc = PointToScreen(printPanel.Location); // Get the location of the Panel in Screen Coordinates
memoryGraphics.CopyFromScreen(screenLoc.X, screenLoc.Y, 0, 0, s);
}
private void printDocument1_PrintPage(System.Object sender,
System.Drawing.Printing.PrintPageEventArgs e)
{
e.Graphics.DrawImage(memoryImage, 0, 0);
}
public static void Main()
{
Application.Run(new Form1());
}
}
you can just get a blank screen by doing something like this
this.FormBorderStyle = System.Windows.Forms.FormsBorderStyle.None;
this.ControlBox = false;
this.Text = String.Empty;

How to draw a screenshot "preview" window?

I have a Winforms application that the user uses to take a region based screenshot. I want to have a small preview pane, but i'm not sure how to do it. So far i tried recreating a bitmap on mouse move and its just way too laggy to be usable. So i thought if i used a pre-defined image (screenshot of the whole screen) and moved it inside the picturebox based off the mouse location so that you get a zoomed in look at the screen (to select the precise pixels you want to take the screenshot with easier). I'm not sure how i can implement this, i am also pretty new to drawing so i will show you what i have now.
private void falseDesktop_MouseMove(object sender, MouseEventArgs e)
{
zoomBox.Image = showZoomBox(e.Location);
zoomBox.Invalidate();
}
private Image showZoomBox(Point curLocation)
{
int x = 0;
int y = 0;
if (curLocation.X - 12 <= 0)
{
x = curLocation.X - 12;
}
else
{
x = curLocation.X;
}
if (curLocation.Y - 11 <= 0)
{
y = curLocation.Y - 11;
}
else
{
y = curLocation.Y;
}
Point start = new Point(curLocation.X - 12, curLocation.Y - 11);
Size size = new Size(24, 22);
Rectangle rect = new Rectangle(start, size);
Image selection = cropImage(falseDesktop.Image, rect);
return selection;
}
private static Image cropImage(Image img, Rectangle cropArea)
{
if (cropArea.Width != 0 && cropArea.Height != 0)
{
Bitmap bmpImage = new Bitmap(img);
Bitmap bmpCrop = bmpImage.Clone(cropArea, bmpImage.PixelFormat);
bmpImage.Dispose();
return (Image)(bmpCrop);
}
return null;
}
EDIT:
Here is a mock up like requested:
The black part of this image is a panel, of course the text being a label and the area where you see the image (stack overflow) would be the picturebox (called zoomBox) the lines on top of the zoomBox would be a guide and where the 2 lines intersect would be the mouse position. Hope this is a better assist to help you understand my issue.
Another thing that might help explain my issue is The form actually fills the entire screen with a "false desktop". its a picturebox that covers the entire screen with a screenshot of the desktop when "printscreen" was pressed. So I want this little "preview pane" to basically be a zoomed in location of where the mouse is.
This is a little bit laggy, but worth a try:
It's a WInForms app in a single file showing how a "live" zoom might work. It doesn't paint the cross hairs etc. that's up to you.
Key Parts:
_scale
PictureBoxSizeMode.StretchImage
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Drawing.Imaging;
static class Program {
[STAThread]
static void Main() {
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
public class Form1 : Form {
private Bitmap _myImage = new Bitmap(#"C:\Users\Public\Pictures\Sample Pictures\LightHouse.jpg");
private int _scale = 10; // keep this < 15
private PictureBox pboxMain;
private PictureBox pboxZoom;
private System.ComponentModel.IContainer components;
public Form1() {
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e) {
pboxMain.Image = _myImage;
}
private void pboxMain_MouseMove(object sender, MouseEventArgs e) {
try {
Rectangle rc = new Rectangle(
new Point(e.X - _scale, e.Y - _scale),
new Size(_scale * 2, _scale * 2));
pboxZoom.Image = _myImage.Clone(rc, PixelFormat.DontCare);
}
catch (OutOfMemoryException ex) {/* ignore... */}
}
protected override void Dispose(bool disposing) {
if (disposing && (components != null)) {
components.Dispose();
}
base.Dispose(disposing);
}
private void InitializeComponent() {
this.pboxMain = new PictureBox();
this.pboxZoom = new PictureBox();
((System.ComponentModel.ISupportInitialize)(this.pboxMain)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.pboxZoom)).BeginInit();
this.SuspendLayout();
this.pboxMain.Dock = DockStyle.Fill;
this.pboxMain.Location = new System.Drawing.Point(0, 0);
this.pboxMain.Name = "pboxMain";
this.pboxMain.Size = new System.Drawing.Size(767, 435);
this.pboxMain.TabIndex = 0;
this.pboxMain.TabStop = false;
this.pboxMain.MouseMove += new MouseEventHandler(this.pboxMain_MouseMove);
this.pboxZoom.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))),
((int)(((byte)(255)))), ((int)(((byte)(192)))));
this.pboxZoom.BorderStyle = BorderStyle.FixedSingle;
this.pboxZoom.Location = new System.Drawing.Point(12, 12);
this.pboxZoom.Name = "pboxZoom";
this.pboxZoom.Size = new System.Drawing.Size(106, 83);
this.pboxZoom.SizeMode = PictureBoxSizeMode.StretchImage;
this.pboxZoom.TabIndex = 1;
this.pboxZoom.TabStop = false;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(767, 435);
this.Controls.Add(this.pboxZoom);
this.Controls.Add(this.pboxMain);
this.Name = "Form1";
this.Text = "Form1";
this.Load += new System.EventHandler(this.Form1_Load);
((System.ComponentModel.ISupportInitialize)(this.pboxMain)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.pboxZoom)).EndInit();
this.ResumeLayout(false);
}
}
This should be of great help TeboScreen: Basic C# Screen Capture
Why reinvent the Wheel :-)

Categories

Resources