summaryrefslogtreecommitdiff
path: root/plugins/ChangeKeyboardLayout
diff options
context:
space:
mode:
authorVadim Dashevskiy <watcherhd@gmail.com>2012-06-06 19:11:34 +0000
committerVadim Dashevskiy <watcherhd@gmail.com>2012-06-06 19:11:34 +0000
commit3dfe76ebba2cc8264d5548db3446587fd08f032e (patch)
tree6354fc3c57cf56b182d0b3e58654f6855fa71d8c /plugins/ChangeKeyboardLayout
parent46a53191c1ad11a41c948594e972568e62d155b4 (diff)
ChangeKeyboardLayout added
git-svn-id: http://svn.miranda-ng.org/main/trunk@333 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'plugins/ChangeKeyboardLayout')
-rw-r--r--plugins/ChangeKeyboardLayout/ChangeKeyboardLayout.rc305
-rw-r--r--plugins/ChangeKeyboardLayout/ChangeKeyboardLayout.sln26
-rw-r--r--plugins/ChangeKeyboardLayout/ChangeKeyboardLayout.vcxproj275
-rw-r--r--plugins/ChangeKeyboardLayout/ChangeKeyboardLayout.vcxproj.filters76
-rw-r--r--plugins/ChangeKeyboardLayout/ChangeLogEn.txt44
-rw-r--r--plugins/ChangeKeyboardLayout/ChangeLogRu.txt89
-rw-r--r--plugins/ChangeKeyboardLayout/Ico/Alt.bmpbin0 -> 1338 bytes
-rw-r--r--plugins/ChangeKeyboardLayout/Ico/CopyToClipboard.icobin0 -> 2550 bytes
-rw-r--r--plugins/ChangeKeyboardLayout/Ico/Ctrl.bmpbin0 -> 1390 bytes
-rw-r--r--plugins/ChangeKeyboardLayout/Ico/Popup.icobin0 -> 2550 bytes
-rw-r--r--plugins/ChangeKeyboardLayout/Ico/Shift.bmpbin0 -> 1442 bytes
-rw-r--r--plugins/ChangeKeyboardLayout/Ico/Win.bmpbin0 -> 1338 bytes
-rw-r--r--plugins/ChangeKeyboardLayout/Ico/alt.icobin0 -> 5494 bytes
-rw-r--r--plugins/ChangeKeyboardLayout/Ico/ctrl.icobin0 -> 6518 bytes
-rw-r--r--plugins/ChangeKeyboardLayout/Ico/shift.icobin0 -> 6518 bytes
-rw-r--r--plugins/ChangeKeyboardLayout/Ico/win.icobin0 -> 6518 bytes
-rw-r--r--plugins/ChangeKeyboardLayout/commonheaders.h123
-rw-r--r--plugins/ChangeKeyboardLayout/hook_events.c334
-rw-r--r--plugins/ChangeKeyboardLayout/hook_events.h15
-rw-r--r--plugins/ChangeKeyboardLayout/include/m_popup.h574
-rw-r--r--plugins/ChangeKeyboardLayout/m_changekeyboardlayout.h32
-rw-r--r--plugins/ChangeKeyboardLayout/main.c123
-rw-r--r--plugins/ChangeKeyboardLayout/options.c499
-rw-r--r--plugins/ChangeKeyboardLayout/options.h9
-rw-r--r--plugins/ChangeKeyboardLayout/resource.h81
-rw-r--r--plugins/ChangeKeyboardLayout/text_operations.c676
-rw-r--r--plugins/ChangeKeyboardLayout/text_operations.h16
27 files changed, 3297 insertions, 0 deletions
diff --git a/plugins/ChangeKeyboardLayout/ChangeKeyboardLayout.rc b/plugins/ChangeKeyboardLayout/ChangeKeyboardLayout.rc
new file mode 100644
index 0000000000..14480583dc
--- /dev/null
+++ b/plugins/ChangeKeyboardLayout/ChangeKeyboardLayout.rc
@@ -0,0 +1,305 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Russian resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
+#ifdef _WIN32
+LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
+#pragma code_page(1251)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE MOVEABLE PURE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE MOVEABLE PURE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE MOVEABLE PURE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_POPUPICON ICON DISCARDABLE "Ico\\Popup.ico"
+IDI_COPYICON ICON DISCARDABLE "Ico\\CopyToClipboard.ico"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Bitmap
+//
+
+IDB_BITMAP_WIN BITMAP DISCARDABLE "Ico\\Win.bmp"
+IDB_BITMAP_ALT BITMAP DISCARDABLE "Ico\\Alt.bmp"
+IDB_BITMAP_CTRL BITMAP DISCARDABLE "Ico\\Ctrl.bmp"
+IDB_BITMAP_SHIFT BITMAP DISCARDABLE "Ico\\Shift.bmp"
+
+#ifndef _MAC
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 0,0,1,5
+ PRODUCTVERSION 0,0,1,5
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "000004b0"
+ BEGIN
+ VALUE "Comments", "\0"
+ VALUE "CompanyName", "\0"
+ VALUE "FileDescription", "Plugin for change keyboard layout of text (multilayout)\0"
+ VALUE "FileVersion", "0, 0, 1, 5\0"
+ VALUE "InternalName", "ChangeKeyboardLayout\0"
+ VALUE "LegalCopyright", "Copyright © 2006-2009 Mikhail Yur'ev\0"
+ VALUE "LegalTrademarks", "\0"
+ VALUE "OriginalFilename", "ChangeKeyboardLayout.dll\0"
+ VALUE "PrivateBuild", "\0"
+ VALUE "ProductName", "ChangeKeyboardLayout\0"
+ VALUE "ProductVersion", "0, 0, 1, 5\0"
+ VALUE "SpecialBuild", "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x0, 1200
+ END
+END
+
+#endif // !_MAC
+
+#endif // Russian resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_MAIN_OPTION_FORM DIALOGEX 0, 0, 313, 249
+STYLE DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_SYSMENU
+FONT 8, "MS Shell Dlg"
+BEGIN
+ GROUPBOX "Hotkeys",IDC_STATIC_GROUP_HOTKEYS,2,0,308,94
+ LTEXT "Changing layout:",IDC_STATIC_HOTKEY_LAYOUT,8,11,296,8
+ CONTROL "",IDC_HOTKEY_LAYOUT,"msctls_hotkey32",WS_BORDER |
+ WS_TABSTOP,162,21,23,12,WS_EX_ACCEPTFILES
+ CONTROL "",IDC_CHECK_LAYOUT_CTRL,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,70,22,9,10
+ CONTROL "",IDC_CHECK_LAYOUT_ALT,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,99,22,9,10
+ CONTROL "",IDC_CHECK_LAYOUT_SHIFT,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,39,22,9,10
+ CONTROL "",IDC_CHECK_LAYOUT_WIN,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,126,22,9,10
+ CONTROL """Current word"" mode",IDC_CHECK_LAYOUT_MODE,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,195,22,109,10
+ LTEXT "Changing layout (alternative):",
+ IDC_STATIC_HOTKEY_LAYOUT2,8,37,296,8
+ CONTROL "",IDC_HOTKEY_LAYOUT2,"msctls_hotkey32",WS_BORDER |
+ WS_TABSTOP,162,48,23,12,WS_EX_ACCEPTFILES
+ CONTROL "",IDC_CHECK_LAYOUT2_CTRL,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,70,49,9,10
+ CONTROL "",IDC_CHECK_LAYOUT2_ALT,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,99,49,9,10
+ CONTROL "",IDC_CHECK_LAYOUT2_SHIFT,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,39,49,9,10
+ CONTROL "",IDC_CHECK_LAYOUT2_WIN,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,126,49,9,10
+ CONTROL """Current word"" mode",IDC_CHECK_LAYOUT_MODE2,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,195,49,109,10
+ LTEXT "Inverting lettercase:",IDC_STATIC_HOTKEY_CASE,8,64,296,
+ 8
+ CONTROL "",IDC_HOTKEY_CASE,"msctls_hotkey32",WS_BORDER |
+ WS_TABSTOP,162,75,23,12,WS_EX_ACCEPTFILES
+ CONTROL "",IDC_CHECK_CASE_CTRL,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,70,76,9,10
+ CONTROL "",IDC_CHECK_CASE_ALT,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,99,76,9,10
+ CONTROL "",IDC_CHECK_CASE_SHIFT,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,39,76,9,10
+ CONTROL "",IDC_CHECK_CASE_WIN,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,126,76,9,10
+ CONTROL """Current word"" mode",IDC_CHECK_CASE_MODE,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,195,76,109,10
+ GROUPBOX "Options",IDC_STATIC_GROUP_OPTIONS,158,96,152,81
+ CONTROL "Two-way changing layout (experimental)",
+ IDC_CHECK_TWOWAY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
+ 164,105,143,10
+ GROUPBOX "Log operations",IDC_STATIC_GROUP_LOG,2,96,152,81
+ CONTROL "Copy result to clipboard",IDC_CHECK_CLIPBOARD,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,8,108,141,10
+ CONTROL "Show result in PopUp",IDC_CHECK_POPUP,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,8,121,141,10
+ GROUPBOX "Strings for keyboard layouts",IDC_STATIC_GROUP_STRINGS,
+ 2,180,308,65
+ LTEXT "EN",IDC_STATIC_EXAMPLE,10,194,10,8
+ EDITTEXT IDC_EDIT_EXAMPLE,42,192,261,14,ES_AUTOHSCROLL |
+ ES_READONLY
+ COMBOBOX IDC_COMBO_LANG,8,209,32,63,CBS_DROPDOWNLIST | WS_VSCROLL |
+ WS_TABSTOP
+ EDITTEXT IDC_EDIT_SET,42,208,261,14,ES_AUTOHSCROLL
+ PUSHBUTTON "Default",IDC_BUTTON_DEFAULT,253,226,50,14
+ CONTROL 112,IDC_STATIC,"Static",SS_BITMAP,80,23,15,8
+ CONTROL 111,IDC_STATIC,"Static",SS_BITMAP,110,23,12,8
+ CONTROL 113,IDC_STATIC,"Static",SS_BITMAP,50,23,17,8
+ CONTROL 110,IDC_STATIC,"Static",SS_BITMAP,136,23,13,8
+ LTEXT "+",IDC_STATIC,153,22,8,8
+ CONTROL 112,IDC_STATIC,"Static",SS_BITMAP,80,50,15,8
+ CONTROL 111,IDC_STATIC,"Static",SS_BITMAP,110,50,12,8
+ CONTROL 113,IDC_STATIC,"Static",SS_BITMAP,50,50,17,8
+ CONTROL 110,IDC_STATIC,"Static",SS_BITMAP,136,50,13,8
+ LTEXT "+",IDC_STATIC,153,49,8,8
+ CONTROL 112,IDC_STATIC,"Static",SS_BITMAP,80,77,15,8
+ CONTROL 111,IDC_STATIC,"Static",SS_BITMAP,110,77,12,8
+ CONTROL 113,IDC_STATIC,"Static",SS_BITMAP,50,77,17,8
+ CONTROL 110,IDC_STATIC,"Static",SS_BITMAP,136,77,13,8
+ LTEXT "+",IDC_STATIC,153,76,8,8
+ CONTROL "Invert current state",IDC_RADIO_INVERTCAPS,"Button",
+ BS_AUTORADIOBUTTON,171,145,133,10
+ CONTROL "Switch off",IDC_RADIO_OFFCAPS,"Button",
+ BS_AUTORADIOBUTTON,171,155,133,10
+ CONTROL "Leave as it is",IDC_RADIO_IGNORECAPS,"Button",
+ BS_AUTORADIOBUTTON,171,165,133,10
+ LTEXT "Set Caps Lock state when inverting lettercase:",
+ IDC_STATIC,164,128,140,18
+ CONTROL "Change active keyboard layout in system",
+ IDC_CHECK_SYSTEMLAYOUT,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,164,116,143,10
+END
+
+IDD_POPUP_OPTION_FORM DIALOGEX 0, 0, 188, 126
+STYLE DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_SYSMENU
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ GROUPBOX "Colours",IDC_GROUP_COLOURS,2,2,91,72,WS_GROUP
+ CONTROL "PopUp colours",IDC_RADIO_COLOURS_POPUP,"Button",
+ BS_AUTORADIOBUTTON,6,12,82,10
+ CONTROL "Windows colours",IDC_RADIO_COLOURS_WINDOWS,"Button",
+ BS_AUTORADIOBUTTON,6,23,82,10
+ CONTROL "Custom colours",IDC_RADIO_COLOURS_CUSTOM,"Button",
+ BS_AUTORADIOBUTTON,6,34,82,10
+ CTEXT "Back",IDC_STATIC,8,46,39,8
+ CONTROL "Custom1",IDC_CUSTOM_BACK,"ColourPicker",WS_TABSTOP,12,
+ 55,29,14
+ CTEXT "Text",IDC_STATIC,51,46,39,8
+ CONTROL "Custom1",IDC_CUSTOM_TEXT,"ColourPicker",WS_TABSTOP,56,
+ 55,29,14
+ GROUPBOX "Timeout",IDC_GROUP_TIMEOUT,95,2,91,72,WS_GROUP
+ CONTROL "From PopUp plugin",IDC_RADIO_TIMEOUT_POPUP,"Button",
+ BS_AUTORADIOBUTTON,99,12,82,10
+ CONTROL "Permanent",IDC_RADIO_TIMEOUT_PERMANENT,"Button",
+ BS_AUTORADIOBUTTON,99,23,82,10
+ CONTROL "Custom",IDC_RADIO_TIMEOUT_CUSTOM,"Button",
+ BS_AUTORADIOBUTTON,99,33,82,10
+ EDITTEXT IDC_EDIT_TIMEOUT,118,50,40,14,ES_AUTOHSCROLL | ES_NUMBER
+ GROUPBOX "On left click",IDC_GROUP_LEFTCLICK,2,74,91,34,WS_GROUP
+ CONTROL "Copy to clipboard",IDC_RADIO_LEFT_CLIPBOARD,"Button",
+ BS_AUTORADIOBUTTON,8,84,82,10
+ CONTROL "Dismiss",IDC_RADIO_LEFT_DISMISS,"Button",
+ BS_AUTORADIOBUTTON,8,94,82,10
+ GROUPBOX "On right click",IDC_GROUP_RIGHTCLICK,95,74,91,34,
+ WS_GROUP
+ CONTROL "Copy to clipboard",IDC_RADIO_RIGHT_CLIPBOARD,"Button",
+ BS_AUTORADIOBUTTON,101,84,82,10
+ CONTROL "Dismiss",IDC_RADIO_RIGHT_DISMISS,"Button",
+ BS_AUTORADIOBUTTON,101,94,82,10
+ PUSHBUTTON "Preview",IDC_BUTTON_PREVIEW,70,110,50,14
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO MOVEABLE PURE
+BEGIN
+ IDD_MAIN_OPTION_FORM, DIALOG
+ BEGIN
+ LEFTMARGIN, 2
+ RIGHTMARGIN, 310
+ TOPMARGIN, 3
+ BOTTOMMARGIN, 246
+ END
+
+ IDD_POPUP_OPTION_FORM, DIALOG
+ BEGIN
+ LEFTMARGIN, 2
+ RIGHTMARGIN, 186
+ TOPMARGIN, 2
+ BOTTOMMARGIN, 124
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/plugins/ChangeKeyboardLayout/ChangeKeyboardLayout.sln b/plugins/ChangeKeyboardLayout/ChangeKeyboardLayout.sln
new file mode 100644
index 0000000000..a8a7e5a067
--- /dev/null
+++ b/plugins/ChangeKeyboardLayout/ChangeKeyboardLayout.sln
@@ -0,0 +1,26 @@
+п»ї
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ChangeKeyboardLayout", "ChangeKeyboardLayout.vcxproj", "{D85D47E7-EAD3-71E0-EE3A-49A7821D4DE4}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Debug|x64 = Debug|x64
+ Release|Win32 = Release|Win32
+ Release|x64 = Release|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {D85D47E7-EAD3-71E0-EE3A-49A7821D4DE4}.Debug|Win32.ActiveCfg = Debug|Win32
+ {D85D47E7-EAD3-71E0-EE3A-49A7821D4DE4}.Debug|Win32.Build.0 = Debug|Win32
+ {D85D47E7-EAD3-71E0-EE3A-49A7821D4DE4}.Debug|x64.ActiveCfg = Debug|x64
+ {D85D47E7-EAD3-71E0-EE3A-49A7821D4DE4}.Debug|x64.Build.0 = Debug|x64
+ {D85D47E7-EAD3-71E0-EE3A-49A7821D4DE4}.Release|Win32.ActiveCfg = Release|Win32
+ {D85D47E7-EAD3-71E0-EE3A-49A7821D4DE4}.Release|Win32.Build.0 = Release|Win32
+ {D85D47E7-EAD3-71E0-EE3A-49A7821D4DE4}.Release|x64.ActiveCfg = Release|x64
+ {D85D47E7-EAD3-71E0-EE3A-49A7821D4DE4}.Release|x64.Build.0 = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/plugins/ChangeKeyboardLayout/ChangeKeyboardLayout.vcxproj b/plugins/ChangeKeyboardLayout/ChangeKeyboardLayout.vcxproj
new file mode 100644
index 0000000000..4a2db66586
--- /dev/null
+++ b/plugins/ChangeKeyboardLayout/ChangeKeyboardLayout.vcxproj
@@ -0,0 +1,275 @@
+п»ї<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectName>ChangeKeyboardLayout</ProjectName>
+ <ProjectGuid>{D85D47E7-EAD3-71E0-EE3A-49A7821D4DE4}</ProjectGuid>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>Unicode</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>Unicode</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <OutDir>$(SolutionDir)$(Configuration)\Plugins\</OutDir>
+ <IntDir>$(SolutionDir)$(Configuration)\Obj\$(ProjectName)\</IntDir>
+ <LinkIncremental>true</LinkIncremental>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <OutDir>$(SolutionDir)$(Configuration)64\Plugins\</OutDir>
+ <IntDir>$(SolutionDir)$(Configuration)64\Obj\$(ProjectName)\</IntDir>
+ <LinkIncremental>true</LinkIncremental>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <OutDir>$(SolutionDir)$(Configuration)\Plugins\</OutDir>
+ <IntDir>$(SolutionDir)$(Configuration)\Obj\$(ProjectName)\</IntDir>
+ <LinkIncremental>false</LinkIncremental>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <OutDir>$(SolutionDir)$(Configuration)64\Plugins\</OutDir>
+ <IntDir>$(SolutionDir)$(Configuration)64\Obj\$(ProjectName)\</IntDir>
+ <LinkIncremental>false</LinkIncremental>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <InlineFunctionExpansion>Default</InlineFunctionExpansion>
+ <FunctionLevelLinking>false</FunctionLevelLinking>
+ <Optimization>Disabled</Optimization>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <WarningLevel>Level3</WarningLevel>
+ <MinimalRebuild>true</MinimalRebuild>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ <AdditionalIncludeDirectories>.\include;..\..\include;..\ExternalAPI;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;ChangeKeyboardLayout_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BrowseInformation>true</BrowseInformation>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ </ClCompile>
+ <Midl>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <TypeLibraryName>.\Debug\ChangeKeyboardLayout.tlb</TypeLibraryName>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <TargetEnvironment>Win32</TargetEnvironment>
+ </Midl>
+ <ResourceCompile>
+ <Culture>0x0809</Culture>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>..\..\include\msapi</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <Bscmake>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <OutputFile>$(IntDir)$(TargetName).bsc</OutputFile>
+ </Bscmake>
+ <Link>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <LinkDLL>true</LinkDLL>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <InlineFunctionExpansion>Default</InlineFunctionExpansion>
+ <FunctionLevelLinking>false</FunctionLevelLinking>
+ <Optimization>Disabled</Optimization>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <AdditionalIncludeDirectories>.\include;..\..\include;..\ExternalAPI;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN64;_DEBUG;_WINDOWS;_MBCS;_USRDLL;ChangeKeyboardLayout_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BrowseInformation>true</BrowseInformation>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ </ClCompile>
+ <Midl>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <TypeLibraryName>.\Debug\ChangeKeyboardLayout.tlb</TypeLibraryName>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ </Midl>
+ <ResourceCompile>
+ <Culture>0x0809</Culture>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>..\..\include\msapi</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <Bscmake>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <OutputFile>$(IntDir)$(TargetName).bsc</OutputFile>
+ </Bscmake>
+ <Link>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <LinkDLL>true</LinkDLL>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <StringPooling>true</StringPooling>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <Optimization>Full</Optimization>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <WarningLevel>Level3</WarningLevel>
+ <AdditionalIncludeDirectories>.\include;..\..\include;..\ExternalAPI;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;ChangeKeyboardLayout_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BrowseInformation>true</BrowseInformation>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ </ClCompile>
+ <Midl>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <TypeLibraryName>.\Release\ChangeKeyboardLayout.tlb</TypeLibraryName>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <TargetEnvironment>Win32</TargetEnvironment>
+ </Midl>
+ <ResourceCompile>
+ <Culture>0x0809</Culture>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>..\..\include\msapi</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <Bscmake>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <OutputFile>$(IntDir)$(TargetName).bsc</OutputFile>
+ </Bscmake>
+ <Link>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <LinkDLL>true</LinkDLL>
+ <SubSystem>Console</SubSystem>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <StringPooling>true</StringPooling>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <Optimization>Full</Optimization>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <WarningLevel>Level3</WarningLevel>
+ <AdditionalIncludeDirectories>.\include;..\..\include;..\ExternalAPI;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN64;NDEBUG;_WINDOWS;_MBCS;_USRDLL;ChangeKeyboardLayout_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BrowseInformation>true</BrowseInformation>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ </ClCompile>
+ <Midl>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <TypeLibraryName>.\Release\ChangeKeyboardLayout.tlb</TypeLibraryName>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ </Midl>
+ <ResourceCompile>
+ <Culture>0x0809</Culture>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>..\..\include\msapi</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <Bscmake>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <OutputFile>$(IntDir)$(TargetName).bsc</OutputFile>
+ </Bscmake>
+ <Link>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <LinkDLL>true</LinkDLL>
+ <SubSystem>Console</SubSystem>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="hook_events.c" />
+ <ClCompile Include="main.c" />
+ <ClCompile Include="options.c" />
+ <ClCompile Include="text_operations.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="commonheaders.h" />
+ <ClInclude Include="hook_events.h" />
+ <ClInclude Include="m_changekeyboardlayout.h" />
+ <ClInclude Include="options.h" />
+ <ClInclude Include="resource.h" />
+ <ClInclude Include="text_operations.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <CustomBuild Include="Ico\Alt.bmp" />
+ <CustomBuild Include="Ico\CopyToClipboard.ico" />
+ <CustomBuild Include="Ico\Ctrl.bmp" />
+ <CustomBuild Include="Ico\Popup.ico" />
+ <CustomBuild Include="Ico\Shift.bmp" />
+ <CustomBuild Include="Ico\Win.bmp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="ChangeKeyboardLayout.rc" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/plugins/ChangeKeyboardLayout/ChangeKeyboardLayout.vcxproj.filters b/plugins/ChangeKeyboardLayout/ChangeKeyboardLayout.vcxproj.filters
new file mode 100644
index 0000000000..001336f281
--- /dev/null
+++ b/plugins/ChangeKeyboardLayout/ChangeKeyboardLayout.vcxproj.filters
@@ -0,0 +1,76 @@
+п»ї<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{cc54d694-45d5-4087-bbef-3c76adfeb05b}</UniqueIdentifier>
+ <Extensions>cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{4ec5c4c7-f01c-4de6-8b8b-0380023afb01}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{768f39e1-b07e-4b84-8973-6504d076d16e}</UniqueIdentifier>
+ <Extensions>ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="hook_events.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="main.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="options.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="text_operations.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="commonheaders.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="hook_events.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="m_changekeyboardlayout.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="options.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="resource.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="text_operations.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="ChangeKeyboardLayout.rc">
+ <Filter>Resource Files</Filter>
+ </ResourceCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <CustomBuild Include="Ico\Alt.bmp">
+ <Filter>Resource Files</Filter>
+ </CustomBuild>
+ <CustomBuild Include="Ico\CopyToClipboard.ico">
+ <Filter>Resource Files</Filter>
+ </CustomBuild>
+ <CustomBuild Include="Ico\Ctrl.bmp">
+ <Filter>Resource Files</Filter>
+ </CustomBuild>
+ <CustomBuild Include="Ico\Popup.ico">
+ <Filter>Resource Files</Filter>
+ </CustomBuild>
+ <CustomBuild Include="Ico\Shift.bmp">
+ <Filter>Resource Files</Filter>
+ </CustomBuild>
+ <CustomBuild Include="Ico\Win.bmp">
+ <Filter>Resource Files</Filter>
+ </CustomBuild>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/plugins/ChangeKeyboardLayout/ChangeLogEn.txt b/plugins/ChangeKeyboardLayout/ChangeLogEn.txt
new file mode 100644
index 0000000000..1d2e0324f5
--- /dev/null
+++ b/plugins/ChangeKeyboardLayout/ChangeLogEn.txt
@@ -0,0 +1,44 @@
+The plugin is intended to switch text layout in the input fileds (all text, selection or current word) (E.g. (EN->RU): Ghbdtn? rfr ltkf& - ЏаЁўҐв, Є Є ¤Ґ« ?) or displaying "decoded" text from readonly fields (in logs of RTF, History++, IEView) using a popup with ability to copy result to clipboard. As of version 0.0.1.0 the ability to change register of symbols was added.
+Keyboards layouts are arbitrary, their list is taken from system layouts. For text conversion configurational strings are used, which beginning from version 0.0.1.0 are generated by the plugin itself(!). The ability to edit this strings is temporary left in case of incorrect strings generation for layouts which weren't tested by author.
+There is ability to define hotkeys for all above functions.
+Questions and requests also bugreports on russian forum: http://lemnews.com/forum/viewtopic.php?t=1493
+
+----------
+ChangeLog:
+
+0.0.1.4
+* Fixed error in hotkeys setup GUI
+* Fixed configurations strings generation for layouts with zero symbol
+* Added ability to change Caps Lock state on lettercase inversion (optional)
+* Removed the "Layout of text is the current layout" option. Now combined method is used for layout detection of converted text.
+* Added a check for IM client.
+* Small bugfixes.
+
+0.0.1.2
+* Enhanced abilities of hotkeys configuration
+* Minor bugfixes
+* Thanks to induction for icons
+
+0.0.1.1
+* Added Updater support
+* Fixed crash when making conversion in History++ window
+* Minor bugfixes
+
+0.0.1.0
+* The plugin is uploaded to FL for the first time.
+* Compiled in two versions: ANSI and Unicode
+* Generated UUID: {c5ef53a8-80d4-4ce9-b341-ec90d3ec9156} (UNICODE)
+ {87af74ba-035c-4d0d-b68d-d0d6ae1ebfcd} (ANSI)
+* Memory leaks were fixed
+* Generation of configurational strings is done by plugin without using predefined strings.
+* Only those configurational strings are kept in the database which differentiate from default strings (generated by plugin). Names of parametrs are changed to reflect full HKL value for layout.
+* Added ability to change the register of text.
+* Added ability to use alternative hotkey for text conversion.
+* "Current word" mode is set for each hotkey, not globally.
+* Added ability of two-way text conversion if system has 2 layouts. (E.g. (EN<->RU): Jgthfwbjyyfz cbcntvf „ивЈз ckj;yf lkz hzljds[ ЈлгЄ-jd - ЋЇҐа жЁ®­­ п бЁб⥬  Linux б«®¦­  ¤«п а冷ўле user-®ў)
+* Added ability to play sound on conversion (Options - Customize - Sounds)
+* Added ability of "decoding" text for History++ log without entering the pseudo-edit mode of message (with ability to select several messages)
+* Displaying of "decoded" text for readonly fields in popups (if a popup plugin is installed and enabled) or in MessageBox (in the opposite case). Popups settings are at Options - PopUps - ChangeKeyboardLayout
+* Thanks to induction for default icons for popups
+* Added ability to change popups icons
+* A lot of code optimizations and tweaks. \ No newline at end of file
diff --git a/plugins/ChangeKeyboardLayout/ChangeLogRu.txt b/plugins/ChangeKeyboardLayout/ChangeLogRu.txt
new file mode 100644
index 0000000000..b71786267a
--- /dev/null
+++ b/plugins/ChangeKeyboardLayout/ChangeLogRu.txt
@@ -0,0 +1,89 @@
+Плагин предназначен для изменения раскладки текста в полях редактирования (всего текста, выделенного, или текущего слова) (Пример (EN->RU): Ghbdtn? rfr ltkf& - Привет, как дела?), или отображения "расшифрованного" текста из нередактируемых полей (включая логи: RTF, History++, IEView) посредством вплывающего окна с возможностью копирования результата в буфер обмена. Начиная с версии 0.0.1.0 в плагин добавлена возможность преобразования и регистра символов.
+
+Раскладки клавиатуры произвольные, их перечень заимствуется из установленных в системе. Для преобразования текста используются конфигурационные строки, которые начиная с версии 0.0.1.0 генерируются плагином самостоятельно(!). Возможность их отредактировать временно оставлена на случай неверной генерации строк для неоттестированных автором раскладок.
+Имеется возможность изменять горячие клавиши для указанных выше функций.
+Вопросы и предложения, а также отчеты о багах на форуме: http://lemnews.com/forum/viewtopic.php?t=1493
+Отдельное спасибо за помощь в разработке и вдохновение: Vasilich, theMIROn, Awkward, Nullbie, Thief, induction, LEMnews-форуму, каналу #mirandaim на RusNet и многим, многим другим, включая всех пользователей, заинтересованных в развитии плагина.
+
+----------
+ChangeLog:
+
+0.0.1.4
+* Исправлена ошибка в GUI настроек горячих клавиш
+* Исправлена генерация конфигурационных строк для раскладок с нулевым символом
+* Добавлена возможность изменения состояния Caps Lock при инвертировании регистра символов (опционально).
+* Убрана опция "Layout of text is the current layout". Для определения раскладки конвертируемого текста теперь используется совмещенный метод.
+* Добавлена проверка на используемый IM-клиент.
+* Мелкие багфиксы
+
+0.0.1.2
+* Расширенные возможности конфигурирования горячих клавиш
+* Мелкие багфиксы
+* Спасибо induction за иконки
+
+0.0.1.1
+* Добавлена поддержка Updater
+* Пофиксен краш при вызове преобразования в окне истории History++
+* Мелкие багфиксы
+
+0.0.1.0
+* Впервые плагин выкладывается на FL.
+* Плагин компилируется в двух версиях: ANSI и Unicode.
+* Сгенерирован UUID: {c5ef53a8-80d4-4ce9-b341-ec90d3ec9156} (UNICODE)
+ {87af74ba-035c-4d0d-b68d-d0d6ae1ebfcd} (ANSI)
+* Пофиксены утечки памяти
+* Генерация конфигурационных строк осуществляется плагином самостоятельно без использования предопределенных строк.
+* В базе хранятся только те конфигурационные строки, что отличаются от строк по-умолчанию (сгенерированных плагином). Имена параметров в базе для них изменены в соответствии с полным значением HKL для раскладки.
+* Добавлена возможность преобразования регистра текста.
+* Добавлена возможность использования альтернативной горячей клавиши для преобразования раскладки текста.
+* Режим "текущего слова" задается не глобально, а для каждой горячей клавиши.
+* Добавлена возможность двунаправленного преобразования текста, если в системе установлено 2 раскладки. (Пример (EN<->RU): Jgthfwbjyyfz cbcntvf Дштгч ckj;yf lkz hzljds[ гыук-jd - Операционная система Linux сложна для рядовых user-ов)
+* Добавлена возможность воспроизведения звука при преобразованиях (Options - Customize - Sounds)
+* Добавлена возможность "расшифровки" текста для лога History++ и без входа в режим псевдо-редактирования сообщения (возможно выделение сразу нескольких сообщений).
+* Отображение "расшифрованного" текста для нередактируемых полей возможно во всплывающих окнах (если установлен и включен popup-плагин), или MessageBoxe-е (в противоположном случае). Настройка всплывающих окон Options - PopUps - ChangeKeyboardLayout
+* Спасибо induction за иконки по-умолчанию для всплывающих окон.
+* Добавлена возможность изменять иконки для всплывающих окон.
+* Большое количество прочих оптимизаций и изменений кода.
+
+0.0.0.9
+* Пофиксен баг, при котором плагин крашил Миранду, если не установлен плагин IEView
+* Некоторые оптимизации
+* Изменена кодировка translate.txt :))))
+* Добавлено 2 новых сервиса (определение раскладки текста и изменение раскладки произвольного текста). См. m_changekeyboardlayout.h
+
+0.0.0.8
+* Вновь обновлены конфигурационные строки для известных плагину раскладок. При первом запуске Миранды после обновления они будут принудительно обновлены. Поэтому, если Вы используете раскладки, отличные от EN, RU, DE, BE, RO сконфигурируйте их заново в соответствии с новыми строками.
+* Добавлены конфигурационные строки по умолчанию для белоруской и румынской раскладок.
+* Добавлена возможность работы с журналом сообщений. Результат преобразования выдается в буфер обмена и MessageBox() (опционально). В случае использования IEView обрабатывается только выделенный текст. Для RTF-журналов равносильно с полем набора (выделенный, весь или текущее слово)
+* Значительное изменение кода, оптимизации и, вероятно, новые баги :-D
+* Добавлен файл перевода translate.txt (на примере русского языка)
+
+0.0.0.7
+* Обновлены конфигурационные строки для известных плагину раскладок. При первом запуске Миранды после обновления они будут принудительно обновлены. Поэтому, если Вы использовали раскладки, отличные от EN, RU, DE, сконфигурируйте их заново в соответствии с новыми строками.
+* Добавлена возможность сброса конфигурационной строки для выбранной раскладки в значение по умолчанию.
+* Добавлена возможность выбора режима "текущего слова" (по умолчанию - отключено). Во включенном состоянии по горячей клавише, если нет выделенного текста, будет преобразовываться текущее слово. Во выключенном состоянии при отсутствии выделенного текста - весь текст в поле редактирования.
+
+0.0.0.6
+* Пофиксен баг, при котором модуль отказывался переключать раскладку текста до повторной установки горячей клавиши.
+
+0.0.0.5
+* Плагин вновь работает только для Unicode Miranda IM.
+* Поддержка произвольных раскладок клавиатуры, перечень которых заимствуется из системы. При наличии неизвестных плагину раскладок, для них необходимо в настройках задать конфигурационные строки, использующиеся для преобразования текста (В данный момент строки конфигурировать не надо для языков EN, RU, DE). Преобразование текста происходит в прямой последовательности расположения раскладок в системе.
+* 2 способа определения текущей раскладки текста: 1) соответствует активной раскладке; 2) по наибольшему количеству символов из конфигурационных строк. Опционально.
+* Переключение раскладки клавиатуры в системе одновременно с изменением раскладки текста.
+* Запоминание позиции курсора и выделения.
+* Одна горячая клавиша для двух функций. Если имеется выделенный текст, он и преобразуется, если нет, то весь текст в окне редактирования.
+* Возможность редактирования конфигурационных строк посредством GUI.
+* Добавлен сервис, позволяющий вызывать функцию преобразования текста в окне редактирования из других модулей. См. m_changekeyboardlayout.h
+
+0.0.0.3
+* Пофиксены баги
+* Изменен алгоритм определения текущей раскладки, теперь он эффективнее
+
+0.0.0.2
+* Теперь плагин универсален для ANSI и Unicode Миранды.
+* Добавлена возможность менять раскладку для всего текста в поле редактирования
+* Добавлена возможность редактирования горячих клавиш (Plugins - ChangeKeyboardLayout)
+
+0.0.0.1
+* Первый публичный релиз
diff --git a/plugins/ChangeKeyboardLayout/Ico/Alt.bmp b/plugins/ChangeKeyboardLayout/Ico/Alt.bmp
new file mode 100644
index 0000000000..e91a8a8f81
--- /dev/null
+++ b/plugins/ChangeKeyboardLayout/Ico/Alt.bmp
Binary files differ
diff --git a/plugins/ChangeKeyboardLayout/Ico/CopyToClipboard.ico b/plugins/ChangeKeyboardLayout/Ico/CopyToClipboard.ico
new file mode 100644
index 0000000000..f1c1b7f2e3
--- /dev/null
+++ b/plugins/ChangeKeyboardLayout/Ico/CopyToClipboard.ico
Binary files differ
diff --git a/plugins/ChangeKeyboardLayout/Ico/Ctrl.bmp b/plugins/ChangeKeyboardLayout/Ico/Ctrl.bmp
new file mode 100644
index 0000000000..982698f8b2
--- /dev/null
+++ b/plugins/ChangeKeyboardLayout/Ico/Ctrl.bmp
Binary files differ
diff --git a/plugins/ChangeKeyboardLayout/Ico/Popup.ico b/plugins/ChangeKeyboardLayout/Ico/Popup.ico
new file mode 100644
index 0000000000..0d95f3523c
--- /dev/null
+++ b/plugins/ChangeKeyboardLayout/Ico/Popup.ico
Binary files differ
diff --git a/plugins/ChangeKeyboardLayout/Ico/Shift.bmp b/plugins/ChangeKeyboardLayout/Ico/Shift.bmp
new file mode 100644
index 0000000000..efb314742c
--- /dev/null
+++ b/plugins/ChangeKeyboardLayout/Ico/Shift.bmp
Binary files differ
diff --git a/plugins/ChangeKeyboardLayout/Ico/Win.bmp b/plugins/ChangeKeyboardLayout/Ico/Win.bmp
new file mode 100644
index 0000000000..61e26876b3
--- /dev/null
+++ b/plugins/ChangeKeyboardLayout/Ico/Win.bmp
Binary files differ
diff --git a/plugins/ChangeKeyboardLayout/Ico/alt.ico b/plugins/ChangeKeyboardLayout/Ico/alt.ico
new file mode 100644
index 0000000000..d9a0c3f721
--- /dev/null
+++ b/plugins/ChangeKeyboardLayout/Ico/alt.ico
Binary files differ
diff --git a/plugins/ChangeKeyboardLayout/Ico/ctrl.ico b/plugins/ChangeKeyboardLayout/Ico/ctrl.ico
new file mode 100644
index 0000000000..0f894cf2cb
--- /dev/null
+++ b/plugins/ChangeKeyboardLayout/Ico/ctrl.ico
Binary files differ
diff --git a/plugins/ChangeKeyboardLayout/Ico/shift.ico b/plugins/ChangeKeyboardLayout/Ico/shift.ico
new file mode 100644
index 0000000000..15d7d89f34
--- /dev/null
+++ b/plugins/ChangeKeyboardLayout/Ico/shift.ico
Binary files differ
diff --git a/plugins/ChangeKeyboardLayout/Ico/win.ico b/plugins/ChangeKeyboardLayout/Ico/win.ico
new file mode 100644
index 0000000000..a6b4623522
--- /dev/null
+++ b/plugins/ChangeKeyboardLayout/Ico/win.ico
Binary files differ
diff --git a/plugins/ChangeKeyboardLayout/commonheaders.h b/plugins/ChangeKeyboardLayout/commonheaders.h
new file mode 100644
index 0000000000..161f74b482
--- /dev/null
+++ b/plugins/ChangeKeyboardLayout/commonheaders.h
@@ -0,0 +1,123 @@
+#ifndef M_CKL_COMMONHEADERS_H
+#define M_CKL_COMMONHEADERS_H
+#define _CRT_SECURE_NO_WARNINGS
+#define _CRT_NONSTDC_NO_DEPRECATE
+
+#define MIRANDA_VER 0x0A00
+
+#include <windows.h>
+#include <commctrl.h>
+#include <richedit.h>
+
+#include <newpluginapi.h>
+#include <m_options.h>
+#include <m_langpack.h>
+#include <m_database.h>
+#include <m_system.h>
+#include <m_ieview.h>
+#include <m_skin.h>
+#include <m_popup.h>
+#include <m_utils.h>
+#include <m_icolib.h>
+#include <m_updater.h>
+
+
+#include "resource.h"
+#include "m_changekeyboardlayout.h"
+#include "options.h"
+#include "hook_events.h"
+#include "text_operations.h"
+
+
+#define VERSION PLUGIN_MAKE_VERSION(0,0,1,5)
+#define MaxTextSize 64000
+#define ModuleName "ChangeKeyboardLayout"
+
+
+// History++ API
+#define MS_HPP_EG_WINDOW "History++/ExtGrid/NewWindow"
+#define MS_HPP_EG_EVENT "History++/ExtGrid/Event"
+#define MS_HPP_EG_NAVIGATE "History++/ExtGrid/Navigate"
+#define MS_HPP_EG_OPTIONSCHANGED "History++/ExtGrid/OptionsChanged"
+
+// Типы окон
+#define WTYPE_Unknown 0
+#define WTYPE_HistoryPP 1
+#define WTYPE_IEView 2
+#define WTYPE_RichEdit 3
+#define WTYPE_Edit 4
+
+//Тип операции над текстом
+#define TOT_Layout 0
+#define TOT_Case 1
+
+// Имена звуков
+#define SND_ChangeLayout "ChangingLayout"
+#define SND_ChangeCase "ChangingCase"
+
+//Цвета попапов
+#define PPC_POPUP 0
+#define PPC_WINDOWS 1
+#define PPC_CUSTOM 2
+
+//Таймаут попапов
+#define PPT_POPUP 0
+#define PPT_PERMANENT 1
+#define PPT_CUSTOM 2
+
+
+typedef struct
+{
+ DWORD dwHotkey_Layout;
+ DWORD dwHotkey_Layout2;
+ DWORD dwHotkey_Case;
+ BOOL CurrentWordLayout;
+ BOOL CurrentWordLayout2;
+ BOOL CurrentWordCase;
+ BOOL TwoWay;
+ BOOL ChangeSystemLayout;
+ BOOL CopyToClipboard;
+ BOOL ShowPopup;
+ BYTE bCaseOperations;
+} MainOptions;
+
+typedef struct
+{
+ BYTE bColourType;
+ COLORREF crTextColour;
+ COLORREF crBackColour;
+ BYTE bTimeoutType;
+ BYTE bTimeout;
+ BYTE bLeftClick;
+ BYTE bRightClick;
+ POPUPACTION paActions[1];
+} PopupOptions;
+
+PLUGININFOEX pluginInfoEx;
+PLUGININFO pluginInfo;
+
+HINSTANCE hInst;
+
+HANDLE hChangeLayout,hGetLayoutOfText,hChangeTextLayout;
+HANDLE hIcoLibIconsChanged;
+
+HICON hPopupIcon, hCopyIcon;
+
+LPCTSTR ptszKeybEng;
+HKL hklEng;
+
+BYTE bLayNum;
+HKL hklLayouts[20];
+LPTSTR ptszLayStrings[20];
+
+LPCTSTR ptszSeparators;
+
+HHOOK kbHook_All;
+
+MainOptions moOptions;
+PopupOptions poOptions,poOptionsTemp;
+DWORD dwMirandaVersion;
+
+LRESULT CALLBACK Keyboard_Hook(int code, WPARAM wParam, LPARAM lParam);
+
+#endif \ No newline at end of file
diff --git a/plugins/ChangeKeyboardLayout/hook_events.c b/plugins/ChangeKeyboardLayout/hook_events.c
new file mode 100644
index 0000000000..5dfa238c9d
--- /dev/null
+++ b/plugins/ChangeKeyboardLayout/hook_events.c
@@ -0,0 +1,334 @@
+#include "hook_events.h"
+
+int APIChangeLayout(WPARAM wParam, LPARAM lParam)
+{
+ BOOL CurrentWord;
+ CurrentWord=moOptions.CurrentWordLayout;
+ return ChangeLayout((HWND)wParam,TOT_Layout,CurrentWord);
+}
+
+int APIGetLayoutOfText(WPARAM wParam, LPARAM lParam)
+{
+ LPTSTR ptszInText;
+ ptszInText=(TCHAR*)lParam;
+ return (int) GetLayoutOfText(ptszInText);
+}
+
+int APIChangeTextLayout(WPARAM wParam, LPARAM lParam)
+{
+ LPTSTR ptszInText;
+ CKLLayouts *ckllFromToLay;
+
+ ptszInText=(TCHAR*)wParam;
+ ckllFromToLay=(CKLLayouts*)lParam;
+
+ return (int) ChangeTextLayout(ptszInText,ckllFromToLay->hklFrom,ckllFromToLay->hklTo,ckllFromToLay->bTwoWay);
+}
+
+BOOL CoreCheck()
+{
+ char version[1024], exepath[1024];
+ GetModuleFileNameA(GetModuleHandle(NULL), exepath, sizeof(exepath));
+ CallService(MS_SYSTEM_GETVERSIONTEXT, sizeof(version), (LPARAM)version);
+ strlwr(version); strlwr(exepath);
+ if (!strstr(strrchr(exepath, '\\'), "miranda") ||
+ strstr(version, "coffee") ||
+ !strncmp(version, "1.", 2) || strstr(version, " 1.") ||
+ (dwMirandaVersion >= PLUGIN_MAKE_VERSION(1,0,0,0)))
+ return FALSE;
+ else return TRUE;
+}
+
+void ReadMainOptions()
+{
+ moOptions.dwHotkey_Layout=DBGetContactSettingDword(NULL,ModuleName,"HotkeyLayout",119);
+ moOptions.dwHotkey_Layout2=DBGetContactSettingDword(NULL,ModuleName,"HotkeyLayout2",120);
+ moOptions.dwHotkey_Case=DBGetContactSettingDword(NULL,ModuleName,"HotkeyCase",121);
+ moOptions.CurrentWordLayout=DBGetContactSettingByte(NULL,ModuleName,"CurrentWordLayout",0);
+ moOptions.CurrentWordLayout2=DBGetContactSettingByte(NULL,ModuleName,"CurrentWordLayout2",1);
+ moOptions.CurrentWordCase=DBGetContactSettingByte(NULL,ModuleName,"CurrentWordCase",0);
+ moOptions.TwoWay=DBGetContactSettingByte(NULL,ModuleName,"TwoWay",1);
+ moOptions.ChangeSystemLayout=DBGetContactSettingByte(NULL,ModuleName,"ChangeSystemLayout",1);
+ moOptions.CopyToClipboard=DBGetContactSettingByte(NULL,ModuleName,"CopyToClipboard",0);
+ moOptions.ShowPopup=DBGetContactSettingByte(NULL,ModuleName,"ShowPopup",1);
+ moOptions.bCaseOperations=DBGetContactSettingByte(NULL,ModuleName,"CaseOperations",0);
+}
+
+void WriteMainOptions()
+{
+ DBWriteContactSettingDword(NULL,ModuleName,"HotkeyLayout",moOptions.dwHotkey_Layout);
+ DBWriteContactSettingDword(NULL,ModuleName,"HotkeyLayout2",moOptions.dwHotkey_Layout2);
+ DBWriteContactSettingDword(NULL,ModuleName,"HotkeyCase",moOptions.dwHotkey_Case);
+ DBWriteContactSettingByte(NULL,ModuleName,"CurrentWordLayout",moOptions.CurrentWordLayout);
+ DBWriteContactSettingByte(NULL,ModuleName,"CurrentWordLayout2",moOptions.CurrentWordLayout2);
+ DBWriteContactSettingByte(NULL,ModuleName,"CurrentWordCase",moOptions.CurrentWordCase);
+ DBWriteContactSettingByte(NULL,ModuleName,"TwoWay",moOptions.TwoWay);
+ DBWriteContactSettingByte(NULL,ModuleName,"ChangeSystemLayout",moOptions.ChangeSystemLayout);
+ DBWriteContactSettingByte(NULL,ModuleName,"CopyToClipboard",moOptions.CopyToClipboard);
+ DBWriteContactSettingByte(NULL,ModuleName,"ShowPopup",moOptions.ShowPopup);
+ DBWriteContactSettingByte(NULL,ModuleName,"CaseOperations",moOptions.bCaseOperations);
+}
+
+
+void ReadPopupOptions()
+{
+ poOptions.bColourType=DBGetContactSettingByte(NULL,ModuleName,"ColourType",0);
+ poOptions.crBackColour=(COLORREF)DBGetContactSettingDword(NULL,ModuleName,"BackColor",0xD2CABF);
+ poOptions.crTextColour=(COLORREF)DBGetContactSettingDword(NULL,ModuleName,"TextColor",0x000000);
+ poOptions.bTimeoutType=DBGetContactSettingByte(NULL,ModuleName,"TimeoutType",0);
+ poOptions.bTimeout=DBGetContactSettingByte(NULL,ModuleName,"Timeout",10);
+ poOptions.bLeftClick=DBGetContactSettingByte(NULL,ModuleName,"LeftClick",0);
+ poOptions.bRightClick=DBGetContactSettingByte(NULL,ModuleName,"RightClick",1);
+}
+
+void WritePopupOptions()
+{
+ DBWriteContactSettingByte(NULL,ModuleName,"ColourType",poOptions.bColourType);
+ DBWriteContactSettingDword(NULL,ModuleName,"BackColor",poOptions.crBackColour);
+ DBWriteContactSettingDword(NULL,ModuleName,"TextColor",poOptions.crTextColour);
+ DBWriteContactSettingByte(NULL,ModuleName,"TimeoutType",poOptions.bTimeoutType);
+ DBWriteContactSettingByte(NULL,ModuleName,"Timeout",poOptions.bTimeout);
+ DBWriteContactSettingByte(NULL,ModuleName,"LeftClick",poOptions.bLeftClick);
+ DBWriteContactSettingByte(NULL,ModuleName,"RightClick",poOptions.bRightClick);
+}
+
+void RegPopupActions()
+{
+ if (ServiceExists(MS_POPUP_ADDPOPUP))
+ {
+ poOptions.paActions[0].cbSize = sizeof(POPUPACTION);
+ strcpy(poOptions.paActions[0].lpzTitle, ModuleName);
+ strcat(poOptions.paActions[0].lpzTitle, "/Copy to clipboard");
+ poOptions.paActions[0].flags = PAF_ENABLED;
+ poOptions.paActions[0].wParam = poOptions.paActions[0].lParam = 0;
+ poOptions.paActions[0].lchIcon = hCopyIcon;
+ CallService(MS_POPUP_REGISTERACTIONS,&poOptions.paActions,1);
+ }
+
+}
+
+int OnIconsChanged(WPARAM wParam, LPARAM lParam)
+{
+ if(ServiceExists(MS_SKIN2_ADDICON))
+ {
+ hPopupIcon = (HICON)CallService(MS_SKIN2_GETICON, 0, (LPARAM)"ckl_popup_icon");
+ hCopyIcon = (HICON)CallService(MS_SKIN2_GETICON, 0, (LPARAM)"ckl_copy_icon");
+ }
+ else
+ {
+ hPopupIcon = (HICON)LoadImage(hInst, MAKEINTRESOURCE(IDI_POPUPICON), IMAGE_ICON, 16, 16, 0);
+ hCopyIcon = (HICON)LoadImage(hInst, MAKEINTRESOURCE(IDI_COPYICON), IMAGE_ICON, 16, 16, 0);
+ }
+ RegPopupActions();
+ return 0;
+}
+
+
+int ModulesLoaded(WPARAM wParam,LPARAM lParam)
+{
+ int i,iRes;
+ DBVARIANT dbv = {0};
+ LPCTSTR ptszEmptySting=_T("");
+ LPTSTR ptszCurrLayout;
+ LPTSTR ptszTemp;
+
+ SKINICONDESC sid = {0};
+ CHAR szFile[MAX_PATH];
+
+
+ //Заполняем конфигурационные строки из базы. Если их там нет - генерируем.
+ for (i = 0;i < bLayNum; i++)
+ {
+ ptszCurrLayout=GenerateLayoutString(hklLayouts[i]);
+ ptszTemp=GetNameOfLayout(hklLayouts[i]);
+ iRes=DBGetContactSettingTString(NULL,ModuleName,ptszTemp,&dbv);
+ if (iRes!=0)
+ ptszLayStrings[i]=ptszCurrLayout;
+ else
+ if(_tcscmp((dbv.ptszVal),ptszEmptySting)==0)
+ {
+ ptszLayStrings[i]=ptszCurrLayout;
+ mir_free(dbv.ptszVal);
+ }
+ else
+ {
+ ptszLayStrings[i]=dbv.ptszVal;
+ if(_tcscmp(ptszCurrLayout,ptszLayStrings[i])==0)
+ DBDeleteContactSetting(NULL,ModuleName,ptszTemp);
+ mir_free(ptszCurrLayout);
+ }
+ mir_free(ptszTemp);
+ }
+
+ // Прочитаем основные настройки
+ ReadMainOptions();
+
+ // Прочитаем настройки попапов
+ ReadPopupOptions();
+
+ // Зарегим звук
+ SkinAddNewSoundEx(SND_ChangeLayout, Translate(ModuleName), Translate("Changing Layout"));
+ SkinAddNewSoundEx(SND_ChangeCase, Translate(ModuleName), Translate("Changing Case"));
+
+ // Хук на нажатие клавиши
+ kbHook_All=SetWindowsHookEx(WH_KEYBOARD,(HOOKPROC)Keyboard_Hook,NULL,GetCurrentThreadId());
+
+ // Зарегим сервисы
+ hChangeLayout=CreateServiceFunction(MS_CKL_CHANGELAYOUT, APIChangeLayout);
+ hGetLayoutOfText=CreateServiceFunction(MS_CKL_GETLAYOUTOFTEXT,APIGetLayoutOfText);
+ hChangeTextLayout=CreateServiceFunction(MS_CKL_CHANGETEXTLAYOUT,APIChangeTextLayout);
+
+ // IcoLib support
+ if(ServiceExists(MS_SKIN2_ADDICON))
+ {
+ GetModuleFileNameA(hInst, szFile, MAX_PATH);
+ sid.pszDefaultFile = szFile;
+ sid.cbSize = SKINICONDESC_SIZE;
+
+ sid.pszSection = Translate(ModuleName);
+ sid.pszDescription = Translate("Popup");
+ sid.pszName = "ckl_popup_icon";
+ sid.iDefaultIndex = -IDI_POPUPICON;
+ CallService(MS_SKIN2_ADDICON, 0, (LPARAM)&sid);
+
+ sid.pszDescription = Translate("Copy to clipboard");
+ sid.pszName = "ckl_copy_icon";
+ sid.iDefaultIndex = -IDI_COPYICON;
+ CallService(MS_SKIN2_ADDICON, 0, (LPARAM)&sid);
+
+ hIcoLibIconsChanged = HookEvent(ME_SKIN2_ICONSCHANGED, OnIconsChanged);
+ }
+ OnIconsChanged(0,0);
+ RegPopupActions();
+
+ //Поддержка Апдейтера
+ if(ServiceExists(MS_UPDATE_REGISTERFL))
+ {
+ #if defined (_UNICODE)
+ CallService(MS_UPDATE_REGISTERFL, (WPARAM)3632, (LPARAM)&pluginInfo);
+ #else
+ CallService(MS_UPDATE_REGISTERFL, (WPARAM)3631, (LPARAM)&pluginInfo);
+ #endif
+ }
+
+
+ DBWriteContactSettingDword(NULL,ModuleName,"CurrentVer",VERSION);
+
+
+ return 0;
+}
+
+int OnOptionsInitialise(WPARAM wParam, LPARAM lParam)
+{
+ OPTIONSDIALOGPAGE odp = {0};
+
+ odp.cbSize = sizeof(odp);
+ odp.hInstance = hInst;
+ odp.pszTemplate = MAKEINTRESOURCE(IDD_MAIN_OPTION_FORM);
+ odp.pszTitle = Translate(ModuleName);
+ odp.pszGroup = Translate("Plugins");
+ odp.flags=ODPF_BOLDGROUPS;
+ odp.pfnDlgProc = DlgMainProcOptions;
+ CallService(MS_OPT_ADDPAGE, wParam, (LPARAM)&odp);
+
+ if (ServiceExists(MS_POPUP_ADDPOPUP))
+ {
+ ZeroMemory(&odp,sizeof(odp));
+ odp.cbSize = sizeof(odp);
+ odp.hInstance = hInst;
+ odp.pszTemplate = MAKEINTRESOURCE(IDD_POPUP_OPTION_FORM);
+ odp.pszTitle = Translate(ModuleName);
+ odp.pszGroup = Translate("PopUps");
+ odp.flags=ODPF_BOLDGROUPS;
+ odp.pfnDlgProc = DlgPopupsProcOptions;
+ CallService(MS_OPT_ADDPAGE, wParam, (LPARAM)&odp);
+ }
+ return 0;
+}
+
+
+
+LRESULT CALLBACK Keyboard_Hook(int code, WPARAM wParam, LPARAM lParam)
+{
+ DWORD lcode;
+
+ if (code==HC_ACTION)
+ {
+ lcode=0;
+ if ((GetKeyState(VK_SHIFT)&0x8000)) lcode|=HOTKEYF_SHIFT;
+ if ((GetKeyState(VK_CONTROL)&0x8000)) lcode|=HOTKEYF_CONTROL;
+ if ((GetKeyState(VK_MENU)&0x8000)) lcode|=HOTKEYF_ALT;
+ if ((GetKeyState(VK_LWIN)&0x8000)||(GetKeyState(VK_RWIN)&0x8000)) lcode|=HOTKEYF_EXT;
+ lcode=lcode<<8;
+
+ if ((wParam!=VK_SHIFT)&&(wParam!=VK_MENU)&&(wParam!=VK_CONTROL)&&(wParam!=VK_LWIN)&&(wParam!=VK_RWIN))
+ lcode+=wParam;
+
+ // Проверка на пустой хоткей. Иначе - пиздец, как в версии 1.4
+ if (lcode!=0)
+ if ((lcode==moOptions.dwHotkey_Layout)&&(!(lParam&0x40000000)))
+ {
+ ChangeLayout(NULL,TOT_Layout,moOptions.CurrentWordLayout);
+ return 1;
+ }
+ else
+ if ((lcode==moOptions.dwHotkey_Layout2)&&(!(lParam&0x40000000)))
+ {
+ ChangeLayout(NULL,TOT_Layout,moOptions.CurrentWordLayout2);
+ return 1;
+ }
+ else
+ if ((lcode==moOptions.dwHotkey_Case)&&(!(lParam&0x40000000)))
+ {
+ ChangeLayout(NULL,TOT_Case,moOptions.CurrentWordCase);
+ return 1;
+ }
+ }
+ return CallNextHookEx(kbHook_All, code, wParam, lParam);
+}
+
+int CALLBACK CKLPopupDlgProc(HWND hWnd, UINT uiMessage, WPARAM wParam, LPARAM lParam)
+{
+ LPTSTR ptszPopupText;
+
+ ptszPopupText=(LPTSTR)CallService(MS_POPUP_GETPLUGINDATA,(WPARAM)hWnd,(LPARAM)&ptszPopupText);
+ switch(uiMessage)
+ {
+ case WM_COMMAND:
+ {
+ if (HIWORD(wParam) == STN_CLICKED)
+ {
+ if (!IsBadStringPtr(ptszPopupText,MaxTextSize))
+ CopyTextToClipboard(ptszPopupText);
+ PUDeletePopUp(hWnd);
+
+ }
+ break;
+ }
+
+ case WM_CONTEXTMENU:
+ {
+ PUDeletePopUp(hWnd);
+ break;
+ }
+
+ case UM_POPUPACTION:
+ {
+ if ((lParam==0)&&(!IsBadStringPtr(ptszPopupText,MaxTextSize)))
+ {
+ CopyTextToClipboard(ptszPopupText);
+ }
+ break;
+ }
+
+ case UM_FREEPLUGINDATA:
+ {
+ mir_free(ptszPopupText);
+ return TRUE;
+ }
+
+ default:
+ break;
+ }
+ return DefWindowProc(hWnd, uiMessage, wParam, lParam);
+}
diff --git a/plugins/ChangeKeyboardLayout/hook_events.h b/plugins/ChangeKeyboardLayout/hook_events.h
new file mode 100644
index 0000000000..1db1f16f40
--- /dev/null
+++ b/plugins/ChangeKeyboardLayout/hook_events.h
@@ -0,0 +1,15 @@
+#ifndef M_CKL_HOOK_EVENTS_H
+#define M_CKL_HOOK_EVENTS_H
+
+#include "commonheaders.h"
+
+BOOL CoreCheck();
+void ReadMainOptions();
+void WriteMainOptions();
+void ReadPopupOptions();
+void WritePopupOptions();
+extern int OnOptionsInitialise(WPARAM wParam, LPARAM lParam);
+extern int ModulesLoaded(WPARAM wParam,LPARAM lParam);
+int CALLBACK CKLPopupDlgProc(HWND hWnd, UINT uiMessage, WPARAM wParam, LPARAM lParam);
+
+#endif \ No newline at end of file
diff --git a/plugins/ChangeKeyboardLayout/include/m_popup.h b/plugins/ChangeKeyboardLayout/include/m_popup.h
new file mode 100644
index 0000000000..8088ef7c9d
--- /dev/null
+++ b/plugins/ChangeKeyboardLayout/include/m_popup.h
@@ -0,0 +1,574 @@
+/*
+===============================================================================
+ PopUp plugin
+Plugin Name: PopUp
+Plugin authors: Luca Santarelli aka hrk (hrk@users.sourceforge.net)
+ Victor Pavlychko (nullbie@gmail.com)
+===============================================================================
+The purpose of this plugin is to give developers a common "platform/interface"
+to show PopUps. It is born from the source code of NewStatusNotify, another
+plugin I've made.
+
+Remember that users *must* have this plugin enabled, or they won't get any
+popup. Write this in the requirements, do whatever you wish ;-)... but tell
+them!
+===============================================================================
+*/
+
+#ifndef __m_popup_h__
+#define __m_popup_h__
+
+/*
+NOTE! Since Popup 1.0.1.2 there is a main meun group called "PopUps" where I
+have put a "Enable/Disable" item. You can add your own "enable/disable" items
+by adding these lines before you call MS_CLIST_ADDMAINMENUITEM:
+mi.pszPopUpName = Translate("PopUps");
+mi.position = 0; //You don't need it and it's better if you put it to zero.
+*/
+
+#ifndef POPUP_VERSION
+#define POPUP_VERSION 0x02010003
+#endif
+
+#define MAX_CONTACTNAME 2048
+#define MAX_SECONDLINE 2048
+#define MAX_ACTIONTITLE 64
+
+// Popup Action flags
+#define PAF_ENABLED 0x01 // Actions is enabled. You may store one global
+ // action set and toggle some items depending on
+ // popup you are requesting
+
+// ANSI Popup Action
+typedef struct
+{
+ int cbSize; // sizeof(POPUPACTION)
+ HICON lchIcon; // Action Icon
+ // Action title text. Please use module name as prefix
+ // (e.g. "Popup Plus/Dismiss Popup") and don't translate
+ // This is translates by popup. So no unicode.
+ char lpzTitle[MAX_ACTIONTITLE];
+ DWORD flags; // set of PAF_* flags
+ WPARAM wParam; // wParam for UM_POPUPACTION message
+ LPARAM lParam; // lParam for UM_POPUPACTION message
+} POPUPACTION, *LPPOPUPACTION;
+
+// This is the basic data you'll need to fill and pass to the service function.
+typedef struct
+{
+ HANDLE lchContact; // Handle to the contact, can be NULL (main contact).
+ HICON lchIcon; // Handle to a icon to be shown. Cannot be NULL.
+ union
+ {
+ char lptzContactName[MAX_CONTACTNAME]; // This is the contact name or the first line in the plugin. Cannot be NULL.
+ char lpzContactName[MAX_CONTACTNAME];
+ };
+ union
+ {
+ char lptzText[MAX_SECONDLINE]; // This is the second line text. Users can choose to hide it. Cannot be NULL.
+ char lpzText[MAX_SECONDLINE];
+ };
+ COLORREF colorBack; // COLORREF to be used for the background. Can be NULL, default will be used.
+ COLORREF colorText; // COLORREF to be used for the text. Can be NULL, default will be used.
+ WNDPROC PluginWindowProc; // Custom window proceudre. It *MUST* use stdcall (CALLBACK) convention. Please read docs.
+ void * PluginData; // Some custom data to store.
+} POPUPDATA, * LPPOPUPDATA;
+
+// Extended popup data
+typedef struct
+{
+ HANDLE lchContact;
+ HICON lchIcon;
+ union
+ {
+ char lptzContactName[MAX_CONTACTNAME];
+ char lpzContactName[MAX_CONTACTNAME];
+ };
+ union
+ {
+ char lptzText[MAX_SECONDLINE];
+ char lpzText[MAX_SECONDLINE];
+ };
+ COLORREF colorBack;
+ COLORREF colorText;
+ WNDPROC PluginWindowProc;
+ void * PluginData;
+ int iSeconds; // Custom delay time in seconds. -1 means "forever", 0 means "default time".
+
+#if POPUP_VERSION < 0x02010003
+ // For compatability
+ char cZero[16]; // Some unused bytes which may come useful in the future.
+
+#else
+ // you *MUST* pass APF_NEWDATA flag for services to take care of this data
+ HANDLE hNotification; // Reserved. Must be NULL
+ int actionCount; // Amount of passed actions
+ LPPOPUPACTION lpActions; // Popup Actions
+ int cbSize; // struct size for future
+#endif
+} POPUPDATAEX, *LPPOPUPDATAEX;
+
+// Unicode version of POPUPDATAEX
+typedef struct
+{
+ HANDLE lchContact;
+ HICON lchIcon;
+ union
+ {
+ WCHAR lptzContactName[MAX_CONTACTNAME];
+ WCHAR lpwzContactName[MAX_CONTACTNAME];
+ };
+ union
+ {
+ WCHAR lptzText[MAX_CONTACTNAME];
+ WCHAR lpwzText[MAX_CONTACTNAME];
+ };
+ COLORREF colorBack;
+ COLORREF colorText;
+ WNDPROC PluginWindowProc;
+ void * PluginData;
+ int iSeconds;
+#if POPUP_VERSION < 0x02010003
+ char cZero[16];
+#else
+ HANDLE hNotification;
+ int actionCount;
+ LPPOPUPACTION lpActions;
+ int cbSize;
+#endif
+} POPUPDATAW, *LPPOPUPDATAW;
+
+#if defined(_UNICODE) || defined(UNICODE)
+ typedef POPUPDATAW POPUPDATAT;
+ typedef LPPOPUPDATAW LPPOPUPDATAT;
+#else
+ typedef POPUPDATAEX POPUPDATAT;
+ typedef LPPOPUPDATAEX LPPOPUPDATAT;
+#endif
+
+/* PopUp/AddPopup
+Creates, adds and shows a popup, given a (valid) POPUPDATA structure pointer.
+
+wParam = (WPARAM)(*POPUPDATA)PopUpDataAddress
+lParam = 0
+
+Returns: > 0 on success, 0 if creation went bad, -1 if the PopUpData contained unacceptable values.
+NOTE: it returns -1 if the PopUpData was not valid, if there were already too many popups, if the module was disabled.
+Otherwise, it can return anything else...
+
+Popup Plus 2.0.4.0+
+You may pass additional creation flags via lParam:
+ APF_RETURN_HWND ....... function returns handle to newly created popup window (however this calls are a bit slower)
+ APF_CUSTOM_POPUP ...... new popup is created in hidden state and doesn't obey to popup queue rules.
+ you may control it via UM_* messages and custom window procedure (not yet implemented)
+ APF_NO_HISTORY ........ do not log this popup in popup history (useful for previews)
+ APF_NO_POPUP .......... do not show popup. this is useful if you want popup yo be stored in history only
+ APF_NEWDATA ........... use new version of POPUPDATAEX/POPUPDATAW structs
+*/
+#define APF_RETURN_HWND 0x01
+#define APF_CUSTOM_POPUP 0x02
+#define APF_NO_HISTORY 0x04
+#define APF_NO_POPUP 0x08
+#define APF_NEWDATA 0x10
+
+#define MS_POPUP_ADDPOPUP "PopUp/AddPopUp"
+static int __inline PUAddPopUp(POPUPDATA* ppdp) {
+ return CallService(MS_POPUP_ADDPOPUP, (WPARAM)ppdp,0);
+}
+
+#define MS_POPUP_ADDPOPUPEX "PopUp/AddPopUpEx"
+static int __inline PUAddPopUpEx(POPUPDATAEX* ppdp) {
+ return CallService(MS_POPUP_ADDPOPUPEX, (WPARAM)ppdp,0);
+}
+
+#define MS_POPUP_ADDPOPUPW "PopUp/AddPopUpW"
+static int __inline PUAddPopUpW(POPUPDATAW* ppdp) {
+ return CallService(MS_POPUP_ADDPOPUPW, (WPARAM)ppdp,0);
+}
+
+#if defined(_UNICODE) || defined(UNICODE)
+ #define MS_POPUP_ADDPOPUPT MS_POPUP_ADDPOPUPW
+ #define PUAddPopUpT PUAddPopUpW
+#else
+ #define MS_POPUP_ADDPOPUPT MS_POPUP_ADDPOPUPEX
+ #define PUAddPopUpT PUAddPopUpEx
+#endif
+
+
+/* PopUp/GetContact
+Returns the handle to the contact associated to the specified PopUpWindow.
+
+wParam = (WPARAM)(HWND)hPopUpWindow
+lParam = 0;
+
+Returns: the HANDLE of the contact. Can return NULL, meaning it's the main contact. -1 means failure.
+*/
+#define MS_POPUP_GETCONTACT "PopUp/GetContact"
+static HANDLE __inline PUGetContact(HWND hPopUpWindow) {
+ return (HANDLE)CallService(MS_POPUP_GETCONTACT, (WPARAM)hPopUpWindow,0);
+}
+
+/* PopUp/GetPluginData
+Returns custom plugin date associated with popup
+
+wParam = (WPARAM)(HWND)hPopUpWindow
+lParam = (LPARAM)(PLUGINDATA*)PluginDataAddress;
+
+Returns: the address of the PLUGINDATA structure. Can return NULL, meaning nothing was given. -1 means failure.
+
+IMPORTANT NOTE: it doesn't seem to work if you do:
+CallService(..., (LPARAM)aPointerToAStruct);
+and then use that struct.
+Do this, instead:
+aPointerToStruct = CallService(..., (LPARAM)aPointerToAStruct);
+and it will work. Just look at the example I've written above (PopUpDlgProc).
+
+*/
+#define MS_POPUP_GETPLUGINDATA "PopUp/GetPluginData"
+static void __inline * PUGetPluginData(HWND hPopUpWindow) {
+ long * uselessPointer = NULL;
+ return (void*)CallService(MS_POPUP_GETPLUGINDATA,(WPARAM)hPopUpWindow,(LPARAM)uselessPointer);
+}
+
+/* PopUp/IsSecondLineShown
+Checks if second line is enable
+
+wParam = 0
+lParam = 0
+
+Returns: 0 if the user has chosen not to have the second line, 1 if he choose to have the second line.
+*/
+#define MS_POPUP_ISSECONDLINESHOWN "PopUp/IsSecondLineShown"
+static BOOL __inline PUIsSecondLineShown() {
+ return (BOOL)CallService(MS_POPUP_ISSECONDLINESHOWN,0,0);
+}
+
+/* PopUp/Query
+
+Requests an action or an answer from PopUp module.
+
+wParam = (WPARAM)wpQuery
+
+returns 0 on success, -1 on error, 1 on stupid calls ;-)
+*/
+
+#define PUQS_ENABLEPOPUPS 1 // returns 0 if state was changed, 1 if state wasn't changed
+#define PUQS_DISABLEPOPUPS 2 // " "
+#define PUQS_GETSTATUS 3 //Returns 1 (TRUE) if popups are enabled, 0 (FALSE) if popups are disabled.
+
+#define MS_POPUP_QUERY "PopUp/Query"
+
+/* UM_FREEPLUGINDATA
+Process this message if you have allocated your own memory. (i.e.: POPUPDATA.PluginData != NULL)
+
+wParam = 0
+lParam = 0
+*/
+#define UM_FREEPLUGINDATA (WM_USER + 0x0200)
+
+/* UM_DESTROYPOPUP
+Send this message when you want to destroy the popup, or use the function below.
+
+wParam = 0
+lParam = 0
+*/
+#define UM_DESTROYPOPUP (WM_USER + 0x0201)
+static int __inline PUDeletePopUp(HWND hWndPopUp) {
+ return (int)SendMessage(hWndPopUp, UM_DESTROYPOPUP,0,0);
+}
+
+/* UM_INITPOPUP
+This message is sent to the PopUp when its creation has been finished, so POPUPDATA (and thus your PluginData) is reachable.
+Catch it if you needed to catch WM_CREATE or WM_INITDIALOG, which you'll never ever get in your entire popup-life.
+Return value: if you process this message, return 0. If you don't process it, return 0. Do whatever you like ;-)
+
+wParam = (WPARAM)(HWND)hPopUpWindow (this is useless, you get message inside your popup window)
+lParam = 0
+*/
+#define UM_INITPOPUP (WM_USER + 0x0202)
+
+/* PopUp/Changetext
+Changes the text displayed in the second line of the popup.
+
+wParam = (WPARAM)(HWND)hPopUpWindow
+lParam = (LPARAM)(char*)lpzNewText
+
+returns: > 0 for success, -1 for failure, 0 if the failure is due to second line not being shown. (but you could call
+PUIsSecondLineShown() before changing the text...)
+*/
+#define MS_POPUP_CHANGETEXT "PopUp/Changetext"
+static int __inline PUChangeText(HWND hWndPopUp, LPCTSTR lpzNewText) {
+ return (int)CallService(MS_POPUP_CHANGETEXT, (WPARAM)hWndPopUp, (LPARAM)lpzNewText);
+}
+
+#define MS_POPUP_CHANGETEXTW "PopUp/ChangetextW"
+static int __inline PUChangeTextW(HWND hWndPopUp, LPCWSTR lpwzNewText) {
+ return (int)CallService(MS_POPUP_CHANGETEXTW, (WPARAM)hWndPopUp, (LPARAM)lpwzNewText);
+}
+
+#if defined(_UNICODE) || defined(UNICODE)
+ #define MS_POPUP_CHANGETEXTT MS_POPUP_CHANGETEXTW
+ #define PUChangeTextT PUChangeTextW
+#else
+ #define MS_POPUP_CHANGETEXTT MS_POPUP_CHANGETEXT
+ #define PUChangeTextT PUChangeText
+#endif
+
+/* PopUp/Change
+Changes the entire popup
+
+wParam = (WPARAM)(HWND)hPopUpWindow
+lParam = (LPARAM)(POPUPDATAEX*)newData
+*/
+#define MS_POPUP_CHANGE "PopUp/Change"
+static int __inline PUChange(HWND hWndPopUp, POPUPDATAEX *newData) {
+ return (int)CallService(MS_POPUP_CHANGE, (WPARAM)hWndPopUp, (LPARAM)newData);
+}
+
+#define MS_POPUP_CHANGEW "PopUp/ChangeW"
+static int __inline PUChangeW(HWND hWndPopUp, POPUPDATAW *newData) {
+ return (int)CallService(MS_POPUP_CHANGE, (WPARAM)hWndPopUp, (LPARAM)newData);
+}
+
+#if defined(_UNICODE) || defined(UNICODE)
+ #define MS_POPUP_CHANGET MS_POPUP_CHANGEW
+ #define PUChangeT PUChangeW
+#else
+ #define MS_POPUP_CHANGET MS_POPUP_CHANGE
+ #define PUChangeT PUChange
+#endif
+
+/* UM_CHANGEPOPUP
+This message is triggered by Change/ChangeText services. You also may post it directly, but make
+sure you allocate memory via miranda mmi, because popup will mir_free() them!
+
+wParam = Modification type
+lParam = value of type defined by wParam
+*/
+
+#define CPT_TEXT 1 // lParam = (char *)text
+#define CPT_TEXTW 2 // lParam = (WCHAR *)text
+#define CPT_TITLE 3 // lParam = (char *)title
+#define CPT_TITLEW 4 // lParam = (WCHAR *)title
+#define CPT_DATA 5 // lParam = (POPUPDATA *)data
+#define CPT_DATAEX 6 // lParam = (POPUPDATAEX *)data
+#define CPT_DATAW 7 // lParam = (POPUPDATAW *)data
+#define CPT_DATA2 8 // lParam = (POPUPDATA2 *)data -- see m_popup2.h for details
+
+#define UM_CHANGEPOPUP (WM_USER + 0x0203)
+
+#if defined(_UNICODE) || defined(UNICODE)
+ #define CPT_TEXTT CPT_TEXTW
+ #define CPT_TITLET CPT_TITLEW
+ #define CPT_DATAT CPT_DATAW
+#else
+ #define CPT_TEXTT CPT_TEXT
+ #define CPT_TITLET CPT_TITLE
+ #define CPT_DATAT CPT_DATA
+#endif
+
+/* UM_POPUPACTION
+Popup Action notification
+
+wParam and lParam are specified bu plugin.
+wParam = 0 is used buy popup plus internally!
+*/
+
+#define UM_POPUPACTION (WM_USER + 0x0204)
+
+/* UM_POPUPMODIFYACTIONICON
+Modify Popup Action Icon
+
+wParam = (WPARAM)(LPPOPUPACTIONID)&actionId
+lParam = (LPARAM)(HICON)hIcon
+*/
+
+typedef struct
+{
+ WPARAM wParam;
+ LPARAM lParam;
+} POPUPACTIONID, *LPPOPUPACTIONID;
+
+#define UM_POPUPMODIFYACTIONICON (WM_USER + 0x0205)
+
+/* UM_POPUPSHOW
+Show popup at position
+
+wParam = x
+lParam = y
+*/
+#define UM_POPUPSHOW (WM_USER + 0x0206)
+
+#define MS_POPUP_CHANGEW "PopUp/ChangeW"
+static int __inline PUModifyActionIcon(HWND hWndPopUp, WPARAM wParam, LPARAM lParam, HICON hIcon) {
+ POPUPACTIONID actionId = { wParam, lParam };
+ return (int)SendMessage(hWndPopUp, UM_POPUPMODIFYACTIONICON, (WPARAM)&actionId, (LPARAM)hIcon);
+}
+
+/* PopUp/ShowMessage
+This is mainly for developers.
+Shows a warning message in a PopUp. It's useful if you need a "MessageBox" like function, but you don't want a modal
+window (which will interfere with a DialogProcedure. MessageBox steals focus and control, this one not.
+
+wParam = (char *)lpzMessage
+lParam = 0;
+
+Returns: 0 if the popup was shown, -1 in case of failure.
+*/
+#define SM_WARNING 0x01 //Triangle icon.
+#define SM_NOTIFY 0x02 //Exclamation mark icon.
+#define SM_ERROR 0x03 //Cross icon.
+#define MS_POPUP_SHOWMESSAGE "PopUp/ShowMessage"
+
+static int __inline PUShowMessage(char *lpzText, DWORD kind) {
+ return (int)CallService(MS_POPUP_SHOWMESSAGE, (WPARAM)lpzText,(LPARAM)kind);
+}
+
+/* PopUp/RegisterActions
+Registers your action in popup action list
+
+wParam = (WPARAM)(LPPOPUPACTION)actions
+lParam = (LPARAM)actionCount
+
+Returns: 0 if the popup was shown, -1 in case of failure.
+*/
+#define MS_POPUP_REGISTERACTIONS "PopUp/RegisterActions"
+
+static int __inline PURegisterActions(LPPOPUPACTION actions, int count) {
+ return (int)CallService(MS_POPUP_REGISTERACTIONS, (WPARAM)actions,(LPARAM)count);
+}
+
+/* PopUp/RegisterNotification
+Registers your action in popup action list
+
+wParam = (WPARAM)(LPPOPUPNOTIFICATION)info
+lParam = 0
+
+Returns: handle of registered notification or sero on failure
+*/
+#define MS_POPUP_REGISTERNOTIFICATION "PopUp/RegisterNotification"
+
+#define PNAF_CALLBACK 0x01
+
+#define POPUP_ACTION_NOTHING "Do nothing"
+#define POPUP_ACTION_DISMISS "Dismiss popup"
+
+typedef struct
+{
+ char lpzTitle[64];
+ DWORD dwFlags;
+ union
+ {
+ struct
+ {
+ char lpzLModule[MAXMODULELABELLENGTH];
+ char lpzLSetting[MAXMODULELABELLENGTH];
+ DBVARIANT dbvLData;
+ char lpzRModule[MAXMODULELABELLENGTH];
+ char lpzRSetting[MAXMODULELABELLENGTH];
+ DBVARIANT dbvRData;
+ };
+ struct
+ {
+ DWORD dwCookie;
+ void (*pfnCallback)(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam, DWORD cookie);
+ };
+ };
+} POPUPNOTIFYACTION, *LPPOPUPNOTIFYACTION;
+
+#define PNF_CONTACT 0x01
+
+typedef struct
+{
+ int cbSize;
+ DWORD dwFlags; // set of PNF_* flags
+ char lpzGroup[MAXMODULELABELLENGTH];
+ char lpzName[MAXMODULELABELLENGTH];
+ HICON lchIcon; // this will be registered in icolib
+ COLORREF colorBack; // this will be registered in fontservice
+ COLORREF colorText; // this will be registered in fontservice
+ int iSeconds; // default timeout
+ int actionCount; // for unified action comboboxes
+ LPPOPUPNOTIFYACTION lpActions;
+ char *lpzLAction;
+ char *lpzRAction;
+ char *pszReserved1; // reserved for future use
+ DLGPROC pfnReserved2; // reserved for future use
+} POPUPNOTIFICATION, *LPPOPUPNOTIFICATION;
+
+static HANDLE __inline PURegisterNotification(LPPOPUPNOTIFICATION notification) {
+ return (HANDLE)CallService(MS_POPUP_REGISTERNOTIFICATION, (WPARAM)notification, (LPARAM)0);
+}
+
+/* PopUp/UnhookEventAsync
+Using of "UnhookEvent" inside PluginWindowProc in conjunction with HookEventMessage
+may cause deadlocks. Use this service instead. It will queue event unhook into main
+thread and notify you when everything has finished.
+
+Deadlock scenario:
+ 1. Event is fired with NotifyEventHooks in the main thread
+ 2. Miranda core calls EnterCriticalSection(csHooks) and starts notifications
+ 3. You decide to unhook event, therefore call UnhookEvent
+ 4. Miranda core *INSIDE YOUR THREAD* calls EnterCriticalSection(csHooks) and
+ waits for main thread to finish processing
+ 5. Main thread calls SendMessage(hwnd, ...) to notify your window
+ 6. Your window's thread is busy waiting for main thread to leave critical section
+ 7. deadlock....
+
+wParam = (WPARAM)(HWND)hwndPopup
+lParam = (LPARAM)(HANDLE)hEvent
+
+Returns: 0 if everything gone ok. -1 if service was not found (and unsafe unhook was performed)
+*/
+
+#define MS_POPUP_UNHOOKEVENTASYNC "PopUp/UnhookEventAsync"
+
+/* UM_POPUPUNHOOKCOMPLETE
+Modify Popup Action Icon
+
+wParam = 0
+lParam = (LPARAM)(HANDLE)hEventUnhooked
+*/
+#define UM_POPUPUNHOOKCOMPLETE (WM_USER + 0x0206)
+
+static int __inline PUUnhookEventAsync(HWND hwndPopup, HANDLE hEvent) {
+ if (ServiceExists(MS_POPUP_UNHOOKEVENTASYNC))
+ return (int)CallService(MS_POPUP_UNHOOKEVENTASYNC, (WPARAM)hwndPopup,(LPARAM)hEvent);
+
+ // old popup plugins: unhook service not found
+ UnhookEvent(hEvent);
+ PostMessage(hwndPopup, UM_POPUPUNHOOKCOMPLETE, 0, (LPARAM)hEvent);
+ return 0;
+}
+
+#ifdef __cplusplus
+/* PopUp/RegisterVfx
+Register new animation (fade in/out) effect
+wParam = 0
+lParam = (LPARAM)(char *)vfx_name
+*/
+
+#define MS_POPUP_REGISTERVFX "PopUp/RegisterVfx"
+
+/* PopUp/Vfx/<vfx_name>
+Define this service to create vfx instance
+wParam = 0
+lParam = 0
+return = (int)(IPopupPlusEffect *)vfx
+*/
+
+#define MS_POPUP_CREATEVFX "PopUp/Vfx/"
+
+class IPopupPlusEffect
+{
+public:
+ virtual void beginEffect(int w, int h, int alpha0, int alpha1, int frameCount) = 0;
+ virtual void beginFrame(int frame) = 0;
+ virtual int getPixelAlpha(int x, int y) = 0;
+ virtual void endFrame() = 0;
+ virtual void endEffect() = 0;
+ virtual void destroy() = 0;
+};
+#endif // __cplusplus
+
+#endif // __m_popup_h__
diff --git a/plugins/ChangeKeyboardLayout/m_changekeyboardlayout.h b/plugins/ChangeKeyboardLayout/m_changekeyboardlayout.h
new file mode 100644
index 0000000000..9e565ec2e1
--- /dev/null
+++ b/plugins/ChangeKeyboardLayout/m_changekeyboardlayout.h
@@ -0,0 +1,32 @@
+#ifndef _M_CHANGEKEYBOARDLAYOUT_H
+#define _M_CHANGEKEYBOARDLAYOUT_H
+
+#define MIID_CKL_UNICODE {0xc5ef53a8, 0x80d4, 0x4ce9, { 0xb3, 0x41, 0xec, 0x90, 0xd3, 0xec, 0x91, 0x56 }} //{c5ef53a8-80d4-4ce9-b341-ec90d3ec9156}
+#define MIID_CKL_ANSI {0x87af74ba, 0x035c, 0x4d0d, { 0xb6, 0x8d, 0xd0, 0xd6, 0xae, 0x1e, 0xbf, 0xcd }} //{87af74ba-035c-4d0d-b68d-d0d6ae1ebfcd}
+// Меняет раскладку текста для окна с указанных хэндлом
+// wParam - HWND окна, или NULL для окна в фокусе
+// lParam должен быть 0
+// Возвращает 0 в случае успеха и ненулевое значение (1) при ошибке.
+// Примечание: Режим "текущего слова" определяется по соответствующей опции для основной горячей клавиши.
+#define MS_CKL_CHANGELAYOUT "ChangeKeyboardLayout/ChangeLayout"
+
+//wParam должен быть ноль.
+//lParam - LPCTSTR текста, раскладку которого требуется определить,
+//Возвращает HKL раскладку текста, или NULL в случае ошибки.
+//Примечание: При определении раскладки учитывается опция "Раскладка текста - текущая раскладка"
+#define MS_CKL_GETLAYOUTOFTEXT "ChangeKeyboardLayout/GetLayoutOfText"
+
+typedef struct
+{
+ HKL hklFrom; //layout of the current text
+ HKL hklTo; //layout of the result text
+ BOOL bTwoWay;
+}CKLLayouts;
+
+//wParam - LPCTSTR исходного текста
+//lParam - указатель на структуру CKLLayouts, содержащую раскладки для
+//изменения текста и опцию "двунаправленного преобразования"
+//Возвращает LPTSTR на результирующую строку
+#define MS_CKL_CHANGETEXTLAYOUT "ChangeKeyboardLayout/ChangeTextLayout"
+
+#endif \ No newline at end of file
diff --git a/plugins/ChangeKeyboardLayout/main.c b/plugins/ChangeKeyboardLayout/main.c
new file mode 100644
index 0000000000..5aabf34801
--- /dev/null
+++ b/plugins/ChangeKeyboardLayout/main.c
@@ -0,0 +1,123 @@
+#include "commonheaders.h"
+
+struct MM_INTERFACE mmi;
+PLUGINLINK *pluginLink;
+int hLangpack;
+
+PLUGININFOEX pluginInfoEx={
+ sizeof(PLUGININFOEX),
+ #if defined (_UNICODE)
+ "Change Keyboard Layout (Unicode)",
+ #else
+ "Change Keyboard Layout (ANSI)",
+ #endif
+ VERSION,
+ "Plugin for change keyboard layout of text (multilayout).",
+ "Yasnovidyashii",
+ "Yasnovidyashii@gmail.com",
+ "© 2006-2009 Mikhail Yur'ev",
+ "http://lemnews.com/forum/viewtopic.php?t=1493",
+ 0, //not transient
+ 0, //doesn't replace anything built-in
+ #if defined (_UNICODE)
+ MIID_CKL_UNICODE
+ #else
+ MIID_CKL_ANSI
+ #endif
+
+};
+
+PLUGININFO pluginInfo={
+ sizeof(PLUGININFO),
+ #if defined (_UNICODE)
+ "Change Keyboard Layout (UNICODE)",
+ #else
+ "Change Keyboard Layout (ANSI)",
+ #endif
+ VERSION,
+ "Plugin for change keyboard layout of text (multilayout)",
+ "Yasnovidyashii",
+ "Yasnovidyashii@gmail.com",
+ "© 2006-2009 Mikhail Yur'ev",
+ "http://lemnews.com/forum/viewtopic.php?t=1493",
+ 0, //not transient
+ 0 //doesn't replace anything built-in
+};
+
+
+LPCTSTR ptszKeybEng=_T("`1234567890-=\\qwertyuiop[]asdfghjkl;'zxcvbnm,./~!@#$%^&*()_+|QWERTYUIOP{}ASDFGHJKL:\"ZXCVBNM<>?");
+HKL hklEng=(HKL)0x04090409;
+
+LPCTSTR ptszSeparators=_T(" \t\n\r");
+
+HANDLE hOptionsInitialize;
+HANDLE hModulesLoaded;
+
+
+BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved)
+{
+ hInst=hinstDLL;
+ return TRUE;
+}
+
+
+__declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion)
+{
+ dwMirandaVersion = mirandaVersion;
+ return &pluginInfoEx;
+}
+
+__declspec(dllexport) PLUGININFO* MirandaPluginInfo(DWORD mirandaVersion)
+{
+ dwMirandaVersion = mirandaVersion;
+ return &pluginInfo;
+}
+
+
+#if defined (_UNICODE)
+ static const MUUID interfaces[] = {MIID_CKL_UNICODE, MIID_LAST};
+#else
+ static const MUUID interfaces[] = {MIID_CKL_ANSI, MIID_LAST};
+#endif
+
+__declspec(dllexport) const MUUID* MirandaPluginInterfaces(void)
+{
+ #if defined (_UNICODE)
+ pluginInfoEx.flags = 1; // dynamic UNICODE_AWARE
+ #endif
+ return interfaces;
+}
+
+
+int __declspec(dllexport) Load(PLUGINLINK *link)
+{
+ pluginLink=link;
+ mir_getMMI(&mmi);
+ mir_getLP(&pluginInfoEx);
+ ZeroMemory(hklLayouts, 20 * sizeof(HKL));
+ bLayNum=GetKeyboardLayoutList(20,hklLayouts);
+ if (bLayNum<2)
+ return 1;
+ hOptionsInitialize = HookEvent(ME_OPT_INITIALISE, OnOptionsInitialise);
+ hModulesLoaded = HookEvent(ME_SYSTEM_MODULESLOADED,ModulesLoaded);
+ return 0;
+}
+
+int __declspec(dllexport) Unload(void)
+{
+ DWORD i;
+
+ for (i=0;i<bLayNum;i++)
+ mir_free(ptszLayStrings[i]);
+
+ UnhookEvent(hOptionsInitialize);
+ UnhookEvent(hIcoLibIconsChanged);
+ UnhookEvent(hModulesLoaded);
+ DestroyServiceFunction(hChangeLayout);
+ DestroyServiceFunction(hGetLayoutOfText);
+ DestroyServiceFunction(hChangeTextLayout);
+ UnhookWindowsHookEx(kbHook_All);
+ return 0;
+}
+
+
diff --git a/plugins/ChangeKeyboardLayout/options.c b/plugins/ChangeKeyboardLayout/options.c
new file mode 100644
index 0000000000..a8d8fb7b91
--- /dev/null
+++ b/plugins/ChangeKeyboardLayout/options.c
@@ -0,0 +1,499 @@
+#include "options.h"
+
+
+int CALLBACK DlgMainProcOptions(HWND hWnd, UINT uiMessage, WPARAM wParam, LPARAM lParam)
+{
+ static BOOL MainDialogLock=FALSE;
+ LPTSTR ptszGenLay,ptszMemLay,ptszFormLay,ptszShortNameLay,ptszNameLay;
+ BYTE i;
+
+ switch (uiMessage)
+ {
+ case WM_INITDIALOG:
+ {
+ MainDialogLock=TRUE;
+ TranslateDialogDefault(hWnd);
+
+ //Горячие клавиши
+ // Запрещаем вводить в контролы все, кроме обычных кнопок
+ SendDlgItemMessage(hWnd, IDC_HOTKEY_LAYOUT, HKM_SETRULES,0xFF, 0);
+ SendDlgItemMessage(hWnd, IDC_HOTKEY_LAYOUT2, HKM_SETRULES,0xFF, 0);
+ SendDlgItemMessage(hWnd, IDC_HOTKEY_CASE, HKM_SETRULES,0xFF, 0);
+
+ //Отображаем управляющие клавиши
+ SendDlgItemMessage(hWnd, IDC_CHECK_LAYOUT_SHIFT, BM_SETCHECK,(moOptions.dwHotkey_Layout&0x00000100),0);
+ SendDlgItemMessage(hWnd, IDC_CHECK_LAYOUT_CTRL, BM_SETCHECK,(moOptions.dwHotkey_Layout&0x00000200),0);
+ SendDlgItemMessage(hWnd, IDC_CHECK_LAYOUT_ALT, BM_SETCHECK,(moOptions.dwHotkey_Layout&0x00000400),0);
+ SendDlgItemMessage(hWnd, IDC_CHECK_LAYOUT_WIN, BM_SETCHECK,(moOptions.dwHotkey_Layout&0x00000800),0);
+
+ SendDlgItemMessage(hWnd, IDC_CHECK_LAYOUT2_SHIFT, BM_SETCHECK,(moOptions.dwHotkey_Layout2&0x00000100),0);
+ SendDlgItemMessage(hWnd, IDC_CHECK_LAYOUT2_CTRL, BM_SETCHECK,(moOptions.dwHotkey_Layout2&0x00000200),0);
+ SendDlgItemMessage(hWnd, IDC_CHECK_LAYOUT2_ALT, BM_SETCHECK,(moOptions.dwHotkey_Layout2&0x00000400),0);
+ SendDlgItemMessage(hWnd, IDC_CHECK_LAYOUT2_WIN, BM_SETCHECK,(moOptions.dwHotkey_Layout2&0x00000800),0);
+
+ SendDlgItemMessage(hWnd, IDC_CHECK_CASE_SHIFT, BM_SETCHECK,(moOptions.dwHotkey_Case&0x00000100),0);
+ SendDlgItemMessage(hWnd, IDC_CHECK_CASE_CTRL, BM_SETCHECK,(moOptions.dwHotkey_Case&0x00000200),0);
+ SendDlgItemMessage(hWnd, IDC_CHECK_CASE_ALT, BM_SETCHECK,(moOptions.dwHotkey_Case&0x00000400),0);
+ SendDlgItemMessage(hWnd, IDC_CHECK_CASE_WIN, BM_SETCHECK,(moOptions.dwHotkey_Case&0x00000800),0);
+
+ //Показываем символ из хоткея
+ SendDlgItemMessage(hWnd, IDC_HOTKEY_LAYOUT, HKM_SETHOTKEY, moOptions.dwHotkey_Layout&0x000000FF, 0);
+ SendDlgItemMessage(hWnd, IDC_HOTKEY_LAYOUT2, HKM_SETHOTKEY, moOptions.dwHotkey_Layout2&0x000000FF, 0);
+ SendDlgItemMessage(hWnd, IDC_HOTKEY_CASE, HKM_SETHOTKEY, moOptions.dwHotkey_Case&0x000000FF, 0);
+
+ //Остальные опции
+ SendDlgItemMessage(hWnd, IDC_CHECK_LAYOUT_MODE, BM_SETCHECK, moOptions.CurrentWordLayout, 0);
+ SendDlgItemMessage(hWnd, IDC_CHECK_LAYOUT_MODE2, BM_SETCHECK, moOptions.CurrentWordLayout2, 0);
+ SendDlgItemMessage(hWnd, IDC_CHECK_CASE_MODE, BM_SETCHECK, moOptions.CurrentWordCase, 0);
+ SendDlgItemMessage(hWnd, IDC_CHECK_TWOWAY, BM_SETCHECK, moOptions.TwoWay, 0);
+ SendDlgItemMessage(hWnd, IDC_CHECK_SYSTEMLAYOUT, BM_SETCHECK, moOptions.ChangeSystemLayout, 0);
+ SendDlgItemMessage(hWnd, IDC_CHECK_CLIPBOARD, BM_SETCHECK, moOptions.CopyToClipboard, 0);
+ SendDlgItemMessage(hWnd, IDC_CHECK_POPUP, BM_SETCHECK, moOptions.ShowPopup, 0);
+
+ //Смена состояния CapsLock
+ switch(moOptions.bCaseOperations)
+ {
+ case 1:
+ SendDlgItemMessage(hWnd, IDC_RADIO_OFFCAPS, BM_SETCHECK, 1, 0);
+ break;
+ case 2:
+ SendDlgItemMessage(hWnd, IDC_RADIO_IGNORECAPS, BM_SETCHECK, 1, 0);
+ break;
+ default:
+ SendDlgItemMessage(hWnd, IDC_RADIO_INVERTCAPS, BM_SETCHECK, 1, 0);
+ break;
+ }
+
+ // Отображаем пример конфиг.строки
+ ptszMemLay=ptszLayStrings[0];
+ SendDlgItemMessage(hWnd, IDC_EDIT_EXAMPLE,WM_SETTEXT,0,(LPARAM)ptszMemLay);
+ ptszShortNameLay=GetShortNameOfLayout(hklLayouts[0]);
+ SendDlgItemMessage(hWnd, IDC_STATIC_EXAMPLE, WM_SETTEXT,0,(LPARAM)ptszShortNameLay);
+ mir_free(ptszShortNameLay);
+
+ // Заполняем комбобокс с текущими раскладками
+ for(i = 0; i < bLayNum; i++)
+ {
+ ptszShortNameLay=GetShortNameOfLayout(hklLayouts[i]);
+ SendDlgItemMessage(hWnd, IDC_COMBO_LANG, CB_ADDSTRING,0,(LPARAM)ptszShortNameLay);
+ mir_free(ptszShortNameLay);
+ }
+ //Отображаем первую раскладку в списке
+ SendDlgItemMessage(hWnd, IDC_COMBO_LANG, CB_SETCURSEL,0,0);
+ ptszMemLay=ptszLayStrings[0];
+ SendDlgItemMessage(hWnd, IDC_EDIT_SET, WM_SETTEXT,0,(LPARAM)ptszMemLay);
+
+ if (bLayNum!=2) EnableWindow(GetDlgItem(hWnd, IDC_CHECK_TWOWAY),FALSE);
+ MainDialogLock=FALSE;
+ return TRUE;
+ }
+ case WM_COMMAND:
+ {
+ switch (LOWORD(wParam))
+ {
+ case IDC_HOTKEY_LAYOUT:
+ case IDC_HOTKEY_LAYOUT2:
+ case IDC_HOTKEY_CASE:
+
+ {
+ if ((HIWORD(wParam) == EN_CHANGE))
+ SendMessage(GetParent(hWnd), PSM_CHANGED, 0, 0);
+ break;
+ }
+ case IDC_CHECK_DETECT:
+ case IDC_CHECK_LAYOUT_MODE:
+ case IDC_CHECK_LAYOUT_MODE2:
+ case IDC_CHECK_CASE_MODE:
+ case IDC_CHECK_TWOWAY:
+ case IDC_CHECK_SYSTEMLAYOUT:
+ case IDC_CHECK_POPUP:
+ case IDC_CHECK_CLIPBOARD:
+ case IDC_CHECK_LAYOUT_SHIFT:
+ case IDC_CHECK_LAYOUT_ALT:
+ case IDC_CHECK_LAYOUT_CTRL:
+ case IDC_CHECK_LAYOUT_WIN:
+ case IDC_CHECK_LAYOUT2_SHIFT:
+ case IDC_CHECK_LAYOUT2_ALT:
+ case IDC_CHECK_LAYOUT2_CTRL:
+ case IDC_CHECK_LAYOUT2_WIN:
+ case IDC_CHECK_CASE_SHIFT:
+ case IDC_CHECK_CASE_ALT:
+ case IDC_CHECK_CASE_CTRL:
+ case IDC_CHECK_CASE_WIN:
+ case IDC_RADIO_IGNORECAPS:
+ case IDC_RADIO_INVERTCAPS:
+ case IDC_RADIO_OFFCAPS:
+
+ {
+ if ((HIWORD(wParam) == BN_CLICKED))
+ SendMessage(GetParent(hWnd), PSM_CHANGED, 0, 0);
+ break;
+ }
+ case IDC_COMBO_LANG:
+ {
+ if ((HIWORD(wParam) == CBN_SELCHANGE))
+ {
+ MainDialogLock=TRUE;
+ ptszMemLay=ptszLayStrings[SendDlgItemMessage(hWnd, IDC_COMBO_LANG,CB_GETCURSEL,0,0)];
+ SendDlgItemMessage(hWnd, IDC_EDIT_SET,WM_SETTEXT,0,(LPARAM)ptszMemLay);
+ MainDialogLock=FALSE;
+ }
+ break;
+ }
+ case IDC_EDIT_SET:
+ {
+ if ((HIWORD(wParam) == EN_CHANGE)&&(!MainDialogLock))
+ SendMessage(GetParent(hWnd), PSM_CHANGED, 0, 0);
+ break;
+ }
+
+ case IDC_BUTTON_DEFAULT:
+ {
+ if ((HIWORD(wParam) == BN_CLICKED ))
+ {
+ ptszGenLay=GenerateLayoutString(hklLayouts[SendDlgItemMessage(hWnd, IDC_COMBO_LANG,CB_GETCURSEL,0,0)]);
+ SendDlgItemMessage(hWnd, IDC_EDIT_SET,WM_SETTEXT,0,(LPARAM)ptszGenLay);
+ mir_free(ptszGenLay);
+ SendMessage(GetParent(hWnd), PSM_CHANGED, 0, 0);
+ }
+ break;
+ }
+
+ }
+ break;
+ }
+ case WM_NOTIFY:
+ {
+ switch(((LPNMHDR)lParam)->idFrom)
+ {
+ case 0:
+ {
+ switch (((LPNMHDR)lParam)->code)
+ {
+ case PSN_APPLY:
+ {
+ // Прочитаем хоткеи
+ moOptions.dwHotkey_Layout = SendDlgItemMessage(hWnd, IDC_HOTKEY_LAYOUT, HKM_GETHOTKEY, 0, 0);
+ moOptions.dwHotkey_Layout2 = SendDlgItemMessage(hWnd, IDC_HOTKEY_LAYOUT2, HKM_GETHOTKEY, 0, 0);
+ moOptions.dwHotkey_Case = SendDlgItemMessage(hWnd, IDC_HOTKEY_CASE, HKM_GETHOTKEY, 0, 0);
+
+ //Допишем к символам управляющие клавиши
+ if (SendDlgItemMessage(hWnd, IDC_CHECK_LAYOUT_SHIFT, BM_GETCHECK,0,0))
+ moOptions.dwHotkey_Layout|=0x00000100;
+ if (SendDlgItemMessage(hWnd, IDC_CHECK_LAYOUT_CTRL, BM_GETCHECK,0,0))
+ moOptions.dwHotkey_Layout|=0x00000200;
+ if (SendDlgItemMessage(hWnd, IDC_CHECK_LAYOUT_ALT, BM_GETCHECK,0,0))
+ moOptions.dwHotkey_Layout|=0x00000400;
+ if (SendDlgItemMessage(hWnd, IDC_CHECK_LAYOUT_WIN, BM_GETCHECK,0,0))
+ moOptions.dwHotkey_Layout|=0x00000800;
+
+ if (SendDlgItemMessage(hWnd, IDC_CHECK_LAYOUT2_SHIFT, BM_GETCHECK,0,0))
+ moOptions.dwHotkey_Layout2|=0x00000100;
+ if (SendDlgItemMessage(hWnd, IDC_CHECK_LAYOUT2_CTRL, BM_GETCHECK,0,0))
+ moOptions.dwHotkey_Layout2|=0x00000200;
+ if (SendDlgItemMessage(hWnd, IDC_CHECK_LAYOUT2_ALT, BM_GETCHECK,0,0))
+ moOptions.dwHotkey_Layout2|=0x00000400;
+ if (SendDlgItemMessage(hWnd, IDC_CHECK_LAYOUT2_WIN, BM_GETCHECK,0,0))
+ moOptions.dwHotkey_Layout2|=0x00000800;
+
+ if (SendDlgItemMessage(hWnd, IDC_CHECK_CASE_SHIFT, BM_GETCHECK,0,0))
+ moOptions.dwHotkey_Case|=0x00000100;
+ if (SendDlgItemMessage(hWnd, IDC_CHECK_CASE_CTRL, BM_GETCHECK,0,0))
+ moOptions.dwHotkey_Case|=0x00000200;
+ if (SendDlgItemMessage(hWnd, IDC_CHECK_CASE_ALT, BM_GETCHECK,0,0))
+ moOptions.dwHotkey_Case|=0x00000400;
+ if (SendDlgItemMessage(hWnd, IDC_CHECK_CASE_WIN, BM_GETCHECK,0,0))
+ moOptions.dwHotkey_Case|=0x00000800;
+
+
+ //Прочие опции
+ moOptions.CurrentWordLayout=SendDlgItemMessage(hWnd, IDC_CHECK_LAYOUT_MODE, BM_GETCHECK, 0, 0);
+ moOptions.CurrentWordLayout2=SendDlgItemMessage(hWnd, IDC_CHECK_LAYOUT_MODE2, BM_GETCHECK, 0, 0);
+ moOptions.CurrentWordCase=SendDlgItemMessage(hWnd, IDC_CHECK_CASE_MODE, BM_GETCHECK, 0, 0);
+ moOptions.TwoWay=SendDlgItemMessage(hWnd, IDC_CHECK_TWOWAY, BM_GETCHECK, 0, 0);
+ moOptions.ChangeSystemLayout=SendDlgItemMessage(hWnd, IDC_CHECK_SYSTEMLAYOUT, BM_GETCHECK, 0, 0);
+ moOptions.CopyToClipboard=SendDlgItemMessage(hWnd, IDC_CHECK_CLIPBOARD, BM_GETCHECK, 0, 0);
+ moOptions.ShowPopup=SendDlgItemMessage(hWnd, IDC_CHECK_POPUP, BM_GETCHECK, 0, 0);
+
+ // CapsLock
+ if (SendDlgItemMessage(hWnd, IDC_RADIO_OFFCAPS, BM_GETCHECK, 0, 0) == BST_CHECKED)
+ moOptions.bCaseOperations = 1;
+ else if (SendDlgItemMessage(hWnd, IDC_RADIO_IGNORECAPS, BM_GETCHECK, 0, 0) == BST_CHECKED)
+ moOptions.bCaseOperations = 2;
+ else moOptions.bCaseOperations = 0;
+
+ WriteMainOptions();
+
+ ptszFormLay=(LPTSTR)mir_alloc(MaxTextSize*sizeof(TCHAR));
+ SendDlgItemMessage(hWnd, IDC_EDIT_SET,WM_GETTEXT,(WPARAM) MaxTextSize,(LPARAM)ptszFormLay);
+ i=SendDlgItemMessage(hWnd, IDC_COMBO_LANG,CB_GETCURSEL,0,0);
+ ptszMemLay=ptszLayStrings[i];
+ if(_tcscmp(ptszMemLay,ptszFormLay)!=0)
+ {
+ _tcscpy(ptszMemLay,ptszFormLay);
+ ptszGenLay=GenerateLayoutString(hklLayouts[i]);
+ ptszNameLay=GetNameOfLayout(hklLayouts[i]);
+
+ if(_tcscmp(ptszMemLay,ptszGenLay)!=0)
+ DBWriteContactSettingTString(NULL,ModuleName,ptszNameLay,ptszMemLay);
+ else
+ DBDeleteContactSetting(NULL,ModuleName,ptszNameLay);
+
+ mir_free(ptszNameLay);
+ mir_free(ptszGenLay);
+ }
+ mir_free(ptszFormLay);
+
+ ptszMemLay=ptszLayStrings[0];
+ SendDlgItemMessage(hWnd, IDC_EDIT_EXAMPLE,WM_SETTEXT,0,(LPARAM)ptszMemLay);
+
+ UnhookWindowsHookEx(kbHook_All);
+ kbHook_All=SetWindowsHookEx(WH_KEYBOARD,(HOOKPROC)Keyboard_Hook,NULL,GetCurrentThreadId());
+
+ break;
+ }
+ }
+ break;
+ }
+ }
+ break;
+ }
+
+ case WM_DESTROY:
+ {
+ break;
+ }
+
+ }
+ return FALSE;
+}
+
+
+int CALLBACK DlgPopupsProcOptions(HWND hWnd, UINT uiMessage, WPARAM wParam, LPARAM lParam)
+{
+ POPUPDATAT pdtData;
+ static BOOL PopupDialogLock=FALSE;
+ LPTSTR ptszPopupPreviewText;
+ DWORD dwTimeOut;
+
+ switch (uiMessage)
+ {
+ case WM_INITDIALOG:
+ {
+ PopupDialogLock=TRUE;
+ TranslateDialogDefault(hWnd);
+ poOptionsTemp=poOptions;
+
+ //Цвета
+ SendDlgItemMessage(hWnd, IDC_CUSTOM_BACK, CPM_SETCOLOUR, 0, poOptionsTemp.crBackColour);
+ SendDlgItemMessage(hWnd, IDC_CUSTOM_TEXT, CPM_SETCOLOUR, 0, poOptionsTemp.crTextColour);
+ CheckDlgButton(hWnd,IDC_RADIO_COLOURS_POPUP,poOptionsTemp.bColourType==PPC_POPUP);
+ CheckDlgButton(hWnd,IDC_RADIO_COLOURS_WINDOWS,poOptionsTemp.bColourType==PPC_WINDOWS);
+ CheckDlgButton(hWnd,IDC_RADIO_COLOURS_CUSTOM,poOptionsTemp.bColourType==PPC_CUSTOM);
+ EnableWindow(GetDlgItem(hWnd,IDC_CUSTOM_BACK),poOptionsTemp.bColourType==PPC_CUSTOM);
+ EnableWindow(GetDlgItem(hWnd,IDC_CUSTOM_TEXT),poOptionsTemp.bColourType==PPC_CUSTOM);
+
+ // Таймаут
+ CheckDlgButton(hWnd,IDC_RADIO_TIMEOUT_POPUP,poOptionsTemp.bTimeoutType==PPT_POPUP);
+ CheckDlgButton(hWnd,IDC_RADIO_TIMEOUT_PERMANENT,poOptionsTemp.bTimeoutType==PPT_PERMANENT);
+ CheckDlgButton(hWnd,IDC_RADIO_TIMEOUT_CUSTOM,poOptionsTemp.bTimeoutType==PPT_CUSTOM);
+ SetDlgItemInt(hWnd, IDC_EDIT_TIMEOUT,poOptionsTemp.bTimeout,FALSE);
+ EnableWindow(GetDlgItem(hWnd, IDC_EDIT_TIMEOUT),poOptionsTemp.bTimeoutType==PPT_CUSTOM);
+
+ // Клик левой
+ CheckDlgButton(hWnd,IDC_RADIO_LEFT_CLIPBOARD,poOptionsTemp.bLeftClick==0);
+ CheckDlgButton(hWnd,IDC_RADIO_LEFT_DISMISS,poOptionsTemp.bLeftClick==1);
+ // Клик правой
+ CheckDlgButton(hWnd,IDC_RADIO_RIGHT_CLIPBOARD,poOptionsTemp.bRightClick==0);
+ CheckDlgButton(hWnd,IDC_RADIO_RIGHT_DISMISS,poOptionsTemp.bRightClick==1);
+ PopupDialogLock=FALSE;
+ return TRUE;
+ }
+
+ case WM_COMMAND:
+ {
+ switch (LOWORD(wParam))
+ {
+ case IDC_RADIO_COLOURS_POPUP:
+ case IDC_RADIO_COLOURS_WINDOWS:
+ case IDC_RADIO_COLOURS_CUSTOM:
+ {
+ if ((HIWORD(wParam) == BN_CLICKED))
+ {
+ if (IsDlgButtonChecked(hWnd,IDC_RADIO_COLOURS_POPUP))
+ poOptionsTemp.bColourType=PPC_POPUP;
+ else if (IsDlgButtonChecked(hWnd,IDC_RADIO_COLOURS_WINDOWS))
+ poOptionsTemp.bColourType=PPC_WINDOWS;
+ else if (IsDlgButtonChecked(hWnd,IDC_RADIO_COLOURS_CUSTOM))
+ poOptionsTemp.bColourType=PPC_CUSTOM;
+
+ EnableWindow(GetDlgItem(hWnd,IDC_CUSTOM_BACK),poOptionsTemp.bColourType==PPC_CUSTOM);
+ EnableWindow(GetDlgItem(hWnd,IDC_CUSTOM_TEXT),poOptionsTemp.bColourType==PPC_CUSTOM);
+ SendMessage(GetParent(hWnd), PSM_CHANGED, 0, 0);
+ }
+ }
+
+
+ case IDC_RADIO_TIMEOUT_POPUP:
+ case IDC_RADIO_TIMEOUT_PERMANENT:
+ case IDC_RADIO_TIMEOUT_CUSTOM:
+ {
+ if ((HIWORD(wParam) == BN_CLICKED))
+ {
+ if (IsDlgButtonChecked(hWnd,IDC_RADIO_TIMEOUT_POPUP))
+ poOptionsTemp.bTimeoutType=PPT_POPUP;
+ else if (IsDlgButtonChecked(hWnd,IDC_RADIO_TIMEOUT_PERMANENT))
+ poOptionsTemp.bTimeoutType=PPT_PERMANENT;
+ if (IsDlgButtonChecked(hWnd,IDC_RADIO_TIMEOUT_CUSTOM))
+ poOptionsTemp.bTimeoutType=PPT_CUSTOM;
+
+ EnableWindow(GetDlgItem(hWnd,IDC_EDIT_TIMEOUT),poOptionsTemp.bTimeoutType==PPT_CUSTOM);
+ SendMessage(GetParent(hWnd), PSM_CHANGED, 0, 0);
+ }
+ break;
+ }
+
+ case IDC_RADIO_LEFT_CLIPBOARD:
+ case IDC_RADIO_LEFT_DISMISS:
+ {
+ if ((HIWORD(wParam) == BN_CLICKED))
+ {
+ if (IsDlgButtonChecked(hWnd,IDC_RADIO_LEFT_CLIPBOARD))
+ poOptionsTemp.bLeftClick=0;
+ else if (IsDlgButtonChecked(hWnd,IDC_RADIO_LEFT_DISMISS))
+ poOptionsTemp.bLeftClick=1;
+ SendMessage(GetParent(hWnd), PSM_CHANGED, 0, 0);
+ }
+ break;
+ }
+
+ case IDC_RADIO_RIGHT_CLIPBOARD:
+ case IDC_RADIO_RIGHT_DISMISS:
+ {
+ if ((HIWORD(wParam) == BN_CLICKED))
+ {
+ if (IsDlgButtonChecked(hWnd,IDC_RADIO_RIGHT_CLIPBOARD))
+ poOptionsTemp.bRightClick=0;
+ else if (IsDlgButtonChecked(hWnd,IDC_RADIO_RIGHT_DISMISS))
+ poOptionsTemp.bRightClick=1;
+ SendMessage(GetParent(hWnd), PSM_CHANGED, 0, 0);
+ }
+ break;
+ }
+
+ case IDC_CUSTOM_BACK:
+ case IDC_CUSTOM_TEXT:
+ {
+ if (HIWORD(wParam)==CBN_SELCHANGE)
+ {
+ poOptionsTemp.crBackColour=SendDlgItemMessage(hWnd, IDC_CUSTOM_BACK, CPM_GETCOLOUR, 0, 0);
+ poOptionsTemp.crTextColour=SendDlgItemMessage(hWnd, IDC_CUSTOM_TEXT, CPM_GETCOLOUR, 0, 0);
+ SendMessage(GetParent(hWnd), PSM_CHANGED, 0, 0);
+ }
+ break;
+ }
+ case IDC_EDIT_TIMEOUT:
+ {
+ if (HIWORD(wParam)==EN_CHANGE)
+ {
+ dwTimeOut=GetDlgItemInt(hWnd, IDC_EDIT_TIMEOUT,NULL,FALSE);
+ if (dwTimeOut>255)
+ poOptionsTemp.bTimeout=255;
+ else
+ poOptionsTemp.bTimeout=dwTimeOut;
+
+ if (!PopupDialogLock)
+ SendMessage(GetParent(hWnd), PSM_CHANGED, 0, 0);
+ }
+ break;
+ }
+
+ case IDC_BUTTON_PREVIEW:
+ {
+ if ((HIWORD(wParam) == BN_CLICKED ))
+ {
+ ptszPopupPreviewText=(LPTSTR)mir_alloc(MaxTextSize*sizeof(TCHAR));
+
+ pdtData.cbSize = sizeof(POPUPDATAT);
+ ZeroMemory(&pdtData, sizeof(pdtData));
+ _tcsncpy(pdtData.lptzContactName,TranslateT(ModuleName), MAX_CONTACTNAME);
+ _tcsncpy(pdtData.lptzText, _T("Ghbdtn? rfr ltkf&"), MAX_SECONDLINE);
+
+ switch(poOptionsTemp.bColourType)
+ {
+ case PPC_POPUP:
+ pdtData.colorBack=pdtData.colorText=0;
+ break;
+ case PPC_WINDOWS:
+ pdtData.colorBack=GetSysColor(COLOR_BTNFACE);
+ pdtData.colorText=GetSysColor(COLOR_WINDOWTEXT);
+ break;
+ case PPC_CUSTOM:
+ pdtData.colorBack=poOptionsTemp.crBackColour;
+ pdtData.colorText=poOptionsTemp.crTextColour;
+ break;
+ default:
+ break;
+ }
+ switch(poOptionsTemp.bTimeoutType)
+ {
+ case PPT_POPUP:
+ pdtData.iSeconds=0;
+ break;
+ case PPT_PERMANENT:
+ pdtData.iSeconds=-1;
+ break;
+ case PPC_CUSTOM:
+ pdtData.iSeconds=poOptionsTemp.bTimeout;
+ break;
+ }
+ _tcscpy(ptszPopupPreviewText, pdtData.lptzText);
+ pdtData.PluginData=ptszPopupPreviewText;
+ pdtData.lchIcon = hPopupIcon;
+ poOptions.paActions[0].lchIcon = hCopyIcon;
+ pdtData.lpActions=poOptions.paActions;
+ pdtData.actionCount = 1;
+ pdtData.PluginWindowProc = (WNDPROC)CKLPopupDlgProc;
+
+ if (CallService(MS_POPUP_ADDPOPUPT, (WPARAM) &pdtData, APF_NEWDATA)<0)
+ mir_free(ptszPopupPreviewText);
+ }
+ break;
+ }
+
+ default:
+ break;
+ }
+ break;
+}
+
+ case WM_NOTIFY:
+ {
+ switch(((LPNMHDR)lParam)->idFrom)
+ {
+ case 0:
+ {
+ switch (((LPNMHDR)lParam)->code)
+ {
+ case PSN_APPLY:
+ {
+ poOptions=poOptionsTemp;
+ WritePopupOptions();
+ break;
+ }
+ }
+ break;
+ }
+ }
+ break;
+ }
+
+ case WM_DESTROY:
+ {
+ break;
+ }
+
+ }
+ return FALSE;
+}
+
diff --git a/plugins/ChangeKeyboardLayout/options.h b/plugins/ChangeKeyboardLayout/options.h
new file mode 100644
index 0000000000..b91a104deb
--- /dev/null
+++ b/plugins/ChangeKeyboardLayout/options.h
@@ -0,0 +1,9 @@
+#ifndef M_CKL_OPTIONS_H
+#define M_CKL_OPTIONS_H
+
+#include "commonheaders.h"
+
+int CALLBACK DlgMainProcOptions(HWND hWnd, UINT uiMessage, WPARAM wParam, LPARAM lParam);
+int CALLBACK DlgPopupsProcOptions(HWND hWnd, UINT uiMessage, WPARAM wParam, LPARAM lParam);
+
+#endif \ No newline at end of file
diff --git a/plugins/ChangeKeyboardLayout/resource.h b/plugins/ChangeKeyboardLayout/resource.h
new file mode 100644
index 0000000000..8ca2e0e8be
--- /dev/null
+++ b/plugins/ChangeKeyboardLayout/resource.h
@@ -0,0 +1,81 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by ChangeKeyboardLayout.rc
+//
+#define IDD_MAIN_OPTION_FORM 101
+#define IDD_POPUP_OPTION_FORM 102
+#define IDI_POPUPICON 103
+#define IDI_COPYICON 104
+#define IDB_BITMAP_WIN 110
+#define IDB_BITMAP_ALT 111
+#define IDB_BITMAP_CTRL 112
+#define IDB_BITMAP_SHIFT 113
+#define IDC_HOTKEY_LAYOUT 1002
+#define IDC_CHECK_DETECT 1003
+#define IDC_EDIT_EXAMPLE 1004
+#define IDC_EDIT_SET 1005
+#define IDC_COMBO_LANG 1006
+#define IDC_BUTTON_DEFAULT 1007
+#define IDC_CHECK_LAYOUT_MODE 1008
+#define IDC_CHECK_CLIPBOARD 1009
+#define IDC_CHECK_POPUP 1010
+#define IDC_STATIC_EXAMPLE 1011
+#define IDC_HOTKEY_CASE 1012
+#define IDC_HOTKEY_LAYOUT2 1013
+#define IDC_CHECK_LAYOUT_MODE2 1014
+#define IDC_CHECK_CASE_MODE 1015
+#define IDC_CHECK_TWOWAY 1016
+#define IDC_STATIC_GROUP_HOTKEYS 1017
+#define IDC_STATIC_HOTKEY_LAYOUT 1018
+#define IDC_STATIC_GROUP_STRINGS 1019
+#define IDC_STATIC_GROUP_LOG 1020
+#define IDC_STATIC_HOTKEY_CASE 1021
+#define IDC_STATIC_HOTKEY_LAYOUT2 1022
+#define IDC_STATIC_CURRENTWORD 1023
+#define IDC_CHECK_SYSTEMLAYOUT 1023
+#define IDC_CUSTOM_BACK 1024
+#define IDC_CHECK_LAYOUT_CTRL 1024
+#define IDC_CUSTOM_TEXT 1025
+#define IDC_CHECK_LAYOUT_ALT 1025
+#define IDC_RADIO_COLOURS_CUSTOM 1026
+#define IDC_CHECK_LAYOUT_SHIFT 1026
+#define IDC_RADIO_COLOURS_POPUP 1027
+#define IDC_CHECK_LAYOUT_WIN 1027
+#define IDC_RADIO_COLOURS_WINDOWS 1028
+#define IDC_CHECK_LAYOUT2_CTRL 1028
+#define IDC_EDIT_TIMEOUT 1029
+#define IDC_CHECK_LAYOUT2_ALT 1029
+#define IDC_RADIO_TIMEOUT_CUSTOM 1030
+#define IDC_CHECK_LAYOUT2_SHIFT 1030
+#define IDC_RADIO_TIMEOUT_POPUP 1031
+#define IDC_CHECK_LAYOUT2_WIN 1031
+#define IDC_RADIO_TIMEOUT_PERMANENT 1032
+#define IDC_CHECK_CASE_CTRL 1032
+#define IDC_RADIO_LEFT_CLIPBOARD 1033
+#define IDC_CHECK_CASE_ALT 1033
+#define IDC_RADIO_LEFT_DISMISS 1034
+#define IDC_CHECK_CASE_SHIFT 1034
+#define IDC_RADIO_RIGHT_CLIPBOARD 1035
+#define IDC_CHECK_CASE_WIN 1035
+#define IDC_RADIO_RIGHT_DISMISS 1036
+#define IDC_STATIC_GROUP_HOTKEYS2 1036
+#define IDC_STATIC_GROUP_OPTIONS 1036
+#define IDC_BUTTON_PREVIEW 1037
+#define IDC_GROUP_COLOURS 1038
+#define IDC_GROUP_TIMEOUT 1039
+#define IDC_GROUP_LEFTCLICK 1040
+#define IDC_GROUP_RIGHTCLICK 1041
+#define IDC_RADIO_INVERTCAPS 1042
+#define IDC_RADIO_OFFCAPS 1043
+#define IDC_RADIO_IGNORECAPS 1044
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 114
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1045
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/plugins/ChangeKeyboardLayout/text_operations.c b/plugins/ChangeKeyboardLayout/text_operations.c
new file mode 100644
index 0000000000..1fdc62b4c7
--- /dev/null
+++ b/plugins/ChangeKeyboardLayout/text_operations.c
@@ -0,0 +1,676 @@
+#include "text_operations.h"
+
+struct EditStreamData {
+ PBYTE pbBuff;
+ int cbBuff;
+ int iCurrent;
+};
+
+static DWORD CALLBACK EditStreamOutRtf(DWORD dwCookie,LPBYTE pbBuff,LONG cb,LONG *pcb)
+{
+ struct EditStreamData *esd=(struct EditStreamData*)dwCookie;
+ esd->cbBuff+=cb;
+ esd->pbBuff=(PBYTE)realloc(esd->pbBuff,esd->cbBuff+sizeof(TCHAR));
+ CopyMemory(esd->pbBuff+esd->iCurrent,pbBuff,cb);
+ esd->iCurrent+=cb;
+ esd->pbBuff[esd->iCurrent]=0;
+ #if defined (_UNICODE)
+ esd->pbBuff[esd->iCurrent+1]=0;
+ #endif
+ *pcb=cb;
+ return 0;
+}
+
+LPTSTR GeTStringFromStreamData(struct EditStreamData *esd)
+{
+ LPTSTR ptszTemp, ptszOutText;
+ DWORD i,k;
+
+ ptszOutText=(LPTSTR)mir_alloc(MaxTextSize*sizeof(TCHAR));
+ ptszTemp=(TCHAR*)esd->pbBuff;
+
+ for (i=k=0;i<_tcslen(ptszTemp);i++)
+ if ((ptszTemp[i]==0x0A)||(ptszTemp[i]==0x2028))
+ ptszOutText[k++]=0x0D;
+ else if (ptszTemp[i]==0x0D)
+ {
+ ptszOutText[k++]=0x0D;
+ if (ptszTemp[i+1]==0x0A) i++;
+ }
+ else
+ ptszOutText[k++]=ptszTemp[i];
+
+ ptszOutText[k]=0;
+ return ptszOutText;
+}
+
+
+BOOL CopyTextToClipboard(LPTSTR ptszText)
+{
+ HGLOBAL hCopy;
+
+ if (OpenClipboard(NULL))
+ {
+ EmptyClipboard();
+ hCopy=GlobalAlloc(GMEM_MOVEABLE,(_tcslen(ptszText)+1)*sizeof(TCHAR));
+ _tcscpy(GlobalLock(hCopy),ptszText);
+ GlobalUnlock(hCopy);
+
+ #if defined (_UNICODE)
+ SetClipboardData(CF_UNICODETEXT,hCopy);
+ #else
+ SetClipboardData(CF_TEXT,hCopy);
+ #endif
+
+ CloseClipboard();
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+LPTSTR GetNameOfLayout(HKL hklLayout)
+{
+ LPTSTR ptszLayName;
+ ptszLayName=mir_alloc((KL_NAMELENGTH+1)*sizeof(TCHAR));
+ sprintf(ptszLayName,"%08x",hklLayout);
+ return ptszLayName;
+}
+
+LPTSTR GetShortNameOfLayout(HKL hklLayout)
+{
+ DWORD dwLcid;
+ TCHAR szLI[20];
+ LPTSTR ptszLiShort;
+
+ ptszLiShort=(LPTSTR)mir_alloc(3*sizeof(TCHAR));
+ dwLcid = MAKELCID(hklLayout, 0);
+ GetLocaleInfo(dwLcid, LOCALE_SISO639LANGNAME , szLI, 10);
+ ptszLiShort[0] = toupper(szLI[0]);
+ ptszLiShort[1] = toupper(szLI[1]);
+ ptszLiShort[2] = 0;
+
+ return ptszLiShort;
+}
+
+HKL GetNextLayout(HKL hklCurLay)
+{
+ DWORD i;
+ for(i = 0; i < bLayNum; i++)
+ if (hklLayouts[i]==hklCurLay)
+ return hklLayouts[(i+1)%(bLayNum)];
+
+ return NULL;
+}
+
+LPTSTR GenerateLayoutString(HKL hklLayout)
+{
+ LPTSTR ptszLayStr,ptszTemp;
+ SHORT shVirtualKey;
+ UINT iScanCode;
+ BYTE bState[256]={0};
+ DWORD i,j;
+ int iRes;
+
+ ptszLayStr=(LPTSTR)mir_alloc(100*sizeof(TCHAR));
+ ptszTemp=(LPTSTR)mir_alloc(3*sizeof(TCHAR));
+ ptszTemp[0]=0;
+ for(i=0;i<_tcslen(ptszKeybEng);i++)
+ {
+ shVirtualKey=VkKeyScanEx(ptszKeybEng[i],hklEng);
+ iScanCode=MapVirtualKeyEx(shVirtualKey&0x00FF,0,hklEng);
+
+ for (j=0;j<256;j++)
+ bState[j]=0;
+
+ if (shVirtualKey&0x0100) bState[VK_SHIFT]=0x80;
+ if (shVirtualKey&0x0200) bState[VK_CONTROL]=0x80;
+ if (shVirtualKey&0x0400) bState[VK_MENU]=0x80;
+
+ shVirtualKey=MapVirtualKeyEx(iScanCode,1,hklLayout);
+ bState[shVirtualKey&0x00FF]=0x80;
+
+ #if defined (_UNICODE)
+ iRes=ToUnicodeEx(shVirtualKey,iScanCode,bState,ptszTemp,3,0,hklLayout);
+ // Защита от дэд-кеев
+ if (iRes<0) ToUnicodeEx(shVirtualKey,iScanCode,bState,ptszTemp,3,0,hklLayout);
+ #else
+ iRes=ToAsciiEx(shVirtualKey,iScanCode,bState,ptszTemp,0,hklLayout);
+ // Защита от дэд-кеев
+ if (iRes<0) ToAsciiEx(shVirtualKey,iScanCode,bState,ptszTemp,0,hklLayout);
+ #endif
+
+ //Если нам вернули нулевой символ, или не вернули ничего, то присвоим "звоночек"
+ if (ptszTemp[0]==0) ptszLayStr[i]=3; else ptszLayStr[i]=ptszTemp[0];
+ }
+ ptszLayStr[i]=0;
+
+ mir_free(ptszTemp);
+ return ptszLayStr;
+}
+
+LPTSTR GetLayoutString(HKL hklLayout)
+{
+ DWORD i;
+ for (i=0;i<bLayNum;i++)
+ if (hklLayouts[i]==hklLayout)
+ return ptszLayStrings[i];
+ return NULL;
+}
+
+LPTSTR ChangeTextCase(LPCTSTR ptszInText)
+{
+ LPTSTR ptszOutText;
+ DWORD i;
+
+ ptszOutText=(LPTSTR)mir_alloc(MaxTextSize*sizeof(TCHAR));
+
+ if (!CoreCheck())
+ {
+ _tcscpy(ptszOutText,TranslateT("Change Keyboard Layout plugin was designed to be used with Miranda IM only. For use with any other application, please contact author."));
+ return ptszOutText;
+ }
+
+ _tcscpy(ptszOutText,ptszInText);
+
+ for (i=0;i<_tcslen(ptszInText);i++)
+ {
+ CharUpperBuff(&ptszOutText[i],1);
+
+ if (ptszOutText[i]==ptszInText[i])
+ CharLowerBuff(&ptszOutText[i],1);
+ }
+ return ptszOutText;
+
+}
+
+LPTSTR ChangeTextLayout(LPCTSTR ptszInText,HKL hklCurLay, HKL hklToLay, BOOL TwoWay)
+{
+ LPTSTR ptszOutText;
+ DWORD i,j;
+ BOOL Found;
+
+ LPTSTR ptszKeybCur,ptszKeybNext;
+
+ ptszOutText=(LPTSTR)mir_alloc(MaxTextSize*sizeof(TCHAR));
+
+ if (!CoreCheck())
+ {
+ _tcscpy(ptszOutText,TranslateT("Change Keyboard Layout plugin was designed to be used with Miranda IM only. For use with any other application, please contact author."));
+ return ptszOutText;
+ }
+
+ _tcscpy(ptszOutText,ptszInText);
+
+ if ((hklCurLay==NULL)||(hklToLay==NULL))
+ return ptszOutText;
+
+ ptszKeybCur=GetLayoutString(hklCurLay);
+ ptszKeybNext=GetLayoutString(hklToLay);
+
+ if ((ptszKeybCur==0)||(ptszKeybNext==0))
+ return ptszOutText;
+
+ for (i=0;i<_tcslen(ptszInText);i++)
+ {
+ Found=FALSE;
+ for (j=0;(j<_tcslen(ptszKeybCur)&&(!Found));j++)
+ if (ptszKeybCur[j]==ptszInText[i])
+ {
+ Found=TRUE;
+ if (_tcslen(ptszKeybNext)>=j)
+ ptszOutText[i]=ptszKeybNext[j];
+ }
+
+ if (TwoWay&&(!Found))
+ for (j=0;(j<_tcslen(ptszKeybNext)&&(!Found));j++)
+ if (ptszKeybNext[j]==ptszInText[i])
+ {
+ Found=TRUE;
+ if (_tcslen(ptszKeybCur)>=j)
+ ptszOutText[i]=ptszKeybCur[j];
+ }
+ };
+ return ptszOutText;
+}
+
+HKL GetLayoutOfText(LPCTSTR ptszInText)
+{
+ DWORD i,j;
+ LPTSTR ptszKeybBuff;
+ DWORD dwCountSymbols,dwMaxSymbols,dwTemp;
+ HKL hklCurLay;
+
+ hklCurLay=hklLayouts[0];
+ ptszKeybBuff=ptszLayStrings[0];
+ dwMaxSymbols=dwTemp=0;
+
+ for (j=0;j<_tcslen(ptszInText);j++)
+ if (_tcschr(ptszKeybBuff,ptszInText[j])!=NULL) ++dwMaxSymbols;
+
+ for(i = 1; i < bLayNum; i++)
+ {
+ ptszKeybBuff=ptszLayStrings[i];
+ dwCountSymbols=0;
+
+ for (j=0;j<_tcslen(ptszInText);j++)
+ if (_tcschr(ptszKeybBuff,ptszInText[j])!=NULL) ++dwCountSymbols;
+
+ if (dwCountSymbols==dwMaxSymbols)
+ dwTemp = dwCountSymbols;
+ else if (dwCountSymbols>dwMaxSymbols)
+ {
+ dwMaxSymbols=dwCountSymbols;
+ hklCurLay=hklLayouts[i];
+ }
+ }
+
+ if (dwMaxSymbols == dwTemp)
+ hklCurLay=GetKeyboardLayout(0);
+
+ return hklCurLay;
+}
+
+int ChangeLayout(HWND hTextWnd,BYTE TextOperation,BOOL CurrentWord)
+{
+ HKL hklCurLay, hklToLay;
+
+ LPTSTR ptszInText,ptszOutText,ptszMBox,ptszPopupText,ptszTemp;
+ IEVIEWEVENT ieEvent;
+ CHARRANGE crSelection,crTemp;
+ DWORD dwStartWord,dwEndWord;
+ int i,iRes;
+
+ BYTE WindowType=WTYPE_Unknown;
+ BOOL WindowIsReadOnly, TwoWay;
+
+ EDITSTREAM esStream={0};
+ struct EditStreamData esdData;
+
+ POPUPDATAT pdtData;
+
+ esStream.dwCookie=(DWORD)&esdData;
+ esStream.pfnCallback=EditStreamOutRtf;
+
+ if (hTextWnd==NULL)
+ hTextWnd=GetFocus();
+ if (hTextWnd!=NULL)
+ {
+ // --------------Определяем тип окна-----------------
+
+ ZeroMemory((void *)&ieEvent, sizeof(ieEvent));
+ ieEvent.cbSize = sizeof(IEVIEWEVENT);
+ ieEvent.dwFlags = 0;
+ ieEvent.iType = IEE_GET_SELECTION;
+ //event.codepage=1200;
+ #if !defined(_UNICODE)
+ ieEvent.dwFlags |= IEEF_NO_UNICODE;
+ #endif
+
+ if (ServiceExists(MS_HPP_EG_EVENT))
+ {
+ //То же самое для History++
+ ieEvent.hwnd = hTextWnd;
+ ptszInText=(TCHAR*)CallService(MS_HPP_EG_EVENT, 0, (LPARAM)&ieEvent);
+
+ if (!IsBadStringPtr(ptszInText,MaxTextSize)) WindowType=WTYPE_HistoryPP;
+ }
+
+ if ((WindowType==WTYPE_Unknown)&&(ServiceExists(MS_IEVIEW_EVENT)))
+ {
+ // Извращенное определение хэндла IEView
+ ieEvent.hwnd = GetParent(GetParent(hTextWnd));
+
+ ptszInText=(TCHAR*)CallService(MS_IEVIEW_EVENT, 0, (LPARAM)&ieEvent);
+ if (!IsBadStringPtr(ptszInText,MaxTextSize)) WindowType=WTYPE_IEView;
+ }
+
+ if (WindowType==WTYPE_Unknown)
+ {
+ ptszTemp=(LPTSTR)mir_alloc(255*sizeof(TCHAR));
+ i = GetClassName(hTextWnd,ptszTemp,255);
+ ptszTemp[i] = 0;
+
+ if (_tcsstr(CharUpper(ptszTemp),_T("RICHEDIT")) != NULL )
+ {
+ WindowType=WTYPE_RichEdit;
+ SendMessage(hTextWnd,EM_EXGETSEL,0,(LPARAM)&crSelection);
+ }
+ mir_free(ptszTemp);
+ }
+
+ if (WindowType==WTYPE_Unknown)
+ {
+ SendMessage(hTextWnd,EM_GETSEL,(WPARAM)&crSelection.cpMin,(LPARAM)&crSelection.cpMax);
+ if ((SendMessage(hTextWnd,WM_GETDLGCODE,(WPARAM)NULL,(LPARAM)NULL)&(DLGC_HASSETSEL))&&(crSelection.cpMin>=0))
+ WindowType=WTYPE_Edit;
+ }
+
+
+ //Получим текст из Рича или обычного Едита
+ if ((WindowType==WTYPE_RichEdit)||(WindowType==WTYPE_Edit))
+ {
+ dwStartWord=dwEndWord=-1;
+ SendMessage(hTextWnd,WM_SETREDRAW,FALSE,0);
+
+ //Бэкап выделения
+ crTemp=crSelection;
+
+ // Если имеется выделенный текст, то получим его
+ if(crSelection.cpMin!=crSelection.cpMax)
+ {
+ if (WindowType==WTYPE_RichEdit)
+ {
+ ZeroMemory(&esdData, sizeof(esdData));
+ #if defined (_UNICODE)
+ if (SendMessage(hTextWnd,EM_STREAMOUT,SF_TEXT|SF_UNICODE|SFF_SELECTION,(LPARAM)&esStream)>0)
+ #else
+ if (SendMessage(hTextWnd,EM_STREAMOUT,SF_TEXT|SFF_SELECTION,(LPARAM)&esStream)>0)
+ #endif
+ ptszInText=GeTStringFromStreamData(&esdData);
+ else
+ {
+ SendMessage(hTextWnd,EM_EXSETSEL,0,(LPARAM)&crSelection);
+ SendMessage(hTextWnd,WM_SETREDRAW,TRUE,0);
+ InvalidateRect(hTextWnd, NULL, FALSE);
+ return 1;
+ }
+ }
+ if (WindowType==WTYPE_Edit)
+ {
+ ptszTemp=(LPTSTR)mir_alloc(MaxTextSize*sizeof(TCHAR));
+ ptszInText=(LPTSTR)mir_alloc(MaxTextSize*sizeof(TCHAR));
+ iRes=SendMessage(hTextWnd,WM_GETTEXT,(WPARAM)MaxTextSize,(LPARAM)ptszTemp);
+ if (!IsBadStringPtr(ptszInText,MaxTextSize)&&(iRes>0))
+ {
+ _tcsncpy(ptszInText,&ptszTemp[crSelection.cpMin],crSelection.cpMax-crSelection.cpMin);
+ ptszInText[crSelection.cpMax-crSelection.cpMin]=0;
+ mir_free(ptszTemp);
+ }
+ else
+ {
+ SendMessage(hTextWnd,EM_EXSETSEL,0,(LPARAM)&crSelection);
+ SendMessage(hTextWnd,WM_SETREDRAW,TRUE,0);
+ InvalidateRect(hTextWnd, NULL, FALSE);
+ return 1;
+ }
+ }
+ }
+ // Если выделения нет, то получим нужный текст
+ else
+ {
+ // Получаем весь текст в поле
+ if (WindowType==WTYPE_RichEdit)
+ {
+ ZeroMemory(&esdData, sizeof(esdData));
+ crTemp.cpMin=0;
+ crTemp.cpMax=-1;
+ SendMessage(hTextWnd,EM_EXSETSEL,0,(LPARAM)&crTemp);
+ #if defined (_UNICODE)
+ if (SendMessage(hTextWnd,EM_STREAMOUT,SF_TEXT|SF_UNICODE|SFF_SELECTION,(LPARAM)&esStream)!=0)
+ #else
+ if (SendMessage(hTextWnd,EM_STREAMOUT,SF_TEXT|SFF_SELECTION,(LPARAM)&esStream)!=0)
+ #endif
+ ptszInText=GeTStringFromStreamData(&esdData);
+ else
+ {
+ SendMessage(hTextWnd,EM_EXSETSEL,0,(LPARAM)&crSelection);
+ SendMessage(hTextWnd,WM_SETREDRAW,TRUE,0);
+ InvalidateRect(hTextWnd, NULL, FALSE);
+ return 1;
+ }
+ }
+ if (WindowType==WTYPE_Edit)
+ {
+ ptszInText=(LPTSTR)mir_alloc(MaxTextSize*sizeof(TCHAR));
+ iRes=SendMessage(hTextWnd,WM_GETTEXT,(WPARAM)MaxTextSize,(LPARAM)ptszInText);
+
+ if (!IsBadStringPtr(ptszInText,MaxTextSize)&&(iRes>0))
+ {
+ crTemp.cpMin=0;
+ crTemp.cpMax=_tcslen(ptszInText);
+ }
+ else
+ {
+ SendMessage(hTextWnd,EM_EXSETSEL,0,(LPARAM)&crSelection);
+ SendMessage(hTextWnd,WM_SETREDRAW,TRUE,0);
+ InvalidateRect(hTextWnd, NULL, FALSE);
+ return 1;
+ }
+ }
+ // Получаем текущее слово
+ if (CurrentWord)
+ {
+ for (dwStartWord=crSelection.cpMin;(dwStartWord>0)&&(_tcschr(ptszSeparators,ptszInText[dwStartWord-1])==NULL);dwStartWord--);
+ for (dwEndWord=crSelection.cpMin;(dwEndWord<(_tcslen(ptszInText)))&&(_tcschr(ptszSeparators,ptszInText[dwEndWord])==NULL);dwEndWord++);
+
+ crTemp.cpMin=dwStartWord;
+ crTemp.cpMax=dwEndWord;
+
+ if (WindowType==WTYPE_RichEdit)
+ {
+ SendMessage(hTextWnd,EM_EXSETSEL,0,(LPARAM)&crTemp);
+ ZeroMemory(&esdData, sizeof(esdData));
+ #if defined (_UNICODE)
+ if (SendMessage(hTextWnd,EM_STREAMOUT,SF_TEXT|SF_UNICODE|SFF_SELECTION,(LPARAM)&esStream)!=0)
+ #else
+ if (SendMessage(hTextWnd,EM_STREAMOUT,SF_TEXT|SFF_SELECTION,(LPARAM)&esStream)!=0)
+ #endif
+ ptszInText=GeTStringFromStreamData(&esdData);
+ else
+ {
+ SendMessage(hTextWnd,EM_EXSETSEL,0,(LPARAM)&crSelection);
+ SendMessage(hTextWnd,WM_SETREDRAW,TRUE,0);
+ InvalidateRect(hTextWnd, NULL, FALSE);
+ return 1;
+ }
+
+ }
+
+ if (WindowType==WTYPE_Edit)
+ {
+ ptszTemp=(LPTSTR)mir_alloc(MaxTextSize*sizeof(TCHAR));
+ _tcsncpy(ptszTemp,&ptszInText[crTemp.cpMin],crTemp.cpMax-crTemp.cpMin);
+ ptszTemp[crTemp.cpMax-crTemp.cpMin]=0;
+ _tcscpy(ptszInText,ptszTemp);
+ mir_free(ptszTemp);
+ if (_tcslen(ptszInText)==0)
+ {
+ mir_free(ptszInText);
+ SendMessage(hTextWnd,EM_EXSETSEL,0,(LPARAM)&crSelection);
+ SendMessage(hTextWnd,WM_SETREDRAW,TRUE,0);
+ InvalidateRect(hTextWnd, NULL, FALSE);
+ return 1;
+ }
+ }
+ }
+ }
+ }
+// ---------------Выдаем результаты--------------------
+ WindowIsReadOnly=FALSE;
+ if ((WindowType==WTYPE_IEView)||(WindowType==WTYPE_HistoryPP)) WindowIsReadOnly=TRUE;
+
+ //if ((SendMessage(hTextWnd,EM_GETOPTIONS,0,0)&ECO_READONLY))
+ if ((WindowType==WTYPE_RichEdit)||(WindowType==WTYPE_Edit))
+ if (GetWindowLong(hTextWnd,GWL_STYLE)&ES_READONLY)
+ WindowIsReadOnly=TRUE;
+
+ // Лог Иевью и ХисториПП в режиме эмуляции Иевью и поля только для чтения.
+ if ((WindowType!=WTYPE_Unknown)&&(!IsBadStringPtr(ptszInText,MaxTextSize)))
+ if (WindowIsReadOnly)
+ {
+ ptszMBox=(LPTSTR)mir_alloc(MaxTextSize*sizeof(TCHAR));
+ ptszMBox[0]=0;
+
+ if (TextOperation==TOT_Layout)
+ {
+ hklCurLay=GetLayoutOfText(ptszInText);
+ hklToLay=GetNextLayout(hklCurLay);
+ TwoWay=(moOptions.TwoWay)&&(bLayNum==2);
+
+ if (bLayNum==2)
+ {
+ ptszMBox=ChangeTextLayout(ptszInText,hklCurLay,hklToLay,TwoWay);
+ }
+ else
+ {
+ for (i=0;i<bLayNum;i++)
+ if (hklLayouts[i]!=hklCurLay)
+ {
+ if (_tcslen(ptszMBox)!=0)
+ _tcscat(ptszMBox,_T("\n\n"));
+ ptszTemp=GetShortNameOfLayout(hklLayouts[i]);
+ _tcscat(ptszMBox,ptszTemp);
+ _tcscat(ptszMBox,_T(":\n"));
+ ptszOutText=ChangeTextLayout(ptszInText,hklCurLay,hklLayouts[i],FALSE);
+ _tcscat(ptszMBox,ptszOutText);
+ mir_free(ptszTemp);
+ mir_free(ptszOutText);
+ }
+ }
+ }
+ else if (TextOperation==TOT_Case)
+ {
+ ptszMBox=ChangeTextCase(ptszInText);
+ }
+
+ mir_free(ptszInText);
+
+ if ((WindowType==WTYPE_Edit)||(WindowType==WTYPE_RichEdit))
+ {
+ SendMessage(hTextWnd,EM_EXSETSEL,0,(LPARAM)&crSelection);
+ SendMessage(hTextWnd,WM_SETREDRAW,TRUE,0);
+ InvalidateRect(hTextWnd, NULL, FALSE);
+ }
+
+ if (TextOperation==TOT_Layout)
+ SkinPlaySound(SND_ChangeLayout);
+ else if (TextOperation==TOT_Case)
+ SkinPlaySound(SND_ChangeCase);
+
+ if (moOptions.CopyToClipboard)
+ CopyTextToClipboard(ptszMBox);
+//-------------------------------Покажем попапы------------------------------------------
+ if (moOptions.ShowPopup)
+ {
+ ptszPopupText=(LPTSTR)mir_alloc(MaxTextSize*sizeof(TCHAR));
+ _tcscpy(ptszPopupText,ptszMBox);
+
+ pdtData.cbSize = sizeof(POPUPDATAT);
+ ZeroMemory(&pdtData, sizeof(pdtData));
+ _tcsncpy(pdtData.lptzContactName,TranslateT(ModuleName), MAX_CONTACTNAME);
+ _tcsncpy(pdtData.lptzText, ptszPopupText, MAX_SECONDLINE);
+ switch(poOptions.bColourType)
+ {
+ case PPC_POPUP:
+ pdtData.colorBack=pdtData.colorText=0;
+ break;
+ case PPC_WINDOWS:
+ pdtData.colorBack=GetSysColor(COLOR_BTNFACE);
+ pdtData.colorText=GetSysColor(COLOR_WINDOWTEXT);
+ break;
+ case PPC_CUSTOM:
+ pdtData.colorBack=poOptions.crBackColour;
+ pdtData.colorText=poOptions.crTextColour;
+ break;
+ default:
+ break;
+ }
+ switch(poOptions.bTimeoutType)
+ {
+ case PPT_POPUP:
+ pdtData.iSeconds=0;
+ break;
+ case PPT_PERMANENT:
+ pdtData.iSeconds=-1;
+ break;
+ case PPC_CUSTOM:
+ pdtData.iSeconds=poOptions.bTimeout;
+ break;
+ }
+ pdtData.PluginData =ptszPopupText;
+
+ pdtData.lchIcon = hPopupIcon;
+ poOptions.paActions[0].lchIcon = hCopyIcon;
+ pdtData.lpActions = poOptions.paActions;
+ pdtData.actionCount = 1;
+
+ pdtData.PluginWindowProc = (WNDPROC)CKLPopupDlgProc;
+
+ if (CallService(MS_POPUP_ADDPOPUPT, (WPARAM) &pdtData, APF_NEWDATA)<0)
+ {
+ mir_free(ptszPopupText);
+ MessageBox(NULL,ptszMBox,_T(ModuleName),MB_ICONINFORMATION);
+ }
+ }
+ mir_free(ptszMBox);
+
+ }
+//------------------Редактируемые поля ----------------------------
+ else
+ {
+ if (TextOperation==TOT_Layout)
+ {
+ hklCurLay=GetLayoutOfText(ptszInText);
+ hklToLay=GetNextLayout(hklCurLay);
+ TwoWay=(moOptions.TwoWay)&&(bLayNum==2);
+ ptszOutText=ChangeTextLayout(ptszInText,hklCurLay,hklToLay,TwoWay);
+ }
+ else if (TextOperation==TOT_Case)
+ {
+ ptszOutText=ChangeTextCase(ptszInText);
+ }
+
+ if (WindowType==WTYPE_RichEdit)
+ {
+ SendMessage(hTextWnd,EM_EXSETSEL,0,(LPARAM)&crTemp);
+ SendMessage(hTextWnd,EM_REPLACESEL,FALSE,(LPARAM)ptszOutText);
+ SendMessage(hTextWnd,EM_EXSETSEL,0,(LPARAM)&crSelection);
+ }
+ else
+ {
+ ptszTemp=(LPTSTR)mir_alloc(MaxTextSize*sizeof(TCHAR));
+ SendMessage(hTextWnd,WM_GETTEXT,(WPARAM)MaxTextSize,(LPARAM)ptszTemp);
+ for (i=crTemp.cpMin;i<crTemp.cpMax;i++)
+ ptszTemp[i]=ptszOutText[i-crTemp.cpMin];
+ SendMessage(hTextWnd,WM_SETTEXT,(WPARAM)NULL,(LPARAM)ptszTemp);
+ SendMessage(hTextWnd,EM_SETSEL,crSelection.cpMin,crSelection.cpMax);
+ mir_free(ptszTemp);
+ }
+
+ // Переключим раскладку или изменим состояние Caps Lock
+ if ((TextOperation==TOT_Layout)&&(hklToLay!=NULL)&&(moOptions.ChangeSystemLayout))
+ ActivateKeyboardLayout(hklToLay,KLF_SETFORPROCESS);
+ else if (TextOperation == TOT_Case)
+ {
+ // Если нужно инвертнуть
+ if (moOptions.bCaseOperations == 0)
+ {
+ keybd_event( VK_CAPITAL, 0x45, 0, 0);
+ keybd_event( VK_CAPITAL, 0x45, KEYEVENTF_KEYUP, 0);
+ }
+ // Если нужно отключить
+ else if (moOptions.bCaseOperations == 1)
+ {
+ if (GetKeyState(VK_CAPITAL)&0x0001)
+ {
+ keybd_event( VK_CAPITAL, 0x45, 0, 0);
+ keybd_event( VK_CAPITAL, 0x45, KEYEVENTF_KEYUP, 0);
+ }
+ }
+ }
+
+ SendMessage(hTextWnd,WM_SETREDRAW,TRUE,0);
+ InvalidateRect(hTextWnd, NULL, FALSE);
+
+ if (TextOperation==TOT_Layout)
+ SkinPlaySound(SND_ChangeLayout);
+ else if (TextOperation==TOT_Case)
+ SkinPlaySound(SND_ChangeCase);
+
+ mir_free(ptszInText);
+ mir_free(ptszOutText);
+ }
+ }
+ return 0;
+}
diff --git a/plugins/ChangeKeyboardLayout/text_operations.h b/plugins/ChangeKeyboardLayout/text_operations.h
new file mode 100644
index 0000000000..a770e845fb
--- /dev/null
+++ b/plugins/ChangeKeyboardLayout/text_operations.h
@@ -0,0 +1,16 @@
+#ifndef M_CKL_TEXT_OPERATIONS_H
+#define M_CKL_TEXT_OPERATIONS_H
+
+#include "commonheaders.h"
+
+BOOL CopyTextToClipboard(LPTSTR ptszText);
+LPTSTR GetNameOfLayout(HKL hklLayout);
+LPTSTR GetShortNameOfLayout(HKL hklLayout);
+LPTSTR GenerateLayoutString(HKL hklLayout);
+LPTSTR GetLayoutString(HKL hklLayout);
+HKL GetLayoutOfText(LPCTSTR ptzsInText);
+LPTSTR ChangeTextCase(LPCTSTR ptszInText);
+LPTSTR ChangeTextLayout(LPCTSTR ptzsInText,HKL hklCurLay, HKL hklToLay, BOOL TwoWay);
+int ChangeLayout(HWND hTextWnd,BYTE bTextOperation,BOOL CurrentWord);
+
+#endif \ No newline at end of file