diff --git a/dlls/riched20/caret.c b/dlls/riched20/caret.c index ebf6c56..85c463b 100644 --- a/dlls/riched20/caret.c +++ b/dlls/riched20/caret.c @@ -59,7 +59,7 @@ int ME_GetTextLengthEx(ME_TextEditor *editor, const GETTEXTLENGTHEX *how) if ((GetWindowLongW(editor->hWnd, GWL_STYLE) & ES_MULTILINE) && (how->flags & GTL_USECRLF) - && !editor->bEmulateVersion10) /* Ignore GTL_USECRLF flag in 1.0 emulation */ + && editor->dwEmulatedVersion >= 0x200) /* Ignore GTL_USECRLF flag in 1.0 emulation */ length += editor->nParagraphs - 1; if (how->flags & GTL_NUMBYTES) @@ -508,7 +508,7 @@ void ME_InsertTextFromCursor(ME_TextEditor *editor, int nCursor, } } /* handle special \r\r\n sequence (richedit 2.x and higher only) */ - if (!editor->bEmulateVersion10 && pos-str < len-2 && pos[0] == '\r' && pos[1] == '\r' && pos[2] == '\n') { + if (editor->dwEmulatedVersion >= 0x200 && pos-str < len-2 && pos[0] == '\r' && pos[1] == '\r' && pos[2] == '\n') { WCHAR space = ' '; if (pos!=str) @@ -539,7 +539,7 @@ void ME_InsertTextFromCursor(ME_TextEditor *editor, int nCursor, /* ME_SplitParagraph increases style refcount */ /* Encode and fill number of CR and LF according to emulation mode */ - if (editor->bEmulateVersion10) { + if (editor->dwEmulatedVersion < 0x200) { const WCHAR * tpos; /* We have to find out how many consecutive \r are there, and if there diff --git a/dlls/riched20/editor.c b/dlls/riched20/editor.c index 28850f9..873cc99 100644 --- a/dlls/riched20/editor.c +++ b/dlls/riched20/editor.c @@ -245,6 +245,11 @@ static const WCHAR REListBox20W[] = {'R','E','L','i','s','t','B','o','x','2','0' static const WCHAR REComboBox20W[] = {'R','E','C','o','m','b','o','B','o','x','2','0','W', 0}; static HCURSOR hLeft; +static ATOM atomRichEdit20A = 0; +static ATOM atomRichEdit50A = 0; +static ATOM atomRichEdit20W = 0; +static ATOM atomRichEdit50W = 0; + int me_debug = 0; HANDLE me_heap = NULL; @@ -1068,8 +1073,8 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre ME_StreamInFill(&inStream); if (!inStream.editstream->dwError) { - if ((!editor->bEmulateVersion10 && strncmp(inStream.buffer, "{\\rtf", 5) && strncmp(inStream.buffer, "{\\urtf", 6)) - || (editor->bEmulateVersion10 && *inStream.buffer != '{')) + if ((editor->dwEmulatedVersion >= 0x200 && strncmp(inStream.buffer, "{\\rtf", 5) && strncmp(inStream.buffer, "{\\urtf", 6)) + || (editor->dwEmulatedVersion < 0x200 && *inStream.buffer != '{')) { invalidRTF = TRUE; inStream.editstream->dwError = -16; @@ -1111,9 +1116,9 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre if (stripLastCR) { int newfrom, newto; ME_GetSelection(editor, &newfrom, &newto); - if (newto > to + (editor->bEmulateVersion10 ? 1 : 0)) { + if (newto > to + (editor->dwEmulatedVersion < 0x200 ? 1 : 0)) { WCHAR lastchar[3] = {'\0', '\0'}; - int linebreakSize = editor->bEmulateVersion10 ? 2 : 1; + int linebreakSize = editor->dwEmulatedVersion < 0x200 ? 2 : 1; ME_GetTextW(editor, lastchar, newto - linebreakSize, linebreakSize, 0); if (lastchar[0] == '\r' && (lastchar[1] == '\n' || lastchar[1] == '\0')) { @@ -1268,13 +1273,13 @@ ME_FindText(ME_TextEditor *editor, DWORD flags, const CHARRANGE *chrg, const WCH nMax = chrg->cpMax > nTextLen ? nTextLen : chrg->cpMax; /* In 1.0 emulation, if cpMax reaches end of text, add the FR_DOWN flag */ - if (editor->bEmulateVersion10 && nMax == nTextLen) + if (editor->dwEmulatedVersion < 0x200 && nMax == nTextLen) { flags |= FR_DOWN; } /* In 1.0 emulation, cpMin must always be no greater than cpMax */ - if (editor->bEmulateVersion10 && nMax < nMin) + if (editor->dwEmulatedVersion < 0x200 && nMax < nMin) { if (chrgText) { @@ -1289,7 +1294,7 @@ ME_FindText(ME_TextEditor *editor, DWORD flags, const CHARRANGE *chrg, const WCH * [cpMax, cpMin]. The exception is when cpMax is -1, in which * case, it is always bigger than cpMin. */ - if (!editor->bEmulateVersion10 && !(flags & FR_DOWN)) + if (editor->dwEmulatedVersion >= 0x200 && !(flags & FR_DOWN)) { int nSwap = nMax; @@ -1642,9 +1647,19 @@ static BOOL ME_ShowContextMenu(ME_TextEditor *editor, int x, int y) ME_TextEditor *ME_MakeEditor(HWND hWnd) { ME_TextEditor *ed = ALLOC_OBJ(ME_TextEditor); + ATOM atom; int i; ed->hWnd = hWnd; - ed->bEmulateVersion10 = FALSE; + atom = (ATOM)GetClassLongW(hWnd, GCW_ATOM); + if (atom == atomRichEdit20A || atom == atomRichEdit20W) + { + ed->dwEmulatedVersion = 0x300; + } else { + /* Can't check for 1.0 since it is registered in riched32, but + * RichEdit10ANSIWndProc can correct dwEmulatedVersion. */ + ed->dwEmulatedVersion = 0x401; + } + TRACE("dwEmulatedVersion=%x\n", ed->dwEmulatedVersion); ed->pBuffer = ME_MakeText(); ed->nZoomNumerator = ed->nZoomDenominator = 0; ME_MakeFirstParagraph(ed); @@ -2554,7 +2569,7 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam, GETTEXTLENGTHEX how; /* CR/LF conversion required in 2.0 mode, verbatim in 1.0 mode */ - how.flags = GTL_CLOSE | (editor->bEmulateVersion10 ? 0 : GTL_USECRLF) | GTL_NUMCHARS; + how.flags = GTL_CLOSE | (editor->dwEmulatedVersion < 0x200 ? 0 : GTL_USECRLF) | GTL_NUMCHARS; how.codepage = unicode ? 1200 : CP_ACP; return ME_GetTextLengthEx(editor, &how); } @@ -2660,9 +2675,9 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam, case EM_GETTEXTRANGE: { TEXTRANGEW *rng = (TEXTRANGEW *)lParam; - TRACE("EM_GETTEXTRANGE min=%d max=%d unicode=%d emul1.0=%d length=%d\n", + TRACE("EM_GETTEXTRANGE min=%d max=%d unicode=%d version=%x length=%d\n", rng->chrg.cpMin, rng->chrg.cpMax, unicode, - editor->bEmulateVersion10, ME_GetTextLength(editor)); + editor->dwEmulatedVersion, ME_GetTextLength(editor)); if (unicode) return ME_GetTextW(editor, rng->lpstrText, rng->chrg.cpMin, rng->chrg.cpMax-rng->chrg.cpMin, 0); else @@ -2765,7 +2780,7 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam, last_para = ME_FindItemBack(item, diRun); assert(last_para); assert(last_para->member.run.nFlags & MERF_ENDPARA); - if (editor->bEmulateVersion10 && prev_para && last_para->member.run.nCharOfs == 0 + if (editor->dwEmulatedVersion < 0x200 && prev_para && last_para->member.run.nCharOfs == 0 && prev_para->member.run.nCR == 1 && prev_para->member.run.nLF == 0) { /* In 1.0 emulation, the last solitary \r at the very end of the text @@ -3406,8 +3421,9 @@ LRESULT WINAPI RichEdit10ANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM if (msg == WM_NCCREATE) { ME_TextEditor *editor = (ME_TextEditor *)GetWindowLongPtrW(hWnd, 0); - - editor->bEmulateVersion10 = TRUE; + + editor->dwEmulatedVersion = 0x100; + TRACE("dwEmulatedVersion=%x\n", editor->dwEmulatedVersion); editor->pBuffer->pLast->member.para.nCharOfs = 2; assert(editor->pBuffer->pLast->prev->type == diRun); assert(editor->pBuffer->pLast->prev->member.run.nFlags & MERF_ENDPARA); @@ -3483,7 +3499,7 @@ int ME_GetTextW(ME_TextEditor *editor, WCHAR *buffer, int nStart, int nChars, in } /* bCRLF flag is only honored in 2.0 and up. 1.0 must always return text verbatim */ - if (editor->bEmulateVersion10) bCRLF = 0; + if (editor->dwEmulatedVersion < 0x200) bCRLF = 0; if (nStart) { @@ -3582,17 +3598,21 @@ static BOOL ME_RegisterEditorClass(HINSTANCE hInstance) if (is_version_nt()) { wcW.lpszClassName = RichEdit20W; - if (!RegisterClassW(&wcW)) return FALSE; + atomRichEdit20A = RegisterClassW(&wcW); + if (!atomRichEdit20A) return FALSE; wcW.lpszClassName = RichEdit50W; - if (!RegisterClassW(&wcW)) return FALSE; + atomRichEdit50A = RegisterClassW(&wcW); + if (!atomRichEdit50A) return FALSE; } else { /* WNDCLASSA/W have the same layout */ wcW.lpszClassName = (LPCWSTR)"RichEdit20W"; - if (!RegisterClassA((WNDCLASSA *)&wcW)) return FALSE; + atomRichEdit20A = RegisterClassA((WNDCLASSA *)&wcW); + if (!atomRichEdit20A) return FALSE; wcW.lpszClassName = (LPCWSTR)"RichEdit50W"; - if (!RegisterClassA((WNDCLASSA *)&wcW)) return FALSE; + atomRichEdit50A = RegisterClassA((WNDCLASSA *)&wcW); + if (!atomRichEdit50A) return FALSE; } wcA.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW | CS_GLOBALCLASS; @@ -3605,9 +3625,11 @@ static BOOL ME_RegisterEditorClass(HINSTANCE hInstance) wcA.hbrBackground = (HBRUSH)GetStockObject(NULL_BRUSH); wcA.lpszMenuName = NULL; wcA.lpszClassName = "RichEdit20A"; - if (!RegisterClassA(&wcA)) return FALSE; + atomRichEdit20W = RegisterClassA(&wcA); + if (!atomRichEdit20W) return FALSE; wcA.lpszClassName = "RichEdit50A"; - if (!RegisterClassA(&wcA)) return FALSE; + atomRichEdit50W = RegisterClassA(&wcA); + if (!atomRichEdit50W) return FALSE; return TRUE; } diff --git a/dlls/riched20/editstr.h b/dlls/riched20/editstr.h index d54edbf..34c8d09 100644 --- a/dlls/riched20/editstr.h +++ b/dlls/riched20/editstr.h @@ -289,7 +289,9 @@ typedef struct tagME_FontCacheItem typedef struct tagME_TextEditor { HWND hWnd; - BOOL bEmulateVersion10; + /* Minor release stored in low byte, and major release in upper bytes + * i.e. 0x100 for v1.0, 0x200 for v2.0, 0x300 for v3.0 and 0x401 for v4.1 */ + DWORD dwEmulatedVersion; BOOL bCaretShown; ME_TextBuffer *pBuffer; ME_Cursor *pCursors; diff --git a/dlls/riched20/paint.c b/dlls/riched20/paint.c index a2bc7c5..1ab9316 100644 --- a/dlls/riched20/paint.c +++ b/dlls/riched20/paint.c @@ -98,7 +98,7 @@ void ME_Repaint(ME_TextEditor *editor) ME_UpdateScrollBar(editor); FIXME("ME_Repaint had to call ME_WrapMarkedParagraphs\n"); } - if (!editor->bEmulateVersion10 || (editor->nEventMask & ENM_UPDATE)) + if (!editor->dwEmulatedVersion || (editor->nEventMask & ENM_UPDATE)) ME_SendOldNotify(editor, EN_UPDATE); UpdateWindow(editor->hWnd); } diff --git a/dlls/riched20/para.c b/dlls/riched20/para.c index de69794..9d1d1e3 100644 --- a/dlls/riched20/para.c +++ b/dlls/riched20/para.c @@ -75,7 +75,7 @@ void ME_MakeFirstParagraph(ME_TextEditor *editor) run = ME_MakeRun(style, ME_MakeString(wszParagraphSign), MERF_ENDPARA); run->member.run.nCharOfs = 0; run->member.run.nCR = 1; - run->member.run.nLF = (editor->bEmulateVersion10) ? 1 : 0; + run->member.run.nLF = (editor->dwEmulatedVersion < 0x200) ? 1 : 0; ME_InsertBefore(text->pLast, para); ME_InsertBefore(text->pLast, run); diff --git a/dlls/riched20/reader.c b/dlls/riched20/reader.c index f456a09..7bdeda9 100644 --- a/dlls/riched20/reader.c +++ b/dlls/riched20/reader.c @@ -2608,7 +2608,7 @@ static void SpecialChar (RTF_Info *info) case rtfRow: case rtfPar: RTFPutUnicodeChar (info, '\r'); - if (info->editor->bEmulateVersion10) RTFPutUnicodeChar (info, '\n'); + if (info->editor->dwEmulatedVersion < 0x200) RTFPutUnicodeChar (info, '\n'); break; case rtfNoBrkSpace: RTFPutUnicodeChar (info, 0x00A0); diff --git a/dlls/riched20/string.c b/dlls/riched20/string.c index 97b5a67..4af3b3a 100644 --- a/dlls/riched20/string.c +++ b/dlls/riched20/string.c @@ -330,7 +330,7 @@ ME_WordBreakProc(LPWSTR s, INT start, INT len, INT code) int ME_CallWordBreakProc(ME_TextEditor *editor, ME_String *str, INT start, INT code) { - /* FIXME: ANSIfy the string when bEmulateVersion10 is TRUE */ + /* FIXME: ANSIfy the string when dwEmulatedVersion < 0x200 (richedit v1.0) */ if (!editor->pfnWordBreak) return ME_WordBreakProc(str->szData, start, str->nLen, code); else diff --git a/dlls/riched20/writer.c b/dlls/riched20/writer.c index ce9e853..8feb779 100644 --- a/dlls/riched20/writer.c +++ b/dlls/riched20/writer.c @@ -775,7 +775,7 @@ ME_StreamOutText(ME_TextEditor *editor, ME_OutStream *pStream, int nStart, int n if (item->member.run.nFlags & MERF_ENDPARA) { static const WCHAR szEOL[2] = { '\r', '\n' }; - if (!editor->bEmulateVersion10) { + if (editor->dwEmulatedVersion >= 0x200) { /* richedit 2.0 - all line breaks are \r\n */ if (dwFormat & SF_UNICODE) success = ME_StreamOutMove(pStream, (const char *)szEOL, sizeof(szEOL));