riched20: Implemented EM_SETTEXTMODE options TM_RICHTEXT and TM_PLAINTEXT
and their tests.
This commit is contained in:
parent
416f504cdd
commit
b03c70a845
|
@ -594,7 +594,7 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre
|
|||
editor->nEventMask = 0;
|
||||
|
||||
ME_GetSelection(editor, &from, &to);
|
||||
if (format & SFF_SELECTION) {
|
||||
if ((format & SFF_SELECTION) && (editor->mode & TM_RICHTEXT)) {
|
||||
style = ME_GetSelectionInsertStyle(editor);
|
||||
|
||||
ME_InternalDeleteText(editor, from, to-from);
|
||||
|
@ -1015,6 +1015,7 @@ ME_TextEditor *ME_MakeEditor(HWND hWnd) {
|
|||
ed->nInvalidOfs = -1;
|
||||
ed->pfnWordBreak = NULL;
|
||||
ed->lpOleCallback = NULL;
|
||||
ed->mode = TM_RICHTEXT | TM_MULTILEVELUNDO | TM_MULTICODEPAGE;
|
||||
GetClientRect(hWnd, &ed->rcFormat);
|
||||
for (i=0; i<HFONT_CACHE_SIZE; i++)
|
||||
{
|
||||
|
@ -1338,7 +1339,6 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP
|
|||
UNSUPPORTED_MSG(EM_SETSCROLLPOS)
|
||||
UNSUPPORTED_MSG(EM_SETTABSTOPS)
|
||||
UNSUPPORTED_MSG(EM_SETTARGETDEVICE)
|
||||
UNSUPPORTED_MSG(EM_SETTEXTMODE)
|
||||
UNSUPPORTED_MSG(EM_SETTYPOGRAPHYOPTIONS)
|
||||
UNSUPPORTED_MSG(EM_SETUNDOLIMIT)
|
||||
UNSUPPORTED_MSG(EM_SETWORDBREAKPROCEX)
|
||||
|
@ -1508,7 +1508,7 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP
|
|||
CHARFORMAT2W buf, *p;
|
||||
BOOL bRepaint = TRUE;
|
||||
p = ME_ToCF2W(&buf, (CHARFORMAT2W *)lParam);
|
||||
if (!wParam)
|
||||
if (!wParam || (editor->mode & TM_PLAINTEXT))
|
||||
ME_SetDefaultCharFormat(editor, p);
|
||||
else if (wParam == (SCF_WORD | SCF_SELECTION))
|
||||
FIXME("EM_SETCHARFORMAT: word selection not supported\n");
|
||||
|
@ -1748,16 +1748,17 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP
|
|||
ME_GetTextW(editor, data, from, to-from, TRUE);
|
||||
GlobalUnlock(hData);
|
||||
|
||||
if (editor->mode & TM_RICHTEXT)
|
||||
{
|
||||
gds.hData = GlobalAlloc(GMEM_MOVEABLE, 0);
|
||||
gds.nLength = 0;
|
||||
es.dwCookie = (DWORD)&gds;
|
||||
es.pfnCallback = ME_AppendToHGLOBAL;
|
||||
ME_StreamOutRange(editor, SF_RTF, from, to, &es);
|
||||
GlobalReAlloc(gds.hData, gds.nLength+1, 0);
|
||||
|
||||
SetClipboardData(CF_UNICODETEXT, hData);
|
||||
SetClipboardData(RegisterClipboardFormatA("Rich Text Format"), gds.hData);
|
||||
|
||||
}
|
||||
SetClipboardData(CF_UNICODETEXT, hData);
|
||||
CloseClipboard();
|
||||
if (msg == WM_CUT)
|
||||
{
|
||||
|
@ -2237,6 +2238,32 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP
|
|||
editor->pfnWordBreak = (EDITWORDBREAKPROCW)lParam;
|
||||
return (LRESULT)pfnOld;
|
||||
}
|
||||
case EM_SETTEXTMODE:
|
||||
{
|
||||
LRESULT ret;
|
||||
int mask = 0;
|
||||
int changes = 0;
|
||||
if ((ret = RichEditANSIWndProc(hWnd, WM_GETTEXTLENGTH, 0, 0)) == 0)
|
||||
{
|
||||
/*Check for valid wParam*/
|
||||
if ((((wParam & TM_RICHTEXT) && ((wParam & TM_PLAINTEXT) << 1))) ||
|
||||
(((wParam & TM_MULTILEVELUNDO) && ((wParam & TM_SINGLELEVELUNDO) << 1))) ||
|
||||
(((wParam & TM_MULTICODEPAGE) && ((wParam & TM_SINGLECODEPAGE) << 1))))
|
||||
return 1;
|
||||
else
|
||||
{
|
||||
if (wParam & (TM_RICHTEXT | TM_PLAINTEXT))
|
||||
{
|
||||
mask |= (TM_RICHTEXT | TM_PLAINTEXT);
|
||||
changes |= (wParam & (TM_RICHTEXT | TM_PLAINTEXT));
|
||||
}
|
||||
/*FIXME: Currently no support for undo level and code page options*/
|
||||
editor->mode = (editor->mode & (~mask)) | changes;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
default:
|
||||
do_default:
|
||||
return DefWindowProcW(hWnd, msg, wParam, lParam);
|
||||
|
|
|
@ -308,6 +308,11 @@ typedef struct tagME_TextEditor
|
|||
int nInvalidOfs;
|
||||
EDITWORDBREAKPROCW pfnWordBreak;
|
||||
LPRICHEDITOLECALLBACK lpOleCallback;
|
||||
/*TEXTMODE variable; contains only one of each of the following options:
|
||||
*TM_RICHTEXT or TM_PLAINTEXT
|
||||
*TM_SINGLELEVELUNDO or TM_MULTILEVELUNDO
|
||||
*TM_SINGLECODEPAGE or TM_MULTICODEPAGE*/
|
||||
int mode;
|
||||
} ME_TextEditor;
|
||||
|
||||
typedef struct tagME_Context
|
||||
|
|
|
@ -255,6 +255,239 @@ static void test_EM_SCROLLCARET(void)
|
|||
DestroyWindow(hwndRichEdit);
|
||||
}
|
||||
|
||||
static void test_EM_SETTEXTMODE(void)
|
||||
{
|
||||
HWND hwndRichEdit = new_richedit(NULL);
|
||||
CHARFORMAT2 cf2, cf2test;
|
||||
CHARRANGE cr;
|
||||
int rc = 0;
|
||||
|
||||
/*Test that EM_SETTEXTMODE fails if text exists within the control*/
|
||||
/*Insert text into the control*/
|
||||
|
||||
SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM) "wine");
|
||||
|
||||
/*Attempt to change the control to plain text mode*/
|
||||
rc = SendMessage(hwndRichEdit, EM_SETTEXTMODE, (WPARAM) TM_PLAINTEXT, 0);
|
||||
ok(rc != 0, "EM_SETTEXTMODE: changed text mode in control containing text - returned: %d\n", rc);
|
||||
|
||||
/*Test that EM_SETTEXTMODE does not allow rich edit text to be pasted.
|
||||
If rich text is pasted, it should have the same formatting as the rest
|
||||
of the text in the control*/
|
||||
|
||||
/*Italicize the text
|
||||
*NOTE: If the default text was already italicized, the test will simply
|
||||
reverse; in other words, it will copy a regular "wine" into a plain
|
||||
text window that uses an italicized format*/
|
||||
cf2.cbSize = sizeof(CHARFORMAT2);
|
||||
SendMessage(hwndRichEdit, EM_GETCHARFORMAT, (WPARAM) SCF_DEFAULT,
|
||||
(LPARAM) &cf2);
|
||||
|
||||
cf2.dwMask = CFM_ITALIC | cf2.dwMask;
|
||||
cf2.dwEffects = CFE_ITALIC ^ cf2.dwEffects;
|
||||
|
||||
/*EM_SETCHARFORMAT is not yet fully implemented for all WPARAMs in wine;
|
||||
however, SCF_ALL has been implemented*/
|
||||
SendMessage(hwndRichEdit, EM_SETCHARFORMAT, (WPARAM) SCF_ALL, (LPARAM) &cf2);
|
||||
SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM) "wine");
|
||||
|
||||
/*Select the string "wine"*/
|
||||
cr.cpMin = 0;
|
||||
cr.cpMax = 4;
|
||||
SendMessage(hwndRichEdit, EM_EXSETSEL, 0, (LPARAM) &cr);
|
||||
|
||||
/*Copy the italicized "wine" to the clipboard*/
|
||||
SendMessage(hwndRichEdit, WM_COPY, 0, 0);
|
||||
|
||||
/*Reset the formatting to default*/
|
||||
cf2.dwEffects = CFE_ITALIC^cf2.dwEffects;
|
||||
SendMessage(hwndRichEdit, EM_SETCHARFORMAT, (WPARAM) SCF_ALL, (LPARAM) &cf2);
|
||||
|
||||
/*Clear the text in the control*/
|
||||
SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM) "");
|
||||
|
||||
/*Switch to Plain Text Mode*/
|
||||
rc = SendMessage(hwndRichEdit, EM_SETTEXTMODE, (WPARAM) TM_PLAINTEXT, 0);
|
||||
ok(rc == 0, "EM_SETTEXTMODE: unable to switch to plain text mode with empty control: returned: %d\n", rc);
|
||||
|
||||
/*Input "wine" again in normal format*/
|
||||
SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM) "wine");
|
||||
|
||||
/*Paste the italicized "wine" into the control*/
|
||||
SendMessage(hwndRichEdit, WM_PASTE, 0, 0);
|
||||
|
||||
/*Select a character from the first "wine" string*/
|
||||
cr.cpMin = 2;
|
||||
cr.cpMax = 3;
|
||||
SendMessage(hwndRichEdit, EM_EXSETSEL, 0, (LPARAM) &cr);
|
||||
|
||||
/*Retrieve its formatting*/
|
||||
SendMessage(hwndRichEdit, EM_GETCHARFORMAT, (WPARAM) SCF_SELECTION,
|
||||
(LPARAM) &cf2);
|
||||
|
||||
/*Select a character from the second "wine" string*/
|
||||
cr.cpMin = 5;
|
||||
cr.cpMax = 6;
|
||||
SendMessage(hwndRichEdit, EM_EXSETSEL, 0, (LPARAM) &cr);
|
||||
|
||||
/*Retrieve its formatting*/
|
||||
cf2test.cbSize = sizeof(CHARFORMAT2);
|
||||
SendMessage(hwndRichEdit, EM_GETCHARFORMAT, (WPARAM) SCF_SELECTION,
|
||||
(LPARAM) &cf2test);
|
||||
|
||||
/*Compare the two formattings*/
|
||||
ok((cf2.dwMask == cf2test.dwMask) && (cf2.dwEffects == cf2test.dwEffects),
|
||||
"two formats found in plain text mode - cf2.dwEffects: %f cf2test.dwEffects: %f\n",(double) cf2.dwEffects, (double) cf2test.dwEffects);
|
||||
/*Test TM_RICHTEXT by: switching back to Rich Text mode
|
||||
printing "wine" in the current format(normal)
|
||||
pasting "wine" from the clipboard(italicized)
|
||||
comparing the two formats(should differ)*/
|
||||
|
||||
/*Attempt to switch with text in control*/
|
||||
rc = SendMessage(hwndRichEdit, EM_SETTEXTMODE, (WPARAM) TM_RICHTEXT, 0);
|
||||
ok(rc != 0, "EM_SETTEXTMODE: changed from plain text to rich text with text in control - returned: %d\n", rc);
|
||||
|
||||
/*Clear control*/
|
||||
SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM) "");
|
||||
|
||||
/*Switch into Rich Text mode*/
|
||||
rc = SendMessage(hwndRichEdit, EM_SETTEXTMODE, (WPARAM) TM_RICHTEXT, 0);
|
||||
ok(rc == 0, "EM_SETTEXTMODE: unable to change to rich text with empty control - returned: %d\n", rc);
|
||||
|
||||
/*Print "wine" in normal formatting into the control*/
|
||||
SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM) "wine");
|
||||
|
||||
/*Paste italicized "wine" into the control*/
|
||||
SendMessage(hwndRichEdit, WM_PASTE, 0, 0);
|
||||
|
||||
/*Select text from the first "wine" string*/
|
||||
cr.cpMin = 1;
|
||||
cr.cpMax = 3;
|
||||
SendMessage(hwndRichEdit, EM_EXSETSEL, 0, (LPARAM) &cr);
|
||||
|
||||
/*Retrieve its formatting*/
|
||||
SendMessage(hwndRichEdit, EM_GETCHARFORMAT, (WPARAM) SCF_SELECTION,
|
||||
(LPARAM) &cf2);
|
||||
|
||||
/*Select text from the second "wine" string*/
|
||||
cr.cpMin = 6;
|
||||
cr.cpMax = 7;
|
||||
SendMessage(hwndRichEdit, EM_EXSETSEL, 0, (LPARAM) &cr);
|
||||
|
||||
/*Retrieve its formatting*/
|
||||
SendMessage(hwndRichEdit, EM_GETCHARFORMAT, (WPARAM) SCF_SELECTION,
|
||||
(LPARAM) &cf2test);
|
||||
|
||||
/*Test that the two formattings are not the same*/
|
||||
ok((cf2.dwMask == cf2test.dwMask) && (cf2.dwEffects != cf2test.dwEffects),
|
||||
"expected different formats - cf2.dwMask: %f, cf2test.dwMask: %f, cf2.dwEffects: %f, cf2test.dwEffects: %f\n",
|
||||
(double) cf2.dwMask, (double) cf2test.dwMask, (double) cf2.dwEffects, (double) cf2test.dwEffects);
|
||||
|
||||
DestroyWindow(hwndRichEdit);
|
||||
}
|
||||
|
||||
static void test_TM_PLAINTEXT()
|
||||
{
|
||||
/*Tests plain text properties*/
|
||||
|
||||
HWND hwndRichEdit = new_richedit(NULL);
|
||||
CHARFORMAT2 cf2, cf2test;
|
||||
CHARRANGE cr;
|
||||
|
||||
/*Switch to plain text mode*/
|
||||
|
||||
SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM) "");
|
||||
SendMessage(hwndRichEdit, EM_SETTEXTMODE, TM_PLAINTEXT, 0);
|
||||
|
||||
/*Fill control with text*/
|
||||
|
||||
SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM) "Is Wine an emulator? No it's not");
|
||||
|
||||
/*Select some text and bold it*/
|
||||
|
||||
cr.cpMin = 10;
|
||||
cr.cpMax = 20;
|
||||
SendMessage(hwndRichEdit, EM_EXSETSEL, 0, (LPARAM) &cr);
|
||||
cf2.cbSize = sizeof(CHARFORMAT2);
|
||||
SendMessage(hwndRichEdit, EM_GETCHARFORMAT, (WPARAM) SCF_DEFAULT,
|
||||
(LPARAM) &cf2);
|
||||
|
||||
cf2.dwMask = CFM_BOLD | cf2.dwMask;
|
||||
cf2.dwEffects = CFE_BOLD ^ cf2.dwEffects;
|
||||
|
||||
SendMessage(hwndRichEdit, EM_SETCHARFORMAT, (WPARAM) SCF_SELECTION, (LPARAM) &cf2);
|
||||
|
||||
/*Get the formatting of those characters*/
|
||||
|
||||
SendMessage(hwndRichEdit, EM_GETCHARFORMAT, (WPARAM) SCF_SELECTION, (LPARAM) &cf2);
|
||||
|
||||
/*Get the formatting of some other characters*/
|
||||
cf2test.cbSize = sizeof(CHARFORMAT2);
|
||||
cr.cpMin = 21;
|
||||
cr.cpMax = 30;
|
||||
SendMessage(hwndRichEdit, EM_EXSETSEL, 0, (LPARAM) &cr);
|
||||
SendMessage(hwndRichEdit, EM_GETCHARFORMAT, (WPARAM) SCF_SELECTION, (LPARAM) &cf2test);
|
||||
|
||||
/*Test that they are the same as plain text allows only one formatting*/
|
||||
|
||||
ok((cf2.dwMask == cf2test.dwMask) && (cf2.dwEffects == cf2test.dwEffects),
|
||||
"two selections' formats differ - cf2.dwMask: %f, cf2test.dwMask %f, cf2.dwEffects: %f, cf2test.dwEffects: %f\n",
|
||||
(double) cf2.dwMask, (double) cf2test.dwMask, (double) cf2.dwEffects, (double) cf2test.dwEffects);
|
||||
|
||||
/*Fill the control with a "wine" string, which when inserted will be bold*/
|
||||
|
||||
SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM) "wine");
|
||||
|
||||
/*Copy the bolded "wine" string*/
|
||||
|
||||
cr.cpMin = 0;
|
||||
cr.cpMax = 4;
|
||||
SendMessage(hwndRichEdit, EM_EXSETSEL, 0, (LPARAM) &cr);
|
||||
SendMessage(hwndRichEdit, WM_COPY, 0, 0);
|
||||
|
||||
/*Swap back to rich text*/
|
||||
|
||||
SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM) "");
|
||||
SendMessage(hwndRichEdit, EM_SETTEXTMODE, (WPARAM) TM_RICHTEXT, 0);
|
||||
|
||||
/*Set the default formatting to bold italics*/
|
||||
|
||||
SendMessage(hwndRichEdit, EM_GETCHARFORMAT, (WPARAM) SCF_DEFAULT, (LPARAM) &cf2);
|
||||
cf2.dwMask |= CFM_ITALIC;
|
||||
cf2.dwEffects ^= CFE_ITALIC;
|
||||
SendMessage(hwndRichEdit, EM_SETCHARFORMAT, (WPARAM) SCF_ALL, (LPARAM) &cf2);
|
||||
|
||||
/*Set the text in the control to "wine", which will be bold and italicized*/
|
||||
|
||||
SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM) "wine");
|
||||
|
||||
/*Paste the plain text "wine" string, which should take the insert
|
||||
formatting, which at the moment is bold italics*/
|
||||
|
||||
SendMessage(hwndRichEdit, WM_PASTE, 0, 0);
|
||||
|
||||
/*Select the first "wine" string and retrieve its formatting*/
|
||||
|
||||
cr.cpMin = 1;
|
||||
cr.cpMax = 3;
|
||||
SendMessage(hwndRichEdit, EM_EXSETSEL, 0, (LPARAM) &cr);
|
||||
SendMessage(hwndRichEdit, EM_GETCHARFORMAT, (WPARAM) SCF_SELECTION, (LPARAM) &cf2);
|
||||
|
||||
/*Select the second "wine" string and retrieve its formatting*/
|
||||
|
||||
cr.cpMin = 5;
|
||||
cr.cpMax = 7;
|
||||
SendMessage(hwndRichEdit, EM_EXSETSEL, 0, (LPARAM) &cr);
|
||||
SendMessage(hwndRichEdit, EM_GETCHARFORMAT, (WPARAM) SCF_SELECTION, (LPARAM) &cf2test);
|
||||
|
||||
/*Compare the two formattings. They should be the same.*/
|
||||
|
||||
ok((cf2.dwMask == cf2test.dwMask) && (cf2.dwEffects == cf2test.dwEffects),
|
||||
"Copied text retained formatting - cf2.dwMask: %f, cf2test.dwMask: %f, cf2.dwEffects: %f, cf2test.dwEffects: %f",
|
||||
(double) cf2.dwMask, (double) cf2test.dwMask, (double) cf2.dwEffects, (double) cf2test.dwEffects);
|
||||
DestroyWindow(hwndRichEdit);
|
||||
}
|
||||
|
||||
START_TEST( editor )
|
||||
{
|
||||
MSG msg;
|
||||
|
@ -267,6 +500,8 @@ START_TEST( editor )
|
|||
|
||||
test_EM_FINDTEXT();
|
||||
test_EM_SCROLLCARET();
|
||||
test_EM_SETTEXTMODE();
|
||||
test_TM_PLAINTEXT();
|
||||
|
||||
/* Set the environment variable WINETEST_RICHED20 to keep windows
|
||||
* responsive and open for 30 seconds. This is useful for debugging.
|
||||
|
|
Loading…
Reference in New Issue