CaptureItPlus – A screen capture utility
Few days back I started working on another open source project, for capturing screen shots. It is similar or can be used as an alternative to Snipping Tool in Windows Vista / 7.
Here is the main features of CaptureItPlus
- Supports all major screen capture modes. Fullscreen, Window, Rectangle, FreeForm and Scheduled capture.
- Supports various output formats, JPG, PNG, GIF, BMP, WMF, and TIFF. Default format in PNG, but users can customize it using settings.
- Supports keyboard shortcuts(customization also) for capture modes
- Sound notification after capture.
- Supports capture screen with cursor.
- Written in Microsoft .Net 2.0; supports major operating systems.
- API support.
- Easy to install, no admin rights required.
- Support for executing plugins after screen capture.
- Licensed under GNU GPL v2.0. Full source code available(C# 2.0)
You can download latest version of CaptureItPlus from CodePlex.
Please try it and let me know your comments.
Image cropping control in C# for Windows Forms
This post is also inspired by a SO post – Image Cropping Control for WinForms with Selection Rectangle. I had done a similar implementation using VB.Net long back but I couldn’t remember the implementation.
Today I tried it again and here is an implementation, which helps to crop an Image using selection rectangle.
namespace dotnetthoughts
{
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
public class CustomPictureBox : PictureBox
{
private Rectangle _rectangle;
private Point _startingPoint;
private Point _finishingPoint;
private bool _isDrawing;
public CustomPictureBox()
{
Cursor = Cursors.Cross;
_startingPoint = new Point();
_finishingPoint = new Point();
}
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
if (e.Button == MouseButtons.Left)
{
_isDrawing = true;
_startingPoint = new Point(e.X, e.Y);
}
Invalidate();
}
protected override void OnMouseUp(MouseEventArgs e)
{
base.OnMouseUp(e);
if (e.Button == MouseButtons.Left && _isDrawing)
{
_finishingPoint = new Point(e.X, e.Y);
if (e.X > _startingPoint.X)
{
_rectangle = new Rectangle(
_startingPoint.X <= e.X ? _startingPoint.X : e.X,
_startingPoint.Y <= e.Y ? _startingPoint.Y : e.Y,
e.X - _startingPoint.X <= 0 ? _startingPoint.X - e.X : e.X - _startingPoint.X,
e.Y - _startingPoint.Y <= 0 ? _startingPoint.Y - e.Y : e.Y - _startingPoint.Y);
}
else
{
_rectangle = new Rectangle(
e.X <= _startingPoint.X ? e.X : _startingPoint.X,
e.Y <= _startingPoint.Y ? e.Y : _startingPoint.Y,
_startingPoint.X - e.X <= 0 ? _startingPoint.X - e.X : _startingPoint.X - e.X,
_startingPoint.Y - e.Y <= 0 ? e.Y - _startingPoint.Y : _startingPoint.Y - e.Y);
}
}
_isDrawing = false;
Invalidate();
}
protected override void OnPaint(PaintEventArgs pe)
{
base.OnPaint(pe);
using (Pen pen = new Pen(Color.Red, 2))
{
pen.DashStyle = DashStyle.Dash;
pe.Graphics.DrawRectangle(pen, _rectangle);
}
}
public void CropImage()
{
Bitmap bitmap = new Bitmap(_rectangle.Width, _rectangle.Height);
using (Graphics graphics = Graphics.FromImage(bitmap))
{
graphics.DrawImage(this.Image, 0, 0, _rectangle, GraphicsUnit.Pixel);
}
Image = bitmap;
//Removing the rectangle after cropping.
_rectangle = new Rectangle(0, 0, 0, 0);
}
}
}
We can modify this control by adding nice to have features like
- Overlay while cropping.
- Drag and Re-size the selection Rectangle.
Happy Coding
Fluent email library for c# using DynamicObject
Today I saw a StackOverflow question (Is there a fluent email library for c#?). And it has got few answers, so I thought of implementing a fluent email library for c# using DynamicObject;and here is a sample implementation.
public class FluentEmailLibrary : DynamicObject
{
private MailMessage _mailMessage = new MailMessage();
public override bool TryInvokeMember
(InvokeMemberBinder binder, object[] args, out object result)
{
switch (binder.Name)
{
case "To":
_mailMessage.To.Add(string.Join(",", args));
break;
case "From":
_mailMessage.From =
new MailAddress(args[0].ToString());
break;
case "Subject":
_mailMessage.Subject = args[0].ToString();
break;
case "Body":
_mailMessage.Body = args[0].ToString();
break;
case "IsBodyHtml":
_mailMessage.IsBodyHtml = Convert.ToBoolean(args[0]);
break;
case "Send":
SmtpClient smtpClient = new SmtpClient();
smtpClient.Send(_mailMessage);
break;
default:
result = null;
return false;
break;
}
result = this;
return true;
}
}
And here is the usage.
class Program
{
static void Main(string[] args)
{
dynamic fluentEmailLibrary = new FluentEmailLibrary();
fluentEmailLibrary.To("touser@server.com")
.From("fromuser@server.com")
.Subject("HelloWorld")
.Body("Mail Sample").IsBodyHtml("true").Send();
}
}
We can improve it by using Reflection instead of hard coding the variables.
How to use TaskDialog API in C#
The TaskDialog API replaces MessageBox. A message box is useful for prompting users for an acknowledgment, confirmation, or an answer to a yes or no question. Message boxes are popular because of the MessageBox function is convenient for developers to use. TaskDialog is the preferred API to use because it is similar to MessageBox but much more flexible. Previously, developers have created their own message box implementations when greater functionality was required. Unfortunately .Net framework doesn’t expose TaskDialog API directly; you need to use WIN32 api for it. Here is one Task dialog implementation in C#. Only limitation of Task Dialog API is it doesn’t supported by Windows operating systems less than Windows Vista.
Here is the API declarations.
[DllImport("comctl32.dll", CharSet = CharSet.Unicode, EntryPoint = "TaskDialog")]
static extern int TaskDialog(IntPtr hWndParent, IntPtr hInstance, String pszWindowTitle,
String pszMainInstruction, String pszContent, int dwCommonButtons,
IntPtr pszIcon, out TaskDialogResult pnButton);
//Dialog buttons
[Flags]
public enum TaskDialogButtons : int
{
Ok = 0x0001,
Cancel = 0x0008,
Yes = 0x0002,
No = 0x0004,
Retry = 0x0010,
Close = 0x0020
}
//Dialog Results
[Flags]
public enum TaskDialogResult : int
{
IDOK = 1,
IDCANCEL = 2,
IDRETRY = 4,
IDYES = 6,
IDNO = 7,
IDCLOSE = 8,
NONE = 0
}
//Dialog Icons
[Flags]
public enum TaskDialogIcon
{
Information = UInt16.MaxValue - 2,
Warning = UInt16.MaxValue,
Stop = UInt16.MaxValue - 1,
Question = 0,
SecurityWarning = UInt16.MaxValue - 5,
SecurityError = UInt16.MaxValue - 6,
SecuritySuccess = UInt16.MaxValue - 7,
SecurityShield = UInt16.MaxValue - 3,
SecurityShieldBlue = UInt16.MaxValue - 4,
SecurityShieldGray = UInt16.MaxValue - 8
}
And here is my TaskDialog wrapper function.
public static TaskDialogResult Show(IntPtr handle, string messageTitle, string mainTitle,
string mainContent, TaskDialogButtons taskDialogButtons, TaskDialogIcon taskDialogIcon)
{
TaskDialogResult buttonClicked = TaskDialogResult.IDCANCEL;
TaskDialog(handle, IntPtr.Zero, messageTitle, mainTitle, mainContent,
(int)taskDialogButtons, (IntPtr)(int)taskDialogIcon, out buttonClicked);
return buttonClicked;
}
And here is the screen shot of Task Dialog running in my Windows 7 machine.
WCF Callbacks – A quick introduction
WCF callbacks are an old topic, but recently I got a chance to play around it. WCF callback means instead of normal request – response pattern, it will be a bidirectional communication between client and server.
First need to create the service interface
[ServiceContract(CallbackContract = typeof(IServiceCallback),
Namespace = "http://dotnetthoughts.net/wcf")]
interface IService
{
[OperationContract(IsOneWay = true)]
void SayHello(string name);
}
If you notice the Service contract attribute, there is parameter, Callback contract, which is required to map the service call with the callback method. And here is the callback contract interface.
interface IServiceCallback
{
[OperationContract(IsOneWay = true)]
void Print(string message);
}
And here is the implementation of the service and callback interface.
class Service : IService
{
public void SayHello(string name)
{
IServiceCallback callback =
OperationContext.Current.GetCallbackChannel<IServiceCallback>();
string message = string.Format("Hello {0}", name);
callback.Print(message);
}
}
class ServiceCallback : IServiceCallback
{
public void Print(string message)
{
Console.WriteLine(message);
}
}
I am using Self Hosting mode to host the service. And here is the implementation.
class Program
{
static void Main(string[] args)
{
string baseAddress = "net.tcp://localhost:8080/";
Uri[] addresses = { new Uri(baseAddress) };
using (var serviceHost = new ServiceHost(typeof(Service), addresses))
{
serviceHost.AddServiceEndpoint(typeof(IService),
new NetTcpBinding(), "IService");
serviceHost.Open();
Console.WriteLine("Service started.");
Console.WriteLine("Press any key to stop.");
Console.ReadKey(true);
serviceHost.Close();
}
}
}
Now we need to create proxy to communicate to our service. Here is the proxy implementation.
class ServiceProxy : DuplexClientBase<IService>, IService
{
public ServiceProxy(object callbackInstance,
Binding binding, EndpointAddress remoteAddress)
: base(callbackInstance, binding, remoteAddress)
{
}
public void SayHello(string name)
{
Channel.SayHello(name);
}
}
And finally here is the client implementation, in the client class; I am implementing the callback interface, so that I can get the callback result in the client.
class Client : IServiceCallback
{
public void SayHelloToService(string name)
{
var proxy =
new ServiceProxy(this, new NetTcpBinding(),
new EndpointAddress("net.tcp://localhost:8080/IService"));
proxy.SayHello(name);
}
public void Print(string message)
{
Console.WriteLine(message);
}
}
Now start the Service first then create the instance of client class and invoke SayHelloToService with name parameter and it will be printed in the console. And here is the Test for the same.
[TestClass]
public class TestService : IServiceCallback
{
private string actual = string.Empty;
private AutoResetEvent autoResetEvent = null;
[TestMethod]
public void TestSayHello()
{
string expected = "Hello dotnetthoughts";
autoResetEvent = new AutoResetEvent(false);
var proxy =
new ServiceProxy(this, new NetTcpBinding(),
new EndpointAddress("net.tcp://localhost:8080/IService"));
proxy.SayHello("dotnetthoughts");
Assert.IsTrue(autoResetEvent.WaitOne(5000), @"Callback not recevied.");
Assert.IsTrue(expected == actual, @"Invalid response from callback.");
}
public void Print(string message)
{
actual = message;
autoResetEvent.Set();
}
}
Happy Coding

