How to capture SDI windows image when it is minimize in MDI form c# win apps
in windows 7 one feature is very good that when any apps is minimize and when user point mouse cursor on that minimize for then the image of that form is show in hover popup. so if i want to do it i开发者_C百科n my MDI form that when any SDI is minimize in MDI form and when user point mouse on that minimize form then the form image will show in hover popup. how to accomplish it in windows application through c#
I have not tried this my self, but if I would think that the most likely solution for an MDI application would be to create the bitmap image of the child window prior to it being minimized and then use that image to show the last state of the window.
You will also need to handle a few of the 'WM_NC*' messages to detect that the mouse is hovering over the minimized window and then render your cached image in a popup.
UPDATE:
Here is a quick and dirty proof of concept, it is not perfect the tooltip does not follow all the standard tooltip functionality etc. but it should be enough to get you started. The code could also be refactored to be more reusable, but at this stage you could derive your MDI child windows from this MDIChild and you would have this basic tooltip functionality. Of course there will be issues if windows are overlapping etc.
using System;
using System.Drawing;
using System.Windows.Forms;
namespace MDITest
{
public partial class MDIChild : Form
{
private static TooltipForm _tooltip = new TooltipForm();
private static Form _lastForm;
private Image _lastSnapshot;
public MDIChild()
{
InitializeComponent();
}
protected override void WndProc(ref Message m)
{
if (m.Msg == WM_COMMAND && m.WParam.ToInt32() == SC_MINIMIZE)
{
OnMinimize(EventArgs.Empty);
}
else if (m.Msg == WM_NCMOUSEMOVE)
{
int x = m.LParam.ToInt32() & 0x0000ffff;
int y = m.LParam.ToInt32() >> 16;
OnNcMouseMove(new MouseEventArgs(MouseButtons.None, 0, x, y, 0));
}
base.WndProc(ref m);
}
protected virtual void OnNcMouseMove(MouseEventArgs e)
{
if (this.WindowState == FormWindowState.Minimized && _lastForm != this)
{
_lastForm = this;
Point pt = MdiParent.PointToScreen(this.Location);
ShowWindowTip(pt, _lastSnapshot);
}
}
protected virtual void OnMinimize(EventArgs e)
{
_tooltip.Visible = false;
if (_lastSnapshot == null)
{
_lastSnapshot = new Bitmap(100, 100);
}
using (Image windowImage = new Bitmap(ClientRectangle.Width, ClientRectangle.Height))
using (Graphics windowGraphics = Graphics.FromImage(windowImage))
using (Graphics tipGraphics = Graphics.FromImage(_lastSnapshot))
{
Rectangle r = this.RectangleToScreen(ClientRectangle);
windowGraphics.CopyFromScreen(new Point(r.Left, r.Top), Point.Empty, new Size(r.Width, r.Height));
windowGraphics.Flush();
float scaleX = 1;
float scaleY = 1;
if (ClientRectangle.Width > ClientRectangle.Height)
{
scaleY = (float)ClientRectangle.Height / ClientRectangle.Width;
}
else if (ClientRectangle.Height > ClientRectangle.Width)
{
scaleX = (float)ClientRectangle.Width / ClientRectangle.Height;
}
tipGraphics.DrawImage(windowImage, 0, 0, 100 * scaleX, 100 * scaleY);
}
}
private static void ShowWindowTip(Point pt, Image image)
{
if (_tooltip.Visible)
{
_tooltip.Visible = false;
}
_tooltip.Image = image;
_tooltip.Show();
_tooltip.Location = new Point(pt.X, pt.Y - _tooltip.Height - 10);
}
private static int WM_NCMOUSEMOVE = 0x00A0;
private static int WM_COMMAND = 0x0112;
private static int SC_MINIMIZE = 0xf020;
}
}
Here is the TooltipForm.designer.cs
namespace MDITest
{
partial class TooltipForm
{
/// <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();
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
this.SuspendLayout();
//
// pictureBox1
//
this.pictureBox1.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Center;
this.pictureBox1.Dock = System.Windows.Forms.DockStyle.Fill;
this.pictureBox1.Location = new System.Drawing.Point(0, 0);
this.pictureBox1.Name = "pictureBox1";
this.pictureBox1.Size = new System.Drawing.Size(134, 112);
this.pictureBox1.TabIndex = 0;
this.pictureBox1.TabStop = false;
//
// TooltipForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(134, 112);
this.ControlBox = false;
this.Controls.Add(this.pictureBox1);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "TooltipForm";
this.ShowIcon = false;
this.ShowInTaskbar = false;
this.Text = "TooltipForm";
this.TopMost = true;
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.PictureBox pictureBox1;
}
}
And the TooltipForm.cs
using System;
using System.Drawing;
using System.Windows.Forms;
namespace MDITest
{
public partial class TooltipForm : Form
{
Timer _timer = new Timer();
public TooltipForm()
{
InitializeComponent();
TopLevel = true;
_timer.Enabled = false;
_timer.Interval = 5000;
_timer.Tick += new EventHandler(_timer_Tick);
}
void _timer_Tick(object sender, EventArgs e)
{
Visible = false;
}
protected override void SetVisibleCore(bool value)
{
if (value == true)
{
_timer.Start();
}
else
{
_timer.Stop();
}
base.SetVisibleCore(value);
}
public Image Image
{
get
{
return pictureBox1.Image;
}
set
{
pictureBox1.Image = value;
}
}
}
}
精彩评论