May 28, 2010

Send An Email Using Outlook

See KB Article 310263
Add a reference to Microsoft.Office.Interop.Outlook then use following code:
using Outlook = Microsoft.Office.Interop.Outlook;

public void SendPlainFormatEmail(
  string recipient, 
  string subject, 
  string body, 
  string filePath, 
  bool silently)
{
    try
    {
        //Check file exists before the method is called
        FileInfo fi = new FileInfo(filePath);

        bool exists = fi.Exists;
        if (!exists)
            return;

        string fileName = fi.Name;

        // Create the Outlook application by using inline initialization.
        Outlook.Application outlookApp = new Outlook.Application();

        //Create the new message by using the simplest approach.
        Outlook.MailItem msg = (Outlook.MailItem)outlookApp.CreateItem(
          Outlook.OlItemType.olMailItem);

        Outlook.Recipient outlookRecip = null;
        //Add a recipient.
        if (!string.IsNullOrEmpty(recipient))
        {
          outlookRecip = (Outlook.Recipient)msg.Recipients.Add(recipient);
          outlookRecip.Resolve();
        }

        //Set the basic properties.
        msg.Subject = subject;
        msg.Body = body;
        msg.BodyFormat = Microsoft.Office.Interop.Outlook.
             OlBodyFormat.olFormatPlain;

        //Add an attachment.
        long sizeKB = fi.Length / 1024;
        string sDisplayName = fileName + "(" + 
                     sizeKB.ToString() + " KB)";
        int position = (int)msg.Body.Length + 1;
        int iAttachType = (int)Outlook.OlAttachmentType.olByValue;
        Outlook.Attachment attachment = msg.Attachments.Add(
          filePath, iAttachType, position, sDisplayName);

        //msg.Save();
        if (silently)
        {
            //Send the message.
            msg.Send();
        }
        else
        {
            msg.Display(true);  //modal
        }

        //Explicitly release objects.
        outlookRecip = null;
        attachment = null;
        msg = null;
        outlookApp = null;
    }

    // Simple error handler.
    catch (Exception e)
    {
        Console.WriteLine("{0} Exception caught: ", e);
    }
}
Following code uses the above method to email a file:
public void EmailFile(string recipient, string filePath)
{
    FileInfo fi = new FileInfo(filePath);
    bool exists = fi.Exists;
    if (!exists)
        return;

    string fileName = fi.Name;
    string subject = "Emailing: " + fileName;
    string body = "Your message is ready to be sent with the following "
           "file or link attachments:" + Environment.NewLine +
           Environment.NewLine +
           fileName + Environment.NewLine +
           Environment.NewLine +
           "Note: To protect against computer viruses, e-mail programs"
           " may prevent sending or receiving certain types of file "
           "attachments.  Check your e-mail security settings to determine"
           " how attachments are handled."; ;
    SendPlainFormatEmail(recipient, subject, body, filePath, false);
}

May 27, 2010

WPF MessageBox Dialog Examples

Copy and paste type samples
using System.Windows;
Suprise type dialog:
MessageBox.Show(this,
 "Specified root directory \'" + rootDir + "\'does not exist",
 "Find files",
 MessageBoxButton.OK,
 MessageBoxImage.Exclamation);
Question type dialog:
MessageBox.Show(this,
 "Are you sure you want to delete these files" + Environment.NewLine +
 fileListStr,
 "Delete selected files",
 MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes) 

May 26, 2010

Beware of using anonymous delegates for event handlers

First found a description of this issue here
There is a problem unsubscribing to an event
Check out the following code:
EventHandler onXXX =
 delegate(object sender, XXXEventArgs e)
 {
  onXXXCallCount++;
  xxxs.Add(e.LastXXX);
 };
... 
m_YYY.OnXXX += onXXX;
...
// The anonymous event handler stays on the event handler until removed
// or the parent object is disposed of!
m_YYY.OnXXX -= onXXX;

May 20, 2010

Open Explorer At Some Directory in C#

Use the following code snippet:
// Open explorer in user temporary directory
OpenExplorerInDir(System.IO.Path.GetTempPath());
...
private void OpenExplorerInDir(string dir)
{
  string exe = "explorer.exe";

  //Driectory.Exists
  Process exeProcess = new Process();
  exeProcess.StartInfo.FileName = exe;
  exeProcess.StartInfo.Arguments = "/e,/root," + dir;
  exeProcess.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
  exeProcess.Start();
}

C++ Pattern: Use pointer behind a reference

The advantage is in the header file the member variable is forward declared so the user of the class only needs the header file in their class source file (and not in their header) In header file declare the reference object:
...
namespace aaaa { namespace bbbb {
  class xxxx;
}}
...
  /// Reference member variable.
 aaaa::bbbb::xxxx& memberVar;
In source file assign reference using *new()
SomeClass::SomeClass(const SomeClass &time)
    // Here is the trick, new() and dereference (*) 
    // immediately into a reference object
  : memberVar(*new xxxx(time.memberVar)) {
}

SomeClass::~SomeClass() {
  delete &memberVar;
}

Null Pointers and Delete in C++

From here: Null Pointers and Delete C++ guarantees that delete operator checks its argument for null-ness. If the argument is 0, the delete expression has no effect. In other words, deleting a null pointer is a safe (yet useless) operation.
 
if (ptr == NULL) // useless, delete already checks for null value
{
  delete(ptr);
}
// but always set ptr = NULL after deleting it otherwise another 
// call to delete(ptr) will throw an exception
ptr = NULL; 

C++ Virtual Destructor

Look at this Why are destructors not virtual by default? Basic rule is if a class has at least one virtual function, it should have a virtual destructor
Example:
class Base 
{
...
  virtual ~Base();
...
};

class Derived : public Base 
{
 ...
  ~Derived();
};

C++ auto_ptr and shared_ptr

std::auto_ptr

Good article on why and how to use it Another good article on when and how to use it
{
  auto_ptr<T> ptr( new T );
  ...
} // when ptr goes out of scope it deletes the underlying object!
  • auto_ptr employs the "exclusive ownership" model. This means that you can't bind more than one auto_ptr object to the same resource.
  • Be careful when passing as a parameter to a method by value because on returning the pointer will point to nothing. The copy in the method will destroy the pointer when the method ends, so pass it by reference.
  • Also because of this do not use it with template libraries!

std::tr1::shared_ptr

  • Unlike auto_ptr, shared_ptr uses reference counting so multiple "shared_ptr"s can point to the same resource.
  • Destructor decrement the reference count. When it reaches zero the resource is "delete"d.
  • Can have a user defined deleter, so shared_ptr need not necessarily hold a "pointer to something" type resource, it could be a file handle, etc. Define a "delete" function to delete the custom resource
  • Be careful of cyclic references, the objects will not be able to delete one another

May 14, 2010

Example Using std::map<> In C++

See Wikipedia reference
std::map<XXX*, DataAveragerPtr> averagerCache;
const XXX* xxx = ...

DataAveragerPtr averager;
if(averagerCache.find(xxx) == averagerCache.end())
{ // Not found so create a new one
  averager.reset(new SomeDataAverager(...));     
  averager->DoSomethingExpensive();
  averagerCache.insert (std::pair<XXX*, DataAveragerPtr>(
  xxx, averager));
}
else // found it
{
  // for parametric types <A, B> use an A to get a B,
  // B b = mymap[a]; where a is of type A
  averager = averagerCache[xxx]; // lookup
}
...
if (!averagerCache.empty())
averagerCache.clear();
When passing it as a parameter, the best option is to pass it by reference and just create it on the stack.

Events In C#

Look here: How to: Implement Events in Your Class - A good beginners guide.
and here: C# events vs. delegates - Good detailed explanation of events and how they differ from delegates

Implementing the event in Your Publisher Class

Step 1 (Optional): Define your custom "EventArgs" class
public class SomethingChangedEventArgs : EventArgs
{
...
}
The following steps take place in the event publisher class
class SomethingChangedEventPublisher
{
Step 2: Expose your custom EventHandler
  public event EventHandler<SomethingChangedEventArgs> SomethingChanged; // for events with custom arguments
  public event EventHandler SomethingChanged; // otherwise use this for standard events
Step 3: Define an event publishing helper method (this is agood practice)
  void PublishSomethingChangedEvent(SomethingChangedEventArgs ea)
  {
    EventHandler<SomethingChangedEventArgs> eh = this.SomethingChanged
    if (eh != null)
      eh(this, ea);
  }
Step 4: Publish/Fire/Trigger the event in the appropriate places
  ...
  PublishSomethingChangedEvent(this, new SomethingChangedEventArgs(...));
  
  ...
}

Subscribing to the event in the Listener/Observer/Subscriber Class

The following steps take place in the event observer/subscriber class
class SomethingChangedEventSubscriber
{
Step 5: Subscribe to the event
  // VS Intellisense will do most of the work for you here!
  SomethingChangedEventSource.SomethingChanged += new EventHandler<SomethingChangedEventArgs>(OnSomethingChanged);
...
Step 6: Handle the event
  // The method where the SomethingChangedEvent is processed 
  private void OnSomethingChanged(object sender, SomethingChangedEventArgs eargs)
  {
    // SomethingChanged detected, now do something with it here
  }
...
Step 7: Unsubscribe to the event. This is in my experience the biggest cause of memory leaks in C# programs
  // VS Intellisense will do most of the work for you here!
  SomethingChangedEventSource.SomethingChanged -= new EventHandler<SomethingChangedEventArgs>(OnSomethingChanged);
  
...
}
Alternatively, use an inline delegate to handle the event
SomethingChangedEventSource.SomethingChanged += delegate (object sender, SomethingChangedEventArgs e)
{
  ...
};
But there is a danger to doing this see here
Also in Windows Forms programs events often lead to memory leaks as the events were never detached seehere
Note that the event source is called the "Event Publisher", ie. it is the class containg the event definition. The event target or "Subscriber" is the object attaching a delegate to the event. Be careful with C# events and the Garbage Collection of unreferenced objects. A C# event publisher holds a reference to the subscriber so the Subscriber cannot be disposed of until that event is detached (or there is no longer a reference to either the publisher or subscriber). This also means that if the subscriber has a Dispose event, you cannot rely on the system to invoke it in a GC round until that event is detached. If you attach a subscriber on to the event of a publisher, ensure it is detached

May 12, 2010

Creating A Single Instance WPF Application

Look here: Initial idea. - Did not seem to work!
How can I provide my own Main() method in my WPF application?
and here

Simplest solution found:
  1. On App.xaml build properties, set "Build Action" to Page.
  2. Add following code to "App.xml.cs" or equivalent, the "App" class source.
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows;

...

[DllImport("user32.dll")]
public static extern bool SetForegroundWindow(IntPtr hWnd);

/// <summary>
/// Application Entry Point.
/// </summary>
[System.STAThreadAttribute()]
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
public static void Main()
{
  // Use mutex to ensure only single instance is running
  bool mutexOwnershipGranted = true;
  using (Mutex mutex = new Mutex(
    true, 
    "$SOMEUNIQUESTRING$", // Use GUID or string id here
    out mutexOwnershipGranted))
  {
    // If this is the only running instance
    if (mutexOwnershipGranted) 
    { // Then run app 
      DevHelperWpf.App app = new DevHelperWpf.App();
      app.InitializeComponent();
      app.Run();
    }
    else 
    { // Bring current running instance to the front
      Process current = Process.GetCurrentProcess();
      foreach (Process process in Process.GetProcessesByName(
          current.ProcessName))
      {
         if (process.Id != current.Id)
         {
            SetForegroundWindow(process.MainWindowHandle);
            break;
         }
      }
    }
  }
}