📄 edit.c
字号:
break;
}
/* fall through */
case WM_CHAR:
{
WCHAR charW;
if(unicode)
charW = wParam;
else
{
CHAR charA = wParam;
MultiByteToWideChar(CP_ACP, 0, &charA, 1, &charW, 1);
}
if ((charW == VK_RETURN || charW == VK_ESCAPE) && es->hwndListBox)
{
if (SendMessageW(GetParent(hwnd), CB_GETDROPPEDSTATE, 0, 0))
SendMessageW(GetParent(hwnd), WM_KEYDOWN, charW, 0);
break;
}
EDIT_WM_Char(es, charW);
break;
}
case WM_CLEAR:
EDIT_WM_Clear(es);
break;
case WM_COMMAND:
EDIT_WM_Command(es, HIWORD(wParam), LOWORD(wParam), (HWND)lParam);
break;
case WM_CONTEXTMENU:
EDIT_WM_ContextMenu(es, (short)LOWORD(lParam), (short)HIWORD(lParam));
break;
case WM_COPY:
EDIT_WM_Copy(es);
break;
case WM_CREATE:
if(unicode)
result = EDIT_WM_Create(es, ((LPCREATESTRUCTW)lParam)->lpszName);
else
{
LPCSTR nameA = ((LPCREATESTRUCTA)lParam)->lpszName;
LPWSTR nameW = NULL;
if(nameA)
{
INT countW = MultiByteToWideChar(CP_ACP, 0, nameA, -1, NULL, 0);
if((nameW = HeapAlloc(GetProcessHeap(), 0, countW * sizeof(WCHAR))))
MultiByteToWideChar(CP_ACP, 0, nameA, -1, nameW, countW);
}
result = EDIT_WM_Create(es, nameW);
HeapFree(GetProcessHeap(), 0, nameW);
}
break;
case WM_CUT:
EDIT_WM_Cut(es);
break;
case WM_ENABLE:
es->bEnableState = (BOOL) wParam;
EDIT_UpdateText(es, NULL, TRUE);
break;
case WM_ERASEBKGND:
result = EDIT_WM_EraseBkGnd(es, (HDC)wParam);
break;
case WM_GETFONT:
result = (LRESULT)es->font;
break;
case WM_GETTEXT:
result = (LRESULT)EDIT_WM_GetText(es, (INT)wParam, (LPWSTR)lParam, unicode);
break;
case WM_GETTEXTLENGTH:
if (unicode) result = strlenW(es->text);
else result = WideCharToMultiByte( CP_ACP, 0, es->text, strlenW(es->text),
NULL, 0, NULL, NULL );
break;
case WM_HSCROLL:
result = EDIT_WM_HScroll(es, LOWORD(wParam), (short)HIWORD(wParam));
break;
case WM_KEYDOWN:
result = EDIT_WM_KeyDown(es, (INT)wParam);
break;
case WM_KILLFOCUS:
result = EDIT_WM_KillFocus(es);
break;
case WM_LBUTTONDBLCLK:
result = EDIT_WM_LButtonDblClk(es);
break;
case WM_LBUTTONDOWN:
result = EDIT_WM_LButtonDown(es, wParam, (short)LOWORD(lParam), (short)HIWORD(lParam));
break;
case WM_LBUTTONUP:
result = EDIT_WM_LButtonUp(es);
break;
case WM_MBUTTONDOWN:
result = EDIT_WM_MButtonDown(es);
break;
case WM_MOUSEMOVE:
result = EDIT_WM_MouseMove(es, (short)LOWORD(lParam), (short)HIWORD(lParam));
break;
case WM_PRINTCLIENT:
case WM_PAINT:
EDIT_WM_Paint(es, (HDC)wParam);
break;
case WM_PASTE:
EDIT_WM_Paste(es);
break;
case WM_SETFOCUS:
EDIT_WM_SetFocus(es);
break;
case WM_SETFONT:
EDIT_WM_SetFont(es, (HFONT)wParam, LOWORD(lParam) != 0);
break;
case WM_SETREDRAW:
/* FIXME: actually set an internal flag and behave accordingly */
break;
case WM_SETTEXT:
EDIT_WM_SetText(es, (LPCWSTR)lParam, unicode);
result = TRUE;
break;
case WM_SIZE:
EDIT_WM_Size(es, (UINT)wParam, LOWORD(lParam), HIWORD(lParam));
break;
case WM_STYLECHANGED:
result = EDIT_WM_StyleChanged(es, wParam, (const STYLESTRUCT *)lParam);
break;
case WM_STYLECHANGING:
result = 0; /* See EDIT_WM_StyleChanged */
break;
case WM_SYSKEYDOWN:
result = EDIT_WM_SysKeyDown(es, (INT)wParam, (DWORD)lParam);
break;
case WM_TIMER:
EDIT_WM_Timer(es);
break;
case WM_VSCROLL:
result = EDIT_WM_VScroll(es, LOWORD(wParam), (short)HIWORD(wParam));
break;
case WM_MOUSEWHEEL:
{
int gcWheelDelta = 0;
UINT pulScrollLines = 3;
SystemParametersInfoW(SPI_GETWHEELSCROLLLINES,0, &pulScrollLines, 0);
if (wParam & (MK_SHIFT | MK_CONTROL)) {
result = DefWindowProcW(hwnd, msg, wParam, lParam);
break;
}
gcWheelDelta -= GET_WHEEL_DELTA_WPARAM(wParam);
if (abs(gcWheelDelta) >= WHEEL_DELTA && pulScrollLines)
{
int cLineScroll= (int) min((UINT) es->line_count, pulScrollLines);
cLineScroll *= (gcWheelDelta / WHEEL_DELTA);
result = EDIT_EM_LineScroll(es, 0, cLineScroll);
}
}
break;
/* IME messages to make the edit control IME aware */
case WM_IME_SETCONTEXT:
break;
case WM_IME_STARTCOMPOSITION:
/*
* FIXME in IME: This message is not always sent like it should be
*/
if (es->selection_start != es->selection_end)
{
static const WCHAR empty_stringW[] = {0};
EDIT_EM_ReplaceSel(es, TRUE, empty_stringW, TRUE, TRUE);
}
es->composition_start = es->selection_end;
es->composition_len = 0;
break;
case WM_IME_COMPOSITION:
if (es->composition_len == 0)
{
if (es->selection_start != es->selection_end)
{
static const WCHAR empty_stringW[] = {0};
EDIT_EM_ReplaceSel(es, TRUE, empty_stringW, TRUE, TRUE);
}
es->composition_start = es->selection_end;
}
EDIT_ImeComposition(hwnd,lParam,es);
break;
case WM_IME_ENDCOMPOSITION:
es->composition_len= 0;
break;
case WM_IME_COMPOSITIONFULL:
break;
case WM_IME_SELECT:
break;
case WM_IME_CONTROL:
break;
default:
result = DefWindowProcT(hwnd, msg, wParam, lParam, unicode);
break;
}
if (es) EDIT_UnlockBuffer(es, FALSE);
TRACE("hwnd=%p msg=%x (%s) -- 0x%08lx\n", hwnd, msg, SPY_GetMsgName(msg, hwnd), result);
return result;
}
/*********************************************************************
*
* EditWndProcW (USER32.@)
*/
LRESULT WINAPI EditWndProcW(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
return EditWndProc_common(hWnd, uMsg, wParam, lParam, TRUE);
}
/*********************************************************************
*
* EditWndProc (USER32.@)
*/
LRESULT WINAPI EditWndProcA(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
return EditWndProc_common(hWnd, uMsg, wParam, lParam, FALSE);
}
/*********************************************************************
*
* EDIT_BuildLineDefs_ML
*
* Build linked list of text lines.
* Lines can end with '\0' (last line), a character (if it is wrapped),
* a soft return '\r\r\n' or a hard return '\r\n'
*
*/
static void EDIT_BuildLineDefs_ML(EDITSTATE *es, INT istart, INT iend, INT delta, HRGN hrgn)
{
HDC dc;
HFONT old_font = 0;
LPWSTR current_position, cp;
INT fw;
LINEDEF *current_line;
LINEDEF *previous_line;
LINEDEF *start_line;
INT line_index = 0, nstart_line = 0, nstart_index = 0;
INT line_count = es->line_count;
INT orig_net_length;
RECT rc;
if (istart == iend && delta == 0)
return;
dc = GetDC(es->hwndSelf);
if (es->font)
old_font = SelectObject(dc, es->font);
previous_line = NULL;
current_line = es->first_line_def;
/* Find starting line. istart must lie inside an existing line or
* at the end of buffer */
do {
if (istart < current_line->index + current_line->length ||
current_line->ending == END_0)
break;
previous_line = current_line;
current_line = current_line->next;
line_index++;
} while (current_line);
if (!current_line) /* Error occurred start is not inside previous buffer */
{
FIXME(" modification occurred outside buffer\n");
ReleaseDC(es->hwndSelf, dc);
return;
}
/* Remember start of modifications in order to calculate update region */
nstart_line = line_index;
nstart_index = current_line->index;
/* We must start to reformat from the previous line since the modifications
* may have caused the line to wrap upwards. */
if (!(es->style & ES_AUTOHSCROLL) && line_index > 0)
{
line_index--;
current_line = previous_line;
}
start_line = current_line;
fw = es->format_rect.right - es->format_rect.left;
current_position = es->text + current_line->index;
do {
if (current_line != start_line)
{
if (!current_line || current_line->index + delta > current_position - es->text)
{
/* The buffer has been expanded, create a new line and
insert it into the link list */
LINEDEF *new_line = HeapAlloc(GetProcessHeap(), 0, sizeof(LINEDEF));
new_line->next = previous_line->next;
previous_line->next = new_line;
current_line = new_line;
es->line_count++;
}
else if (current_line->index + delta < current_position - es->text)
{
/* The previous line merged with this line so we delete this extra entry */
previous_line->next = current_line->next;
HeapFree(GetProcessHeap(), 0, current_line);
current_line = previous_line->next;
es->line_count--;
continue;
}
else /* current_line->index + delta == current_position */
{
if (current_position - es->text > iend)
break; /* We reached end of line modifications */
/* else recalulate this line */
}
}
current_line->index = current_position - es->text;
orig_net_length = current_line->net_length;
/* Find end of line */
cp = current_position;
while (*cp) {
if (*cp == '\n') break;
if ((*cp == '\r') && (*(cp + 1) == '\n'))
break;
cp++;
}
/* Mark type of line termination */
if (!(*cp)) {
current_line->ending = END_0;
current_line->net_length = strlenW(current_position);
} else if ((cp > current_position) && (*(cp - 1) == '\r')) {
current_line->ending = END_SOFT;
current_line->net_length = cp - current_position - 1;
} else if (*cp == '\n') {
current_line->ending = END_RICH;
current_line->net_length = cp - current_position;
} else {
current_line->ending = END_HARD;
current_line->net_length = cp - current_position;
}
/* Calculate line width */
current_line->width = (INT)LOWORD(GetTabbedTextExtentW(dc,
current_position, current_line->net_length,
es->tabs_count, es->tabs));
/* FIXME: check here for lines that are too wide even in AUTOHSCROLL (> 32767 ???) */
if (!(es->style & ES_AUTOHSCROLL)) {
if (current_line->width > fw) {
INT next = 0;
INT prev;
do {
prev = next;
next = EDIT_CallWordBreakProc(es, current_position - es->text,
prev + 1, current_line->net_length, WB_RIGHT);
current_line->width = (INT)LOWORD(GetTabbedTextExtentW(dc,
current_position, next, es->tabs_count, es->tabs));
} while (current_line->width <= fw);
if (!prev) { /* Didn't find a line break so force a break */
next = 0;
do {
prev = next;
next++;
current_line->width = (INT)LOWORD(GetTabbedTextExtentW(dc,
current_position, next, es->tabs_count, es->tabs));
} while (current_line->width <= fw);
if (!prev)
prev = 1;
}
/* If the first line we are calculating, wrapped before istart, we must
* adjust istart in order for this to be reflected in the update region. */
if (current_line->index == nstart_index && istart > current_line->index + prev)
istart = current_line->index + prev;
/* else if we are updating the previous line before the first line we
* are re-calculating and it expanded */
else if (current_line == start_line &&
current_line->index != nstart_index && orig_net_length < prev)
{
/* Line expanded due to an upwards line wrap so we must partially include
* previous line in update region */
nstart_line = line_index;
nstart_index = current_line->index;
istart = current_line->index + orig_net_length;
}
current_line->net_length = prev;
current_line->ending = END_WRAP;
current_line->width = (INT)LOWORD(GetTabbedTextExtentW(dc, current_position,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -