How to block mouse inputs and simulate them programmatically? - c#

I have a task to make a software model of device which has touchpad and screen.
I'm using C# and Windows XP.
So I have TouchpadPanel and ScreenPanel.
How can I route mouse inputs of TouchpadPanel to ScreenPanel? I want ScreenPanel (or ScreenForm) not to capture mouse and its events but to get them from TouchpadPanel. Is it really possible to do it?

I spent couple of days trying to figure out the best way to solve the problem which I described above.
Finally I found very good manner which helped me successfully finish requested job.
I decided to share with you - hopefully it might save you some time.
I used System.Windows.Forms.ControlPaint to create all the controls that I needed from scratch: buttons, labels, custom textboxes and comboboxes. Most important of all - I made separate top layer for cursor.
Now when I'm drawing everything myself I can draw extra cursor which is always visible in my window no matter what I'm doing with the real cursor.
Here is some code example:
class MCDUComboBox : MCDUStateControl
{
public event EventHandler<GosNIIAS.EventArgs<string>> SelectedIndexChanged;
private const int buttonOffset = 2;
private const int buttonWidth = 20;
private const int buttonHeight = 20;
private string[] m_items;
private int m_hightlight_index;
private int m_selected_index;
private Rectangle m_drop_down_bounds;
private int m_scroll_index;
private ButtonState m_top_scroll_button_state;
private ButtonState m_bottom_scroll_button_state;
#region Properties
public string[] Items
{
get { return m_items; }
set { m_items = value; }
}
public override string Text
{
get { return base.Text; }
set
{
if (ControlState == ControlState.Normal)
base.Text = value;
}
}
#endregion
public MCDUComboBox()
{
this.Font = new System.Drawing.Font("Courier New", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
this.m_items = new string[0];
this.m_hightlight_index = -1;
this.m_selected_index = -1;
this.m_drop_down_bounds = new Rectangle();
this.m_scroll_index = 0;
this.m_top_scroll_button_state = ButtonState.Normal;
this.m_bottom_scroll_button_state = ButtonState.Normal;
}
public override void Draw(Graphics g)
{
if (Visible)
{
Rectangle bounds = ClipRectangle;
if (ControlState == ControlState.Normal)
{
g.FillRectangle(BackBrush, bounds);
g.DrawString(Text, Font, ForeBrush, bounds, StringFormat);
}
else if (ControlState == ControlState.Edit)
{
g.FillRectangle(ForeBrush, bounds);
ControlPaint.DrawBorder3D(g, bounds, Border3DStyle.Sunken);
Rectangle rectangle = new Rectangle(bounds.X + bounds.Width - buttonOffset - buttonWidth,
bounds.Y + buttonOffset,
buttonWidth,
bounds.Height - 2 * buttonOffset);
ControlPaint.DrawComboButton(g, rectangle, ButtonState.Normal);
}
else if (ControlState == ControlState.WaitingFeedback)
{
g.FillRectangle(BackBrush, bounds);
g.DrawString(Text, Font, WaitFeedbackBrush, bounds, StringFormat);
}
}
}
public override void OnMouseDown(MouseEventArgs e)
{
if (Visible)
{
Rectangle bounds = ClipRectangle;
if (bounds.Contains(e.Location))
{
if (e.Button == MouseButtons.Left)
{
if (ControlState == ControlState.Normal)
ControlState = ControlState.Edit;
}
}
else
{
if (ControlState == ControlState.Edit)
ControlState = ControlState.Normal;
}
}
}
public override bool OnMouseDownTopLayer(MouseEventArgs e)
{
if (Visible && ControlState == MCDU.Drawing.ControlState.Edit)
{
if (m_drop_down_bounds.Contains(e.Location) && m_items.Length > 0)
{
Rectangle bounds = new Rectangle(m_drop_down_bounds.X,
m_drop_down_bounds.Y,
m_items.Length > 10 ? m_drop_down_bounds.Width - buttonWidth
: m_drop_down_bounds.Width,
m_drop_down_bounds.Height);
if (bounds.Contains(e.Location))
{
if (SelectedIndexChanged != null)
{
int itemHeight = m_drop_down_bounds.Height / Math.Min(10, m_items.Length);
m_selected_index = (e.Location.Y - m_drop_down_bounds.Y) / itemHeight;
string text = m_items[m_selected_index + m_scroll_index];
SelectedIndexChanged(this, new GosNIIAS.EventArgs<string>(text));
base.Text = text;
ControlState = ControlState.WaitingFeedback;
}
else
ControlState = ControlState.Normal;
}
else
{
bounds = new Rectangle(m_drop_down_bounds.X + m_drop_down_bounds.Width - buttonWidth,
m_drop_down_bounds.Y,
buttonWidth,
buttonHeight);
if (bounds.Contains(e.Location))
{
m_scroll_index -= 1;
m_scroll_index = Math.Max(0, m_scroll_index);
m_top_scroll_button_state = ButtonState.Pushed;
}
else
{
bounds = new Rectangle(m_drop_down_bounds.X + m_drop_down_bounds.Width - buttonWidth,
m_drop_down_bounds.Y + m_drop_down_bounds.Height - buttonHeight,
buttonWidth,
buttonHeight);
if (bounds.Contains(e.Location))
{
m_scroll_index += 1;
m_scroll_index = Math.Min(m_items.Length - 10, m_scroll_index);
m_bottom_scroll_button_state = ButtonState.Pushed;
}
}
}
return true;
}
else
return false;
}
else
return false;
}
public override void OnMouseMove(MouseEventArgs e)
{
if (Visible && ControlState == MCDU.Drawing.ControlState.Edit)
{
if (m_drop_down_bounds.Contains(e.Location))
{
Rectangle bounds = new Rectangle(m_drop_down_bounds.X,
m_drop_down_bounds.Y,
m_items.Length > 10 ? m_drop_down_bounds.Width - buttonWidth
: m_drop_down_bounds.Width,
m_drop_down_bounds.Height);
if (bounds.Contains(e.Location) && m_items.Length > 0)
{
int itemHeight = m_drop_down_bounds.Height / Math.Min(10, m_items.Length);
m_hightlight_index = (e.Location.Y - m_drop_down_bounds.Y) / itemHeight + m_scroll_index;
}
}
}
}
public override void OnMouseUp(MouseEventArgs e)
{
base.OnMouseUp(e);
m_top_scroll_button_state = ButtonState.Normal;
m_bottom_scroll_button_state = ButtonState.Normal;
}
public override void DrawTopLayer(Graphics g)
{
if (Visible && ControlState == MCDU.Drawing.ControlState.Edit)
{
int itemHeight = GetItemHeight(g);
Rectangle bounds = ClipRectangle;
m_drop_down_bounds = new Rectangle(bounds.X,
bounds.Y + bounds.Height,
bounds.Width,
itemHeight * Math.Max(1, Math.Min(10, m_items.Length)) + 2);
g.FillRectangle(ForeBrush, m_drop_down_bounds);
g.DrawRectangle(new Pen(BackColor), new Rectangle(m_drop_down_bounds.X,
m_drop_down_bounds.Y,
m_drop_down_bounds.Width - 1,
m_drop_down_bounds.Height - 1));
for (int index = 0; index < Math.Min(10, m_items.Length); index++)
{
Rectangle itemBounds = new Rectangle(bounds.X,
bounds.Y + bounds.Height + index * itemHeight,
m_items.Length > 10 ? bounds.Width - buttonWidth : bounds.Width,
itemHeight);
if (m_hightlight_index == index + m_scroll_index)
g.FillRectangle(new SolidBrush(SystemColors.Highlight), itemBounds);
g.DrawString(m_items[index + m_scroll_index], Font, BackBrush, itemBounds, StringFormat);
}
if (m_items.Length > 10)
{
Rectangle rectangle = new Rectangle(m_drop_down_bounds.X + m_drop_down_bounds.Width - buttonWidth - 1,
m_drop_down_bounds.Y + 1,
buttonWidth,
itemHeight * 10);
g.FillRectangle(new SolidBrush(SystemColors.ScrollBar), rectangle);
rectangle = new Rectangle(m_drop_down_bounds.X + m_drop_down_bounds.Width - buttonWidth - 1,
m_drop_down_bounds.Y + 1,
buttonWidth,
buttonHeight);
ControlPaint.DrawScrollButton(g, rectangle, ScrollButton.Up, m_top_scroll_button_state);
rectangle = new Rectangle(m_drop_down_bounds.X + m_drop_down_bounds.Width - buttonWidth - 1,
m_drop_down_bounds.Y + 1 + itemHeight * 10 - buttonHeight,
buttonWidth,
buttonHeight);
ControlPaint.DrawScrollButton(g, rectangle, ScrollButton.Down, m_bottom_scroll_button_state);
int height = (int)((itemHeight * 10 - 2 * buttonHeight) * 10.0 / m_items.Length);
int y = m_drop_down_bounds.Y + 1 + buttonHeight +
(int)((itemHeight * 10 - 2 * buttonHeight) * m_scroll_index / m_items.Length);
rectangle = new Rectangle(m_drop_down_bounds.X + m_drop_down_bounds.Width - buttonWidth - 1,
y,
buttonWidth,
height);
ControlPaint.DrawButton(g, rectangle, ButtonState.Normal);
}
}
}
protected int GetItemHeight(Graphics g)
{
return (int)g.MeasureString(" ", Font).Height;
}
}

Related

DrawPolygon() erases the old polygon when drawing

I set the points and when the points of the same color form a square, I draw a polygon. But when a new square is formed, the old one disappears.
can you tell me how to make sure that when drawing a new polygon, the old one does not disappear?
in the checkpoint() function, I check whether there is a square of points of the same color and return e coordinates for drawing.
public partial class Form1 : Form
{
private Class1 Class1 = new Class1();
private CellState currentPlayer = CellState.Red;
public const int SIZE = 11;
public const int Icon_Size = 30;
public Form1()
{
InitializeComponent();
}
//ставит точки
protected override void OnMouseClick(MouseEventArgs e)
{
base.OnMouseClick(e);
var p = new Point((int)Math.Round(1f * e.X / Icon_Size), (int)Math.Round(1f * e.Y / Icon_Size));
if (Class1[p] == CellState.Empty)
{
Class1.SetPoint(p, currentPlayer);
currentPlayer = Class1.Inverse(currentPlayer);
Invalidate();
}
}
//рисуем
private void OnPaint(object sender, PaintEventArgs e)
{
e.Graphics.ScaleTransform(Icon_Size, Icon_Size);
//рисуем сеточку
using (var pen = new Pen(Color.Gainsboro, 0.1f))
{
for (int x = 1; x < SIZE; x++)
e.Graphics.DrawLine(pen, x, 1, x, SIZE - 1);
for (int y = 1; y < SIZE; y++)
e.Graphics.DrawLine(pen, 1, y, SIZE - 1, y);
}
e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
//рисуем точки
using (var brush = new SolidBrush(Color.White))
for (int x = 1; x < Form1.SIZE; x++)
for (int y = 1; y < Form1.SIZE; y++)
{
var p = new Point(x, y);
var cell = Class1[p];
if (cell != CellState.Empty)
{
brush.Color = StateToColor(cell);
e.Graphics.FillEllipse(brush, x - 0.2f, y - 0.2f, 0.4f, 0.4f);
}
}
using (var PenP = new Pen(Color.Black, 0.1f))
using (var brush = new SolidBrush(Color.White))
{
Class1.CheckPoint();
int i = Class1.CheckPoint()[0];
int j = Class1.CheckPoint()[1];
int cp = Class1.CheckPoint()[2];
if (cp == 1)
{
PenP.Color = Color.Red;
brush.Color = Color.IndianRed;
Point[] a = { new Point(i, j), new Point(i + 1, j), new Point(i + 1, j + 1), new Point(i, j + 1) };
e.Graphics.FillPolygon(brush, a);
e.Graphics.DrawPolygon(PenP, a);
}
if (cp == 2)
{
PenP.Color = Color.Blue;
brush.Color = Color.RoyalBlue;
Point[] a = { new Point(i, j), new Point(i + 1, j), new Point(i + 1, j + 1), new Point(i, j + 1) };
e.Graphics.FillPolygon(brush, a);
e.Graphics.DrawPolygon(PenP, a);
}
}
}
//условие смены цвета под ход игрока
Color StateToColor(CellState state, byte alpha = 255)
{
var res = state == CellState.Blue ? Color.Blue : Color.Red;
return Color.FromArgb(alpha, res);
}
}

How to exclude or set a area of a rectangle transparent in a control [duplicate]

Hello, through some research around here and other sites, I've made a rounded edges button.
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
Rectangle Rect = new Rectangle(0, 0, this.Width, this.Height);
GraphicsPath GraphPath = new GraphicsPath();
GraphPath.AddArc(Rect.X, Rect.Y, 50, 50, 180, 90);
GraphPath.AddArc(Rect.X + Rect.Width - 50, Rect.Y, 50, 50, 270, 90);
GraphPath.AddArc(Rect.X + Rect.Width - 50, Rect.Y + Rect.Height - 50, 50, 50, 0, 90);
GraphPath.AddArc(Rect.X, Rect.Y + Rect.Height - 50, 50, 50, 90, 90);
this.Region = new Region(GraphPath);
}
The problem I'm facing is the button's "blue highlight": It shows on most of the button, but it doesn't show on the rounded edges, so my button is part highlighted and part non-highlighted (on the edges). What could I do to solve this? Thank you.
PS: I can't use WPF. The application is for an very old computer; so, please, don't suggest it. Also, the client doesn't have the money to get a newer computer.
This is a quick one, you may want to fine tune things and optimize quite a few details..
class RoundedButton : Button
{
GraphicsPath GetRoundPath(RectangleF Rect, int radius)
{
float r2 = radius / 2f;
GraphicsPath GraphPath = new GraphicsPath();
GraphPath.AddArc(Rect.X, Rect.Y, radius, radius, 180, 90);
GraphPath.AddLine(Rect.X + r2, Rect.Y, Rect.Width - r2, Rect.Y);
GraphPath.AddArc(Rect.X + Rect.Width - radius, Rect.Y, radius, radius, 270, 90);
GraphPath.AddLine(Rect.Width, Rect.Y + r2, Rect.Width, Rect.Height - r2);
GraphPath.AddArc(Rect.X + Rect.Width - radius,
Rect.Y + Rect.Height - radius, radius, radius, 0, 90);
GraphPath.AddLine(Rect.Width - r2, Rect.Height, Rect.X + r2, Rect.Height);
GraphPath.AddArc(Rect.X, Rect.Y + Rect.Height - radius, radius, radius, 90, 90);
GraphPath.AddLine(Rect.X, Rect.Height - r2, Rect.X, Rect.Y + r2);
GraphPath.CloseFigure();
return GraphPath;
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
RectangleF Rect = new RectangleF(0, 0, this.Width, this.Height);
using (GraphicsPath GraphPath = GetRoundPath(Rect, 50))
{
this.Region = new Region(GraphPath);
using (Pen pen = new Pen(Color.CadetBlue, 1.75f))
{
pen.Alignment = PenAlignment.Inset;
e.Graphics.DrawPath(pen, GraphPath);
}
}
}
}
Obviously, since we have a class we can cache the GraphicsPath in a class variable. And of course you pick the color..
This is a tweak on TaW's answer to more easily tweak the borderRadius and borderThickness. If you get random white space between the border and the button background color, m needs to be tweaked.
public class RoundedButton : Button
{
GraphicsPath GetRoundPath(RectangleF Rect, int radius)
{
float m = 2.75F;
float r2 = radius / 2f;
GraphicsPath GraphPath = new GraphicsPath();
GraphPath.AddArc(Rect.X + m, Rect.Y + m, radius, radius, 180, 90);
GraphPath.AddLine(Rect.X + r2 + m, Rect.Y + m, Rect.Width - r2 - m, Rect.Y + m);
GraphPath.AddArc(Rect.X + Rect.Width - radius - m, Rect.Y + m, radius, radius, 270, 90);
GraphPath.AddLine(Rect.Width - m, Rect.Y + r2, Rect.Width - m, Rect.Height - r2 - m);
GraphPath.AddArc(Rect.X + Rect.Width - radius - m,
Rect.Y + Rect.Height - radius - m, radius, radius, 0, 90);
GraphPath.AddLine(Rect.Width - r2 - m, Rect.Height - m, Rect.X + r2 - m, Rect.Height - m);
GraphPath.AddArc(Rect.X + m, Rect.Y + Rect.Height - radius - m, radius, radius, 90, 90);
GraphPath.AddLine(Rect.X + m, Rect.Height - r2 - m, Rect.X + m, Rect.Y + r2 + m);
GraphPath.CloseFigure();
return GraphPath;
}
protected override void OnPaint(PaintEventArgs e)
{
int borderRadius = 50;
float borderThickness = 1.75f;
base.OnPaint(e);
RectangleF Rect = new RectangleF(0, 0, this.Width, this.Height);
GraphicsPath GraphPath = GetRoundPath(Rect, borderRadius);
this.Region = new Region(GraphPath);
using (Pen pen = new Pen(Color.Silver, borderThickness))
{
pen.Alignment = PenAlignment.Inset;
e.Graphics.DrawPath(pen, GraphPath);
}
}
}
Cheers!
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.ComponentModel;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace button2
{
public partial class Form1 : Form
{
private Button button1;
private GroupBox box;
public Form1()
{
InitializeComponent();
show();
}
private void show()
{
box = new GroupBox();
button1 = new Button();
button1.Location = new Point(50, 50);
ElipseControl nn = new ElipseControl();
nn.TargetControl = button1;
button1.Text = "First Name";
button1.BackColor = Color.Cyan;
button1.FlatStyle = FlatStyle.Flat;
button1.FlatAppearance.BorderSize = 0;
button1.FlatAppearance.BorderColor = Color.White;
nn.CornerRadius = 10;
button1.ForeColor = Color.Blue;
button1.Font = new Font("Arial", 9, FontStyle.Bold);
box.Controls.Add(button1);
box.AutoSize = true;
this.Controls.Add(box);
}
}
class ElipseControl : Component
{
[DllImport("Gdi32.dll", EntryPoint = "CreateRoundRectRgn")]
public static extern IntPtr CreateRoundRectRgn
(
int nLeftRect,
int nTopRect,
int nRightRect,
int nBottomRect,
int nWidthEllipse,
int nHeightEllipse
);
private Control _cntrl;
private int _CornerRadius = 30;
public Control TargetControl
{
get { return _cntrl; }
set
{
_cntrl = value;
_cntrl.SizeChanged += (sender, eventArgs) => _cntrl.Region = Region.FromHrgn(CreateRoundRectRgn(0, 0, _cntrl.Width, _cntrl.Height, _CornerRadius, _CornerRadius));
}
}
public int CornerRadius
{
get { return _CornerRadius; }
set
{
_CornerRadius = value;
if (_cntrl != null)
_cntrl.Region = Region.FromHrgn(CreateRoundRectRgn(0, 0, _cntrl.Width, _cntrl.Height, _CornerRadius, _CornerRadius));
}
}
}
}
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Text;
using System.Linq;
using System.Reflection;
using System.Windows.Forms;
namespace ButtonRounded
{
public enum ButtonAction
{
Highlight,
Click,
Disabled,
Normal,
}
public enum ShadowPosition
{
BottomRight,
Bottom,
BottomLeft,
Left,
TopLeft,
Top,
TopRight,
Right,
}
public enum ShadowSize
{
Thin,
Normal,
Thick,
None,
}
public static class ControlExtensions
{
public static T Clone<T>(this T controlToClone)
where T : Control
{
PropertyInfo[] controlProperties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
T instance = Activator.CreateInstance<T>();
foreach (PropertyInfo propInfo in controlProperties)
{
if (propInfo.CanWrite && propInfo.Name != "WindowTarget")
{
propInfo.SetValue(instance, propInfo.GetValue(controlToClone, null), null);
}
}
return instance;
}
public static void Copy<T>(this T controlToClone, ref T targetControl)
where T : Control
{
foreach (PropertyInfo propInfo in typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance))
{
if (propInfo.CanWrite && propInfo.Name != "WindowTarget")
{
propInfo.SetValue(targetControl, propInfo.GetValue(controlToClone, null), null);
}
}
}
}
public class RoundedButtons : IDisposable
{
public bool IsDisposed;
private readonly Dictionary<Button, Button> _ButtonDataDictionary = new Dictionary<Button, Button>();
public RoundedButtons()
{
MouseEventClick = (sender, e) => Button_MouseAction(sender, ButtonAction.Click);
MouseEventHighlight = (sender, e) => Button_MouseAction(sender, ButtonAction.Highlight);
EventHighlight = (sender, e) => Button_MouseAction(sender, ButtonAction.Highlight);
EventNormal = (sender, e) => Button_MouseAction(sender, ButtonAction.Normal);
}
private event EventHandler EventHighlight;
private event EventHandler EventNormal;
private event MouseEventHandler MouseEventClick;
private event MouseEventHandler MouseEventHighlight;
public int Btn_CornerRadius { get; set; } = 8;
public int Btn_LineWidth { get; set; } = 1;
public ShadowPosition Btn_ShadowLocation { get; set; }
public ShadowSize Btn_ShadowWidth { get; set; } = ShadowSize.Normal;
public Padding Btn_TextPadding { get; set; } = new Padding(0);
public Color ClickBGColor { get; set; } = Color.Empty;
public Color ClickLineColor { get; set; } = Color.Black;
public Color ClickShadowColor { get; set; } = Color.Black;
public Color ClickTextColor { get; set; } = Color.GhostWhite;
public Color DisabledBGColor { get; set; } = Color.Empty;
public Color DisabledLineColor { get; set; } = Color.LightGray;
public Color DisabledShadowColor { get; set; } = Color.DarkGray;
public Color DisabledTextColor { get; set; } = Color.Gray;
public Color HighlightBGColor { get; set; } = Color.Empty;
public Color HighlightLineColor { get; set; } = Color.Blue;
public Color HighlightShadowColor { get; set; } = Color.Black;
public Color HighlightTextColor { get; set; } = Color.Empty;
public Color MainBGColor { get; set; } = Color.Empty;
public Color MainLineColor { get; set; } = Color.Black;
public Color MainShadowColor { get; set; } = Color.DarkGray;
public Color MainTextColor { get; set; } = Color.Empty;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
public string GetButtonText(Button button)
{
string text = "";
_ButtonDataDictionary.TryGetValue(button, out Button copy);
if (copy != null)
{
text = copy.Text;
}
return text;
}
public void PaintButton(object sender)
{
if (sender is Button b)
{
_ButtonDataDictionary.Add(b, b.Clone());
b.TabStop = false;
b.FlatStyle = FlatStyle.Flat;
b.FlatAppearance.BorderSize = 0;
b.FlatAppearance.MouseDownBackColor = Color.FromArgb(0, 255, 255, 255);
b.FlatAppearance.MouseOverBackColor = Color.FromArgb(0, 255, 255, 255);
b.FlatAppearance.BorderColor = Color.FromArgb(0, 255, 255, 255);
b.BackColor = Color.FromArgb(0, 255, 255, 255);
//Clear text field to prevent double drawn text with Transparency.
b.Text = "";
b.Paint += B_Paint;
b.EnabledChanged += EventNormal;
b.MouseEnter += EventHighlight;
b.MouseLeave += EventNormal;
b.MouseDown += MouseEventClick;
b.MouseUp += MouseEventHighlight;
b.TextChanged += B_TextChanged;
b.Refresh();
}
}
protected virtual void Dispose(bool disposing)
{
if (!IsDisposed && disposing)
{
Button[] keys = _ButtonDataDictionary.Keys.ToArray();
for (int i = 0; i < keys.Length; i++)
{
Button b = _ButtonDataDictionary.ElementAt(i).Key;
Button copy = _ButtonDataDictionary.ElementAt(i).Value;
b.Paint -= B_Paint;
b.EnabledChanged -= EventNormal;
b.MouseEnter -= EventHighlight;
b.MouseLeave -= EventNormal;
b.MouseDown -= MouseEventClick;
b.MouseUp -= MouseEventHighlight;
b.TextChanged -= B_TextChanged;
copy?.Copy(ref b);
copy?.Dispose();
b?.Refresh();
}
_ButtonDataDictionary.Clear();
IsDisposed = true;
}
}
private void B_Paint(object sender, PaintEventArgs e)
{
RoundedButton_Paint(sender, e, ButtonAction.Normal);
}
private void B_Paint_Click(object sender, PaintEventArgs e)
{
RoundedButton_Paint(sender, e, ButtonAction.Click);
}
private void B_Paint_Disable(object sender, PaintEventArgs e)
{
RoundedButton_Paint(sender, e, ButtonAction.Disabled);
}
private void B_Paint_Hightlight(object sender, PaintEventArgs e)
{
RoundedButton_Paint(sender, e, ButtonAction.Highlight);
}
private void B_TextChanged(object sender, EventArgs e)
{
if (sender is Button b)
{
_ButtonDataDictionary.TryGetValue(b, out Button copy);
copy.Text = b.Text;
b.TextChanged -= B_TextChanged;
b.Text = "";
b.TextChanged += B_TextChanged;
}
}
private void Button_MouseAction(object sender, ButtonAction action)
{
if (sender is Button b)
{
b.Paint -= B_Paint_Disable;
b.Paint -= B_Paint_Click;
b.Paint -= B_Paint_Hightlight;
b.Paint -= B_Paint;
b.Paint += action switch
{
ButtonAction.Click => B_Paint_Click,
ButtonAction.Disabled => B_Paint_Disable,
ButtonAction.Highlight => B_Paint_Hightlight,
_ => B_Paint
};
b.Refresh();
}
}
private Rectangle[] CalculateRects(Button b, int shadowWidth)
{
int width = b.Size.Width - 1;
int height = b.Size.Height - 1;
if (Btn_ShadowLocation.ToString().Contains("Bottom") || Btn_ShadowLocation.ToString().Contains("Top"))
{
height -= Btn_LineWidth * 2; height -= shadowWidth;
}
if (Btn_ShadowLocation.ToString().Contains("Right") || Btn_ShadowLocation.ToString().Contains("Left"))
{
width -= Btn_LineWidth * 2; width -= shadowWidth;
}
Size size = new Size(width, height);
Rectangle shadow = new Rectangle(new Point(0, 0), size);
Rectangle button = new Rectangle(new Point(0, 0), size);
if (Btn_ShadowLocation.ToString().Contains("Right"))
{
shadow.X = shadowWidth;
button.X = 0;
}
if (Btn_ShadowLocation.ToString().Contains("Bottom"))
{
shadow.Y = shadowWidth;
button.Y = 0;
}
if (Btn_ShadowLocation.ToString().Contains("Left"))
{
shadow.X = 0;
button.X = shadowWidth;
}
if (Btn_ShadowLocation.ToString().Contains("Top"))
{
shadow.Y = 0;
button.Y = shadowWidth;
}
return new Rectangle[] { shadow, button };
}
private void RoundedButton_Paint(object sender, PaintEventArgs e, ButtonAction action = ButtonAction.Normal)
{
if (sender is Button b)
{
if (!b.Enabled)
{
action = ButtonAction.Disabled;
}
//================Setup================
e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
e.Graphics.InterpolationMode = InterpolationMode.NearestNeighbor;
e.Graphics.CompositingQuality = CompositingQuality.HighSpeed;
e.Graphics.TextRenderingHint = TextRenderingHint.SystemDefault; //Causes issues with application text.
StringFormat stringFormat = new StringFormat
{
Alignment = StringAlignment.Center,
LineAlignment = StringAlignment.Center
};
int shadowWidth = (Btn_ShadowWidth == ShadowSize.Thin) ? 1 : (Btn_ShadowWidth == ShadowSize.Normal) ? 2 : (Btn_ShadowWidth == ShadowSize.Thick) ? 3 : 0;
Rectangle[] rect = CalculateRects(b, shadowWidth);
_ButtonDataDictionary.TryGetValue(b, out Button copy);
//=====================================
//===============Colors================
Color shadowColor = action switch
{
ButtonAction.Click => ClickShadowColor,
ButtonAction.Disabled => DisabledShadowColor,
ButtonAction.Highlight => HighlightShadowColor,
ButtonAction.Normal => MainShadowColor,
_ => MainShadowColor
};
shadowColor = shadowColor == Color.Transparent ? Color.FromArgb(0, 255, 255, 255) : shadowColor;
Color bgColor = action switch
{
ButtonAction.Click => ClickBGColor,
ButtonAction.Disabled => DisabledBGColor,
ButtonAction.Highlight => HighlightBGColor,
ButtonAction.Normal => MainBGColor,
_ => MainBGColor
};
bgColor = bgColor == Color.Transparent ? Color.FromArgb(0, 255, 255, 255) : bgColor;
bgColor = bgColor.IsEmpty ? copy.BackColor : bgColor;
Color lineColor = action switch
{
ButtonAction.Click => ClickLineColor,
ButtonAction.Disabled => DisabledLineColor,
ButtonAction.Highlight => HighlightLineColor,
ButtonAction.Normal => MainLineColor,
_ => MainLineColor
};
lineColor = lineColor == Color.Transparent ? Color.FromArgb(0, 255, 255, 255) : lineColor;
Color textColor = action switch
{
ButtonAction.Click => ClickTextColor,
ButtonAction.Disabled => DisabledTextColor,
ButtonAction.Highlight => HighlightTextColor,
ButtonAction.Normal => MainTextColor,
_ => MainTextColor
};
textColor = textColor == Color.Transparent ? Color.FromArgb(0, 255, 255, 255) : textColor;
if (shadowWidth > 0)
{
//Draw shadow in the back
using Brush shadowBrush = new SolidBrush(shadowColor);
using Pen shadowPen = new Pen(shadowBrush, shadowWidth * 2);
if (b.Parent is PictureBox || copy.BackColor == Color.FromArgb(0, 255, 255, 255))
{
e.Graphics.DrawRoundedRectanglePart(shadowPen, rect[0], Btn_CornerRadius, Btn_ShadowLocation);
}
else
{
e.Graphics.DrawRoundedRectangle(shadowPen, rect[0], Btn_CornerRadius);
}
}
//Draw over any existing button graphics
using Brush clearBrush = new SolidBrush((b.Parent is PictureBox) ? Color.FromArgb(0, 255, 255, 255) : ExtensionMethods.GetParentBackColor(b));
e.Graphics.FillRoundedRectangle(clearBrush, rect[1], Btn_CornerRadius);
//Draw background color of the button
using Brush backBrush = new SolidBrush(bgColor);
e.Graphics.FillRoundedRectangle(backBrush, rect[1], Btn_CornerRadius);
//Draw outline of the button
using Brush buttonBrush = new SolidBrush(lineColor);
using Pen buttonPen = new Pen(buttonBrush, Btn_LineWidth);
e.Graphics.DrawRoundedRectangle(buttonPen, rect[1], Btn_CornerRadius);
//Draw text of the button
//Button text is set to "" so that transparency will not show the original text.
//I use a copy of the button to pull the text to draw.
using Brush textBrush = new SolidBrush(textColor.IsEmpty ? b.ForeColor : textColor);
Rectangle rectangleText = new Rectangle(
rect[1].X + Btn_TextPadding.Left,
rect[1].Y + Btn_TextPadding.Top,
rect[1].Width - Btn_TextPadding.Right,
rect[1].Height - Btn_TextPadding.Bottom
);
e.Graphics.DrawString(copy.Text, b.Font, textBrush, rectangleText, stringFormat);
}
}
}
internal static class ExtensionMethods
{
public static void DrawRoundedRectangle(this Graphics graphics, Pen pen, Rectangle bounds, int cornerRadius)
{
using GraphicsPath path = RoundedRect(bounds, cornerRadius);
graphics.DrawPath(pen, path);
}
public static void DrawRoundedRectanglePart(this Graphics graphics, Pen pen, Rectangle bounds, int cornerRadius, ShadowPosition position)
{
using GraphicsPath path = RoundedRectPart(bounds, cornerRadius, position);
path.Flatten(new Matrix(), 0.12f);
PointF prevP = new PointF();
int total = path.PathPoints.Length;
int count = 1;
float penSize;
int trim;
if (position == ShadowPosition.Bottom || position == ShadowPosition.Top || position == ShadowPosition.Left || position == ShadowPosition.Right)
{
trim = 1;
}
else
{
trim = 2;
}
foreach (PointF p in path.PathPoints)
{
if (prevP.IsEmpty || count <= trim || count >= total - trim)
{
prevP = p; count++; continue;
}
if (count <= 3 || count >= total - 3)
{
penSize = 1;
}
else if (count <= 5 || count >= total - 5)
{
penSize = 2;
}
else if (count <= 8 || count >= total - 8)
{
penSize = 3;
}
else
{
penSize = pen.Width;
}
if (penSize > pen.Width)
{
penSize = pen.Width;
}
graphics.DrawLine(new Pen(pen.Color, penSize), prevP, p);
prevP = p;
count++;
}
}
public static void FillRoundedRectangle(this Graphics graphics, Brush brush, Rectangle bounds, int cornerRadius)
{
using GraphicsPath path = RoundedRect(bounds, cornerRadius);
graphics.FillPath(brush, path);
}
internal static Color GetParentBackColor(object sender)
{
Color c;
try
{
if ((sender as dynamic)?.Parent != null)
{
c = (sender as dynamic)?.Parent.BackColor;
}
else
{
c = Color.White;
}
}
catch
{
c = Color.White;
}
if (c == Color.Transparent)
{
try
{
if ((sender as dynamic)?.Parent != null)
{
c = GetParentBackColor((sender as dynamic)?.Parent);
}
else
{
c = Color.White;
}
}
catch
{
c = Color.White;
}
}
return c;
}
internal static GraphicsPath RoundedRect(Rectangle bounds, int radius)
{
int diameter = radius * 2;
Size size = new Size(diameter, diameter);
Rectangle arc = new Rectangle(bounds.Location, size);
GraphicsPath path = new GraphicsPath { FillMode = FillMode.Alternate };
if (radius == 0)
{
path.AddRectangle(bounds);
return path;
}
path.AddArc(arc, 180, 90);
arc.X = bounds.Right - diameter;
path.AddArc(arc, 270, 90);
arc.Y = bounds.Bottom - diameter;
path.AddArc(arc, 0, 90);
arc.X = bounds.Left;
path.AddArc(arc, 90, 90);
path.CloseFigure();
return path;
}
internal static GraphicsPath RoundedRectPart(Rectangle bounds, int radius, ShadowPosition position)
{
int diameter = radius * 2;
Size size = new Size(diameter, diameter);
Rectangle arc = new Rectangle(bounds.Location, size);
GraphicsPath path = new GraphicsPath { FillMode = FillMode.Alternate, };
if (radius == 0)
{
path.AddRectangle(bounds);
return path;
}
if (position == ShadowPosition.Right)
{
arc.X = bounds.Right - diameter;
path.AddArc(arc, 270, 90);
arc.Y = bounds.Bottom - diameter;
path.AddArc(arc, 0, 90);
}
else if (position == ShadowPosition.BottomRight)
{
arc.X = bounds.Right - diameter;
path.AddArc(arc, 270, 90);
arc.Y = bounds.Bottom - diameter;
path.AddArc(arc, 0, 90);
arc.X = bounds.Left;
path.AddArc(arc, 90, 90);
}
else if (position == ShadowPosition.Bottom)
{
arc.X = bounds.Right - diameter;
arc.Y = bounds.Bottom - diameter;
path.AddArc(arc, 0, 90);
arc.X = bounds.Left;
path.AddArc(arc, 90, 90);
}
else if (position == ShadowPosition.BottomLeft)
{
arc.X = bounds.Right - diameter;
arc.Y = bounds.Bottom - diameter;
path.AddArc(arc, 0, 90);
arc.X = bounds.Left;
path.AddArc(arc, 90, 90);
arc.Y = bounds.Top;
path.AddArc(arc, 180, 90);
}
else if (position == ShadowPosition.Left)
{
arc.Y = bounds.Bottom - diameter;
arc.X = bounds.Left;
path.AddArc(arc, 90, 90);
arc.Y = bounds.Top;
path.AddArc(arc, 180, 90);
}
else if (position == ShadowPosition.TopLeft)
{
arc.Y = bounds.Bottom - diameter;
arc.X = bounds.Left;
path.AddArc(arc, 90, 90);
arc.Y = bounds.Top;
path.AddArc(arc, 180, 90);
arc.X = bounds.Right - diameter;
path.AddArc(arc, 270, 90);
}
else if (position == ShadowPosition.Top)
{
path.AddArc(arc, 180, 90);
arc.X = bounds.Right - diameter;
path.AddArc(arc, 270, 90);
}
else if (position == ShadowPosition.TopRight)
{
path.AddArc(arc, 180, 90);
arc.X = bounds.Right - diameter;
path.AddArc(arc, 270, 90);
arc.Y = bounds.Bottom - diameter;
path.AddArc(arc, 0, 90);
}
return path;
}
}
}
Short of painting it yourself, I don't think there's anything you can do. The base button paint logic isn't written as "show a blue highlight around such-and-such portion of whatever the window region is". Instead, it's written with the type of region it expects -- a rectangular one. So the base paint is always going to paint a rectangular image into a cropped shape. You'll have an easier time of such things in WPF.
You can use a WebBrowser, make a button with HTML and CSS, then use webbrowser.DocumentText = "your html";

Capturing screen not actually capturing right region

In C# I have written an application where you select a box to take a screen shot of and what happens is if you are above a 0 on the X axis it doesn't take a picture. I drew a small image to show what I mean:
Red = Image will actually not be of that section
Black = Ok
My code is as follows:
#region testing
private Point start = Point.Empty;
private Point end = Point.Empty;
private void Form2_MouseDown(object sender, MouseEventArgs e)
{
if ((e.Button & MouseButtons.Left) != 0)
{
start.X = e.X;
start.Y = e.Y;
}
}
private void Form2_MouseMove(object sender, MouseEventArgs e)
{
Point p1;
Point p2;
if (((e.Button & MouseButtons.Left) != 0) && (start != Point.Empty))
{
using (Graphics g = this.CreateGraphics())
{
p1 = PointToScreen(start);
if (end != Point.Empty)
{
p2 = PointToScreen(end);
ControlPaint.DrawReversibleFrame(GetRectangleForPoints(p1, p2),
Color.Black, FrameStyle.Dashed);
}
end.X = e.X;
end.Y = e.Y;
p2 = PointToScreen(end);
ControlPaint.DrawReversibleFrame(GetRectangleForPoints(p1, p2),
Color.Black, FrameStyle.Dashed);
}
}
}
private void Form2_MouseUp(object sender, MouseEventArgs e)
{
Point p1;
Point p2;
if ((end != Point.Empty) && (start != Point.Empty))
{
using (Graphics g = this.CreateGraphics())
{
p1 = PointToScreen(start);
p2 = PointToScreen(end);
ControlPaint.DrawReversibleFrame(GetRectangleForPoints(p1, p2),
Color.Black, FrameStyle.Dashed);
int x1 = p1.X;
int y1 = p1.Y;
int x2 = p2.X;
int y2 = p2.Y;
int x = x2 - x1;
int y = y2 - y1;
string[] xsp;
int rx = 0;
string[] ysp;
int ry = 0;
if (x.ToString().Contains("-"))
{
xsp = x.ToString().Split('-');
rx = Convert.ToInt32(xsp[1]);
}
else
{
rx = x;
}
if (y.ToString().Contains("-"))
{
ysp = y.ToString().Split('-');
ry = Convert.ToInt32(ysp[1]);
}
else
{
ry = y;
}
using (Bitmap bmpScreenCapture = new Bitmap(rx, ry, g))
{
using (Graphics gra = Graphics.FromImage(bmpScreenCapture))
{
if(x.ToString().Contains("-"))
{
gra.CopyFromScreen(x2, y1, 0, 0, bmpScreenCapture.Size,
CopyPixelOperation.SourceCopy);
}
else if(!x.ToString().Contains("-"))
{
gra.CopyFromScreen(x1, y1, 0, 0, bmpScreenCapture.Size,
CopyPixelOperation.SourceCopy);
}
else if(y.ToString().Contains("-"))
{
gra.CopyFromScreen(x1, y2, 0, 0, bmpScreenCapture.Size,
CopyPixelOperation.SourceCopy);
}
else if (!y.ToString().Contains("-"))
{
gra.CopyFromScreen(x1, y1, 0, 0, bmpScreenCapture.Size,
CopyPixelOperation.SourceCopy);
}
else if (x.ToString().Contains("-") && y.ToString().Contains("-"))
{
gra.CopyFromScreen(x2, y2, 0, 0, bmpScreenCapture.Size,
CopyPixelOperation.SourceCopy);
}
string filename = GenerateRandomString(20) + ".png";
bmpScreenCapture.Save(Path.GetTempPath() + "" + filename,
ImageFormat.Png);
ControlPaint.DrawReversibleFrame(GetRectangleForPoints
(new Point(0), new Point(0)), Color.Black, FrameStyle.Dashed);
//Upload(Path.GetTempPath() + "" + filename, filename);
}
}
}
}
start = Point.Empty;
end = Point.Empty;
}
private Rectangle GetRectangleForPoints(Point beginPoint, Point endPoint)
{
int top = beginPoint.Y < endPoint.Y ? beginPoint.Y : endPoint.Y;
int bottom = beginPoint.Y > endPoint.Y ? beginPoint.Y : endPoint.Y;
int left = beginPoint.X < endPoint.X ? beginPoint.X : endPoint.X;
int right = beginPoint.X > endPoint.X ? beginPoint.X : endPoint.X;
rect = new Rectangle(left, top, (right - left), (bottom - top));
return rect;
}
#endregion
I have attempted to correct it and I have had no success. I mean the picture still shows up but it is not the right region of the screen.
I started to use a different selection method and that allowed for me to get the rectangles X and Y and Size. A lot better solution :)
Code:
#region testing
private Point start = Point.Empty;
private Point end = Point.Empty;
private void Form2_MouseDown(object sender, MouseEventArgs e)
{
if ((e.Button & MouseButtons.Left) != 0)
{
start.X = e.X;
start.Y = e.Y;
}
}
private void Form2_MouseMove(object sender, MouseEventArgs e)
{
//this.Invalidate();
Point p1;
Point p2;
if (((e.Button & MouseButtons.Left) != 0) && (start != Point.Empty))
{
using (Graphics g = this.CreateGraphics())
{
g.Clear(this.BackColor);
p1 = PointToScreen(start);
if (end != Point.Empty)
{
p2 = PointToScreen(end);
ControlPaint.DrawReversibleFrame(GetRectangleForPoints(p1, p2), Color.Black, FrameStyle.Dashed);
}
end.X = e.X;
end.Y = e.Y;
p2 = PointToScreen(end);
ControlPaint.DrawReversibleFrame(GetRectangleForPoints(p1, p2), Color.Black, FrameStyle.Dashed);
}
}
}
private void Form2_MouseUp(object sender, MouseEventArgs e)
{
Point p1;
Point p2;
if ((end != Point.Empty) && (start != Point.Empty))
{
using (Graphics g = this.CreateGraphics())
{
p1 = PointToScreen(start);
p2 = PointToScreen(end);
ControlPaint.DrawReversibleFrame(GetRectangleForPoints(p1, p2), Color.Black, FrameStyle.Dashed);
int x1 = p1.X;
int y1 = p1.Y;
int x2 = p2.X;
int y2 = p2.Y;
int x = x2 - x1;
int y = y2 - y1;
string[] xsp;
int rx = 0;
string[] ysp;
int ry = 0;
if (x.ToString().Contains("-"))
{
xsp = x.ToString().Split('-');
rx = Convert.ToInt32(xsp[1]);
}
else
{
rx = x;
}
if (y.ToString().Contains("-"))
{
ysp = y.ToString().Split('-');
ry = Convert.ToInt32(ysp[1]);
}
else
{
ry = y;
}
using (Bitmap bmpScreenCapture = new Bitmap(rect.Width, rect.Height, g))
{
using (Graphics gra = Graphics.FromImage(bmpScreenCapture))
{
gra.CopyFromScreen(rect.X, rect.Y, 0, 0, bmpScreenCapture.Size, CopyPixelOperation.SourceCopy);
string filename = GenerateRandomString(20) + ".png";
bmpScreenCapture.Save(Path.GetTempPath() + "" + filename, ImageFormat.Png);
g.Clear(this.BackColor);
//Upload(Path.GetTempPath() + "" + filename, filename);
}
}
}
}
start = Point.Empty;
end = Point.Empty;
}
private Rectangle GetRectangleForPoints(Point beginPoint, Point endPoint)
{
int top = beginPoint.Y < endPoint.Y ? beginPoint.Y : endPoint.Y;
int bottom = beginPoint.Y > endPoint.Y ? beginPoint.Y : endPoint.Y;
int left = beginPoint.X < endPoint.X ? beginPoint.X : endPoint.X;
int right = beginPoint.X > endPoint.X ? beginPoint.X : endPoint.X;
rect = new Rectangle(left, top, (right - left), (bottom - top));
return rect;
}
#endregion

How can i check that the pictureBox i'm moving around will not get out the borders top left right bottom of the second picturebox area?

private void picZoom_MouseMove(object sender, MouseEventArgs e)
{
if (PicImageClicked == false)
{
if (checkBox1.Checked)
{
int x = e.X + picZoom.Left - picImage.Left;
int y = e.Y + picZoom.Top - picImage.Top;
if (x <= picImage.Width && y <= picImage.Height &&
x <= picImage.Top && y <= picImage.Left)
{
MouseEventArgs e2 = new MouseEventArgs(MouseButtons.None, 0, x, y, 0);
picImageReposition(null, e2);
}
}
else
{
UpdateZoomedImage(e);
}
}
}
picImage is a bigger pictureBox and picZoom is a smaller pictureBox the picZoom i'm moving aorund inside the picImage are with the mouse.
This condition:
if (x <= picImage.Width && y <= picImage.Height
Is working if i'm moving the picZoom to the left border or the bottom border it stop on it and not continue.
But the second condition:
x <= picImage.Top && y <= picImage.Left
Is not working good it make everything slow and it's not stopping on the left or top borders.
I want to make a condition/s so the picZoom will stay in the picImage area borders.
What i tried now is:
private void picZoom_MouseMove(object sender, MouseEventArgs e)
{
Point pnt;
int x, y;
if (MouseButtons.Left == e.Button)
{
pnt = picZoom.PointToScreen(e.Location);
pnt = this.PointToClient(pnt);
x = pnt.X - mouseDown.X;
y = pnt.Y - mouseDown.Y;
if (x < picImage.Left)
{
x = picImage.Left;
}
else if (x + picZoom.Width > picImage.Left + picImage.Width)
{
x = picImage.Left + picImage.Width - picZoom.Width;
}
else
{ }
if (y < picImage.Top)
{
y = picImage.Top;
}
else if (y + picZoom.Height > picImage.Top + picImage.Height)
{
y = picImage.Top + picImage.Height - picZoom.Height;
}
else
{ }
picZoom.Location = new Point(x, y);
if (PicImageClicked == false)
{
if (checkBox1.Checked)
{
MouseEventArgs e2 = new MouseEventArgs(MouseButtons.None, 0, x, y, 0);
picImageReposition(null, e2);
}
else
{
UpdateZoomedImage(e);
}
}
}
}
picImageReposition is:
private void picImageReposition(object sender, MouseEventArgs e)
{
// If no picture is loaded, return
if (picImage.Image == null)
return;
if (PicImageClicked == false)
{
picZoom.BringToFront();
picZoom.Left = e.X + picImage.Left - picZoom.Width/2;
picZoom.Top = e.Y + picImage.Top - picZoom.Height/2;
UpdateZoomedImage(e);
}
}
And UpdateZoomedImage is:
private void UpdateZoomedImage(MouseEventArgs e)
{
// Calculate the width and height of the portion of the image we want
// to show in the picZoom picturebox. This value changes when the zoom
// factor is changed.
int zoomWidth = picZoom.Width / _ZoomFactor;
int zoomHeight = picZoom.Height / _ZoomFactor;
// Calculate the horizontal and vertical midpoints for the crosshair
// cursor and correct centering of the new image
int halfWidth = zoomWidth / 2;
int halfHeight = zoomHeight / 2;
// Create a new temporary bitmap to fit inside the picZoom picturebox
tempBitmap = new Bitmap(zoomWidth, zoomHeight, PixelFormat.Format24bppRgb);
// Create a temporary Graphics object to work on the bitmap
Graphics bmGraphics = Graphics.FromImage(tempBitmap);
// Clear the bitmap with the selected backcolor
bmGraphics.Clear(_BackColor);
// Set the interpolation mode
bmGraphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
// Draw the portion of the main image onto the bitmap
// The target rectangle is already known now.
// Here the mouse position of the cursor on the main image is used to
// cut out a portion of the main image.
bmGraphics.DrawImage(picImage.Image,
new Rectangle(0, 0, zoomWidth, zoomHeight),
new Rectangle(e.X - halfWidth, e.Y - halfHeight, zoomWidth, zoomHeight),
GraphicsUnit.Pixel);
// Draw the bitmap on the picZoom picturebox
picZoom.Image = tempBitmap;
// Draw a crosshair on the bitmap to simulate the cursor position
bmGraphics.DrawLine(Pens.Black, halfWidth + 1, halfHeight - 4, halfWidth + 1, halfHeight - 1);
bmGraphics.DrawLine(Pens.Black, halfWidth + 1, halfHeight + 6, halfWidth + 1, halfHeight + 3);
bmGraphics.DrawLine(Pens.Black, halfWidth - 4, halfHeight + 1, halfWidth - 1, halfHeight + 1);
bmGraphics.DrawLine(Pens.Black, halfWidth + 6, halfHeight + 1, halfWidth + 3, halfHeight + 1);
// Dispose of the Graphics object
bmGraphics.Dispose();
// Refresh the picZoom picturebox to reflect the changes
picZoom.Refresh();
}
If the formula of moving the picZoom control is what you want eg
int x = e.X + picZoom.Left - picImage.Left;
int y = e.Y + picZoom.Top - picImage.Top;
then the comparison is(x, y is the position in picImage meaning that 0,0 is the left top position):
if(x >= 0 && y >= 0 && x + picZoom.Width <= picImage.Width && y + picZoom.Height <= picImage.Height)
{
...
...
}
EDIT
When you click in picZoom and drag, the control moves with the mouse:
private Point mouseDown;
private void picZoom_MouseDown(object sender, MouseEventArgs e)
{
mouseDown = e.Location;
}
private void picZoom_MouseMove(object sender, MouseEventArgs e)
{
Point pnt;
int x, y;
if (MouseButtons.Left == e.Button)
{
pnt = picZoom.PointToScreen(e.Location);
pnt = this.PointToClient(pnt);
x = pnt.X - mouseDown.X;
y = pnt.Y - mouseDown.Y;
if (x < picImage.Left)
{
x = picImage.Left;
}
else if (x + picZoom.Width > picImage.Left + picImage.Width)
{
x = picImage.Left + picImage.Width - picZoom.Width;
}
else
{ }
if (y < picImage.Top)
{
y = picImage.Top;
}
else if (y + picZoom.Height > picImage.Top + picImage.Height)
{
y = picImage.Top + picImage.Height - picZoom.Height;
}
else
{ }
picZoom.Location = new Point(x, y);
}
}
valter
This is not an answer to your question as much as it is a suggestion. Could you not create a Rect() directly over your picture and simply check if the mouse position is within it's bounds.
Something along the lines of:
Rectangle rect = obj.GetBounds(e.Graphics);
if (!rect.Intersects(e.ClipRectangle))
continue;
(stolen from another post)
So I looked over your code again, and it struck me.
You are comparing an x value to the top bound of your picture and a y value to the left bound...
x <= picImage.Top && y <= picImage.Left
should be
x <= picImage.Left && y <= picImage.Top
That is, if I understand what you are trying to do.
Good luck!

Windows Forms -> WPF image control conversion question

I've always worked with Windows Forms, but now I'm trying to learn WPF due to it's advantages. Some time ago I created a picturebox control (with help of Damien here). And for me it's very hard to convert this control into WPF's Image control. I haven't found any appropriate help on the Internet.
My control is used for displaying (founded before) middle between two pages on a scanned image of book. It consists of two moveable points, line between them and areas to the left and to the right filled with semitransparent polygons.
The problem is that WPF is VERY different. It's even hard to draw a filled circle on a Image control.
Here is my code listing:
public partial class SplitPictureBox : System.Windows.Forms.PictureBox
{
public SplitPictureBox()
{
InitializeComponent();
}
private int mPointMoveInProgress = 0;
private int handleRadius = 5;
public int HandleRaduis
{
get { return handleRadius; }
set { handleRadius = value; }
}
private int middleTop = 0;
private int middleBottom = 0;
private int middle;
public int Middle
{
get
{
return (middleTop + middleBottom) /2;
}
set { middle = value; }
}
private double theta;
public double Theta
{
get
{
return (Math.Atan(((middleTop - middleBottom) / (double)this.Height)) * 180) / Math.PI;
}
set
{
theta = value;
int deltaX = (int)((Math.Tan((Math.PI / 180) * value)) * this.Height / 2);
middleTop = middle + deltaX;
middleBottom = middle - deltaX;
}
}
protected override void OnPaint(PaintEventArgs pe)
{
base.OnPaint(pe);
SolidBrush left = new SolidBrush(Color.FromArgb(80, Color.Blue));
SolidBrush right = new SolidBrush(Color.FromArgb(80, Color.Green));
SolidBrush brush = new SolidBrush(Color.Red);
pe.Graphics.FillPolygon(left, new Point[4] { new Point(0,0), new Point(middleTop,0),
new Point(middleBottom, this.Height), new Point(0, this.Height)
});
pe.Graphics.FillPolygon(right, new Point[4] { new Point(this.Width,0), new Point(middleTop,0),
new Point(middleBottom, this.Height), new Point(this.Width, this.Height)
});
// Draw line
pe.Graphics.DrawLine(new Pen(Color.Red, 2), new Point(middleTop, handleRadius), new Point(middleBottom, this.Height - handleRadius));
Rectangle rectangle;
// Draw first handle
rectangle = new Rectangle(middleTop - handleRadius, 0, handleRadius * 2, handleRadius * 2);
pe.Graphics.FillEllipse(brush, rectangle);
// Draw second handle
rectangle = new Rectangle(middleBottom - handleRadius, this.Height - handleRadius * 2, handleRadius * 2, handleRadius * 2);
pe.Graphics.FillEllipse(brush, rectangle);
}
private Point moveLineTop;
private Point moveLineBottom;
protected override void OnMouseDown(MouseEventArgs e)
{
moveLineTop = new Point(e.X - middleTop, 0);
moveLineBottom = new Point(e.X - middleBottom, this.Height);
if (Math.Abs(e.X - middleTop) < handleRadius && Math.Abs(e.Y) <= handleRadius * 2)
{
Cursor.Current = Cursors.Hand;
mPointMoveInProgress = 1;
}
else if (Math.Abs(e.X - middleBottom) < handleRadius && Math.Abs(e.Y - this.Height) <= handleRadius * 2)
{
Cursor.Current = Cursors.Hand;
mPointMoveInProgress = 2;
}
else if (Math.Abs(e.X - x) < handleRadius && e.Y > handleRadius * 2 && e.Y < this.Height - handleRadius * 2)
{
Cursor.Current = Cursors.SizeWE;
mPointMoveInProgress = 3;
}
else mPointMoveInProgress = 0;
base.OnMouseDown(e);
}
private int x = 0;
protected override void OnMouseMove(MouseEventArgs e)
{
x = middleTop - (int)((e.Y * (middleTop - middleBottom)) / (double)this.Height);
if (mPointMoveInProgress == 1)
{
Cursor.Current = Cursors.Hand;
if (e.X > 0 && e.X < this.Width)
{
middleTop = e.X;
Refresh();
}
}
else if (mPointMoveInProgress == 2)
{
Cursor.Current = Cursors.Hand;
if (e.X > 0 && e.X < this.Width)
{
middleBottom = e.X;
Refresh();
}
}
else if (mPointMoveInProgress == 3)
{
if (e.X - moveLineTop.X >= 0 && e.X - moveLineTop.X <= this.Width &&
e.X - moveLineBottom.X >= 0 && e.X - moveLineBottom.X <= this.Width)
{
Cursor.Current = Cursors.SizeWE;
middleTop = e.X - moveLineTop.X;
middleBottom = e.X - moveLineBottom.X;
Refresh();
}
}
else
{
if (Math.Abs(e.X - middleTop) < handleRadius && Math.Abs(e.Y) <= handleRadius * 2)
Cursor.Current = Cursors.Hand;
else if (Math.Abs(e.X - middleBottom) < handleRadius && Math.Abs(e.Y - this.Height) <= handleRadius * 2)
Cursor.Current = Cursors.Hand;
else if (Math.Abs(e.X - x) < handleRadius && e.Y > handleRadius * 2 && e.Y < this.Height - handleRadius * 2)
Cursor.Current = Cursors.SizeWE;
else Cursor.Current = Cursors.Default;
}
base.OnMouseMove(e);
}
protected override void OnMouseUp(MouseEventArgs e)
{
mPointMoveInProgress = 0;
middle = (middleTop + middleBottom) / 2;
base.OnMouseUp(e);
}
}
Could anybody to help me with this? Give me some useful links or code samples.
Thanks!
You are looking for Adorners, they can draw items over other controls, and also handle events, etc.
Some tips:
How to: Implement an Adorner
Adorners How-To Topics

Categories

Resources