Files
AC_Pro/Component/LineEdit/LineEdit.cpp
T
2026-06-13 00:05:19 +08:00

785 lines
17 KiB
C++

//---------------------------------------------------------------------------
#include <vcl.h>
#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;
}
}
/******************************************************************************/