[Roam-commit] SF.net SVN: roam: [80] Trunk/Source
Status: Alpha
Brought to you by:
jonfroehlich
|
From: <jon...@us...> - 2007-07-01 22:43:16
|
Revision: 80
http://roam.svn.sourceforge.net/roam/?rev=80&view=rev
Author: jonfroehlich
Date: 2007-07-01 15:43:14 -0700 (Sun, 01 Jul 2007)
Log Message:
-----------
added KeySniffer
Modified Paths:
--------------
Trunk/Source/Roam/Media/SoundLoopPlayer.cs
Trunk/Source/Roam/Roam.csproj
Trunk/Source/Roam/Utils/DeviceUtils.cs
Trunk/Source/Roam/Utils/PowerUtils.cs
Trunk/Source/Roam.Test/Roam.Test.csproj
Trunk/Source/Roam.Test.Desktop/MeasureStringTest.cs
Trunk/Source/Roam.Test.Desktop/Roam.Test.Desktop.csproj
Trunk/Source/Roam.Test.Desktop/ShapeItemTest.cs
Trunk/Source/Roam.UI/Controls/TextBoxFilteredList.Designer.cs
Trunk/Source/Roam.UI/Controls/TextBoxFilteredList.cs
Trunk/Source/Roam.UI/Drawing/PolygonItem.cs
Trunk/Source/Roam.UI/Drawing/ShapeItem.cs
Trunk/Source/Roam.UI/Roam.UI.csproj
Trunk/Source/Roam.UI/Utils/DrawingUtils.cs
Trunk/Source/Roam.UI/Utils/HotKeyManager.cs
Trunk/Source/Roam.UI/Utils/WindowsMessagingUtils.cs
Trunk/Source/Roam.suo
Added Paths:
-----------
Trunk/Source/Roam/Utils/PerformanceUtils.cs
Trunk/Source/Roam/Utils/WindowsConstants.cs
Trunk/Source/Roam/Utils/WindowsHooks.cs
Trunk/Source/Roam.Test/Sandbox/PhoneButtonManager.cs
Trunk/Source/Roam.Test/Sandbox/PhoneButtonManagerTest.Designer.cs
Trunk/Source/Roam.Test/Sandbox/PhoneButtonManagerTest.cs
Trunk/Source/Roam.Test/Sandbox/PhoneButtonManagerTest.resx
Trunk/Source/Roam.Test/Sandbox/TimeTest.Designer.cs
Trunk/Source/Roam.Test/Sandbox/TimeTest.cs
Trunk/Source/Roam.Test/Sandbox/TimeTest.resx
Trunk/Source/Roam.Test/Utils/KeySnifferTest.Designer.cs
Trunk/Source/Roam.Test/Utils/KeySnifferTest.cs
Trunk/Source/Roam.Test/Utils/KeySnifferTest.resx
Trunk/Source/Roam.Test/Utils/KeySniffersTest.Designer.cs
Trunk/Source/Roam.Test/Utils/KeySniffersTest.cs
Trunk/Source/Roam.Test/Utils/KeySniffersTest.resx
Trunk/Source/Roam.Test.Desktop/ActuationItemForm.Designer.cs
Trunk/Source/Roam.Test.Desktop/ActuationItemForm.cs
Trunk/Source/Roam.UI/Utils/KeySniffer.cs
Modified: Trunk/Source/Roam/Media/SoundLoopPlayer.cs
===================================================================
--- Trunk/Source/Roam/Media/SoundLoopPlayer.cs 2007-04-25 06:42:49 UTC (rev 79)
+++ Trunk/Source/Roam/Media/SoundLoopPlayer.cs 2007-07-01 22:43:14 UTC (rev 80)
@@ -21,14 +21,6 @@
namespace Roam.Media
{
- /// <summary>
- /// <summary>
- ///
- /// </summary>
- /// <remarks>
- ///
- /// </remarks>
- /// <author>Jon Froehlich</author>
/// This class is used for looping sounds over and over.
///
/// It would derive from CyclePlayer and use that functionality but in order to do so
Modified: Trunk/Source/Roam/Roam.csproj
===================================================================
--- Trunk/Source/Roam/Roam.csproj 2007-04-25 06:42:49 UTC (rev 79)
+++ Trunk/Source/Roam/Roam.csproj 2007-07-01 22:43:14 UTC (rev 80)
@@ -69,12 +69,15 @@
<Compile Include="PocketOutlook\Sms.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Utils\DeviceUtils.cs" />
+ <Compile Include="Utils\PerformanceUtils.cs" />
<Compile Include="Utils\PowerNotification.cs" />
<Compile Include="Utils\PowerUtils.cs" />
<Compile Include="Utils\ProcessUtils.cs" />
<Compile Include="Utils\StorageCardUtils.cs" />
<Compile Include="Utils\SystemUtils.cs" />
<Compile Include="Utils\ThreadUtils.cs" />
+ <Compile Include="Utils\WindowsHooks.cs" />
+ <Compile Include="Utils\WindowsConstants.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Roam.Common\Roam.Common.csproj">
Modified: Trunk/Source/Roam/Utils/DeviceUtils.cs
===================================================================
--- Trunk/Source/Roam/Utils/DeviceUtils.cs 2007-04-25 06:42:49 UTC (rev 79)
+++ Trunk/Source/Roam/Utils/DeviceUtils.cs 2007-07-01 22:43:14 UTC (rev 80)
@@ -20,21 +20,8 @@
namespace Roam.Utils
{
- /// <summary>
- ///
- /// </summary>
- /// <remarks>
- ///
- /// </remarks>
- /// <author>Jon Froehlich</author>
+
//jeffixme I believe the deviceid functionality is in OpenNetCF in the DeviceManagement class
- /// <summary>
- ///
- /// </summary>
- /// <remarks>
- ///
- /// </remarks>
- /// <author>Jon Froehlich</author>
//If that's the case, some of this class is redundant.
/// <summary>
@@ -47,25 +34,6 @@
public static class DeviceUtils
{
/// <summary>
- /// <summary>
- ///
- /// </summary>
- /// <remarks>
- ///
- /// </remarks>
- /// <author>Jon Froehlich</author>
- /// I would suggest using the Stopwatch class for performance timing
- /// which can be found in OpenNETCF's SDF.
- /// </summary>
- /// <param name="perfCounter"></param>
- /// <returns></returns>
- [DllImport("coredll.dll")]
- internal static extern int QueryPerformanceCounter(out Int64 perfCounter);
-
- [DllImport("coredll.dll")]
- internal static extern int QueryPerformanceFrequency(out Int64 frequency);
-
- /// <summary>
/// This function returns the amount of time, in milliseconds, that the
/// system has been idle.
/// </summary>
Added: Trunk/Source/Roam/Utils/PerformanceUtils.cs
===================================================================
--- Trunk/Source/Roam/Utils/PerformanceUtils.cs (rev 0)
+++ Trunk/Source/Roam/Utils/PerformanceUtils.cs 2007-07-01 22:43:14 UTC (rev 80)
@@ -0,0 +1,44 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Runtime.InteropServices;
+
+namespace Roam.Utils
+{
+ public static class PerformanceUtils
+ {
+ [DllImport("coredll.dll", EntryPoint = "QueryPerformanceCounter")]
+ private static extern bool QueryPerformanceCounter(out long count);
+
+ [DllImport("coredll.dll", EntryPoint = "QueryPerformanceFrequency")]
+ private static extern bool QueryPerformanceFrequency(out long countsPerSecond);
+
+ //these two variables are initialized in the PerformanceUtils static constructor
+ public static readonly long Frequency;
+ public static readonly long FrequencyInMs;
+
+ static PerformanceUtils()
+ {
+ if (QueryPerformanceFrequency(out Frequency) == false)
+ {
+ throw new Exception("The high resolution timer is not available on this device.");
+ }
+
+ FrequencyInMs = Frequency / 1000;
+ }
+
+ public static long GetTimestampMs()
+ {
+ long count;
+ QueryPerformanceCounter(out count);
+ return (long)Math.Round(count / (double)FrequencyInMs);
+ }
+
+ public static long GetPerformanceCount()
+ {
+ long count;
+ QueryPerformanceCounter(out count);
+ return count;
+ }
+ }
+}
Modified: Trunk/Source/Roam/Utils/PowerUtils.cs
===================================================================
--- Trunk/Source/Roam/Utils/PowerUtils.cs 2007-04-25 06:42:49 UTC (rev 79)
+++ Trunk/Source/Roam/Utils/PowerUtils.cs 2007-07-01 22:43:14 UTC (rev 80)
@@ -234,41 +234,13 @@
/// These flags are defined in pm.h
///
/// A note on flags: Bit fields are generally used for lists of elements that might
- /// <summary>
- ///
- /// </summary>
- /// <remarks>
- ///
- /// </remarks>
- /// <author>Jon Froehlich</author>
/// occur in combination, whereas enumeration constants are generally used for
/// lists of mutually exclusive elements. Therefore, bit fields are designed to
/// be combined with a bitwise OR operation to generate unnamed values, whereas
- /// <summary>
- ///
- /// </summary>
- /// <remarks>
- ///
- /// </remarks>
- /// <author>Jon Froehlich</author>
/// enumerated constants are not. Languages vary in their use of bit fields
- /// <summary>
- ///
- /// </summary>
- /// <remarks>
- ///
- /// </remarks>
- /// <author>Jon Froehlich</author>
/// compared to enumeration constants.
/// </summary>
[Flags]
- /// <summary>
- ///
- /// </summary>
- /// <remarks>
- ///
- /// </remarks>
- /// <author>Jon Froehlich</author>
public enum PowerStateFlags : uint
{
On = (0x00010000), // on state
Added: Trunk/Source/Roam/Utils/WindowsConstants.cs
===================================================================
--- Trunk/Source/Roam/Utils/WindowsConstants.cs (rev 0)
+++ Trunk/Source/Roam/Utils/WindowsConstants.cs 2007-07-01 22:43:14 UTC (rev 80)
@@ -0,0 +1,96 @@
+#region Copyright & License
+//
+// Copyright (c) 2005 - 2007 The Regents of the University of Washington, Intel
+// Research Seattle, and the Roam project. All rights reserved.
+//
+// This software is open-source under the BSD license. You may obtain a copy
+// of this license at
+//
+// http://roam.sourceforge.net/license.txt
+//
+// Alternatively, please see "license.txt" which should be included in
+// this source code distribution.
+//
+#endregion Copyright & License
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Roam.Utils
+{
+ /// <summary>
+ ///
+ /// </summary>
+ /// <remarks>
+ ///
+ /// </remarks>
+ /// <author>Jon Froehlich</author>
+ public static class WindowsConstants
+ {
+ //these values are found in winuser.h or through experimentation
+
+ #region Keys
+ /// <summary>
+ /// The WM_KEYDOWN message is posted to the window with the keyboard focus when a nonsystem key
+ /// is pressed. A nonsystem key is a key that is pressed when the ALT key is not pressed.
+ /// </summary>
+ public static int WM_KEYDOWN = 0x100;
+
+ /// <summary>
+ /// The WM_KEYUP message is posted to the window with the keyboard focus when a nonsystem key is released.
+ /// A nonsystem key is a key that is pressed when the ALT key is not pressed, or a keyboard key that
+ /// is pressed when a window has the keyboard focus.
+ /// </summary>
+ public static int WM_KEYUP = 0x0101;
+
+ /// <summary>
+ /// The WM_SYSKEYDOWN message is posted to the window with the keyboard focus when the user
+ /// presses the F10 key (which activates the menu bar) or holds down the ALT key and then
+ /// presses another key. It also occurs when no window currently has the keyboard focus;
+ /// in this case, the WM_SYSKEYDOWN message is sent to the active window. The window that
+ /// receives the message can distinguish between these two contexts by checking the context
+ /// code in the lParam parameter.
+ /// </summary>
+ public static int WM_SYSKEYDOWN = 0x104;
+
+ /// <summary>
+ /// The WM_SYSKEYUP message is posted to the window with the keyboard focus when the user
+ /// releases a key that was pressed while the ALT key was held down. It also occurs when no
+ /// window currently has the keyboard focus; in this case, the WM_SYSKEYUP message is sent
+ /// to the active window. The window that receives the message can distinguish between
+ /// these two contexts by checking the context code in the lParam parameter.
+ /// </summary>
+ public static int WM_SYSKEYUP = 0x105;
+
+ public static int WM_KEYPRESS = 0x010F;
+ public static int WM_HOTKEY = 0x0312;
+ #endregion Keys
+
+ #region Mouse
+ public static int WM_MOUSEMOVE = 0x0200;
+ public static int WM_LBUTTONDOWN = 0x0201;
+ public static int WM_LBUTTONUP = 0x0202;
+ public static int WM_LBUTTONDBLCLK = 0x0203;
+ public static int WM_RBUTTONDOWN = 0x0204;
+ public static int WM_RBUTTONUP = 0x0205;
+ public static int WM_RBUTTONDBLCLK = 0x0206;
+ public static int WM_MBUTTONDOWN = 0x0207;
+ public static int WM_MBUTTONUP = 0x0208;
+ public static int WM_MBUTTONDBLCLK = 0x0209;
+ public static int WM_MOUSELAST = 0x0209;
+ #endregion Mouse
+
+ public static byte VK_BACK = 0x08;
+ public static byte VK_ESCAPE = 0x1B;
+ public static byte VK_SHIFT = 0x10;
+ public static byte VK_CAPITAL = 0x14;
+ public static byte VK_NUMLOCK = 0x90;
+
+ public static int MOD_ALT = 0x0001;
+ public static int MOD_CONTROL = 0x0002;
+ public static int MOD_SHIFT = 0x0004;
+ public static int MOD_WIN = 0x0008;
+ public static int MOD_KEYUP = 0x1000;
+ }
+}
Added: Trunk/Source/Roam/Utils/WindowsHooks.cs
===================================================================
--- Trunk/Source/Roam/Utils/WindowsHooks.cs (rev 0)
+++ Trunk/Source/Roam/Utils/WindowsHooks.cs 2007-07-01 22:43:14 UTC (rev 80)
@@ -0,0 +1,229 @@
+#region Copyright & License
+//
+// Copyright (c) 2005 - 2007 The Regents of the University of Washington, Intel
+// Research Seattle, and the Roam project. All rights reserved.
+//
+// This software is open-source under the BSD license. You may obtain a copy
+// of this license at
+//
+// http://roam.sourceforge.net/license.txt
+//
+// Alternatively, please see "license.txt" which should be included in
+// this source code distribution.
+//
+#endregion Copyright & License
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Runtime.InteropServices;
+
+namespace Roam.Utils
+{
+ /// <summary>
+ ///
+ /// </summary>
+ /// <remarks>
+ ///
+ /// </remarks>
+ /// <author>Jon Froehlich</author>
+ [Flags]
+ public enum LowLevelKeyHookFlags : uint
+ {
+ /// <summary>
+ /// Specifies whether the key is an extended key, such as a function key or a key on the numeric keypad.
+ /// The value is 1 if the key is an extended key; otherwise, it is 0.
+ /// </summary>
+ LLKHF_EXTENDED = 0x00,
+
+ /// <summary>
+ /// Reserved.
+ /// </summary>
+ LLKHF_RESERVED1 = 0x01,
+
+ /// <summary>
+ /// Reserved.
+ /// </summary>
+ LLKHF_RESERVED2 = 0x02,
+
+ /// <summary>
+ /// Reserved.
+ /// </summary>
+ LLKHF_RESERVED3 = 0x03,
+
+ /// <summary>
+ /// Specifies whether the event was injected. The value is 1 if the event
+ /// was injected; otherwise, it is 0.
+ /// </summary>
+ LLKHF_INJECTED = 0x04,
+
+ /// <summary>
+ /// Specifies the context code. The value is 1 if the ALT key is pressed;
+ /// otherwise, it is 0.
+ /// </summary>
+ LLKHF_ALTDOWN = 0x05,
+
+ /// <summary>
+ /// Reserved.
+ /// </summary>
+ LLKHF_RESERVED4 = 0x06,
+
+ /// <summary>
+ /// Specifies the transition state. The value is 0 if the key is
+ /// pressed and 1 if it is being released.
+ /// </summary>
+ LLKHF_UP = 0x07
+ }
+
+ /// <summary>
+ /// As found in WinUser.h. Also, see SetWindowsHookEx documentation
+ ///
+ /// UPDATE: I found that the windows hook values listed in WinUser.h do _not_ actually
+ /// work in Windows Mobile. I empirically found that the WH_KEYBOARD_LL value is 20
+ /// by looping through codes from 1 onward. No other hook appears to work. I checked
+ /// all values up to around 800,000.
+ /// </summary>
+ /// <author>Jon Froehlich</author>
+ public enum WindowsHooks : int
+ {
+ //WH_MSGFILTER = -1,
+
+ /// <summary>
+ /// Installs a hook procedure that records input messages posted to the system message queue. This hook is useful for recording macros.
+ /// For more information, see the JournalRecordProc hook procedure.
+ /// </summary>
+ //WH_JOURNALRECORD = 0,
+
+ /// <summary>
+ /// Installs a hook procedure that posts messages previously recorded by a WH_JOURNALRECORD hook procedure.
+ /// For more information, see the JournalPlaybackProc hook procedure.
+ /// </summary>
+ //WH_JOURNALPLAYBACK = 1,
+
+ /// <summary>
+ /// Installs a hook procedure that monitors keystroke messages. For more information, see the KeyboardProc hook procedure.
+ /// </summary>
+ //WH_KEYBOARD = 2,
+
+ /// <summary>
+ /// Installs a hook procedure that monitors messages posted to a message queue. For more information, see the GetMsgProc hook procedure.
+ /// </summary>
+ //WH_GETMESSAGE = 3,
+
+ /// <summary>
+ /// Installs a hook procedure that monitors messages before the system sends them to
+ /// the destination window procedure. For more information, see the CallWndProc hook procedure.
+ /// </summary>
+ //WH_CALLWNDPROC = 4,
+
+ /// <summary>
+ /// Installs a hook procedure that receives notifications useful to a computer-based training (CBT) application.
+ /// For more information, see the CBTProc hook procedure.
+ /// </summary>
+ //WH_CBT = 5,
+
+ /// <summary>
+ /// Installs a hook procedure that monitors messages generated as a result of an input event
+ /// in a dialog box, message box, menu, or scroll bar. The hook procedure monitors these
+ /// messages for all applications in the same desktop as the calling thread.
+ /// For more information, see the SysMsgProc hook procedure.
+ /// </summary>
+ //WH_SYSMSGFILTER = 6,
+
+ /// <summary>
+ /// Installs a hook procedure that monitors mouse messages.
+ /// For more information, see the MouseProc hook procedure.
+ /// </summary>
+ //WH_MOUSE = 7,
+ //WH_HARDWARE = 8,
+
+ /// <summary>
+ /// Installs a hook procedure useful for debugging other hook procedures. For more
+ /// information, see the DebugProc hook procedure.
+ /// </summary>
+ //WH_DEBUG = 9,
+
+ /// <summary>
+ /// Installs a hook procedure that receives notifications useful to shell applications.
+ /// For more information, see the ShellProc hook procedure.
+ /// </summary>
+ //WH_SHELL = 10,
+
+ /// <summary>
+ /// Installs a hook procedure that will be called when the application's foreground thread is about to become idle.
+ /// This hook is useful for performing low priority tasks during idle time.
+ /// For more information, see the ForegroundIdleProc hook procedure.
+ /// </summary>
+ //WH_FOREGROUNDIDLE = 11,
+
+ /// <summary>
+ /// Installs a hook procedure that monitors messages after they have been processed by the destination window procedure.
+ /// For more information, see the CallWndRetProc hook procedure.
+ /// </summary>
+ //WH_CALLWNDPROCRET = 12,
+
+ /// <summary>
+ /// Windows NT/2000/XP: Installs a hook procedure that monitors low-level keyboard input events.
+ /// For more information, see the LowLevelKeyboardProc hook procedure.
+ /// </summary>
+ WH_KEYBOARD_LL = 20,
+
+ /// <summary>
+ /// Windows NT/2000/XP: Installs a hook procedure that monitors low-level mouse input events.
+ /// For more information, see the LowLevelMouseProc hook procedure.
+ /// </summary>
+ //WH_MOUSE_LL = 14
+ }
+
+ /// <summary>
+ /// The KBDLLHOOKSTRUCT structure contains information about a low-level keyboard input event.
+ /// </summary>
+ /// <remarks>
+ /// Declared in Winuser.h
+ /// </remarks>
+ /// <author>Jon Froehlich</author>
+ [StructLayout(LayoutKind.Sequential)]
+ public struct KBDLLHOOKSTRUCT
+ {
+ #region Fields
+ private int _vkCode;
+ private int _scanCode;
+ private LowLevelKeyHookFlags _flags;
+ private int _time;
+ private IntPtr _dwExtraInfo;
+ #endregion Fields
+
+ #region Properties
+ /// <summary>
+ /// Specifies a virtual-key code. The code must be a value in the range 1 to 254.
+ /// </summary>
+ public int VkCode { get { return _vkCode; } }
+
+ /// <summary>
+ /// Specifies a hardware scan code for the key.
+ /// </summary>
+ public int ScanCode { get { return _scanCode; } }
+
+ /// <summary>
+ /// Specifies the extended-key flag, event-injected flag, context code, and
+ /// transition-state flag.
+ /// </summary>
+ /// <remarks>
+ /// This member is specified as follows. An application can use
+ /// the following values to test the keystroke flags.
+ /// </remarks>
+ public LowLevelKeyHookFlags Flags { get { return _flags; } }
+
+ /// <summary>
+ /// Specifies the time stamp for this message, equivalent to what GetMessageTime
+ /// would return for this message. Note: I believe GetMessageTime is equivalent
+ /// to Environment.TickCount
+ /// </summary>
+ public int Time { get { return _time; } }
+
+ /// <summary>
+ /// Specifies extra information associated with the message.
+ /// </summary>
+ public IntPtr ExtraInfo { get { return _dwExtraInfo; } }
+ #endregion Properties
+ }
+}
Modified: Trunk/Source/Roam.Test/Roam.Test.csproj
===================================================================
--- Trunk/Source/Roam.Test/Roam.Test.csproj 2007-04-25 06:42:49 UTC (rev 79)
+++ Trunk/Source/Roam.Test/Roam.Test.csproj 2007-07-01 22:43:14 UTC (rev 80)
@@ -73,6 +73,7 @@
<Compile Include="Media\SoundLoopPlayerTest.Designer.cs">
<DependentUpon>SoundLoopPlayerTest.cs</DependentUpon>
</Compile>
+ <Compile Include="Sandbox\PhoneButtonManager.cs" />
<Compile Include="Sandbox\Camera.cs">
<SubType>Component</SubType>
</Compile>
@@ -128,6 +129,10 @@
<SubType>Designer</SubType>
<DependentUpon>AssemblyTest.cs</DependentUpon>
</EmbeddedResource>
+ <EmbeddedResource Include="Sandbox\PhoneButtonManagerTest.resx">
+ <SubType>Designer</SubType>
+ <DependentUpon>PhoneButtonManagerTest.cs</DependentUpon>
+ </EmbeddedResource>
<EmbeddedResource Include="Sandbox\ColorsTest.resx">
<SubType>Designer</SubType>
<DependentUpon>ColorsTest.cs</DependentUpon>
@@ -168,6 +173,10 @@
<SubType>Designer</SubType>
<DependentUpon>StarItemTest.cs</DependentUpon>
</EmbeddedResource>
+ <EmbeddedResource Include="Sandbox\TimeTest.resx">
+ <SubType>Designer</SubType>
+ <DependentUpon>TimeTest.cs</DependentUpon>
+ </EmbeddedResource>
<EmbeddedResource Include="Sandbox\TopMostFormTest.resx">
<SubType>Designer</SubType>
<DependentUpon>TopMostFormTest.cs</DependentUpon>
@@ -324,6 +333,14 @@
<SubType>Designer</SubType>
<DependentUpon>InsetsForm.cs</DependentUpon>
</EmbeddedResource>
+ <EmbeddedResource Include="Utils\KeySniffersTest.resx">
+ <SubType>Designer</SubType>
+ <DependentUpon>KeySniffersTest.cs</DependentUpon>
+ </EmbeddedResource>
+ <EmbeddedResource Include="Utils\KeySnifferTest.resx">
+ <SubType>Designer</SubType>
+ <DependentUpon>KeySnifferTest.cs</DependentUpon>
+ </EmbeddedResource>
<EmbeddedResource Include="Utils\MeasureStringTest.resx">
<SubType>Designer</SubType>
<DependentUpon>MeasureStringTest.cs</DependentUpon>
@@ -371,6 +388,12 @@
<Compile Include="Sandbox\MonthCalendarTest.Designer.cs">
<DependentUpon>MonthCalendarTest.cs</DependentUpon>
</Compile>
+ <Compile Include="Sandbox\PhoneButtonManagerTest.cs">
+ <SubType>Form</SubType>
+ </Compile>
+ <Compile Include="Sandbox\PhoneButtonManagerTest.Designer.cs">
+ <DependentUpon>PhoneButtonManagerTest.cs</DependentUpon>
+ </Compile>
<Compile Include="Sandbox\PhoneStateTest.cs">
<SubType>Form</SubType>
</Compile>
@@ -404,6 +427,12 @@
<Compile Include="Sandbox\TextBoxBackgroundTest.cs">
<SubType>Component</SubType>
</Compile>
+ <Compile Include="Sandbox\TimeTest.cs">
+ <SubType>Form</SubType>
+ </Compile>
+ <Compile Include="Sandbox\TimeTest.Designer.cs">
+ <DependentUpon>TimeTest.cs</DependentUpon>
+ </Compile>
<Compile Include="Sandbox\TopMostFormTest.cs">
<SubType>Form</SubType>
</Compile>
@@ -483,7 +512,7 @@
<DependentUpon>TextBoxFilteredListTest.cs</DependentUpon>
</Compile>
<Compile Include="UI\Controls\FontTest.cs">
- <SubType>Form</SubType>
+ <SubType>Component</SubType>
</Compile>
<Compile Include="UI\Controls\FontTest.Designer.cs">
<DependentUpon>FontTest.cs</DependentUpon>
@@ -621,7 +650,7 @@
<DependentUpon>SystemColorTest.cs</DependentUpon>
</Compile>
<Compile Include="UI\Controls\TabControlTest.cs">
- <SubType>Component</SubType>
+ <SubType>Form</SubType>
</Compile>
<Compile Include="UI\Controls\TabControlTest.Designer.cs">
<DependentUpon>TabControlTest.cs</DependentUpon>
@@ -674,6 +703,18 @@
<Compile Include="Utils\InsetsForm.Designer.cs">
<DependentUpon>InsetsForm.cs</DependentUpon>
</Compile>
+ <Compile Include="Utils\KeySniffersTest.cs">
+ <SubType>Form</SubType>
+ </Compile>
+ <Compile Include="Utils\KeySniffersTest.Designer.cs">
+ <DependentUpon>KeySniffersTest.cs</DependentUpon>
+ </Compile>
+ <Compile Include="Utils\KeySnifferTest.cs">
+ <SubType>Form</SubType>
+ </Compile>
+ <Compile Include="Utils\KeySnifferTest.Designer.cs">
+ <DependentUpon>KeySnifferTest.cs</DependentUpon>
+ </Compile>
<Compile Include="Utils\MeasureStringTest.cs">
<SubType>Form</SubType>
</Compile>
Added: Trunk/Source/Roam.Test/Sandbox/PhoneButtonManager.cs
===================================================================
--- Trunk/Source/Roam.Test/Sandbox/PhoneButtonManager.cs (rev 0)
+++ Trunk/Source/Roam.Test/Sandbox/PhoneButtonManager.cs 2007-07-01 22:43:14 UTC (rev 80)
@@ -0,0 +1,333 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Runtime.InteropServices;
+using System.Windows.Forms;
+
+namespace Roam.Test.Sandbox
+{
+ public class PhoneButtonManager
+ {
+ #region EventsDelegates
+
+ public delegate void PhoneButtonDelegate(PhoneButtonEventArgs args);
+ public static event PhoneButtonDelegate AnyButtonEvent;
+ public static event PhoneButtonDelegate EscapeButtonEvent;
+ public static event PhoneButtonDelegate LeftMenuButtonEvent;
+ public static event PhoneButtonDelegate RightMenuButtonEvent;
+
+ #endregion
+
+ #region Imports
+ private delegate int HookProc(int nCode, IntPtr wParam, IntPtr lParam);
+
+ //This is the Import for the SetWindowsHookEx function.
+ //Use this function to install a thread-specific hook.
+ [DllImport("coredll.dll", CharSet = CharSet.Auto,
+ CallingConvention = CallingConvention.Winapi)]
+ private static extern int SetWindowsHookEx(int idHook, HookProc lpfn,
+ IntPtr hInstance, int threadId);
+
+ //This is the Import for the UnhookWindowsHookEx function.
+ //Call this function to uninstall the hook.
+ [DllImport("coredll.dll", CharSet = CharSet.Auto,
+ CallingConvention = CallingConvention.Winapi)]
+ private static extern bool UnhookWindowsHookEx(int idHook);
+
+ //This is the Import for the CallNextHookEx function.
+ //Use this function to pass the hook information to the next hook procedure in chain.
+ [DllImport("coredll.dll", CharSet = CharSet.Auto,
+ CallingConvention = CallingConvention.Winapi)]
+ private static extern int CallNextHookEx(int idHook, int nCode,
+ IntPtr wParam, IntPtr lParam);
+
+ [DllImport("coredll.dll", CharSet = CharSet.Auto,
+ CallingConvention = CallingConvention.Winapi)]
+ private static extern IntPtr GetModuleHandle(string mod);
+
+#pragma warning disable 649
+ private struct KBDLLHOOKSTRUCT
+ {
+ public uint vkCode;
+ public uint scanCode;
+ public uint flags;
+ public uint time;
+ public IntPtr dwExtraInfo;
+ }
+#pragma warning restore 649
+
+ private const int WH_KEYBOARD = 2;
+ private const int WH_KEYBOARD_LL = 20;
+
+ #endregion Imports
+
+ #region Private
+
+ private static readonly log4net.ILog _log = log4net.LogManager.GetLogger(typeof(PhoneButtonManager));
+ private static int _hHook = 0;
+ private static HookProc _kbdHookProcedure;
+ private static bool _buttonActive = false;
+ private static bool _allowCamera = false;
+ private static uint _lastDownTime = 0;
+ private static uint _requiredButtonTime = 1500;
+ private static uint _requiredEscapeTime = 1000;
+ private static bool _bCameraDown = false;
+
+ private const int TRAPALL_STATE = 0;
+ private const int TRAPMENU_STATE = 1;
+ private const int TRAPNOTHING_STATE = 2;
+ private static int _state = TRAPNOTHING_STATE;
+
+ private const uint CAMERA = 196;
+ private const uint RECORDER = 204;
+ private const uint VOICEDIAL = 193;
+ private const uint ESC1 = RECORDER;
+ private const uint ESC2 = VOICEDIAL;
+
+ #endregion Private
+
+ #region Properties
+
+ public static bool IsTrappingAll
+ { get { return (_state == TRAPALL_STATE); } }
+
+ public static bool IsTrappingMenu
+ { get { return (_state == TRAPMENU_STATE); } }
+
+ public static bool IsTrappingNothing
+ { get { return (_state == TRAPNOTHING_STATE); } }
+
+
+ public static uint RequiredEscapeTime
+ {
+ get { return _requiredEscapeTime; }
+ set { _requiredEscapeTime = value; }
+ }
+
+ public static uint RequiredButtonTime
+ {
+ get { return _requiredButtonTime; }
+ set { _requiredButtonTime = value; }
+ }
+
+ public static bool AllowCamera
+ {
+ get { return _allowCamera; }
+ set { _allowCamera = value; }
+ }
+
+ #endregion Properties
+
+ #region Methods
+
+ public bool StartPhoneButtonManager()
+ {
+ if (_hHook == 0)
+ {
+ // Create an instance of HookProc.
+ _kbdHookProcedure = new HookProc(OnKbdHookEvent);
+
+ _hHook = SetWindowsHookEx(WH_KEYBOARD_LL,
+ _kbdHookProcedure,
+ GetModuleHandle(null),
+ 0);
+ }
+
+ return (_hHook != 0);
+ }
+
+ public void StopPhoneButtonManager()
+ {
+ if (_hHook != 0)
+ UnhookWindowsHookEx(_hHook);
+
+ _hHook = 0;
+ }
+
+ public static void EnterTrapAllMode()
+ { SetState(TRAPALL_STATE); }
+
+ public static void EnterTrapMenuMode()
+ { SetState(TRAPMENU_STATE); }
+
+ public static void EnterTrapNothingMode()
+ { SetState(TRAPNOTHING_STATE); }
+
+
+ #endregion Methods
+
+
+ private static void SetState(int iNewState)
+ {
+ _state = iNewState;
+ }
+
+ private static int OnKbdHookEvent(int nCode, IntPtr wParam, IntPtr lParam)
+ {
+ if (nCode < 0) // || _buttonActive)
+ return CallNextHookEx(_hHook, nCode, wParam, lParam);
+
+ KBDLLHOOKSTRUCT hookStruct = (KBDLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(KBDLLHOOKSTRUCT));
+ uint iVKCode = hookStruct.vkCode;
+ int iDirection = (wParam.ToInt32() == 257) ? 1 : -1;
+
+ if (iVKCode == CAMERA)
+ {
+ _bCameraDown = (iDirection < 0);
+ }
+ else if (iVKCode == ESC1 || iVKCode == ESC2)
+ {
+ //Check for escape button up action
+ if ((iDirection > 0) &&
+ ((hookStruct.time - _lastDownTime) >= _requiredEscapeTime))
+ {
+
+ if (!_buttonActive)
+ {
+ _buttonActive = true;
+
+ PhoneButtonEventArgs pbea = new PhoneButtonEventArgs(iVKCode, 1);
+ if (EscapeButtonEvent != null)
+ EscapeButtonEvent.Invoke(pbea);
+
+ _buttonActive = false;
+ }
+ }
+
+
+ return 1; // don't ever allow escape (up or down) to pass
+ }
+
+
+ if (_state != TRAPNOTHING_STATE)
+ {
+ // the camera button behaves differently than the others. If camera
+ // activity is allowed, then pass it through. Otherwise, forcefully block it
+ if (iVKCode == CAMERA)
+ {
+ // If the camera is special right now, allow all camera actions to pass
+ if (_allowCamera)
+ return CallNextHookEx(_hHook, nCode, wParam, lParam);
+ else
+ return 1;
+ }
+
+ // Stupid hack to fix problem with "bonus keys" when dealing with the camera
+ if (_allowCamera || _bCameraDown)
+ if (iVKCode == (uint)Keys.LWin || iVKCode == (uint)Keys.RWin ||
+ iVKCode == (uint)Keys.F21 || iVKCode == (uint)Keys.F23)
+ return 1;
+ }
+
+
+ // Now see if this was a button up and, if so, how long it's been
+ // since the last button down.
+ bool bDownLongEnough = false;
+ if (iDirection < 0)
+ _lastDownTime = hookStruct.time;
+ else
+ bDownLongEnough = ((hookStruct.time - _lastDownTime) >= _requiredButtonTime);
+
+ // look for Dpad, jog wheel, and enter keys
+ if (iVKCode == (uint)Keys.Left || iVKCode == (uint)Keys.Right ||
+ iVKCode == (uint)Keys.Up || iVKCode == (uint)Keys.Down ||
+ iVKCode == (uint)Keys.Enter)
+ {
+ if (bDownLongEnough && _state == TRAPALL_STATE)
+ {
+ if (!_buttonActive)
+ {
+ _buttonActive = true;
+
+ PhoneButtonEventArgs pbea = new PhoneButtonEventArgs(iVKCode, iDirection);
+ if (AnyButtonEvent != null)
+ AnyButtonEvent.Invoke(pbea);
+
+ _buttonActive = false;
+ }
+ }
+
+ // all direction and enter indicators pass to underlying OS
+ // regardless of state
+ return CallNextHookEx(_hHook, nCode, wParam, lParam);
+ }
+
+ // in system state, every thing passes (except escape as handled above
+ if (_state == TRAPNOTHING_STATE)
+ {
+ return CallNextHookEx(_hHook, nCode, wParam, lParam);
+ }
+
+ if (_state == TRAPALL_STATE)
+ {
+ if (bDownLongEnough) // implies iDirection == 1) // key up
+ {
+ //if ((iVKCode >= Keys.F1 && iVKCode <= Keys.F7) ||
+ // (iVKCode >= 193 && iVKCode <= 199))
+ if (iVKCode != (uint)Keys.LWin && iVKCode != (uint)Keys.RWin &&
+ iVKCode != (uint)Keys.F21 && iVKCode != (uint)Keys.F23 &&
+ iVKCode != (uint)RECORDER)
+ {
+ if (!_buttonActive)
+ {
+ _buttonActive = true;
+
+ PhoneButtonEventArgs pbea = new PhoneButtonEventArgs(iVKCode, 1);
+ if (AnyButtonEvent != null)
+ AnyButtonEvent.Invoke(pbea);
+
+ _buttonActive = false;
+ }
+ }
+ }
+
+ return 1;
+ }
+
+ //only manage up action of pseudo-menu keys in TRAP_MENU state
+ if ((_state == TRAPMENU_STATE) && (iDirection > 0)) // key up
+ {
+ if (iVKCode == (uint)Keys.LWin || iVKCode == (uint)Keys.F3 || iVKCode == (uint)Keys.F1)
+ {
+ //if (!_buttonActive)
+ {
+ //_buttonActive = true;
+
+ PhoneButtonEventArgs pbea = new PhoneButtonEventArgs(iVKCode, 1);
+ if (LeftMenuButtonEvent != null)
+ LeftMenuButtonEvent.Invoke(pbea);
+
+ //_buttonActive = false;
+ }
+ }
+ else if (iVKCode == (uint)Keys.RWin || iVKCode == (uint)Keys.F4 || iVKCode == (uint)Keys.F2)
+ {
+ //if (!_buttonActive)
+ {
+ //_buttonActive = true;
+
+ PhoneButtonEventArgs pbea = new PhoneButtonEventArgs(iVKCode, 1);
+ if (RightMenuButtonEvent != null)
+ RightMenuButtonEvent.Invoke(pbea);
+
+ //_buttonActive = false;
+ }
+ }
+ }
+
+ return 1;
+ }
+ }
+
+ // The class to hold the information about an event firing
+ public class PhoneButtonEventArgs : EventArgs
+ {
+ public PhoneButtonEventArgs(uint button, int direction)
+ {
+ this.button = button;
+ this.direction = direction;
+ }
+ public readonly uint button;
+ public readonly int direction;
+ }
+}
Added: Trunk/Source/Roam.Test/Sandbox/PhoneButtonManagerTest.Designer.cs
===================================================================
--- Trunk/Source/Roam.Test/Sandbox/PhoneButtonManagerTest.Designer.cs (rev 0)
+++ Trunk/Source/Roam.Test/Sandbox/PhoneButtonManagerTest.Designer.cs 2007-07-01 22:43:14 UTC (rev 80)
@@ -0,0 +1,90 @@
+namespace Roam.Test.Sandbox
+{
+ partial class PhoneButtonManagerTest
+ {
+ /// <summary>
+ /// Required designer variable.
+ /// </summary>
+ private System.ComponentModel.IContainer components = null;
+ private System.Windows.Forms.MainMenu mainMenu1;
+
+ /// <summary>
+ /// Clean up any resources being used.
+ /// </summary>
+ /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ /// <summary>
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ /// </summary>
+ private void InitializeComponent()
+ {
+ this.mainMenu1 = new System.Windows.Forms.MainMenu();
+ this.menuItem1 = new System.Windows.Forms.MenuItem();
+ this.menuItem2 = new System.Windows.Forms.MenuItem();
+ this._menuItemStartStop = new System.Windows.Forms.MenuItem();
+ this._scrollableLabel = new Roam.UI.Controls.ScrollableLabel();
+ this.SuspendLayout();
+ //
+ // mainMenu1
+ //
+ this.mainMenu1.MenuItems.Add(this.menuItem1);
+ this.mainMenu1.MenuItems.Add(this.menuItem2);
+ //
+ // menuItem1
+ //
+ this.menuItem1.Text = "Exit";
+ this.menuItem1.Click += new System.EventHandler(this.menuItem1_Click);
+ //
+ // menuItem2
+ //
+ this.menuItem2.MenuItems.Add(this._menuItemStartStop);
+ this.menuItem2.Text = "Menu";
+ //
+ // _menuItemStartStop
+ //
+ this._menuItemStartStop.Text = "Stop";
+ this._menuItemStartStop.Click += new System.EventHandler(this.menuItem3_Click);
+ //
+ // _scrollableLabel
+ //
+ this._scrollableLabel.Dock = System.Windows.Forms.DockStyle.Fill;
+ this._scrollableLabel.Font = new System.Drawing.Font("Segoe Condensed", 7F, System.Drawing.FontStyle.Regular);
+ this._scrollableLabel.Location = new System.Drawing.Point(0, 0);
+ this._scrollableLabel.Name = "_scrollableLabel";
+ this._scrollableLabel.Size = new System.Drawing.Size(240, 266);
+ this._scrollableLabel.TabIndex = 2;
+ this._scrollableLabel.Text = "scrollableLabel1";
+ //
+ // PhoneButtonManagerTest
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(131F, 131F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
+ this.AutoScroll = true;
+ this.ClientSize = new System.Drawing.Size(240, 266);
+ this.Controls.Add(this._scrollableLabel);
+ this.Menu = this.mainMenu1;
+ this.Name = "PhoneButtonManagerTest";
+ this.Text = "ButtonManagerTest";
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.MenuItem menuItem1;
+ private System.Windows.Forms.MenuItem menuItem2;
+ private System.Windows.Forms.MenuItem _menuItemStartStop;
+ private Roam.UI.Controls.ScrollableLabel _scrollableLabel;
+ }
+}
\ No newline at end of file
Added: Trunk/Source/Roam.Test/Sandbox/PhoneButtonManagerTest.cs
===================================================================
--- Trunk/Source/Roam.Test/Sandbox/PhoneButtonManagerTest.cs (rev 0)
+++ Trunk/Source/Roam.Test/Sandbox/PhoneButtonManagerTest.cs 2007-07-01 22:43:14 UTC (rev 80)
@@ -0,0 +1,67 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Text;
+using System.Windows.Forms;
+
+namespace Roam.Test.Sandbox
+{
+ public partial class PhoneButtonManagerTest : Form
+ {
+ PhoneButtonManager _phoneButtonManager = new PhoneButtonManager();
+
+ public PhoneButtonManagerTest()
+ {
+ PhoneButtonManager.LeftMenuButtonEvent += new PhoneButtonManager.PhoneButtonDelegate(PhoneButtonManager_LeftMenuButtonEvent);
+ PhoneButtonManager.EscapeButtonEvent += new PhoneButtonManager.PhoneButtonDelegate(PhoneButtonManager_EscapeButtonEvent);
+ PhoneButtonManager.AnyButtonEvent += new PhoneButtonManager.PhoneButtonDelegate(PhoneButtonManager_AnyButtonEvent);
+ PhoneButtonManager.RightMenuButtonEvent += new PhoneButtonManager.PhoneButtonDelegate(PhoneButtonManager_RightMenuButtonEvent);
+
+ _phoneButtonManager.StartPhoneButtonManager();
+ //PhoneButtonManager.EnterTrapAllMode();
+
+ InitializeComponent();
+ }
+
+ void PhoneButtonManager_RightMenuButtonEvent(PhoneButtonEventArgs args)
+ {
+ _scrollableLabel.AddLine("RMBE: btn: {0} dir: {1}", args.button, args.direction);
+ }
+
+ void PhoneButtonManager_AnyButtonEvent(PhoneButtonEventArgs args)
+ {
+ _scrollableLabel.AddLine("ABE: btn: {0} dir: {1}", args.button, args.direction);
+ }
+
+ void PhoneButtonManager_EscapeButtonEvent(PhoneButtonEventArgs args)
+ {
+ _scrollableLabel.AddLine("EBE: btn: {0} dir: {1}", args.button, args.direction);
+ }
+
+ private void PhoneButtonManager_LeftMenuButtonEvent(PhoneButtonEventArgs args)
+ {
+ _scrollableLabel.AddLine("LMBE: btn: {0} dir: {1}", args.button, args.direction);
+ }
+
+ private void menuItem1_Click(object sender, EventArgs e)
+ {
+ this.Close();
+ }
+
+ private void menuItem3_Click(object sender, EventArgs e)
+ {
+ if (_menuItemStartStop.Text == "Stop")
+ {
+ _menuItemStartStop.Text = "Start";
+ _phoneButtonManager.StopPhoneButtonManager();
+ }
+ else
+ {
+ _menuItemStartStop.Text = "Stop";
+ _phoneButtonManager.StartPhoneButtonManager();
+ }
+ }
+ }
+}
\ No newline at end of file
Added: Trunk/Source/Roam.Test/Sandbox/PhoneButtonManagerTest.resx
===================================================================
--- Trunk/Source/Roam.Test/Sandbox/PhoneButtonManagerTest.resx (rev 0)
+++ Trunk/Source/Roam.Test/Sandbox/PhoneButtonManagerTest.resx 2007-07-01 22:43:14 UTC (rev 80)
@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+ <!--
+ Microsoft ResX Schema
+
+ Version 2.0
+
+ The primary goals of this format is to allow a simple XML format
+ that is mostly human readable. The generation and parsing of the
+ various data types are done through the TypeConverter classes
+ associated with the data types.
+
+ Example:
+
+ ... ado.net/XML headers & schema ...
+ <resheader name="resmimetype">text/microsoft-resx</resheader>
+ <resheader name="version">2.0</resheader>
+ <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+ <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+ <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+ <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+ <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+ <value>[base64 mime encoded serialized .NET Framework object]</value>
+ </data>
+ <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+ <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+ <comment>This is a comment</comment>
+ </data>
+
+ There are any number of "resheader" rows that contain simple
+ name/value pairs.
+
+ Each data row contains a name, and value. The row also contains a
+ type or mimetype. Type corresponds to a .NET class that support
+ text/value conversion through the TypeConverter architecture.
+ Classes that don't support this are serialized and stored with the
+ mimetype set.
+
+ The mimetype is used for serialized objects, and tells the
+ ResXResourceReader how to depersist the object. This is currently not
+ extensible. For a given mimetype the value must be set accordingly:
+
+ Note - application/x-microsoft.net.object.binary.base64 is the format
+ that the ResXResourceWriter will generate, however the reader can
+ read any of the formats listed below.
+
+ mimetype: application/x-microsoft.net.object.binary.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.soap.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.bytearray.base64
+ value : The object must be serialized into a byte array
+ : using a System.ComponentModel.TypeConverter
+ : and then encoded with base64 encoding.
+ -->
+ <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+ <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+ <xsd:element name="root" msdata:IsDataSet="true">
+ <xsd:complexType>
+ <xsd:choice maxOccurs="unbounded">
+ <xsd:element name="metadata">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="name" use="required" type="xsd:string" />
+ <xsd:attribute name="type" type="xsd:string" />
+ <xsd:attribute name="mimetype" type="xsd:string" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="assembly">
+ <xsd:complexType>
+ <xsd:attribute name="alias" type="xsd:string" />
+ <xsd:attribute name="name" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="data">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+ <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+ <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="resheader">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:schema>
+ <resheader name="resmimetype">
+ <value>text/microsoft-resx</value>
+ </resheader>
+ <resheader name="version">
+ <value>2.0</value>
+ </resheader>
+ <resheader name="reader">
+ <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <resheader name="writer">
+ <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <metadata name="mainMenu1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+ <value>17, 17</value>
+ </metadata>
+ <metadata name="$this.FormFactorShadowProperty" xml:space="preserve">
+ <value>Smartphone QVGA</value>
+ </metadata>
+ <metadata name="$this.Skin" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <value>True</value>
+ </metadata>
+</root>
\ No newline at end of file
Added: Trunk/Source/Roam.Test/Sandbox/TimeTest.Designer.cs
===================================================================
--- Trunk/Source/Roam.Test/Sandbox/TimeTest.Designer.cs (rev 0)
+++ Trunk/Source/Roam.Test/Sandbox/TimeTest.Designer.cs 2007-07-01 22:43:14 UTC (rev 80)
@@ -0,0 +1,83 @@
+namespace Roam.Test.Sandbox
+{
+ partial class TimeTest
+ {
+ /// <summary>
+ /// Required designer variable.
+ /// </summary>
+ private System.ComponentModel.IContainer components = null;
+ private System.Windows.Forms.MainMenu mainMenu1;
+
+ /// <summary>
+ /// Clean up any resources being used.
+ /// </summary>
+ /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ /// <summary>
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ /// </summary>
+ private void InitializeComponent()
+ {
+ this.mainMenu1 = new System.Windows.Forms.MainMenu();
+ this.menuItem1 = new System.Windows.Forms.MenuItem();
+ this.menuItem2 = new System.Windows.Forms.MenuItem();
+ this.scrollableLabel1 = new Roam.UI.Controls.ScrollableLabel();
+ this.SuspendLayout();
+ //
+ // mainMenu1
+ //
+ this.mainMenu1.MenuItems.Add(this.menuItem1);
+ this.mainMenu1.MenuItems.Add(this.menuItem2);
+ //
+ // menuItem1
+ //
+ this.menuItem1.Text = "Exit";
+ this.menuItem1.Click += new System.EventHandler(this.menuItem1_Click);
+ //
+ // menuItem2
+ //
+ this.menuItem2.Text = "Refresh";
+ this.menuItem2.Click += new System.EventHandler(this.menuItem2_Click);
+ //
+ // scrollableLabel1
+ //
+ this.scrollableLabel1.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.scrollableLabel1.Font = new System.Drawing.Font("Segoe Condensed", 7F, System.Drawing.FontStyle.Regular);
+ this.scrollableLabel1.Location = new System.Drawing.Point(0, 0);
+ this.scrollableLabel1.Name = "scrollableLabel1";
+ this.scrollableLabel1.Size = new System.Drawing.Size(240, 266);
+ this.scrollableLabel1.TabIndex = 0;
+ this.scrollableLabel1.Text = "scrollableLabel1";
+ //
+ // TimeTest
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(131F, 131F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
+ this.AutoScroll = true;
+ this.ClientSize = new System.Drawing.Size(240, 266);
+ this.Controls.Add(this.scrollableLabel1);
+ this.Menu = this.mainMenu1;
+ this.Name = "TimeTest";
+ this.Text = "TimeTest";
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.MenuItem menuItem1;
+ private System.Windows.Forms.MenuItem menuItem2;
+ private Roam.UI.Controls.ScrollableLabel scrollableLabel1;
+ }
+}
\ No newline at end of file
Added: Trunk/Source/Roam.Test/Sandbox/TimeTest.cs
===================================================================
--- Trunk/Source/Roam.Test/Sandbox/TimeTest.cs (rev 0)
+++ Trunk/Source/Roam.Test/Sandbox/TimeTest.cs 2007-07-01 22:43:14 UTC (rev 80)
@@ -0,0 +1,63 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Text;
+using System.Windows.Forms;
+using Roam.Utils;
+
+namespace Roam.Test.Sandbox
+{
+ public partial class TimeTest : Form
+ {
+ int lastTickCount = 0;
+ DateTime lastDateTime;
+ long lastPerformanceCount = 0;
+
+ int curTickCount = 0;
+ DateTime curDateTime;
+ long curPerformanceCount = 0;
+
+ public TimeTest()
+ {
+ InitializeComponent();
+ scrollableLabel1.Text = "";
+ TakeTimeSnapshot();
+ }
+
+ private void TakeTimeSnapshot()
+ {
+ lastTickCount = curTickCount;
+ lastDateTime = curDateTime;
+ lastPerformanceCount = curPerformanceCount;
+
+ curTickCount = Environment.TickCount;
+ curDateTime = DateTime.Now;
+ curPerformanceCount = PerformanceUtils.GetTimestampMs();
+ }
+
+ private void menuItem1_Click(object sender, EventArgs e)
+ {
+ this.Close();
+ }
+
+ private void menuItem2_Click(object sender, EventArgs e)
+ {
+ TakeTimeSnapshot();
+ scrollableLabel1.AddLine("TickCountDiffMs: {0} RawCurrent: {1}", (curTickCount - lastTickCount), curTickCount);
+ scrollableLabel1.AddLine("DateTimeDiffMs: {0} RawCurrent: {1}", ((TimeSpan)(curDateTime - lastDateTime)).TotalMilliseconds, curDateTime);
+ scrollableLabel1.AddLine("PerformanceCountDiffMs: {0} RawCurrent: {1}", (curPerformanceCount - lastPerformanceCount), curPerformanceCount);
+
+ //The value of this property represents the number of 100-nanosecond intervals that have elapsed since 12:00:00 midnight, January 1, 0001.
+ // 100 nanoseconds
+ // 100 x 10-9 seconds
+ // 100 x 10-6 milliseconds
+ // 10 x 10-5 milliseconds
+ // 100 nanoseconds x 1 microseconds x 1 millisecond = 100/1000000 millseconds = 1/10000
+ // ---- ----
+ // 1000 nanoseconds 1000 microseconds
+ scrollableLabel1.AddLine("TicksDiffMs: {0} RawCurrent: {1}", (curDateTime.Ticks - lastDateTime.Ticks) / 10000, curDateTime.Ticks);
+ }
+ }
+}
\ No newline at end of file
Added: Trunk/Source/Roam.Test/Sandbox/TimeTest.resx
===================================================================
--- Trunk/Source/Roam.Test/Sandbox/TimeTest.resx (rev 0)
+++ Trunk/Source/Roam.Test/Sandbox/TimeTest.resx 2007-07-01 22:43:14 UTC (rev 80)
@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+ <!--
+ Microsoft ResX Schema
+
+ Version 2.0
+
+ The primary goals of this format is to allow a simple XML format
+ that is mostly human readable. The generation and parsing of the
+ various data types are done through the TypeConverter classes
+ associated with the data types.
+
+ Example:
+
+ ... ado.net/XML headers & schema ...
+ <resheader name="resmimetype">text/microsoft-resx</resheader>
+ <resheader name="version">2.0</resheader>
+ <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+ <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+ <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+ <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+ <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+ <value>[base64 mime encoded serialized .NET Framework object]</value>
+ </data>
+ <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+ <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+ <comment>This is a comment</comment>
+ </data>
+
+ There are any number of "resheader" rows that contain simple
+ name/value pairs.
+
+ Each data row contains a name, and value. The row also contains a
+ type or mimetype. Type corresponds to a .NET class that support
+ text/value conversion through the TypeConverter architecture.
+ Classes that don't support this are serialized and stored with the
+ mimetype set.
+
+ The mimetype is used for serialized objects, and tells the
+ ResXResourceReader how to depersist the object. This is currently not
+ extensible. For a given mimetype the value must be set accordingly:
+
+ Note - applicat...
[truncated message content] |