mirror of
https://github.com/reactos/reactos.git
synced 2025-04-29 10:39:07 +00:00
Synced riched20.dll with Wine HEAD
svn path=/trunk/; revision=34367
This commit is contained in:
parent
b513c98fb2
commit
0fe1322cbc
16 changed files with 2031 additions and 189 deletions
|
@ -164,7 +164,6 @@ ME_GetCursorCoordinates(ME_TextEditor *editor, ME_Cursor *pCursor,
|
|||
ME_DisplayItem *pCursorRun = pCursor->pRun;
|
||||
ME_DisplayItem *pSizeRun = pCursor->pRun;
|
||||
|
||||
assert(!pCursor->nOffset || !editor->bCaretAtEnd);
|
||||
assert(height && x && y);
|
||||
assert(!(ME_GetParagraph(pCursorRun)->member.para.nFlags & MEPF_REWRAP));
|
||||
assert(pCursor->pRun);
|
||||
|
@ -182,9 +181,9 @@ ME_GetCursorCoordinates(ME_TextEditor *editor, ME_Cursor *pCursor,
|
|||
|
||||
ME_InitContext(&c, editor, hDC);
|
||||
|
||||
if (!pCursor->nOffset && !editor->bCaretAtEnd)
|
||||
if (!pCursor->nOffset)
|
||||
{
|
||||
ME_DisplayItem *prev = ME_FindItemBack(pCursorRun, diRunOrStartRow);
|
||||
ME_DisplayItem *prev = ME_FindItemBack(pCursorRun, diRunOrParagraph);
|
||||
assert(prev);
|
||||
if (prev->type == diRun)
|
||||
pSizeRun = prev;
|
||||
|
@ -209,15 +208,14 @@ ME_GetCursorCoordinates(ME_TextEditor *editor, ME_Cursor *pCursor,
|
|||
row->member.row.nLMargin);
|
||||
}
|
||||
}
|
||||
if (pCursor->nOffset && !(run->member.run.nFlags & MERF_SKIPPED)) {
|
||||
if (pCursor->nOffset) {
|
||||
sz = ME_GetRunSize(&c, ¶->member.para, &run->member.run, pCursor->nOffset,
|
||||
row->member.row.nLMargin);
|
||||
}
|
||||
|
||||
*height = pSizeRun->member.run.nAscent + pSizeRun->member.run.nDescent;
|
||||
*x = run->member.run.pt.x + sz.cx;
|
||||
*y = para->member.para.nYPos + row->member.row.nBaseline + pSizeRun->member.run.pt.y - pSizeRun->member.run.nAscent - ME_GetYScrollPos(editor);
|
||||
|
||||
*y = para->member.para.nYPos + row->member.row.nBaseline + run->member.run.pt.y - pSizeRun->member.run.nAscent - ME_GetYScrollPos(editor);
|
||||
ME_DestroyContext(&c, editor->hWnd);
|
||||
return;
|
||||
}
|
||||
|
@ -238,6 +236,10 @@ ME_MoveCaret(ME_TextEditor *editor)
|
|||
ME_GetCursorCoordinates(editor, &editor->pCursors[0], &x, &y, &height);
|
||||
if(editor->bHaveFocus)
|
||||
{
|
||||
RECT rect;
|
||||
|
||||
GetClientRect(editor->hWnd, &rect);
|
||||
x = min(x, rect.right-2);
|
||||
CreateCaret(editor->hWnd, NULL, 0, height);
|
||||
SetCaretPos(x, y);
|
||||
}
|
||||
|
@ -744,11 +746,9 @@ ME_MoveCursorWords(ME_TextEditor *editor, ME_Cursor *cursor, int nRelOfs)
|
|||
void
|
||||
ME_SelectWord(ME_TextEditor *editor)
|
||||
{
|
||||
if (!(editor->pCursors[0].pRun->member.run.nFlags & MERF_ENDPARA))
|
||||
ME_MoveCursorWords(editor, &editor->pCursors[0], -1);
|
||||
ME_MoveCursorWords(editor, &editor->pCursors[1], +1);
|
||||
ME_InvalidateSelection(editor);
|
||||
ME_SendSelChange(editor);
|
||||
editor->pCursors[0] = editor->pCursors[1];
|
||||
ME_MoveCursorWords(editor, &editor->pCursors[0], -1);
|
||||
}
|
||||
|
||||
|
||||
|
@ -797,6 +797,20 @@ static void ME_FindPixelPos(ME_TextEditor *editor, int x, int y, ME_Cursor *resu
|
|||
}
|
||||
p = pp;
|
||||
}
|
||||
if (p == editor->pBuffer->pLast)
|
||||
{
|
||||
/* The position is below the last paragraph, so the last row will be used
|
||||
* rather than the end of the text, so the x position will be used to
|
||||
* determine the offset closest to the pixel position. */
|
||||
p = ME_FindItemBack(p, diStartRow);
|
||||
if (p != NULL){
|
||||
p = ME_FindItemFwd(p, diRun);
|
||||
}
|
||||
else
|
||||
{
|
||||
p = editor->pBuffer->pLast;
|
||||
}
|
||||
}
|
||||
for (; p != editor->pBuffer->pLast; p = p->next)
|
||||
{
|
||||
switch (p->type)
|
||||
|
@ -855,7 +869,7 @@ ME_CharFromPos(ME_TextEditor *editor, int x, int y)
|
|||
}
|
||||
|
||||
|
||||
void ME_LButtonDown(ME_TextEditor *editor, int x, int y)
|
||||
void ME_LButtonDown(ME_TextEditor *editor, int x, int y, int clickNum)
|
||||
{
|
||||
ME_Cursor tmp_cursor;
|
||||
int is_selection = 0;
|
||||
|
@ -872,19 +886,15 @@ void ME_LButtonDown(ME_TextEditor *editor, int x, int y)
|
|||
ME_FindPixelPos(editor, x, y, &editor->pCursors[0], &editor->bCaretAtEnd);
|
||||
if (GetKeyState(VK_SHIFT)>=0)
|
||||
{
|
||||
/* Shift key is not down */
|
||||
editor->pCursors[1] = editor->pCursors[0];
|
||||
if (clickNum > 1)
|
||||
ME_SelectWord(editor);
|
||||
}
|
||||
else if (!is_selection) {
|
||||
editor->pCursors[1] = tmp_cursor;
|
||||
is_selection = 1;
|
||||
}
|
||||
|
||||
ME_InvalidateSelection(editor);
|
||||
HideCaret(editor->hWnd);
|
||||
ME_MoveCaret(editor);
|
||||
ShowCaret(editor->hWnd);
|
||||
ME_ClearTempStyle(editor);
|
||||
ME_SendSelChange(editor);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -918,13 +928,13 @@ void ME_LButtonDown(ME_TextEditor *editor, int x, int y)
|
|||
}
|
||||
editor->pCursors[2] = editor->pCursors[0];
|
||||
editor->pCursors[3] = editor->pCursors[1];
|
||||
ME_InvalidateSelection(editor);
|
||||
HideCaret(editor->hWnd);
|
||||
ME_MoveCaret(editor);
|
||||
ShowCaret(editor->hWnd);
|
||||
ME_ClearTempStyle(editor);
|
||||
ME_SendSelChange(editor);
|
||||
}
|
||||
ME_InvalidateSelection(editor);
|
||||
HideCaret(editor->hWnd);
|
||||
ME_MoveCaret(editor);
|
||||
ShowCaret(editor->hWnd);
|
||||
ME_ClearTempStyle(editor);
|
||||
ME_SendSelChange(editor);
|
||||
}
|
||||
|
||||
void ME_MouseMove(ME_TextEditor *editor, int x, int y)
|
||||
|
@ -967,6 +977,7 @@ void ME_MouseMove(ME_TextEditor *editor, int x, int y)
|
|||
ME_InvalidateSelection(editor);
|
||||
ShowCaret(editor->hWnd);
|
||||
ME_SendSelChange(editor);
|
||||
SendMessageW(editor->hWnd, EM_SCROLLCARET, 0, 0);
|
||||
}
|
||||
|
||||
static ME_DisplayItem *ME_FindRunInRow(ME_TextEditor *editor, ME_DisplayItem *pRow,
|
||||
|
@ -976,13 +987,13 @@ static ME_DisplayItem *ME_FindRunInRow(ME_TextEditor *editor, ME_DisplayItem *pR
|
|||
pNext = ME_FindItemFwd(pRow, diRunOrStartRow);
|
||||
assert(pNext->type == diRun);
|
||||
pLastRun = pNext;
|
||||
*pbCaretAtEnd = FALSE;
|
||||
if (pbCaretAtEnd) *pbCaretAtEnd = FALSE;
|
||||
if (pOffset) *pOffset = 0;
|
||||
do {
|
||||
int run_x = pNext->member.run.pt.x;
|
||||
int width = pNext->member.run.nWidth;
|
||||
if (x < run_x)
|
||||
{
|
||||
if (pOffset) *pOffset = 0;
|
||||
return pNext;
|
||||
}
|
||||
if (x >= run_x && x < run_x+width)
|
||||
|
@ -1002,12 +1013,9 @@ static ME_DisplayItem *ME_FindRunInRow(ME_TextEditor *editor, ME_DisplayItem *pR
|
|||
if ((pLastRun->member.run.nFlags & MERF_ENDPARA) == 0)
|
||||
{
|
||||
pNext = ME_FindItemFwd(pNext, diRun);
|
||||
if (pbCaretAtEnd) *pbCaretAtEnd = 1;
|
||||
if (pOffset) *pOffset = 0;
|
||||
if (pbCaretAtEnd) *pbCaretAtEnd = TRUE;
|
||||
return pNext;
|
||||
} else {
|
||||
if (pbCaretAtEnd) *pbCaretAtEnd = 0;
|
||||
if (pOffset) *pOffset = 0;
|
||||
return pLastRun;
|
||||
}
|
||||
}
|
||||
|
@ -1179,9 +1187,6 @@ static void ME_ArrowPageDown(ME_TextEditor *editor, ME_Cursor *pCursor)
|
|||
static void ME_ArrowHome(ME_TextEditor *editor, ME_Cursor *pCursor)
|
||||
{
|
||||
ME_DisplayItem *pRow = ME_FindItemBack(pCursor->pRun, diStartRow);
|
||||
/* bCaretAtEnd doesn't make sense if the cursor isn't set at the
|
||||
first character of the next row */
|
||||
assert(!editor->bCaretAtEnd || !pCursor->nOffset);
|
||||
ME_WrapMarkedParagraphs(editor);
|
||||
if (pRow) {
|
||||
ME_DisplayItem *pRun;
|
||||
|
@ -1297,27 +1302,13 @@ void ME_DeleteSelection(ME_TextEditor *editor)
|
|||
|
||||
ME_Style *ME_GetSelectionInsertStyle(ME_TextEditor *editor)
|
||||
{
|
||||
ME_Style *style;
|
||||
int from, to;
|
||||
|
||||
ME_GetSelection(editor, &from, &to);
|
||||
if (from != to) {
|
||||
ME_Cursor c;
|
||||
ME_CursorFromCharOfs(editor, from, &c);
|
||||
style = c.pRun->member.run.style;
|
||||
ME_AddRefStyle(style); /* ME_GetInsertStyle has already done that */
|
||||
}
|
||||
else
|
||||
style = ME_GetInsertStyle(editor, 0);
|
||||
return style;
|
||||
return ME_GetInsertStyle(editor, 0);
|
||||
}
|
||||
|
||||
void ME_SendSelChange(ME_TextEditor *editor)
|
||||
{
|
||||
SELCHANGE sc;
|
||||
|
||||
ME_ClearTempStyle(editor);
|
||||
|
||||
if (!(editor->nEventMask & ENM_SELCHANGE))
|
||||
return;
|
||||
|
||||
|
@ -1336,6 +1327,8 @@ void ME_SendSelChange(ME_TextEditor *editor)
|
|||
(sc.seltyp & SEL_MULTICHAR) ? "SEL_MULTICHAR" : "");
|
||||
if (sc.chrg.cpMin != editor->notified_cr.cpMin || sc.chrg.cpMax != editor->notified_cr.cpMax)
|
||||
{
|
||||
ME_ClearTempStyle(editor);
|
||||
|
||||
editor->notified_cr = sc.chrg;
|
||||
SendMessageW(GetParent(editor->hWnd), WM_NOTIFY, sc.nmhdr.idFrom, (LPARAM)&sc);
|
||||
}
|
||||
|
@ -1350,7 +1343,6 @@ ME_ArrowKey(ME_TextEditor *editor, int nVKey, BOOL extend, BOOL ctrl)
|
|||
BOOL success = FALSE;
|
||||
|
||||
ME_CheckCharOffsets(editor);
|
||||
editor->nUDArrowX = -1;
|
||||
switch(nVKey) {
|
||||
case VK_LEFT:
|
||||
editor->bCaretAtEnd = 0;
|
||||
|
|
|
@ -124,7 +124,7 @@
|
|||
- EM_SETWORDWRAPMODE 1.0asian
|
||||
+ EM_SETZOOM 3.0
|
||||
+ EM_SHOWSCROLLBAR 2.0
|
||||
- EM_STOPGROUPTYPING 2.0
|
||||
+ EM_STOPGROUPTYPING 2.0
|
||||
+ EM_STREAMIN
|
||||
+ EM_STREAMOUT
|
||||
+ EM_UNDO
|
||||
|
@ -190,7 +190,6 @@
|
|||
* RICHED20 TODO (incomplete):
|
||||
*
|
||||
* - messages/styles/notifications listed above
|
||||
* - Undo coalescing
|
||||
* - add remaining CHARFORMAT/PARAFORMAT fields
|
||||
* - right/center align should strip spaces from the beginning
|
||||
* - pictures/OLE objects (not just smiling faces that lack API support ;-) )
|
||||
|
@ -970,11 +969,11 @@ static void ME_RTFReadHook(RTF_Info *info) {
|
|||
{
|
||||
ME_Style *s;
|
||||
RTFFlushOutputBuffer(info);
|
||||
if (info->stackTop<=1) {
|
||||
info->stackTop--;
|
||||
if (info->stackTop<=0) {
|
||||
info->rtfClass = rtfEOF;
|
||||
return;
|
||||
}
|
||||
info->stackTop--;
|
||||
assert(info->stackTop >= 0);
|
||||
if (info->styleChanged)
|
||||
{
|
||||
|
@ -1102,6 +1101,9 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre
|
|||
if (parser.lpRichEditOle)
|
||||
IRichEditOle_Release(parser.lpRichEditOle);
|
||||
|
||||
if (!inStream.editstream->dwError && parser.stackTop > 0)
|
||||
inStream.editstream->dwError = HRESULT_FROM_WIN32(ERROR_HANDLE_EOF);
|
||||
|
||||
/* Remove last line break, as mandated by tests. This is not affected by
|
||||
CR/LF counters, since RTF streaming presents only \para tokens, which
|
||||
are converted according to the standard rules: \r for 2.0, \r\n for 1.0
|
||||
|
@ -1148,7 +1150,9 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre
|
|||
if (!(format & SFF_SELECTION)) {
|
||||
ME_ClearTempStyle(editor);
|
||||
}
|
||||
HideCaret(editor->hWnd);
|
||||
ME_MoveCaret(editor);
|
||||
ShowCaret(editor->hWnd);
|
||||
ME_SendSelChange(editor);
|
||||
ME_SendRequestResize(editor, FALSE);
|
||||
|
||||
|
@ -1366,7 +1370,7 @@ ME_FindText(ME_TextEditor *editor, DWORD flags, const CHARRANGE *chrg, const WCH
|
|||
break;
|
||||
}
|
||||
|
||||
nStart += para->member.para.nCharOfs + pCurItem->member.run.nCharOfs;
|
||||
nStart += para->member.para.nCharOfs + item->member.run.nCharOfs;
|
||||
if (chrgText)
|
||||
{
|
||||
chrgText->cpMin = nStart;
|
||||
|
@ -1538,31 +1542,52 @@ ME_KeyDown(ME_TextEditor *editor, WORD nKey)
|
|||
{
|
||||
case VK_LEFT:
|
||||
case VK_RIGHT:
|
||||
case VK_UP:
|
||||
case VK_DOWN:
|
||||
case VK_HOME:
|
||||
case VK_END:
|
||||
editor->nUDArrowX = -1;
|
||||
/* fall through */
|
||||
case VK_UP:
|
||||
case VK_DOWN:
|
||||
case VK_PRIOR:
|
||||
case VK_NEXT:
|
||||
ME_CommitUndo(editor); /* End coalesced undos for typed characters */
|
||||
ME_ArrowKey(editor, nKey, shift_is_down, ctrl_is_down);
|
||||
return TRUE;
|
||||
case VK_BACK:
|
||||
case VK_DELETE:
|
||||
editor->nUDArrowX = -1;
|
||||
/* FIXME backspace and delete aren't the same, they act different wrt paragraph style of the merged paragraph */
|
||||
if (GetWindowLongW(editor->hWnd, GWL_STYLE) & ES_READONLY)
|
||||
return FALSE;
|
||||
if (ME_IsSelection(editor))
|
||||
{
|
||||
ME_DeleteSelection(editor);
|
||||
else if (nKey == VK_DELETE || ME_ArrowKey(editor, VK_LEFT, FALSE, FALSE))
|
||||
ME_CommitUndo(editor);
|
||||
}
|
||||
else if (nKey == VK_DELETE)
|
||||
{
|
||||
/* Delete stops group typing.
|
||||
* (See MSDN remarks on EM_STOPGROUPTYPING message) */
|
||||
ME_DeleteTextAtCursor(editor, 1, 1);
|
||||
ME_CommitUndo(editor);
|
||||
}
|
||||
else if (ME_ArrowKey(editor, VK_LEFT, FALSE, FALSE))
|
||||
{
|
||||
/* Backspace can be grouped for a single undo */
|
||||
ME_ContinueCoalescingTransaction(editor);
|
||||
ME_DeleteTextAtCursor(editor, 1, 1);
|
||||
ME_CommitCoalescingUndo(editor);
|
||||
}
|
||||
else
|
||||
return TRUE;
|
||||
ME_CommitUndo(editor);
|
||||
ME_UpdateSelectionLinkAttribute(editor);
|
||||
ME_UpdateRepaint(editor);
|
||||
ME_SendRequestResize(editor, FALSE);
|
||||
return TRUE;
|
||||
|
||||
default:
|
||||
if (nKey != VK_SHIFT && nKey != VK_CONTROL && nKey && nKey != VK_MENU)
|
||||
editor->nUDArrowX = -1;
|
||||
if (ctrl_is_down)
|
||||
{
|
||||
if (nKey == 'W')
|
||||
|
@ -1663,7 +1688,6 @@ ME_TextEditor *ME_MakeEditor(HWND hWnd) {
|
|||
ed->mode = TM_RICHTEXT | TM_MULTILEVELUNDO | TM_MULTICODEPAGE;
|
||||
ed->AutoURLDetect_bEnable = FALSE;
|
||||
ed->bHaveFocus = FALSE;
|
||||
GetClientRect(hWnd, &ed->rcFormat);
|
||||
for (i=0; i<HFONT_CACHE_SIZE; i++)
|
||||
{
|
||||
ed->pFontCache[i].nRefs = 0;
|
||||
|
@ -1673,7 +1697,7 @@ ME_TextEditor *ME_MakeEditor(HWND hWnd) {
|
|||
|
||||
ME_CheckCharOffsets(ed);
|
||||
if (GetWindowLongW(hWnd, GWL_STYLE) & ES_SELECTIONBAR)
|
||||
ed->selofs = 16;
|
||||
ed->selofs = SELECTIONBAR_WIDTH;
|
||||
else
|
||||
ed->selofs = 0;
|
||||
ed->linesel = 0;
|
||||
|
@ -2045,11 +2069,9 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
|
|||
return editor->pRedoStack != NULL;
|
||||
case WM_UNDO: /* FIXME: actually not the same */
|
||||
case EM_UNDO:
|
||||
ME_Undo(editor);
|
||||
return 0;
|
||||
return ME_Undo(editor);
|
||||
case EM_REDO:
|
||||
ME_Redo(editor);
|
||||
return 0;
|
||||
return ME_Redo(editor);
|
||||
case EM_GETOPTIONS:
|
||||
{
|
||||
/* these flags are equivalent to the ES_* counterparts */
|
||||
|
@ -2089,7 +2111,7 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
|
|||
if (settings & ECO_AUTOWORDSELECTION)
|
||||
FIXME("ECO_AUTOWORDSELECTION not implemented yet!\n");
|
||||
if (settings & ECO_SELECTIONBAR)
|
||||
editor->selofs = 16;
|
||||
editor->selofs = SELECTIONBAR_WIDTH;
|
||||
else
|
||||
editor->selofs = 0;
|
||||
ME_WrapMarkedParagraphs(editor);
|
||||
|
@ -2180,6 +2202,8 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
|
|||
ME_StreamInRTFString(editor, 0, (char *)lParam);
|
||||
else ME_InsertTextFromCursor(editor, 0, wszText, len, style);
|
||||
ME_ReleaseStyle(style);
|
||||
|
||||
if (editor->AutoURLDetect_bEnable) ME_UpdateSelectionLinkAttribute(editor);
|
||||
}
|
||||
else {
|
||||
ME_InternalDeleteText(editor, 0, ME_GetTextLength(editor));
|
||||
|
@ -2187,6 +2211,8 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
|
|||
ME_StreamInRTFString(editor, 0, (char *)lParam);
|
||||
else ME_InsertTextFromCursor(editor, 0, wszText, len, editor->pBuffer->pDefaultStyle);
|
||||
len = 1;
|
||||
|
||||
if (editor->AutoURLDetect_bEnable) ME_UpdateLinkAttribute(editor, 0, -1);
|
||||
}
|
||||
ME_CommitUndo(editor);
|
||||
if (!(pStruct->flags & ST_KEEPUNDO))
|
||||
|
@ -2375,6 +2401,7 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
|
|||
ME_ClearTempStyle(editor);
|
||||
ME_EndToUnicode(unicode, wszText);
|
||||
ME_CommitUndo(editor);
|
||||
if (editor->AutoURLDetect_bEnable) ME_UpdateSelectionLinkAttribute(editor);
|
||||
if (!wParam)
|
||||
ME_EmptyUndoStack(editor);
|
||||
ME_UpdateRepaint(editor);
|
||||
|
@ -2454,6 +2481,10 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
|
|||
}
|
||||
else
|
||||
TRACE("WM_SETTEXT - NULL\n");
|
||||
if (editor->AutoURLDetect_bEnable)
|
||||
{
|
||||
ME_UpdateLinkAttribute(editor, 0, -1);
|
||||
}
|
||||
ME_SetSelection(editor, 0, 0);
|
||||
editor->nModifyStep = 0;
|
||||
ME_CommitUndo(editor);
|
||||
|
@ -2607,7 +2638,7 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
|
|||
buffer = heap_alloc((crlfmul*nCount + 1) * sizeof(WCHAR));
|
||||
|
||||
buflen = ME_GetTextW(editor, buffer, nStart, nCount, ex->flags & GT_USECRLF);
|
||||
rc = WideCharToMultiByte(ex->codepage, flags, buffer, -1, (LPSTR)lParam, ex->cb, ex->lpDefaultChar, ex->lpUsedDefChar);
|
||||
rc = WideCharToMultiByte(ex->codepage, flags, buffer, buflen+1, (LPSTR)lParam, ex->cb, ex->lpDefaultChar, ex->lpUsedDefChar);
|
||||
if (rc) rc--; /* do not count 0 terminator */
|
||||
|
||||
heap_free(buffer);
|
||||
|
@ -2889,6 +2920,7 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
|
|||
ME_DisplayItem *pRun;
|
||||
int nCharOfs, nOffset, nLength;
|
||||
POINTL pt = {0,0};
|
||||
SCROLLINFO si;
|
||||
|
||||
nCharOfs = wParam;
|
||||
/* detect which API version we're dealing with */
|
||||
|
@ -2907,12 +2939,21 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
|
|||
pt.y = editor->pBuffer->pLast->member.para.nYPos;
|
||||
}
|
||||
pt.x += editor->selofs;
|
||||
|
||||
si.cbSize = sizeof(si);
|
||||
si.fMask = SIF_POS;
|
||||
if (GetScrollInfo(editor->hWnd, SB_VERT, &si)) pt.y -= si.nPos;
|
||||
si.cbSize = sizeof(si);
|
||||
si.fMask = SIF_POS;
|
||||
if (GetScrollInfo(editor->hWnd, SB_HORZ, &si)) pt.x -= si.nPos;
|
||||
|
||||
if (wParam >= 0x40000) {
|
||||
*(POINTL *)wParam = pt;
|
||||
}
|
||||
return MAKELONG( pt.x, pt.y );
|
||||
return (wParam >= 0x40000) ? 0 : MAKELONG( pt.x, pt.y );
|
||||
}
|
||||
case WM_CREATE:
|
||||
GetClientRect(hWnd, &editor->rcFormat);
|
||||
if (GetWindowLongW(hWnd, GWL_STYLE) & WS_HSCROLL)
|
||||
{ /* Squelch the default horizontal scrollbar it would make */
|
||||
ShowScrollBar(editor->hWnd, SB_HORZ, FALSE);
|
||||
|
@ -2925,16 +2966,22 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
|
|||
ME_DestroyEditor(editor);
|
||||
SetWindowLongPtrW(hWnd, 0, 0);
|
||||
return 0;
|
||||
case WM_LBUTTONDBLCLK:
|
||||
case WM_LBUTTONDOWN:
|
||||
{
|
||||
int clickNum = (msg == WM_LBUTTONDBLCLK) ? 2 : 1;
|
||||
ME_CommitUndo(editor); /* End coalesced undos for typed characters */
|
||||
if ((editor->nEventMask & ENM_MOUSEEVENTS) &&
|
||||
!ME_FilterEvent(editor, msg, &wParam, &lParam))
|
||||
return 0;
|
||||
SetFocus(hWnd);
|
||||
ME_LButtonDown(editor, (short)LOWORD(lParam), (short)HIWORD(lParam));
|
||||
ME_LButtonDown(editor, (short)LOWORD(lParam), (short)HIWORD(lParam),
|
||||
clickNum);
|
||||
SetCapture(hWnd);
|
||||
ME_LinkNotify(editor,msg,wParam,lParam);
|
||||
if (!ME_SetCursor(editor, LOWORD(lParam))) goto do_default;
|
||||
break;
|
||||
}
|
||||
case WM_MOUSEMOVE:
|
||||
if ((editor->nEventMask & ENM_MOUSEEVENTS) &&
|
||||
!ME_FilterEvent(editor, msg, &wParam, &lParam))
|
||||
|
@ -2959,15 +3006,9 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
|
|||
if (!ret) goto do_default;
|
||||
}
|
||||
break;
|
||||
case WM_LBUTTONDBLCLK:
|
||||
if ((editor->nEventMask & ENM_MOUSEEVENTS) &&
|
||||
!ME_FilterEvent(editor, msg, &wParam, &lParam))
|
||||
return 0;
|
||||
ME_LinkNotify(editor,msg,wParam,lParam);
|
||||
ME_SelectWord(editor);
|
||||
break;
|
||||
case WM_RBUTTONUP:
|
||||
case WM_RBUTTONDOWN:
|
||||
ME_CommitUndo(editor); /* End coalesced undos for typed characters */
|
||||
if ((editor->nEventMask & ENM_MOUSEEVENTS) &&
|
||||
!ME_FilterEvent(editor, msg, &wParam, &lParam))
|
||||
return 0;
|
||||
|
@ -2993,6 +3034,7 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
|
|||
ME_SendOldNotify(editor, EN_SETFOCUS);
|
||||
return 0;
|
||||
case WM_KILLFOCUS:
|
||||
ME_CommitUndo(editor); /* End coalesced undos for typed characters */
|
||||
ME_HideCaret(editor);
|
||||
editor->bHaveFocus = FALSE;
|
||||
ME_SendOldNotify(editor, EN_KILLFOCUS);
|
||||
|
@ -3036,9 +3078,7 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
|
|||
CHAR charA = wParam;
|
||||
MultiByteToWideChar(CP_ACP, 0, &charA, 1, &wstr, 1);
|
||||
}
|
||||
if (editor->AutoURLDetect_bEnable)
|
||||
ME_AutoURLDetect(editor, wstr);
|
||||
|
||||
|
||||
switch (wstr)
|
||||
{
|
||||
case 1: /* Ctrl-A */
|
||||
|
@ -3080,17 +3120,24 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
|
|||
{
|
||||
ME_Style *style = ME_GetInsertStyle(editor, 0);
|
||||
ME_SaveTempStyle(editor);
|
||||
ME_ContinueCoalescingTransaction(editor);
|
||||
if (wstr == '\r' && (GetKeyState(VK_SHIFT) & 0x8000))
|
||||
ME_InsertEndRowFromCursor(editor, 0);
|
||||
else
|
||||
ME_InsertTextFromCursor(editor, 0, &wstr, 1, style);
|
||||
ME_ReleaseStyle(style);
|
||||
ME_CommitUndo(editor);
|
||||
ME_CommitCoalescingUndo(editor);
|
||||
}
|
||||
|
||||
if (editor->AutoURLDetect_bEnable) ME_UpdateSelectionLinkAttribute(editor);
|
||||
|
||||
ME_UpdateRepaint(editor);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
case EM_STOPGROUPTYPING:
|
||||
ME_CommitUndo(editor); /* End coalesced undos for typed characters */
|
||||
return 0;
|
||||
case EM_SCROLL: /* fall through */
|
||||
case WM_VSCROLL:
|
||||
{
|
||||
|
@ -3449,9 +3496,11 @@ int ME_GetTextW(ME_TextEditor *editor, WCHAR *buffer, int nStart, int nChars, in
|
|||
CopyMemory(buffer, item->member.run.strText->szData + nStart, sizeof(WCHAR)*nLen);
|
||||
nChars -= nLen;
|
||||
nWritten += nLen;
|
||||
if (!nChars)
|
||||
return nWritten;
|
||||
buffer += nLen;
|
||||
if (!nChars) {
|
||||
*buffer = 0;
|
||||
return nWritten;
|
||||
}
|
||||
nStart = 0;
|
||||
item = ME_FindItemFwd(item, diRun);
|
||||
}
|
||||
|
@ -3713,3 +3762,277 @@ int ME_AutoURLDetect(ME_TextEditor *editor, WCHAR curChar)
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static BOOL isurlspecial(WCHAR c)
|
||||
{
|
||||
static const WCHAR special_chars[] = {'.','/','%','@','*','|','\\','+','#',0};
|
||||
return strchrW( special_chars, c ) != NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* This proc takes a selection, and scans it forward in order to select the span
|
||||
* of a possible URL candidate. A possible URL candidate must start with isalnum
|
||||
* or one of the following special characters: *|/\+%#@ and must consist entirely
|
||||
* of the characters allowed to start the URL, plus : (colon) which may occur
|
||||
* at most once, and not at either end.
|
||||
*
|
||||
* sel_max == -1 indicates scan to end of text.
|
||||
*/
|
||||
BOOL ME_FindNextURLCandidate(ME_TextEditor *editor, int sel_min, int sel_max,
|
||||
int * candidate_min, int * candidate_max)
|
||||
{
|
||||
ME_DisplayItem * item;
|
||||
ME_DisplayItem * para;
|
||||
int nStart;
|
||||
BOOL foundColon = FALSE;
|
||||
WCHAR lastAcceptedChar = '\0';
|
||||
|
||||
TRACE("sel_min = %d sel_max = %d\n", sel_min, sel_max);
|
||||
|
||||
*candidate_min = *candidate_max = -1;
|
||||
item = ME_FindItemAtOffset(editor, diRun, sel_min, &nStart);
|
||||
if (!item) return FALSE;
|
||||
TRACE("nStart = %d\n", nStart);
|
||||
para = ME_GetParagraph(item);
|
||||
if (sel_max == -1) sel_max = ME_GetTextLength(editor);
|
||||
while (item && para->member.para.nCharOfs + item->member.run.nCharOfs + nStart < sel_max)
|
||||
{
|
||||
ME_DisplayItem * next_item;
|
||||
|
||||
if (!(item->member.run.nFlags & MERF_ENDPARA)) {
|
||||
/* Find start of candidate */
|
||||
if (*candidate_min == -1) {
|
||||
while (nStart < ME_StrLen(item->member.run.strText) &&
|
||||
!(isalnumW(item->member.run.strText->szData[nStart]) ||
|
||||
isurlspecial(item->member.run.strText->szData[nStart]))) {
|
||||
nStart++;
|
||||
}
|
||||
if (nStart < ME_StrLen(item->member.run.strText) &&
|
||||
(isalnumW(item->member.run.strText->szData[nStart]) ||
|
||||
isurlspecial(item->member.run.strText->szData[nStart]))) {
|
||||
*candidate_min = para->member.para.nCharOfs + item->member.run.nCharOfs + nStart;
|
||||
lastAcceptedChar = item->member.run.strText->szData[nStart];
|
||||
nStart++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Find end of candidate */
|
||||
if (*candidate_min >= 0) {
|
||||
while (nStart < ME_StrLen(item->member.run.strText) &&
|
||||
(isalnumW(item->member.run.strText->szData[nStart]) ||
|
||||
isurlspecial(item->member.run.strText->szData[nStart]) ||
|
||||
(!foundColon && item->member.run.strText->szData[nStart] == ':') )) {
|
||||
if (item->member.run.strText->szData[nStart] == ':') foundColon = TRUE;
|
||||
lastAcceptedChar = item->member.run.strText->szData[nStart];
|
||||
nStart++;
|
||||
}
|
||||
if (nStart < ME_StrLen(item->member.run.strText) &&
|
||||
!(isalnumW(item->member.run.strText->szData[nStart]) ||
|
||||
isurlspecial(item->member.run.strText->szData[nStart]) )) {
|
||||
*candidate_max = para->member.para.nCharOfs + item->member.run.nCharOfs + nStart;
|
||||
nStart++;
|
||||
if (lastAcceptedChar == ':') (*candidate_max)--;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* End of paragraph: skip it if before candidate span, or terminates
|
||||
current active span */
|
||||
if (*candidate_min >= 0) {
|
||||
*candidate_max = para->member.para.nCharOfs + item->member.run.nCharOfs;
|
||||
if (lastAcceptedChar == ':') (*candidate_max)--;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Reaching this point means no span was found, so get next span */
|
||||
next_item = ME_FindItemFwd(item, diRun);
|
||||
if (!next_item) {
|
||||
if (*candidate_min >= 0) {
|
||||
/* There are no further runs, so take end of text as end of candidate */
|
||||
*candidate_max = para->member.para.nCharOfs + item->member.run.nCharOfs + nStart;
|
||||
if (lastAcceptedChar == ':') (*candidate_max)--;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
item = next_item;
|
||||
para = ME_GetParagraph(item);
|
||||
nStart = 0;
|
||||
}
|
||||
|
||||
if (item) {
|
||||
if (*candidate_min >= 0) {
|
||||
/* There are no further runs, so take end of text as end of candidate */
|
||||
*candidate_max = para->member.para.nCharOfs + item->member.run.nCharOfs + nStart;
|
||||
if (lastAcceptedChar == ':') (*candidate_max)--;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* This proc evaluates the selection and returns TRUE if it can be considered an URL
|
||||
*/
|
||||
BOOL ME_IsCandidateAnURL(ME_TextEditor *editor, int sel_min, int sel_max)
|
||||
{
|
||||
struct prefix_s {
|
||||
const char *text;
|
||||
int length;
|
||||
} prefixes[12] = {
|
||||
/* Code below depends on these being in decreasing length order! */
|
||||
{"prospero:", 10},
|
||||
{"telnet:", 8},
|
||||
{"gopher:", 8},
|
||||
{"mailto:", 8},
|
||||
{"https:", 7},
|
||||
{"file:", 6},
|
||||
{"news:", 6},
|
||||
{"wais:", 6},
|
||||
{"nntp:", 6},
|
||||
{"http:", 5},
|
||||
{"www.", 5},
|
||||
{"ftp:", 5},
|
||||
};
|
||||
LPWSTR bufferW = NULL;
|
||||
WCHAR bufW[32];
|
||||
int i;
|
||||
|
||||
if (sel_max == -1) sel_max = ME_GetTextLength(editor);
|
||||
assert(sel_min <= sel_max);
|
||||
for (i = 0; i < sizeof(prefixes) / sizeof(struct prefix_s); i++)
|
||||
{
|
||||
if (sel_max - sel_min < prefixes[i].length) continue;
|
||||
if (bufferW == NULL) {
|
||||
bufferW = (LPWSTR)heap_alloc((sel_max - sel_min + 1) * sizeof(WCHAR));
|
||||
}
|
||||
ME_GetTextW(editor, bufferW, sel_min, min(sel_max - sel_min, strlen(prefixes[i].text)), 0);
|
||||
MultiByteToWideChar(CP_ACP, 0, prefixes[i].text, -1, bufW, 32);
|
||||
if (!lstrcmpW(bufW, bufferW))
|
||||
{
|
||||
heap_free(bufferW);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
heap_free(bufferW);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* This proc walks through the indicated selection and evaluates whether each
|
||||
* section identified by ME_FindNextURLCandidate and in-between sections have
|
||||
* their proper CFE_LINK attributes set or unset. If the CFE_LINK attribute is
|
||||
* not what it is supposed to be, this proc sets or unsets it as appropriate.
|
||||
*
|
||||
* Returns TRUE if at least one section was modified.
|
||||
*/
|
||||
BOOL ME_UpdateLinkAttribute(ME_TextEditor *editor, int sel_min, int sel_max)
|
||||
{
|
||||
BOOL modified = FALSE;
|
||||
int cMin, cMax;
|
||||
|
||||
if (sel_max == -1) sel_max = ME_GetTextLength(editor);
|
||||
do
|
||||
{
|
||||
int beforeURL[2];
|
||||
int inURL[2];
|
||||
CHARFORMAT2W link;
|
||||
|
||||
if (ME_FindNextURLCandidate(editor, sel_min, sel_max, &cMin, &cMax))
|
||||
{
|
||||
/* Section before candidate is not an URL */
|
||||
beforeURL[0] = sel_min;
|
||||
beforeURL[1] = cMin;
|
||||
|
||||
if (ME_IsCandidateAnURL(editor, cMin, cMax))
|
||||
{
|
||||
inURL[0] = cMin; inURL[1] = cMax;
|
||||
}
|
||||
else
|
||||
{
|
||||
beforeURL[1] = cMax;
|
||||
inURL[0] = inURL[1] = -1;
|
||||
}
|
||||
sel_min = cMax;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No more candidates until end of selection */
|
||||
beforeURL[0] = sel_min;
|
||||
beforeURL[1] = sel_max;
|
||||
inURL[0] = inURL[1] = -1;
|
||||
sel_min = sel_max;
|
||||
}
|
||||
|
||||
if (beforeURL[0] < beforeURL[1])
|
||||
{
|
||||
/* CFE_LINK effect should be consistently unset */
|
||||
link.cbSize = sizeof(link);
|
||||
ME_GetCharFormat(editor, beforeURL[0], beforeURL[1], &link);
|
||||
if (!(link.dwMask & CFM_LINK) || (link.dwEffects & CFE_LINK))
|
||||
{
|
||||
/* CFE_LINK must be unset from this range */
|
||||
memset(&link, 0, sizeof(CHARFORMAT2W));
|
||||
link.cbSize = sizeof(link);
|
||||
link.dwMask = CFM_LINK;
|
||||
link.dwEffects = 0;
|
||||
ME_SetCharFormat(editor, beforeURL[0], beforeURL[1] - beforeURL[0], &link);
|
||||
modified = TRUE;
|
||||
}
|
||||
}
|
||||
if (inURL[0] < inURL[1])
|
||||
{
|
||||
/* CFE_LINK effect should be consistently set */
|
||||
link.cbSize = sizeof(link);
|
||||
ME_GetCharFormat(editor, inURL[0], inURL[1], &link);
|
||||
if (!(link.dwMask & CFM_LINK) || !(link.dwEffects & CFE_LINK))
|
||||
{
|
||||
/* CFE_LINK must be set on this range */
|
||||
memset(&link, 0, sizeof(CHARFORMAT2W));
|
||||
link.cbSize = sizeof(link);
|
||||
link.dwMask = CFM_LINK;
|
||||
link.dwEffects = CFE_LINK;
|
||||
ME_SetCharFormat(editor, inURL[0], inURL[1] - inURL[0], &link);
|
||||
modified = TRUE;
|
||||
}
|
||||
}
|
||||
} while (sel_min < sel_max);
|
||||
return modified;
|
||||
}
|
||||
|
||||
void ME_UpdateSelectionLinkAttribute(ME_TextEditor *editor)
|
||||
{
|
||||
ME_DisplayItem * startPara, * endPara;
|
||||
ME_DisplayItem * item;
|
||||
int dummy;
|
||||
int from, to;
|
||||
|
||||
ME_GetSelection(editor, &from, &to);
|
||||
if (from > to) from ^= to, to ^=from, from ^= to;
|
||||
startPara = NULL; endPara = NULL;
|
||||
|
||||
/* Find paragraph previous to the one that contains start cursor */
|
||||
item = ME_FindItemAtOffset(editor, diRun, from, &dummy);
|
||||
if (item) {
|
||||
startPara = ME_FindItemBack(item, diParagraph);
|
||||
item = ME_FindItemBack(startPara, diParagraph);
|
||||
if (item) startPara = item;
|
||||
}
|
||||
|
||||
/* Find paragraph that contains end cursor */
|
||||
item = ME_FindItemAtOffset(editor, diRun, to, &dummy);
|
||||
if (item) {
|
||||
endPara = ME_FindItemFwd(item, diParagraph);
|
||||
}
|
||||
|
||||
if (startPara && endPara) {
|
||||
ME_UpdateLinkAttribute(editor,
|
||||
startPara->member.para.nCharOfs,
|
||||
endPara->member.para.nCharOfs);
|
||||
} else if (startPara) {
|
||||
ME_UpdateLinkAttribute(editor,
|
||||
startPara->member.para.nCharOfs,
|
||||
-1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -181,7 +181,7 @@ void ME_HideCaret(ME_TextEditor *ed);
|
|||
void ME_ShowCaret(ME_TextEditor *ed);
|
||||
void ME_MoveCaret(ME_TextEditor *ed);
|
||||
int ME_CharFromPos(ME_TextEditor *editor, int x, int y);
|
||||
void ME_LButtonDown(ME_TextEditor *editor, int x, int y);
|
||||
void ME_LButtonDown(ME_TextEditor *editor, int x, int y, int clickNum);
|
||||
void ME_MouseMove(ME_TextEditor *editor, int x, int y);
|
||||
void ME_DeleteTextAtCursor(ME_TextEditor *editor, int nCursor, int nChars);
|
||||
void ME_InsertTextFromCursor(ME_TextEditor *editor, int nCursor,
|
||||
|
@ -214,8 +214,6 @@ void ME_DestroyContext(ME_Context *c, HWND release);
|
|||
BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor);
|
||||
void ME_InvalidateMarkedParagraphs(ME_TextEditor *editor);
|
||||
void ME_SendRequestResize(ME_TextEditor *editor, BOOL force);
|
||||
int ME_twips2pointsX(ME_Context *c, int x);
|
||||
int ME_twips2pointsY(ME_Context *c, int y);
|
||||
|
||||
/* para.c */
|
||||
ME_DisplayItem *ME_GetParagraph(ME_DisplayItem *run);
|
||||
|
@ -244,6 +242,8 @@ void ME_EnsureVisible(ME_TextEditor *editor, ME_DisplayItem *pRun);
|
|||
void ME_InvalidateSelection(ME_TextEditor *editor);
|
||||
void ME_QueueInvalidateFromCursor(ME_TextEditor *editor, int nCursor);
|
||||
BOOL ME_SetZoom(ME_TextEditor *editor, int numerator, int denominator);
|
||||
int ME_twips2pointsX(ME_Context *c, int x);
|
||||
int ME_twips2pointsY(ME_Context *c, int y);
|
||||
|
||||
/* scroll functions in paint.c */
|
||||
|
||||
|
@ -279,12 +279,19 @@ void ME_StreamInFill(ME_InStream *stream);
|
|||
int ME_AutoURLDetect(ME_TextEditor *editor, WCHAR curChar);
|
||||
extern int me_debug;
|
||||
extern void DoWrap(ME_TextEditor *editor);
|
||||
extern BOOL ME_FindNextURLCandidate(ME_TextEditor *editor, int sel_min, int sel_max,
|
||||
int * candidate_min, int * candidate_max);
|
||||
extern BOOL ME_IsCandidateAnURL(ME_TextEditor *editor, int sel_min, int sel_max);
|
||||
BOOL ME_UpdateLinkAttribute(ME_TextEditor *editor, int sel_min, int sel_max);
|
||||
void ME_UpdateSelectionLinkAttribute(ME_TextEditor *editor);
|
||||
|
||||
/* undo.c */
|
||||
ME_UndoItem *ME_AddUndoItem(ME_TextEditor *editor, ME_DIType type, const ME_DisplayItem *pdi);
|
||||
void ME_CommitUndo(ME_TextEditor *editor);
|
||||
void ME_Undo(ME_TextEditor *editor);
|
||||
void ME_Redo(ME_TextEditor *editor);
|
||||
void ME_ContinueCoalescingTransaction(ME_TextEditor *editor);
|
||||
void ME_CommitCoalescingUndo(ME_TextEditor *editor);
|
||||
BOOL ME_Undo(ME_TextEditor *editor);
|
||||
BOOL ME_Redo(ME_TextEditor *editor);
|
||||
void ME_EmptyUndoStack(ME_TextEditor *editor);
|
||||
|
||||
/* writer.c */
|
||||
|
|
|
@ -85,10 +85,13 @@ typedef enum {
|
|||
diUndoSplitParagraph, /* 14 */
|
||||
diUndoSetParagraphFormat, /* 15 */
|
||||
diUndoSetCharFormat, /* 16 */
|
||||
diUndoEndTransaction, /* 17 */
|
||||
diUndoEndTransaction, /* 17 - marks the end of a group of changes for undo */
|
||||
diUndoSetDefaultCharFormat, /* 18 */
|
||||
diUndoPotentialEndTransaction, /* 19 - allows grouping typed chars for undo */
|
||||
} ME_DIType;
|
||||
|
||||
#define SELECTIONBAR_WIDTH 9
|
||||
|
||||
/******************************** run flags *************************/
|
||||
#define MERF_STYLEFLAGS 0x0FFF
|
||||
/* run contains non-text content, which has its own rules for wrapping, sizing etc */
|
||||
|
|
|
@ -169,6 +169,7 @@ const char *ME_GetDITypeName(ME_DIType type)
|
|||
case diTextEnd: return "diTextEnd";
|
||||
case diStartRow: return "diStartRow";
|
||||
case diUndoEndTransaction: return "diUndoEndTransaction";
|
||||
case diUndoPotentialEndTransaction: return "diUndoPotentialEndTransaction";
|
||||
case diUndoSetParagraphFormat: return "diUndoSetParagraphFormat";
|
||||
case diUndoSetCharFormat: return "diUndoSetCharFormat";
|
||||
case diUndoInsertRun: return "diUndoInsertRun";
|
||||
|
|
|
@ -98,7 +98,8 @@ void ME_Repaint(ME_TextEditor *editor)
|
|||
ME_UpdateScrollBar(editor);
|
||||
FIXME("ME_Repaint had to call ME_WrapMarkedParagraphs\n");
|
||||
}
|
||||
ME_SendOldNotify(editor, EN_UPDATE);
|
||||
if (!editor->bEmulateVersion10 || (editor->nEventMask & ENM_UPDATE))
|
||||
ME_SendOldNotify(editor, EN_UPDATE);
|
||||
UpdateWindow(editor->hWnd);
|
||||
}
|
||||
|
||||
|
@ -288,7 +289,7 @@ static void ME_DrawRun(ME_Context *c, int x, int y, ME_DisplayItem *rundi, ME_Pa
|
|||
}
|
||||
}
|
||||
|
||||
static struct {unsigned width_num : 4, width_den : 4, pen_style : 4, dble : 1;} border_details[] = {
|
||||
static const struct {unsigned width_num : 4, width_den : 4, pen_style : 4, dble : 1;} border_details[] = {
|
||||
/* none */ {0, 1, PS_SOLID, FALSE},
|
||||
/* 3/4 */ {3, 4, PS_SOLID, FALSE},
|
||||
/* 1 1/2 */ {3, 2, PS_SOLID, FALSE},
|
||||
|
@ -303,7 +304,7 @@ static struct {unsigned width_num : 4, width_den : 4, pen_style : 4, dble : 1;}
|
|||
/* 1 1/2 dashed */ {3, 2, PS_DASH, FALSE},
|
||||
};
|
||||
|
||||
static COLORREF pen_colors[16] = {
|
||||
static const COLORREF pen_colors[16] = {
|
||||
/* Black */ RGB(0x00, 0x00, 0x00), /* Blue */ RGB(0x00, 0x00, 0xFF),
|
||||
/* Cyan */ RGB(0x00, 0xFF, 0xFF), /* Green */ RGB(0x00, 0xFF, 0x00),
|
||||
/* Magenta */ RGB(0xFF, 0x00, 0xFF), /* Red */ RGB(0xFF, 0x00, 0x00),
|
||||
|
@ -675,7 +676,7 @@ void ME_Scroll(ME_TextEditor *editor, int value, int type)
|
|||
|
||||
si.nMin = 0;
|
||||
si.nMax = editor->nTotalLength;
|
||||
|
||||
|
||||
si.nPage = editor->sizeWindow.cy;
|
||||
|
||||
TRACE("min=%d max=%d page=%d\n", si.nMin, si.nMax, si.nPage);
|
||||
|
|
|
@ -52,7 +52,8 @@ void ME_MakeFirstParagraph(ME_TextEditor *editor)
|
|||
|
||||
cf.dwEffects = CFE_AUTOCOLOR | CFE_AUTOBACKCOLOR;
|
||||
lstrcpyW(cf.szFaceName, lf.lfFaceName);
|
||||
cf.yHeight = ME_twips2pointsY(&c, lf.lfHeight);
|
||||
/* Convert system font height from logical units to twips for cf.yHeight */
|
||||
cf.yHeight = (lf.lfHeight * 72 * 1440) / (c.dpi.cy * c.dpi.cy);
|
||||
if (lf.lfWeight > FW_NORMAL) cf.dwEffects |= CFE_BOLD;
|
||||
cf.wWeight = lf.lfWeight;
|
||||
if (lf.lfItalic) cf.dwEffects |= CFE_ITALIC;
|
||||
|
@ -104,7 +105,7 @@ void ME_MarkForWrapping(ME_TextEditor *editor, ME_DisplayItem *first, const ME_D
|
|||
|
||||
void ME_MarkForPainting(ME_TextEditor *editor, ME_DisplayItem *first, const ME_DisplayItem *last)
|
||||
{
|
||||
while(first != last)
|
||||
while(first != last && first)
|
||||
{
|
||||
first->member.para.nFlags |= MEPF_REPAINT;
|
||||
first = first->member.para.next_para;
|
||||
|
|
|
@ -638,14 +638,16 @@ static void _RTFGetToken2(RTF_Info *info)
|
|||
{
|
||||
int c2;
|
||||
|
||||
if ((c = GetChar (info)) != EOF && (c2 = GetChar (info)) != EOF)
|
||||
if ((c = GetChar (info)) != EOF && (c2 = GetChar (info)) != EOF
|
||||
&& isxdigit(c) && isxdigit(c2))
|
||||
{
|
||||
/* should do isxdigit check! */
|
||||
info->rtfClass = rtfText;
|
||||
info->rtfMajor = RTFCharToHex (c) * 16 + RTFCharToHex (c2);
|
||||
return;
|
||||
}
|
||||
/* early eof, whoops (class is rtfUnknown) */
|
||||
/* early eof, whoops */
|
||||
info->rtfClass = rtfEOF;
|
||||
info->stream->editstream->dwError = -14;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2665,10 +2667,10 @@ RTFPutUnicodeString(RTF_Info *info, const WCHAR *string, int length)
|
|||
|
||||
memmove(info->OutputBuffer + info->dwOutputCount, string, fit * sizeof(WCHAR));
|
||||
info->dwOutputCount += fit;
|
||||
if (fit == sizeof(info->OutputBuffer) / sizeof(WCHAR) - info->dwOutputCount)
|
||||
RTFFlushUnicodeOutputBuffer(info);
|
||||
length -= fit;
|
||||
string += fit;
|
||||
if (sizeof(info->OutputBuffer) / sizeof(WCHAR) == info->dwOutputCount)
|
||||
RTFFlushUnicodeOutputBuffer(info);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,14 +8,6 @@
|
|||
<define name="__WINESRC__" />
|
||||
<define name="WINVER">0x600</define>
|
||||
<define name="_WIN32_WINNT">0x600</define>
|
||||
<library>wine</library>
|
||||
<library>ole32</library>
|
||||
<library>imm32</library>
|
||||
<library>user32</library>
|
||||
<library>gdi32</library>
|
||||
<library>kernel32</library>
|
||||
<library>uuid</library>
|
||||
<library>ntdll</library>
|
||||
<file>caret.c</file>
|
||||
<file>clipboard.c</file>
|
||||
<file>context.c</file>
|
||||
|
@ -35,5 +27,13 @@
|
|||
<file>writer.c</file>
|
||||
<file>version.rc</file>
|
||||
<file>riched20.spec</file>
|
||||
<library>wine</library>
|
||||
<library>uuid</library>
|
||||
<library>ole32</library>
|
||||
<library>imm32</library>
|
||||
<library>user32</library>
|
||||
<library>gdi32</library>
|
||||
<library>kernel32</library>
|
||||
<library>ntdll</library>
|
||||
</module>
|
||||
</group>
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -241,11 +241,7 @@ void ME_JoinRuns(ME_TextEditor *editor, ME_DisplayItem *p)
|
|||
assert(p->member.run.nCharOfs != -1);
|
||||
ME_GetParagraph(p)->member.para.nFlags |= MEPF_REWRAP;
|
||||
|
||||
/* if we were at the end of screen line, and the next run is in the new
|
||||
* line, then it's not the end of the line anymore */
|
||||
if (editor->bCaretAtEnd && editor->pCursors[0].pRun == pNext)
|
||||
editor->bCaretAtEnd = FALSE;
|
||||
/* Update all cursors so that they don't contain the soon deleted run */
|
||||
/* Update all cursors so that they don't contain the soon deleted run */
|
||||
for (i=0; i<editor->nCursors; i++) {
|
||||
if (editor->pCursors[i].pRun == pNext) {
|
||||
editor->pCursors[i].pRun = p;
|
||||
|
@ -682,9 +678,9 @@ static SIZE ME_GetRunSizeCommon(ME_Context *c, const ME_Paragraph *para, ME_Run
|
|||
}
|
||||
else
|
||||
{
|
||||
pos += 720-(pos%720);
|
||||
pos += lDefaultTab - (pos % lDefaultTab);
|
||||
}
|
||||
ppos = ME_twips2pointsX(c, pos);
|
||||
ppos = ME_twips2pointsX(c, pos) + c->editor->selofs;
|
||||
if (ppos > startx + run->pt.x) {
|
||||
size.cx = ppos - startx - run->pt.x;
|
||||
break;
|
||||
|
@ -838,6 +834,7 @@ void ME_SetDefaultCharFormat(ME_TextEditor *editor, CHARFORMAT2W *mod)
|
|||
ME_Style *style;
|
||||
ME_UndoItem *undo;
|
||||
|
||||
/* FIXME: Should this be removed? It breaks a test. */
|
||||
assert(mod->cbSize == sizeof(CHARFORMAT2W));
|
||||
undo = ME_AddUndoItem(editor, diUndoSetDefaultCharFormat, NULL);
|
||||
if (undo) {
|
||||
|
@ -857,6 +854,16 @@ void ME_SetDefaultCharFormat(ME_TextEditor *editor, CHARFORMAT2W *mod)
|
|||
static void ME_GetRunCharFormat(ME_TextEditor *editor, ME_DisplayItem *run, CHARFORMAT2W *pFmt)
|
||||
{
|
||||
ME_CopyCharFormat(pFmt, &run->member.run.style->fmt);
|
||||
if ((pFmt->dwMask & CFM_UNDERLINETYPE) && (pFmt->bUnderlineType == CFU_CF1UNDERLINE))
|
||||
{
|
||||
pFmt->dwMask |= CFM_UNDERLINE;
|
||||
pFmt->dwEffects |= CFE_UNDERLINE;
|
||||
}
|
||||
if ((pFmt->dwMask & CFM_UNDERLINETYPE) && (pFmt->bUnderlineType == CFU_UNDERLINENONE))
|
||||
{
|
||||
pFmt->dwMask |= CFM_UNDERLINE;
|
||||
pFmt->dwEffects &= ~CFE_UNDERLINE;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
@ -928,7 +935,7 @@ void ME_GetCharFormat(ME_TextEditor *editor, int nFrom, int nTo, CHARFORMAT2W *p
|
|||
do {
|
||||
/* FIXME add more style feature comparisons */
|
||||
int nAttribs = CFM_SIZE | CFM_FACE | CFM_COLOR | CFM_UNDERLINETYPE;
|
||||
int nEffects = CFM_BOLD | CFM_ITALIC;
|
||||
int nEffects = CFM_BOLD | CFM_ITALIC | CFM_UNDERLINE | CFM_STRIKEOUT | CFM_PROTECTED | CFM_LINK | CFM_SUPERSCRIPT;
|
||||
|
||||
run = ME_FindItemFwd(run, diRun);
|
||||
|
||||
|
@ -937,7 +944,6 @@ void ME_GetCharFormat(ME_TextEditor *editor, int nFrom, int nTo, CHARFORMAT2W *p
|
|||
ME_GetRunCharFormat(editor, run, &tmp);
|
||||
|
||||
assert((tmp.dwMask & nAttribs) == nAttribs);
|
||||
assert((tmp.dwMask & nEffects) == nEffects);
|
||||
/* reset flags that differ */
|
||||
|
||||
if (pFmt->yHeight != tmp.yHeight)
|
||||
|
@ -964,6 +970,7 @@ void ME_GetCharFormat(ME_TextEditor *editor, int nFrom, int nTo, CHARFORMAT2W *p
|
|||
}
|
||||
|
||||
pFmt->dwMask &= ~((pFmt->dwEffects ^ tmp.dwEffects) & nEffects);
|
||||
pFmt->dwEffects = tmp.dwEffects;
|
||||
|
||||
} while(run != run_end);
|
||||
}
|
||||
|
|
|
@ -128,7 +128,7 @@ ME_String *ME_VSplitString(ME_String *orig, int charidx)
|
|||
assert(charidx>=0);
|
||||
assert(charidx<=orig->nLen);
|
||||
|
||||
s = ME_MakeString(orig->szData+charidx);
|
||||
s = ME_MakeStringN(orig->szData+charidx, orig->nLen-charidx);
|
||||
orig->nLen = charidx;
|
||||
orig->szData[charidx] = '\0';
|
||||
return s;
|
||||
|
@ -317,18 +317,10 @@ ME_WordBreakProc(LPWSTR s, INT start, INT len, INT code)
|
|||
return start;
|
||||
case WB_RIGHT:
|
||||
case WB_MOVEWORDRIGHT:
|
||||
if (start && ME_IsWSpace(s[start - 1]))
|
||||
{
|
||||
while (start < len && ME_IsWSpace(s[start]))
|
||||
start++;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (start < len && !ME_IsWSpace(s[start]))
|
||||
start++;
|
||||
while (start < len && ME_IsWSpace(s[start]))
|
||||
start++;
|
||||
}
|
||||
while (start < len && !ME_IsWSpace(s[start]))
|
||||
start++;
|
||||
while (start < len && ME_IsWSpace(s[start]))
|
||||
start++;
|
||||
return start;
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -221,6 +221,15 @@ ME_Style *ME_ApplyStyle(ME_Style *sSrc, CHARFORMAT2W *style)
|
|||
s->fmt.bUnderlineType = (style->dwEffects & CFM_UNDERLINE) ?
|
||||
CFU_CF1UNDERLINE : CFU_UNDERLINENONE;
|
||||
}
|
||||
if (style->dwMask & CFM_BOLD && !(style->dwMask & CFM_WEIGHT))
|
||||
{
|
||||
s->fmt.wWeight = (style->dwEffects & CFE_BOLD) ? FW_BOLD : FW_NORMAL;
|
||||
} else if (style->dwMask & CFM_WEIGHT && !(style->dwMask & CFM_BOLD)) {
|
||||
if (style->wWeight > FW_NORMAL)
|
||||
s->fmt.dwEffects |= CFE_BOLD;
|
||||
else
|
||||
s->fmt.dwEffects &= ~CFE_BOLD;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
|
|
|
@ -59,6 +59,10 @@ ME_UndoItem *ME_AddUndoItem(ME_TextEditor *editor, ME_DIType type, const ME_Disp
|
|||
((ME_UndoItem *)pItem)->nCR = ((ME_UndoItem *)pItem)->nLF = -1;
|
||||
switch(type)
|
||||
{
|
||||
case diUndoPotentialEndTransaction:
|
||||
/* only should be added for manually typed chars, not undos or redos */
|
||||
assert(editor->nUndoMode == umAddToUndo);
|
||||
/* intentional fall-through to next case */
|
||||
case diUndoEndTransaction:
|
||||
break;
|
||||
case diUndoSetParagraphFormat:
|
||||
|
@ -99,13 +103,18 @@ ME_UndoItem *ME_AddUndoItem(ME_TextEditor *editor, ME_DIType type, const ME_Disp
|
|||
pItem->prev = NULL;
|
||||
if (editor->nUndoMode == umAddToUndo || editor->nUndoMode == umAddBackToUndo)
|
||||
{
|
||||
if (editor->pUndoStack
|
||||
&& editor->pUndoStack->type == diUndoPotentialEndTransaction)
|
||||
{
|
||||
editor->pUndoStack->type = diUndoEndTransaction;
|
||||
}
|
||||
if (editor->nUndoMode == umAddToUndo)
|
||||
TRACE("Pushing id=%s to undo stack, deleting redo stack\n", ME_GetDITypeName(type));
|
||||
else
|
||||
TRACE("Pushing id=%s to undo stack\n", ME_GetDITypeName(type));
|
||||
|
||||
pItem->next = editor->pUndoStack;
|
||||
if (type == diUndoEndTransaction)
|
||||
if (type == diUndoEndTransaction || type == diUndoPotentialEndTransaction)
|
||||
editor->nUndoStackSize++;
|
||||
if (editor->pUndoStack)
|
||||
editor->pUndoStack->prev = pItem;
|
||||
|
@ -154,6 +163,18 @@ ME_UndoItem *ME_AddUndoItem(ME_TextEditor *editor, ME_DIType type, const ME_Disp
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Commits preceding changes into a transaction that can be undone together.
|
||||
*
|
||||
* This should be called after all the changes occur associated with an event
|
||||
* so that the group of changes can be undone atomically as a transaction.
|
||||
*
|
||||
* This will have no effect the undo mode is set to ignore changes, or if no
|
||||
* changes preceded calling this function before the last time it was called.
|
||||
*
|
||||
* This can also be used to conclude a coalescing transaction (used for grouping
|
||||
* typed characters).
|
||||
*/
|
||||
void ME_CommitUndo(ME_TextEditor *editor) {
|
||||
if (editor->nUndoMode == umIgnore)
|
||||
return;
|
||||
|
@ -168,10 +189,84 @@ void ME_CommitUndo(ME_TextEditor *editor) {
|
|||
if (editor->pUndoStack->type == diUndoEndTransaction)
|
||||
return;
|
||||
|
||||
if (editor->pUndoStack->type == diUndoPotentialEndTransaction)
|
||||
{
|
||||
/* Previous transaction was as a result of characters typed,
|
||||
* so the end of this transaction is confirmed. */
|
||||
editor->pUndoStack->type = diUndoEndTransaction;
|
||||
return;
|
||||
}
|
||||
|
||||
ME_AddUndoItem(editor, diUndoEndTransaction, NULL);
|
||||
ME_SendSelChange(editor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Groups supsequent changes with previous ones for an undo if coalescing.
|
||||
*
|
||||
* Has no effect if the previous changes were followed by a ME_CommitUndo. This
|
||||
* function will only have an affect if the previous changes were followed by
|
||||
* a call to ME_CommitCoalescingUndo, which allows the transaction to be
|
||||
* continued.
|
||||
*
|
||||
* This allows multiple consecutively typed characters to be grouped together
|
||||
* to be undone by a single undo operation.
|
||||
*/
|
||||
void ME_ContinueCoalescingTransaction(ME_TextEditor *editor)
|
||||
{
|
||||
ME_DisplayItem* p;
|
||||
|
||||
if (editor->nUndoMode == umIgnore)
|
||||
return;
|
||||
|
||||
assert(editor->nUndoMode == umAddToUndo);
|
||||
|
||||
p = editor->pUndoStack;
|
||||
|
||||
if (p && p->type == diUndoPotentialEndTransaction) {
|
||||
assert(p->next); /* EndTransactions shouldn't be at bottom of undo stack */
|
||||
editor->pUndoStack = p->next;
|
||||
editor->pUndoStack->prev = NULL;
|
||||
editor->nUndoStackSize--;
|
||||
ME_DestroyDisplayItem(p);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Commits preceding changes into a undo transaction that can be expanded.
|
||||
*
|
||||
* This function allows the transaction to be reopened with
|
||||
* ME_ContinueCoalescingTransaction in order to continue the transaction. If an
|
||||
* undo item is added to the undo stack as a result of a change without the
|
||||
* transaction being reopened, then the transaction will be ended, and the
|
||||
* changes will become a part of the next transaction.
|
||||
*
|
||||
* This is used to allow typed characters to be grouped together since each
|
||||
* typed character results in a single event, and each event adding undo items
|
||||
* must be committed. Using this function as opposed to ME_CommitUndo allows
|
||||
* multiple events to be grouped, and undone together.
|
||||
*/
|
||||
void ME_CommitCoalescingUndo(ME_TextEditor *editor)
|
||||
{
|
||||
if (editor->nUndoMode == umIgnore)
|
||||
return;
|
||||
|
||||
assert(editor->nUndoMode == umAddToUndo);
|
||||
|
||||
/* no transactions, no need to commit */
|
||||
if (!editor->pUndoStack)
|
||||
return;
|
||||
|
||||
/* no need to commit empty transactions */
|
||||
if (editor->pUndoStack->type == diUndoEndTransaction)
|
||||
return;
|
||||
if (editor->pUndoStack->type == diUndoPotentialEndTransaction)
|
||||
return;
|
||||
|
||||
ME_AddUndoItem(editor, diUndoPotentialEndTransaction, NULL);
|
||||
ME_SendSelChange(editor);
|
||||
}
|
||||
|
||||
static void ME_PlayUndoItem(ME_TextEditor *editor, ME_DisplayItem *pItem)
|
||||
{
|
||||
ME_UndoItem *pUItem = (ME_UndoItem *)pItem;
|
||||
|
@ -182,6 +277,7 @@ static void ME_PlayUndoItem(ME_TextEditor *editor, ME_DisplayItem *pItem)
|
|||
|
||||
switch(pItem->type)
|
||||
{
|
||||
case diUndoPotentialEndTransaction:
|
||||
case diUndoEndTransaction:
|
||||
assert(0);
|
||||
case diUndoSetParagraphFormat:
|
||||
|
@ -239,50 +335,53 @@ static void ME_PlayUndoItem(ME_TextEditor *editor, ME_DisplayItem *pItem)
|
|||
}
|
||||
}
|
||||
|
||||
void ME_Undo(ME_TextEditor *editor) {
|
||||
BOOL ME_Undo(ME_TextEditor *editor) {
|
||||
ME_DisplayItem *p;
|
||||
ME_UndoMode nMode = editor->nUndoMode;
|
||||
|
||||
if (editor->nUndoMode == umIgnore)
|
||||
return;
|
||||
return FALSE;
|
||||
assert(nMode == umAddToUndo || nMode == umIgnore);
|
||||
|
||||
/* no undo items ? */
|
||||
if (!editor->pUndoStack)
|
||||
return;
|
||||
return FALSE;
|
||||
|
||||
/* watch out for uncommitted transactions ! */
|
||||
assert(editor->pUndoStack->type == diUndoEndTransaction);
|
||||
assert(editor->pUndoStack->type == diUndoEndTransaction
|
||||
|| editor->pUndoStack->type == diUndoPotentialEndTransaction);
|
||||
|
||||
editor->nUndoMode = umAddToRedo;
|
||||
p = editor->pUndoStack->next;
|
||||
ME_DestroyDisplayItem(editor->pUndoStack);
|
||||
do {
|
||||
ME_DisplayItem *pp = p;
|
||||
ME_PlayUndoItem(editor, p);
|
||||
p = p->next;
|
||||
ME_DestroyDisplayItem(pp);
|
||||
} while(p && p->type != diUndoEndTransaction);
|
||||
ME_AddUndoItem(editor, diUndoEndTransaction, NULL);
|
||||
editor->pUndoStack = p;
|
||||
editor->nUndoStackSize--;
|
||||
do {
|
||||
p->prev = NULL;
|
||||
ME_PlayUndoItem(editor, p);
|
||||
editor->pUndoStack = p->next;
|
||||
ME_DestroyDisplayItem(p);
|
||||
p = editor->pUndoStack;
|
||||
} while(p && p->type != diUndoEndTransaction);
|
||||
if (p)
|
||||
p->prev = NULL;
|
||||
ME_AddUndoItem(editor, diUndoEndTransaction, NULL);
|
||||
editor->nUndoStackSize--;
|
||||
editor->nUndoMode = nMode;
|
||||
ME_UpdateRepaint(editor);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void ME_Redo(ME_TextEditor *editor) {
|
||||
BOOL ME_Redo(ME_TextEditor *editor) {
|
||||
ME_DisplayItem *p;
|
||||
ME_UndoMode nMode = editor->nUndoMode;
|
||||
|
||||
assert(nMode == umAddToUndo || nMode == umIgnore);
|
||||
|
||||
if (editor->nUndoMode == umIgnore)
|
||||
return;
|
||||
return FALSE;
|
||||
/* no redo items ? */
|
||||
if (!editor->pRedoStack)
|
||||
return;
|
||||
return FALSE;
|
||||
|
||||
/* watch out for uncommitted transactions ! */
|
||||
assert(editor->pRedoStack->type == diUndoEndTransaction);
|
||||
|
@ -290,16 +389,18 @@ void ME_Redo(ME_TextEditor *editor) {
|
|||
editor->nUndoMode = umAddBackToUndo;
|
||||
p = editor->pRedoStack->next;
|
||||
ME_DestroyDisplayItem(editor->pRedoStack);
|
||||
do {
|
||||
ME_DisplayItem *pp = p;
|
||||
ME_PlayUndoItem(editor, p);
|
||||
p = p->next;
|
||||
ME_DestroyDisplayItem(pp);
|
||||
} while(p && p->type != diUndoEndTransaction);
|
||||
ME_AddUndoItem(editor, diUndoEndTransaction, NULL);
|
||||
editor->pRedoStack = p;
|
||||
do {
|
||||
p->prev = NULL;
|
||||
ME_PlayUndoItem(editor, p);
|
||||
editor->pRedoStack = p->next;
|
||||
ME_DestroyDisplayItem(p);
|
||||
p = editor->pRedoStack;
|
||||
} while(p && p->type != diUndoEndTransaction);
|
||||
if (p)
|
||||
p->prev = NULL;
|
||||
ME_AddUndoItem(editor, diUndoEndTransaction, NULL);
|
||||
editor->nUndoMode = nMode;
|
||||
ME_UpdateRepaint(editor);
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -58,21 +58,47 @@ static void ME_BeginRow(ME_WrapContext *wc)
|
|||
static void ME_InsertRowStart(ME_WrapContext *wc, const ME_DisplayItem *pEnd)
|
||||
{
|
||||
ME_DisplayItem *p, *row, *para;
|
||||
BOOL bSkippingSpaces = TRUE;
|
||||
int ascent = 0, descent = 0, width=0, shift = 0, align = 0;
|
||||
/* wrap text */
|
||||
para = ME_GetParagraph(wc->pRowStart);
|
||||
for (p = wc->pRowStart; p!=pEnd; p = p->next)
|
||||
|
||||
for (p = pEnd->prev; p!=wc->pRowStart->prev; p = p->prev)
|
||||
{
|
||||
/* ENDPARA run shouldn't affect row height, except if it's the only run in the paragraph */
|
||||
if (p->type==diRun && ((p==wc->pRowStart) || !(p->member.run.nFlags & MERF_ENDPARA))) { /* FIXME add more run types */
|
||||
if (p->member.run.nAscent>ascent)
|
||||
ascent = p->member.run.nAscent;
|
||||
if (p->member.run.nDescent>descent)
|
||||
descent = p->member.run.nDescent;
|
||||
if (!(p->member.run.nFlags & (MERF_ENDPARA|MERF_SKIPPED)))
|
||||
width += p->member.run.nWidth;
|
||||
}
|
||||
/* ENDPARA run shouldn't affect row height, except if it's the only run in the paragraph */
|
||||
if (p->type==diRun && ((p==wc->pRowStart) || !(p->member.run.nFlags & MERF_ENDPARA))) { /* FIXME add more run types */
|
||||
if (p->member.run.nAscent>ascent)
|
||||
ascent = p->member.run.nAscent;
|
||||
if (p->member.run.nDescent>descent)
|
||||
descent = p->member.run.nDescent;
|
||||
if (bSkippingSpaces)
|
||||
{
|
||||
/* Exclude space characters from run width.
|
||||
* Other whitespace or delimiters are not treated this way. */
|
||||
SIZE sz;
|
||||
int len = p->member.run.strText->nLen;
|
||||
WCHAR *text = p->member.run.strText->szData + len - 1;
|
||||
|
||||
assert (len);
|
||||
while (len && *(text--) == ' ')
|
||||
len--;
|
||||
if (len)
|
||||
{
|
||||
if (len == p->member.run.strText->nLen)
|
||||
{
|
||||
width += p->member.run.nWidth;
|
||||
} else {
|
||||
sz = ME_GetRunSize(wc->context, ¶->member.para,
|
||||
&p->member.run, len, p->member.run.pt.x);
|
||||
width += sz.cx;
|
||||
}
|
||||
}
|
||||
bSkippingSpaces = !len;
|
||||
} else if (!(p->member.run.nFlags & MERF_ENDPARA))
|
||||
width += p->member.run.nWidth;
|
||||
}
|
||||
}
|
||||
|
||||
row = ME_MakeRow(ascent+descent, ascent, width);
|
||||
row->member.row.nYPos = wc->pt.y;
|
||||
row->member.row.nLMargin = (!wc->nRow ? wc->nFirstMargin : wc->nLeftMargin);
|
||||
|
@ -98,7 +124,7 @@ static void ME_InsertRowStart(ME_WrapContext *wc, const ME_DisplayItem *pEnd)
|
|||
static void ME_WrapEndParagraph(ME_WrapContext *wc, ME_DisplayItem *p)
|
||||
{
|
||||
if (wc->pRowStart)
|
||||
ME_InsertRowStart(wc, p->next);
|
||||
ME_InsertRowStart(wc, p);
|
||||
|
||||
/*
|
||||
p = p->member.para.prev_para->next;
|
||||
|
@ -471,6 +497,7 @@ BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor) {
|
|||
ME_Context c;
|
||||
BOOL bModified = FALSE;
|
||||
int yStart = -1;
|
||||
int yLastPos = 0;
|
||||
|
||||
ME_InitContext(&c, editor, GetDC(editor->hWnd));
|
||||
editor->nHeight = 0;
|
||||
|
@ -496,6 +523,7 @@ BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor) {
|
|||
|
||||
bModified = bModified | bRedraw;
|
||||
|
||||
yLastPos = c.pt.y;
|
||||
c.pt.y += item->member.para.nHeight;
|
||||
item = item->member.para.next_para;
|
||||
}
|
||||
|
@ -503,6 +531,7 @@ BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor) {
|
|||
editor->sizeWindow.cy = c.rcView.bottom-c.rcView.top;
|
||||
|
||||
editor->nTotalLength = c.pt.y;
|
||||
editor->pBuffer->pLast->member.para.nYPos = yLastPos;
|
||||
|
||||
ME_DestroyContext(&c, editor->hWnd);
|
||||
|
||||
|
|
|
@ -32,6 +32,14 @@ extern "C" {
|
|||
|
||||
#define cchTextLimitDefault 0x7fff
|
||||
|
||||
#if defined(__GNUC__)
|
||||
# define MSFTEDIT_CLASS (const WCHAR []){ 'R','i','c','h','E','d','i','t','5','0','W',0 }
|
||||
#elif defined(_MSC_VER)
|
||||
# define MSFTEDIT_CLASS L"RichEdit50W"
|
||||
#else
|
||||
static const WCHAR MSFTEDIT_CLASS[] = { 'R','i','c','h','E','d','i','t','5','0','W',0 };
|
||||
#endif
|
||||
|
||||
#define RICHEDIT_CLASS20A "RichEdit20A"
|
||||
#if defined(__GNUC__)
|
||||
# define RICHEDIT_CLASS20W (const WCHAR []){ 'R','i','c','h','E','d','i','t','2','0','W',0 }
|
||||
|
@ -48,6 +56,26 @@ static const WCHAR RICHEDIT_CLASS20W[] = { 'R','i','c','h','E','d','i','t','2','
|
|||
#define RICHEDIT_CLASS RICHEDIT_CLASS10A
|
||||
#endif
|
||||
|
||||
#ifndef WM_NOTIFY
|
||||
#define WM_NOTIFY 0x004e
|
||||
#endif
|
||||
#ifndef WM_CONTEXTMENU
|
||||
#define WM_CONTEXTMENU 0x007b
|
||||
#endif
|
||||
#ifndef WM_UNICHAR
|
||||
#define WM_UNICHAR 0x0109
|
||||
#endif
|
||||
#ifndef WM_PRINTCLIENT
|
||||
#define WM_PRINTCLIENT 0x0318
|
||||
#endif
|
||||
|
||||
#ifndef EM_GETLIMITTEXT
|
||||
#define EM_GETLIMITTEXT (WM_USER + 37)
|
||||
#endif
|
||||
#ifndef EM_POSFROMCHAR
|
||||
#define EM_POSFROMCHAR (WM_USER + 38)
|
||||
#define EM_CHARFROMPOS (WM_USER + 39)
|
||||
#endif
|
||||
#ifndef EM_SCROLLCARET
|
||||
#define EM_SCROLLCARET (WM_USER + 49)
|
||||
#endif
|
||||
|
@ -139,6 +167,24 @@ static const WCHAR RICHEDIT_CLASS20W[] = { 'R','i','c','h','E','d','i','t','2','
|
|||
#define EM_SETFONTSIZE (WM_USER + 223)
|
||||
#define EM_GETZOOM (WM_USER + 224)
|
||||
#define EM_SETZOOM (WM_USER + 225)
|
||||
#define EM_GETVIEWKIND (WM_USER + 226)
|
||||
#define EM_SETVIEWKIND (WM_USER + 227)
|
||||
|
||||
#define EM_GETPAGE (WM_USER + 228)
|
||||
#define EM_SETPAGE (WM_USER + 229)
|
||||
#define EM_GETHYPHENATEINFO (WM_USER + 230)
|
||||
#define EM_SETHYPHENATEINFO (WM_USER + 231)
|
||||
#define EM_GETPAGEROTATE (WM_USER + 235)
|
||||
#define EM_SETPAGEROTATE (WM_USER + 236)
|
||||
#define EM_GETCTFMODEBIAS (WM_USER + 237)
|
||||
#define EM_SETCTFMODEBIAS (WM_USER + 238)
|
||||
#define EM_GETCTFOPENSTATUS (WM_USER + 240)
|
||||
#define EM_SETCTFOPENSTATUS (WM_USER + 241)
|
||||
#define EM_GETIMECOMPTEXT (WM_USER + 242)
|
||||
#define EM_ISIME (WM_USER + 243)
|
||||
#define EM_GETIMEPROPERTY (WM_USER + 244)
|
||||
#define EM_GETQUERYRTFOBJ (WM_USER + 269)
|
||||
#define EM_SETQUERYRTFOBJ (WM_USER + 270)
|
||||
|
||||
/* New notifications */
|
||||
#define EN_MSGFILTER 0x0700
|
||||
|
@ -155,16 +201,25 @@ static const WCHAR RICHEDIT_CLASS20W[] = { 'R','i','c','h','E','d','i','t','2','
|
|||
#define EN_LINK 0x070b
|
||||
#define EN_DRAGDROPDONE 0x070c
|
||||
#define EN_PARAGRAPHEXPANDED 0x070d
|
||||
#define EN_PAGECHANGE 0x070e
|
||||
#define EN_LOWFIRTF 0x070f
|
||||
#define EN_ALIGNLTR 0x0710
|
||||
#define EN_ALIGNRTL 0x0711
|
||||
|
||||
|
||||
typedef DWORD (CALLBACK * EDITSTREAMCALLBACK)( DWORD_PTR, LPBYTE, LONG, LONG * );
|
||||
|
||||
|
||||
#define yHeightCharPtsMost 1638
|
||||
#define lDefaultTab 720
|
||||
|
||||
/* tab stops number limit */
|
||||
#define MAX_TAB_STOPS 0x00000020
|
||||
|
||||
#define MAX_TABLE_CELLS 63
|
||||
|
||||
/* Rich edit control styles */
|
||||
#define ES_NOOLEDRAGDROP 0x00000008
|
||||
#define ES_DISABLENOSCROLL 0x00002000
|
||||
#define ES_SUNKEN 0x00004000
|
||||
#define ES_SAVESEL 0x00008000
|
||||
|
@ -180,6 +235,18 @@ typedef DWORD (CALLBACK * EDITSTREAMCALLBACK)( DWORD_PTR, LPBYTE, LONG, LONG * )
|
|||
#define SCF_WORD 0x00000002
|
||||
#define SCF_ALL 0x00000004
|
||||
#define SCF_USEUIRULES 0x00000008
|
||||
#define SCF_ASSOCIATEFONT 0x00000010
|
||||
#define SCF_NOKBUPDATE 0x00000020
|
||||
#define SCF_ASSOCIATEFONT2 0x00000040
|
||||
|
||||
#ifndef WM_NOTIFY
|
||||
typedef struct _nmhdr
|
||||
{
|
||||
HWND hwndFrom;
|
||||
UINT idFrom;
|
||||
UINT code;
|
||||
} NMHDR;
|
||||
#endif
|
||||
|
||||
/* CHARFORMAT structure */
|
||||
typedef struct _charformat
|
||||
|
@ -208,6 +275,8 @@ typedef struct _charformatw
|
|||
WCHAR szFaceName[LF_FACESIZE];
|
||||
} CHARFORMATW;
|
||||
|
||||
DECL_WINELIB_TYPE_AW(CHARFORMAT)
|
||||
|
||||
typedef struct _charformat2a {
|
||||
UINT cbSize;
|
||||
DWORD dwMask;
|
||||
|
@ -252,6 +321,10 @@ typedef struct _charformat2w {
|
|||
BYTE bRevAuthor;
|
||||
} CHARFORMAT2W;
|
||||
|
||||
DECL_WINELIB_TYPE_AW(CHARFORMAT2)
|
||||
|
||||
#define CHARFORMATDELTA (sizeof(CHARFORMAT2) - sizeof(CHARFORMAT))
|
||||
|
||||
/* CHARFORMAT masks */
|
||||
#define CFM_BOLD 0x00000001
|
||||
#define CFM_ITALIC 0x00000002
|
||||
|
@ -284,7 +357,47 @@ typedef struct _charformat2w {
|
|||
#define CFM_FACE 0x20000000
|
||||
#define CFM_COLOR 0x40000000
|
||||
#define CFM_SIZE 0x80000000
|
||||
#define CFM_EFFECTS (CFM_BOLD | CFM_ITALIC | CFM_UNDERLINE | CFM_COLOR | CFM_STRIKEOUT | CFE_PROTECTED | CFM_LINK)
|
||||
|
||||
#define CFM_EFFECTS (CFM_BOLD | \
|
||||
CFM_ITALIC | \
|
||||
CFM_UNDERLINE | \
|
||||
CFM_COLOR | \
|
||||
CFM_STRIKEOUT | \
|
||||
CFE_PROTECTED | \
|
||||
CFM_LINK)
|
||||
|
||||
#define CFM_EFFECTS2 (CFM_EFFECTS | \
|
||||
CFM_DISABLED | \
|
||||
CFM_SMALLCAPS | \
|
||||
CFM_ALLCAPS | \
|
||||
CFM_HIDDEN | \
|
||||
CFM_OUTLINE | \
|
||||
CFM_SHADOW | \
|
||||
CFM_EMBOSS | \
|
||||
CFM_IMPRINT | \
|
||||
CFM_DISABLED | \
|
||||
CFM_REVISED | \
|
||||
CFM_SUBSCRIPT | \
|
||||
CFM_SUPERSCRIPT | \
|
||||
CFM_BACKCOLOR)
|
||||
|
||||
#define CFM_ALL (CFM_EFFECTS | \
|
||||
CFM_SIZE | \
|
||||
CFM_FACE | \
|
||||
CFM_OFFSET | \
|
||||
CFM_CHARSET)
|
||||
|
||||
#define CFM_ALL2 (CFM_ALL | \
|
||||
CFM_EFFECTS2 | \
|
||||
CFM_BACKCOLOR | \
|
||||
CFM_LCID | \
|
||||
CFM_UNDERLINETYPE | \
|
||||
CFM_WEIGHT | \
|
||||
CFM_REVAUTHOR | \
|
||||
CFM_SPACING | \
|
||||
CFM_KERNING | \
|
||||
CFM_STYLE | \
|
||||
CFM_ANIMATION)
|
||||
|
||||
/* CHARFORMAT effects */
|
||||
#define CFE_BOLD 0x00000001
|
||||
|
@ -308,13 +421,27 @@ typedef struct _charformat2w {
|
|||
#define CFE_REVISED CFM_REVISED
|
||||
#define CFE_AUTOBACKCOLOR CFM_BACKCOLOR
|
||||
|
||||
#define CFU_CF1UNDERLINE 0xFF
|
||||
#define CFU_INVERT 0xFE
|
||||
#define CFU_UNDERLINEDOTTED 0x04
|
||||
#define CFU_UNDERLINEDOUBLE 0x03
|
||||
#define CFU_UNDERLINEWORD 0x02
|
||||
#define CFU_UNDERLINE 0x01
|
||||
#define CFU_UNDERLINENONE 0x00
|
||||
#define CFU_UNDERLINENONE 0x00
|
||||
#define CFU_UNDERLINE 0x01
|
||||
#define CFU_UNDERLINEWORD 0x02
|
||||
#define CFU_UNDERLINEDOUBLE 0x03
|
||||
#define CFU_UNDERLINEDOTTED 0x04
|
||||
#define CFU_UNDERLINEDASH 0x05
|
||||
#define CFU_UNDERLINEDASHDOT 0x06
|
||||
#define CFU_UNDERLINEDASHDOTDOT 0x07
|
||||
#define CFU_UNDERLINEWAVE 0x08
|
||||
#define CFU_UNDERLINETHICK 0x09
|
||||
#define CFU_UNDERLINEHAIRLINE 0x0a
|
||||
#define CFU_UNDERLINEDOUBLEWAVE 0x0b
|
||||
#define CFU_UNDERLINEHEAVYWAVE 0x0c
|
||||
#define CFU_UNDERLINELONGDASH 0x0d
|
||||
#define CFU_UNDERLINETHICKDASH 0x0e
|
||||
#define CFU_UNDERLINETHICKDASHDOT 0x0f
|
||||
#define CFU_UNDERLINETHICKDASHDOTDOT 0x10
|
||||
#define CFU_UNDERLINETHICKDOTTED 0x11
|
||||
#define CFU_UNDERLINETHICKLONGDASH 0x12
|
||||
#define CFU_INVERT 0xFE
|
||||
#define CFU_CF1UNDERLINE 0xFF
|
||||
|
||||
/* ECO operations */
|
||||
#define ECOOP_SET 0x0001
|
||||
|
@ -338,6 +465,10 @@ typedef struct _charformat2w {
|
|||
#define ENM_CHANGE 0x00000001
|
||||
#define ENM_UPDATE 0x00000002
|
||||
#define ENM_SCROLL 0x00000004
|
||||
#define ENM_SCROLLEVENTS 0x00000008
|
||||
#define ENM_DRAGDROPDONE 0x00000010
|
||||
#define ENM_PARAGRAPHEXPANDED 0x00000020
|
||||
#define ENM_PAGECHANGE 0x00000040
|
||||
#define ENM_KEYEVENTS 0x00010000
|
||||
#define ENM_MOUSEEVENTS 0x00020000
|
||||
#define ENM_REQUESTRESIZE 0x00040000
|
||||
|
@ -346,7 +477,17 @@ typedef struct _charformat2w {
|
|||
#define ENM_PROTECTED 0x00200000
|
||||
#define ENM_CORRECTTEXT 0x00400000
|
||||
#define ENM_IMECHANGE 0x00800000
|
||||
#define ENM_LANGCHANGE 0x01000000
|
||||
#define ENM_OBJECTPOSITIONS 0x02000000
|
||||
#define ENM_LINK 0x04000000
|
||||
#define ENM_LOWFIRTF 0x08000000
|
||||
|
||||
typedef struct _bidioptions
|
||||
{
|
||||
UINT cbSize;
|
||||
WORD wMask;
|
||||
WORD wEffects;
|
||||
} BIDIOPTIONS;
|
||||
|
||||
#ifndef __RICHEDIT_CHARRANGE_DEFINED
|
||||
#define __RICHEDIT_CHARRANGE_DEFINED
|
||||
|
@ -371,6 +512,8 @@ typedef struct _textrangew
|
|||
LPWSTR lpstrText;
|
||||
} TEXTRANGEW;
|
||||
|
||||
DECL_WINELIB_TYPE_AW(TEXTRANGE)
|
||||
|
||||
typedef struct _editstream
|
||||
{
|
||||
DWORD dwCookie;
|
||||
|
@ -405,6 +548,11 @@ typedef struct _enlink {
|
|||
CHARRANGE chrg;
|
||||
} ENLINK;
|
||||
|
||||
typedef struct _enlowfirtf {
|
||||
NMHDR nmhdr;
|
||||
char *szControl;
|
||||
} ENLOWFIRTF;
|
||||
|
||||
typedef struct {
|
||||
NMHDR nmhdr;
|
||||
LONG iob;
|
||||
|
@ -436,6 +584,8 @@ typedef struct _findtextW {
|
|||
LPCWSTR lpstrText;
|
||||
} FINDTEXTW;
|
||||
|
||||
DECL_WINELIB_TYPE_AW(FINDTEXT)
|
||||
|
||||
typedef struct _findtextexA {
|
||||
CHARRANGE chrg;
|
||||
LPCSTR lpstrText;
|
||||
|
@ -448,6 +598,8 @@ typedef struct _findtextexW {
|
|||
CHARRANGE chrgText;
|
||||
} FINDTEXTEXW;
|
||||
|
||||
DECL_WINELIB_TYPE_AW(FINDTEXTEX)
|
||||
|
||||
typedef struct _formatrange {
|
||||
HDC hdc;
|
||||
HDC hdcTarget;
|
||||
|
@ -456,6 +608,31 @@ typedef struct _formatrange {
|
|||
CHARRANGE chrg;
|
||||
} FORMATRANGE;
|
||||
|
||||
typedef enum tagKHYPH
|
||||
{
|
||||
khyphNil = 0,
|
||||
khyphNormal = 1,
|
||||
khyphAddBefore = 2,
|
||||
khyphChangeBefore = 3,
|
||||
khyphDeleteBefore = 4,
|
||||
khyphChangeAfter = 5,
|
||||
khyphDelAndChange = 6
|
||||
} KHYPH;
|
||||
|
||||
typedef struct hyphresult
|
||||
{
|
||||
KHYPH khyph;
|
||||
long ichHyph;
|
||||
WCHAR chHyph;
|
||||
} HYPHRESULT;
|
||||
|
||||
typedef struct tagHyphenateInfo
|
||||
{
|
||||
SHORT cbSize;
|
||||
SHORT dxHyphenateZone;
|
||||
void (WINAPI* pfnHyphenate)(WCHAR*, LANGID, long, HYPHRESULT*);
|
||||
} HYPHENATEINFO;
|
||||
|
||||
typedef struct _msgfilter {
|
||||
NMHDR nmhdr;
|
||||
UINT msg;
|
||||
|
@ -463,6 +640,12 @@ typedef struct _msgfilter {
|
|||
LPARAM lParam;
|
||||
} MSGFILTER;
|
||||
|
||||
typedef struct _objectpositions {
|
||||
NMHDR nmhdr;
|
||||
LONG cObjectCount;
|
||||
LONG *pcpPositions;
|
||||
} OBJECTPOSITIONS;
|
||||
|
||||
typedef struct _paraformat {
|
||||
UINT cbSize;
|
||||
DWORD dwMask;
|
||||
|
@ -524,6 +707,13 @@ typedef struct _gettextex {
|
|||
LPBOOL lpUsedDefChar;
|
||||
} GETTEXTEX;
|
||||
|
||||
typedef struct _imecomptext {
|
||||
LONG cb;
|
||||
DWORD flags;
|
||||
} IMECOMPTEXT;
|
||||
|
||||
void WINAPI HyphenateProc(WCHAR*, LANGID, long, HYPHRESULT*);
|
||||
|
||||
#define SF_TEXT 0x00000001
|
||||
#define SF_RTF 0x00000002
|
||||
#define SF_RTFNOOBJS 0x00000003
|
||||
|
@ -533,11 +723,86 @@ typedef struct _gettextex {
|
|||
#define SF_NCRFORNONASCII 0x00000040
|
||||
#define SF_RTFVAL 0x00000700
|
||||
|
||||
/* BIDIOPTIONS.wMask flag values */
|
||||
#define BOM_DEFPARADIR 0x00000001
|
||||
#define BOM_PLAINTEXT 0x00000002
|
||||
#define BOM_NEUTRALOVERRIDE 0x00000004
|
||||
#define BOM_CONTEXTREADING 0x00000008
|
||||
#define BOM_CONTEXTALIGNMENT 0x00000010
|
||||
#define BOM_LEGACYBIDICLASS 0x00000040
|
||||
|
||||
/* BIDIOPTIONS.wEffects flag values */
|
||||
#define BOE_RTLDIR 0x00000001
|
||||
#define BOE_PLAINTEXT 0x00000002
|
||||
#define BOE_NEUTRALOVERRIDE 0x00000004
|
||||
#define BOE_CONTEXTREADING 0x00000008
|
||||
#define BOE_CONTEXTALIGNMENT 0x00000010
|
||||
#define BOE_LEGACYBIDICLASS 0x00000040
|
||||
|
||||
/* Clipboard formats */
|
||||
#define CF_RTF TEXT("Rich Text Format")
|
||||
#define CF_RTFNOOBJS TEXT("Rich Text Format Without Objects")
|
||||
#define CF_RETEXTOBJ TEXT("RichEdit Text and Objects")
|
||||
|
||||
/* Mode bias wParam values for EM_SETCTFMODEBIAS message */
|
||||
#define CTFMODEBIAS_DEFAULT 0x00000000
|
||||
#define CTFMODEBIAS_FILENAME 0x00000001
|
||||
#define CTFMODEBIAS_NAME 0x00000002
|
||||
#define CTFMODEBIAS_READING 0x00000003
|
||||
#define CTFMODEBIAS_DATETIME 0x00000004
|
||||
#define CTFMODEBIAS_CONVERSATION 0x00000005
|
||||
#define CTFMODEBIAS_NUMERIC 0x00000006
|
||||
#define CTFMODEBIAS_HIRAGANA 0x00000007
|
||||
#define CTFMODEBIAS_KATAKANA 0x00000008
|
||||
#define CTFMODEBIAS_HANGUL 0x00000009
|
||||
#define CTFMODEBIAS_HALFWIDTHKATAKANA 0x0000000a
|
||||
#define CTFMODEBIAS_FULLWIDTHALPHANUMERIC 0x0000000b
|
||||
#define CTFMODEBIAS_HALFWIDTHALPHANUMERIC 0x0000000c
|
||||
|
||||
#define EMO_EXIT 0x00000000
|
||||
#define EMO_ENTER 0x00000001
|
||||
#define EMO_PROMOTE 0x00000002
|
||||
#define EMO_EXPAND 0x00000003
|
||||
#define EMO_MOVESELECTION 0x00000004
|
||||
#define EMO_GETVIEWMODE 0x00000005
|
||||
|
||||
#define EMO_EXPANDSELECTION 0x00000000
|
||||
#define EMO_EXPANDDOCUMENT 0x00000001
|
||||
|
||||
/* Page Rotate values used in wParam of EM_SETPAGEROTATE message */
|
||||
#define EPR_0 0x00000000
|
||||
#define EPR_270 0x00000001
|
||||
#define EPR_180 0x00000002
|
||||
#define EPR_90 0x00000003
|
||||
|
||||
/* Find flags for wParam of EM_FINDTEXT message */
|
||||
#define FR_MATCHDIAC 0x20000000
|
||||
#define FR_MATCHKASHIDA 0x40000000
|
||||
#define FR_MATCHALEFHAMZA 0x80000000
|
||||
|
||||
/* IME Compatibility Mode return values for EM_GETIMECOMPMODE message */
|
||||
#define ICM_NOTOPEN 0x00000000
|
||||
#define ICM_LEVEL3 0x00000001
|
||||
#define ICM_LEVEL2 0x00000002
|
||||
#define ICM_LEVEL2_5 0x00000003
|
||||
#define ICM_LEVEL2_SUI 0x00000004
|
||||
#define ICM_CTF 0x00000005
|
||||
|
||||
/* Flags value for IMECOMPTEXT structure */
|
||||
#define ICT_RESULTREADSTR 0x00000001
|
||||
|
||||
/* Input Method Flags used in EM_SETLANGOPTIONS message */
|
||||
#define IMF_AUTOKEYBOARD 0x00000001
|
||||
#define IMF_AUTOFONT 0x00000002
|
||||
#define IMF_IMECANCELCOMPLETE 0x00000004
|
||||
#define IMF_IMEALWAYSSENDNOTIFY 0x00000008
|
||||
#define IMF_AUTOFONTSIZEADJUST 0x00000010
|
||||
#define IMF_UIFONTS 0x00000020
|
||||
#define IMF_DUALFONT 0x00000080
|
||||
|
||||
/* Parameters values for the EM_SETIMEMODEBIAS message */
|
||||
#define IMF_SMODE_PLAURALCLAUSE 0x00000001
|
||||
#define IMF_SMODE_NONE 0x00000002
|
||||
|
||||
/* Parameters of the EM_SETIMEOPTIONS message */
|
||||
#define IMF_FORCENONE 0x00000001
|
||||
|
@ -548,6 +813,7 @@ typedef struct _gettextex {
|
|||
#define IMF_FORCEACTIVE 0x00000040
|
||||
#define IMF_FORCEINACTIVE 0x00000080
|
||||
#define IMF_FORCEREMEMBER 0x00000100
|
||||
#define IMF_MULTIPLEEDIT 0x00000400
|
||||
|
||||
/* return values of the EM_SELECTION_TYPE message */
|
||||
#define SEL_EMPTY 0x00000000
|
||||
|
@ -556,6 +822,15 @@ typedef struct _gettextex {
|
|||
#define SEL_MULTICHAR 0x00000004
|
||||
#define SEL_MULTIOBJECT 0x00000008
|
||||
|
||||
/* ENOLEOPFAILED.lOper value that indicates operation failure */
|
||||
#define OLEOP_DOVERB 0x00000001
|
||||
|
||||
/* punctionation type values for wParam of EM_SETPUNCTUATION message */
|
||||
#define PC_FOLLOWING 0x00000001
|
||||
#define PC_LEADING 0x00000002
|
||||
#define PC_OVERFLOW 0x00000003
|
||||
#define PC_DELIMITER 0x00000004
|
||||
|
||||
/* mask values in the PARAFORMAT structure */
|
||||
#define PFM_STARTINDENT 0x00000001
|
||||
#define PFM_RIGHTINDENT 0x00000002
|
||||
|
@ -572,7 +847,6 @@ typedef struct _gettextex {
|
|||
#define PFM_STYLE 0x00000400
|
||||
#define PFM_BORDER 0x00000800
|
||||
#define PFM_SHADING 0x00001000
|
||||
|
||||
#define PFM_NUMBERINGSTYLE 0x00002000
|
||||
#define PFM_NUMBERINGTAB 0x00004000
|
||||
#define PFM_NUMBERINGSTART 0x00008000
|
||||
|
@ -584,10 +858,61 @@ typedef struct _gettextex {
|
|||
#define PFM_NOWIDOWCONTROL 0x00200000
|
||||
#define PFM_DONOTHYPHEN 0x00400000
|
||||
#define PFM_SIDEBYSIDE 0x00800000
|
||||
#define PFM_COLLAPSED 0x01000000
|
||||
#define PFM_OUTLINELEVEL 0x02000000
|
||||
#define PFM_BOX 0x04000000
|
||||
#define PFM_RESERVED2 0x08000000
|
||||
#define PFM_TABLEROWDELIMITER 0x10000000
|
||||
#define PFM_TEXTWRAPPINGBREAK 0x20000000
|
||||
#define PFM_TABLE 0x40000000
|
||||
|
||||
#define PFM_ALL (PFM_STARTINDENT | \
|
||||
PFM_RIGHTINDENT | \
|
||||
PFM_OFFSET | \
|
||||
PFM_ALIGNMENT | \
|
||||
PFM_TABSTOPS | \
|
||||
PFM_NUMBERING | \
|
||||
PFM_OFFSETINDENT | \
|
||||
PFM_RTLPARA)
|
||||
|
||||
#define PFM_EFFECTS (PFM_RTLPARA | \
|
||||
PFM_KEEP | \
|
||||
PFM_KEEPNEXT | \
|
||||
PFM_PAGEBREAKBEFORE | \
|
||||
PFM_NOLINENUMBER | \
|
||||
PFM_NOWIDOWCONTROL | \
|
||||
PFM_DONOTHYPHEN | \
|
||||
PFM_SIDEBYSIDE | \
|
||||
PFM_TABLEROWDELIMITER | \
|
||||
PFM_TABLE)
|
||||
|
||||
#define PFM_ALL2 (PFM_ALL | \
|
||||
PFM_EFFECTS | \
|
||||
PFM_SPACEBEFORE | \
|
||||
PFM_SPACEAFTER | \
|
||||
PFM_LINESPACING | \
|
||||
PFM_STYLE | \
|
||||
PFM_BORDER | \
|
||||
PFM_SHADING | \
|
||||
PFM_NUMBERINGSTYLE | \
|
||||
PFM_NUMBERINGTAB | \
|
||||
PFM_NUMBERINGSTART)
|
||||
|
||||
/* numbering option */
|
||||
#define PFN_BULLET 0x00000001
|
||||
#define PFN_ARABIC 0x00000002
|
||||
#define PFN_LCLETTER 0x00000003
|
||||
#define PFN_UCLETTER 0x00000004
|
||||
#define PFN_LCROMAN 0x00000005
|
||||
#define PFN_UCROMAN 0x00000006
|
||||
|
||||
/* paragraph format numbering styles */
|
||||
#define PFNS_PAREN 0x00000000
|
||||
#define PFNS_PARENS 0x00000100
|
||||
#define PFNS_PERIOD 0x00000200
|
||||
#define PFNS_PLAIN 0x00000300
|
||||
#define PFNS_NONUMBER 0x00000400
|
||||
#define PFNS_NEWNUMBER 0x00008000
|
||||
|
||||
/* paragraph alignment */
|
||||
#define PFA_LEFT 0x00000001
|
||||
|
@ -596,6 +921,9 @@ typedef struct _gettextex {
|
|||
#define PFA_JUSTIFY 0x00000004
|
||||
#define PFA_FULL_INTERWORD 0x00000004
|
||||
#define PFA_FULL_INTERLETTER 0x00000005
|
||||
#define PFA_FULL_SCALED 0x00000006
|
||||
#define PFA_FULL_GLYPHS 0x00000007
|
||||
#define PFA_SNAP_GRID 0x00000008
|
||||
|
||||
/* paragraph effects */
|
||||
#define PFE_RTLPARA 0x00000001
|
||||
|
@ -606,17 +934,64 @@ typedef struct _gettextex {
|
|||
#define PFE_NOWIDOWCONTROL 0x00000020
|
||||
#define PFE_DONOTHYPHEN 0x00000040
|
||||
#define PFE_SIDEBYSIDE 0x00000080
|
||||
#define PFE_COLLAPSED 0x00000100
|
||||
#define PFE_BOX 0x00000400
|
||||
#define PFE_TABLEROWDELIMITER 0x00001000
|
||||
#define PFE_TEXTWRAPPINGBREAK 0x00002000
|
||||
#define PFE_TABLE 0x00004000
|
||||
|
||||
/* Set Edit Style flags for EM_SETEDITSTYLE message */
|
||||
#define SES_EMULATESYSEDIT 0x00000001
|
||||
#define SES_BEEPONMAXTEXT 0x00000002
|
||||
#define SES_EXTENDBACKCOLOR 0x00000004
|
||||
#define SES_MAPCPS 0x00000008
|
||||
#define SES_EMULATE10 0x00000010
|
||||
#define SES_USECRLF 0x00000020
|
||||
#define SES_NOXLTSYMBOLRANGE 0x00000020
|
||||
#define SES_USEAIMM 0x00000040
|
||||
#define SES_NOIME 0x00000080
|
||||
#define SES_ALLOWBEEPS 0x00000100
|
||||
#define SES_UPPERCASE 0x00000200
|
||||
#define SES_LOWERCASE 0x00000400
|
||||
#define SES_NOINPUTSEQUENCECHK 0x00000800
|
||||
#define SES_BIDI 0x00001000
|
||||
#define SES_SCROLLONKILLFOCUS 0x00002000
|
||||
#define SES_XLTCRCRLFTOCR 0x00004000
|
||||
#define SES_DRAFTMODE 0x00008000
|
||||
#define SES_USECTF 0x00010000
|
||||
#define SES_HIDEGRIDLINES 0x00020000
|
||||
#define SES_USEATFONT 0x00040000
|
||||
#define SES_CUSTOMLOOK 0x00080000
|
||||
#define SES_LBSCROLLNOTIFY 0x00100000
|
||||
#define SES_CTFALLOWEMBED 0x00200000
|
||||
#define SES_CTFALLOWSMARTTAG 0x00400000
|
||||
#define SES_CTFALLOWPROOFING 0x00800000
|
||||
|
||||
/* streaming flags */
|
||||
#define SFF_WRITEXTRAPAR 0x00000080
|
||||
#define SFF_PWD 0x00000800
|
||||
#define SFF_KEEPDOCINFO 0x00001000
|
||||
#define SFF_PERSISTVIEWSCALE 0x00002000
|
||||
#define SFF_PLAINRTF 0x00004000
|
||||
#define SFF_SELECTION 0x00008000
|
||||
|
||||
typedef enum _undonameid
|
||||
{
|
||||
UID_UNKNOWN = 0,
|
||||
UID_TYPING = 1,
|
||||
UID_DELETE = 2,
|
||||
UID_DRAGDROP = 3,
|
||||
UID_CUT = 4,
|
||||
UID_PASTE = 5,
|
||||
UID_AUTOCORRECT = 6
|
||||
} UNDONAMEID;
|
||||
|
||||
typedef LONG (*EDITWORDBREAKPROCEX)(char*,LONG,BYTE,INT);
|
||||
|
||||
#define VM_OUTLINE 0x00000002
|
||||
#define VM_NORMAL 0x00000004
|
||||
#define VM_PAGE 0x00000009
|
||||
|
||||
/* options of the EM_FINDWORDBREAK message */
|
||||
#define WB_CLASSIFY 0x00000003
|
||||
#define WB_MOVEWORDLEFT 0x00000004
|
||||
|
@ -636,6 +1011,16 @@ typedef LONG (*EDITWORDBREAKPROCEX)(char*,LONG,BYTE,INT);
|
|||
#define WBF_LEVEL2 0x00000100
|
||||
#define WBF_CUSTOM 0x00000200
|
||||
|
||||
#define WBF_CLASS ((BYTE) 0x0F)
|
||||
#define WBF_ISWHITE ((BYTE) 0x10)
|
||||
#define WBF_BREAKLINE ((BYTE) 0x20)
|
||||
#define WBF_BREAKAFTER ((BYTE) 0x40)
|
||||
|
||||
/* Placeholder unicode character for an embedded object */
|
||||
#ifndef WCH_EMBEDDING
|
||||
#define WCH_EMBEDDING (WCHAR)0xFFFC
|
||||
#endif
|
||||
|
||||
/* options of the EM_SETTEXTMODE message */
|
||||
#define TM_PLAINTEXT 0x00000001
|
||||
#define TM_RICHTEXT 0x00000002
|
||||
|
@ -648,10 +1033,14 @@ typedef LONG (*EDITWORDBREAKPROCEX)(char*,LONG,BYTE,INT);
|
|||
#define GT_DEFAULT 0x00000000
|
||||
#define GT_USECRLF 0x00000001
|
||||
#define GT_SELECTION 0x00000002
|
||||
#define GT_RAWTEXT 0x00000004
|
||||
#define GT_NOHIDDENTEXT 0x00000008
|
||||
|
||||
/* Options of the EM_SETTYPOGRAPHYOPTIONS message */
|
||||
#define TO_ADVANCEDTYPOGRAPHY 0x00000001
|
||||
#define TO_SIMPLELINEBREAK 0x00000002
|
||||
#define TO_ADVANCEDTYPOGRAPHY 0x00000001
|
||||
#define TO_SIMPLELINEBREAK 0x00000002
|
||||
#define TO_DISABLECUSTOMTEXTOUT 0x00000004
|
||||
#define TO_ADVANCEDLAYOUT 0x00000008
|
||||
|
||||
typedef struct _gettextlengthex {
|
||||
DWORD flags;
|
||||
|
@ -675,23 +1064,11 @@ typedef struct _settextex {
|
|||
} SETTEXTEX;
|
||||
|
||||
/* Flags of the EM_SETTEXTEX message */
|
||||
#define ST_DEFAULT 0x00000000
|
||||
#define ST_DEFAULT 0x00000000
|
||||
#define ST_KEEPUNDO 0x00000001
|
||||
#define ST_SELECTION 0x00000002
|
||||
|
||||
#ifdef UNICODE
|
||||
typedef CHARFORMATW CHARFORMAT;
|
||||
typedef CHARFORMAT2W CHARFORMAT2;
|
||||
typedef FINDTEXTW FINDTEXT;
|
||||
typedef FINDTEXTEXW FINDTEXTEX;
|
||||
typedef TEXTRANGEW TEXTRANGE;
|
||||
#else
|
||||
typedef CHARFORMATA CHARFORMAT;
|
||||
typedef CHARFORMAT2A CHARFORMAT2;
|
||||
typedef FINDTEXTA FINDTEXT;
|
||||
typedef FINDTEXTEXA FINDTEXTEX;
|
||||
typedef TEXTRANGEA TEXTRANGE;
|
||||
#endif
|
||||
#define ST_NEWCHARS 0x00000004
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue