I am trying to implement the functionality of taking screenshot and sending the capture to printer. No need to implement the print functionality,user will decide whether to print or cancel that particular document. After digging around the internet and tweaking it to my requirement I am able to save the screenshot locally but unable to send it to printer.
public ActionResult About()
{
ScreenCapture sc = new ScreenCapture();
// capture entire screen, and save it to a file
Image img = sc.CaptureScreen();
// capture this window, and save it
sc.CaptureScreenToFile("C:\\temp2.png", ImageFormat.Png);
return View();
}
public class ScreenCapture
{
/// <summary>
/// Creates an Image object containing a screen shot of the entire desktop
/// </summary>
/// <returns></returns>
public Image CaptureScreen()
{
return CaptureWindow(User32.GetDesktopWindow());
}
/// <summary>
/// Creates an Image object containing a screen shot of a specific window
/// </summary>
/// <param name="handle">The handle to the window. (In windows forms, this is obtained by the Handle property)</param>
/// <returns></returns>
public Image CaptureWindow(IntPtr handle)
{
// get te hDC of the target window
IntPtr hdcSrc = User32.GetWindowDC(handle);
// get the size
User32.RECT windowRect = new User32.RECT();
User32.GetWindowRect(handle, ref windowRect);
int width = windowRect.right - windowRect.left;
int height = windowRect.bottom - windowRect.top;
// create a device context we can copy to
IntPtr hdcDest = GDI32.CreateCompatibleDC(hdcSrc);
// create a bitmap we can copy it to,
// using GetDeviceCaps to get the width/height
IntPtr hBitmap = GDI32.CreateCompatibleBitmap(hdcSrc, width, height);
// select the bitmap object
IntPtr hOld = GDI32.SelectObject(hdcDest, hBitmap);
// bitblt over
GDI32.BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, GDI32.SRCCOPY);
// restore selection
GDI32.SelectObject(hdcDest, hOld);
// clean up
GDI32.DeleteDC(hdcDest);
User32.ReleaseDC(handle, hdcSrc);
// get a .NET image object for it
Image img = Image.FromHbitmap(hBitmap);
// free up the Bitmap object
GDI32.DeleteObject(hBitmap);
return img;
}
/// <summary>
/// Captures a screen shot of a specific window, and saves it to a file
/// </summary>
/// <param name="handle"></param>
/// <param name="filename"></param>
/// <param name="format"></param>
public void CaptureWindowToFile(IntPtr handle, string filename, ImageFormat format)
{
Image img = CaptureWindow(handle);
img.Save(filename, format);
}
/// <summary>
/// Captures a screen shot of the entire desktop, and saves it to a file
/// </summary>
/// <param name="filename"></param>
/// <param name="format"></param>
public void CaptureScreenToFile(string filename, ImageFormat format)
{
Image img = CaptureScreen();
img.Save(filename, format);
}
/// <summary>
/// Helper class containing Gdi32 API functions
/// </summary>
private class GDI32
{
public const int SRCCOPY = 0x00CC0020; // BitBlt dwRop parameter
[DllImport("gdi32.dll")]
public static extern bool BitBlt(IntPtr hObject, int nXDest, int nYDest,
int nWidth, int nHeight, IntPtr hObjectSource,
int nXSrc, int nYSrc, int dwRop);
[DllImport("gdi32.dll")]
public static extern IntPtr CreateCompatibleBitmap(IntPtr hDC, int nWidth,
int nHeight);
[DllImport("gdi32.dll")]
public static extern IntPtr CreateCompatibleDC(IntPtr hDC);
[DllImport("gdi32.dll")]
public static extern bool DeleteDC(IntPtr hDC);
[DllImport("gdi32.dll")]
public static extern bool DeleteObject(IntPtr hObject);
[DllImport("gdi32.dll")]
public static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject);
}
/// <summary>
/// Helper class containing User32 API functions
/// </summary>
private class User32
{
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
}
[DllImport("user32.dll")]
public static extern IntPtr GetDesktopWindow();
[DllImport("user32.dll")]
public static extern IntPtr GetWindowDC(IntPtr hWnd);
[DllImport("user32.dll")]
public static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDC);
[DllImport("user32.dll")]
public static extern IntPtr GetWindowRect(IntPtr hWnd, ref RECT rect);
}
}
Any leads/help will be appreciated. I have come across the PrintDocument class but they were mostly used in WindowsForm/WPF, was not very confident about using in MVC. Thanks in Advance
Related
This question already has answers here:
Capture screenshot of active window?
(13 answers)
Closed 3 years ago.
I am trying to capture the screen using Visual Studio 12 (sorry, we have to use 12) cand C#.
I found an algorithm here: Capture screenshot of active window?
ScreenCapture sc = new ScreenCapture();
I tried this and got an error message that the type or namespace is not found.
This is not unexpected. I figured I just need another "using..." statement up at the top.
I tried to do a search for which package to do a "using" on to get ScreenCapture() but I come up empty handed. Does anyone know?
I think it is probably giving you an error around using System.Runtime.InteropServices;
You need to add the reference of the DLL System.Runtime.InteropServices
This lib doesn't seem to exist on NuGet. However, you can find it at Developer Fusion.
The downloads section only includes a zip file with the following class, that you can copy-paste in your VS Project
using System;
using System.Runtime.InteropServices;
using System.Drawing;
using System.Drawing.Imaging;
namespace ScreenShotDemo
{
/// <summary>
/// Provides functions to capture the entire screen, or a particular window, and save it to a file.
/// </summary>
public class ScreenCapture
{
/// <summary>
/// Creates an Image object containing a screen shot of the entire desktop
/// </summary>
/// <returns></returns>
public Image CaptureScreen()
{
return CaptureWindow( User32.GetDesktopWindow() );
}
/// <summary>
/// Creates an Image object containing a screen shot of a specific window
/// </summary>
/// <param name="handle">The handle to the window. (In windows forms, this is obtained by the Handle property)</param>
/// <returns></returns>
public Image CaptureWindow(IntPtr handle)
{
// get te hDC of the target window
IntPtr hdcSrc = User32.GetWindowDC(handle);
// get the size
User32.RECT windowRect = new User32.RECT();
User32.GetWindowRect(handle,ref windowRect);
int width = windowRect.right - windowRect.left;
int height = windowRect.bottom - windowRect.top;
// create a device context we can copy to
IntPtr hdcDest = GDI32.CreateCompatibleDC(hdcSrc);
// create a bitmap we can copy it to,
// using GetDeviceCaps to get the width/height
IntPtr hBitmap = GDI32.CreateCompatibleBitmap(hdcSrc,width,height);
// select the bitmap object
IntPtr hOld = GDI32.SelectObject(hdcDest,hBitmap);
// bitblt over
GDI32.BitBlt(hdcDest,0,0,width,height,hdcSrc,0,0,GDI32.SRCCOPY);
// restore selection
GDI32.SelectObject(hdcDest,hOld);
// clean up
GDI32.DeleteDC(hdcDest);
User32.ReleaseDC(handle,hdcSrc);
// get a .NET image object for it
Image img = Image.FromHbitmap(hBitmap);
// free up the Bitmap object
GDI32.DeleteObject(hBitmap);
return img;
}
/// <summary>
/// Captures a screen shot of a specific window, and saves it to a file
/// </summary>
/// <param name="handle"></param>
/// <param name="filename"></param>
/// <param name="format"></param>
public void CaptureWindowToFile(IntPtr handle, string filename, ImageFormat format)
{
Image img = CaptureWindow(handle);
img.Save(filename,format);
}
/// <summary>
/// Captures a screen shot of the entire desktop, and saves it to a file
/// </summary>
/// <param name="filename"></param>
/// <param name="format"></param>
public void CaptureScreenToFile(string filename, ImageFormat format)
{
Image img = CaptureScreen();
img.Save(filename,format);
}
/// <summary>
/// Helper class containing Gdi32 API functions
/// </summary>
private class GDI32
{
public const int SRCCOPY = 0x00CC0020; // BitBlt dwRop parameter
[DllImport("gdi32.dll")]
public static extern bool BitBlt(IntPtr hObject,int nXDest,int nYDest,
int nWidth,int nHeight,IntPtr hObjectSource,
int nXSrc,int nYSrc,int dwRop);
[DllImport("gdi32.dll")]
public static extern IntPtr CreateCompatibleBitmap(IntPtr hDC,int nWidth,
int nHeight);
[DllImport("gdi32.dll")]
public static extern IntPtr CreateCompatibleDC(IntPtr hDC);
[DllImport("gdi32.dll")]
public static extern bool DeleteDC(IntPtr hDC);
[DllImport("gdi32.dll")]
public static extern bool DeleteObject(IntPtr hObject);
[DllImport("gdi32.dll")]
public static extern IntPtr SelectObject(IntPtr hDC,IntPtr hObject);
}
/// <summary>
/// Helper class containing User32 API functions
/// </summary>
private class User32
{
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
}
[DllImport("user32.dll")]
public static extern IntPtr GetDesktopWindow();
[DllImport("user32.dll")]
public static extern IntPtr GetWindowDC(IntPtr hWnd);
[DllImport("user32.dll")]
public static extern IntPtr ReleaseDC(IntPtr hWnd,IntPtr hDC);
[DllImport("user32.dll")]
public static extern IntPtr GetWindowRect(IntPtr hWnd,ref RECT rect);
}
}
}
According to the documentation you need to use Windows.Media.Capture. Please note that
Important
The ScreenCapture feature is only supported for mobile devices running Windows Phone 8.1. This API is not supported on Windows 10.
You can check this answer which works on all windows desktop platforms.
Purpose: Mirror a window of an external process by capturing images from this window and presenting the images in a picturebox using a timer.
Problem: When my application is in focus, everything happens fine! But if I switch the focus to the other window (not from my application), the picturebox stops refreshing the images. When I focus on my application again, everything returns to normal.
Limitation: I need the picturebox to continue updating even though my application is in the background.
Timer to capture images and show in picturebox:
private void timer_picBOX_refresh_Tick(object sender, EventArgs e)
{
pictureBox1.BackgroundImage = PrintScreen.CaptureWindow(GAME_MainHandle);
pictureBox1.Refresh();
}
Class to capture specific window:
public class class_ScreenCapture
{
public Image CaptureScreen()
{
return CaptureWindow(User32.GetDesktopWindow());
}
/// <summary>
/// Creates an Image object containing a screen shot of a specific window
/// </summary>
public Image CaptureWindow(IntPtr handle, int imgX = 0, int imgY = 0, int largura = 0, int altura = 0)
{
// get te hDC of the target window
IntPtr hdcSrc = User32.GetWindowDC(handle);
// get the size
User32.RECT windowRect = new User32.RECT();
User32.GetWindowRect(handle, ref windowRect);
if (largura == 0 || altura == 0)
{
largura = windowRect.right - windowRect.left;
altura = windowRect.bottom - windowRect.top;
}
// create a device context we can copy to
IntPtr hdcDest = GDI32.CreateCompatibleDC(hdcSrc);
// create a bitmap we can copy it to,
// using GetDeviceCaps to get the width/height
IntPtr hBitmap = GDI32.CreateCompatibleBitmap(hdcSrc, largura, altura);
// select the bitmap object
IntPtr hOld = GDI32.SelectObject(hdcDest, hBitmap);
// bitblt over
GDI32.BitBlt(hdcDest, 0, 0, largura, altura, hdcSrc, imgX, imgY, GDI32.SRCCOPY);
// restore selection
GDI32.SelectObject(hdcDest, hOld);
// clean up
GDI32.DeleteDC(hdcDest);
User32.ReleaseDC(handle, hdcSrc);
// get a .NET image object for it
Image img = Image.FromHbitmap(hBitmap);
// free up the Bitmap object
GDI32.DeleteObject(hBitmap);
return img;
}
/// <summary>
/// Helper class containing Gdi32 API functions
/// </summary>
private class GDI32
{
public const int SRCCOPY = 0x00CC0020; // BitBlt dwRop parameter
[DllImport("gdi32.dll")]
public static extern bool BitBlt(IntPtr hObject, int nXDest, int nYDest,
int nWidth, int nHeight, IntPtr hObjectSource,
int nXSrc, int nYSrc, int dwRop);
[DllImport("gdi32.dll")]
public static extern IntPtr CreateCompatibleBitmap(IntPtr hDC, int nWidth,
int nHeight);
[DllImport("gdi32.dll")]
public static extern IntPtr CreateCompatibleDC(IntPtr hDC);
[DllImport("gdi32.dll")]
public static extern bool DeleteDC(IntPtr hDC);
[DllImport("gdi32.dll")]
public static extern bool DeleteObject(IntPtr hObject);
[DllImport("gdi32.dll")]
public static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject);
}
/// <summary>
/// Helper class containing User32 API functions
/// </summary>
private class User32
{
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
}
[DllImport("user32.dll")]
public static extern IntPtr GetDesktopWindow();
[DllImport("user32.dll")]
public static extern IntPtr GetWindowDC(IntPtr hWnd);
[DllImport("user32.dll")]
public static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDC);
[DllImport("user32.dll")]
public static extern IntPtr GetWindowRect(IntPtr hWnd, ref RECT rect);
}
}
Test it.
private void timer_picBOX_refresh_Tick(object sender, EventArgs e)
{
pictureBox1.Image = PrintScreen.CaptureWindow(GAME_MainHandle);
pictureBox1.Refresh();
Refresh();
}
I downloaded a class with handy methods that I use to take screenshots of other programs for a while now
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
namespace EmulatorObserver.model
{
/// <summary>
/// Provides functions to capture the entire screen, or a particular window, and save it to a file.
/// </summary>
public static class ScreenCapture
{
/// <summary>
/// Creates an Image object containing a screen shot of a specific window
/// </summary>
/// <param name="handle">The handle to the window. (In windows forms, this is obtained by the Handle property)</param>
/// <returns></returns>
public static Bitmap CaptureWindow(IntPtr handle)
{
// get te hDC of the target window
IntPtr hdcSrc = GetWindowDC(handle);
// get the size
RECT windowRect = new RECT();
GetWindowRect(handle, ref windowRect);
int width = windowRect.right - windowRect.left;
int height = windowRect.bottom - windowRect.top;
// create a device context we can copy to
IntPtr hdcDest = CreateCompatibleDC(hdcSrc);
// create a bitmap we can copy it to,
// using GetDeviceCaps to get the width/height
IntPtr hBitmap = CreateCompatibleBitmap(hdcSrc, width, height);
// select the bitmap object
IntPtr hOld = SelectObject(hdcDest, hBitmap);
// bitblt over
BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, SRCCOPY);
// restore selection
SelectObject(hdcDest, hOld);
// clean up
DeleteDC(hdcDest);
ReleaseDC(handle, hdcSrc);
// get a .NET image object for it
Bitmap raw;
using(Image img = Image.FromHbitmap(hBitmap))
{
raw = (Bitmap)img.Clone();
}
// free up the Bitmap object
DeleteObject(hBitmap);
return raw;
}
////////////////////////////////////////////////////////////////////////////////////////////
// Win32 API
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
}
public const int SRCCOPY = 0x00CC0020; // BitBlt dwRop parameter
[DllImport("user32.dll")]
public static extern IntPtr GetWindowRect(IntPtr hWnd, ref RECT rect);
[DllImport("gdi32.dll")]
public static extern bool BitBlt(IntPtr hObject, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hObjectSource, int nXSrc, int nYSrc, int dwRop);
[DllImport("user32.dll")]
public static extern IntPtr GetWindowDC(IntPtr hWnd);
[DllImport("gdi32.dll")]
public static extern bool DeleteDC(IntPtr hDC);
[DllImport("gdi32.dll")]
public static extern bool DeleteObject(IntPtr hObject);
[DllImport("gdi32.dll")]
public static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject);
[DllImport("gdi32.dll")]
public static extern IntPtr CreateCompatibleBitmap(IntPtr hDC, int nWidth, int nHeight);
[DllImport("user32.dll")]
public static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDC);
[DllImport("gdi32.dll")]
public static extern IntPtr CreateCompatibleDC(IntPtr hDC);
}
}
so far it worked nicely, but when trying to take a screenshot of an Android emulator MEmu
the resulting picture looks like this
what can I not take a screenshot of the content by running 'ScreenCapture.CaptureWindow(h).Save(#"screenshot.bmp");' ? what way do I have to (quickly) get these pictures?
I'm trying to save screenshot of all the open windows on windows 7.
Issue is that instead of getting screenshot of open windows, it's giving me cmd.exe screenshot. (For example instead of taking google chrome screenshot it shows black cmd.exe screenshot).
I tried the same code on windows 10 before and it seemed to be working.
I have used following code from the http://www.developerfusion.com/code/4630/capture-a-screen-shot/ to get the screenshot of a particular window.
namespace ScreenShotDemo
{
/// <summary>
/// Provides functions to capture the entire screen, or a particular window, and save it to a file.
/// </summary>
public class ScreenCapture
{
/// <summary>
/// Creates an Image object containing a screen shot of the entire desktop
/// </summary>
/// <returns></returns>
public Image CaptureScreen()
{
return CaptureWindow(User32.GetDesktopWindow());
}
/// <summary>
/// Creates an Image object containing a screen shot of a specific window
/// </summary>
/// <param name="handle">The handle to the window. (In windows forms, this is obtained by the Handle property)</param>
/// <returns></returns>
public Image CaptureWindow(IntPtr handle)
{
// get te hDC of the target window
IntPtr hdcSrc = User32.GetWindowDC(handle);
// get the size
//User32.RECT windowRect = new User32.RECT();
//User32.GetWindowRect(handle, ref windowRect);
//int width = windowRect.right - windowRect.left;
//int height = windowRect.bottom - windowRect.top;
User32.WINDOWINFO info = new User32.WINDOWINFO();
User32.GetWindowInfo(handle, ref info);
int width = info.rcWindow.right - info.rcWindow.left;
int height = info.rcWindow.bottom - info.rcWindow.top;
// create a device context we can copy to
IntPtr hdcDest = GDI32.CreateCompatibleDC(hdcSrc);
// create a bitmap we can copy it to,
// using GetDeviceCaps to get the width/height
IntPtr hBitmap = GDI32.CreateCompatibleBitmap(hdcSrc, width, height);
// select the bitmap object
IntPtr hOld = GDI32.SelectObject(hdcDest, hBitmap);
// bitblt over
GDI32.BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, GDI32.SRCCOPY);
// restore selection
GDI32.SelectObject(hdcDest, hOld);
// clean up
GDI32.DeleteDC(hdcDest);
User32.ReleaseDC(handle, hdcSrc);
// get a .NET image object for it
Image img = Image.FromHbitmap(hBitmap);
// free up the Bitmap object
GDI32.DeleteObject(hBitmap);
return img;
}
/// <summary>
/// Captures a screen shot of a specific window, and saves it to a file
/// </summary>
/// <param name="handle"></param>
/// <param name="filename"></param>
/// <param name="format"></param>
public void CaptureWindowToFile(IntPtr handle, string filename, ImageFormat format)
{
Image img = CaptureWindow(handle);
img.Save(filename, format);
}
/// <summary>
/// Captures a screen shot of the entire desktop, and saves it to a file
/// </summary>
/// <param name="filename"></param>
/// <param name="format"></param>
public void CaptureScreenToFile(string filename, ImageFormat format)
{
Image img = CaptureScreen();
img.Save(filename, format);
}
/// <summary>
/// Helper class containing Gdi32 API functions
/// </summary>
private class GDI32
{
public const int SRCCOPY = 0x00CC0020; // BitBlt dwRop parameter
[DllImport("gdi32.dll")]
public static extern bool BitBlt(IntPtr hObject, int nXDest, int nYDest,
int nWidth, int nHeight, IntPtr hObjectSource,
int nXSrc, int nYSrc, int dwRop);
[DllImport("gdi32.dll")]
public static extern IntPtr CreateCompatibleBitmap(IntPtr hDC, int nWidth,
int nHeight);
[DllImport("gdi32.dll")]
public static extern IntPtr CreateCompatibleDC(IntPtr hDC);
[DllImport("gdi32.dll")]
public static extern bool DeleteDC(IntPtr hDC);
[DllImport("gdi32.dll")]
public static extern bool DeleteObject(IntPtr hObject);
[DllImport("gdi32.dll")]
public static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject);
}
/// <summary>
/// Helper class containing User32 API functions
/// </summary>
private class User32
{
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
}
[DllImport("user32.dll")]
public static extern IntPtr GetDesktopWindow();
[DllImport("user32.dll")]
public static extern IntPtr GetWindowDC(IntPtr hWnd);
[DllImport("user32.dll")]
public static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDC);
[DllImport("user32.dll")]
public static extern IntPtr GetWindowRect(IntPtr hWnd, ref RECT rect);
[DllImport("user32.dll")]
public static extern bool GetWindowInfo(IntPtr hwnd, ref WINDOWINFO pwi);
[StructLayout(LayoutKind.Sequential)]
public struct WINDOWINFO
{
public uint cbSize;
public RECT rcWindow;
public RECT rcClient;
public uint dwStyle;
public uint dwExStyle;
public uint dwWindowStatus;
public uint cxWindowBorders;
public uint cyWindowBorders;
public ushort atomWindowType;
public ushort wCreatorVersion;
public WINDOWINFO(Boolean? filler)
: this() // Allows automatic initialization of "cbSize" with "new WINDOWINFO(null/true/false)".
{
cbSize = (UInt32)(Marshal.SizeOf(typeof(WINDOWINFO)));
}
}
}
}
}
To get the list of open windows I'm using following code.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using HWND = System.IntPtr;
/// <summary>Contains functionality to get all the open windows.</summary>
public static class OpenWindowGetter
{
/// <summary>Returns a dictionary that contains the handle and title of all the open windows.</summary>
/// <returns>A dictionary that contains the handle and title of all the open windows.</returns>
public static IDictionary<HWND, string> GetOpenWindows()
{
HWND shellWindow = GetShellWindow();
Dictionary<HWND, string> windows = new Dictionary<HWND, string>();
EnumWindows(delegate (HWND hWnd, int lParam)
{
if (hWnd == shellWindow) return true;
if (!IsWindowVisible(hWnd)) return true;
int length = GetWindowTextLength(hWnd);
if (length == 0) return true;
StringBuilder builder = new StringBuilder(length);
GetWindowText(hWnd, builder, length + 1);
windows[hWnd] = builder.ToString();
return true;
}, 0);
return windows;
}
private delegate bool EnumWindowsProc(HWND hWnd, int lParam);
[DllImport("USER32.DLL")]
private static extern bool EnumWindows(EnumWindowsProc enumFunc, int lParam);
[DllImport("USER32.DLL")]
private static extern int GetWindowText(HWND hWnd, StringBuilder lpString, int nMaxCount);
[DllImport("USER32.DLL")]
private static extern int GetWindowTextLength(HWND hWnd);
[DllImport("USER32.DLL")]
private static extern bool IsWindowVisible(HWND hWnd);
[DllImport("USER32.DLL")]
private static extern IntPtr GetShellWindow();
}
Following is the Main class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ScreenShotDemo;
using System.Drawing.Imaging;
namespace ScreenCaptureTest
{
class Program
{
static void Main(string[] args)
{
long start = DateTime.Now.Millisecond;
captureAllWindowsToFile();
//captureAllWindowsToFile2();
//captureDesktopToFile();
long end = DateTime.Now.Millisecond;
Console.WriteLine("time taken: " + (end - start));
//Console.Read();
}
static void captureAllWindowsToFile()
{
IDictionary<IntPtr, string> windowDict = OpenWindowGetter.GetOpenWindows();
ScreenCapture sc = new ScreenCapture();
int captureI = 0;
string message = "";
foreach(KeyValuePair<IntPtr, string> window in windowDict)
{
string imageName = "test" + ++captureI + ".jpg";
message +=imageName + " : " + window.Value + "\n";
sc.CaptureWindowToFile(window.Key, imageName, ImageFormat.Jpeg);
}
Console.WriteLine(message);
}
static void captureDesktopToFile()
{
ScreenCapture sc = new ScreenCapture();
sc.CaptureScreenToFile("current.jpg", ImageFormat.Jpeg);
}
}
}
Any help is appreciated.
I finally found the issue.
I had changed windows 7 settings for best performance, once I changed it to normal Aero settings. It works as expected.
I am trying to change the cursor of my control on certain conditions. I have created my own custom cursor and assigned it to the Cursor.Current property. Everything working fine up-to this.
When I check whether the current control cursor and the new cursor is same or not based on their names by converting cursor using ToString() method, I get:
Custom Cursor cannot be converted to String
There is no problem in converting the System's default cursor and it raise only when converting custom cursor. Any one please tell me why this exception raised only on custom cursor?
this is the place where i got the error...
**if (m_cursorAction.ToString() != newCursor.ToString())
m_cursorAction = newCursor;**
Here is my cursor implementation code:
Bitmap bitmap = new Bitmap(140, 25);
Graphics g = Graphics.FromImage(bitmap);
using (Font f = new Font("SEGOE UI", 10))
g.DrawString("Node 30", f, System.Drawing.Brushes.Black, 0, 0);
Cursor.Current = MyCursor.CreateCursor(bitmap, 140, 25);
**if (m_cursorAction.ToString() != newCursor.ToString())**
m_cursorAction = newCursor;
public class MyCursor
{
#region Class members
private static IntPtr ptr;
public struct IconInfo
{
public bool bIcon;
public int xHotspot;
public int yHotspot;
public IntPtr hbmMask;
public IntPtr hbmColor;
}
#endregion
#region Class Public Methods
[System.Runtime.InteropServices.DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
public static extern bool DestroyIcon(IntPtr handle);
[System.Runtime.InteropServices.DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
[return: System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.Bool)]
public static extern bool GetIconInfo(IntPtr hIcon, ref IconInfo pIconInfo);
[System.Runtime.InteropServices.DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
public static extern IntPtr CreateIconIndirect([System.Runtime.InteropServices.In]ref IconInfo icon);
[System.Runtime.InteropServices.DllImport("gdi32")]
extern internal static bool DeleteObject(IntPtr hObject);
/// <summary>
/// Create a custom cursor with the given bitmap
/// </summary>
/// <param name="bmp">Bitmap for the cursor.</param>
/// <param name="xHotSpot">x hot spot to the cursor.</param>
/// <param name="yHotSpot">y hot spot to the cursor.</param>
public static System.Windows.Forms.Cursor CreateCursor(System.Drawing.Bitmap bmp, int xHotSpot, int yHotSpot)
{
IntPtr bmpPtr= bmp.GetHicon();
IconInfo icon = new IconInfo();
GetIconInfo(bmpPtr, ref icon);
icon.xHotspot = xHotSpot;
icon.yHotspot = yHotSpot;
icon.bIcon = false;
DestroyIcon(bmpPtr);
DeleteObject(bmpPtr);
ptr = CreateIconIndirect(ref icon);
System.Windows.Forms.Cursor cursor = new System.Windows.Forms.Cursor(ptr);
//delete the GDI objects and icon
DeleteObject(icon.hbmColor);
DeleteObject(icon.hbmMask);
DestroyIcon(icon.hbmColor);
DestroyIcon(icon.hbmMask);
return cursor;
}
/// <summary>
/// Destroy the custom cursor
/// </summary>
public static void Destroy()
{
DestroyIcon(ptr);
DeleteObject(ptr);
}
#endregion
}
Because it delegates to CursorConverter.ConvertTo, which is designed to throw that exception only for custom cursors.
Just don't use string comparison to test whether cursors are equal. Instead, use the Cursor.Equals method which is designed for comparing cursors.
One way, for custom Cursors, if you know what you're looking for, is to check the Handle:
// 65569 = Hand Pointer:
int handle = 65569;
if (handle == System.Windows.Forms.Cursor.Current.Handle.ToInt32())
MessageBox.Show("Hand Pointer Cursor");