richedit: Handle ctrl-key shortcuts on WM_KEYDOWN.

This commit is contained in:
Dylan Smith 2008-10-21 20:43:47 -04:00 committed by Alexandre Julliard
parent aa3b75f6b7
commit 5bcb15dd7f
2 changed files with 138 additions and 111 deletions

View File

@ -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; i<cb && pSrc[pData->nLength+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; i<cb && pSrc[pData->nLength+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; i<cb && pSrc[pData->nLength+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; i<cb && pSrc[pData->nLength+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') {

View File

@ -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',