Updated HotKey management and registration.

Added HotKey settings to settings side panel.
String resource update for new settings panel.
This commit is contained in:
Lorenz Cuno Klopfenstein 2011-03-27 22:12:02 +02:00
parent 3ad9a6eb11
commit 34a190dbde
18 changed files with 1010 additions and 697 deletions

View file

@ -0,0 +1,55 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
namespace OnTopReplica {
class HotKeyTextBox : TextBox {
protected override void OnCreateControl() {
ReadOnly = true;
base.OnCreateControl();
}
readonly Keys[] IgnoredKeys = new Keys[] {
Keys.ControlKey,
Keys.Control,
Keys.Alt,
Keys.Menu,
Keys.ShiftKey,
Keys.Shift,
Keys.LWin,
Keys.RWin
};
readonly Keys[] CancelKeys = new Keys[] {
Keys.Back,
Keys.Escape
};
protected override void OnKeyUp(KeyEventArgs e) {
if (CancelKeys.Contains(e.KeyCode)) {
Text = string.Empty;
}
else if (!IgnoredKeys.Contains(e.KeyCode)) {
var sb = new StringBuilder();
if (e.Control)
sb.Append("[CTRL]+");
if (e.Alt)
sb.Append("[ALT]+");
if (e.Shift)
sb.Append("[SHIFT]+");
sb.Append(e.KeyCode.ToString());
Text = sb.ToString();
}
e.Handled = true;
base.OnKeyUp(e);
}
}
}

View file

@ -56,13 +56,6 @@ namespace OnTopReplica {
//Init message pump extensions
_msgPumpManager.Initialize(this);
//Add hotkeys
var hotKeyMgr = _msgPumpManager.Get<MessagePumpProcessors.HotKeyManager>();
hotKeyMgr.RegisterHotKey(Native.HotKeyModifiers.Control | Native.HotKeyModifiers.Shift,
Keys.O, new Native.HotKeyMethods.HotKeyHandler(HotKeyOpenHandler));
hotKeyMgr.RegisterHotKey(Native.HotKeyModifiers.Control | Native.HotKeyModifiers.Shift,
Keys.C, new Native.HotKeyMethods.HotKeyHandler(HotKeyCloneHandler));
//Set to Key event preview
this.KeyPreview = true;
}
@ -280,26 +273,6 @@ namespace OnTopReplica {
}
}
void HotKeyOpenHandler() {
if (IsFullscreen)
IsFullscreen = false;
if (!Program.Platform.IsHidden(this)) {
Program.Platform.HideForm(this);
}
else {
EnsureMainFormVisible();
}
}
void HotKeyCloneHandler() {
var handle = Win32Helper.GetCurrentForegroundWindow();
if (handle.Handle == this.Handle)
return;
SetThumbnail(handle, null);
}
#endregion
#region Fullscreen

View file

@ -10,7 +10,7 @@ namespace OnTopReplica.MessagePumpProcessors {
#region IMessagePumpProcessor Members
public void Initialize(MainForm form) {
public virtual void Initialize(MainForm form) {
Form = form;
}
@ -18,10 +18,10 @@ namespace OnTopReplica.MessagePumpProcessors {
#endregion
bool _isDisposed = false;
protected abstract void Shutdown();
bool _isDisposed = false;
#region IDisposable Members
public void Dispose() {

View file

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using OnTopReplica.Native;
using OnTopReplica.Properties;
namespace OnTopReplica.MessagePumpProcessors {
@ -11,40 +12,156 @@ namespace OnTopReplica.MessagePumpProcessors {
/// </summary>
class HotKeyManager : BaseMessagePumpProcessor {
int _lastUsedKey = 0;
public HotKeyManager() {
Enabled = true;
}
Dictionary<int, HotKeyMethods.HotKeyHandler> _handlers = new Dictionary<int, HotKeyMethods.HotKeyHandler>();
delegate void HotKeyHandler();
public void RegisterHotKey(HotKeyModifiers mod, Keys keys, HotKeyMethods.HotKeyHandler handler) {
var newKey = ++_lastUsedKey;
if (!HotKeyMethods.RegisterHotKey(Form.Handle, newKey, (int)mod, (int)keys)) {
Console.Error.WriteLine("Failed to register {0} hot key.", newKey);
return;
/// <summary>
/// Wraps hot key handler registration data.
/// </summary>
private class HotKeyHandlerRegistration : IDisposable {
private HotKeyHandlerRegistration() {
}
_handlers[newKey] = handler;
private HotKeyHandlerRegistration(IntPtr hwnd, int key, HotKeyHandler handler) {
if (hwnd == IntPtr.Zero)
throw new ArgumentException();
if (handler == null)
throw new ArgumentNullException();
_hwnd = hwnd;
RegistrationKey = key;
Handler = handler;
}
static int _lastUsedKey = 0;
/// <summary>
/// Registers a new hotkey and returns a handle to the registration.
/// </summary>
/// <returns>Returns null on failure.</returns>
public static HotKeyHandlerRegistration Register(Form owner, int keyCode, int modifiers, HotKeyHandler handler) {
var key = ++_lastUsedKey;
if (!HotKeyMethods.RegisterHotKey(owner.Handle, key, modifiers, keyCode)) {
Console.Error.WriteLine("Failed to create hotkey on keys {0}.", keyCode);
return null;
}
return new HotKeyHandlerRegistration(owner.Handle, key, handler);
}
IntPtr _hwnd;
public int RegistrationKey { get; private set; }
public HotKeyHandler Handler { get; private set; }
public void Dispose() {
if (!HotKeyMethods.UnregisterHotKey(_hwnd, RegistrationKey)) {
Console.Error.WriteLine("Failed to unregister hotkey #{0}.", RegistrationKey);
}
}
}
Dictionary<int, HotKeyHandlerRegistration> _handlers = new Dictionary<int, HotKeyHandlerRegistration>();
public override void Initialize(MainForm form) {
base.Initialize(form);
RefreshHotkeys();
}
public override bool Process(ref Message msg) {
if (msg.Msg == HotKeyMethods.WM_HOTKEY) {
if (Enabled && msg.Msg == HotKeyMethods.WM_HOTKEY) {
int keyId = msg.WParam.ToInt32();
if (!_handlers.ContainsKey(keyId))
return false;
_handlers[keyId].Invoke();
_handlers[keyId].Handler.Invoke();
}
return false;
}
public bool Enabled { get; set; }
/// <summary>
/// Refreshes registered hotkeys from Settings.
/// </summary>
/// <remarks>
/// Application settings contain hotkey registration strings that are used
/// automatically by this registration process.
/// </remarks>
public void RefreshHotkeys() {
ClearHandlers();
RegisterHandler(Settings.Default.HotKeyCloneCurrent, HotKeyCloneHandler);
RegisterHandler(Settings.Default.HotKeyShowHide, HotKeyShowHideHandler);
}
private void RegisterHandler(string spec, HotKeyHandler handler) {
if (string.IsNullOrEmpty(spec))
return; //this can happen and is allowed => simply don't register
if (handler == null)
throw new ArgumentNullException();
int modifiers = 0, keyCode = 0;
try {
HotKeyMethods.TranslateStringToKeyValues(spec, out modifiers, out keyCode);
}
catch (ArgumentException) {
//TODO: swallowed exception
return;
}
var reg = HotKeyHandlerRegistration.Register(Form, keyCode, modifiers, handler);
_handlers.Add(reg.RegistrationKey, reg);
}
private void ClearHandlers() {
foreach (var hotkey in _handlers) {
hotkey.Value.Dispose();
}
_handlers.Clear();
}
protected override void Shutdown() {
foreach (var key in _handlers.Keys) {
if (!HotKeyMethods.UnregisterHotKey(Form.Handle, key)) {
Console.Error.WriteLine("Failed to unregister {0} hot key.", key);
}
ClearHandlers();
}
#region Hotkey callbacks
/// <summary>
/// Handles "show/hide" hotkey. Ensures the form is in restored state and switches
/// between shown and hidden states.
/// </summary>
void HotKeyShowHideHandler() {
if (Form.IsFullscreen)
Form.IsFullscreen = false;
if (!Program.Platform.IsHidden(Form)) {
Program.Platform.HideForm(Form);
}
else {
Form.EnsureMainFormVisible();
}
}
/// <summary>
/// Handles the "clone current" hotkey.
/// </summary>
void HotKeyCloneHandler() {
var handle = Win32Helper.GetCurrentForegroundWindow();
if (handle.Handle == Form.Handle)
return;
Form.SetThumbnail(handle, null);
}
#endregion
}
}

View file

@ -15,6 +15,7 @@ namespace OnTopReplica.MessagePumpProcessors {
if (Form.CurrentThumbnailWindowHandle != null &&
msg.Msg == HookMethods.WM_SHELLHOOKMESSAGE) {
int hookCode = msg.WParam.ToInt32();
if (hookCode == HookMethods.HSHELL_WINDOWDESTROYED) {
//Check whether the destroyed window is the one we were cloning
IntPtr destroyedHandle = msg.LParam;

View file

@ -14,10 +14,11 @@ namespace OnTopReplica.Native {
Windows = 0x8
}
/// <summary>
/// Static native methods for HotKey management.
/// </summary>
static class HotKeyMethods {
public delegate void HotKeyHandler();
public const int WM_HOTKEY = 0x312;
[DllImport("user32.dll")]
@ -26,7 +27,52 @@ namespace OnTopReplica.Native {
[DllImport("user32.dll")]
public static extern bool UnregisterHotKey(IntPtr hWnd, int id);
public delegate void FormDelegate(HotKeyModifiers mod, Keys key, HotKeyHandler handler);
/// <summary>
/// Translates a key combination specification into key code values.
/// </summary>
/// <param name="hotkeySpec">Key combination specification (see remarks).</param>
/// <param name="modifiers">Modifier values.</param>
/// <param name="keys">Key values.</param>
/// <remarks>
/// Specification can contain one single key value (from the enumeration System.Windows.Forms.Keys)
/// preceded by modifier strings (each one separated by a single '+').
/// For instance:
/// [CTRL]+[ALT]+A
/// or
/// [ALT]+[SHIFT]+O
/// </remarks>
public static void TranslateStringToKeyValues(string hotkeySpec, out int modifiers, out int keys) {
if (string.IsNullOrEmpty(hotkeySpec))
throw new ArgumentNullException();
modifiers = 0;
keys = 0;
if (ExtractModifier(ref hotkeySpec, "[CTRL]+"))
modifiers |= (int)HotKeyModifiers.Control;
if (ExtractModifier(ref hotkeySpec, "[ALT]+"))
modifiers |= (int)HotKeyModifiers.Alt;
if (ExtractModifier(ref hotkeySpec, "[SHIFT]+"))
modifiers |= (int)HotKeyModifiers.Shift;
//Attempt to translate last part (should be single key)
try {
var keyValue = Enum.Parse(typeof(Keys), hotkeySpec, true);
keys = (int)keyValue;
}
catch (ArgumentException) {
throw new ArgumentException("Couldn't parse key value '" + hotkeySpec + "'.");
}
}
private static bool ExtractModifier(ref string spec, string modifier) {
int modIndex = spec.IndexOf(modifier);
if (modIndex == -1)
return false;
spec = spec.Remove(modIndex, modifier.Length);
return true;
}
}
}

View file

@ -115,6 +115,9 @@
<Compile Include="EnumerableExtensions.cs" />
<Compile Include="ExtensionAttribute.cs" />
<Compile Include="GeometryExtensions.cs" />
<Compile Include="HotKeyTextBox.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="ImageComboBox.cs">
<SubType>Component</SubType>
</Compile>
@ -206,7 +209,6 @@
<Compile Include="StoredRegionComparer.cs" />
<Compile Include="Native\WindowsSevenMethods.cs" />
<None Include="Native\CommonControls.cs" />
<Compile Include="EnumerationExtensions.cs" />
<Compile Include="MessagePumpProcessors\HotKeyManager.cs" />
<Compile Include="PlatformSupport.cs" />
<Compile Include="Platforms\Other.cs" />

View file

@ -201,5 +201,29 @@ namespace OnTopReplica.Properties {
this["RestoreLastWindowHwnd"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("[CTRL]+[SHIFT]+C")]
public string HotKeyCloneCurrent {
get {
return ((string)(this["HotKeyCloneCurrent"]));
}
set {
this["HotKeyCloneCurrent"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("[CTRL]+[SHIFT]+O")]
public string HotKeyShowHide {
get {
return ((string)(this["HotKeyShowHide"]));
}
set {
this["HotKeyShowHide"] = value;
}
}
}
}

View file

@ -47,5 +47,11 @@
<Setting Name="RestoreLastWindowHwnd" Type="System.Int64" Scope="User">
<Value Profile="(Default)">0</Value>
</Setting>
<Setting Name="HotKeyCloneCurrent" Type="System.String" Scope="User">
<Value Profile="(Default)">[CTRL]+[SHIFT]+C</Value>
</Setting>
<Setting Name="HotKeyShowHide" Type="System.String" Scope="User">
<Value Profile="(Default)">[CTRL]+[SHIFT]+O</Value>
</Setting>
</Settings>
</SettingsFile>

View file

@ -25,10 +25,17 @@
private void InitializeComponent() {
this.btnClose = new System.Windows.Forms.Button();
this.panelMain = new System.Windows.Forms.Panel();
this.groupHotkeys = new System.Windows.Forms.GroupBox();
this.label1 = new System.Windows.Forms.Label();
this.lblHotKeyShowHide = new System.Windows.Forms.Label();
this.txtHotKeyShowHide = new OnTopReplica.HotKeyTextBox();
this.lblHotKeyClone = new System.Windows.Forms.Label();
this.txtHotKeyClone = new OnTopReplica.HotKeyTextBox();
this.groupLanguage = new System.Windows.Forms.GroupBox();
this.comboLanguage = new OnTopReplica.ImageComboBox();
this.lblLanguage = new System.Windows.Forms.Label();
this.panelMain.SuspendLayout();
this.groupHotkeys.SuspendLayout();
this.groupLanguage.SuspendLayout();
this.SuspendLayout();
//
@ -39,7 +46,7 @@
this.btnClose.Name = "btnClose";
this.btnClose.Size = new System.Drawing.Size(75, 23);
this.btnClose.TabIndex = 0;
this.btnClose.Text = "Close";
this.btnClose.Text = Strings.MenuClose;
this.btnClose.UseVisualStyleBackColor = true;
this.btnClose.Click += new System.EventHandler(this.Close_click);
//
@ -49,12 +56,77 @@
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.panelMain.AutoScroll = true;
this.panelMain.Controls.Add(this.groupHotkeys);
this.panelMain.Controls.Add(this.groupLanguage);
this.panelMain.Location = new System.Drawing.Point(0, 0);
this.panelMain.Name = "panelMain";
this.panelMain.Size = new System.Drawing.Size(260, 211);
this.panelMain.TabIndex = 1;
//
// groupHotkeys
//
this.groupHotkeys.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.groupHotkeys.Controls.Add(this.label1);
this.groupHotkeys.Controls.Add(this.lblHotKeyShowHide);
this.groupHotkeys.Controls.Add(this.txtHotKeyShowHide);
this.groupHotkeys.Controls.Add(this.lblHotKeyClone);
this.groupHotkeys.Controls.Add(this.txtHotKeyClone);
this.groupHotkeys.Location = new System.Drawing.Point(3, 77);
this.groupHotkeys.Name = "groupHotkeys";
this.groupHotkeys.Size = new System.Drawing.Size(254, 113);
this.groupHotkeys.TabIndex = 1;
this.groupHotkeys.TabStop = false;
this.groupHotkeys.Text = Strings.SettingsHotKeyTitle;
//
// label1
//
this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.label1.Location = new System.Drawing.Point(6, 68);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(158, 43);
this.label1.TabIndex = 4;
this.label1.Text = Strings.SettingsHotKeyDescription;
//
// lblHotKeyShowHide
//
this.lblHotKeyShowHide.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.lblHotKeyShowHide.Location = new System.Drawing.Point(170, 22);
this.lblHotKeyShowHide.Name = "lblHotKeyShowHide";
this.lblHotKeyShowHide.Size = new System.Drawing.Size(78, 17);
this.lblHotKeyShowHide.TabIndex = 3;
this.lblHotKeyShowHide.Text = Strings.SettingsHotKeyShowHide;
//
// txtHotKeyShowHide
//
this.txtHotKeyShowHide.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.txtHotKeyShowHide.Location = new System.Drawing.Point(6, 19);
this.txtHotKeyShowHide.Name = "txtHotKeyShowHide";
this.txtHotKeyShowHide.ReadOnly = true;
this.txtHotKeyShowHide.Size = new System.Drawing.Size(158, 20);
this.txtHotKeyShowHide.TabIndex = 2;
//
// lblHotKeyClone
//
this.lblHotKeyClone.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.lblHotKeyClone.Location = new System.Drawing.Point(170, 48);
this.lblHotKeyClone.Name = "lblHotKeyClone";
this.lblHotKeyClone.Size = new System.Drawing.Size(78, 29);
this.lblHotKeyClone.TabIndex = 1;
this.lblHotKeyClone.Text = Strings.SettingsHotKeyClone;
//
// txtHotKeyClone
//
this.txtHotKeyClone.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.txtHotKeyClone.Location = new System.Drawing.Point(6, 45);
this.txtHotKeyClone.Name = "txtHotKeyClone";
this.txtHotKeyClone.ReadOnly = true;
this.txtHotKeyClone.Size = new System.Drawing.Size(158, 20);
this.txtHotKeyClone.TabIndex = 0;
//
// groupLanguage
//
this.groupLanguage.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
@ -66,10 +138,12 @@
this.groupLanguage.Size = new System.Drawing.Size(254, 68);
this.groupLanguage.TabIndex = 0;
this.groupLanguage.TabStop = false;
this.groupLanguage.Text = "Language:";
this.groupLanguage.Text = Strings.SettingsLanguageTitle;
//
// comboLanguage
//
this.comboLanguage.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.comboLanguage.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawFixed;
this.comboLanguage.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.comboLanguage.FormattingEnabled = true;
@ -86,9 +160,9 @@
| System.Windows.Forms.AnchorStyles.Right)));
this.lblLanguage.Location = new System.Drawing.Point(6, 43);
this.lblLanguage.Name = "lblLanguage";
this.lblLanguage.Size = new System.Drawing.Size(242, 23);
this.lblLanguage.Size = new System.Drawing.Size(242, 22);
this.lblLanguage.TabIndex = 1;
this.lblLanguage.Text = "Requires a restart.";
this.lblLanguage.Text = Strings.SettingsRestartRequired;
//
// OptionsPanel
//
@ -101,6 +175,8 @@
this.Name = "OptionsPanel";
this.Size = new System.Drawing.Size(260, 240);
this.panelMain.ResumeLayout(false);
this.groupHotkeys.ResumeLayout(false);
this.groupHotkeys.PerformLayout();
this.groupLanguage.ResumeLayout(false);
this.ResumeLayout(false);
@ -113,5 +189,11 @@
private System.Windows.Forms.GroupBox groupLanguage;
private System.Windows.Forms.Label lblLanguage;
private ImageComboBox comboLanguage;
private System.Windows.Forms.GroupBox groupHotkeys;
private HotKeyTextBox txtHotKeyClone;
private System.Windows.Forms.Label lblHotKeyShowHide;
private HotKeyTextBox txtHotKeyShowHide;
private System.Windows.Forms.Label lblHotKeyClone;
private System.Windows.Forms.Label label1;
}
}

View file

@ -13,8 +13,17 @@ namespace OnTopReplica.SidePanels {
public OptionsPanel() {
InitializeComponent();
}
public override void OnFirstShown(MainForm form) {
base.OnFirstShown(form);
PopulateLanguageComboBox();
//Stop hotkey handling and load current shortcuts
form.MessagePumpManager.Get<OnTopReplica.MessagePumpProcessors.HotKeyManager>().Enabled = false;
txtHotKeyShowHide.Text = Settings.Default.HotKeyShowHide;
txtHotKeyClone.Text = Settings.Default.HotKeyCloneCurrent;
}
private void Close_click(object sender, EventArgs e) {
@ -23,18 +32,40 @@ namespace OnTopReplica.SidePanels {
public override string Title {
get {
return Strings.MenuSettings;
return Strings.SettingsTitle;
}
}
public override void OnClosing(MainForm form) {
base.OnClosing(form);
//Update hotkey settings and update processor
Settings.Default.HotKeyShowHide = txtHotKeyShowHide.Text;
Settings.Default.HotKeyCloneCurrent = txtHotKeyClone.Text;
var manager = form.MessagePumpManager.Get<OnTopReplica.MessagePumpProcessors.HotKeyManager>();
manager.RefreshHotkeys();
manager.Enabled = true;
}
#region Language
Pair<CultureInfo, Image>[] _languageList = {
new Pair<CultureInfo, Image>(new CultureInfo("en-US"), Resources.flag_usa),
new Pair<CultureInfo, Image>(new CultureInfo("it-IT"), Resources.flag_ita),
new Pair<CultureInfo, Image>(new CultureInfo("cs-CZ"), Resources.flag_czech),
new Pair<CultureInfo, Image>(new CultureInfo("da-DK"), Resources.flag_danish),
new Pair<CultureInfo, Image>(new CultureInfo("es-ES"), Resources.flag_spanish),
class CultureWrapper {
public CultureWrapper(string name, CultureInfo culture, Image img) {
Culture = culture;
Image = img;
Name = name;
}
public CultureInfo Culture { get; set; }
public Image Image { get; set; }
public string Name { get; set; }
}
CultureWrapper[] _languageList = {
new CultureWrapper("English", new CultureInfo("en-US"), Resources.flag_usa),
new CultureWrapper("Italiano", new CultureInfo("it-IT"), Resources.flag_ita),
new CultureWrapper("Čeština", new CultureInfo("cs-CZ"), Resources.flag_czech),
new CultureWrapper("Dansk", new CultureInfo("da-DK"), Resources.flag_danish),
new CultureWrapper("Español", new CultureInfo("es-ES"), Resources.flag_spanish),
};
private void PopulateLanguageComboBox() {
@ -48,18 +79,21 @@ namespace OnTopReplica.SidePanels {
int selectedIndex = -1;
foreach (var langPair in _languageList) {
var item = new ImageComboBoxItem(langPair.Item1.NativeName, imageList.Images.Count) {
Tag = langPair.Item1
var item = new ImageComboBoxItem(langPair.Name, imageList.Images.Count) {
Tag = langPair.Culture
};
imageList.Images.Add(langPair.Item2);
imageList.Images.Add(langPair.Image);
comboLanguage.Items.Add(item);
if (langPair.Item1.Equals(CultureInfo.CurrentUICulture) ||
(CultureInfo.CurrentUICulture.Equals(CultureInfo.InvariantCulture) && langPair.Item1.TwoLetterISOLanguageName.Equals("en"))) {
if (langPair.Culture.Equals(CultureInfo.CurrentUICulture)) {
selectedIndex = comboLanguage.Items.Count - 1;
}
}
//Handle case when there is not explicitly set culture (default to first one, i.e. english)
if (CultureInfo.CurrentUICulture.Equals(CultureInfo.InvariantCulture))
selectedIndex = 0;
comboLanguage.SelectedIndex = selectedIndex;
}

View file

@ -97,40 +97,40 @@ namespace OnTopReplica {
}
/// <summary>
/// Looks up a localized string similar to &lt;html&gt;
/// &lt;head&gt;
/// &lt;style type=&quot;text/css&quot;&gt;
///body {
/// font-family: Segoe UI, Arial, sans-serif;
/// font-size: 0.8em;
/// margin: 0;
///padding: 0.75em;
///}
///h1 {
/// font-size: 1.4em;
/// font-weight: bold;
///
/// margin: 1em 0 0.4em 0;
/// padding: 0;
///}
///p {
/// margin: 0.5em 0 0.5em 1em;
/// padding: 0;
///}
///a {
/// font-weight: bold;
/// color: blue;
///}
///a:hover {
/// color: red;
///}
/// &lt;/style&gt;
/// &lt;/head&gt;
///
/// &lt;body&gt;
///
/// &lt;h1&gt;License&lt;/h1&gt;
///
/// Looks up a localized string similar to &lt;html&gt;
/// &lt;head&gt;
/// &lt;style type=&quot;text/css&quot;&gt;
///body {
/// font-family: Segoe UI, Arial, sans-serif;
/// font-size: 0.8em;
/// margin: 0;
///padding: 0.75em;
///}
///h1 {
/// font-size: 1.4em;
/// font-weight: bold;
///
/// margin: 1em 0 0.4em 0;
/// padding: 0;
///}
///p {
/// margin: 0.5em 0 0.5em 1em;
/// padding: 0;
///}
///a {
/// font-weight: bold;
/// color: blue;
///}
///a:hover {
/// color: red;
///}
/// &lt;/style&gt;
/// &lt;/head&gt;
///
/// &lt;body&gt;
///
/// &lt;h1&gt;License&lt;/h1&gt;
///
/// &lt;p&gt;&lt;b&gt;OnTopReplica&lt;/b&gt; is licensed under the &lt;a href=&quot;http://opensource.org/licenses/ms-rl.html&quot;&gt;Microsoft Reciprocal [rest of string was truncated]&quot;;.
/// </summary>
internal static string AboutDetails {
@ -158,7 +158,7 @@ namespace OnTopReplica {
}
/// <summary>
/// Looks up a localized string similar to &amp;Reset
/// Looks up a localized string similar to &amp;Reset
///All settings will be lost..
/// </summary>
internal static string AskResetButtonOk {
@ -222,7 +222,7 @@ namespace OnTopReplica {
}
/// <summary>
/// Looks up a localized string similar to Cancel update
/// Looks up a localized string similar to Cancel update
///OnTopReplica will prompt you the next time it is started..
/// </summary>
internal static string AskUpdateButtonCancel {
@ -232,7 +232,7 @@ namespace OnTopReplica {
}
/// <summary>
/// Looks up a localized string similar to Download
/// Looks up a localized string similar to Download
///Install OnTopReplica {0}..
/// </summary>
internal static string AskUpdateButtonOk {
@ -251,7 +251,7 @@ namespace OnTopReplica {
}
/// <summary>
/// Looks up a localized string similar to Installed version: {0}
/// Looks up a localized string similar to Installed version: {0}
///Available version: {1}.
/// </summary>
internal static string AskUpdateExpanded {
@ -333,8 +333,8 @@ namespace OnTopReplica {
}
/// <summary>
/// Looks up a localized string similar to You must enable desktop composition, by selecting &apos;Windows Aero&apos; as the theme used by Windows.
///
/// Looks up a localized string similar to You must enable desktop composition, by selecting &apos;Windows Aero&apos; as the theme used by Windows.
///
///To do so, right-click on the desktop and click on Personalize..
/// </summary>
internal static string ErrorDwmOffContent {
@ -380,7 +380,7 @@ namespace OnTopReplica {
}
/// <summary>
/// Looks up a localized string similar to Desktop Composition&apos; is not supported on your Operating System.
/// Looks up a localized string similar to Desktop Composition&apos; is not supported on your Operating System.
///You must run this application on Windows Vista Home Premium or better..
/// </summary>
internal static string ErrorNoDwm {
@ -597,8 +597,8 @@ namespace OnTopReplica {
}
/// <summary>
/// Looks up a localized string similar to If this mode is enabled, OnTopReplica will forward all left mouse clicks to the window that is being cloned (this will allow you to do basic mouse operations on the cloned window without having to activate it).
///
/// Looks up a localized string similar to If this mode is enabled, OnTopReplica will forward all left mouse clicks to the window that is being cloned (this will allow you to do basic mouse operations on the cloned window without having to activate it).
///
///To exit this mode, push ESC..
/// </summary>
internal static string InfoClickForwardingContent {
@ -635,8 +635,8 @@ namespace OnTopReplica {
}
/// <summary>
/// Looks up a localized string similar to In this mode the fullscreen window will behave as a partially transparent overlay, allowing you to click on the other windows behind it.
///
/// Looks up a localized string similar to In this mode the fullscreen window will behave as a partially transparent overlay, allowing you to click on the other windows behind it.
///
///To return to normal mode anytime, activate OnTopReplica by clicking on the task bar (or the tray icon)..
/// </summary>
internal static string InfoClickThroughInformation {
@ -646,7 +646,7 @@ namespace OnTopReplica {
}
/// <summary>
/// Looks up a localized string similar to No, thank you.
/// Looks up a localized string similar to No, thank you.
///You can enable click-through later.
/// </summary>
internal static string InfoClickThroughNo {
@ -871,24 +871,6 @@ namespace OnTopReplica {
}
}
/// <summary>
/// Looks up a localized string similar to Glass.
/// </summary>
internal static string MenuGlass {
get {
return ResourceManager.GetString("MenuGlass", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Toggles &quot;glass mode&quot; on and off..
/// </summary>
internal static string MenuGlassTT {
get {
return ResourceManager.GetString("MenuGlassTT", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Group Switch mode.
/// </summary>
@ -1348,6 +1330,69 @@ namespace OnTopReplica {
}
}
/// <summary>
/// Looks up a localized string similar to Clone current window.
/// </summary>
internal static string SettingsHotKeyClone {
get {
return ResourceManager.GetString("SettingsHotKeyClone", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to These system-wide shortcuts can also be used when OnTopReplica is not in focus..
/// </summary>
internal static string SettingsHotKeyDescription {
get {
return ResourceManager.GetString("SettingsHotKeyDescription", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Show/Hide.
/// </summary>
internal static string SettingsHotKeyShowHide {
get {
return ResourceManager.GetString("SettingsHotKeyShowHide", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Hot keys:.
/// </summary>
internal static string SettingsHotKeyTitle {
get {
return ResourceManager.GetString("SettingsHotKeyTitle", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Language:.
/// </summary>
internal static string SettingsLanguageTitle {
get {
return ResourceManager.GetString("SettingsLanguageTitle", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Requires a restart..
/// </summary>
internal static string SettingsRestartRequired {
get {
return ResourceManager.GetString("SettingsRestartRequired", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Settings.
/// </summary>
internal static string SettingsTitle {
get {
return ResourceManager.GetString("SettingsTitle", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to A lightweight, real-time, always on top thumbnail of a window of your choice..
/// </summary>

View file

@ -309,12 +309,6 @@ Režim "Proklikávání" je možné zvolit později v menu</value>
<data name="MenuFitQuarter" xml:space="preserve">
<value>1:4 Čtvrtinová</value>
</data>
<data name="MenuGlass" xml:space="preserve">
<value>Glass efekt</value>
</data>
<data name="MenuGlassTT" xml:space="preserve">
<value>Přepíná "glass efekt" okna.</value>
</data>
<data name="MenuOp100" xml:space="preserve">
<value>100% (neprůhledné)</value>
</data>

View file

@ -304,12 +304,6 @@ Du kan aktivere gennem klik senere.</value>
<data name="MenuFitQuarter" xml:space="preserve">
<value>1:4 kvart</value>
</data>
<data name="MenuGlass" xml:space="preserve">
<value>Glas</value>
</data>
<data name="MenuGlassTT" xml:space="preserve">
<value>Vælger "glas tilstand" til/fra</value>
</data>
<data name="MenuOp100" xml:space="preserve">
<value>100% (uigennemsigtig)</value>
</data>

View file

@ -334,12 +334,6 @@ Se podrá activar Click a través más tarde</value>
<data name="MenuFitQuarter" xml:space="preserve">
<value>1:4 Un cuarto</value>
</data>
<data name="MenuGlass" xml:space="preserve">
<value>Efecto vidrio</value>
</data>
<data name="MenuGlassTT" xml:space="preserve">
<value>Activa o desactiva el efecto vidrio.</value>
</data>
<data name="MenuGroupSwitch" xml:space="preserve">
<value>Modo en grupo</value>
</data>

View file

@ -334,11 +334,11 @@ Puoi abilitare il Click-Through in futuro</value>
<data name="MenuFitQuarter" xml:space="preserve">
<value>1:4 Quarto</value>
</data>
<data name="MenuGlass" xml:space="preserve">
<value>Effetto vetro</value>
<data name="SettingsHotKeyDescription" xml:space="preserve">
<value>Queste scorciatoie possono essere usate quando OnTopReplica non è attivo.</value>
</data>
<data name="MenuGlassTT" xml:space="preserve">
<value>Abilita o disabilita l'effetto vetro.</value>
<data name="SettingsHotKeyClone" xml:space="preserve">
<value>Clona finestra corrente</value>
</data>
<data name="MenuGroupSwitch" xml:space="preserve">
<value>Modalità Gruppo di finestre</value>
@ -487,4 +487,34 @@ Puoi abilitare il Click-Through in futuro</value>
<data name="UpdateNow" xml:space="preserve">
<value>Aggiorna!</value>
</data>
<data name="SettingsHotKeyShowHide" xml:space="preserve">
<value>Nascondi</value>
</data>
<data name="SettingsHotKeyTitle" xml:space="preserve">
<value>Scorciatoie:</value>
</data>
<data name="SettingsLanguageTitle" xml:space="preserve">
<value>Lingua:</value>
</data>
<data name="SettingsRestartRequired" xml:space="preserve">
<value>Richiede un riavvio.</value>
</data>
<data name="SettingsTitle" xml:space="preserve">
<value>Impostazioni</value>
</data>
<data name="MenuRestoreLast" xml:space="preserve">
<value>Ripristina ultima finestra</value>
</data>
<data name="MenuRestoreLastTT" xml:space="preserve">
<value>Se abilitato, all'avvio OnTopReplica tenterà di ripristinare l'ultima finestra precedentemente clonata.</value>
</data>
<data name="MenuSettings" xml:space="preserve">
<value>Impostazioni...</value>
</data>
<data name="MenuSettingsTT" xml:space="preserve">
<value>Mostra il pannello delle impostazioni.</value>
</data>
<data name="MenuPosCenter" xml:space="preserve">
<value>Centrato</value>
</data>
</root>

File diff suppressed because it is too large Load diff

View file

@ -49,6 +49,12 @@
<setting name="RestoreLastWindowHwnd" serializeAs="String">
<value>0</value>
</setting>
<setting name="HotKeyCloneCurrent" serializeAs="String">
<value>[CTRL]+[SHIFT]+C</value>
</setting>
<setting name="HotKeyShowHide" serializeAs="String">
<value>[CTRL]+[SHIFT]+O</value>
</setting>
</OnTopReplica.Properties.Settings>
</userSettings>
<startup><supportedRuntime version="v2.0.50727"/></startup></configuration>