Jesper Niedermann's .NET Blog
about .NET and related technologies RSS 2.0
# Friday, 13 November 2009

In the Day View project I needed to open a Windows 7 Sticky Note programmatically and write to it. Unfortunately I found out that there is not an API for the Sticky Notes application. At least not a managed one.

So I had to fake it and make my own API. I have made a small class that basicly uses Process.Start to open the program, and SendKeys to write to the Note.

Here it is:

using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;

namespace DayView
{
public class StickyNote
{
private const string m_ProcessName = "StikyNot";
private readonly string m_ProcessFileName = Path.Combine(Environment.SystemDirectory, "StikyNot.exe");
private event EventHandler m_Activated = delegate { };
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SetForegroundWindow(IntPtr hWnd);

public void Activate()
{
bool makeNewNote = true;
Process p = FindProcess();
if (p == null)
{
p = StartProcess();
if (!NoteContainsText(p.MainWindowHandle))
{
makeNewNote = false;
}
}
var state = new StickyNoteState();
state.MakeNewNote = makeNewNote;
state.StickyNoteProcess = p;
ThreadPool.QueueUserWorkItem(Activate, state);
}

private void Activate(object state)
{
var stickyNoteState = state as StickyNoteState;
if (stickyNoteState.MakeNewNote)
{
NewNote(stickyNoteState.StickyNoteProcess);
}
OnActivated();
}

private Process StartProcess()
{
var startInfo = new ProcessStartInfo(m_ProcessFileName);
Process p = Process.Start(startInfo);
Thread.Sleep(200); //This is an annoying hack. I haven't been able to find another way to be sure the process is started.
return p;
}

private void NewNote(Process p)
{
SetForegroundWindow(p.MainWindowHandle);
Signal("^n");
}

/// <summary>
/// Weird hack to find out if note contains text.
/// </summary>
/// <returns></returns>
private bool NoteContainsText(IntPtr handle)
{
string textOfClipboard = Clipboard.GetText();
Signal("^a");
Signal("^c");
Signal("{RIGHT}");
string noteText = Clipboard.GetText().Trim();
if (textOfClipboard == null)
{
Clipboard.SetText(textOfClipboard);
}
return !string.IsNullOrEmpty(noteText);
}

private Process FindProcess()
{
Process[] processes = Process.GetProcessesByName(m_ProcessName);
if(processes != null && processes.Length > 0)
{
return processes[0];
}
return null;
}

internal void OnActivated()
{
m_Activated(this, new EventArgs());
}

public event EventHandler Activated
{
add { m_Activated += value; }
remove { m_Activated -= value; }
}

public void Signal(string message)
{
SendKeys.SendWait(message);
SendKeys.Flush();
}
}

public class StickyNoteState
{
public bool MakeNewNote { get; set; }
public Process StickyNoteProcess { get; set; }

}
}

It works OK. The only really buggy thing in the code is in line 47, where I have to use a Thread.Sleep in order to make sure the note is loaded before I write to it. Unfortunately this is necessary because the Process class does not provide an event to signal when it has finished loading. I arbitrarily chose 200 milliseconds for the Sleep. Larger values might be necessary on slower computers.

In order to use the class you have to configure SendKeys in your app.config like this:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="SendKeys" value="SendInput"/>
</appSettings>
</configuration>
Friday, 13 November 2009 23:28:10 (GMT Standard Time, UTC+00:00)  #    Comments [4] -
.NET | Tips & Tricks | Windows 7
Archive
<2017 December>
SunMonTueWedThuFriSat
262728293012
3456789
10111213141516
17181920212223
24252627282930
31123456
About the author/Disclaimer
I am a software architect with focus on Microsoft Technologies. I have been working with these in different large companies since 1995. I am currently employed at UVdata A/S.
Here is my View Jesper Niedermann's profile on LinkedIn

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

Privacy policy
The privacy policy of this site.

© Copyright 2017
Jesper Niedermann
Sign In
Statistics
Total Posts: 28
This Year: 0
This Month: 0
This Week: 0
Comments: 32
All Content © 2017, Jesper Niedermann
DasBlog theme 'Niedermann' created by Jesper Niedermann, based on 'Business' created by Christoph De Baene (delarou)