InvalidateRec with User32.dll , trying to delete all other frames except last frame created - c#

Im actually trying to paint an elipse around my cursor when i moove it, I dont want it to leave a trail like it does actually.
Can someone help with this, I believe it has something to do with the invalidaterec option
Any example son using invalidate rec?
Here is my code, besides the trail it has to work the same way it does now.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace MouseTest
{
public partial class Form1 : Form
{
[DllImport("user32.dll", EntryPoint = "GetDC")]
private static extern IntPtr GetDC(IntPtr hWnd);
[DllImport("user32.dll", EntryPoint = "ReleaseDC")]
private static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);
[System.Runtime.InteropServices.DllImport("Shell32.dll")]
private static extern int SHChangeNotify(int eventId, int flags, IntPtr item1, IntPtr item2);
System.Timers.Timer t1 = new System.Timers.Timer(100);
public Form1()
{
t1.Elapsed += new System.Timers.ElapsedEventHandler(t1_Elapsed);
t1.Start();
// System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.WaitCursor;
//Mouse.OverrideCursor = System.Windows.Input.Cursors.Hand;
InitializeComponent();
}
void t1_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
t1.Stop();
//SolidBrush b = new SolidBrush(Color.Red);
IntPtr desktopDC = GetDC(IntPtr.Zero);
Graphics g = Graphics.FromHdc(desktopDC);
g.FillEllipse(new SolidBrush(Color.BlueViolet), Cursor.Position.X, Cursor.Position.Y, 25, 25);
g.Dispose();
ReleaseDC(IntPtr.Zero, desktopDC);
t1.Start();
}
}
}

Yes, keeping the previous coordinate and calling InvalidateRect on the previous enclosing rectangle before drawing the new new ellipse would probably work. I don't have any code lying around that calls InvalidateRect, but if this is exactly your goal:" to paint an elipse around my cursor when i moove it, I dont want it to leave a trail like it does actually." there are other, more straight forward ways.
One way is to draw the ellipse on a transparent form and then move that form around based on the cursor's movement:
Here, first is the form definition:
namespace MouseForm
{
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (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()
{
this.components = new System.ComponentModel.Container();
this.shapeContainer1 = new Microsoft.VisualBasic.PowerPacks.ShapeContainer();
this.ovalShape1 = new Microsoft.VisualBasic.PowerPacks.OvalShape();
this.timer1 = new System.Windows.Forms.Timer(this.components);
this.SuspendLayout();
//
// shapeContainer1
//
this.shapeContainer1.Location = new System.Drawing.Point(0, 0);
this.shapeContainer1.Margin = new System.Windows.Forms.Padding(0);
this.shapeContainer1.Name = "shapeContainer1";
this.shapeContainer1.Shapes.AddRange(new Microsoft.VisualBasic.PowerPacks.Shape[] {
this.ovalShape1});
this.shapeContainer1.Size = new System.Drawing.Size(74, 74);
this.shapeContainer1.TabIndex = 0;
this.shapeContainer1.TabStop = false;
//
// ovalShape1
//
this.ovalShape1.BorderColor = System.Drawing.Color.Red;
this.ovalShape1.BorderWidth = 3;
this.ovalShape1.FillColor = System.Drawing.SystemColors.Control;
this.ovalShape1.FillStyle = Microsoft.VisualBasic.PowerPacks.FillStyle.Solid;
this.ovalShape1.Location = new System.Drawing.Point(2, 2);
this.ovalShape1.Name = "ovalShape1";
this.ovalShape1.Size = new System.Drawing.Size(70, 70);
//
// timer1
//
this.timer1.Enabled = true;
this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(74, 74);
this.ControlBox = false;
this.Controls.Add(this.shapeContainer1);
this.Enabled = false;
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.Name = "Form1";
this.ShowIcon = false;
this.ShowInTaskbar = false;
this.Text = "Form1";
this.TopMost = true;
this.TransparencyKey = System.Drawing.SystemColors.Control;
this.ResumeLayout(false);
}
#endregion
private Microsoft.VisualBasic.PowerPacks.ShapeContainer shapeContainer1;
private Microsoft.VisualBasic.PowerPacks.OvalShape ovalShape1;
private System.Windows.Forms.Timer timer1;
}
}
And here is the code:
using System;
using System.Windows.Forms;
namespace MouseForm
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void timer1_Tick(object sender, EventArgs e)
{
this.Left = Cursor.Position.X - this.Width / 2;
this.Top = Cursor.Position.Y - this.Height / 2;
}
}
}
I'll leave it as an exercise to the reader to implement a way to close the transparent form :)

Related

Why aren't the generated buttons showing in the FlowLayoutPanel?

So, I'm trying to create an accordion with dynamically loaded buttons. In the future, the title of the buttons will change depending on the details I've retrieved from somewhere. For now, what I'm trying to do is to load buttons to look like these:
I've tried doing the following below:
// Forms1.cs
using System;
using System.Drawing;
using System.Windows.Forms;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
int buttonCount = 3;
var buttons = new FontAwesome.Sharp.IconButton[buttonCount];
for (int i = 0; i < buttonCount; i++)
{
var btn = new FontAwesome.Sharp.IconButton
{
Text = "Button " + i,
TextAlign = ContentAlignment.MiddleLeft,
IconChar = FontAwesome.Sharp.IconChar.Book,
IconColor = ColorTranslator.FromHtml("#6A6A73"),
IconSize = 20,
IconFont = FontAwesome.Sharp.IconFont.Auto,
TextImageRelation = TextImageRelation.ImageBeforeText,
FlatStyle = FlatStyle.Flat
};
btn.FlatAppearance.BorderSize = 0;
btn.ForeColor = ColorTranslator.FromHtml("#6A6A73");
btn.BackColor = ColorTranslator.FromHtml("#FDFEFF");
btn.Dock = DockStyle.Top;
buttons[i] = btn;
}
flowLayoutPanel1.Controls.AddRange(buttons);
}
}
}
// Forms1.Designer.cs
namespace WindowsFormsApp1
{
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (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()
{
this.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel();
this.SuspendLayout();
//
// flowLayoutPanel1
//
this.flowLayoutPanel1.BackColor = System.Drawing.SystemColors.ControlLight;
this.flowLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Left;
this.flowLayoutPanel1.Location = new System.Drawing.Point(0, 0);
this.flowLayoutPanel1.Name = "flowLayoutPanel1";
this.flowLayoutPanel1.Size = new System.Drawing.Size(200, 450);
this.flowLayoutPanel1.TabIndex = 0;
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 450);
this.Controls.Add(this.flowLayoutPanel1);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1;
}
}
Here's what it looks like after building and running the application:
What am I doing wrong?
Form1_Load method is not subscribed to Load event of your form. Body of InitializeComponent is missing following line of code.
this.Load += new System.EventHandler(this.Form1_Load);
Insert this line before this.ResumeLayout(false);. You can fix it in designer as well.

How to capture screenshot without user32.dll which is unmanaged code

Overview
I am trying to capture a screenshot of external application and load the image to a .NET PictureBox.
user32.dll Unmanaged Code
There are a bunch of examples using user32.dll an I am looking for a .NET answer that does not use the user32.dll file.
App #1
I have provided sample code below that I am using for demonstration purposes. When the program is executed, it parses Processes and saves ones with valid window titles to the drop-down list.
When you select the app name from the drop-down list and click the button, it will try to capture the screenshot app and load into the .NET PictureBox.
Form1.cs
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Windows.Forms;
namespace WindowsFormsApplication3
{
public partial class Form1 : Form
{
Dictionary<string, IntPtr> apps = new Dictionary<string, IntPtr>();
public Form1()
{
InitializeComponent();
foreach (Process process in Process.GetProcesses())
{
if (string.IsNullOrEmpty(process.MainWindowTitle))
continue;
apps.Add(process.MainWindowTitle, process.MainWindowHandle);
comboBox1.Items.Add(process.MainWindowTitle);
}
}
private void button1_Click(object sender, EventArgs e)
{
IntPtr intptr = apps[comboBox1.Items[comboBox1.SelectedIndex].ToString()];
Graphics g = Graphics.FromHwnd(intptr);
// get width and height of app #2
int width = (int)g.VisibleClipBounds.Width;
int height = (int)g.VisibleClipBounds.Height;
Size s = new Size(width, height);
// create new bitmap
Bitmap wincapture = new Bitmap(width, height, g);
// code tried.
//g.CopyFromScreen(0, 0, 0, 0, new Size(width, height));
//g.DrawImage(wincapture, 0, 0, width, height);
// once App #2 has been captured, show image in picture box.
pictureBox1.Image = wincapture;
}
}
}
Form1.Designer.cs
namespace WindowsFormsApplication3
{
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (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()
{
this.pictureBox1 = new System.Windows.Forms.PictureBox();
this.button1 = new System.Windows.Forms.Button();
this.comboBox1 = new System.Windows.Forms.ComboBox();
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
this.SuspendLayout();
//
// pictureBox1
//
this.pictureBox1.Location = new System.Drawing.Point(13, 13);
this.pictureBox1.Name = "pictureBox1";
this.pictureBox1.Size = new System.Drawing.Size(267, 183);
this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
this.pictureBox1.TabIndex = 0;
this.pictureBox1.TabStop = false;
//
// button1
//
this.button1.Location = new System.Drawing.Point(102, 227);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(82, 23);
this.button1.TabIndex = 2;
this.button1.Text = "View Ext App";
this.button1.UseVisualStyleBackColor = true;
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// comboBox1
//
this.comboBox1.FormattingEnabled = true;
this.comboBox1.Location = new System.Drawing.Point(13, 202);
this.comboBox1.Name = "comboBox1";
this.comboBox1.Size = new System.Drawing.Size(267, 21);
this.comboBox1.TabIndex = 3;
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(292, 256);
this.Controls.Add(this.comboBox1);
this.Controls.Add(this.button1);
this.Controls.Add(this.pictureBox1);
this.Name = "Form1";
this.Text = "App #1";
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.PictureBox pictureBox1;
private System.Windows.Forms.Button button1;
private System.Windows.Forms.ComboBox comboBox1;
}
}
This is the code I came up with to take a screenshot of an application without using user32.dll.
To make the app active, and wait for 20 to make sure it has completed.
Microsoft.VisualBasic.Interaction.AppActivate(ProcessId);
Threading.Thread.Sleep(20);
To capture the active window, I used the following. Added a delay of 200, then convert the clipboard object to an image.
SendKeys.SendWait("%{PRTSC}");
Threading.Thread.Sleep(200);
IDataObject objData = Clipboard.GetDataObject();

C# reforming a task manager code made with C#

this is C# (Visual Studio 2013) Non of this codes where made from or for me...
hello, I have THIS CODE
/* Made by TheDarkJoker94.
* Check http://thedarkjoker094.blogspot.com/ for more C# Tutorials
* and also SUBSCRIBE to my Youtube Channel http://www.youtube.com/user/TheDarkJoker094
* Thanks! */
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
namespace SimpleTaskManager
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
Process[] procs;
public void GetProcesses()
{
procs = Process.GetProcesses();
if (Convert.ToInt32(label2.Text) != procs.Length) // Check if new processes have been started or terminated
{
listBox1.Items.Clear();
for (int i = 0; i < procs.Length; i++)
{
listBox1.Items.Add(procs[i].ProcessName); // Add the process name to the listbox
}
label2.Text = procs.Length.ToString();
}
}
private void Form1_Load(object sender, EventArgs e)
{
GetProcesses();
}
// Check every 1 second for changes in the processes list
private void timer1_Tick(object sender, EventArgs e)
{
GetProcesses();
}
private void button1_Click(object sender, EventArgs e)
{
procs[listBox1.SelectedIndex].Kill(); // Kill the process coresponding to the selected index of listbox1
}
private void kIllProcessToolStripMenuItem_Click(object sender, EventArgs e)
{
procs[listBox1.SelectedIndex].Kill();
}
public void lsit()
{
}
}
}
it works perfectly, but is not EXACTLY what im looking for... I need a code that tells me which is the FOREGROUND window at the moment... so using THIS other code i archived that...
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Runtime.InteropServices;
using System.Text;
namespace activeWindow
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
[ DllImport("user32.dll") ]
static extern int GetForegroundWindow();
[ DllImport("user32.dll") ]
static extern int GetWindowText(int hWnd, StringBuilder text, int count);
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.Label captionWindowLabel;
private System.Windows.Forms.Label IDWindowLabel;
private System.Windows.Forms.Button button1;
private System.Windows.Forms.Timer timer1;
private System.ComponentModel.IContainer components;
//
// GetForegroundWindow API
//
private void GetActiveWindow()
{
const int nChars = 256;
int handle = 0;
StringBuilder Buff = new StringBuilder(nChars);
handle = GetForegroundWindow();
if ( GetWindowText(handle, Buff, nChars) > 0 )
{
this.captionWindowLabel.Text = Buff.ToString();
this.IDWindowLabel.Text = handle.ToString();
}
}
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()
{
this.components = new System.ComponentModel.Container();
this.label1 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.label3 = new System.Windows.Forms.Label();
this.captionWindowLabel = new System.Windows.Forms.Label();
this.IDWindowLabel = new System.Windows.Forms.Label();
this.button1 = new System.Windows.Forms.Button();
this.timer1 = new System.Windows.Forms.Timer(this.components);
this.SuspendLayout();
//
// label1
//
this.label1.Location = new System.Drawing.Point(136, 8);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(112, 16);
this.label1.TabIndex = 0;
this.label1.Text = "Active Window Detail";
//
// label2
//
this.label2.Location = new System.Drawing.Point(16, 40);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(96, 16);
this.label2.TabIndex = 1;
this.label2.Text = "Window Caption : ";
//
// label3
//
this.label3.Location = new System.Drawing.Point(16, 88);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(96, 16);
this.label3.TabIndex = 2;
this.label3.Text = "Window Handle :";
//
// captionWindowLabel
//
this.captionWindowLabel.Location = new System.Drawing.Point(112, 40);
this.captionWindowLabel.Name = "captionWindowLabel";
this.captionWindowLabel.Size = new System.Drawing.Size(224, 40);
this.captionWindowLabel.TabIndex = 3;
//
// IDWindowLabel
//
this.IDWindowLabel.Location = new System.Drawing.Point(112, 88);
this.IDWindowLabel.Name = "IDWindowLabel";
this.IDWindowLabel.Size = new System.Drawing.Size(100, 16);
this.IDWindowLabel.TabIndex = 4;
//
// button1
//
this.button1.Location = new System.Drawing.Point(176, 128);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(48, 24);
this.button1.TabIndex = 5;
this.button1.Text = "EXIT";
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// timer1
//
this.timer1.Enabled = true;
this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(400, 173);
this.Controls.AddRange(new System.Windows.Forms.Control[] {
this.button1,
this.IDWindowLabel,
this.captionWindowLabel,
this.label3,
this.label2,
this.label1});
this.Name = "Form1";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Window Information";
this.TopMost = true;
this.ResumeLayout(false);
}
#endregion
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
private void timer1_Tick(object sender, System.EventArgs e)
{
GetActiveWindow();
}
private void button1_Click(object sender, System.EventArgs e)
{
this.Close();
}
}
}
EXPLANATION: The first code gives me the Process name of ALL of the applications that are running at the time... and the second gives me the "WINDOW NAME" and a code... of the application in the foreground.... what I need... is the PROCESS NAME of the FOREGROUND WINDOWS... so as you can see... if i could "mix" the two of them... it will be giving me what i need... ps... i only need the name of the ACTUAL foreground window in a Variable so i can use inside the code.... dont need the windows, boxes o actual text on me desktop... thanks
To get the process name of the foreground Window, you have to get the foregound Window GetForegroundWindow and then you can get its process id by using GetWindowThreadProcessId:
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
public static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll", SetLastError = true)]
static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
Process GetActiveProcess()
{
IntPtr hwnd = GetForegroundWindow();
uint pid;
GetWindowThreadProcessId(hwnd, out pid);
Process p = Process.GetProcessById((int)pid);
return p;
}
Then you can get the process name:
GetActiveProcess().ProcessName

Control resizing mathematics

Ok... So I've got this pretty killer Screenshot system I've been using for a while... It pretty much involves creating a somewhat transparent Form that auto-sizes to fit all monitors... Which gives the screen(s) a "dark-out" effect... I then have a hidden "button" control whos position is set upon mouse-down... Then, until mouse-up, the button will resize in real-time to create a sort of "selection" area... The Button is granted full transparency to implement this effect.
Source Example: http://db.tt/LWxfDB6 [Also posted below]
I'm having two issues that are directly related, I believe.
1.) The coordinates are off for multimonitors, it properly returns the coordinates that are clicked upon (highlighted), but the highlight box (effect) is often on the wrong monitor.
2.) You can only select from top-left ---> bottom-right and not universal.
Sorry if I didn't explain it well, the source should explain better.
Thanks, in advance, for any and all help received. :)
:MarkRect.cs:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Imaging;
using System.IO;
namespace TW_Media_Chat_
{
public partial class MarkRect : Form
{
Point Point1;
Point Point2;
public MarkRect()
{
InitializeComponent();
// Programatically maximize to all monitors
Screen[] Screens = Screen.AllScreens;
int AllWidth = 0;
int AllHeight = 0;
for (int index = 0; index < Screens.Length; index++)
{
AllWidth += Screens[index].Bounds.Width;
AllHeight += Screens[index].Bounds.Height;
}
this.Width = AllWidth;
this.Height = AllHeight;
}
private void Transparency_MouseDown(object sender, MouseEventArgs e)
{
button1.Visible = true;
button1.Location = Cursor.Position;
Point1 = Cursor.Position;
}
private void Transparency_MouseUp(object sender, MouseEventArgs e)
{
this.Visible = false;
Point2 = Cursor.Position;
AjaxChatBridge.AjaxVars.Point1 = Point1;
AjaxChatBridge.AjaxVars.Point2 = Point2;
this.Close();
}
private void MarkRect_MouseMove(object sender, MouseEventArgs e)
{
this.button1.Width = Cursor.Position.X - this.button1.Left;
this.button1.Height = Cursor.Position.Y - this.button1.Top;
}
}
}
:MarkRect.Designer.cs:
namespace TW_Media_Chat_
{
partial class MarkRect
{
///
/// Required designer variable.
///
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (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()
{
this.button1 = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// button1
//
this.button1.BackColor = System.Drawing.Color.Lime;
this.button1.ForeColor = System.Drawing.Color.Lime;
this.button1.Location = new System.Drawing.Point(220, 172);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(19, 18);
this.button1.TabIndex = 0;
this.button1.Text = "button1";
this.button1.UseVisualStyleBackColor = false;
this.button1.Visible = false;
//
// MarkRect
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.Color.Black;
this.ClientSize = new System.Drawing.Size(490, 406);
this.Controls.Add(this.button1);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.Name = "MarkRect";
this.Opacity = 0.5D;
this.Text = "Transparency";
this.TopMost = true;
this.TransparencyKey = System.Drawing.Color.Lime;
this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.Transparency_MouseDown);
this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.MarkRect_MouseMove);
this.MouseUp += new System.Windows.Forms.MouseEventHandler(this.Transparency_MouseUp);
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Button button1;
}
}
You should implement control resizing logic easier:
void MarkRect_MouseMove(...)
{
var mouseX = Cursor.Position.X;
var originalMouseX = Point1.X;
button1.Left = Math.Min(mouseX, originalMouseX);
button1.Width = Math.Abs(mouseX - originalMouseX);
// the same for Y
}
You should post that code here. We are to lazy to go to your dropbox to see the code. There are easier questions to answer here.

What's the correct way to use controls in Owner drawn list box?

I am experimenting with owner drawn list box. I am adding a text box to a specific item within list box. However, when I start scrolling, the text box does not display in the right location. What is the right way to do this?
Here's the code I am using.
Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
namespace ListBoxControlScrollIssue
{
public partial class Form1 : Form
{
private const Int32 cellHeight = 40;
private ListBox listBox1;
private Font displayFont = new Font(FontFamily.GenericSerif, 8, FontStyle.Regular);
private Brush displayBrush = Brushes.Black;
private Pen displayPen = Pens.Black;
private Button separateDebug;
private TextBox item3Text;
public Form1()
{
SetupListBox();
}
private void SetupListBox()
{
this.listBox1 = new System.Windows.Forms.ListBox();
this.SuspendLayout();
//
// listBox1
//
this.listBox1.FormattingEnabled = true;
this.listBox1.Location = new System.Drawing.Point(40, 40);
this.listBox1.Name = "listBox1";
this.listBox1.Size = new System.Drawing.Size(300, 100);
this.listBox1.TabIndex = 0;
this.listBox1.DrawMode = DrawMode.OwnerDrawVariable;
this.listBox1.MeasureItem += new MeasureItemEventHandler(listBox1_MeasureItem);
this.listBox1.DrawItem += new DrawItemEventHandler(listBox1_DrawItem);
//
// Add items to list box.
//
this.listBox1.Items.Add("Item0");
this.listBox1.Items.Add("Item1");
this.listBox1.Items.Add("Item2");
this.listBox1.Items.Add("Item3");
this.listBox1.Items.Add("Item4");
//
// Add button.
//
separateDebug = new Button();
separateDebug.Name = "SeperateDebug";
separateDebug.Text = "Seperator";
separateDebug.Location = new Point(400, 100);
separateDebug.Click += new EventHandler(separateDebug_Click);
//
// Create the text box. However, don't add it to anything.
//
item3Text = new TextBox();
item3Text.Name = "item3Text";
item3Text.Multiline = false;
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(525, 421);
this.Controls.Add(this.listBox1);
this.Controls.Add(this.separateDebug);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
}
void separateDebug_Click(object sender, EventArgs e)
{
Debug.Print("\n=========================\n");
}
void listBox1_DrawItem(object sender, DrawItemEventArgs e)
{
PointF displayLocation = new PointF(20, e.Index * cellHeight + 3);
//
// Display text names of the items here.
//
//
Debug.Print("DrawItem:: Index = {0}, location = {1}", e.Index, displayLocation);
e.Graphics.DrawString(this.listBox1.Items[e.Index].ToString(), displayFont, displayBrush, e.Bounds);
//
// Draw rectangle around the border to show boundary of cell.
//
e.Graphics.DrawRectangle(displayPen, e.Bounds);
}
void listBox1_MeasureItem(object sender, MeasureItemEventArgs e)
{
e.ItemHeight = cellHeight;
e.ItemWidth = this.listBox1.Width;
if (e.Index == 3)
{
//
// Set the location of item3Text to the location of bounds.
//
item3Text.Location = new Point(21, e.Index * cellHeight + 21);
listBox1.Controls.Add(item3Text);
}
}
}
}
Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
namespace ListBoxControlScrollIssue
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}
Form.Designer.cs
namespace ListBoxControlScrollIssue
{
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (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()
{
}
#endregion
}
}
Edit I re-wrote my answer in order to be clearer.
The ListBox below displays a TextBox with along its SelectedItem.
GetItemRectangle(int index)
is used to retrieve an item's current location in the ListBox. It seems to be the key method you're looking for.
public class ListBoxEx : ListBox
{
public ListBoxEx()
{
TextBox.Visible = false;
Controls.Add(TextBox);
}
private readonly Size TextBoxOffset = new Size(16, 16);
private const Int32 CellHeight = 40;
private readonly TextBox TextBox = new TextBox();
protected override void OnSelectedIndexChanged(EventArgs e)
{
base.OnSelectedIndexChanged(e);
TextBox.Visible = SelectedIndex != -1;
}
protected override void OnDrawItem(DrawItemEventArgs e)
{
base.OnDrawItem(e);
// Somehow necessary
e.Graphics.FillRectangle(new SolidBrush(BackColor), e.Bounds);
// Drawing the item's text
e.Graphics.DrawString(Items[e.Index].ToString(), Font, new SolidBrush(ForeColor), e.Bounds);
// Drawing the item's borders
e.Graphics.DrawRectangle(new Pen(ForeColor), e.Bounds);
// Drawing updating the TextBox location
if (SelectedIndex != -1)
TextBox.Location = Point.Add(GetItemRectangle(SelectedIndex).Location, TextBoxOffset);
// Because clicking the scrollbar sometimes cause the ListBox to hide the TextBox
TextBox.BringToFront();
// Making sure the TextBox is redrawn ASAP
TextBox.Invalidate();
}
protected override void OnMeasureItem(MeasureItemEventArgs e)
{
base.OnMeasureItem(e);
e.ItemHeight = CellHeight;
}
}

Categories