riched20: Implement ITextSelection::GetText.

This commit is contained in:
Jactry Zeng 2014-07-22 00:41:29 +08:00 committed by Alexandre Julliard
parent 68b9018d50
commit 1f6073c861
6 changed files with 132 additions and 13 deletions

View File

@ -352,7 +352,7 @@ static HGLOBAL get_unicode_text(ME_TextEditor *editor, const ME_Cursor *start, i
ret = GlobalAlloc(GMEM_MOVEABLE, sizeof(WCHAR) * (nChars + pars + 1)); ret = GlobalAlloc(GMEM_MOVEABLE, sizeof(WCHAR) * (nChars + pars + 1));
data = GlobalLock(ret); data = GlobalLock(ret);
ME_GetTextW(editor, data, nChars + pars, start, nChars, TRUE); ME_GetTextW(editor, data, nChars + pars, start, nChars, TRUE, FALSE);
GlobalUnlock(ret); GlobalUnlock(ret);
return ret; return ret;
} }

View File

@ -1630,7 +1630,7 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre
ME_Cursor linebreakCursor = *selEnd; ME_Cursor linebreakCursor = *selEnd;
ME_MoveCursorChars(editor, &linebreakCursor, -linebreakSize); ME_MoveCursorChars(editor, &linebreakCursor, -linebreakSize);
ME_GetTextW(editor, lastchar, 2, &linebreakCursor, linebreakSize, FALSE); ME_GetTextW(editor, lastchar, 2, &linebreakCursor, linebreakSize, FALSE, FALSE);
if (lastchar[0] == '\r' && (lastchar[1] == '\n' || lastchar[1] == '\0')) { if (lastchar[0] == '\r' && (lastchar[1] == '\n' || lastchar[1] == '\0')) {
ME_InternalDeleteText(editor, &linebreakCursor, linebreakSize, FALSE); ME_InternalDeleteText(editor, &linebreakCursor, linebreakSize, FALSE);
} }
@ -1968,7 +1968,7 @@ static int ME_GetTextEx(ME_TextEditor *editor, GETTEXTEX *ex, LPARAM pText)
if (ex->codepage == CP_UNICODE) if (ex->codepage == CP_UNICODE)
{ {
return ME_GetTextW(editor, (LPWSTR)pText, ex->cb / sizeof(WCHAR) - 1, return ME_GetTextW(editor, (LPWSTR)pText, ex->cb / sizeof(WCHAR) - 1,
&start, nChars, ex->flags & GT_USECRLF); &start, nChars, ex->flags & GT_USECRLF, FALSE);
} }
else else
{ {
@ -1985,7 +1985,7 @@ static int ME_GetTextEx(ME_TextEditor *editor, GETTEXTEX *ex, LPARAM pText)
buflen = min(crlfmul * nChars, ex->cb - 1); buflen = min(crlfmul * nChars, ex->cb - 1);
buffer = heap_alloc((buflen + 1) * sizeof(WCHAR)); buffer = heap_alloc((buflen + 1) * sizeof(WCHAR));
nChars = ME_GetTextW(editor, buffer, buflen, &start, nChars, ex->flags & GT_USECRLF); nChars = ME_GetTextW(editor, buffer, buflen, &start, nChars, ex->flags & GT_USECRLF, FALSE);
rc = WideCharToMultiByte(ex->codepage, 0, buffer, nChars + 1, rc = WideCharToMultiByte(ex->codepage, 0, buffer, nChars + 1,
(LPSTR)pText, ex->cb, ex->lpDefaultChar, ex->lpUsedDefChar); (LPSTR)pText, ex->cb, ex->lpDefaultChar, ex->lpUsedDefChar);
if (rc) rc--; /* do not count 0 terminator */ if (rc) rc--; /* do not count 0 terminator */
@ -2000,12 +2000,12 @@ static int ME_GetTextRange(ME_TextEditor *editor, WCHAR *strText,
{ {
if (!strText) return 0; if (!strText) return 0;
if (unicode) { if (unicode) {
return ME_GetTextW(editor, strText, INT_MAX, start, nLen, FALSE); return ME_GetTextW(editor, strText, INT_MAX, start, nLen, FALSE, FALSE);
} else { } else {
int nChars; int nChars;
WCHAR *p = ALLOC_N_OBJ(WCHAR, nLen+1); WCHAR *p = ALLOC_N_OBJ(WCHAR, nLen+1);
if (!p) return 0; if (!p) return 0;
nChars = ME_GetTextW(editor, p, nLen, start, nLen, FALSE); nChars = ME_GetTextW(editor, p, nLen, start, nLen, FALSE, FALSE);
WideCharToMultiByte(CP_ACP, 0, p, nChars+1, (char *)strText, WideCharToMultiByte(CP_ACP, 0, p, nChars+1, (char *)strText,
nLen+1, NULL, NULL); nLen+1, NULL, NULL);
FREE_OBJ(p); FREE_OBJ(p);
@ -4747,7 +4747,8 @@ void ME_SendOldNotify(ME_TextEditor *editor, int nCode)
* The written text is always NULL terminated. * The written text is always NULL terminated.
*/ */
int ME_GetTextW(ME_TextEditor *editor, WCHAR *buffer, int buflen, int ME_GetTextW(ME_TextEditor *editor, WCHAR *buffer, int buflen,
const ME_Cursor *start, int srcChars, BOOL bCRLF) const ME_Cursor *start, int srcChars, BOOL bCRLF,
BOOL bEOP)
{ {
ME_DisplayItem *pRun, *pNextRun; ME_DisplayItem *pRun, *pNextRun;
const WCHAR *pStart = buffer; const WCHAR *pStart = buffer;
@ -4765,7 +4766,6 @@ int ME_GetTextW(ME_TextEditor *editor, WCHAR *buffer, int buflen,
nLen = pRun->member.run.len - start->nOffset; nLen = pRun->member.run.len - start->nOffset;
str = get_text( &pRun->member.run, start->nOffset ); str = get_text( &pRun->member.run, start->nOffset );
/* No '\r' is appended to the last paragraph. */
while (srcChars && buflen && pNextRun) while (srcChars && buflen && pNextRun)
{ {
int nFlags = pRun->member.run.nFlags; int nFlags = pRun->member.run.nFlags;
@ -4797,6 +4797,12 @@ int ME_GetTextW(ME_TextEditor *editor, WCHAR *buffer, int buflen,
nLen = pRun->member.run.len; nLen = pRun->member.run.len;
str = get_text( &pRun->member.run, 0 ); str = get_text( &pRun->member.run, 0 );
} }
/* append '\r' to the last paragraph. */
if (pRun->next->type == diTextEnd && bEOP)
{
*buffer = '\r';
buffer ++;
}
*buffer = 0; *buffer = 0;
return buffer - pStart; return buffer - pStart;
} }
@ -5041,7 +5047,7 @@ static BOOL ME_IsCandidateAnURL(ME_TextEditor *editor, const ME_Cursor *start, i
WCHAR bufferW[MAX_PREFIX_LEN + 1]; WCHAR bufferW[MAX_PREFIX_LEN + 1];
unsigned int i; unsigned int i;
ME_GetTextW(editor, bufferW, MAX_PREFIX_LEN, start, nChars, FALSE); ME_GetTextW(editor, bufferW, MAX_PREFIX_LEN, start, nChars, FALSE, FALSE);
for (i = 0; i < sizeof(prefixes) / sizeof(*prefixes); i++) for (i = 0; i < sizeof(prefixes) / sizeof(*prefixes); i++)
{ {
if (nChars < prefixes[i].length) continue; if (nChars < prefixes[i].length) continue;

View File

@ -252,7 +252,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
LPARAM lParam, BOOL unicode, HRESULT* phresult) DECLSPEC_HIDDEN; LPARAM lParam, BOOL unicode, HRESULT* phresult) DECLSPEC_HIDDEN;
void ME_SendOldNotify(ME_TextEditor *editor, int nCode) DECLSPEC_HIDDEN; void ME_SendOldNotify(ME_TextEditor *editor, int nCode) DECLSPEC_HIDDEN;
int ME_GetTextW(ME_TextEditor *editor, WCHAR *buffer, int buflen, int ME_GetTextW(ME_TextEditor *editor, WCHAR *buffer, int buflen,
const ME_Cursor *start, int srcChars, BOOL bCRLF) DECLSPEC_HIDDEN; const ME_Cursor *start, int srcChars, BOOL bCRLF, BOOL bEOP) DECLSPEC_HIDDEN;
void ME_RTFCharAttrHook(struct _RTF_Info *info) DECLSPEC_HIDDEN; void ME_RTFCharAttrHook(struct _RTF_Info *info) DECLSPEC_HIDDEN;
void ME_RTFParAttrHook(struct _RTF_Info *info) DECLSPEC_HIDDEN; void ME_RTFParAttrHook(struct _RTF_Info *info) DECLSPEC_HIDDEN;
void ME_RTFTblAttrHook(struct _RTF_Info *info) DECLSPEC_HIDDEN; void ME_RTFTblAttrHook(struct _RTF_Info *info) DECLSPEC_HIDDEN;

View File

@ -783,11 +783,34 @@ static HRESULT WINAPI ITextSelection_fnInvoke(
static HRESULT WINAPI ITextSelection_fnGetText(ITextSelection *me, BSTR *pbstr) static HRESULT WINAPI ITextSelection_fnGetText(ITextSelection *me, BSTR *pbstr)
{ {
ITextSelectionImpl *This = impl_from_ITextSelection(me); ITextSelectionImpl *This = impl_from_ITextSelection(me);
ME_Cursor *start = NULL, *end = NULL;
int nChars, endOfs;
BOOL bEOP;
if (!This->reOle) if (!This->reOle)
return CO_E_RELEASED; return CO_E_RELEASED;
TRACE("%p\n", pbstr);
if (!pbstr)
return E_INVALIDARG;
FIXME("not implemented\n"); ME_GetSelection(This->reOle->editor, &start, &end);
return E_NOTIMPL; endOfs = ME_GetCursorOfs(end);
nChars = endOfs - ME_GetCursorOfs(start);
if (!nChars)
{
*pbstr = NULL;
return S_OK;
}
*pbstr = SysAllocStringLen(NULL, nChars);
if (!*pbstr)
return E_OUTOFMEMORY;
bEOP = (end->pRun->next->type == diTextEnd && endOfs > ME_GetTextLength(This->reOle->editor));
ME_GetTextW(This->reOle->editor, *pbstr, nChars, start, nChars, FALSE, bEOP);
TRACE("%s\n", wine_dbgstr_w(*pbstr));
return S_OK;
} }
static HRESULT WINAPI ITextSelection_fnSetText(ITextSelection *me, BSTR bstr) static HRESULT WINAPI ITextSelection_fnSetText(ITextSelection *me, BSTR bstr)

View File

@ -402,6 +402,95 @@ static void test_ITextDocument_Open(void)
VariantClear(&testfile); VariantClear(&testfile);
} }
static void test_ITextSelection_GetText(void)
{
HWND w;
IRichEditOle *reOle = NULL;
ITextDocument *txtDoc = NULL;
ITextSelection *txtSel = NULL;
HRESULT hres;
BSTR bstr = NULL;
int first, lim;
static const CHAR test_text1[] = "TestSomeText";
static const WCHAR bufW1[] = {'T', 'e', 's', 't', 0};
static const WCHAR bufW2[] = {'T', 'e', 'x', 't', '\r', 0};
static const WCHAR bufW3[] = {'T', 'e', 'x', 't', 0};
static const WCHAR bufW4[] = {'T', 'e', 's', 't', 'S', 'o', 'm',
'e', 'T', 'e', 'x', 't', '\r', 0};
static const WCHAR bufW5[] = {'\r', 0};
SYSTEM_INFO sysinfo;
int is64bit;
GetSystemInfo(&sysinfo);
is64bit = (sysinfo.wProcessorArchitecture & PROCESSOR_ARCHITECTURE_AMD64);
create_interfaces(&w, &reOle, &txtDoc, &txtSel);
SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
first = 0, lim = 4;
SendMessageA(w, EM_SETSEL, first, lim);
hres = ITextSelection_GetText(txtSel, &bstr);
ok(hres == S_OK, "ITextSelection_GetText\n");
ok(!lstrcmpW(bstr, bufW1), "got wrong text: %s\n", wine_dbgstr_w(bstr));
SysFreeString(bstr);
first = 4, lim = 0;
SendMessageA(w, EM_SETSEL, first, lim);
hres = ITextSelection_GetText(txtSel, &bstr);
ok(hres == S_OK, "ITextSelection_GetText\n");
ok(!lstrcmpW(bstr, bufW1), "got wrong text: %s\n", wine_dbgstr_w(bstr));
SysFreeString(bstr);
first = 1, lim = 1;
SendMessageA(w, EM_SETSEL, first, lim);
hres = ITextSelection_GetText(txtSel, &bstr);
ok(hres == S_OK, "ITextSelection_GetText\n");
ok(!bstr, "got wrong text: %s\n", wine_dbgstr_w(bstr));
if(is64bit)
win_skip("native 64bit riched20 can't support a NULL parameter\n");
else
{
hres = ITextSelection_GetText(txtSel, NULL);
ok(hres == E_INVALIDARG, "ITextSelection_GetText\n");
}
first = 8, lim = 12;
SendMessageA(w, EM_SETSEL, first, lim);
hres = ITextSelection_GetText(txtSel, &bstr);
ok(hres == S_OK, "ITextSelection_GetText\n");
ok(!lstrcmpW(bstr, bufW3), "got wrong text: %s\n", wine_dbgstr_w(bstr));
SysFreeString(bstr);
first = 8, lim = 13;
SendMessageA(w, EM_SETSEL, first, lim);
hres = ITextSelection_GetText(txtSel, &bstr);
ok(hres == S_OK, "ITextSelection_GetText\n");
ok(!lstrcmpW(bstr, bufW2), "got wrong text: %s\n", wine_dbgstr_w(bstr));
SysFreeString(bstr);
first = 12, lim = 13;
SendMessageA(w, EM_SETSEL, first, lim);
hres = ITextSelection_GetText(txtSel, &bstr);
ok(hres == S_OK, "ITextSelection_GetText\n");
ok(!lstrcmpW(bstr, bufW5), "got wrong text: %s\n", wine_dbgstr_w(bstr));
SysFreeString(bstr);
first = 0, lim = -1;
SendMessageA(w, EM_SETSEL, first, lim);
hres = ITextSelection_GetText(txtSel, &bstr);
ok(hres == S_OK, "ITextSelection_GetText\n");
ok(!lstrcmpW(bstr, bufW4), "got wrong text: %s\n", wine_dbgstr_w(bstr));
SysFreeString(bstr);
first = -1, lim = 9;
SendMessageA(w, EM_SETSEL, first, lim);
hres = ITextSelection_GetText(txtSel, &bstr);
ok(hres == S_OK, "ITextSelection_GetText\n");
ok(!bstr, "got wrong text: %s\n", wine_dbgstr_w(bstr));
release_interfaces(&w, &reOle, &txtDoc, &txtSel);
}
START_TEST(richole) START_TEST(richole)
{ {
/* Must explicitly LoadLibrary(). The test has no references to functions in /* Must explicitly LoadLibrary(). The test has no references to functions in
@ -411,4 +500,5 @@ START_TEST(richole)
test_Interfaces(); test_Interfaces();
test_ITextDocument_Open(); test_ITextDocument_Open();
test_ITextSelection_GetText();
} }

View File

@ -264,7 +264,7 @@ DECLSPEC_HIDDEN HRESULT WINAPI fnTextSrv_TxGetText(ITextServices *iface, BSTR *p
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
ME_CursorFromCharOfs(This->editor, 0, &start); ME_CursorFromCharOfs(This->editor, 0, &start);
ME_GetTextW(This->editor, bstr, length, &start, INT_MAX, FALSE); ME_GetTextW(This->editor, bstr, length, &start, INT_MAX, FALSE, FALSE);
*pbstrText = bstr; *pbstrText = bstr;
} else { } else {
*pbstrText = NULL; *pbstrText = NULL;