📄 edit.c
字号:
/*** $Id: edit.c,v 1.105 2005/01/31 09:12:48 clear Exp $**** edit.c: the Single Line Edit Control module.**** Copyright (C) 2003 Feynman Software.** Copyright (C) 1999 ~ 2002 Wei Yongming.** ** Current maintainer: Wei Yongming.**** Note:** Although there was a version by Zhao Jianghua, this version of** EDIT control is written by Wei Yongming from scratch.**** Create date: 1999/8/26*//*** This program is free software; you can redistribute it and/or modify** it under the terms of the GNU General Public License as published by** the Free Software Foundation; either version 2 of the License, or** (at your option) any later version.**** This program is distributed in the hope that it will be useful,** but WITHOUT ANY WARRANTY; without even the implied warranty of** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the** GNU General Public License for more details.**** You should have received a copy of the GNU General Public License** along with this program; if not, write to the Free Software** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*//*** TODO:** * Replace** * Undo.**/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#include "common.h"#include "minigui.h"#include "gdi.h"#include "window.h"#include "ctrl/ctrlhelper.h"#include "ctrl/edit.h"#include "cliprect.h"#include "internals.h"#include "ctrlclass.h"#include "clipboard.h"#ifdef _CTRL_SLEDIT#include "ctrlmisc.h"#include "text.h"#include "edit_impl.h"static int SLEditCtrlProc (HWND hWnd, int message, WPARAM wParam, LPARAM lParam);#define check_caret() \ if(sled->selStart != sled->selEnd) \ HideCaret(hWnd); \ else \ ShowCaret(hWnd);#define shift_one_char_r(pos) \ { \ int len = CHLENNEXT( (sled->content.string + sled->pos), (sled->content.txtlen - sled->pos)); \ sled->pos += len; \ }#define shift_one_char_l(pos) \ { \ int len = CHLENPREV( sled->content.string, (sled->content.string + sled->pos) ); \ sled->pos -= len; \ }BOOL RegisterSLEditControl (void){ WNDCLASS WndClass; WndClass.spClassName = CTRL_SLEDIT; WndClass.dwStyle = WS_NONE; WndClass.dwExStyle = WS_EX_NONE; WndClass.hCursor = GetSystemCursor (IDC_IBEAM); WndClass.iBkColor = GetWindowElementColor (BKC_EDIT_DEF); WndClass.WinProc = SLEditCtrlProc; return AddNewControlClass (&WndClass) == ERR_OK;}/* -------------------------------------------------------------------------- */static void setup_dc (HWND hWnd, SLEDITDATA *sled, HDC hdc, BOOL bSel){ DWORD dwStyle = GetWindowStyle (hWnd); if (!bSel) { if (dwStyle & WS_DISABLED) SetTextColor (hdc, GetWindowElementColorEx (hWnd, FGC_CONTROL_DISABLED)); else SetTextColor (hdc, GetWindowElementColorEx (hWnd, FGC_CONTROL_NORMAL)); SetBkMode (hdc, BM_TRANSPARENT); } else { if (dwStyle & WS_DISABLED) SetTextColor (hdc, GetWindowElementColorEx (hWnd, FGC_HILIGHT_DISABLED)); else SetTextColor (hdc, GetWindowElementColorEx (hWnd, FGC_HILIGHT_NORMAL)); if (sled->status & EST_FOCUSED) SetBkColor (hdc, GetWindowElementColorEx (hWnd, BKC_HILIGHT_NORMAL)); else SetBkColor (hdc, GetWindowElementColorEx (hWnd, BKC_HILIGHT_LOSTFOCUS)); SetBkMode (hdc, BM_OPAQUE); }}/* -------------------------------------------------------------------------- */static int sledit_settext (PSLEDITDATA sled, const char *newtext){ int len, txtlen; txtlen = strlen (newtext); len = (txtlen <= 0) ? sled->nBlockSize : txtlen; if (sled->hardLimit >= 0) { len = MIN (len, sled->hardLimit); txtlen = MIN (txtlen, sled->hardLimit); } /* free the old text */ if (sled->content.string) testr_free (&sled->content); if (!testr_alloc (&sled->content, len, sled->nBlockSize)) return -1; if (newtext && txtlen > 0) testr_setstr (&sled->content, newtext, txtlen); else sled->content.txtlen = 0; return 0;}static void get_content_width (HWND hWnd, PSLEDITDATA sled){ GetClientRect (hWnd, &sled->rcCont); sled->rcCont.left += sled->leftMargin; sled->rcCont.top += sled->topMargin; sled->rcCont.right -= sled->rightMargin; sled->rcCont.bottom -= sled->bottomMargin; sled->starty = sled->topMargin + ( sled->rcCont.bottom - sled->rcCont.top - GetWindowFont (hWnd)->size - 1 ) / 2;}static int sledit_init (HWND hWnd, PSLEDITDATA sled){ if (!sled) return -1; SetWindowAdditionalData2 (hWnd,(DWORD)sled); sled->status = 0; sled->editPos = 0; sled->selStart = 0; sled->selEnd = 0; sled->leftMargin = MARGIN_EDIT_LEFT; sled->topMargin = MARGIN_EDIT_TOP; sled->rightMargin = MARGIN_EDIT_RIGHT; sled->bottomMargin = MARGIN_EDIT_BOTTOM; get_content_width (hWnd, sled); sled->nContX = 0; sled->nContW = sled->rcCont.right - sled->rcCont.left; sled->passwdChar = '*'; sled->nBlockSize = DEF_LINE_BLOCK_SIZE; sled->hardLimit = -1; if (GetWindowStyle(hWnd) & ES_TIP) { sled->tiptext = FixStrAlloc (DEF_TIP_LEN + 1); sled->tiptext[0] = 0; } else sled->tiptext = NULL; sled->content.string = NULL; sled->content.buffsize = 0; sled->content.txtlen = 0; sledit_settext (sled, GetWindowCaption(hWnd)); CreateCaret (hWnd, NULL, 1, GetWindowFont (hWnd)->size); SetCaretPos (hWnd, sled->leftMargin, sled->starty); return 0;}static void sledit_destroy (HWND hWnd, PSLEDITDATA sled){ DestroyCaret (hWnd); if ( (GetWindowStyle(hWnd) & ES_TIP) && sled->tiptext) FreeFixStr (sled->tiptext); testr_free (&sled->content);}static void slePaint (HWND hWnd, HDC hdc, PSLEDITDATA sled){ char* dispBuffer, *passwdBuffer = NULL; DWORD dwStyle = GetWindowStyle(hWnd); StrBuffer *content = &sled->content; int starty = sled->starty; int outw = 0; if (dwStyle & ES_TIP && content->txtlen <= 0 && GetFocus(GetParent(hWnd)) != hWnd) { setup_dc (hWnd, sled, hdc, FALSE); TextOut (hdc, sled->leftMargin, starty, sled->tiptext); return; } if (dwStyle & ES_PASSWORD) { dispBuffer = FixStrAlloc (content->txtlen); memset (dispBuffer, sled->passwdChar, content->txtlen); passwdBuffer = dispBuffer; } else { dispBuffer = content->string; } if (dwStyle & ES_BASELINE) { SetPenColor (hdc, GetWindowElementColorEx (hWnd, FGC_CONTROL_NORMAL));#ifdef _PHONE_WINDOW_STYLE MoveTo (hdc, sled->leftMargin, sled->rcCont.bottom); LineTo (hdc, sled->rcCont.right, sled->rcCont.bottom);#else DrawHDotLine (hdc, sled->leftMargin, sled->rcCont.bottom, sled->rcCont.right - sled->rcCont.left);#endif } ClipRectIntersect (hdc, &sled->rcCont); if (sled->selStart != sled->selEnd) {//select chars int startx = sled->leftMargin - sled->nContX; /* draw first normal chars */ if (sled->selStart > 0) { setup_dc (hWnd, sled, hdc, FALSE); outw += TextOutLen (hdc, startx, starty, dispBuffer, sled->selStart); dispBuffer += sled->selStart; } /* draw selected chars */ setup_dc (hWnd, sled, hdc, TRUE); outw += TextOutLen (hdc, startx + outw, starty, dispBuffer, sled->selEnd - sled->selStart); dispBuffer += sled->selEnd - sled->selStart; /* draw others */ if (sled->selEnd < content->txtlen) { setup_dc (hWnd, sled, hdc, FALSE); outw += TextOutLen (hdc, startx + outw, starty, dispBuffer, content->txtlen - sled->selEnd); } } else { setup_dc (hWnd, sled, hdc, FALSE); outw += TextOutLen (hdc, sled->leftMargin - sled->nContX, starty, dispBuffer, content->txtlen); } sled->nContW = outw; if (sled->nContW < sled->rcCont.right - sled->rcCont.left) sled->nContW = sled->rcCont.right - sled->rcCont.left; if (dwStyle & ES_PASSWORD) FreeFixStr (passwdBuffer);}static int sleSetSel (HWND hWnd, PSLEDITDATA sled, int sel_start, int sel_end){ if (sled->content.txtlen <= 0) return -1; if (sel_start < 0) sel_start = 0; if (sel_end < 0) sel_end = sled->content.txtlen; if (sel_start == sel_end) return -1; sled->selStart = sel_start; sled->selEnd = sel_end; HideCaret(hWnd); InvalidateRect(hWnd, NULL, TRUE); return sled->selEnd - sled->selStart;}static void set_caret_pos (HWND hWnd, PSLEDITDATA sled, int x, BOOL bSel){ int out_chars; HDC hdc; SIZE txtsize; hdc = GetClientDC (hWnd); if (x + sled->nContX <= 0) { out_chars = 0; txtsize.cx = 0; } else out_chars = GetTextExtentPoint (hdc, sled->content.string, sled->content.txtlen, x + sled->nContX, NULL, NULL, NULL, &txtsize); if (!bSel) { sled->selStart = sled->selEnd = 0; sled->editPos = out_chars; SetCaretPos (hWnd, txtsize.cx - sled->nContX, sled->starty); } else { if (out_chars > sled->editPos) { sled->selStart = sled->editPos; sled->selEnd = out_chars; } else { sled->selEnd = sled->editPos; sled->selStart = out_chars; } } ReleaseDC (hdc);}static BOOL make_pos_visible (HWND hWnd, PSLEDITDATA sled, int x){ if (x - sled->nContX > sled->rcCont.right - sled->rcCont.left) { //FIXME sled->nContX = x - (sled->rcCont.right - sled->rcCont.left - 3); return TRUE; } else if (x < sled->nContX) { sled->nContX = x; return TRUE; } return FALSE;}static BOOL make_charpos_visible (HWND hWnd, PSLEDITDATA sled, int charPos, int *cx){ SIZE txtsize; HDC hdc; if (charPos <= 0) txtsize.cx = 0; else { hdc = GetClientDC (hWnd); GetTextExtent (hdc, sled->content.string, charPos, &txtsize); ReleaseDC (hdc); } if (cx) *cx = txtsize.cx; return make_pos_visible (hWnd, sled, txtsize.cx);}static BOOL edtSetCaretPos (HWND hWnd, PSLEDITDATA sled){ BOOL bRefresh; int cx; bRefresh = make_charpos_visible (hWnd, sled, sled->editPos, &cx); SetCaretPos (hWnd, sled->leftMargin + cx - sled->nContX, sled->starty); if (bRefresh) InvalidateRect (hWnd, NULL, TRUE); return bRefresh;}/*static void get_cont_x (HWND hWnd, PSLEDITDATA sled){ HDC hdc; SIZE txtsize; hdc = GetClientDC (hWnd); if (sled->startPos == 0) sled->nContX = 0; else { GetTextExtent (hdc, sled->content.string, sled->startPos, &txtsize); sled->nContX = txtsize.cx; } ReleaseDC (hdc);}*/static int sleMouseMove (HWND hWnd, PSLEDITDATA sled, LPARAM lParam){ int mouseX, mouseY; RECT rcClient;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -