/*
* Please leave this Copyright notice in your code if you use it
* Written by Decebal Mihailescu [http://www.codeproject.com/script/articles/list_articles.asp?userid=634640]
*/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Drawing.Imaging;
namespace SnapShot
{
public partial class LocalSnapShotForm : Form
{
private IntPtr _hwnd = IntPtr.Zero;
private UIApps _Apps;
private const Int32 IDM_ABOUT = 5000;
private Image GetScreenShot( Point location, Size size)
{
IntPtr windowHandle = Win32API.GetDesktopWindow();
Image myImage = new Bitmap(size.Width, size.Height);
Graphics g = Graphics.FromImage(myImage);
IntPtr destDeviceContext = g.GetHdc();
IntPtr srcDeviceContext = Win32API.GetWindowDC(windowHandle);
Win32API.BitBlt(destDeviceContext, 0, 0, size.Width, size.Height, srcDeviceContext, location.X, location.Y, Win32API.SRCCOPY);
Win32API.ReleaseDC(windowHandle, srcDeviceContext);
g.ReleaseHdc(destDeviceContext);
return myImage;
}
private static Bitmap MakeSnapshot(IntPtr AppWndHandle, bool IsClientWnd, Win32API.WindowShowStyle nCmdShow)
{
if (AppWndHandle == IntPtr.Zero || !Win32API.IsWindow(AppWndHandle) || !Win32API.IsWindowVisible(AppWndHandle))
return null;
if(Win32API.IsIconic(AppWndHandle))
Win32API.ShowWindow(AppWndHandle,nCmdShow);//show it
if(!Win32API.SetForegroundWindow(AppWndHandle))
return null;//can't bring it to front
System.Threading.Thread.Sleep(1000);//give it some time to redraw
RECT appRect;
bool res = IsClientWnd ? Win32API.GetClientRect(AppWndHandle, out appRect): Win32API.GetWindowRect(AppWndHandle, out appRect);
if (!res || appRect.Height == 0 || appRect.Width == 0)
{
return null;//some hidden window
}
if(IsClientWnd)
{
Point lt = new Point(appRect.Left, appRect.Top);
Point rb = new Point(appRect.Right, appRect.Bottom);
Win32API.ClientToScreen(AppWndHandle,ref lt);
Win32API.ClientToScreen(AppWndHandle,ref rb);
appRect.Left = lt.X;
appRect.Top = lt.Y;
appRect.Right = rb.X;
appRect.Bottom = rb.Y;
}
//Intersect with the Desktop rectangle and get what's visible
IntPtr DesktopHandle = Win32API.GetDesktopWindow();
RECT desktopRect;
Win32API.GetWindowRect(DesktopHandle, out desktopRect);
RECT visibleRect;
if (!Win32API.IntersectRect(out visibleRect, ref desktopRect, ref appRect))
{
visibleRect = appRect;
}
if(Win32API.IsRectEmpty(ref visibleRect))
return null;
int Width = visibleRect.Width;
int Height = visibleRect.Height;
IntPtr hdcTo = IntPtr.Zero;
IntPtr hdcFrom = IntPtr.Zero;
IntPtr hBitmap = IntPtr.Zero;
try
{
Bitmap clsRet = null;
// get device context of the window...
hdcFrom = IsClientWnd ? Win32API.GetDC(AppWndHandle) : Win32API.GetWindowDC(AppWndHandle);
// create dc that we can draw to...
hdcTo = Win32API.CreateCompatibleDC(hdcFrom);
hBitmap = Win32API.CreateCompatibleBitmap(hdcFrom, Width, Height);
// validate...
if (hBitmap != IntPtr.Zero)
{
// copy...
int x = appRect.Left < 0 ? -appRect.Left : 0;
int y = appRect.Top < 0 ? -appRect.Top : 0;
IntPtr hLocalBitmap = Win32API.SelectObject(hdcTo, hBitmap);
Win32API.BitBlt(hdcTo, 0, 0, Width, Height, hdcFrom, x, y, Win32API.SRCCOPY);
Win32API.SelectObject(hdcTo, hLocalBitmap);
// create bitmap for window image...
clsRet = System.Drawing.Image.FromHbitmap(hBitmap);
}
//MessageBox.Show(string.Format("rect ={0} \n deskrect ={1} \n visiblerect = {2}",rct,drct,VisibleRCT));
// return...
return clsRet;
}
finally
{
// release ...
if (hdcFrom != IntPtr.Zero)
Win32API.ReleaseDC(AppWndHandle, hdcFrom);
if(hdcTo != IntPtr.Zero)
Win32API.DeleteDC(hdcTo);
if (hBitmap != IntPtr.Zero)
Win32API.DeleteObject(hBitmap);
}
}
public LocalSnapShotForm()
{
InitializeComponent();
}
private void btnSnapShot_Click(object sender, EventArgs e)
{
Bitmap bitmap = MakeSnapshot(_hwnd, this.ckbClientWnd.Checked, Win32API.WindowShowStyle.Restore);
if (bitmap != null)
_pictureBox.Image = bitmap;
else
{
lblHwnd.Text = "Hwnd:";
btnSnapSot.Enabled = false;
}
btnSaveImage.Enabled = _pictureBox.Image != null;
Win32API.SetForegroundWindow(this.Handle);
}
private void btnSaveImage_Click(object sender, EventArgs e)
{
if(saveFileDialog1.ShowDialog()!=DialogResult.Cancel)
{
try
{
string ext = System.IO.Path.GetExtension(saveFileDialog1.FileName).Substring(1).ToLower();
switch (ext)
{
case "jpg":
case "jpeg":
_pictureBox.Image.Save(saveFileDialog1.FileName, ImageFormat.Jpeg);
break;
case "bmp":
_pictureBox.Image.Save(saveFileDialog1.FileName, ImageFormat.Bmp);
break;
case "gif":
_pictureBox.Image.Save(saveFileDialog1.FileName, ImageFormat.Gif);
break;
case "emf":
_pictureBox.Image.Save(saveFileDialog1.FileName, ImageFormat.Emf);
break;
case "ico":
_pictureBox.Image.Save(saveFileDialog1.FileName, ImageFormat.Icon);
break;
case "png":
_pictureBox.Image.Save(saveFileDialog1.FileName, ImageFormat.Png);
break;
case "tif":
_pictureBox.Image.Save(saveFileDialog1.FileName, ImageFormat.Tiff);
break;
case "wmf":
_pictureBox.Image.Save(saveFileDialog1.FileName, ImageFormat.Wmf);
break;
case "exif":
_pictureBox.Image.Save(saveFileDialog1.FileName, ImageFormat.Exif);
break;
default:
MessageBox.Show(this, "Unknown format.Select a known one.", "Conversion error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
break;
}
}
catch (Exception ex)
{
MessageBox.Show(this, ex.Message, "Image Conversion error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
private void LocalSnapShotForm_Load(object sender, EventArgs e)
{
saveFileDialog1.AddExtension = true;
saveFileDialog1.Filter = "Img(.bmp;.jpg;.jpeg;.gif;.emf;.ico;.png;.tif;.wmf;.exif)|*.BMP;*.JPG;*.jpeg;*.GIF;*.emf;*.ico;*.png;*.tif;*.wmf;*.exif|All files (*.*)|*.*";
saveFileDialog1.FilterIndex = 1;
IntPtr sysMenuHandle = Win32API.GetSystemMenu(this.Handle, false);
Win32API.AppendMenu(sysMenuHandle, Win32API.MF_SEPARATOR, 0, string.Empty);
Win32API.AppendMenu(sysMenuHandle, Win32API.MF_STRING, IDM_ABOUT, "About SnapShot...");
}
private void LocalSnapShotForm_Shown(object sender, EventArgs e)
{
_Apps = new UIApps(System.Diagnostics.Process.GetProcesses());
cmbProcs.BeginUpdate();
cmbProcs.DataSource = _Apps;
cmbProcs.DisplayMember = "Description";
cmbProcs.EndUpdate();
}
private void btnFindWnd_Click(object sender, EventArgs e)
{
_hwnd = Win32API.FindWindow((textBoxClass.Text.Length > 0) ? textBoxClass.Text : null,
(textBoxCaption.Text.Length > 0)?textBoxCaption.Text:null);
btnSnapSot.Enabled = false;
if (_hwnd != IntPtr.Zero)
{
RECT rct;
bool res = ckbClientWnd.Checked ? Win32API.GetWindowRect(_hwnd, out rct) : Win32API.GetClientRect(_hwnd, out rct);
if (!res)
{
MessageBox.Show("Can't get the window rectangle");
}
else
{
btnSnapSot.Enabled = true;
}
lblHwnd.Text = string.Format("Hwnd: {0:X}", (int)_hwnd);
}
else
{
lblHwnd.Text = "Hwnd:";
MessageBox.Show(string.Format("No window with class = '{0}' & Caption = '{1}'", textBoxClass.Text, textBoxCaption.Text));
}
}
private void textBox_TextChanged(object sender, EventArgs e)
{
btn_FindWnd.Enabled = textBoxCaption.Text.Length > 0 || textBoxClass.Text.Length > 0;
}
private void cmbProcs_SelectedIndexChanged(object sender, EventArgs e)
{
int ind = 0;
ComboBox cb = sender as ComboBox;
ind = cb.SelectedIndex;
_hwnd = _Apps[ind].HWnd;
btnSnapSot.Enabled = _hwnd != IntPtr.Zero;
textBoxCaption.Text = _Apps[ind].Caption;
textBoxClass.Text = _Apps[ind].WindowClass;
lblHwnd.Text = string.Format("Hwnd: {0:X}", (int)_hwnd);
btn_FindWnd.Enabled = false;
}
internal delegate void AboutHandler();
protected override void WndProc(ref Message m)
{
switch(m.WParam.ToInt32())
{
case IDM_ABOUT:
{
AboutHandler hnd = delegate()
{
AboutUtil.About dlg = new AboutUtil.About(this);
dlg.ShowDialog();
dlg.Dispose();
};
BeginInvoke(hnd);
}
break;
default:
break;
}
base.WndProc(ref m);
}
}
}
// HDC hDC, // Handle to the display device context
// hDCMem; // Handle to the memory device context
// HBITMAP hBitmap; // Handle to the new bitmap
// int iWidth, iHeight; // Width and height of the bitmap
// // Retrieve the handle to a display device context for the client
// // area of the window.
// hDC = GetDC (hwnd);
// // Create a memory device context compatible with the device.
// hDCMem = CreateCompatibleDC (hDC);
// // Retrieve the width and height of window display elements.
// iWidth = GetSystemMetrics (SM_CXSCREEN) / 10;
// iHeight = GetSystemMetrics (SM_CYSCREEN) / 10;
// // Create a bitmap compatible with the device associated with the
// // device context.
// hBitmap = CreateCompatibleBitmap (hDC, iWidth, iHeight);
//// Insert code to use the bitmap.
// // Delete the bitmap object and free all resources associated with it.
// DeleteObject (hBitmap);
// // Delete the memory device context and the display device context.
// DeleteDC (hDCMem);
// DeleteDC (hDC);