//--------------------------------------------------------------------------- #include #pragma hdrstop #include "LineEdit.h" #pragma package(smart_init) //--------------------------------------------------------------------------- // ValidCtrCheck is used to assure that the components created do not have // any pure virtual functions. // static inline void ValidCtrCheck(TLineEdit *) { new TLineEdit(NULL); } //--------------------------------------------------------------------------- __fastcall TLineEdit::TLineEdit(TComponent* Owner) : TWinControl(Owner) { m_Canvas = new TControlCanvas(); m_Canvas->Control = this; m_HintLabel = new TLabel(this); m_HintLabel->Font->Color = TColor(0x594D43); m_HintLabel->OnMouseDown = DoHintLabelMouseDown; Height = 24; Width = 124; FBorderColor = TColor(0x5F5954); FShadowColor = TColor(0x4C463F); Color = TColor(0xC4B4A8); FHintColor = TColor(0x594D43); FMaxLength = 500; FOnChange = NULL; TabStop = true; FNumberMax = -1; FNumberMin = -1; m_IsCreated = false; } //--------------------------------------------------------------------------- namespace Lineedit { void __fastcall PACKAGE Register() { TComponentClass classes[1] = {__classid(TLineEdit)}; RegisterComponents(L"Samples", classes, 0); } } //--------------------------------------------------------------------------- __fastcall TLineEdit::~TLineEdit() { if(m_Canvas) { delete m_Canvas; m_Canvas = NULL; } if(m_HintLabel) { delete m_HintLabel; m_HintLabel = NULL; } } //--------------------------------------------------------------------------- void __fastcall TLineEdit::SetTextFont(String name, int size) { Font->Name = name; Font->Size = size; m_HintLabel->Font->Name = Font->Name; m_HintLabel->Font->Size = Font->Size; } //--------------------------------------------------------------------------- void __fastcall TLineEdit::AdjustThisSize() { // 设置创建圆角窗口 HRGN var_Hrgn; var_Hrgn = CreateRoundRectRgn(0, 0, Width + 1, Height + 1, 3, 3); SetWindowRgn(Handle, var_Hrgn, true); DeleteObject(var_Hrgn); // 获取字体高度 m_FontHeight = CalcFontHeight(); int var_EditTop = (Height - m_FontHeight) / 2; // 计算编辑区位置 m_TextRect = GetClientRect(); m_TextRect.Left += 4; m_TextRect.Right -= 4; m_TextRect.Top = var_EditTop; // 设置HintText位置 m_HintLabel->Top = m_TextRect.Top; m_HintLabel->Left = m_TextRect.Left; m_HintLabel->Width = m_TextRect.Width(); // 设置编辑区左右边距 SendMessage(Handle, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, 0); // 设置编辑区域(多行编辑有效) SendMessage(Handle, EM_SETRECT, 0, (LPARAM)(&m_TextRect)); } int __fastcall TLineEdit::CalcColorValue(TColor Bg, TColor Fr, int Level, int Alpha) { return ((Bg * (Level - Alpha) + Fr * Alpha) / Level); } int __fastcall TLineEdit::CalcFontHeight() { // 计算字体高度 TTextMetric var_Metric; HDC var_DC = GetDC(0); SelectObject(var_DC, Font->Handle); GetTextMetricsW(var_DC, &var_Metric); ReleaseDC(0, var_DC); return var_Metric.tmHeight; } void __fastcall TLineEdit::CreateShadowColor() { int var_R, var_G, var_B, var_Alpha; int Level = (int)(atan(3.14 / 2) * 500); // 计算阴影颜色 for(int var_Index = 0; var_Index < 4; var_Index++) { var_Alpha = (int)(atan(3.14 / (2 * 3) * var_Index) * 500); var_R = CalcColorValue(GetRValue(FShadowColor), GetRValue(Color), Level, var_Alpha); var_G = CalcColorValue(GetGValue(FShadowColor), GetGValue(Color), Level, var_Alpha); var_B = CalcColorValue(GetBValue(FShadowColor), GetBValue(Color), Level, var_Alpha); m_ShadowColorArray[var_Index] = RGB(var_R, var_G, var_B); } m_ShadowColorArray[4] = Color; } void __fastcall TLineEdit::CreateParams(TCreateParams &Params) { TWinControl::CreateParams(Params); CreateSubClass(Params, L"EDIT"); DWORD var_Alignments[] = {ES_LEFT, ES_RIGHT, ES_CENTER}; DWORD var_CharCase[] = {0, ES_UPPERCASE, ES_LOWERCASE}; DWORD var_HideSelection[] = {ES_NOHIDESEL, 0}; DWORD var_NumbersOnly[] = {0, ES_NUMBER}; DWORD var_OEMConvert[] = {0, ES_OEMCONVERT}; DWORD var_PasswordChar[] = {0, ES_PASSWORD}; DWORD var_ReadOnly[] = {0, ES_READONLY}; Params.Style |= var_Alignments[FAlignment]; Params.Style |= var_CharCase[FCharCase]; Params.Style |= var_HideSelection[FHideSelection]; Params.Style |= var_NumbersOnly[FNumbersOnly]; Params.Style |= var_OEMConvert[FOEMConvert]; Params.Style |= var_PasswordChar[FPasswordChar != 0]; Params.Style |= var_ReadOnly[FReadOnly]; Params.Style |= ES_AUTOHSCROLL; Params.Style |= ES_MULTILINE; //Params.Style |= WS_TABSTOP; //Params.ExStyle |= WS_EX_CONTROLPARENT; } void __fastcall TLineEdit::CreateWindowHandle(const TCreateParams &Params) { TWinControl::CreateWindowHandle(Params); } void __fastcall TLineEdit::CreateWnd() { TWinControl::CreateWnd(); m_HintLabel->Parent = this; if(FPasswordChar != 0) { if(FPasswordChar == '*') { SendMessageW(Handle, EM_SETPASSWORDCHAR, L'●', 0); } else { SendMessageW(Handle, EM_SETPASSWORDCHAR, FPasswordChar, 0); } } if(FReadOnly) { SendMessage(WindowHandle, EM_SETREADONLY, 1, 0); } if(!m_IsCreated) { SetText(FText); m_IsCreated = true; } SetMaxLength(FMaxLength); AdjustThisSize(); } void __fastcall TLineEdit::CMColorChanged(TMessage &Message) { CreateShadowColor(); Invalidate(); } void __fastcall TLineEdit::CMFontChanged(TWMFontChange &Message) { TColor var_FontColor = Font->Color; if(var_FontColor != m_FontColor) { m_FontColor = var_FontColor; // 保存字体颜色 Invalidate(); } else { m_HintLabel->Font->Name = Font->Name; m_HintLabel->Font->Size = Font->Size; RecreateWnd(); } } void __fastcall TLineEdit::SetBorderColor(TColor Color) { if(FBorderColor != Color) { FBorderColor = Color; SendMessage(Handle, CM_COLORCHANGED, 0, 0); } } void __fastcall TLineEdit::SetCursorPos(int Pos) { //SendMessage(Handle, EM_SETSEL, Pos, Pos); SendMessage(Handle, EM_SCROLL, SB_PAGEUP, 0); } void __fastcall TLineEdit::SetFocus() { m_HintLabel->Visible = false; TWinControl::SetFocus(); } void __fastcall TLineEdit::SetOnChange(TNotifyEvent OnChange) { FOnChange = OnChange; } void __fastcall TLineEdit::SetShadowColor(TColor Color) { if(FShadowColor != Color) { FShadowColor = Color; SendMessage(Handle, CM_COLORCHANGED, 0, 0); } } void __fastcall TLineEdit::ShowHintText() { if(Text.IsEmpty() && !Focused()) m_HintLabel->Visible = true; else m_HintLabel->Visible = false; //if(Text.Length() == 0) m_HintLabel->Visible = true; //else m_HintLabel->Visible = false; } void __fastcall TLineEdit::WMChar(TWMChar &Message) { if(Message.CharCode < 32) { switch(Message.CharCode) { case 1: // Ctrl + A case 3: // 双击鼠标左键 SelectAll(); break; default: TWinControl::Dispatch(&Message); } } else if(Message.CharCode == 32) { if(!FNumbersOnly) TWinControl::Dispatch(&Message); } else { // 限制长度 String text = GetText(); int selStart = GetSelStart(); int selLen = GetSelLength(); text.Delete(selStart + 1, selLen); if(text.Length() < FMaxLength) { if(FNumbersOnly) { if(Message.CharCode >= 0x30 && Message.CharCode <= 0x39) { if(FNumberMax != -1) { wchar_t c = Message.CharCode; if(!text.IsEmpty()) { if(selStart == 0 && Message.CharCode == '0') return; if(StrToInt(text) == 0 && Message.CharCode == '0') return; } text.Insert(String(c), selStart); int num = StrToInt(text); if(num <= FNumberMax) { TWinControl::Dispatch(&Message); } } else TWinControl::Dispatch(&Message); } } else { TWinControl::Dispatch(&Message); } } else { //MessageBeep(MB_OK); } } } void __fastcall TLineEdit::WMCommand(TWMCommand &Message) { if(Message.NotifyCode == EN_CHANGE) { //ShowHintText(); Invalidate(); if(FOnChange) FOnChange(this); } } void __fastcall TLineEdit::WMCtlColorEdit(TWMCtlColorEdit &Message) { if(GetTextColor(Message.ChildDC) != ColorToRGB(Font->Color)) SetTextColor(Message.ChildDC, ColorToRGB(Font->Color)); // 设置编辑文字颜色 //if(GetBkColor(Message.ChildDC) != ColorToRGB(Color)) //{ // SetBkColor(Message.ChildDC, ColorToRGB(Color)); // 设置编辑背景颜色 //} if(GetBkMode(Message.ChildDC) != TRANSPARENT) SetBkMode(Message.ChildDC, TRANSPARENT); //ExcludeUpdateRgn(Message.ChildDC, Message.ChildWnd); */ } void __fastcall TLineEdit::WMCtlColorStatic(TWMCtlColorStatic &Message) { SetTextColor(Message.ChildDC, ColorToRGB(Font->Color)); // 设置编辑文字颜色 if(GetBkMode(Message.ChildDC) != TRANSPARENT) SetBkMode(Message.ChildDC, TRANSPARENT); //SetBkColor(Message.ChildDC, ColorToRGB(Color)); // 设置编辑背景颜色 } void __fastcall TLineEdit::WMEraseBkgnd(TWMEraseBkgnd &Message) { m_Canvas->Lock(); m_Canvas->Handle = Message.DC; TRect var_Rect = GetClientRect(); // 绘制背景 m_Canvas->Brush->Color = Color; m_Canvas->FillRect(var_Rect); // 绘制边框 m_Canvas->Brush->Color = FBorderColor; m_Canvas->FrameRect(var_Rect); var_Rect.Top++; var_Rect.Left++; var_Rect.Right--; var_Rect.Bottom--; // 绘制阴影 m_Canvas->Brush->Color = TColor(m_ShadowColorArray[0]); //m_Canvas->Brush->Color = FShadowColor; m_Canvas->FrameRect(var_Rect); for(int var_Layer = 1; var_Layer < 4; var_Layer++) { // 设置画笔颜色 m_Canvas->Pen->Color = TColor(m_ShadowColorArray[var_Layer]); m_Canvas->MoveTo(var_Rect.Left + var_Layer, var_Rect.Bottom - 2); m_Canvas->LineTo(var_Rect.Left + var_Layer, var_Rect.Top + var_Layer); m_Canvas->MoveTo(var_Rect.Left + var_Layer, var_Rect.Top + var_Layer); m_Canvas->LineTo(var_Rect.Right - 1, var_Rect.Top + var_Layer); } m_Canvas->UpdateTextFlags(); m_Canvas->Unlock(); } void __fastcall TLineEdit::WMKeyDown(TWMKeyDown &Message) { if(Message.CharCode == VK_RETURN && !FReadOnly && Enabled) { MessageBeep(MB_OK); } TWinControl::Dispatch(&Message); } void __fastcall TLineEdit::WMKillFocus(TWMKillFocus &Message) { ShowHintText(); TWinControl::Dispatch(&Message); if(Text.Length() < FMaxLength && !Text.IsEmpty()) { if(FNumbersOnly && FNumberMin != -1) { int Value = StrToInt(Text); if(Value < FNumberMin) { Text = IntToStr(FNumberMin); } } } Invalidate(); } void __fastcall TLineEdit::WMPaint(TWMPaint &Message) { PaintHandler(Message); } void __fastcall TLineEdit::WMSetFocus(TWMSetFocus &Message) { //ShowHintText(); m_HintLabel->Visible = false; TWinControl::Dispatch(&Message); } void __fastcall TLineEdit::WMSize(TWMSize &Message) { // 获取当前字体高度 m_FontHeight = CalcFontHeight(); // 计算编辑框的最小高度 int var_MinHeight = m_FontHeight + 4; int var_MinWidth = 20; // 检查宽高的合法性 if(Height < var_MinHeight) { Height = var_MinHeight; return; } if(Width < var_MinWidth) { Width = var_MinWidth; return; } AdjustThisSize(); } /******************************************************************************/ // 编辑框操作 /******************************************************************************/ void __fastcall TLineEdit::DoHintLabelMouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y) { SetFocus(); } void __fastcall TLineEdit::Clear() { FText = ""; SetText(FText); } void __fastcall TLineEdit::ClearSelection() { SendMessage(Handle, WM_CLEAR, 0, 0); } void __fastcall TLineEdit::CopyToClipboard() { SendMessage(Handle, WM_COPY, 0, 0); } void __fastcall TLineEdit::CutToClipboard() { SendMessage(Handle, WM_CUT, 0, 0); } void __fastcall TLineEdit::PasteFromClipboard() { SendMessage(Handle, WM_PASTE, 0, 0); } void __fastcall TLineEdit::Undo() { SendMessage(Handle, WM_UNDO, 0, 0); } void __fastcall TLineEdit::ClearUndo() { SendMessage(Handle, EM_EMPTYUNDOBUFFER, 0, 0); } void __fastcall TLineEdit::SelectAll() { SendMessage(Handle, EM_SETSEL, 0, -1); } String __fastcall TLineEdit::GetText() { if(HandleAllocated()) { SendMessageW(Handle, WM_GETTEXT, 1024, (LPARAM)m_TextBuf); } else { wcscpy( m_TextBuf, FText.c_str() ); } return String(m_TextBuf); } bool __fastcall TLineEdit::GetCanUndo() { if(HandleAllocated()) { return (SendMessage(Handle, EM_CANUNDO, 0, 0) != 0); } else { return false; } } int __fastcall TLineEdit::GetSelLength() { TSelection Selection; SendMessage(Handle, EM_GETSEL, (WPARAM)&Selection.StartPos, (LPARAM)&Selection.EndPos); return Selection.EndPos - Selection.StartPos; } int __fastcall TLineEdit::GetSelStart() { int var_Result; SendMessage(Handle, EM_GETSEL, (WPARAM)&var_Result, 0); return var_Result; } String __fastcall TLineEdit::GetSelText() { int var_Start, var_Length; var_Start = GetSelStart(); var_Length = GetSelLength(); return Text.SubString(var_Start + 1, var_Length); } void __fastcall TLineEdit::SetMaxLength(int Value) { if(Value > 500 || Value <= 0) { Value = 500; } if(FMaxLength != Value) { FMaxLength = Value; } } void __fastcall TLineEdit::SetSelLength(int Value) { TSelection Selection; SendMessage(Handle, EM_GETSEL, (WPARAM)&Selection.StartPos, (LPARAM)&Selection.EndPos); Selection.EndPos = Selection.StartPos + Value; SendMessage(Handle, EM_SETSEL, Selection.StartPos, Selection.EndPos); SendMessage(Handle, EM_SCROLLCARET, 0, 0); } void __fastcall TLineEdit::SetSelStart(int Value) { SendMessage(Handle, EM_SETSEL, Value, Value); } void __fastcall TLineEdit::SetAlignment(TAlignment Value) { if(FAlignment != Value) { FAlignment = Value; m_HintLabel->Alignment = Value; if(HandleAllocated()) { RecreateWnd(); } } } void __fastcall TLineEdit::SetCharCase(TEditCharCase Value) { if(FCharCase != Value) { FCharCase = Value; if(HandleAllocated()) { RecreateWnd(); } } } void __fastcall TLineEdit::SetHideSelection(bool Value) { if(FHideSelection != Value) { FHideSelection = Value; if(HandleAllocated()) { RecreateWnd(); } } } void __fastcall TLineEdit::SetHintText(String Value) { if(FHintText != Value) { FHintText = Value; m_HintLabel->Caption = Value; } } void __fastcall TLineEdit::SetHintColor(TColor Value) { if(FHintColor != Value) { FHintColor = Value; m_HintLabel->Font->Color = Value; } } void __fastcall TLineEdit::SetNumbersOnly(bool Value) { if(FNumbersOnly != Value) { FNumbersOnly = Value; if(HandleAllocated()) { RecreateWnd(); } } } void __fastcall TLineEdit::SetOEMConvert(bool Value) { if(FOEMConvert != Value) { FOEMConvert = Value; if(HandleAllocated()) { RecreateWnd(); } } } void __fastcall TLineEdit::SetPasswordChar(WideChar Value) { if(FPasswordChar != Value) { FPasswordChar = Value; if(HandleAllocated()) { RecreateWnd(); } } } void __fastcall TLineEdit::SetReadOnly(bool Value) { if(FReadOnly != Value) { FReadOnly = Value; if(HandleAllocated()) { RecreateWnd(); } } } void __fastcall TLineEdit::SetText(String Value) { FText = Value; if(HandleAllocated()) { //SetWindowText(Handle, Value.c_str()); //SetWindowText(Handle, FText.c_str()); if(Value.IsEmpty()) { m_HintLabel->SetDesignVisible(true); m_HintLabel->Visible = true; } else { m_HintLabel->SetDesignVisible(false); m_HintLabel->Visible = false; } SendMessageW(Handle, WM_SETTEXT, 0, (LPARAM)Value.c_str()); if(FOnChange) FOnChange(this); } } void __fastcall TLineEdit::SetNumberMax(int Value) { if(FNumberMax != Value) { FNumberMax = Value; } } void __fastcall TLineEdit::SetNumberMin(int Value) { if(FNumberMin != Value) { if(Value > FNumberMax) { Value = FNumberMax; } FNumberMin = Value; } } /******************************************************************************/