📄 newedit.c
字号:
pSLEditData->caretX = pSLEditData->epX - pSLEditData->scrollX + pSLEditData->leftMargin; pSLEditData->caretRow = pSLEditData->epY / pSLEditData->charHeight - pSLEditData->scrollRow; if (pSLEditData->caretRow >= pSLEditData->cLines - 1) { int delta = pSLEditData->caretRow - pSLEditData->cLines + 2; pSLEditData->scrollRow += delta; pSLEditData->caretRow -= delta; } else if (pSLEditData->caretRow < 0) { pSLEditData->scrollRow += pSLEditData->caretRow; pSLEditData->caretRow = 0; } return ((lastscrollX != pSLEditData->scrollX) || (lastscrollR != pSLEditData->scrollRow) || ((pSLEditData->epFirstIdx > pfirst || pSLEditData->epLineAlign != palign) && checkNewline));}/* * Draw or calculate the text in the client area */static voidneDrawAllText(HWND hWnd, HDC hdc, PSLEDITDATA pSLEditData, int action){ DWORD dwStyle = hWnd->style; BOOL bRelDC = FALSE; RECT rc; int bkcol, fgcol; EDITCHAR *pTxt, *pEnd, *edittext; int szy; int tot = 0; int cy = 0; int cx; int ln; int xs; int idxLine; int done; unsigned long attrib = 0; if ((action & (NEDRAW_ENTIRE | NEDRAW_ROW)) && (GetFocus() == hWnd)) HideCaret(hWnd); if (hdc == NULL) { hdc = GetDC(hWnd); bRelDC = TRUE; } if (dwStyle & WS_DISABLED) bkcol = GetSysColor(COLOR_INACTIVECAPTIONTEXT); else bkcol = GetSysColor(COLOR_INFOBK); fgcol = GetSysColor(COLOR_INFOTEXT); SelectObject(hdc, pSLEditData->hFont); GetClientRect(hWnd, &rc); rc.left = pSLEditData->leftMargin - pSLEditData->scrollX; rc.top = pSLEditData->topMargin - pSLEditData->scrollRow * pSLEditData->charHeight; xs = edtGetOutWidth(hWnd); ln = pSLEditData->dataEnd; edittext = doCharShape_UC16(pSLEditData->buffer, ln, &ln, &attrib); pTxt = edittext; pEnd = pTxt + pSLEditData->dataEnd; tot = 0; SetTextColor(hdc, fgcol); SetBkColor(hdc, bkcol); SetBkMode(hdc, OPAQUE); szy = neGetTextHeight(hWnd, hdc); cx = rc.left; idxLine = 0; done = 0; while ((pTxt < pEnd) && !done) { int count; int isEditRow = 0; count = pSLEditData->dataEnd - tot; if (count > 0) { int n = count; int nl = 0; EDITCHAR *vtxt = NULL; int *v2l = NULL; char *direction = NULL; int deltay = 0, deltachr = 0; attrib &= ~TEXTIP_RTOL; if (dwStyle & ES_MULTILINE) { for (n = 0; tot + n < ln; n++) if (pTxt[n] == '\n') { deltachr = 1; break; } if (!(dwStyle & ES_AUTOHSCROLL)) { int newn = n; int wx = neGetTextWith(hWnd, hdc, pSLEditData, pTxt, newn); while ((wx > xs) && (newn > 1)) { // note that the macro isspace cause segfault on che > 255 while (newn > 1 && (pTxt[--newn] > ' ')); wx = neGetTextWith(hWnd, hdc, pSLEditData, pTxt, newn); } if ((newn < n) && (pTxt[newn] <= ' ')) n = newn, deltachr = 1; } if (n < count) deltay = szy, nl = 1; count = n; } if (attrib & TEXTIP_EXTENDED) { v2l = (int *) malloc(sizeof(int) * (1 + n)); direction = (char *) malloc(sizeof(char) * (1 + n)); vtxt = doCharBidi_UC16(pTxt, n, v2l, direction, &attrib); if ((vtxt != NULL) && (cx == rc.left) && (attrib & TEXTIP_RTOL)) cx = rc.left + xs - neGetTextWith(hWnd, hdc, pSLEditData, vtxt, n); } isEditRow = ((tot <= pSLEditData->editPos) && (pSLEditData->editPos <= tot + count)); // If this row is the one with editPos, set the index of newline if (isEditRow) { pSLEditData->epFirstIdx = tot; pSLEditData->epLineCount = count; pSLEditData->epLineOX = cx; pSLEditData->epLineAlign = (attrib & TEXTIP_RTOL) ? 1 : 0; } if ((action & NEDRAW_ENTIRE) || (isEditRow && (action & NEDRAW_ROW))) { if (dwStyle & ES_PASSWORD) neTextOutPwd(hdc, cx, rc.top + cy, pSLEditData->passwdChar, count); else { EDITCHAR *drawtxt = (vtxt != NULL) ? vtxt : pTxt; // Verify if text should be displayed reversed or normal. if ((pSLEditData->selStart >= pSLEditData->selEnd) || (tot >= pSLEditData->selEnd) || (tot + count < pSLEditData->selStart) || ((tot >= pSLEditData->selStart) && (tot + count < pSLEditData->selEnd))) { if (((tot >= pSLEditData->selStart) && (tot + count < pSLEditData-> selEnd))) { SetTextColor(hdc, bkcol); SetBkColor(hdc, RGB(0, 0, 255)); } else { SetTextColor(hdc, fgcol); SetBkColor(hdc, bkcol); } neTextOut(hdc, cx, rc.top + cy, drawtxt, count); } else { // Text that is mixed sel and nonsel is displayed char by char int idx; int ox = 0; for (idx = 0; idx < count; idx++) { int ridx = (v2l != NULL) ? v2l[idx] : idx; if ((tot + ridx >= pSLEditData-> selStart) && (tot + ridx < pSLEditData-> selEnd)){ SetTextColor(hdc, bkcol); SetBkColor (hdc, RGB (0, 0, 255)); } else { SetTextColor(hdc, fgcol); SetBkColor (hdc, bkcol); } neTextOut(hdc, cx + ox, rc.top + cy, drawtxt + idx, 1); ox += neGetTextWith(hWnd, hdc, pSLEditData, drawtxt + idx, 1); } } } } if ((action & NEDRAW_CALC_CURSOR)) { if (isEditRow) { int x; int idx = pSLEditData->editPos - tot; int nc = idx; DPRINTF("***IDX=%d, vidx=%d, n=%d, dir=%d, chr=%04X\n", idx, (v2l != NULL) ? v2l[idx] : idx, n, (direction != NULL) ? direction[idx] : 0, pSLEditData->buffer[tot + idx]); if (vtxt) { // for RTOL characters cursor will be displayed at the right. if (idx < n) nc = v2l[idx] + ((direction [idx] & 1) ? 1 : 0); else nc = (((idx > 0) && (direction [idx - 1] & 1)) ? v2l[idx - 1] : idx); if (nc <= n) x = neGetTextWith(hWnd, hdc, pSLEditData, vtxt, nc); } else x = neGetTextWith(hWnd, hdc, pSLEditData, pTxt, idx); if (nc <= n) { pSLEditData->epX = cx + x + pSLEditData->scrollX; pSLEditData->epY = cy; // If we're called only for this, set done. if (action == NEDRAW_CALC_CURSOR) done = 1; action &= ~NEDRAW_CALC_CURSOR; } } } else if ((action & NEDRAW_CALC_EDITPOS)) { if (cy / pSLEditData->charHeight >= pSLEditData->epY / pSLEditData->charHeight) { int nc, idx, x, dx, bdx = 100000, bi = n, bx = -1; for (idx = 0; idx <= n; idx++) { if (vtxt) { if (idx < n) nc = v2l[idx] + ((direction[idx] & 1) ? 1 : 0); else nc = (((idx > 0) && (direction [idx - 1] & 1))? v2l[idx - 1] : idx); x = neGetTextWith(hWnd, hdc, pSLEditData, vtxt, nc); } else x = neGetTextWith(hWnd, hdc, pSLEditData, pTxt, idx); dx = cx + x - pSLEditData->epX + pSLEditData->scrollX; if ((dx >= -2) && ((dx <= bdx))) bdx = dx, bi = idx, bx = x; } if (bx < 0) bx = x; pSLEditData->editPos = tot + bi; pSLEditData->epX = cx + bx - pSLEditData->leftMargin + pSLEditData->scrollX; pSLEditData->epY = cy; if (action == NEDRAW_CALC_EDITPOS) done = 1; action &= ~NEDRAW_CALC_EDITPOS; } } if (vtxt) { free(vtxt); free(direction); free(v2l); vtxt = NULL; } // Maybe obsolete here: does nl could be zero here ?? if (!nl) cx += neGetTextWith(hWnd, hdc, pSLEditData, pTxt, count); else cx = rc.left; pTxt += count + deltachr; tot += count + deltachr; cy += deltay; if ((rc.top + cy >= rc.bottom) && !(action & (NEDRAW_CALC_CURSOR | NEDRAW_CALC_EDITPOS))) break; } } // If it's finisced without calculating, put to end if ((action & NEDRAW_CALC_CURSOR)) { pSLEditData->epX = cx + pSLEditData->scrollX; pSLEditData->epY = cy; } // If called for editpos and not found a pos, set to zero if ((action & NEDRAW_CALC_EDITPOS)) { pSLEditData->epX = cx + pSLEditData->scrollX; pSLEditData->epY = cy; pSLEditData->editPos = pSLEditData->dataEnd; } free(edittext); if (bRelDC) ReleaseDC(hWnd, hdc); if ((action & (NEDRAW_ENTIRE | NEDRAW_ROW)) && (GetFocus() == hWnd)) ShowCaret(hWnd);}/* * neNCPaint */static voidneNCPaint(HWND hWnd, WPARAM wParam){ HDC hdc; RECT rc; DWORD dwStyle = hWnd->style; hdc = wParam ? (HDC) wParam : GetWindowDC(hWnd); GetClientRect(hWnd, &rc); if (dwStyle & WS_DISABLED) FastFillRect(hdc, &rc, GetSysColor(COLOR_INACTIVECAPTIONTEXT)); else FastFillRect(hdc, &rc, GetSysColor(COLOR_INFOBK)); GetWindowRect(hWnd, &rc); if (dwStyle & WS_BORDER) Draw3dInset(hdc, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top); if (!wParam) ReleaseDC(hWnd, hdc);}/* * PAINT the EDIT CLIENT AREA */static voidnePaint(HWND hWnd, WPARAM wParam, LPARAM lParam){ RECT rect, rc; PAINTSTRUCT ps; DWORD dwStyle = hWnd->style; PSLEDITDATA pSLEditData = (PSLEDITDATA) (hWnd->userdata2); HDC hdc; hdc = BeginPaint(hWnd, &ps); GetClientRect(hWnd, &rect); if (dwStyle & WS_DISABLED) { rc.left = 0; rc.top = 0; rc.bottom = rect.bottom; rc.right = rect.right; FillRect(hdc, &rc, GetStockObject(LTGRAY_BRUSH)); SetBkColor(hdc, LTGRAY /*COLOR_lightgray */ ); } else { rc.left = 0; rc.top = 0; rc.bottom = rect.bottom; rc.right = rect.right; FillRect(hdc, &rc, GetStockObject(WHITE_BRUSH)); SetBkColor(hdc, WHITE /*COLOR_lightwhite */ ); } SetTextColor(hdc, BLACK /*COLOR_black */ ); SelectObject(hdc, pSLEditData->hFont); neDrawAllText(hWnd, hdc, pSLEditData, NEDRAW_ENTIRE); EndPaint(hWnd, &ps);}/* * Invalidate client area */static voidneInvalidateClient(HWND hWnd){ RECT InvRect; PSLEDITDATA pSLEditData = (PSLEDITDATA) (hWnd->userdata2); InvRect.left = pSLEditData->leftMargin; InvRect.top = pSLEditData->topMargin; InvRect.right = hWnd->clirect.right - hWnd->clirect.left; InvRect.bottom = hWnd->clirect.bottom - hWnd->clirect.top; InvalidateRect(hWnd, &InvRect, FALSE);}/* * Set the focus, create caret */static voidneSetFocus(HWND hWnd, WPARAM wParam, LPARAM lParam){ PSLEDITDATA pSLEditData = (PSLEDITDATA) (hWnd->userdata2); if ((hWnd->userdata & EST_FOCUSED) != 0) return; hWnd->userdata |= EST_FOCUSED; pSLEditData = (PSLEDITDATA) (hWnd->userdata2); if ((hWnd->userdata & EST_REPLACE)) CreateCaret(hWnd, NULL, mwDefEditCaretSizeIns, pSLEditData->charHeight); else CreateCaret(hWnd, NULL, mwDefEditCaretSize, pSLEditData->charHeight); neUpdateCaretPos(hWnd); ShowCaret(hWnd); SendMessage(GetParent(hWnd), WM_COMMAND, (WPARAM) MAKELONG(hWnd->id, EN_SETFOCUS), (LPARAM) hWnd);}/* * Kill focus */static voidneKillFocus(HWND hWnd){ hWnd->userdata &= ~EST_FOCUSED; HideCaret(hWnd); DestroyCaret(); SendMessage(GetParent(hWnd), WM_COMMAND, (WPARAM) MAKELONG(hWnd->id, EN_KILLFOCUS), (LPARAM) hWnd);}/* * Move selection with new cursor position */static BOOLneMoveSelection(PSLEDITDATA pSLEditData){ int s = pSLEditData->selStart; int e = pSLEditData->selEnd; if (pSLEditData->editPos < pSLEditData->selCenter) { pSLEditData->selStart = pSLEditData->editPos; pSLEditData->selEnd = pSLEditData->selCenter; } else { pSLEditData->selEnd = pSLEditData->editPos; pSLEditData->selStart = pSLEditData->selCenter; } return ((s != pSLEditData->selStart) || (e != pSLEditData->selEnd));}/* * Handle mouse down */static voidneMouseLButtonDown(HWND hWnd, WPARAM wParam, LPARAM lParam){ PSLEDITDATA pSLEditData = (PSLEDITDATA) (hWnd->userdata2); DWORD dwStyle = hWnd->style; pSLEditData->epX = LOWORD(lParam) - pSLEditData->leftMargin + pSLEditData->scrollX; pSLEditData->epY = HIWORD(lParam) - pSLEditData->topMargin + pSLEditData->scrollRow * pSLEditData->charHeight; if (!(dwStyle & ES_MULTILINE)) pSLEditData->epY = 0; //i = neIndexFromPos ( hWnd, &pt ); neDrawAllText(hWnd, NULL, pSLEditData, NEDRAW_CALC_EDITPOS); // If a selection was present, remove and redraw if (pSLEditData->selStart < pSLEditData->selEnd) neInvalidateClient(hWnd); pSLEditData->selStart = pSLEditData->editPos; pSLEditData->selCenter = pSLEditData->editPos; pSLEditData->selEnd = pSLEditData->editPos; pSLEditData->caretX = pSLEditData->epX - pSLEditData->scrollX + pSLEditData->leftMargin; if ((dwStyle & ES_MULTILINE)) pSLEditData->caretRow = pSLEditData->epY / pSLEditData->charHeight - pSLEditData->scrollRow; neUpdateCaretPos(hWnd); SetCapture(hWnd);}/* * Handle mouse move */static voidneMouseMove(HWND hWnd, WPARAM wParam, LPARAM lParam){ PSLEDITDATA pSLEditData = (PSLEDITDATA) (hWnd->userdata2); POINT pt; int i; pt.x = LOWORD(lParam); pt.y = HIWORD(lParam); if (GetCapture() != hWnd) return; ScreenToClient(hWnd, &pt); do { if (pt.x < pSLEditData->leftMargin) { if (!(hWnd->userdata & EST_SELSCROLLLEFT)) { hWnd->userdata |= EST_SELSCROLLLEFT; SetTimer(hWnd, IDTM_SELSCROLLLEFT, TM_SELSCROLL, NULL); pt.x = pSLEditData->leftMargin; break; } return; } if (pt.x > pSLEditData->leftMargin + edtGetOutWidth(hWnd)) { if (!(hWnd->userdata & EST_SELSCROLLRIGHT)) { hWnd->userdata |= EST_SELSCROLLRIGHT; SetTimer(hWnd, IDTM_SELSCROLLRIGHT, TM_SELSCROLL, NULL); pt.x = pSLEditData->leftMargin + edtGetOutWidth(hWnd); break; } return; } if ((hWnd->userdata & EST_SELSCROLLLEFT)) KillTimer(hWnd, IDTM_SELSCROLLLEFT); if ((hWnd->userdata & EST_SELSCROLLRIGHT)) KillTimer(hWnd, IDTM_SELSCROLLRIGHT); hWnd->userdata &= ~(EST_SELSCROLLLEFT | EST_SELSCROLLRIGHT); } while (0); i = neIndexFromPos(hWnd, &pt); pSLEditData->editPos = i; neMoveSelection(pSLEditData); pSLEditData->caretX = pt.x; neUpdateCaretPos(hWnd); neDrawAllText(hWnd, NULL, pSLEditData, NEDRAW_ENTIRE);}/* * Handle mouse LBUTTUP */static voidneMouseLButtonUp(HWND hWnd, WPARAM wParam, LPARAM lParam){ if (GetCapture() != hWnd) return; ReleaseCapture(); if ((hWnd->userdata & EST_SELSCROLLLEFT)) KillTimer(hWnd, IDTM_SELSCROLLLEFT); if ((hWnd->userdata & EST_SELSCROLLRIGHT)) KillTimer(hWnd, IDTM_SELSCROLLRIGHT);}/* * Handle mouse DOUBLE CLICK */static voidneMouseDblClk(HWND hWnd, WPARAM wParam, LPARAM lParam)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -