From 881cdec3f53d98320cee55318f8adbe47b93e5e0 Mon Sep 17 00:00:00 2001 From: Kirill Volinsky Date: Fri, 22 Jun 2012 20:31:16 +0000 Subject: renamed to .cpp git-svn-id: http://svn.miranda-ng.org/main/trunk@534 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/ChangeKeyboardLayout/text_operations.cpp | 661 +++++++++++++++++++++++ 1 file changed, 661 insertions(+) create mode 100644 plugins/ChangeKeyboardLayout/text_operations.cpp (limited to 'plugins/ChangeKeyboardLayout/text_operations.cpp') diff --git a/plugins/ChangeKeyboardLayout/text_operations.cpp b/plugins/ChangeKeyboardLayout/text_operations.cpp new file mode 100644 index 0000000000..c7652c7776 --- /dev/null +++ b/plugins/ChangeKeyboardLayout/text_operations.cpp @@ -0,0 +1,661 @@ +#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 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