From 5bcb15dd7f5182ba90d43e07f27373e054f4ebe7 Mon Sep 17 00:00:00 2001 From: Dylan Smith Date: Tue, 21 Oct 2008 20:43:47 -0400 Subject: [PATCH] richedit: Handle ctrl-key shortcuts on WM_KEYDOWN. --- dlls/riched20/editor.c | 239 +++++++++++++++++++---------------- dlls/riched20/tests/editor.c | 10 +- 2 files changed, 138 insertions(+), 111 deletions(-) diff --git a/dlls/riched20/editor.c b/dlls/riched20/editor.c index 792f05fe17c..a4a26cc5a3a 100644 --- a/dlls/riched20/editor.c +++ b/dlls/riched20/editor.c @@ -1938,6 +1938,93 @@ ME_FindText(ME_TextEditor *editor, DWORD flags, const CHARRANGE *chrg, const WCH return -1; } +typedef struct tagME_GlobalDestStruct +{ + HGLOBAL hData; + int nLength; +} ME_GlobalDestStruct; + +static DWORD CALLBACK ME_ReadFromHGLOBALUnicode(DWORD_PTR dwCookie, LPBYTE lpBuff, LONG cb, LONG *pcb) +{ + ME_GlobalDestStruct *pData = (ME_GlobalDestStruct *)dwCookie; + int i; + WORD *pSrc, *pDest; + + cb = cb >> 1; + pDest = (WORD *)lpBuff; + pSrc = (WORD *)GlobalLock(pData->hData); + for (i = 0; inLength+i]; i++) { + pDest[i] = pSrc[pData->nLength+i]; + } + pData->nLength += i; + *pcb = 2*i; + GlobalUnlock(pData->hData); + return 0; +} + +static DWORD CALLBACK ME_ReadFromHGLOBALRTF(DWORD_PTR dwCookie, LPBYTE lpBuff, LONG cb, LONG *pcb) +{ + ME_GlobalDestStruct *pData = (ME_GlobalDestStruct *)dwCookie; + int i; + BYTE *pSrc, *pDest; + + pDest = lpBuff; + pSrc = (BYTE *)GlobalLock(pData->hData); + for (i = 0; inLength+i]; i++) { + pDest[i] = pSrc[pData->nLength+i]; + } + pData->nLength += i; + *pcb = i; + GlobalUnlock(pData->hData); + return 0; +} + +static BOOL ME_Paste(ME_TextEditor *editor) +{ + DWORD dwFormat = 0; + EDITSTREAM es; + ME_GlobalDestStruct gds; + UINT nRTFFormat = RegisterClipboardFormatA("Rich Text Format"); + UINT cf = 0; + + if (IsClipboardFormatAvailable(nRTFFormat)) + cf = nRTFFormat, dwFormat = SF_RTF; + else if (IsClipboardFormatAvailable(CF_UNICODETEXT)) + cf = CF_UNICODETEXT, dwFormat = SF_TEXT|SF_UNICODE; + else + return FALSE; + + if (!OpenClipboard(editor->hWnd)) + return FALSE; + gds.hData = GetClipboardData(cf); + gds.nLength = 0; + es.dwCookie = (DWORD)&gds; + es.pfnCallback = dwFormat == SF_RTF ? ME_ReadFromHGLOBALRTF : ME_ReadFromHGLOBALUnicode; + ME_StreamIn(editor, dwFormat|SFF_SELECTION, &es, FALSE); + + CloseClipboard(); + return TRUE; +} + +static BOOL ME_Copy(ME_TextEditor *editor, CHARRANGE *range) +{ + LPDATAOBJECT dataObj = NULL; + HRESULT hr = S_OK; + + if (editor->cPasswordMask) + return FALSE; /* Copying or Cutting masked text isn't allowed */ + + if(editor->lpOleCallback) + hr = IRichEditOleCallback_GetClipboardData(editor->lpOleCallback, range, RECO_COPY, &dataObj); + if(FAILED(hr) || !dataObj) + hr = ME_GetDataObject(editor, range, &dataObj); + if(SUCCEEDED(hr)) { + hr = OleSetClipboard(dataObj); + IDataObject_Release(dataObj); + } + return SUCCEEDED(hr) != 0; +} + /* helper to send a msg filter notification */ static BOOL ME_FilterEvent(ME_TextEditor *editor, UINT msg, WPARAM* wParam, LPARAM* lParam) @@ -2023,6 +2110,49 @@ ME_KeyDown(ME_TextEditor *editor, WORD nKey) ME_UpdateRepaint(editor); ME_SendRequestResize(editor, FALSE); return TRUE; + case 'A': + if (ctrl_is_down) + { + ME_SetSelection(editor, 0, -1); + return TRUE; + } + break; + case 'V': + if (ctrl_is_down) + return ME_Paste(editor); + break; + case 'C': + case 'X': + if (ctrl_is_down) + { + CHARRANGE range; + BOOL result; + + ME_GetSelection(editor, &range.cpMin, &range.cpMax); + result = ME_Copy(editor, &range); + if (result && nKey == 'X') + { + ME_InternalDeleteText(editor, range.cpMin, range.cpMax-range.cpMin, FALSE); + ME_CommitUndo(editor); + ME_UpdateRepaint(editor); + } + return result; + } + break; + case 'Z': + if (ctrl_is_down) + { + ME_Undo(editor); + return TRUE; + } + break; + case 'Y': + if (ctrl_is_down) + { + ME_Redo(editor); + return TRUE; + } + break; default: if (nKey != VK_SHIFT && nKey != VK_CONTROL && nKey && nKey != VK_MENU) @@ -2270,48 +2400,6 @@ ME_TextEditor *ME_MakeEditor(HWND hWnd) { return ed; } -typedef struct tagME_GlobalDestStruct -{ - HGLOBAL hData; - int nLength; -} ME_GlobalDestStruct; - -static DWORD CALLBACK ME_ReadFromHGLOBALUnicode(DWORD_PTR dwCookie, LPBYTE lpBuff, LONG cb, LONG *pcb) -{ - ME_GlobalDestStruct *pData = (ME_GlobalDestStruct *)dwCookie; - int i; - WORD *pSrc, *pDest; - - cb = cb >> 1; - pDest = (WORD *)lpBuff; - pSrc = (WORD *)GlobalLock(pData->hData); - for (i = 0; inLength+i]; i++) { - pDest[i] = pSrc[pData->nLength+i]; - } - pData->nLength += i; - *pcb = 2*i; - GlobalUnlock(pData->hData); - return 0; -} - -static DWORD CALLBACK ME_ReadFromHGLOBALRTF(DWORD_PTR dwCookie, LPBYTE lpBuff, LONG cb, LONG *pcb) -{ - ME_GlobalDestStruct *pData = (ME_GlobalDestStruct *)dwCookie; - int i; - BYTE *pSrc, *pDest; - - pDest = lpBuff; - pSrc = (BYTE *)GlobalLock(pData->hData); - for (i = 0; inLength+i]; i++) { - pDest[i] = pSrc[pData->nLength+i]; - } - pData->nLength += i; - *pcb = i; - GlobalUnlock(pData->hData); - return 0; -} - - void ME_DestroyEditor(ME_TextEditor *editor) { ME_DisplayItem *pFirst = editor->pBuffer->pFirst; @@ -3066,51 +3154,15 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam, return FALSE; } case WM_PASTE: - { - DWORD dwFormat = 0; - EDITSTREAM es; - ME_GlobalDestStruct gds; - UINT nRTFFormat = RegisterClipboardFormatA("Rich Text Format"); - UINT cf = 0; - - if (IsClipboardFormatAvailable(nRTFFormat)) - cf = nRTFFormat, dwFormat = SF_RTF; - else if (IsClipboardFormatAvailable(CF_UNICODETEXT)) - cf = CF_UNICODETEXT, dwFormat = SF_TEXT|SF_UNICODE; - else - return 0; - - if (!OpenClipboard(hWnd)) - return 0; - gds.hData = GetClipboardData(cf); - gds.nLength = 0; - es.dwCookie = (DWORD)&gds; - es.pfnCallback = dwFormat == SF_RTF ? ME_ReadFromHGLOBALRTF : ME_ReadFromHGLOBALUnicode; - ME_StreamIn(editor, dwFormat|SFF_SELECTION, &es, FALSE); - - CloseClipboard(); + ME_Paste(editor); return 0; - } case WM_CUT: case WM_COPY: { - LPDATAOBJECT dataObj = NULL; CHARRANGE range; - HRESULT hr = S_OK; - - if (editor->cPasswordMask) - return 0; /* Copying or Cutting masked text isn't allowed */ - ME_GetSelection(editor, &range.cpMin, &range.cpMax); - if(editor->lpOleCallback) - hr = IRichEditOleCallback_GetClipboardData(editor->lpOleCallback, &range, RECO_COPY, &dataObj); - if(FAILED(hr) || !dataObj) - hr = ME_GetDataObject(editor, &range, &dataObj); - if(SUCCEEDED(hr)) { - hr = OleSetClipboard(dataObj); - IDataObject_Release(dataObj); - } - if (SUCCEEDED(hr) && msg == WM_CUT) + + if (ME_Copy(editor, &range) && msg == WM_CUT) { ME_InternalDeleteText(editor, range.cpMin, range.cpMax-range.cpMin, FALSE); ME_CommitUndo(editor); @@ -3657,36 +3709,11 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam, MultiByteToWideChar(CP_ACP, 0, &charA, 1, &wstr, 1); } - switch (wstr) - { - case 1: /* Ctrl-A */ - ME_SetSelection(editor, 0, -1); - return 0; - case 3: /* Ctrl-C */ - SendMessageW(editor->hWnd, WM_COPY, 0, 0); - return 0; - } - if (GetWindowLongW(editor->hWnd, GWL_STYLE) & ES_READONLY) { MessageBeep(MB_ICONERROR); return 0; /* FIXME really 0 ? */ } - switch (wstr) - { - case 22: /* Ctrl-V */ - SendMessageW(editor->hWnd, WM_PASTE, 0, 0); - return 0; - case 24: /* Ctrl-X */ - SendMessageW(editor->hWnd, WM_CUT, 0, 0); - return 0; - case 25: /* Ctrl-Y */ - SendMessageW(editor->hWnd, EM_REDO, 0, 0); - return 0; - case 26: /* Ctrl-Z */ - SendMessageW(editor->hWnd, EM_UNDO, 0, 0); - return 0; - } if (((unsigned)wstr)>=' ' || (wstr=='\r' && (GetWindowLongW(hWnd, GWL_STYLE) & ES_MULTILINE)) || wstr=='\t') { diff --git a/dlls/riched20/tests/editor.c b/dlls/riched20/tests/editor.c index 948f5197372..14bfb6dc888 100644 --- a/dlls/riched20/tests/editor.c +++ b/dlls/riched20/tests/editor.c @@ -4495,7 +4495,7 @@ static void test_WM_PASTE(void) SendMessage(hwndRichEdit, WM_GETTEXT, 1024, (LPARAM) buffer); /* Shouldn't paste because pasting is handled by WM_KEYDOWN */ result = strcmp(buffer,""); - todo_wine ok(result == 0, + ok(result == 0, "test paste: strcmp = %i, actual = '%s'\n", result, buffer); /* Send keystrokes with WM_KEYDOWN after setting the modifiers @@ -4509,7 +4509,7 @@ static void test_WM_PASTE(void) release_key(VK_CONTROL); SendMessage(hwndRichEdit, WM_GETTEXT, 1024, (LPARAM) buffer); result = strcmp(buffer,"paste"); - todo_wine ok(result == 0, + ok(result == 0, "test paste: strcmp = %i, actual = '%s'\n", result, buffer); SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM) text1); @@ -4523,7 +4523,7 @@ static void test_WM_PASTE(void) SendMessage(hwndRichEdit, WM_PASTE, 0, 0); SendMessage(hwndRichEdit, WM_GETTEXT, 1024, (LPARAM) buffer); result = strcmp(buffer,"testing"); - todo_wine ok(result == 0, + ok(result == 0, "test paste: strcmp = %i, actual = '%s'\n", result, buffer); /* Cut with WM_KEYDOWN to simulate Ctrl-X */ @@ -4538,7 +4538,7 @@ static void test_WM_PASTE(void) release_key(VK_CONTROL); SendMessage(hwndRichEdit, WM_GETTEXT, 1024, (LPARAM) buffer); result = strcmp(buffer,""); - todo_wine ok(result == 0, + ok(result == 0, "test paste: strcmp = %i, actual = '%s'\n", result, buffer); SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM) NULL); SendMessage(hwndRichEdit, WM_PASTE, 0, 0); @@ -4552,7 +4552,7 @@ static void test_WM_PASTE(void) (MapVirtualKey('Z', MAPVK_VK_TO_VSC) << 16) & 1); SendMessage(hwndRichEdit, WM_GETTEXT, 1024, (LPARAM) buffer); result = strcmp(buffer,""); - todo_wine ok(result == 0, + ok(result == 0, "test paste: strcmp = %i, actual = '%s'\n", result, buffer); /* Simulates redo (Ctrl-Y) */ SendMessage(hwndRichEdit, WM_KEYDOWN, 'Y',