227 #define NONAMELESSUNION 232 #define NO_SHLWAPI_STREAM 242 #define STACK_SIZE_DEFAULT 100 243 #define STACK_SIZE_MAX 1000 245 #define TEXT_LIMIT_DEFAULT 32767 252 static const WCHAR REListBox20W[] = {
'R',
'E',
'L',
'i',
's',
't',
'B',
'o',
'x',
'2',
'0',
'W', 0};
253 static const WCHAR REComboBox20W[] = {
'R',
'E',
'C',
'o',
'm',
'b',
'o',
'B',
'o',
'x',
'2',
'0',
'W', 0};
296 static const char bom_utf8[] = {0xEF, 0xBB, 0xBF};
307 if (
stream->editstream->dwError)
311 total_bytes_read +=
stream->dwSize;
339 while ((
buf[
end-1] & 0xC0) == 0x80)
347 if ((
buf[
end-1] & 0xE0) == 0xC0)
349 if ((
buf[
end-1] & 0xF0) == 0xE0)
351 if ((
buf[
end-1] & 0xF8) == 0xF0)
383 nWideChars =
stream->dwSize >> 1;
392 return total_bytes_read;
404 for (
i = 0;
i < 4;
i++)
408 colorNum = borderDef[
i].
color;
409 while (colorDef && colorDef->
rtfCNum != colorNum)
428 switch(
info->rtfMinor)
446 fmt.dwEffects =
info->rtfParam ?
fmt.dwMask : 0;
474 fmt.dwEffects =
info->rtfParam ?
fmt.dwMask : 0;
488 fmt.dwEffects =
info->rtfParam ?
fmt.dwMask : 0;
493 if (
info->rtfParam == 0)
498 if (
c &&
c->rtfCBlue >= 0)
499 fmt.crBackColor = (
c->rtfCBlue<<16)|(
c->rtfCGreen<<8)|(
c->rtfCRed);
507 if (
info->rtfParam == 0)
512 if (
c &&
c->rtfCBlue >= 0)
513 fmt.crTextColor = (
c->rtfCBlue<<16)|(
c->rtfCGreen<<8)|(
c->rtfCRed);
527 fmt.bCharSet =
f->rtfFCharSet;
529 fmt.bPitchAndFamily =
f->rtfFPitch | (
f->rtfFFamily << 4);
536 fmt.yHeight =
info->rtfParam*10;
545 info->style = style2;
554 switch(
info->rtfMinor)
557 if (!
info->editor->bEmulateVersion10)
567 info->fmt.cTabCount = 0;
568 info->fmt.dxOffset =
info->fmt.dxStartIndent =
info->fmt.dxRightIndent = 0;
569 info->fmt.wBorderWidth =
info->fmt.wBorders = 0;
570 info->fmt.wBorderSpace = 0;
571 info->fmt.bLineSpacingRule = 0;
572 info->fmt.dySpaceBefore =
info->fmt.dySpaceAfter = 0;
573 info->fmt.dyLineSpacing = 0;
575 info->fmt.wNumbering = 0;
576 info->fmt.wNumberingStart = 0;
577 info->fmt.wNumberingStyle = 0;
578 info->fmt.wNumberingTab = 0;
580 if (!
info->editor->bEmulateVersion10)
582 if (
info->tableDef &&
info->tableDef->tableRowStart &&
591 if (para ==
info->tableDef->tableRowStart->member.para.next_para
592 && !
cursor.nOffset && !
cursor.pRun->member.run.nCharOfs)
598 info->tableDef->tableRowStart =
NULL;
608 if (!
info->editor->bEmulateVersion10)
610 while (
info->rtfParam >
info->nestingLevel) {
611 RTFTable *tableDef = heap_alloc_zero(
sizeof(*tableDef));
613 info->tableDef = tableDef;
632 info->nestingLevel++;
639 if (!
info->editor->bEmulateVersion10)
641 if (
info->nestingLevel < 1)
645 info->tableDef = heap_alloc_zero(
sizeof(*
info->tableDef));
646 tableDef =
info->tableDef;
663 info->nestingLevel = 1;
681 info->fmt.dxStartIndent =
fmt.dxStartIndent;
682 info->fmt.dxOffset =
fmt.dxOffset;
686 info->fmt.dxStartIndent +=
info->fmt.dxOffset +
info->rtfParam;
687 info->fmt.dxOffset = -
info->rtfParam;
690 info->fmt.dxStartIndent =
info->rtfParam -
info->fmt.dxOffset;
694 info->fmt.dxRightIndent =
info->rtfParam;
716 fmt.cTabCount *
sizeof(
fmt.rgxTabs[0]));
717 info->fmt.cTabCount =
fmt.cTabCount;
721 info->fmt.rgxTabs[
info->fmt.cTabCount++] =
info->rtfParam;
737 info->fmt.dySpaceAfter =
info->rtfParam;
741 info->fmt.dySpaceBefore =
info->rtfParam;
745 if ((
int)
info->rtfParam > 0)
747 info->fmt.dyLineSpacing =
info->rtfParam;
748 info->fmt.bLineSpacingRule = 3;
752 info->fmt.dyLineSpacing =
info->rtfParam;
753 info->fmt.bLineSpacingRule = 4;
758 info->fmt.dyLineSpacing =
info->rtfParam * 20;
759 info->fmt.bLineSpacingRule = 5;
767 info->fmt.wNumbering = 2;
771 info->fmt.wBorders |= 1;
776 info->fmt.wBorders |= 2;
781 info->fmt.wBorders |= 4;
786 info->fmt.wBorders |= 8;
790 info->fmt.wBorders &= ~0x700;
791 info->fmt.wBorders |= 1 << 8;
795 info->fmt.wBorders &= ~0x700;
796 info->fmt.wBorders |= 2 << 8;
800 info->fmt.wBorders &= ~0x700;
801 info->fmt.wBorders |= 10 << 8;
805 info->fmt.wBorders &= ~0x700;
806 info->fmt.wBorders |= 7 << 8;
810 info->fmt.wBorders &= ~0x700;
811 info->fmt.wBorders |= 11 << 8;
827 info->fmt.wBorderWidth =
info->rtfParam;
832 info->fmt.wBorderSpace =
info->rtfParam;
843 if (!
info->editor->bEmulateVersion10)
872 switch (
info->rtfMinor)
876 if (!
info->editor->bEmulateVersion10)
877 info->borderType = 0;
880 if (!
info->tableDef) {
894 cellNum =
info->tableDef->numCellsDefined;
897 info->tableDef->cells[cellNum].rightBoundary =
info->rtfParam;
903 pFmt->
rgxTabs[cellNum] &= ~0x00FFFFFF;
904 pFmt->
rgxTabs[cellNum] |= 0x00FFFFFF &
info->rtfParam;
906 info->tableDef->numCellsDefined++;
935 info->tableDef->gapH =
info->rtfParam;
939 info->tableDef->leftEdge =
info->rtfParam;
947 switch (
info->rtfMinor)
950 if (
info->editor->bEmulateVersion10)
957 if (!
info->editor->bEmulateVersion10) {
960 if (!
info->nestingLevel &&
967 info->nestingLevel = 1;
984 if (
info->editor->bEmulateVersion10)
995 if (!
info->editor->bEmulateVersion10) {
998 if (!
info->nestingLevel &&
1005 info->nestingLevel++;
1014 const int defaultCellSize = 2000;
1015 int nRightBoundary = defaultCellSize;
1019 nRightBoundary += defaultCellSize;
1044 if (
info->editor->pCursors[0].pRun != run ||
1045 info->editor->pCursors[0].nOffset)
1049 info->editor->pCursors[1].pRun = run;
1051 info->editor->pCursors[1].nOffset = 0;
1063 info->nestingLevel--;
1064 if (!
info->nestingLevel)
1066 if (
info->canInheritInTbl) {
1069 while (
info->tableDef) {
1070 tableDef =
info->tableDef;
1104 if (
info->editor->bEmulateVersion10) {
1108 para =
info->editor->pCursors[0].pPara;
1114 info->rtfMajor =
' ';
1116 else if (
info->rtfMinor ==
rtfPar && tableDef)
1128 LPOLECLIENTSITE lpClientSite =
NULL;
1130 LPOLECACHE lpOleCache =
NULL;
1131 LPRICHEDITOLE lpReOle =
NULL;
1140 stgm.tymed = TYMED_ENHMF;
1141 stgm.u.hEnhMetaFile = hemf;
1146 stgm.tymed = TYMED_GDI;
1147 stgm.u.hBitmap =
hbmp;
1150 stgm.pUnkForRelease =
NULL;
1153 fm.dwAspect = DVASPECT_CONTENT;
1155 fm.tymed = stgm.tymed;
1164 IUnknown_QueryInterface(editor->
reOle, &IID_IRichEditOle, (
void**)&lpReOle) ==
S_OK &&
1165 IRichEditOle_GetClientSite(lpReOle, &lpClientSite) ==
S_OK &&
1166 IOleObject_SetClientSite(lpObject, lpClientSite) ==
S_OK &&
1167 IOleObject_GetUserClassID(lpObject, &
clsid) ==
S_OK &&
1168 IOleObject_QueryInterface(lpObject, &
IID_IOleCache, (
void**)&lpOleCache) ==
S_OK &&
1169 IOleCache_Cache(lpOleCache, &fm, 0, &conn) ==
S_OK &&
1171 IDataObject_SetData(lpDataObject, &fm, &stgm,
TRUE) ==
S_OK)
1175 reobject.cbStruct =
sizeof(reobject);
1176 reobject.cp = REO_CP_SELECTION;
1177 reobject.clsid =
clsid;
1178 reobject.poleobj = lpObject;
1179 reobject.pstg = lpStorage;
1180 reobject.polesite = lpClientSite;
1182 reobject.sizel.cx =
MulDiv(sz->
cx, 254, 144);
1183 reobject.sizel.cy =
MulDiv(sz->
cy, 254, 144);
1184 reobject.dvaspect = DVASPECT_CONTENT;
1185 reobject.dwFlags = 0;
1186 reobject.dwUser = 0;
1192 if (lpObject) IOleObject_Release(lpObject);
1193 if (lpClientSite) IOleClientSite_Release(lpClientSite);
1194 if (lpStorage) IStorage_Release(lpStorage);
1195 if (lpDataObject) IDataObject_Release(lpDataObject);
1196 if (lpOleCache) IOleCache_Release(lpOleCache);
1197 if (lpReOle) IRichEditOle_Release(lpReOle);
1213 if (--
level == 0)
break;
1241 ERR(
"Called with incorrect token\n");
1249 for (flip =
TRUE;; flip = !flip)
1271 if (flip)
FIXME(
"wrong hex string\n");
1285 enum gfxkind {gfx_unknown = 0, gfx_enhmetafile, gfx_metafile, gfx_dib} gfx = gfx_unknown;
1312 if (--
level == 0)
break;
1335 if (
info->rtfParam != 0)
FIXME(
"dibitmap should be 0 (%d)\n",
info->rtfParam);
1339 gfx = gfx_enhmetafile;
1349 FIXME(
"Non supported attribute: %d %d %d\n",
info->rtfClass,
info->rtfMajor,
info->rtfMinor);
1356 case gfx_enhmetafile:
1423 FIXME(
"Non supported attribute: %d %d %d\n",
info->rtfClass,
info->rtfMajor,
info->rtfMinor);
1434 WCHAR txt_before = 0, txt_after = 0;
1443 int loc =
info->rtfMinor;
1449 txt_before =
info->rtfMajor;
1451 txt_after =
info->rtfMajor;
1462 if (--
level == 0)
break;
1476 switch (
info->rtfMinor)
1518 if (txt_before == 0 && txt_after == 0)
1520 else if (txt_after ==
'.')
1522 else if (txt_before ==
'(' && txt_after ==
')')
1528 TRACE(
"type %d indent %d start %d txt before %04x txt after %04x\n",
1536 switch(
info->rtfClass)
1539 switch(
info->rtfMajor)
1546 info->stack[
info->stackTop].unicodeLength =
info->unicodeLength;
1555 if (
info->stackTop <= 0)
1557 if (
info->stackTop < 0)
1563 info->unicodeLength =
info->stack[
info->stackTop].unicodeLength;
1574 stream->editstream->dwError =
stream->editstream->pfnCallback(
stream->editstream->dwCookie,
1585 int from, to, nUndoMode;
1684 if (!
parser.editor->bEmulateVersion10)
1695 if (
parser.tableDef &&
parser.tableDef->tableRowStart &&
1707 if (
parser.nestingLevel > 0)
1709 while (
parser.nestingLevel > 1)
1711 para =
parser.tableDef->tableRowStart;
1714 para =
parser.tableDef->tableRowStart;
1735 while (--
parser.stackTop >= 0)
1753 WCHAR lastchar[3] = {
'\0',
'\0'};
1755 ME_Cursor linebreakCursor = *selEnd, lastcharCursor = *selEnd;
1759 cf.cbSize =
sizeof(
cf);
1769 if (lastchar[0] ==
'\r' && (lastchar[1] ==
'\n' || lastchar[1] ==
'\0')) {
1775 num_read = to -
from;
1785 ERR(
"EM_STREAMIN without SF_TEXT or SF_RTF\n");
1858 WCHAR wLastChar =
' ';
1860 TRACE(
"flags==0x%08x, chrg->cpMin==%d, chrg->cpMax==%d text==%s\n",
1864 FIXME(
"Flags 0x%08x not implemented\n",
1868 if (chrg->
cpMax == -1)
1871 nMax = chrg->
cpMax > nTextLen ? nTextLen : chrg->
cpMax;
1884 chrgText->
cpMin = -1;
1885 chrgText->
cpMax = -1;
1899 nMax = nMin > nTextLen ? nTextLen : nMin;
1900 if (nMin < nSwap || chrg->cpMax == -1)
1906 if (!nLen || nMin < 0 || nMax < 0 || nMax < nMin)
1928 int nCurStart =
cursor.nOffset;
1937 if (nMatched == nLen)
1940 int nNextStart = nCurStart;
1949 nNextStart = -nMatched;
1961 cursor.nOffset +=
cursor.pPara->member.para.nCharOfs +
cursor.pRun->member.run.nCharOfs;
1973 nCurStart = -nMatched;
2005 int nCurEnd =
cursor.nOffset;
2021 if (nMatched == nLen)
2024 int nPrevEnd = nCurEnd;
2031 if (nPrevEnd - nMatched == 0)
2051 chrgText->
cpMin = nStart;
2052 chrgText->
cpMax = nStart + nLen;
2054 TRACE(
"found at %d-%d\n", nStart, nStart + nLen);
2057 if (nCurEnd - nMatched == 0)
2078 TRACE(
"not found\n");
2089 if (!
ex->cb || !
pText)
return 0;
2123 buflen =
min(crlfmul * nChars,
ex->cb - 1);
2139 if (!strText)
return 0;
2182 pDest = (
WORD *)lpBuff;
2184 for (
i = 0;
i<
cb && pSrc[
pData->nLength+
i];
i++) {
2185 pDest[
i] = pSrc[
pData->nLength+
i];
2201 for (
i = 0;
i<
cb && pSrc[
pData->nLength+
i];
i++) {
2202 pDest[
i] = pSrc[
pData->nLength+
i];
2210 static const WCHAR rtfW[] = {
'R',
'i',
'c',
'h',
' ',
'T',
'e',
'x',
't',
' ',
'F',
'o',
'r',
'm',
'a',
't',0};
2218 gds.
hData = med->u.hGlobal;
2233 gds.
hData = med->u.hGlobal;
2305 if (ps && ps->
dwAspect != DVASPECT_CONTENT)
2316 if (
cf &&
cf !=
format->fmt.cfFormat)
continue;
2323 if (
hr !=
S_OK)
goto done;
2331 IDataObject_Release(
data );
2349 hr = IRichEditOleCallback_GetClipboardData(editor->
lpOleCallback, &
range, RECO_COPY, &dataObj);
2355 IDataObject_Release(dataObj);
2363 int offs, num_chars;
2419 startPara =
from->pPara;
2426 start.pPara = startPara;
2467 static const WCHAR endlv10[] = {
'\r',
'\n'};
2499 cursor.nOffset +
cursor.pRun->member.run.nCharOfs == 0 &&
2548 if (
cursor.pRun->member.run.nCharOfs +
cursor.nOffset == 0 &&
2633 ME_ArrowKey(editor, nKey, shift_is_down, ctrl_is_down);
2655 BOOL bDeletionSucceeded;
2726 chf.
cbSize =
sizeof(chf);
2756 wstr = (
WCHAR)charCode;
2759 CHAR charA = charCode;
2766 if ((
unsigned)wstr >=
' ' || wstr ==
'\t')
2782 cursor.pRun->member.run.nCharOfs +
cursor.nOffset == 0 &&
2787 bSelectedRow =
TRUE;
2841 static int clickNum = 0;
2848 (
msg == WM_XBUTTONDBLCLK))
2856 (
msg == WM_XBUTTONDOWN))
2858 static MSG prevClickMsg;
2862 clickMsg.hwnd = (
HWND)editor;
2863 clickMsg.message =
msg;
2864 clickMsg.wParam =
wParam;
2865 clickMsg.lParam =
lParam;
2869 if ((clickNum != 0) &&
2870 (clickMsg.message == prevClickMsg.message) &&
2871 (clickMsg.hwnd == prevClickMsg.hwnd) &&
2872 (clickMsg.wParam == prevClickMsg.wParam) &&
2881 prevClickMsg = clickMsg;
2905 sbi.
cbSize =
sizeof(sbi);
2914 sbi.
cbSize =
sizeof(sbi);
2957 run = &
cursor.pRun->member.run;
2968 int selStart, selEnd;
2972 if (selStart <= offset && selEnd >=
offset) {
3011 if (
cursor.pRun->member.run.reobj)
3018 if (character_count)
3021 if (character_count >= 2)
3221 ITextHost_Release(editor->
texthost);
3224 IUnknown_Release(editor->
reOle);
3279 *remain -=
WHEEL_DELTA * change / amount_per_click;
3312 "EM_SETPASSWORDCHAR",
3313 "EM_EMPTYUNDOBUFFER",
3314 "EM_GETFIRSTVISIBLELINE",
3316 "EM_SETWORDBREAKPROC",
3317 "EM_GETWORDBREAKPROC",
3318 "EM_GETPASSWORDCHAR",
3333 "EM_EXLINEFROMCHAR",
3339 "EM_GETOLEINTERFACE",
3349 "EM_SETOLECALLBACK",
3351 "EM_SETTARGETDEVICE",
3359 "EM_GETWORDBREAKPROCEX",
3360 "EM_SETWORDBREAKPROCEX",
3362 "EM_UNKNOWN_USER_83",
3367 "EM_STOPGROUPTYPING",
3371 "EM_GETAUTOURLDETECT",
3374 "EM_GETTEXTLENGTHEX",
3377 "EM_UNKNOWN_USER_98",
3378 "EM_UNKNOWN_USER_99",
3379 "EM_SETPUNCTUATION",
3380 "EM_GETPUNCTUATION",
3381 "EM_SETWORDWRAPMODE",
3382 "EM_GETWORDWRAPMODE",
3388 "EM_UNKNOWN_USER_109",
3389 "EM_UNKNOWN_USER_110",
3390 "EM_UNKNOWN_USER_111",
3391 "EM_UNKNOWN_USER_112",
3392 "EM_UNKNOWN_USER_113",
3393 "EM_UNKNOWN_USER_114",
3394 "EM_UNKNOWN_USER_115",
3395 "EM_UNKNOWN_USER_116",
3396 "EM_UNKNOWN_USER_117",
3397 "EM_UNKNOWN_USER_118",
3398 "EM_UNKNOWN_USER_119",
3399 "EM_SETLANGOPTIONS",
3400 "EM_GETLANGOPTIONS",
3401 "EM_GETIMECOMPMODE",
3405 "EM_SETIMEMODEBIAS",
3429 if (!isExact)
return;
3436 info.nmhdr.idFrom = 0;
3461 int from, to, nStartCursor;
3589 #define UNSUPPORTED_MSG(e) \ 3591 FIXME(#e ": stub\n"); \ 3592 *phresult = S_FALSE; \ 3658 if ((*pfrom|*pto) & 0xFFFF0000)
3707 cf.cbSize =
sizeof(
cf);
3710 tmp_size = (
cf.yHeight / 20) +
wParam;
3714 else if (tmp_size > 12 && tmp_size < 28 && tmp_size % 2)
3715 size = tmp_size + (is_increase ? 1 : -1);
3716 else if (tmp_size > 28 && tmp_size < 36)
3717 size = is_increase ? 36 : 28;
3718 else if (tmp_size > 36 && tmp_size < 48)
3719 size = is_increase ? 48 : 36;
3720 else if (tmp_size > 48 && tmp_size < 72)
3721 size = is_increase ? 72 : 48;
3722 else if (tmp_size > 72 && tmp_size < 80)
3723 size = is_increase ? 80 : 72;
3724 else if (tmp_size > 80 && tmp_size < 1638)
3725 size = 10 * (is_increase ? (tmp_size / 10 + 1) : (tmp_size / 10));
3726 else if (tmp_size >= 1638)
3749 DWORD changedSettings;
3765 changedSettings = oldSettings ^
settings;
3767 if (changedSettings) {
3788 FIXME(
"ECO_VERTICAL not implemented yet!\n");
3790 FIXME(
"ECO_AUTOHSCROLL not implemented yet!\n");
3792 FIXME(
"ECO_AUTOVSCROLL not implemented yet!\n");
3794 FIXME(
"ECO_WANTRETURN not implemented yet!\n");
3796 FIXME(
"ECO_AUTOWORDSELECTION not implemented yet!\n");
3869 BOOL bRtf, bUnicode, bSelection, bUTF8;
3871 static const char utf8_bom[] = {0xef, 0xbb, 0xbf};
3873 if (!pStruct)
return 0;
3882 TRACE(
"EM_SETTEXTEX - %s, flags %d, cp %d\n",
3906 if (bUTF8 && !bUnicode) {
3997 tmp.
cbSize =
sizeof(tmp);
4028 ypara =
p->member.para.pt.y;
4031 ystart = ypara +
p->member.row.pt.y;
4032 yend = ystart +
p->member.row.nHeight;
4126 TRACE(
"WM_SETTEXT - NULL\n");
4178 nTo - nFrom, unicode);
4200 TRACE(
"EM_GETTEXTRANGE min=%d max=%d unicode=%d textlength=%d\n",
4202 if (nStart < 0)
return 0;
4203 if ((nStart == 0 && nEnd == -1) || nEnd > textlength)
4205 if (nStart >= nEnd)
return 0;
4213 const unsigned int nMaxChars = *(
WORD *)
lParam;
4214 unsigned int nCharsLeft = nMaxChars;
4218 TRACE(
"EM_GETLINE: row=%d, nMaxChars=%d (%s)\n", (
int)
wParam, nMaxChars,
4219 unicode ?
"Unicode" :
"Ansi");
4238 dest += nCopy * (unicode ?
sizeof(
WCHAR) : 1);
4239 nCharsLeft -= nCopy;
4253 TRACE(
"EM_GETLINE: got %u characters\n", nMaxChars - nCharsLeft);
4254 return nMaxChars - nCharsLeft - (wroteNull ? 1 : 0);
4277 TRACE(
"EM_GETLINECOUNT: nRows==%d\n",
nRows);
4308 TRACE(
"EM_LINEINDEX: nCharOfs==%d\n", nCharOfs);
4314 int nChars = 0, nThisLineOfs = 0, nNextLineOfs = 0;
4321 FIXME(
"EM_LINELENGTH: returning number of unselected characters on lines with selection unsupported.\n");
4335 nChars = nNextLineOfs - nThisLineOfs;