Hi Utkarsh,
I made a little app that mimics the magnifier behaviour you talked about,
with an image on the left and a magnified version on the right. I loaded a
3MB file and it seems to take about 50% of the CPU on my home computer when I
move the mouse very rapidly, but with no flickering.
I have 3 files:
1. ZoomSelectorPictureBox.cs -> displays an image with a red rectangle
around the mouse indicating where the zoomed in portion of the image will be
displayed. This inherits from PictureBox (although it doesn't really need to)
2. ZoomMagnifierPictureBox which shows a zoomed in version of the selected
region in ZoomSelectorPictureBox, this also inherits from picturebox
3. Form1.cs -> creates instances of the above classes. you will need to
modify the Form1_Load method to load an image on your computer.
I have pasted all three files below, but the formatting will be messed up in
these windows. If you like you can download the entire source from
http://www.markdawson.org/software/csharp/magnifier.zip which may be easier
than getting the text code out from below.
//FORM1.cs
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
namespace WindowsApplication4
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
public Form1()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
//
// TODO: Add any constructor code after InitializeComponent call
//
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(800, 469);
this.Name = "Form1";
this.Text = "Form1";
this.Load += new System.EventHandler(this.Form1_Load);
}
#endregion
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
private void Form1_Load(object sender, System.EventArgs e)
{
ZoomSelectorPictureBox selectorPictureBox = new ZoomSelectorPictureBox();
selectorPictureBox.Image = Image.FromFile(@"c:\test.bmp");
this.Controls.Add(selectorPictureBox);
selectorPictureBox.Left = 0;
selectorPictureBox.Top = 0;
selectorPictureBox.Width = 400;
selectorPictureBox.Height = 400;
ZoomMagnifierPictureBox zoomMagnifier = new
ZoomMagnifierPictureBox(selectorPictureBox);
this.Controls.Add(zoomMagnifier);
zoomMagnifier.Left = 400;
zoomMagnifier.Top = 0;
zoomMagnifier.Width = 400;
zoomMagnifier.Height = 400;
}
}
}
//ZoomMagnifierPictureBox.cs
using System;
using System.Windows.Forms;
using System.Drawing;
namespace WindowsApplication4
{
public class ZoomMagnifierPictureBox : PictureBox
{
private Rectangle _zoomRegion;
private Image _originalImage;
public ZoomMagnifierPictureBox(ZoomSelectorPictureBox zoomSelector) : base()
{
_originalImage = zoomSelector.Image;
zoomSelector.ZoomRectangleChanged += new
WindowsApplication4.ZoomSelectorPictureBox.ZoomRec tangleLocationChangedEventHandler(zoomSelector_Zoo mRectangleChanged);
}
protected override void OnPaintBackground(PaintEventArgs pevent)
{
//base.OnPaintBackground (pevent);
}
protected override void OnPaint(PaintEventArgs e)
{
//base.OnPaint (e);
e.Graphics.DrawImage(_originalImage, new Rectangle(0,0, this.Width,
this.Height), _zoomRegion.X, _zoomRegion.Y, _zoomRegion.Width,
_zoomRegion.Height, GraphicsUnit.Pixel);
}
private void zoomSelector_ZoomRectangleChanged(Rectangle zoomRectangle)
{
_zoomRegion = zoomRectangle;
this.Refresh();
}
}
}
//ZoomSelectorPictureBox.cs
using System;
using System.Windows.Forms;
using System.Drawing;
namespace WindowsApplication4
{
public class ZoomSelectorPictureBox : PictureBox
{
private Rectangle _zoomRegion;
private bool _mouseIsOver = false;
public delegate void ZoomRectangleLocationChangedEventHandler(Rectangle
zoomRectangle);
public event ZoomRectangleLocationChangedEventHandler ZoomRectangleChanged;
public ZoomSelectorPictureBox() : base()
{
//create zoom region rectangle
_zoomRegion = new Rectangle(0, 0, 50, 50);
//set up event handlers
this.MouseMove += new MouseEventHandler(ZoomSelectorPictureBox_MouseMove );
this.MouseLeave += new EventHandler(ZoomSelectorPictureBox_MouseLeave);
this.MouseEnter += new EventHandler(ZoomSelectorPictureBox_MouseEnter);
}
protected override void OnPaintBackground(PaintEventArgs pevent)
{
//base.OnPaintBackground (pevent);
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint (e);
//only do this if the mouse is over the control
if(_mouseIsOver)
{
using(Pen p = new Pen(Color.Red, 5))
{
e.Graphics.DrawRectangle(p, _zoomRegion);
}
}
}
private void ZoomSelectorPictureBox_MouseMove(object sender,
MouseEventArgs e)
{
//make the mouse in the center of the zoom region
_zoomRegion.X = e.X - _zoomRegion.Width / 2;
_zoomRegion.Y = e.Y - _zoomRegion.Width / 2;
//raise the event to listeners to refresh their
//zoomed view
if(ZoomRectangleChanged != null)
{
ZoomRectangleChanged(_zoomRegion);
}
//force image to be redrawn
this.Refresh();
}
private void ZoomSelectorPictureBox_MouseLeave(object sender, EventArgs e)
{
_mouseIsOver = false;
//force image to redraw without the rectangle
this.Refresh();
}
private void ZoomSelectorPictureBox_MouseEnter(object sender, EventArgs e)
{
_mouseIsOver = true;
}
}
}
Hope that helps
Mark R Dawson
http://www.markdawson.org
"utkarsh" wrote:
Thanks Mark for your code and so much help!! :)
But my problem is little bit different.
I have two screen left and right. In left panel I have loaded a Image
in picture box. When user move the mouse on the left panel, a
maginified view of a image section, near by the cursor, should be
visible in the right panel.
I have to do the similar work like the windows magnifier ( Programs ->
Accessories -> Accessibility -> Magnifier)
So I have loaded the same image in both the screens and I have to
update the right screen as mouse move in left. I have removed the
flickering by using the timer tick event. But only problem left is,
timer is consuming the 100% CPU.
Thanks again,
Utkarsh Panwar