From 226e4fb73c7cc9fe7aa8d7e2afe9afc124a51cb7 Mon Sep 17 00:00:00 2001 From: Vadim Dashevskiy Date: Mon, 9 Jul 2012 07:51:11 +0000 Subject: changekeyboardlayout: changed folder structure git-svn-id: http://svn.miranda-ng.org/main/trunk@872 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/ChangeKeyboardLayout/src/commonheaders.h | 120 ++++ plugins/ChangeKeyboardLayout/src/hook_events.cpp | 291 +++++++++ plugins/ChangeKeyboardLayout/src/hook_events.h | 14 + plugins/ChangeKeyboardLayout/src/main.cpp | 75 +++ plugins/ChangeKeyboardLayout/src/options.cpp | 500 ++++++++++++++++ plugins/ChangeKeyboardLayout/src/options.h | 9 + plugins/ChangeKeyboardLayout/src/resource.h | 81 +++ .../ChangeKeyboardLayout/src/text_operations.cpp | 649 +++++++++++++++++++++ plugins/ChangeKeyboardLayout/src/text_operations.h | 16 + 9 files changed, 1755 insertions(+) create mode 100644 plugins/ChangeKeyboardLayout/src/commonheaders.h create mode 100644 plugins/ChangeKeyboardLayout/src/hook_events.cpp create mode 100644 plugins/ChangeKeyboardLayout/src/hook_events.h create mode 100644 plugins/ChangeKeyboardLayout/src/main.cpp create mode 100644 plugins/ChangeKeyboardLayout/src/options.cpp create mode 100644 plugins/ChangeKeyboardLayout/src/options.h create mode 100644 plugins/ChangeKeyboardLayout/src/resource.h create mode 100644 plugins/ChangeKeyboardLayout/src/text_operations.cpp create mode 100644 plugins/ChangeKeyboardLayout/src/text_operations.h (limited to 'plugins/ChangeKeyboardLayout/src') 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 +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include "m_changekeyboardlayout.h" +#include + +#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;iidFrom) + { + 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=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