Capture the screen selected by Current Form in WPF? - c#

I am creating a application which can capture the screen which is selected by current active windows form and make user aware by setting it as the background of it. Please refer the image
But my problem is i cant get the size of the active window size. This is the code i have been working on
private void button5_Click(object sender, RoutedEventArgs e)
{
Image b = null;
int w = (int)this.Width;
int h = (int)this.Height;
**System.Drawing.Size sz = this.Size;
System.Drawing.Point loc = this.Location;**
Hide();
System.Threading.Thread.Sleep(500);
using (b = new Bitmap(w, h))
{
using (Graphics g = Graphics.FromImage(b))
{
g.CopyFromScreen(loc, new System.Drawing.Point(0, 0), sz);
}
Image x = new Bitmap(b);
ImageBrush myBrush = new ImageBrush();
x.Save(#"C:\Users\DZN\Desktop\testBMP.jpeg", ImageFormat.Jpeg);
myBrush.ImageSource = new BitmapImage(new Uri(#"C:\Users\DZN\Desktop\testBMP.jpeg", UriKind.Absolute));
this.Background = myBrush;
}
Show();
}
In the bolded lines i get the error saying WpfApplication1.MainWindow' does not contain a definition for 'Size, location. but this works well in windows forms. Any help is hugly appreciated. Thank you.

WPF Window doesn't have a size property instead you can use ActualWidth and ActualHeight. Same way it doesn't exposes Location also but you can use Left and Top properties.
All the above properties are of type double so you need a cast to appropriate type.
System.Drawing.Size sz = new System.Drawing.Size((int)ActualWidth, (int)ActualHeight);
System.Drawing.Point loc = new System.Drawing.Point((int)Left, (int)Top);

Related

How to create a Windows Form in C# that can be seen only but can not be clicked or brought to focus

I am working on an Accessibility Screen Reader application that will put a rectangle highlighter around the element that is selected on the Focused program. I am able to detect the currently focused AutomationElement, and get its BoundingRectangle property. (How is Spy++ element highlighting working?)
Given a rectangle's topLeftCorner and bottomRightCorner, I am trying to draw a highlighter rectangle using the code below:
internal class HighlighterForm : Form
{
public HighlighterForm(Point topLeftCorner, Point bottomRightCorner, float borderWidth=5){
int length = bottomRightCorner.X - topLeftCorner.X;
int width = bottomRightCorner.Y - topLeftCorner.Y;
this.Text = "Highlighter";
this.FormBorderStyle = FormBorderStyle.None;
this.StartPosition = FormStartPosition.Manual;
this.Location = new Point(topLeftCorner.X, topLeftCorner.Y);
this.TopLevel = true;
this.TopMost = true;
this.Size = new Size(length, width);
// Make the Form background transparent
this.TransparencyKey = Color.Turquoise;
this.BackColor = Color.Turquoise;
this.Paint += (o, e) => {
Graphics g = e.Graphics;
using (Pen selPen = new Pen(Color.Blue, borderWidth*2))
{
g.DrawRectangle(selPen, 0, 0, length, width);
}
};
}
}
And then, I am using the following snippet to create the highlighter:
Point topLeftCorner = new Point(10, 50);
Point bottomRightCorner = new Point(600, 200);
HighlighterForm highlighter = new HighlighterForm(topLeftCorner, bottomRightCorner);
highlighter.ShowDialog();
This can draw a rectangle anywhere on the screen, but the problem is that this form does not let any contents found on an app under the rectangle to be selected. For example, if the currently selected element is a page from Microsoft Word, then the user won't be able to select a paragraph because the rectangle is on top.
How can I make sure the rectangle is there only visually and cannot be interacted with or clicked on?

Styling Windows Form Tab

I am creating windows Tabbed Application. Everything is good but the tabs are quiet faded and borders are very dull. I have tried changing the border style to 3D as well but no effect. Below is the screenshot
There are forums where people have suggested to use third party library to make Google Chrome type tabs. But I want the native way to get beautiful tabs.
You can take control of how the tabs are drawn by setting the DrawMode = TabDrawMode.OwnerDrawFixed. The example below assumes you have a TabControl named tabControl1 on the form, this will add a new tab with a blue box.
private Rectangle myTabRect;
private Rectangle myInsideRect;
private Rectangle myOutsideRect;
public Form1()
{
InitializeComponent();
TabPage tabPage1 = new TabPage();
// Sets the tabs to be drawn by the parent window Form1.
// OwnerDrawFixed allows access to DrawItem.
tabControl1.DrawMode = TabDrawMode.OwnerDrawFixed;
tabControl1.Controls.Add(tabPage1);
tabControl1.Location = new Point(25, 25);
tabControl1.Size = new Size(250, 250);
tabPage1.TabIndex = 0;
myTabRect = tabControl1.GetTabRect(0);
myInsideRect = new Rectangle(tabControl1.DisplayRectangle.X -1, tabControl1.DisplayRectangle.Y -1, tabControl1.DisplayRectangle.Width + 1, tabControl1.DisplayRectangle.Height + 1);
myOutsideRect = tabControl1.ClientRectangle;
myOutsideRect.Width--;
myOutsideRect.Height--;
ClientSize = new Size(300, 500);
Controls.Add(tabControl1);
tabControl1.DrawItem += new DrawItemEventHandler(OnDrawItem);
}
private void OnDrawItem(object sender, DrawItemEventArgs e)
{
// Draw your tab graphics here
Graphics g = e.Graphics;
Pen p = new Pen(Color.Blue);
g.DrawRectangle(p, myTabRect);
p = new Pen(Color.Red);
g.DrawRectangle(p, myInsideRect);
p = new Pen(Color.Green);
g.DrawRectangle(p, myOutsideRect);
}
You can draw whatever style you like into the graphic context, add text, images, etc

Adding element to another element win forms

I am adding one panel to another panel it works but circle which is in inspanel not shown. how can i solved this.
I am using below code. It works but not show circle
public static int xTemp = 0;
public static int yTemp = 0;
private void button1_Click(object sender, EventArgs e)
{
Panel insPanel = new Panel();
Random xRandom = new Random();
xTemp= xRandom.Next(20,100);
Random yRandom = new Random();
yTemp = yRandom.Next(20, 100);
insPanel.Location = new Point(xTemp, yTemp);
insPanel.Width=40;
insPanel.Height = 40;
insPanel.Visible = true;
insPanel.BorderStyle = BorderStyle.FixedSingle;
insPanel.Paint += new PaintEventHandler(insPanel_Paint);
panel1.Controls.Add(insPanel);
}
void insPanel_Paint(object sender, PaintEventArgs e)
{
System.Drawing.SolidBrush myBrush = new System.Drawing.SolidBrush(System.Drawing.Color.Red);
System.Drawing.Graphics formGraphics =this.CreateGraphics();
formGraphics.FillEllipse(myBrush, new Rectangle(xTemp,yTemp, 10, 10));
myBrush.Dispose();
formGraphics.Dispose();
}
Main issue: you're trying to draw your circle at wrong coordinates.
xTemp and yTemp are coordinates of insPanel relative to panel1. But when you drawing your circle, you should use coordinates relative to panel you're drawing at - insPanel.
Another issue: there is no need to create and dispose graphics each time you're drawing something on your panel. You can use e.Graphics from Paint eventhandler arguments.
Based on above, your code could look like:
void insPanel_Paint(object sender, PaintEventArgs e)
{
using (var myBrush = new SolidBrush(Color.Red))
{
e.Graphics.FillEllipse(myBrush, new Rectangle(0, 0, 10, 10));
}
}
Also note - since paint event can occur very frequently, it could be a good idea not to create and dispose brush every time, but use brush cached in your class private field.
Use e.Graphics instead of this.CreateGraphics:
System.Drawing.Graphics formGraphics = e.Graphics;
One more issue is you're getting coordinates in range of 20 - 100 (xRandom.Next(20,100)) and your panel dimensions are just 40, 40.

How to make picturebox transparent?

I am making an application in C# .NET. I have 8 picture boxes in it. I used PNG images with transparent background but in my form it is not transparent when it comes above another image.
I am using Visual Studio 2012. This is a screenshot of my form:
One way to do this is by changing the parent of the overlapping picture box to the PictureBox over which it is lapping. Since the Visual Studio designer doesn't allow you to add a PictureBox to a PictureBox, this will have to be done in your code (Form1.cs) and within the Intializing function:
public Form1()
{
InitializeComponent();
pictureBox7.Controls.Add(pictureBox8);
pictureBox8.Location = new Point(0, 0);
pictureBox8.BackColor = Color.Transparent;
}
Just change the picture box names to what ever you need. This should return:
GameBoard is control of type DataGridView;
The image should be type of PNG with transparent alpha channel background;
Image test = Properties.Resources.checker_black;
PictureBox b = new PictureBox();
b.Parent = GameBoard;
b.Image = test;
b.Width = test.Width*2;
b.Height = test.Height*2;
b.Location = new Point(0, 90);
b.BackColor = Color.Transparent;
b.BringToFront();
Try using an ImageList
ImageList imgList = new ImageList;
imgList.TransparentColor = Color.White;
Load the image like this:
picturebox.Image = imgList.Images[img_index];
I've had a similar problem like this.
You can not make Transparent picturebox easily such as picture that shown at top of this page, because .NET Framework and VS .NET objects are created by INHERITANCE! (Use Parent Property).
I solved this problem by RectangleShape and with the below code I removed background,
if difference between PictureBox and RectangleShape is not important and doesn't matter, you can use RectangleShape easily.
private void CreateBox(int X, int Y, int ObjectType)
{
ShapeContainer canvas = new ShapeContainer();
RectangleShape box = new RectangleShape();
box.Parent = canvas;
box.Size = new System.Drawing.Size(100, 90);
box.Location = new System.Drawing.Point(X, Y);
box.Name = "Box" + ObjectType.ToString();
box.BackColor = Color.Transparent;
box.BorderColor = Color.Transparent;
box.BackgroundImage = img.Images[ObjectType];// Load from imageBox Or any resource
box.BackgroundImageLayout = ImageLayout.Stretch;
box.BorderWidth = 0;
canvas.Controls.Add(box); // For feature use
}
One fast solution is set image property for image1 and set backgroundimage property to imag2, the only inconvenience is that you have the two images inside the picture box, but you can change background properties to tile, streched, etc. Make sure that backcolor be transparent.
Hope this helps
Just use the Form Paint method and draw every Picturebox on it, it allows transparency :
private void frmGame_Paint(object sender, PaintEventArgs e)
{
DoubleBuffered = true;
for (int i = 0; i < Controls.Count; i++)
if (Controls[i].GetType() == typeof(PictureBox))
{
var p = Controls[i] as PictureBox;
p.Visible = false;
e.Graphics.DrawImage(p.Image, p.Left, p.Top, p.Width, p.Height);
}
}
you can set the PictureBox BackColor proprty to Transparent

Select an image from rectangle using writeablebitmap

I have written an application in silverlight, I am placing a rectangle on the image and want to select the part of image covered by rectangle and show it on a image control on click of a button.
I am not good at handling ratios and image manipulation things, so I am unable to get it right way.
The code for the same goes as below, and would appreciate, if anyone could suggest me a way or solution to get around with this.
public void CaptureImage(object sender, RoutedEventArgs e)
{
BitmapImage bitmapImage = new BitmapImage();
//// bitmapImage.CreateOptions = BitmapCreateOptions.None;
bitmapImage = NewImage;
////calculate bounding box
int originalWidth = bitmapImage.PixelWidth;
int originalHeight = bitmapImage.PixelHeight;
int newSmallWidth = (int)SquareBlue.Width;
int newSmallHeight = (int)SquareBlue.Height;
////generate temporary control to render image
Image temporaryImage = new Image { Source = bitmapImage, Width = newSmallWidth, Height = newSmallHeight };
////create writeablebitmap
WriteableBitmap wb = new WriteableBitmap(newSmallWidth, newSmallHeight);
TranslateTransform t = new TranslateTransform();
t.X = -5;
t.Y = -5;
wb.Render(temporaryImage, t);
wb.Invalidate();
myImage.Source = wb;
}
Whenever this code gets executed, whole image gets snapped, instead of the part selected by rectangle. Could anyone, guide me as what I am doing wrong here.
I'd recommend that you use the Crop method the WriteableBitmapEx library provides.

Categories