227#define NONAMELESSUNION
232#define NO_SHLWAPI_STREAM
245#define STACK_SIZE_DEFAULT 100
246#define STACK_SIZE_MAX 1000
248#define TEXT_LIMIT_DEFAULT 32767
255static const WCHAR REListBox20W[] = {
'R',
'E',
'L',
'i',
's',
't',
'B',
'o',
'x',
'2',
'0',
'W', 0};
256static const WCHAR REComboBox20W[] = {
'R',
'E',
'C',
'o',
'm',
'b',
'o',
'B',
'o',
'x',
'2',
'0',
'W', 0};
299 static const char bom_utf8[] = {0xEF, 0xBB, 0xBF};
310 if (
stream->editstream->dwError)
314 total_bytes_read +=
stream->dwSize;
342 while ((
buf[
end-1] & 0xC0) == 0x80)
350 if ((
buf[
end-1] & 0xE0) == 0xC0)
352 if ((
buf[
end-1] & 0xF0) == 0xE0)
354 if ((
buf[
end-1] & 0xF8) == 0xF0)
386 nWideChars =
stream->dwSize >> 1;
395 return total_bytes_read;
407 for (
i = 0;
i < 4;
i++)
411 colorNum = borderDef[
i].
color;
412 while (colorDef && colorDef->
rtfCNum != colorNum)
431 switch(
info->rtfMinor)
449 fmt.dwEffects =
info->rtfParam ?
fmt.dwMask : 0;
477 fmt.dwEffects =
info->rtfParam ?
fmt.dwMask : 0;
491 fmt.dwEffects =
info->rtfParam ?
fmt.dwMask : 0;
496 if (
info->rtfParam == 0)
501 if (
c &&
c->rtfCBlue >= 0)
502 fmt.crBackColor = (
c->rtfCBlue<<16)|(
c->rtfCGreen<<8)|(
c->rtfCRed);
510 if (
info->rtfParam == 0)
515 if (
c &&
c->rtfCBlue >= 0)
516 fmt.crTextColor = (
c->rtfCBlue<<16)|(
c->rtfCGreen<<8)|(
c->rtfCRed);
530 fmt.bCharSet =
f->rtfFCharSet;
532 fmt.bPitchAndFamily =
f->rtfFPitch | (
f->rtfFFamily << 4);
539 fmt.yHeight =
info->rtfParam*10;
548 info->style = style2;
557 switch(
info->rtfMinor)
560 if (!
info->editor->bEmulateVersion10)
570 info->fmt.cTabCount = 0;
571 info->fmt.dxOffset =
info->fmt.dxStartIndent =
info->fmt.dxRightIndent = 0;
572 info->fmt.wBorderWidth =
info->fmt.wBorders = 0;
573 info->fmt.wBorderSpace = 0;
574 info->fmt.bLineSpacingRule = 0;
575 info->fmt.dySpaceBefore =
info->fmt.dySpaceAfter = 0;
576 info->fmt.dyLineSpacing = 0;
577 info->fmt.wEffects &= ~PFE_RTLPARA;
578 info->fmt.wNumbering = 0;
579 info->fmt.wNumberingStart = 0;
580 info->fmt.wNumberingStyle = 0;
581 info->fmt.wNumberingTab = 0;
583 if (!
info->editor->bEmulateVersion10)
585 if (
info->tableDef &&
info->tableDef->tableRowStart &&
594 if (para ==
info->tableDef->tableRowStart->member.para.next_para
595 && !
cursor.nOffset && !
cursor.pRun->member.run.nCharOfs)
601 info->tableDef->tableRowStart =
NULL;
607 info->fmt.wEffects &= ~PFE_TABLE;
611 if (!
info->editor->bEmulateVersion10)
613 while (
info->rtfParam >
info->nestingLevel) {
614 RTFTable *tableDef = heap_alloc_zero(
sizeof(*tableDef));
616 info->tableDef = tableDef;
635 info->nestingLevel++;
642 if (!
info->editor->bEmulateVersion10)
644 if (
info->nestingLevel < 1)
648 info->tableDef = heap_alloc_zero(
sizeof(*
info->tableDef));
649 tableDef =
info->tableDef;
666 info->nestingLevel = 1;
684 info->fmt.dxStartIndent =
fmt.dxStartIndent;
685 info->fmt.dxOffset =
fmt.dxOffset;
689 info->fmt.dxStartIndent +=
info->fmt.dxOffset +
info->rtfParam;
690 info->fmt.dxOffset = -
info->rtfParam;
693 info->fmt.dxStartIndent =
info->rtfParam -
info->fmt.dxOffset;
697 info->fmt.dxRightIndent =
info->rtfParam;
719 fmt.cTabCount *
sizeof(
fmt.rgxTabs[0]));
720 info->fmt.cTabCount =
fmt.cTabCount;
724 info->fmt.rgxTabs[
info->fmt.cTabCount++] =
info->rtfParam;
740 info->fmt.dySpaceAfter =
info->rtfParam;
744 info->fmt.dySpaceBefore =
info->rtfParam;
748 if ((
int)
info->rtfParam > 0)
750 info->fmt.dyLineSpacing =
info->rtfParam;
751 info->fmt.bLineSpacingRule = 3;
755 info->fmt.dyLineSpacing =
info->rtfParam;
756 info->fmt.bLineSpacingRule = 4;
761 info->fmt.dyLineSpacing =
info->rtfParam * 20;
762 info->fmt.bLineSpacingRule = 5;
770 info->fmt.wNumbering = 2;
774 info->fmt.wBorders |= 1;
779 info->fmt.wBorders |= 2;
784 info->fmt.wBorders |= 4;
789 info->fmt.wBorders |= 8;
793 info->fmt.wBorders &= ~0x700;
794 info->fmt.wBorders |= 1 << 8;
798 info->fmt.wBorders &= ~0x700;
799 info->fmt.wBorders |= 2 << 8;
803 info->fmt.wBorders &= ~0x700;
804 info->fmt.wBorders |= 10 << 8;
808 info->fmt.wBorders &= ~0x700;
809 info->fmt.wBorders |= 7 << 8;
813 info->fmt.wBorders &= ~0x700;
814 info->fmt.wBorders |= 11 << 8;
830 info->fmt.wBorderWidth =
info->rtfParam;
835 info->fmt.wBorderSpace =
info->rtfParam;
846 if (!
info->editor->bEmulateVersion10)
868 info->fmt.wEffects &= ~PFE_RTLPARA;
875 switch (
info->rtfMinor)
879 if (!
info->editor->bEmulateVersion10)
880 info->borderType = 0;
883 if (!
info->tableDef) {
897 cellNum =
info->tableDef->numCellsDefined;
900 info->tableDef->cells[cellNum].rightBoundary =
info->rtfParam;
906 pFmt->
rgxTabs[cellNum] &= ~0x00FFFFFF;
907 pFmt->
rgxTabs[cellNum] |= 0x00FFFFFF &
info->rtfParam;
909 info->tableDef->numCellsDefined++;
938 info->tableDef->gapH =
info->rtfParam;
942 info->tableDef->leftEdge =
info->rtfParam;
950 switch (
info->rtfMinor)
953 if (
info->editor->bEmulateVersion10)
960 if (!
info->editor->bEmulateVersion10) {
963 if (!
info->nestingLevel &&
970 info->nestingLevel = 1;
987 if (
info->editor->bEmulateVersion10)
998 if (!
info->editor->bEmulateVersion10) {
1001 if (!
info->nestingLevel &&
1008 info->nestingLevel++;
1017 const int defaultCellSize = 2000;
1018 int nRightBoundary = defaultCellSize;
1022 nRightBoundary += defaultCellSize;
1047 if (
info->editor->pCursors[0].pRun != run ||
1048 info->editor->pCursors[0].nOffset)
1052 info->editor->pCursors[1].pRun = run;
1054 info->editor->pCursors[1].nOffset = 0;
1066 info->nestingLevel--;
1067 if (!
info->nestingLevel)
1069 if (
info->canInheritInTbl) {
1072 while (
info->tableDef) {
1073 tableDef =
info->tableDef;
1107 if (
info->editor->bEmulateVersion10) {
1111 para =
info->editor->pCursors[0].pPara;
1117 info->rtfMajor =
' ';
1119 else if (
info->rtfMinor ==
rtfPar && tableDef)
1131 LPOLECLIENTSITE lpClientSite =
NULL;
1133 LPOLECACHE lpOleCache =
NULL;
1134 LPRICHEDITOLE lpReOle =
NULL;
1143 stgm.tymed = TYMED_ENHMF;
1144 stgm.u.hEnhMetaFile = hemf;
1149 stgm.tymed = TYMED_GDI;
1150 stgm.u.hBitmap =
hbmp;
1153 stgm.pUnkForRelease =
NULL;
1156 fm.dwAspect = DVASPECT_CONTENT;
1158 fm.tymed = stgm.tymed;
1167 IUnknown_QueryInterface(editor->
reOle, &IID_IRichEditOle, (
void**)&lpReOle) ==
S_OK &&
1168 IRichEditOle_GetClientSite(lpReOle, &lpClientSite) ==
S_OK &&
1169 IOleObject_SetClientSite(lpObject, lpClientSite) ==
S_OK &&
1170 IOleObject_GetUserClassID(lpObject, &
clsid) ==
S_OK &&
1171 IOleObject_QueryInterface(lpObject, &
IID_IOleCache, (
void**)&lpOleCache) ==
S_OK &&
1172 IOleCache_Cache(lpOleCache, &fm, 0, &conn) ==
S_OK &&
1174 IDataObject_SetData(lpDataObject, &fm, &stgm,
TRUE) ==
S_OK)
1178 reobject.
cbStruct =
sizeof(reobject);
1179 reobject.
cp = REO_CP_SELECTION;
1182 reobject.
pstg = lpStorage;
1187 reobject.
dvaspect = DVASPECT_CONTENT;
1195 if (lpObject) IOleObject_Release(lpObject);
1196 if (lpClientSite) IOleClientSite_Release(lpClientSite);
1197 if (lpStorage) IStorage_Release(lpStorage);
1198 if (lpDataObject) IDataObject_Release(lpDataObject);
1199 if (lpOleCache) IOleCache_Release(lpOleCache);
1200 if (lpReOle) IRichEditOle_Release(lpReOle);
1216 if (--
level == 0)
break;
1244 ERR(
"Called with incorrect token\n");
1252 for (flip =
TRUE;; flip = !flip)
1274 if (flip)
FIXME(
"wrong hex string\n");
1288 enum gfxkind {gfx_unknown = 0, gfx_enhmetafile, gfx_metafile, gfx_dib} gfx = gfx_unknown;
1315 if (--
level == 0)
break;
1338 if (
info->rtfParam != 0)
FIXME(
"dibitmap should be 0 (%d)\n",
info->rtfParam);
1342 gfx = gfx_enhmetafile;
1352 FIXME(
"Non supported attribute: %d %d %d\n",
info->rtfClass,
info->rtfMajor,
info->rtfMinor);
1359 case gfx_enhmetafile:
1426 FIXME(
"Non supported attribute: %d %d %d\n",
info->rtfClass,
info->rtfMajor,
info->rtfMinor);
1437 WCHAR txt_before = 0, txt_after = 0;
1446 int loc =
info->rtfMinor;
1452 txt_before =
info->rtfMajor;
1454 txt_after =
info->rtfMajor;
1465 if (--
level == 0)
break;
1479 switch (
info->rtfMinor)
1521 if (txt_before == 0 && txt_after == 0)
1523 else if (txt_after ==
'.')
1525 else if (txt_before ==
'(' && txt_after ==
')')
1531 TRACE(
"type %d indent %d start %d txt before %04x txt after %04x\n",
1539 switch(
info->rtfClass)
1542 switch(
info->rtfMajor)
1549 info->stack[
info->stackTop].unicodeLength =
info->unicodeLength;
1558 if (
info->stackTop <= 0)
1560 if (
info->stackTop < 0)
1566 info->unicodeLength =
info->stack[
info->stackTop].unicodeLength;
1577 stream->editstream->dwError =
stream->editstream->pfnCallback(
stream->editstream->dwCookie,
1588 int from, to, nUndoMode;
1687 if (!
parser.editor->bEmulateVersion10)
1698 if (
parser.tableDef &&
parser.tableDef->tableRowStart &&
1710 if (
parser.nestingLevel > 0)
1712 while (
parser.nestingLevel > 1)
1714 para =
parser.tableDef->tableRowStart;
1717 para =
parser.tableDef->tableRowStart;
1738 while (--
parser.stackTop >= 0)
1756 WCHAR lastchar[3] = {
'\0',
'\0'};
1758 ME_Cursor linebreakCursor = *selEnd, lastcharCursor = *selEnd;
1762 cf.cbSize =
sizeof(
cf);
1772 if (lastchar[0] ==
'\r' && (lastchar[1] ==
'\n' || lastchar[1] ==
'\0')) {
1778 num_read = to -
from;
1788 ERR(
"EM_STREAMIN without SF_TEXT or SF_RTF\n");
1861 WCHAR wLastChar =
' ';
1863 TRACE(
"flags==0x%08x, chrg->cpMin==%d, chrg->cpMax==%d text==%s\n",
1867 FIXME(
"Flags 0x%08x not implemented\n",
1871 if (chrg->
cpMax == -1)
1874 nMax = chrg->
cpMax > nTextLen ? nTextLen : chrg->
cpMax;
1887 chrgText->
cpMin = -1;
1888 chrgText->
cpMax = -1;
1902 nMax = nMin > nTextLen ? nTextLen : nMin;
1903 if (nMin < nSwap || chrg->cpMax == -1)
1909 if (!nLen || nMin < 0 || nMax < 0 || nMax < nMin)
1931 int nCurStart =
cursor.nOffset;
1940 if (nMatched == nLen)
1943 int nNextStart = nCurStart;
1952 nNextStart = -nMatched;
1964 cursor.nOffset +=
cursor.pPara->member.para.nCharOfs +
cursor.pRun->member.run.nCharOfs;
1976 nCurStart = -nMatched;
2008 int nCurEnd =
cursor.nOffset;
2024 if (nMatched == nLen)
2027 int nPrevEnd = nCurEnd;
2034 if (nPrevEnd - nMatched == 0)
2054 chrgText->
cpMin = nStart;
2055 chrgText->
cpMax = nStart + nLen;
2057 TRACE(
"found at %d-%d\n", nStart, nStart + nLen);
2060 if (nCurEnd - nMatched == 0)
2081 TRACE(
"not found\n");
2092 if (!
ex->cb || !
pText)
return 0;
2126 buflen =
min(crlfmul * nChars,
ex->cb - 1);
2142 if (!strText)
return 0;
2185 pDest = (
WORD *)lpBuff;
2187 for (
i = 0;
i<
cb && pSrc[
pData->nLength+
i];
i++) {
2188 pDest[
i] = pSrc[
pData->nLength+
i];
2204 for (
i = 0;
i<
cb && pSrc[
pData->nLength+
i];
i++) {
2205 pDest[
i] = pSrc[
pData->nLength+
i];
2213static const WCHAR rtfW[] = {
'R',
'i',
'c',
'h',
' ',
'T',
'e',
'x',
't',
' ',
'F',
'o',
'r',
'm',
'a',
't',0};
2221 gds.
hData = med->u.hGlobal;
2236 gds.
hData = med->u.hGlobal;
2308 if (ps && ps->
dwAspect != DVASPECT_CONTENT)
2319 if (
cf &&
cf !=
format->fmt.cfFormat)
continue;
2326 if (
hr !=
S_OK)
goto done;
2334 IDataObject_Release(
data );
2352 hr = IRichEditOleCallback_GetClipboardData(editor->
lpOleCallback, &
range, RECO_COPY, &dataObj);
2358 IDataObject_Release(dataObj);
2366 int offs, num_chars;
2422 startPara =
from->pPara;
2429 start.pPara = startPara;
2470 static const WCHAR endlv10[] = {
'\r',
'\n'};
2502 cursor.nOffset +
cursor.pRun->member.run.nCharOfs == 0 &&
2551 if (
cursor.pRun->member.run.nCharOfs +
cursor.nOffset == 0 &&
2636 ME_ArrowKey(editor, nKey, shift_is_down, ctrl_is_down);
2658 BOOL bDeletionSucceeded;
2729 chf.
cbSize =
sizeof(chf);
2759 wstr = (
WCHAR)charCode;
2762 CHAR charA = charCode;
2769 if ((
unsigned)wstr >=
' ' || wstr ==
'\t')
2785 cursor.pRun->member.run.nCharOfs +
cursor.nOffset == 0 &&
2790 bSelectedRow =
TRUE;
2844 static int clickNum = 0;
2851 (
msg == WM_XBUTTONDBLCLK))
2859 (
msg == WM_XBUTTONDOWN))
2861 static MSG prevClickMsg;
2865 clickMsg.hwnd = (
HWND)editor;
2866 clickMsg.message =
msg;
2867 clickMsg.wParam =
wParam;
2868 clickMsg.lParam =
lParam;
2872 if ((clickNum != 0) &&
2873 (clickMsg.message == prevClickMsg.message) &&
2874 (clickMsg.hwnd == prevClickMsg.hwnd) &&
2875 (clickMsg.wParam == prevClickMsg.wParam) &&
2884 prevClickMsg = clickMsg;
2908 sbi.
cbSize =
sizeof(sbi);
2917 sbi.
cbSize =
sizeof(sbi);
2960 run = &
cursor.pRun->member.run;
2971 int selStart, selEnd;
2975 if (selStart <= offset && selEnd >=
offset) {
3014 if (
cursor.pRun->member.run.reobj)
3021 if (character_count)
3024 if (character_count >= 2)
3224 ITextHost_Release(editor->
texthost);
3227 IUnknown_Release(editor->
reOle);
3282 *remain -=
WHEEL_DELTA * change / amount_per_click;
3315 "EM_SETPASSWORDCHAR",
3316 "EM_EMPTYUNDOBUFFER",
3317 "EM_GETFIRSTVISIBLELINE",
3319 "EM_SETWORDBREAKPROC",
3320 "EM_GETWORDBREAKPROC",
3321 "EM_GETPASSWORDCHAR",
3336 "EM_EXLINEFROMCHAR",
3342 "EM_GETOLEINTERFACE",
3352 "EM_SETOLECALLBACK",
3354 "EM_SETTARGETDEVICE",
3362 "EM_GETWORDBREAKPROCEX",
3363 "EM_SETWORDBREAKPROCEX",
3365 "EM_UNKNOWN_USER_83",
3370 "EM_STOPGROUPTYPING",
3374 "EM_GETAUTOURLDETECT",
3377 "EM_GETTEXTLENGTHEX",
3380 "EM_UNKNOWN_USER_98",
3381 "EM_UNKNOWN_USER_99",
3382 "EM_SETPUNCTUATION",
3383 "EM_GETPUNCTUATION",
3384 "EM_SETWORDWRAPMODE",
3385 "EM_GETWORDWRAPMODE",
3391 "EM_UNKNOWN_USER_109",
3392 "EM_UNKNOWN_USER_110",
3393 "EM_UNKNOWN_USER_111",
3394 "EM_UNKNOWN_USER_112",
3395 "EM_UNKNOWN_USER_113",
3396 "EM_UNKNOWN_USER_114",
3397 "EM_UNKNOWN_USER_115",
3398 "EM_UNKNOWN_USER_116",
3399 "EM_UNKNOWN_USER_117",
3400 "EM_UNKNOWN_USER_118",
3401 "EM_UNKNOWN_USER_119",
3402 "EM_SETLANGOPTIONS",
3403 "EM_GETLANGOPTIONS",
3404 "EM_GETIMECOMPMODE",
3408 "EM_SETIMEMODEBIAS",
3432 if (!isExact)
return;
3439 info.nmhdr.idFrom = 0;
3464 int from, to, nStartCursor;
3592#define UNSUPPORTED_MSG(e) \
3594 FIXME(#e ": stub\n"); \
3595 *phresult = S_FALSE; \
3661 if ((*pfrom|*pto) & 0xFFFF0000)
3710 cf.cbSize =
sizeof(
cf);
3713 tmp_size = (
cf.yHeight / 20) +
wParam;
3717 else if (tmp_size > 12 && tmp_size < 28 && tmp_size % 2)
3718 size = tmp_size + (is_increase ? 1 : -1);
3719 else if (tmp_size > 28 && tmp_size < 36)
3720 size = is_increase ? 36 : 28;
3721 else if (tmp_size > 36 && tmp_size < 48)
3722 size = is_increase ? 48 : 36;
3723 else if (tmp_size > 48 && tmp_size < 72)
3724 size = is_increase ? 72 : 48;
3725 else if (tmp_size > 72 && tmp_size < 80)
3726 size = is_increase ? 80 : 72;
3727 else if (tmp_size > 80 && tmp_size < 1638)
3728 size = 10 * (is_increase ? (tmp_size / 10 + 1) : (tmp_size / 10));
3729 else if (tmp_size >= 1638)
3752 DWORD changedSettings;
3768 changedSettings = oldSettings ^
settings;
3770 if (changedSettings) {
3791 FIXME(
"ECO_VERTICAL not implemented yet!\n");
3793 FIXME(
"ECO_AUTOHSCROLL not implemented yet!\n");
3795 FIXME(
"ECO_AUTOVSCROLL not implemented yet!\n");
3797 FIXME(
"ECO_WANTRETURN not implemented yet!\n");
3799 FIXME(
"ECO_AUTOWORDSELECTION not implemented yet!\n");
3872 BOOL bRtf, bUnicode, bSelection, bUTF8;
3874 static const char utf8_bom[] = {0xef, 0xbb, 0xbf};
3876 if (!pStruct)
return 0;
3885 TRACE(
"EM_SETTEXTEX - %s, flags %d, cp %d\n",
3909 if (bUTF8 && !bUnicode) {
4000 tmp.
cbSize =
sizeof(tmp);
4031 ypara =
p->member.para.pt.y;
4034 ystart = ypara +
p->member.row.pt.y;
4035 yend = ystart +
p->member.row.nHeight;