227#define NONAMELESSUNION
232#define NO_SHLWAPI_STREAM
246#define STACK_SIZE_DEFAULT 100
247#define STACK_SIZE_MAX 1000
249#define TEXT_LIMIT_DEFAULT 32767
256static const WCHAR REListBox20W[] = {
'R',
'E',
'L',
'i',
's',
't',
'B',
'o',
'x',
'2',
'0',
'W', 0};
257static const WCHAR REComboBox20W[] = {
'R',
'E',
'C',
'o',
'm',
'b',
'o',
'B',
'o',
'x',
'2',
'0',
'W', 0};
300 static const char bom_utf8[] = {0xEF, 0xBB, 0xBF};
311 if (
stream->editstream->dwError)
315 total_bytes_read +=
stream->dwSize;
343 while ((
buf[
end-1] & 0xC0) == 0x80)
351 if ((
buf[
end-1] & 0xE0) == 0xC0)
353 if ((
buf[
end-1] & 0xF0) == 0xE0)
355 if ((
buf[
end-1] & 0xF8) == 0xF0)
387 nWideChars =
stream->dwSize >> 1;
396 return total_bytes_read;
408 for (
i = 0;
i < 4;
i++)
412 colorNum = borderDef[
i].
color;
413 while (colorDef && colorDef->
rtfCNum != colorNum)
432 switch(
info->rtfMinor)
450 fmt.dwEffects =
info->rtfParam ?
fmt.dwMask : 0;
478 fmt.dwEffects =
info->rtfParam ?
fmt.dwMask : 0;
492 fmt.dwEffects =
info->rtfParam ?
fmt.dwMask : 0;
497 if (
info->rtfParam == 0)
502 if (
c &&
c->rtfCBlue >= 0)
503 fmt.crBackColor = (
c->rtfCBlue<<16)|(
c->rtfCGreen<<8)|(
c->rtfCRed);
511 if (
info->rtfParam == 0)
516 if (
c &&
c->rtfCBlue >= 0)
517 fmt.crTextColor = (
c->rtfCBlue<<16)|(
c->rtfCGreen<<8)|(
c->rtfCRed);
531 fmt.bCharSet =
f->rtfFCharSet;
533 fmt.bPitchAndFamily =
f->rtfFPitch | (
f->rtfFFamily << 4);
540 fmt.yHeight =
info->rtfParam*10;
549 info->style = style2;
558 switch(
info->rtfMinor)
561 if (!
info->editor->bEmulateVersion10)
571 info->fmt.cTabCount = 0;
572 info->fmt.dxOffset =
info->fmt.dxStartIndent =
info->fmt.dxRightIndent = 0;
573 info->fmt.wBorderWidth =
info->fmt.wBorders = 0;
574 info->fmt.wBorderSpace = 0;
575 info->fmt.bLineSpacingRule = 0;
576 info->fmt.dySpaceBefore =
info->fmt.dySpaceAfter = 0;
577 info->fmt.dyLineSpacing = 0;
578 info->fmt.wEffects &= ~PFE_RTLPARA;
579 info->fmt.wNumbering = 0;
580 info->fmt.wNumberingStart = 0;
581 info->fmt.wNumberingStyle = 0;
582 info->fmt.wNumberingTab = 0;
584 if (!
info->editor->bEmulateVersion10)
586 if (
info->tableDef &&
info->tableDef->tableRowStart &&
595 if (para ==
info->tableDef->tableRowStart->member.para.next_para
596 && !
cursor.nOffset && !
cursor.pRun->member.run.nCharOfs)
602 info->tableDef->tableRowStart =
NULL;
608 info->fmt.wEffects &= ~PFE_TABLE;
612 if (!
info->editor->bEmulateVersion10)
614 while (
info->rtfParam >
info->nestingLevel) {
615 RTFTable *tableDef = heap_alloc_zero(
sizeof(*tableDef));
617 info->tableDef = tableDef;
636 info->nestingLevel++;
643 if (!
info->editor->bEmulateVersion10)
645 if (
info->nestingLevel < 1)
649 info->tableDef = heap_alloc_zero(
sizeof(*
info->tableDef));
650 tableDef =
info->tableDef;
667 info->nestingLevel = 1;
685 info->fmt.dxStartIndent =
fmt.dxStartIndent;
686 info->fmt.dxOffset =
fmt.dxOffset;
690 info->fmt.dxStartIndent +=
info->fmt.dxOffset +
info->rtfParam;
691 info->fmt.dxOffset = -
info->rtfParam;
694 info->fmt.dxStartIndent =
info->rtfParam -
info->fmt.dxOffset;
698 info->fmt.dxRightIndent =
info->rtfParam;
720 fmt.cTabCount *
sizeof(
fmt.rgxTabs[0]));
721 info->fmt.cTabCount =
fmt.cTabCount;
725 info->fmt.rgxTabs[
info->fmt.cTabCount++] =
info->rtfParam;
741 info->fmt.dySpaceAfter =
info->rtfParam;
745 info->fmt.dySpaceBefore =
info->rtfParam;
749 if ((
int)
info->rtfParam > 0)
751 info->fmt.dyLineSpacing =
info->rtfParam;
752 info->fmt.bLineSpacingRule = 3;
756 info->fmt.dyLineSpacing =
info->rtfParam;
757 info->fmt.bLineSpacingRule = 4;
762 info->fmt.dyLineSpacing =
info->rtfParam * 20;
763 info->fmt.bLineSpacingRule = 5;
771 info->fmt.wNumbering = 2;
775 info->fmt.wBorders |= 1;
780 info->fmt.wBorders |= 2;
785 info->fmt.wBorders |= 4;
790 info->fmt.wBorders |= 8;
794 info->fmt.wBorders &= ~0x700;
795 info->fmt.wBorders |= 1 << 8;
799 info->fmt.wBorders &= ~0x700;
800 info->fmt.wBorders |= 2 << 8;
804 info->fmt.wBorders &= ~0x700;
805 info->fmt.wBorders |= 10 << 8;
809 info->fmt.wBorders &= ~0x700;
810 info->fmt.wBorders |= 7 << 8;
814 info->fmt.wBorders &= ~0x700;
815 info->fmt.wBorders |= 11 << 8;
831 info->fmt.wBorderWidth =
info->rtfParam;
836 info->fmt.wBorderSpace =
info->rtfParam;
847 if (!
info->editor->bEmulateVersion10)
869 info->fmt.wEffects &= ~PFE_RTLPARA;
876 switch (
info->rtfMinor)
880 if (!
info->editor->bEmulateVersion10)
881 info->borderType = 0;
884 if (!
info->tableDef) {
898 cellNum =
info->tableDef->numCellsDefined;
901 info->tableDef->cells[cellNum].rightBoundary =
info->rtfParam;
907 pFmt->
rgxTabs[cellNum] &= ~0x00FFFFFF;
908 pFmt->
rgxTabs[cellNum] |= 0x00FFFFFF &
info->rtfParam;
910 info->tableDef->numCellsDefined++;
939 info->tableDef->gapH =
info->rtfParam;
943 info->tableDef->leftEdge =
info->rtfParam;
951 switch (
info->rtfMinor)
954 if (
info->editor->bEmulateVersion10)
961 if (!
info->editor->bEmulateVersion10) {
964 if (!
info->nestingLevel &&
971 info->nestingLevel = 1;
988 if (
info->editor->bEmulateVersion10)
999 if (!
info->editor->bEmulateVersion10) {
1002 if (!
info->nestingLevel &&
1009 info->nestingLevel++;
1018 const int defaultCellSize = 2000;
1019 int nRightBoundary = defaultCellSize;
1023 nRightBoundary += defaultCellSize;
1048 if (
info->editor->pCursors[0].pRun != run ||
1049 info->editor->pCursors[0].nOffset)
1053 info->editor->pCursors[1].pRun = run;
1055 info->editor->pCursors[1].nOffset = 0;
1067 info->nestingLevel--;
1068 if (!
info->nestingLevel)
1070 if (
info->canInheritInTbl) {
1073 while (
info->tableDef) {
1074 tableDef =
info->tableDef;
1108 if (
info->editor->bEmulateVersion10) {
1112 para =
info->editor->pCursors[0].pPara;
1118 info->rtfMajor =
' ';
1120 else if (
info->rtfMinor ==
rtfPar && tableDef)
1132 LPOLECLIENTSITE lpClientSite =
NULL;
1134 LPOLECACHE lpOleCache =
NULL;
1135 LPRICHEDITOLE lpReOle =
NULL;
1144 stgm.tymed = TYMED_ENHMF;
1145 stgm.u.hEnhMetaFile = hemf;
1150 stgm.tymed = TYMED_GDI;
1151 stgm.u.hBitmap =
hbmp;
1154 stgm.pUnkForRelease =
NULL;
1157 fm.dwAspect = DVASPECT_CONTENT;
1159 fm.tymed = stgm.tymed;
1168 IUnknown_QueryInterface(editor->
reOle, &IID_IRichEditOle, (
void**)&lpReOle) ==
S_OK &&
1169 IRichEditOle_GetClientSite(lpReOle, &lpClientSite) ==
S_OK &&
1170 IOleObject_SetClientSite(lpObject, lpClientSite) ==
S_OK &&
1171 IOleObject_GetUserClassID(lpObject, &
clsid) ==
S_OK &&
1172 IOleObject_QueryInterface(lpObject, &
IID_IOleCache, (
void**)&lpOleCache) ==
S_OK &&
1173 IOleCache_Cache(lpOleCache, &fm, 0, &conn) ==
S_OK &&
1175 IDataObject_SetData(lpDataObject, &fm, &stgm,
TRUE) ==
S_OK)
1179 reobject.
cbStruct =
sizeof(reobject);
1180 reobject.
cp = REO_CP_SELECTION;
1183 reobject.
pstg = lpStorage;
1188 reobject.
dvaspect = DVASPECT_CONTENT;
1196 if (lpObject) IOleObject_Release(lpObject);
1197 if (lpClientSite) IOleClientSite_Release(lpClientSite);
1198 if (lpStorage) IStorage_Release(lpStorage);
1199 if (lpDataObject) IDataObject_Release(lpDataObject);
1200 if (lpOleCache) IOleCache_Release(lpOleCache);
1201 if (lpReOle) IRichEditOle_Release(lpReOle);
1217 if (--
level == 0)
break;
1245 ERR(
"Called with incorrect token\n");
1253 for (flip =
TRUE;; flip = !flip)
1275 if (flip)
FIXME(
"wrong hex string\n");
1289 enum gfxkind {gfx_unknown = 0, gfx_enhmetafile, gfx_metafile, gfx_dib} gfx = gfx_unknown;
1316 if (--
level == 0)
break;
1339 if (
info->rtfParam != 0)
FIXME(
"dibitmap should be 0 (%d)\n",
info->rtfParam);
1343 gfx = gfx_enhmetafile;
1353 FIXME(
"Non supported attribute: %d %d %d\n",
info->rtfClass,
info->rtfMajor,
info->rtfMinor);
1360 case gfx_enhmetafile:
1427 FIXME(
"Non supported attribute: %d %d %d\n",
info->rtfClass,
info->rtfMajor,
info->rtfMinor);
1438 WCHAR txt_before = 0, txt_after = 0;
1447 int loc =
info->rtfMinor;
1453 txt_before =
info->rtfMajor;
1455 txt_after =
info->rtfMajor;
1466 if (--
level == 0)
break;
1480 switch (
info->rtfMinor)
1522 if (txt_before == 0 && txt_after == 0)
1524 else if (txt_after ==
'.')
1526 else if (txt_before ==
'(' && txt_after ==
')')
1532 TRACE(
"type %d indent %d start %d txt before %04x txt after %04x\n",
1540 switch(
info->rtfClass)
1543 switch(
info->rtfMajor)
1550 info->stack[
info->stackTop].unicodeLength =
info->unicodeLength;
1559 if (
info->stackTop <= 0)
1561 if (
info->stackTop < 0)
1567 info->unicodeLength =
info->stack[
info->stackTop].unicodeLength;
1578 stream->editstream->dwError =
stream->editstream->pfnCallback(
stream->editstream->dwCookie,
1589 int from, to, nUndoMode;
1688 if (!
parser.editor->bEmulateVersion10)
1699 if (
parser.tableDef &&
parser.tableDef->tableRowStart &&
1711 if (
parser.nestingLevel > 0)
1713 while (
parser.nestingLevel > 1)
1715 para =
parser.tableDef->tableRowStart;
1718 para =
parser.tableDef->tableRowStart;
1739 while (--
parser.stackTop >= 0)
1757 WCHAR lastchar[3] = {
'\0',
'\0'};
1759 ME_Cursor linebreakCursor = *selEnd, lastcharCursor = *selEnd;
1763 cf.cbSize =
sizeof(
cf);
1773 if (lastchar[0] ==
'\r' && (lastchar[1] ==
'\n' || lastchar[1] ==
'\0')) {
1779 num_read = to -
from;
1789 ERR(
"EM_STREAMIN without SF_TEXT or SF_RTF\n");
1862 WCHAR wLastChar =
' ';
1864 TRACE(
"flags==0x%08x, chrg->cpMin==%d, chrg->cpMax==%d text==%s\n",
1868 FIXME(
"Flags 0x%08x not implemented\n",
1872 if (chrg->
cpMax == -1)
1875 nMax = chrg->
cpMax > nTextLen ? nTextLen : chrg->
cpMax;
1888 chrgText->
cpMin = -1;
1889 chrgText->
cpMax = -1;
1903 nMax = nMin > nTextLen ? nTextLen : nMin;
1904 if (nMin < nSwap || chrg->cpMax == -1)
1910 if (!nLen || nMin < 0 || nMax < 0 || nMax < nMin)
1932 int nCurStart =
cursor.nOffset;
1941 if (nMatched == nLen)
1944 int nNextStart = nCurStart;
1953 nNextStart = -nMatched;
1965 cursor.nOffset +=
cursor.pPara->member.para.nCharOfs +
cursor.pRun->member.run.nCharOfs;
1977 nCurStart = -nMatched;
2009 int nCurEnd =
cursor.nOffset;
2025 if (nMatched == nLen)
2028 int nPrevEnd = nCurEnd;
2035 if (nPrevEnd - nMatched == 0)
2055 chrgText->
cpMin = nStart;
2056 chrgText->
cpMax = nStart + nLen;
2058 TRACE(
"found at %d-%d\n", nStart, nStart + nLen);
2061 if (nCurEnd - nMatched == 0)
2082 TRACE(
"not found\n");
2093 if (!
ex->cb || !
pText)
return 0;
2127 buflen =
min(crlfmul * nChars,
ex->cb - 1);
2143 if (!strText)
return 0;
2186 pDest = (
WORD *)lpBuff;
2188 for (
i = 0;
i<
cb && pSrc[
pData->nLength+
i];
i++) {
2189 pDest[
i] = pSrc[
pData->nLength+
i];
2205 for (
i = 0;
i<
cb && pSrc[
pData->nLength+
i];
i++) {
2206 pDest[
i] = pSrc[
pData->nLength+
i];
2214static const WCHAR rtfW[] = {
'R',
'i',
'c',
'h',
' ',
'T',
'e',
'x',
't',
' ',
'F',
'o',
'r',
'm',
'a',
't',0};
2222 gds.
hData = med->u.hGlobal;
2237 gds.
hData = med->u.hGlobal;
2309 if (ps && ps->
dwAspect != DVASPECT_CONTENT)
2320 if (
cf &&
cf !=
format->fmt.cfFormat)
continue;
2327 if (
hr !=
S_OK)
goto done;
2335 IDataObject_Release(
data );
2353 hr = IRichEditOleCallback_GetClipboardData(editor->
lpOleCallback, &
range, RECO_COPY, &dataObj);
2359 IDataObject_Release(dataObj);
2367 int offs, num_chars;
2423 startPara =
from->pPara;
2430 start.pPara = startPara;
2471 static const WCHAR endlv10[] = {
'\r',
'\n'};
2503 cursor.nOffset +
cursor.pRun->member.run.nCharOfs == 0 &&
2552 if (
cursor.pRun->member.run.nCharOfs +
cursor.nOffset == 0 &&
2637 ME_ArrowKey(editor, nKey, shift_is_down, ctrl_is_down);
2659 BOOL bDeletionSucceeded;
2730 chf.
cbSize =
sizeof(chf);
2760 wstr = (
WCHAR)charCode;
2763 CHAR charA = charCode;
2770 if ((
unsigned)wstr >=
' ' || wstr ==
'\t')
2786 cursor.pRun->member.run.nCharOfs +
cursor.nOffset == 0 &&
2791 bSelectedRow =
TRUE;
2845 static int clickNum = 0;
2852 (
msg == WM_XBUTTONDBLCLK))
2860 (
msg == WM_XBUTTONDOWN))
2862 static MSG prevClickMsg;
2866 clickMsg.hwnd = (
HWND)editor;
2867 clickMsg.message =
msg;
2868 clickMsg.wParam =
wParam;
2869 clickMsg.lParam =
lParam;
2873 if ((clickNum != 0) &&
2874 (clickMsg.message == prevClickMsg.message) &&
2875 (clickMsg.hwnd == prevClickMsg.hwnd) &&
2876 (clickMsg.wParam == prevClickMsg.wParam) &&
2885 prevClickMsg = clickMsg;
2909 sbi.
cbSize =
sizeof(sbi);
2918 sbi.
cbSize =
sizeof(sbi);
2961 run = &
cursor.pRun->member.run;
2972 int selStart, selEnd;
2976 if (selStart <= offset && selEnd >=
offset) {
3015 if (
cursor.pRun->member.run.reobj)
3022 if (character_count)
3025 if (character_count >= 2)
3225 ITextHost_Release(editor->
texthost);
3228 IUnknown_Release(editor->
reOle);
3283 *remain -=
WHEEL_DELTA * change / amount_per_click;
3316 "EM_SETPASSWORDCHAR",
3317 "EM_EMPTYUNDOBUFFER",
3318 "EM_GETFIRSTVISIBLELINE",
3320 "EM_SETWORDBREAKPROC",
3321 "EM_GETWORDBREAKPROC",
3322 "EM_GETPASSWORDCHAR",
3337 "EM_EXLINEFROMCHAR",
3343 "EM_GETOLEINTERFACE",
3353 "EM_SETOLECALLBACK",
3355 "EM_SETTARGETDEVICE",
3363 "EM_GETWORDBREAKPROCEX",
3364 "EM_SETWORDBREAKPROCEX",
3366 "EM_UNKNOWN_USER_83",
3371 "EM_STOPGROUPTYPING",
3375 "EM_GETAUTOURLDETECT",
3378 "EM_GETTEXTLENGTHEX",
3381 "EM_UNKNOWN_USER_98",
3382 "EM_UNKNOWN_USER_99",
3383 "EM_SETPUNCTUATION",
3384 "EM_GETPUNCTUATION",
3385 "EM_SETWORDWRAPMODE",
3386 "EM_GETWORDWRAPMODE",
3392 "EM_UNKNOWN_USER_109",
3393 "EM_UNKNOWN_USER_110",
3394 "EM_UNKNOWN_USER_111",
3395 "EM_UNKNOWN_USER_112",
3396 "EM_UNKNOWN_USER_113",
3397 "EM_UNKNOWN_USER_114",
3398 "EM_UNKNOWN_USER_115",
3399 "EM_UNKNOWN_USER_116",
3400 "EM_UNKNOWN_USER_117",
3401 "EM_UNKNOWN_USER_118",
3402 "EM_UNKNOWN_USER_119",
3403 "EM_SETLANGOPTIONS",
3404 "EM_GETLANGOPTIONS",
3405 "EM_GETIMECOMPMODE",
3409 "EM_SETIMEMODEBIAS",
3433 if (!isExact)
return;
3440 info.nmhdr.idFrom = 0;
3465 int from, to, nStartCursor;
3593#define UNSUPPORTED_MSG(e) \
3595 FIXME(#e ": stub\n"); \
3596 *phresult = S_FALSE; \
3662 if ((*pfrom|*pto) & 0xFFFF0000)
3711 cf.cbSize =
sizeof(
cf);
3714 tmp_size = (
cf.yHeight / 20) +
wParam;
3718 else if (tmp_size > 12 && tmp_size < 28 && tmp_size % 2)
3719 size = tmp_size + (is_increase ? 1 : -1);
3720 else if (tmp_size > 28 && tmp_size < 36)
3721 size = is_increase ? 36 : 28;
3722 else if (tmp_size > 36 && tmp_size < 48)
3723 size = is_increase ? 48 : 36;
3724 else if (tmp_size > 48 && tmp_size < 72)
3725 size = is_increase ? 72 : 48;
3726 else if (tmp_size > 72 && tmp_size < 80)
3727 size = is_increase ? 80 : 72;
3728 else if (tmp_size > 80 && tmp_size < 1638)
3729 size = 10 * (is_increase ? (tmp_size / 10 + 1) : (tmp_size / 10));
3730 else if (tmp_size >= 1638)
3753 DWORD changedSettings;
3769 changedSettings = oldSettings ^
settings;
3771 if (changedSettings) {
3792 FIXME(
"ECO_VERTICAL not implemented yet!\n");
3794 FIXME(
"ECO_AUTOHSCROLL not implemented yet!\n");
3796 FIXME(
"ECO_AUTOVSCROLL not implemented yet!\n");
3798 FIXME(
"ECO_WANTRETURN not implemented yet!\n");
3800 FIXME(
"ECO_AUTOWORDSELECTION not implemented yet!\n");
3873 BOOL bRtf, bUnicode, bSelection, bUTF8;
3875 static const char utf8_bom[] = {0xef, 0xbb, 0xbf};
3877 if (!pStruct)
return 0;
3886 TRACE(
"EM_SETTEXTEX - %s, flags %d, cp %d\n",
3910 if (bUTF8 && !bUnicode) {
4001 tmp.
cbSize =
sizeof(tmp);
4032 ypara =
p->member.para.pt.y;
4035 ystart = ypara +
p->member.row.pt.y;
4036 yend = ystart +
p->member.row.nHeight;