📄 edit.c
字号:
/*** $Id: edit.c,v 1.55 2003/11/23 04:09:08 weiym 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:** * Selection.** * 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 "control.h"#include "cliprect.h"#include "internals.h"#include "ctrlclass.h"#ifdef _CTRL_SLEDIT#include "ctrlmisc.h"#include "edit.h"#define DX_CHARS(Pos) (sled->dx_chars[sled->Pos])#define POS_CHARS(Pos) (sled->pos_chars[sled->Pos])static int SLEditCtrlProc (HWND hWnd, int message, WPARAM wParam, LPARAM lParam);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 = PIXEL_lightwhite; WndClass.WinProc = SLEditCtrlProc; return AddNewControlClass (&WndClass) == ERR_OK;}#if 0void SLEditControlCleanup (void){ // do nothing return;}#endifstatic int edtGetOutWidth (HWND hWnd, PSLEDITDATA sled){ RECT rc; GetClientRect(hWnd, &rc); return RECTW(rc) - sled->leftMargin - sled->rightMargin;}static void edtGetLineInfo (HWND hWnd, PSLEDITDATA sled){ HDC hdc; hdc = GetClientDC (hWnd); if (GetWindowStyle(hWnd) & ES_PASSWORD) { sled->nr_chars = GetTextMCharInfo (GetWindowFont (hWnd), sled->buffer, sled->dataEnd, sled->pos_chars); if (sled->nr_chars) {#ifdef HAVE_ALLOCA unsigned char* temp = alloca (sled->nr_chars);#else unsigned char* temp = FixStrAlloc (sled->nr_chars);#endif memset (temp, '*', sled->nr_chars); GetTextExtentPoint (hdc, temp, sled->nr_chars, 0, NULL, NULL, sled->dx_chars, &(sled->extent));#ifndef HAVE_ALLOCA FreeFixStr (temp);#endif } } else { GetTextExtentPoint (hdc, sled->buffer, sled->dataEnd, 0, &(sled->nr_chars), sled->pos_chars, sled->dx_chars, &(sled->extent)); } sled->pos_chars[sled->nr_chars] = sled->dataEnd; sled->dx_chars[sled->nr_chars] = sled->extent.cx; ReleaseDC (hdc);}static int edtGetPosByX (PSLEDITDATA sled, int x){ int i = 0; if (x < 0) return 0; for (i = 0; i < sled->nr_chars; i++) { if (sled->dx_chars[i] >= x) return i; } return i;}static int edtGetStartDispPosAtEnd (const HWND hWnd, PSLEDITDATA sled){ int out_width = edtGetOutWidth (hWnd, sled); if (sled->extent.cx <= out_width) return 0; return edtGetPosByX (sled, sled->extent.cx - out_width);}static void edtOnEraseBackground (HWND hWnd, DWORD dwStyle, HDC hdc, const RECT* pClipRect){ RECT rcTemp; BOOL fGetDC = FALSE; PSLEDITDATA sled = (PSLEDITDATA) GetWindowAdditionalData2(hWnd); if (hdc == 0) { hdc = GetClientDC (hWnd); fGetDC = TRUE; } GetClientRect (hWnd, &rcTemp); if (pClipRect) ClipRectIntersect (hdc, pClipRect); if (dwStyle & WS_DISABLED) { SetBrushColor (hdc, PIXEL_lightgray); } else { SetBrushColor (hdc, PIXEL_lightwhite); } FillBox (hdc, rcTemp.left, rcTemp.top, RECTW (rcTemp), RECTH (rcTemp)); if (dwStyle & ES_BASELINE) { SetPenColor (hdc, PIXEL_black); DrawHDotLine (hdc, sled->leftMargin, sled->topMargin + GetWindowFont (hWnd)->size + 1, RECTW (rcTemp) - sled->leftMargin - sled->rightMargin); } if (fGetDC) ReleaseDC (hdc);}static int SLEditCtrlProc (HWND hWnd, int message, WPARAM wParam, LPARAM lParam){ PCONTROL pCtrl; DWORD dwStyle; HDC hdc; PSLEDITDATA sled; pCtrl = Control(hWnd); dwStyle = GetWindowStyle(hWnd); switch (message) { case MSG_CREATE: if (!(sled = calloc (1, sizeof (SLEDITDATA)))) { return -1; } sled->status = 0; sled->editPos = 0; sled->startPos = 0; sled->nr_chars = 0; sled->bufferLen = LEN_SLEDIT_BUFFER - 1; sled->buffer = calloc (LEN_SLEDIT_BUFFER, sizeof(char)); sled->pos_chars = calloc (LEN_SLEDIT_BUFFER, sizeof(int)); sled->dx_chars = calloc (LEN_SLEDIT_BUFFER, sizeof(int)); if (!sled->buffer || !sled->pos_chars || !sled->dx_chars) { free (sled->buffer); free (sled->pos_chars); free (sled->dx_chars); free (sled); return -1; } sled->passwdChar = '*'; sled->leftMargin = MARGIN_EDIT_LEFT; sled->topMargin = MARGIN_EDIT_TOP; sled->rightMargin = MARGIN_EDIT_RIGHT; sled->bottomMargin = MARGIN_EDIT_BOTTOM; sled->hardLimit = -1; sled->dataEnd = strlen (GetWindowCaption (hWnd)); sled->dataEnd = MIN (sled->bufferLen, sled->dataEnd); memcpy (sled->buffer, GetWindowCaption (hWnd), sled->dataEnd); if (!CreateCaret (hWnd, NULL, 1, GetWindowFont (hWnd)->size)) { free (sled->buffer); free (sled->pos_chars); free (sled->dx_chars); free (sled); return -1; } edtGetLineInfo (hWnd, sled); SetWindowAdditionalData2 (hWnd,(DWORD)sled); break; case MSG_DESTROY: sled = (PSLEDITDATA) GetWindowAdditionalData2(hWnd); DestroyCaret (hWnd); free (sled->buffer); free (sled->pos_chars); free (sled->dx_chars); free (sled); break; case MSG_ERASEBKGND: { BOOL hidden = HideCaret (hWnd); edtOnEraseBackground (hWnd, dwStyle, (HDC)wParam, (const RECT*)lParam); if (hidden) ShowCaret (hWnd); return 0; } case MSG_FONTCHANGING: return 0; case MSG_FONTCHANGED: { sled =(PSLEDITDATA) GetWindowAdditionalData2 (hWnd); sled->startPos = 0; sled->editPos = 0; edtGetLineInfo (hWnd, sled); DestroyCaret (hWnd); CreateCaret (hWnd, NULL, 1, GetWindowFont (hWnd)->size); SetCaretPos (hWnd, sled->leftMargin, sled->topMargin); InvalidateRect (hWnd, NULL, TRUE); return 0; } case MSG_SETCURSOR: if (dwStyle & WS_DISABLED) { SetCursor (GetSystemCursor (IDC_ARROW)); return 0; } break; case MSG_KILLFOCUS: sled = (PSLEDITDATA) GetWindowAdditionalData2(hWnd); if (sled->status & EST_FOCUSED) { sled->status &= ~EST_FOCUSED; HideCaret (hWnd); NotifyParent (hWnd, GetDlgCtrlID(hWnd), EN_KILLFOCUS); } break; case MSG_SETFOCUS: sled = (PSLEDITDATA) GetWindowAdditionalData2(hWnd); if (sled->status & EST_FOCUSED) break; sled->status |= EST_FOCUSED; SetCaretPos (hWnd, DX_CHARS(editPos) - DX_CHARS(startPos) + sled->leftMargin, sled->topMargin); ShowCaret (hWnd); ActiveCaret (hWnd); NotifyParent (hWnd, GetDlgCtrlID(hWnd), EN_SETFOCUS); break; case MSG_ENABLE: if ( (!(dwStyle & WS_DISABLED) && !wParam) || ((dwStyle & WS_DISABLED) && wParam) ) { if (wParam) ExcludeWindowStyle(hWnd,WS_DISABLED); else IncludeWindowStyle(hWnd,WS_DISABLED); InvalidateRect (hWnd, NULL, TRUE); } return 0; case MSG_NCPAINT: if (wParam) hdc = wParam; else hdc = GetDC (hWnd); if (lParam) ClipRectIntersect (hdc, (RECT*)lParam); if (dwStyle & WS_BORDER)#ifdef _FLAT_WINDOW_STYLE DrawFlatControlFrameEx (hdc, 0, 0, pCtrl->right - pCtrl->left - 1, pCtrl->bottom - pCtrl->top - 1, PIXEL_invalid, 1, -1);#else Draw3DDownFrame (hdc, 0, 0, pCtrl->right - pCtrl->left - 1, pCtrl->bottom - pCtrl->top - 1, PIXEL_invalid);#endif if (!wParam) ReleaseDC (hdc); return 0; case MSG_PAINT: { char* dispBuffer; int len; RECT rect; sled = (PSLEDITDATA) (pCtrl->dwAddData2); if (dwStyle & ES_PASSWORD) { len = sled->nr_chars - sled->startPos; //dispBuffer = alloca (len); dispBuffer = FixStrAlloc (len); memset (dispBuffer, '*', len); } else { dispBuffer = sled->buffer + POS_CHARS(startPos); len = sled->dataEnd - POS_CHARS(startPos); } GetClientRect (hWnd, &rect); rect.left += sled->leftMargin; rect.top += sled->topMargin; rect.right -= sled->rightMargin; rect.bottom -= sled->bottomMargin; hdc = BeginPaint (hWnd); if (dwStyle & WS_DISABLED) { SetBrushColor (hdc, PIXEL_lightgray); SetBkColor (hdc, PIXEL_lightgray); } else { SetBrushColor (hdc, PIXEL_lightwhite); SetBkColor (hdc, PIXEL_lightwhite); } SetTextColor (hdc, PIXEL_black); ClipRectIntersect (hdc, &rect); TextOutLen (hdc, sled->leftMargin, sled->topMargin, dispBuffer, len); if (dwStyle & ES_PASSWORD) { FreeFixStr (dispBuffer); } EndPaint (hWnd, hdc); return 0; } case MSG_KEYDOWN: { BOOL bChange = FALSE; RECT InvRect; sled = (PSLEDITDATA) (pCtrl->dwAddData2); InvRect.left = sled->leftMargin - 1; InvRect.top = sled->topMargin; InvRect.right = pCtrl->cr - pCtrl->cl; InvRect.bottom = pCtrl->cb - pCtrl->ct; switch (LOWORD (wParam)) { case SCANCODE_ENTER: NotifyParent (hWnd, pCtrl->id, EN_ENTER); return 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -