This commit is contained in:
shanselman 2008-06-02 18:49:35 +00:00
Коммит da282ff33c
13 изменённых файлов: 1368 добавлений и 0 удалений

Двоичные данные
App.ico Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.2 KiB

8
App.xaml Normal file
Просмотреть файл

@ -0,0 +1,8 @@
<Application x:Class="BabySmash.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Startup="Application_Startup"
>
<Application.Resources>
</Application.Resources>
</Application>

96
App.xaml.cs Normal file
Просмотреть файл

@ -0,0 +1,96 @@
using System.Windows;
using System;
using System.Runtime.InteropServices;
using System.Diagnostics;
using WinForms = System.Windows.Forms;
namespace BabySmash
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
private static IntPtr _hookID = IntPtr.Zero;
static InterceptKeys.LowLevelKeyboardProc _proc = HookCallback;
Window1 mainWindow = null;
public App()
: base()
{
_hookID = InterceptKeys.SetHook(_proc);
try
{
this.ShutdownMode = ShutdownMode.OnLastWindowClose; //TODO: Should this be OnMainWindowClose?
mainWindow = new Window1();
MainWindow.WindowState = WindowState.Maximized; //Do it here, rather than in XAML otherwise multimon won't work.
mainWindow.Show();
}
catch (Exception e)
{
//TODO: Logging?
InterceptKeys.UnhookWindowsHookEx(_hookID);
}
}
public static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode >= 0)
{
//Prevent ALT-TAB and CTRL-ESC by eating TAB and ESC. Also kill Windows Keys.
int vkCode = Marshal.ReadInt32(lParam);
if ((WinForms.Keys)vkCode == WinForms.Keys.LWin ||
(WinForms.Keys)vkCode == WinForms.Keys.RWin)
{
//Debug.WriteLine("ATE: " + (WinForms.Keys)vkCode);
return (IntPtr)1; //handled
}
bool Alt = (System.Windows.Forms.Control.ModifierKeys & WinForms.Keys.Alt) != 0;
bool Control = (System.Windows.Forms.Control.ModifierKeys & WinForms.Keys.Control) != 0;
if (Alt && (WinForms.Keys)vkCode == WinForms.Keys.Tab)
{
//Debug.WriteLine("ATE ALT-TAB: " + (WinForms.Keys)vkCode);
return (IntPtr)1; //handled
}
if (Control && (WinForms.Keys)vkCode == WinForms.Keys.Escape)
{
//Debug.WriteLine("ATE CTRL-ESC: " + (WinForms.Keys)vkCode);
return (IntPtr)1; //handled
}
//Debug.WriteLine("HOOKED: " + (WinForms.Keys)vkCode);
}
return InterceptKeys.CallNextHookEx(_hookID, nCode, wParam, lParam);
}
private void Application_Startup(object sender, StartupEventArgs e)
{
//UNDONE: Make a Window instance for each screen, position them, show them, then maximize them.
//TODO: Now, how to respond to events on all screens at once?
foreach (WinForms.Screen s in WinForms.Screen.AllScreens)
{
if (s.Primary == false)
{
Window1 w = new Window1();
w.WindowStartupLocation = WindowStartupLocation.Manual; //key!
Debug.Write("Found screen: " + s.DeviceName);
w.Left = s.WorkingArea.Left;
Debug.Write(" Left: " + s.WorkingArea.Left);
w.Top = s.WorkingArea.Top;
Debug.Write(" Top: " + s.WorkingArea.Top);
w.Width = s.WorkingArea.Width;
Debug.Write(" Width: " + s.WorkingArea.Width);
w.Height = s.WorkingArea.Height;
Debug.Write("Height: " + s.WorkingArea.Height);
w.WindowStyle = WindowStyle.None;
w.Topmost = true;
w.Owner = mainWindow;
w.Show();
w.WindowState = WindowState.Maximized;
}
mainWindow.Focus();
};
}
}
}

68
Audio.cs Normal file
Просмотреть файл

@ -0,0 +1,68 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.IO;
using System.Reflection;
using System.Collections;
namespace BabySmash
{
public class Winmm
{
public const UInt32 SND_ASYNC = 1;
public const UInt32 SND_MEMORY = 4;
// these 2 overloads we dont need ...
// [DllImport("Winmm.dll")]
// public static extern bool PlaySound(IntPtr rsc, IntPtr hMod, UInt32 dwFlags);
// [DllImport("Winmm.dll")]
// public static extern bool PlaySound(string Sound, IntPtr hMod, UInt32 dwFlags);
// this is the overload we want to play embedded resource...
[DllImport("Winmm.dll")]
public static extern bool PlaySound(byte[] data, IntPtr hMod, UInt32 dwFlags);
public Winmm()
{
}
public static Dictionary<string, byte[]> cachedWavs = new Dictionary<string, byte[]>();
public static object cachedWavsLock = new object();
public static void PlayWavResource(string wav)
{
byte[] b = GetWavResource(wav);
PlaySound(b, IntPtr.Zero, SND_ASYNC | SND_MEMORY);
}
private static byte[] GetWavResource(string wav)
{
//UNDONE: Is this valid caching?
byte[] b = null;
if(cachedWavs.ContainsKey(wav))
b = cachedWavs[wav];
if (b == null)
{
lock (cachedWavsLock)
{
// get the namespace
string strNameSpace = Assembly.GetExecutingAssembly().GetName().Name.ToString();
// get the resource into a stream
using (Stream str = Assembly.GetExecutingAssembly().GetManifestResourceStream(strNameSpace + wav))
{
if (str == null)
throw new ArgumentException(wav + " not found!");
// bring stream into a byte array
byte[] bStr = new Byte[str.Length];
str.Read(bStr, 0, (int)str.Length);
cachedWavs.Add(wav, bStr);
return bStr;
}
}
}
return b;
}
}
}

207
BabySmash.csproj Normal file
Просмотреть файл

@ -0,0 +1,207 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.21022</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{FB378E07-FDE4-4FC7-9210-68F80B561164}</ProjectGuid>
<OutputType>WinExe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>BabySmash</RootNamespace>
<AssemblyName>BabySmash</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<WarningLevel>4</WarningLevel>
<ManifestCertificateThumbprint>323251D3E7929FA0384D4513B8D1AC5881D2EF71</ManifestCertificateThumbprint>
<ManifestKeyFile>BabySmash_TemporaryKey.pfx</ManifestKeyFile>
<GenerateManifests>true</GenerateManifests>
<SignManifests>true</SignManifests>
<IsWebBootstrapper>true</IsWebBootstrapper>
<ApplicationIcon>App.ico</ApplicationIcon>
<PublishUrl>ftp://www.hanselman.com/babysmash/</PublishUrl>
<Install>false</Install>
<InstallFrom>Web</InstallFrom>
<UpdateEnabled>true</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<InstallUrl>http://www.hanselman.com/BabySmash/</InstallUrl>
<SupportUrl>http://www.babysmash.com</SupportUrl>
<ProductName>BabySmash!</ProductName>
<PublisherName>Scott Hanselman</PublisherName>
<CreateWebPageOnPublish>true</CreateWebPageOnPublish>
<WebPage>publish.htm</WebPage>
<ApplicationRevision>16</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml.Linq">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data.DataSetExtensions">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<Reference Include="UIAutomationProvider">
<RequiredTargetFramework>3.0</RequiredTargetFramework>
</Reference>
<Reference Include="WindowsBase">
<RequiredTargetFramework>3.0</RequiredTargetFramework>
</Reference>
<Reference Include="PresentationCore">
<RequiredTargetFramework>3.0</RequiredTargetFramework>
</Reference>
<Reference Include="PresentationFramework">
<RequiredTargetFramework>3.0</RequiredTargetFramework>
</Reference>
</ItemGroup>
<ItemGroup>
<ApplicationDefinition Include="App.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</ApplicationDefinition>
<Page Include="Options.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Window1.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Compile Include="App.xaml.cs">
<DependentUpon>App.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="Window1.xaml.cs">
<DependentUpon>Window1.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
</ItemGroup>
<ItemGroup>
<Compile Include="Audio.cs" />
<Compile Include="ConfigurationManager.cs" />
<Compile Include="HiResTextBlock.cs" />
<Compile Include="Keyboard.cs" />
<Compile Include="KeyboardHook.cs" />
<Compile Include="Options.xaml.cs">
<DependentUpon>Options.xaml</DependentUpon>
</Compile>
<Compile Include="Properties\AssemblyInfo.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
<Compile Include="Star.cs" />
<Compile Include="Utils.cs" />
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
<None Include="BabySmash_TemporaryKey.pfx" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<AppDesigner Include="Properties\" />
</ItemGroup>
<ItemGroup>
<COMReference Include="SpeechLib">
<Guid>{C866CA3A-32F7-11D2-9602-00C04F8EE628}</Guid>
<VersionMajor>5</VersionMajor>
<VersionMinor>3</VersionMinor>
<Lcid>0</Lcid>
<WrapperTool>tlbimp</WrapperTool>
<Isolated>False</Isolated>
</COMReference>
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include="Microsoft.Net.Framework.2.0">
<Visible>False</Visible>
<ProductName>.NET Framework 2.0 %28x86%29</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.0">
<Visible>False</Visible>
<ProductName>.NET Framework 3.0 %28x86%29</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
<Visible>False</Visible>
<ProductName>Windows Installer 3.1</ProductName>
<Install>true</Install>
</BootstrapperPackage>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Resources\Sounds\babylaugh.wav" />
<EmbeddedResource Include="Resources\Sounds\giggle.wav" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Resources\Sounds\babygigl2.wav" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Resources\Sounds\laughingmice.wav" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Resources\Sounds\ccgiggle.wav" />
<EmbeddedResource Include="Resources\Sounds\scooby2.wav" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="App.ico" />
</ItemGroup>
<ItemGroup>
<Folder Include="Resources\Voices\" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

20
BabySmash.sln Normal file
Просмотреть файл

@ -0,0 +1,20 @@

Microsoft Visual Studio Solution File, Format Version 10.00
# Visual Studio 2008
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BabySmash", "BabySmash.csproj", "{FB378E07-FDE4-4FC7-9210-68F80B561164}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{FB378E07-FDE4-4FC7-9210-68F80B561164}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FB378E07-FDE4-4FC7-9210-68F80B561164}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FB378E07-FDE4-4FC7-9210-68F80B561164}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FB378E07-FDE4-4FC7-9210-68F80B561164}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

Двоичные данные
BabySmash_TemporaryKey.pfx Normal file

Двоичный файл не отображается.

286
ConfigurationManager.cs Normal file
Просмотреть файл

@ -0,0 +1,286 @@
using System;
using System.IO;
using System.IO.IsolatedStorage;
using System.Xml;
namespace IsolatedStorage
{
/// <summary>
/// IsolatedStorageConfigurationManager
/// ===================================
/// Read and Write application and formsettings to isolated storage
/// Setting are saved as XML in a file named <application-name>.config
/// in folder C:\Documents and Settings\<user>\Local Settings\Application Data\IsolatedStorage\<...>\<...>\<...>\AssemFiles\
///
/// Class is implemented as a Singleton.
/// Example for use:
/// IsolatedStorageConfigurationManager configManager = IsolatedStorageConfigurationManager.ConfigurationManager(Application.ProductName)
/// string databaseName = configManager.Read("Database")
/// configManager.Write("Database", DatabaseName)
/// configManager.Persist()
///
/// Edwin Roetman, January 2004
/// </summary>
public sealed class ConfigurationManager
{
#region Singleton
//The ConfigurationManager singleton instance
private static ConfigurationManager _singleton;
//The ConfigurationManager singleton instance
public static ConfigurationManager GetConfigurationManager(string applicationName)
{
if (_singleton == null)
{
_singleton = new ConfigurationManager(applicationName);
}
return _singleton;
}
/// <summary>
/// Singleton, do not allow this class to be instantiated by making the contructor private
/// </summary>
/// <param name="applicationName"></param>
private ConfigurationManager(string applicationName)
{
this.InitializeConfiguration(applicationName);
}
#endregion
#region Private members
private XmlDocument _xml;
private XmlDocument _xmlOriginal;
private string _fileName;
private IsolatedStorageFile _isoStore;
#endregion
#region public implementation
public string Read(string section)
{
return Read(section, String.Empty);
}
public string Read(string section, string defaultValue)
{
try
{
if (this._xml == null)
{
//return String.Empty;
return defaultValue;
}
//Select the item node(s)
XmlNode sectionNode = this._xml.SelectSingleNode((@"/configuration/" + section));
if (sectionNode == null)
{
return defaultValue;
}
return sectionNode.FirstChild.Value;
}
catch
{
return defaultValue;
}
}
public int ReadInteger(string section)
{
return ReadInteger(section, 0);
}
public int ReadInteger(string section, int defaultValue)
{
string valuestring = Read(section);
if (valuestring.Length <= 0)
{
return defaultValue;
}
try
{
int value = Convert.ToInt32(valuestring);
return value;
}
catch
{
return defaultValue;
}
}
public bool ReadBoolean(string section)
{
return ReadBoolean(section, false);
}
public bool ReadBoolean(string section, bool defaultValue)
{
string value = this.Read(section);
if (value.Length <= 0)
{
return defaultValue;
}
try
{
return Boolean.Parse(value);
}
catch
{
return defaultValue;
}
}
public void Write(string section, string value)
{
try
{
if (this._xml == null)
{
this._xml = new XmlDocument();
XmlNode configurationRootNode = this._xml.CreateElement(@"configuration");
this._xml.AppendChild(configurationRootNode);
}
//Select the item node(s)
XmlNode sectionNode = this._xml.SelectSingleNode((@"/configuration/" + section));
if (sectionNode == null)
{
//if the node does not exist create it
sectionNode = this._xml.CreateElement(section);
XmlNode configurationRootNode = this._xml.SelectSingleNode(@"/configuration");
configurationRootNode.AppendChild(sectionNode);
}
sectionNode.InnerText = value;
}
catch { }
}
///Read form state, size and position
public void ReadFormSettings(System.Windows.Forms.Form form)
{
string windowStateString = this.Read(form.Name + "WindowState");
System.Windows.Forms.FormWindowState windowState = System.Windows.Forms.FormWindowState.Normal;
if (windowStateString.Length > 0)
{
windowState = (System.Windows.Forms.FormWindowState)Convert.ToInt32(windowStateString);
}
if (windowState == System.Windows.Forms.FormWindowState.Maximized)
{
form.WindowState = windowState;
}
else
{
string valuesString = this.Read(form.Name);
if (valuesString.Length > 0)
{
string[] values = valuesString.Split(Convert.ToChar(","));
form.Top = Convert.ToInt16(values[0]);
form.Left = Convert.ToInt16(values[1]);
int width = Convert.ToInt16(values[2]);
if (width > 0) form.Width = width;
int height = Convert.ToInt16(values[3]);
if (height > 0) form.Height = height;
}
}
}
///Write form state, size and position
public void WriteFormSettings(System.Windows.Forms.Form form)
{
this.Write(form.Name + "WindowState", ((int)form.WindowState).ToString());
//Me.Write(form.Name & "WindowState", (CType(form.WindowState, Integer)).ToString())
if (form.WindowState == System.Windows.Forms.FormWindowState.Normal)
{
string valuesstring = form.Top.ToString() + "," + form.Left.ToString() + "," + form.Width.ToString() + "," + form.Height.ToString();
this.Write(form.Name, valuesstring);
}
}
public void Persist()
{
try
{
this.WriteBackConfiguration();
}
catch
{
}
finally
{
_singleton = null;
}
}
#endregion
#region private methods and functions
private void InitializeConfiguration(string applicationName)
{
this._fileName = applicationName + ".config";
this._isoStore = IsolatedStorageFile.GetStore(IsolatedStorageScope.User | IsolatedStorageScope.Assembly, null, null);
//Check to see if the settings file exists, if so load xml from it
string[] storeFileNames;
storeFileNames = this._isoStore.GetFileNames(this._fileName);
foreach (string storeFile in storeFileNames)
{
if (storeFile == this._fileName)
{
//Create isoStorage StreamReader
StreamReader streamReader = new StreamReader(new IsolatedStorageFileStream(this._fileName, FileMode.Open, this._isoStore));
this._xml = new XmlDocument();
this._xml.Load(streamReader);
this._xmlOriginal = new XmlDocument();
this._xmlOriginal.LoadXml(this._xml.OuterXml);
streamReader.Close();
}
}
}
private void WriteBackConfiguration()
{
//if no config information is present write null
if (this._xml == null) return;
//if config is unchanged write null
if (this._xmlOriginal != null)
{
if (this._xml.OuterXml == this._xmlOriginal.OuterXml) return;
}
//Save the document
StreamWriter streamWriter = null;
try
{
streamWriter = new StreamWriter(new IsolatedStorageFileStream(this._fileName, FileMode.Create, this._isoStore));
this._xml.Save(streamWriter);
streamWriter.Flush();
streamWriter.Close();
if (this._xmlOriginal == null) this._xmlOriginal = new XmlDocument();
this._xmlOriginal.LoadXml(this._xml.OuterXml);
}
catch
{
//throw;
}
finally
{
if (streamWriter != null)
{
streamWriter.Flush();
streamWriter.Close();
}
}
}
#endregion
}
}

210
HiResTextBlock.cs Normal file
Просмотреть файл

@ -0,0 +1,210 @@
using System.Globalization;
using System.Windows;
using System.Windows.Media;
namespace BabySmash
{
class HiResTextBlock : FrameworkElement
{
public HiResTextBlock()
: base()
{
RenderOptions.SetEdgeMode(this, EdgeMode.Unspecified);
this.SnapsToDevicePixels = true;
}
#region props
Geometry m_textg;
static Pen m_pen;
#endregion
#region methods
protected override void OnRender(DrawingContext drawingContext)
{
drawingContext.DrawGeometry(Fill, m_pen, m_textg);
}
private static void OnTextInvalidated(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
m_pen = new Pen(((HiResTextBlock)d).Stroke, ((HiResTextBlock)d).StrokeThickness);
m_pen.LineJoin = PenLineJoin.Round;
m_pen.MiterLimit = 1;
m_pen = m_pen.GetAsFrozen() as Pen;
((HiResTextBlock)d).GenerateText();
}
private void GenerateText()
{
if (Font == null)
Font = new FontFamily("Arial");
FormattedText fText = new FormattedText(
Text,
CultureInfo.CurrentCulture,
FlowDirection.LeftToRight,
new Typeface(
Font,
FontStyles.Normal,
FontWeights.Heavy,
FontStretches.Normal),
FontSize,
Brushes.Black
);
m_textg = fText.BuildGeometry(new Point(0, 0)).GetAsFrozen() as Geometry;
}
#endregion
#region DPs
public Brush Stroke
{
get
{
return (Brush)GetValue(StrokeProperty);
}
set
{
SetValue(StrokeProperty, value);
}
}
public static readonly DependencyProperty StrokeProperty = DependencyProperty.Register(
"Stroke",
typeof(Brush),
typeof(HiResTextBlock),
new FrameworkPropertyMetadata(
new SolidColorBrush(Colors.Black),
FrameworkPropertyMetadataOptions.AffectsRender,
new PropertyChangedCallback(OnTextInvalidated),
null
)
);
public ushort StrokeThickness
{
get
{
return (ushort)GetValue(StrokeThicknessProperty);
}
set
{
SetValue(StrokeThicknessProperty, value);
}
}
public static readonly DependencyProperty StrokeThicknessProperty = DependencyProperty.Register(
"StrokeThickness",
typeof(ushort),
typeof(HiResTextBlock),
new FrameworkPropertyMetadata(
(ushort)1,
FrameworkPropertyMetadataOptions.AffectsRender,
new PropertyChangedCallback(OnTextInvalidated),
null
)
);
public string Text
{
get
{
return (string)GetValue(TextProperty);
}
set
{
SetValue(TextProperty, value);
}
}
public static readonly DependencyProperty TextProperty = DependencyProperty.Register(
"Text",
typeof(string),
typeof(HiResTextBlock),
new FrameworkPropertyMetadata(
"",
FrameworkPropertyMetadataOptions.AffectsRender,
new PropertyChangedCallback(OnTextInvalidated),
null
)
);
public double FontSize
{
get
{
return (double)GetValue(FontSizeProperty);
}
set
{
SetValue(FontSizeProperty, value);
}
}
public static readonly DependencyProperty FontSizeProperty = DependencyProperty.Register(
"FontSize",
typeof(double),
typeof(HiResTextBlock),
new FrameworkPropertyMetadata(
(double)12,
FrameworkPropertyMetadataOptions.AffectsRender,
new PropertyChangedCallback(OnTextInvalidated),
null
)
);
public Brush Fill
{
get
{
return (Brush)GetValue(FillProperty);
}
set
{
SetValue(FillProperty, value);
}
}
public static readonly DependencyProperty FillProperty = DependencyProperty.Register(
"Fill",
typeof(Brush),
typeof(HiResTextBlock),
new FrameworkPropertyMetadata(
new SolidColorBrush(Colors.White),
FrameworkPropertyMetadataOptions.AffectsRender,
new PropertyChangedCallback(OnTextInvalidated),
null
)
);
public FontFamily Font
{
get
{
return (FontFamily)GetValue(FontProperty);
}
set
{
SetValue(FontProperty, value);
}
}
public static readonly DependencyProperty FontProperty = DependencyProperty.Register(
"Font",
typeof(FontFamily),
typeof(HiResTextBlock),
new FrameworkPropertyMetadata(
new FontFamily("Arial"),
FrameworkPropertyMetadataOptions.AffectsRender,
new PropertyChangedCallback(OnTextInvalidated),
null
)
);
#endregion
}
}

365
Keyboard.cs Normal file
Просмотреть файл

@ -0,0 +1,365 @@
/// KEYBOARD.CS
/// (c) 2006 by Emma Burrows
/// This file contains the following items:
/// - KeyboardHook: class to enable low-level keyboard hook using
/// the Windows API.
/// - KeyboardHookEventHandler: delegate to handle the KeyIntercepted
/// event raised by the KeyboardHook class.
/// - KeyboardHookEventArgs: EventArgs class to contain the information
/// returned by the KeyIntercepted event.
///
/// Change history:
/// 17/06/06: 1.0 - First version.
/// 18/06/06: 1.1 - Modified proc assignment in constructor to make class backward
/// compatible with 2003.
/// 10/07/06: 1.2 - Added support for modifier keys:
/// -Changed filter in HookCallback to WM_KEYUP instead of WM_KEYDOWN
/// -Imported GetKeyState from user32.dll
/// -Moved native DLL imports to a separate internal class as this
/// is a Good Idea according to Microsoft's guidelines
/// 13/02/07: 1.3 - Improved modifier key support:
/// -Added CheckModifiers() method
/// -Deleted LoWord/HiWord methods as they weren't necessary
/// -Implemented Barry Dorman's suggestion to AND GetKeyState
/// values with 0x8000 to get their result
/// 23/03/07: 1.4 - Fixed bug which made the Alt key appear stuck
/// - Changed the line
/// if (nCode >= 0 && (wParam == (IntPtr)WM_KEYUP || wParam == (IntPtr)WM_SYSKEYUP))
/// to
/// if (nCode >= 0)
/// {
/// if (wParam == (IntPtr)WM_KEYUP || wParam == (IntPtr)WM_SYSKEYUP)
/// ...
/// Many thanks to "Scottie Numbnuts" for the solution.
using System;
using System.Diagnostics;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Text;
/// <summary>
/// Low-level keyboard intercept class to trap and suppress system keys.
/// </summary>
public class KeyboardHook : IDisposable
{
/// <summary>
/// Parameters accepted by the KeyboardHook constructor.
/// </summary>
public enum Parameters
{
None,
AllowAltTab,
AllowWindowsKey,
AllowAltTabAndWindows,
PassAllKeysToNextApp
}
//Internal parameters
private bool PassAllKeysToNextApp = false;
private bool AllowAltTab = false;
private bool AllowWindowsKey = false;
//Keyboard API constants
private const int WH_KEYBOARD_LL = 13;
private const int WM_KEYUP = 0x0101;
private const int WM_SYSKEYUP = 0x0105;
//Modifier key constants
private const int VK_SHIFT = 0x10;
private const int VK_CONTROL = 0x11;
private const int VK_MENU = 0x12;
private const int VK_CAPITAL = 0x14;
//Variables used in the call to SetWindowsHookEx
private HookHandlerDelegate proc;
private IntPtr hookID = IntPtr.Zero;
internal delegate IntPtr HookHandlerDelegate(
int nCode, IntPtr wParam, ref KBDLLHOOKSTRUCT lParam);
/// <summary>
/// Event triggered when a keystroke is intercepted by the
/// low-level hook.
/// </summary>
public event KeyboardHookEventHandler KeyIntercepted;
// Structure returned by the hook whenever a key is pressed
internal struct KBDLLHOOKSTRUCT
{
public int vkCode;
int scanCode;
public int flags;
int time;
int dwExtraInfo;
}
#region Constructors
/// <summary>
/// Sets up a keyboard hook to trap all keystrokes without
/// passing any to other applications.
/// </summary>
public KeyboardHook()
{
proc = new HookHandlerDelegate(HookCallback);
using (Process curProcess = Process.GetCurrentProcess())
using (ProcessModule curModule = curProcess.MainModule)
{
hookID = NativeMethods.SetWindowsHookEx(WH_KEYBOARD_LL, proc,
NativeMethods.GetModuleHandle(curModule.ModuleName), 0);
}
}
/// <summary>
/// Sets up a keyboard hook with custom parameters.
/// </summary>
/// <param name="param">A valid name from the Parameter enum; otherwise, the
/// default parameter Parameter.None will be used.</param>
public KeyboardHook(string param)
: this()
{
if (!String.IsNullOrEmpty(param) && Enum.IsDefined(typeof(Parameters), param))
{
SetParameters((Parameters)Enum.Parse(typeof(Parameters), param));
}
}
/// <summary>
/// Sets up a keyboard hook with custom parameters.
/// </summary>
/// <param name="param">A value from the Parameters enum.</param>
public KeyboardHook(Parameters param)
: this()
{
SetParameters(param);
}
private void SetParameters(Parameters param)
{
switch (param)
{
case Parameters.None:
break;
case Parameters.AllowAltTab:
AllowAltTab = true;
break;
case Parameters.AllowWindowsKey:
AllowWindowsKey = true;
break;
case Parameters.AllowAltTabAndWindows:
AllowAltTab = true;
AllowWindowsKey = true;
break;
case Parameters.PassAllKeysToNextApp:
PassAllKeysToNextApp = true;
break;
}
}
#endregion
#region Check Modifier keys
/// <summary>
/// Checks whether Alt, Shift, Control or CapsLock
/// is enabled at the same time as another key.
/// Modify the relevant sections and return type
/// depending on what you want to do with modifier keys.
/// </summary>
private void CheckModifiers()
{
StringBuilder sb = new StringBuilder();
if ((NativeMethods.GetKeyState(VK_CAPITAL) & 0x0001) != 0)
{
//CAPSLOCK is ON
sb.AppendLine("Capslock is enabled.");
}
if ((NativeMethods.GetKeyState(VK_SHIFT) & 0x8000) != 0)
{
//SHIFT is pressed
sb.AppendLine("Shift is pressed.");
}
if ((NativeMethods.GetKeyState(VK_CONTROL) & 0x8000) != 0)
{
//CONTROL is pressed
sb.AppendLine("Control is pressed.");
}
if ((NativeMethods.GetKeyState(VK_MENU) & 0x8000) != 0)
{
//ALT is pressed
sb.AppendLine("Alt is pressed.");
}
Console.WriteLine(sb.ToString());
}
#endregion Check Modifier keys
#region Hook Callback Method
/// <summary>
/// Processes the key event captured by the hook.
/// </summary>
private IntPtr HookCallback(
int nCode, IntPtr wParam, ref KBDLLHOOKSTRUCT lParam)
{
bool AllowKey = PassAllKeysToNextApp;
//Filter wParam for KeyUp events only
if (nCode >= 0)
{
if (wParam == (IntPtr)WM_KEYUP || wParam == (IntPtr)WM_SYSKEYUP)
{
// Check for modifier keys, but only if the key being
// currently processed isn't a modifier key (in other
// words, CheckModifiers will only run if Ctrl, Shift,
// CapsLock or Alt are active at the same time as
// another key)
if (!(lParam.vkCode >= 160 && lParam.vkCode <= 164))
{
CheckModifiers();
}
// Check for key combinations that are allowed to
// get through to Windows
//
// Ctrl+Esc or Windows key
if (AllowWindowsKey)
{
switch (lParam.flags)
{
//Ctrl+Esc
case 0:
if (lParam.vkCode == 27)
AllowKey = true;
break;
//Windows keys
case 1:
if ((lParam.vkCode == 91) || (lParam.vkCode == 92))
AllowKey = true;
break;
}
}
// Alt+Tab
if (AllowAltTab)
{
if ((lParam.flags == 32) && (lParam.vkCode == 9))
AllowKey = true;
}
OnKeyIntercepted(new KeyboardHookEventArgs(lParam.vkCode, AllowKey));
}
//If this key is being suppressed, return a dummy value
if (AllowKey == false)
return (System.IntPtr)1;
}
//Pass key to next application
return NativeMethods.CallNextHookEx(hookID, nCode, wParam, ref lParam);
}
#endregion
#region Event Handling
/// <summary>
/// Raises the KeyIntercepted event.
/// </summary>
/// <param name="e">An instance of KeyboardHookEventArgs</param>
public void OnKeyIntercepted(KeyboardHookEventArgs e)
{
if (KeyIntercepted != null)
KeyIntercepted(e);
}
/// <summary>
/// Delegate for KeyboardHook event handling.
/// </summary>
/// <param name="e">An instance of InterceptKeysEventArgs.</param>
public delegate void KeyboardHookEventHandler(KeyboardHookEventArgs e);
/// <summary>
/// Event arguments for the KeyboardHook class's KeyIntercepted event.
/// </summary>
public class KeyboardHookEventArgs : System.EventArgs
{
private string keyName;
private int keyCode;
private bool passThrough;
/// <summary>
/// The name of the key that was pressed.
/// </summary>
public string KeyName
{
get { return keyName; }
}
/// <summary>
/// The virtual key code of the key that was pressed.
/// </summary>
public int KeyCode
{
get { return keyCode; }
}
/// <summary>
/// True if this key combination was passed to other applications,
/// false if it was trapped.
/// </summary>
public bool PassThrough
{
get { return passThrough; }
}
public KeyboardHookEventArgs(int evtKeyCode, bool evtPassThrough)
{
keyName = ((Keys)evtKeyCode).ToString();
keyCode = evtKeyCode;
passThrough = evtPassThrough;
}
}
#endregion
#region IDisposable Members
/// <summary>
/// Releases the keyboard hook.
/// </summary>
public void Dispose()
{
NativeMethods.UnhookWindowsHookEx(hookID);
}
#endregion
#region Native methods
[ComVisibleAttribute(false),
System.Security.SuppressUnmanagedCodeSecurity()]
internal class NativeMethods
{
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr GetModuleHandle(string lpModuleName);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr SetWindowsHookEx(int idHook,
HookHandlerDelegate lpfn, IntPtr hMod, uint dwThreadId);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool UnhookWindowsHookEx(IntPtr hhk);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode,
IntPtr wParam, ref KBDLLHOOKSTRUCT lParam);
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]
public static extern short GetKeyState(int keyCode);
}
#endregion
}

48
KeyboardHook.cs Normal file
Просмотреть файл

@ -0,0 +1,48 @@
using System;
using System.Diagnostics;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace BabySmash
{
class InterceptKeys
{
private const int WH_KEYBOARD_LL = 13;
private const int WM_KEYDOWN = 0x0100;
public static IntPtr SetHook(LowLevelKeyboardProc proc)
{
using (Process curProcess = Process.GetCurrentProcess())
using (ProcessModule curModule = curProcess.MainModule)
{
return SetWindowsHookEx(WH_KEYBOARD_LL, proc,
GetModuleHandle(curModule.ModuleName), 0);
}
}
public delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr SetWindowsHookEx(int idHook,
LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool UnhookWindowsHookEx(IntPtr hhk);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode,
IntPtr wParam, IntPtr lParam);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr GetModuleHandle(string lpModuleName);
//private static IntPtr _hookID = IntPtr.Zero;
//public static void Main()
//{
// _hookID = SetHook(_proc);
// Application.Run();
// UnhookWindowsHookEx(_hookID);
//}
}
}

18
Options.xaml Normal file
Просмотреть файл

@ -0,0 +1,18 @@
<Window x:Class="BabySmash.Options"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Baby Smash! - Options" Unloaded="Window_Unloaded" Loaded="Window_Loaded" Height="188" Width="268" ShowInTaskbar="False" Topmost="True" WindowStartupLocation="CenterScreen" WindowStyle="ThreeDBorderWindow" ResizeMode="NoResize">
<Grid>
<Button Height="23" Name="OK" VerticalAlignment="Bottom" Click="OK_Click" IsDefault="True" Margin="64,0,102,9">OK</Button>
<Button Height="23" Margin="0,0,8,9" Name="Cancel" VerticalAlignment="Bottom" IsCancel="True" HorizontalAlignment="Right" Width="80" Click="Cancel_Click">Cancel</Button>
<Label Height="28" Margin="14,19,0,0" Name="lblClearAfter" VerticalAlignment="Top" HorizontalAlignment="Left" Width="120">Clear After x Shapes</Label>
<TextBox Height="23" Margin="0,19,8,0" Name="txtClearAfter" VerticalAlignment="Top" HorizontalAlignment="Right" Width="101">0</TextBox>
<CheckBox Margin="0,81,0,0" Name="chkForceUppercase" Height="16" HorizontalAlignment="Right" VerticalAlignment="Top" Width="109">Force Uppercase</CheckBox>
<ComboBox Margin="0,48,8,0" Name="cmbSound" Height="23" HorizontalAlignment="Right" VerticalAlignment="Top" Width="101" IsDropDownOpen="False">
<ComboBoxItem>None</ComboBoxItem>
<ComboBoxItem>Speech</ComboBoxItem>
<ComboBoxItem>Laughter</ComboBoxItem>
</ComboBox>
<Label Height="28" Margin="14,43,112,0" Name="label1" VerticalAlignment="Top">Sounds</Label>
</Grid>
</Window>

42
Options.xaml.cs Normal file
Просмотреть файл

@ -0,0 +1,42 @@
using System.Windows;
namespace BabySmash
{
/// <summary>
/// Interaction logic for Options.xaml
/// </summary>
public partial class Options : Window
{
IsolatedStorage.ConfigurationManager config = null;
public Options()
{
InitializeComponent();
}
private void OK_Click(object sender, RoutedEventArgs e)
{
config.Write("ClearAfter", txtClearAfter.Text);
config.Write("ForceUppercase", chkForceUppercase.IsChecked.ToString());
config.Write("Sounds", cmbSound.Text);
config.Persist();
this.Close();
}
private void Cancel_Click(object sender, RoutedEventArgs e)
{
this.Close();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
config = IsolatedStorage.ConfigurationManager.GetConfigurationManager("BabySmash");
txtClearAfter.Text = config.ReadInteger("ClearAfter", 20).ToString();
chkForceUppercase.IsChecked = config.ReadBoolean("ForceUppercase", true);
cmbSound.Text = config.Read("Sounds", "Laughter");
}
private void Window_Unloaded(object sender, RoutedEventArgs e)
{
}
}
}