summaryrefslogtreecommitdiff
path: root/plugins/ChangeKeyboardLayout/src
diff options
context:
space:
mode:
authorVadim Dashevskiy <watcherhd@gmail.com>2012-07-09 07:51:11 +0000
committerVadim Dashevskiy <watcherhd@gmail.com>2012-07-09 07:51:11 +0000
commit226e4fb73c7cc9fe7aa8d7e2afe9afc124a51cb7 (patch)
tree8c425311bfaf8199af2b55745f9cc7908184bdd6 /plugins/ChangeKeyboardLayout/src
parentfb601ef6dc92cfcb1ce60fc7e93faae774a98b20 (diff)
changekeyboardlayout: changed folder structure
git-svn-id: http://svn.miranda-ng.org/main/trunk@872 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'plugins/ChangeKeyboardLayout/src')
-rw-r--r--plugins/ChangeKeyboardLayout/src/commonheaders.h120
-rw-r--r--plugins/ChangeKeyboardLayout/src/hook_events.cpp291
-rw-r--r--plugins/ChangeKeyboardLayout/src/hook_events.h14
-rw-r--r--plugins/ChangeKeyboardLayout/src/main.cpp75
-rw-r--r--plugins/ChangeKeyboardLayout/src/options.cpp500
-rw-r--r--plugins/ChangeKeyboardLayout/src/options.h9
-rw-r--r--plugins/ChangeKeyboardLayout/src/resource.h81
-rw-r--r--plugins/ChangeKeyboardLayout/src/text_operations.cpp649
-rw-r--r--plugins/ChangeKeyboardLayout/src/text_operations.h16
9 files changed, 1755 insertions, 0 deletions
diff --git a/plugins/ChangeKeyboardLayout/src/commonheaders.h b/plugins/ChangeKeyboardLayout/src/commonheaders.h
new file mode 100644
index 0000000000..32aa776844
--- /dev/null
+++ b/plugins/ChangeKeyboardLayout/src/commonheaders.h
@@ -0,0 +1,120 @@
+#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_skin.h>
+#include <m_popup.h>
+#include <m_utils.h>
+#include <m_icolib.h>
+
+#include <m_ieview.h>
+#include <m_updater.h>
+#include "m_changekeyboardlayout.h"
+#include <m_popup2.h>
+
+#include "resource.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;
+
+extern HINSTANCE hInst;
+
+extern HANDLE hChangeLayout, hGetLayoutOfText, hChangeTextLayout;
+extern HANDLE hIcoLibIconsChanged;
+
+extern HICON hPopupIcon, hCopyIcon;
+
+extern LPCTSTR ptszKeybEng;
+extern HKL hklEng;
+
+extern BYTE bLayNum;
+extern HKL hklLayouts[20];
+extern LPTSTR ptszLayStrings[20];
+
+extern LPCTSTR ptszSeparators;
+
+extern HHOOK kbHook_All;
+
+extern MainOptions moOptions;
+extern PopupOptions poOptions, poOptionsTemp;
+
+LRESULT CALLBACK Keyboard_Hook(int code, WPARAM wParam, LPARAM lParam);
+
+#endif \ No newline at end of file
diff --git a/plugins/ChangeKeyboardLayout/src/hook_events.cpp b/plugins/ChangeKeyboardLayout/src/hook_events.cpp
new file mode 100644
index 0000000000..5c94609252
--- /dev/null
+++ b/plugins/ChangeKeyboardLayout/src/hook_events.cpp
@@ -0,0 +1,291 @@
+#include "hook_events.h"
+
+INT_PTR APIChangeLayout(WPARAM wParam, LPARAM lParam)
+{
+ BOOL CurrentWord;
+ CurrentWord = moOptions.CurrentWordLayout;
+ return ChangeLayout((HWND)wParam, TOT_Layout, CurrentWord);
+}
+
+INT_PTR APIGetLayoutOfText(WPARAM wParam, LPARAM lParam)
+{
+ LPTSTR ptszInText;
+ ptszInText = (TCHAR*)lParam;
+ return (int) GetLayoutOfText(ptszInText);
+}
+
+INT_PTR 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);
+}
+
+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, (WPARAM)&poOptions.paActions, 1);
+ }
+}
+
+int OnIconsChanged(WPARAM wParam, LPARAM lParam)
+{
+ hPopupIcon = (HICON)CallService(MS_SKIN2_GETICON, 0, (LPARAM)"ckl_popup_icon");
+ hCopyIcon = (HICON)CallService(MS_SKIN2_GETICON, 0, (LPARAM)"ckl_copy_icon");
+ RegPopupActions();
+ return 0;
+}
+
+
+int ModulesLoaded(WPARAM wParam, LPARAM lParam)
+{
+ int i, iRes;
+ DBVARIANT dbv = {0};
+ LPCTSTR ptszEmptySting = _T("");
+ LPTSTR ptszCurrLayout;
+ LPSTR ptszTemp;
+
+ SKINICONDESC sid = {0};
+ TCHAR 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, ModuleName, LPGEN("Changing Layout"));
+ SkinAddNewSoundEx(SND_ChangeCase, ModuleName, LPGEN("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
+ GetModuleFileName(hInst, szFile, MAX_PATH);
+ sid.ptszDefaultFile = szFile;
+ sid.cbSize = sizeof(sid);
+ sid.flags = SIDF_PATH_TCHAR;
+
+ sid.pszSection = Translate(ModuleName);
+ sid.pszDescription = Translate("Popup");
+ sid.pszName = "ckl_popup_icon";
+ sid.iDefaultIndex = -IDI_POPUPICON;
+ Skin_AddIcon(&sid);
+
+ sid.pszDescription = Translate("Copy to clipboard");
+ sid.pszName = "ckl_copy_icon";
+ sid.iDefaultIndex = -IDI_COPYICON;
+ Skin_AddIcon(&sid);
+
+ hIcoLibIconsChanged = HookEvent(ME_SKIN2_ICONSCHANGED, OnIconsChanged);
+
+ OnIconsChanged(0, 0);
+ RegPopupActions();
+
+ 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 = MAKEINTRESOURCEA(IDD_MAIN_OPTION_FORM);
+ odp.pszTitle = ModuleName;
+ odp.pszGroup = LPGEN("Plugins");
+ odp.flags = ODPF_BOLDGROUPS;
+ odp.pfnDlgProc = DlgMainProcOptions;
+ Options_AddPage(wParam, &odp);
+
+ if (ServiceExists(MS_POPUP_ADDPOPUP)) {
+ odp.pszTemplate = MAKEINTRESOURCEA(IDD_POPUP_OPTION_FORM);
+ odp.pszGroup = LPGEN("PopUps");
+ odp.pfnDlgProc = DlgPopupsProcOptions;
+ Options_AddPage(wParam, &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/src/hook_events.h b/plugins/ChangeKeyboardLayout/src/hook_events.h
new file mode 100644
index 0000000000..992c7cd0c3
--- /dev/null
+++ b/plugins/ChangeKeyboardLayout/src/hook_events.h
@@ -0,0 +1,14 @@
+#ifndef M_CKL_HOOK_EVENTS_H
+#define M_CKL_HOOK_EVENTS_H
+
+#include "commonheaders.h"
+
+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/src/main.cpp b/plugins/ChangeKeyboardLayout/src/main.cpp
new file mode 100644
index 0000000000..5cda47443b
--- /dev/null
+++ b/plugins/ChangeKeyboardLayout/src/main.cpp
@@ -0,0 +1,75 @@
+#include "commonheaders.h"
+
+int hLangpack;
+LPTSTR ptszLayStrings[20];
+HANDLE hChangeLayout, hGetLayoutOfText, hChangeTextLayout;
+HICON hPopupIcon, hCopyIcon;
+HKL hklLayouts[20];
+BYTE bLayNum;
+HINSTANCE hInst;
+HHOOK kbHook_All;
+MainOptions moOptions;
+PopupOptions poOptions, poOptionsTemp;
+HANDLE hIcoLibIconsChanged;
+
+PLUGININFOEX pluginInfoEx = {
+ sizeof(PLUGININFOEX),
+ "Change Keyboard Layout",
+ 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",
+ UNICODE_AWARE, //doesn't replace anything built-in
+ // {c5ef53a8-80d4-4ce9-b341-ec90d3ec9156}
+ {0xc5ef53a8, 0x80d4, 0x4ce9, { 0xb3, 0x41, 0xec, 0x90, 0xd3, 0xec, 0x91, 0x56 }}
+};
+
+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;
+}
+
+extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion)
+{
+ return &pluginInfoEx;
+}
+
+extern "C" __declspec(dllexport) int Load(void)
+{
+ 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;
+}
+
+extern "C" __declspec(dllexport) int 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;
+} \ No newline at end of file
diff --git a/plugins/ChangeKeyboardLayout/src/options.cpp b/plugins/ChangeKeyboardLayout/src/options.cpp
new file mode 100644
index 0000000000..39c678a9f3
--- /dev/null
+++ b/plugins/ChangeKeyboardLayout/src/options.cpp
@@ -0,0 +1,500 @@
+#include "options.h"
+
+
+INT_PTR CALLBACK DlgMainProcOptions(HWND hWnd, UINT uiMessage, WPARAM wParam, LPARAM lParam)
+{
+ static BOOL MainDialogLock = FALSE;
+ LPTSTR ptszGenLay, ptszMemLay, ptszFormLay, ptszShortNameLay;
+ LPSTR pszNameLay;
+ 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]);
+ pszNameLay = GetNameOfLayout(hklLayouts[i]);
+
+ if(_tcscmp(ptszMemLay, ptszGenLay) != 0)
+ DBWriteContactSettingTString(NULL, ModuleName, pszNameLay, ptszMemLay);
+ else
+ DBDeleteContactSetting(NULL, ModuleName, pszNameLay);
+
+ mir_free(pszNameLay);
+ 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_PTR CALLBACK DlgPopupsProcOptions(HWND hWnd, UINT uiMessage, WPARAM wParam, LPARAM lParam)
+{
+ POPUPDATAT_V2 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_V2);
+ 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/src/options.h b/plugins/ChangeKeyboardLayout/src/options.h
new file mode 100644
index 0000000000..bcf46a244b
--- /dev/null
+++ b/plugins/ChangeKeyboardLayout/src/options.h
@@ -0,0 +1,9 @@
+#ifndef M_CKL_OPTIONS_H
+#define M_CKL_OPTIONS_H
+
+#include "commonheaders.h"
+
+INT_PTR CALLBACK DlgMainProcOptions(HWND hWnd, UINT uiMessage, WPARAM wParam, LPARAM lParam);
+INT_PTR CALLBACK DlgPopupsProcOptions(HWND hWnd, UINT uiMessage, WPARAM wParam, LPARAM lParam);
+
+#endif \ No newline at end of file
diff --git a/plugins/ChangeKeyboardLayout/src/resource.h b/plugins/ChangeKeyboardLayout/src/resource.h
new file mode 100644
index 0000000000..8ca2e0e8be
--- /dev/null
+++ b/plugins/ChangeKeyboardLayout/src/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/src/text_operations.cpp b/plugins/ChangeKeyboardLayout/src/text_operations.cpp
new file mode 100644
index 0000000000..f4441ef4ae
--- /dev/null
+++ b/plugins/ChangeKeyboardLayout/src/text_operations.cpp
@@ -0,0 +1,649 @@
+#include "text_operations.h"
+
+struct EditStreamData {
+ PBYTE pbBuff;
+ int cbBuff;
+ int iCurrent;
+};
+
+static DWORD CALLBACK EditStreamOutRtf(DWORD_PTR 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;
+
+ esd->pbBuff[esd->iCurrent+1] = 0;
+
+ *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((TCHAR*)GlobalLock(hCopy), ptszText);
+ GlobalUnlock(hCopy);
+
+
+ SetClipboardData(CF_UNICODETEXT, hCopy);
+
+
+ CloseClipboard();
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+LPSTR GetNameOfLayout(HKL hklLayout)
+{
+ LPSTR ptszLayName = (LPSTR)mir_alloc(KL_NAMELENGTH+1);
+ 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;
+
+
+ iRes = ToUnicodeEx(shVirtualKey, iScanCode, bState, ptszTemp, 3, 0, hklLayout);
+ // Защита от дэд-кеев
+ if (iRes<0) ToUnicodeEx(shVirtualKey, iScanCode, bState, ptszTemp, 3, 0, hklLayout);
+
+
+ //Если нам вернули нулевой символ, или не вернули ничего, то присвоим "звоночек"
+ 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));
+
+ _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));
+
+ _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_V2 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 (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 (SendMessage(hTextWnd, EM_STREAMOUT, SF_TEXT|SF_UNICODE|SFF_SELECTION, (LPARAM)&esStream)>0)
+
+ 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 (SendMessage(hTextWnd, EM_STREAMOUT, SF_TEXT|SF_UNICODE|SFF_SELECTION, (LPARAM)&esStream) != 0)
+
+ 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 = (int)_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 (SendMessage(hTextWnd, EM_STREAMOUT, SF_TEXT|SF_UNICODE|SFF_SELECTION, (LPARAM)&esStream) != 0)
+
+ 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 (GetWindowLongPtr(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_V2);
+ 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/src/text_operations.h b/plugins/ChangeKeyboardLayout/src/text_operations.h
new file mode 100644
index 0000000000..6671406f3d
--- /dev/null
+++ b/plugins/ChangeKeyboardLayout/src/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);
+LPSTR 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