表面上是label,实际上也是Memo

在项目中,需要这么一个控件:

平常状态就像一个label,当鼠标双击后得到focus后处于可编辑状态
失去焦点后恢复到一开始的平常状态

这样的控件感觉好多软件都有,主要用于图形界面上的文本框,不过我找啊找都没有找到,只好自己写一个了:

一:基本原理

利用一个label控件和一个memo控件模拟得到。memo控件开始时候隐藏当鼠标双击label时候,显示并修改memo的位置和大小,并将label的caption赋给memo的Text.最后,当memo失去焦点时候,隐藏memo。

二:难点

 当编辑memo时候,点击其它区域时候,也应恢复到平常状态。由于不是焦点的转移,OnExit事件并不能捕获。最后的解决方法是利用捕获CM_MOUSELEAVE、WM_KILLFOCUS消息,在CM_MOUSELEAVE中SetCapture,并在OnMouseDown事件中判断鼠标的位置,如果在控件外则::SetFocus(NULL);,WM_KILLFOCUS中做隐藏memo等善后事务。

三:使用方法

1、添加组件(TNoteLabel、TFloatMemo)

2、在Form上放置若干个TNoteLabel和一个TFloatMemo即可,并将TNoteLabel的EditMemo属性设置为TFloatMemo。或者在程序中动态赋也可以。

四:实现代码

呵呵,列出来大家参考,如有需要改进之处,请指正(email:wu_07@sina.com)

//---------------------------------------------------------------------------

#ifndef FloatMemoH
#define FloatMemoH
//---------------------------------------------------------------------------
#include
#include
#include
#include
//---------------------------------------------------------------------------
class PACKAGE TFloatMemo : public TMemo
{
private:
  TNotifyEvent fOnMouseLeave ;
  TNotifyEvent fOnLoseFocus;
  MESSAGE void __fastcall CMMouseLeave(TMessage &Msg);
  MESSAGE void __fastcall WMKillFocus(TMessage &Msg);
protected:

   virtual void __fastcall Loaded(void);
public:
  __fastcall TFloatMemo(TComponent* Owner);
   bool b;
__published:

    BEGIN_MESSAGE_MAP
        MESSAGE_HANDLER(CM_MOUSELEAVE, TMessage, CMMouseLeave)
        MESSAGE_HANDLER(WM_KILLFOCUS,TMessage,WMKillFocus)
    END_MESSAGE_MAP(TControl)
  __property Classes::TNotifyEvent OnMouseLeave= {read=fOnMouseLeave, write=fOnMouseLeave};
  __property Classes::TNotifyEvent OnLoseFocus= {read=fOnLoseFocus, write=fOnLoseFocus};

};
//---------------------------------------------------------------------------
#endif


//---------------------------------------------------------------------------

#include

#pragma hdrstop

#include "FloatMemo.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(TFloatMemo *)
{
  new TFloatMemo(NULL);
}
//---------------------------------------------------------------------------
__fastcall TFloatMemo::TFloatMemo(TComponent* Owner)
  : TMemo(Owner)
{

}
//---------------------------------------------------------------------------
namespace Floatmemo
{
  void __fastcall PACKAGE Register()
  {
     TComponentClass classes[1] = {__classid(TFloatMemo)};
     RegisterComponents("Additional", classes, 0);
  }
}
//---------------------------------------------------------------------------
void __fastcall TFloatMemo::Loaded(void)
{
  this->Ctl3D =false;
  this->Visible =false;
  this->Cursor =crArrow;
}
//---------------------------------------------------------------------------
void __fastcall TFloatMemo::CMMouseLeave(TMessage &Msg)
{

  TMemo::Dispatch(&Msg);
  if (fOnMouseLeave) fOnMouseLeave(this);

}
//---------------------------------------------------------------------------
void __fastcall TFloatMemo::WMKillFocus(TMessage &Msg)
{
  TMemo::Dispatch(&Msg);
  if (fOnLoseFocus) fOnLoseFocus(this);
}
//---------------------------------------------------------------------------





//---------------------------------------------------------------------------

#ifndef NoteLabelH
#define NoteLabelH
//---------------------------------------------------------------------------
#include
#include
#include
#include
#include "FloatMemo.h"
//---------------------------------------------------------------------------
class PACKAGE TNoteLabel : public TCustomLabel
{
private:
  TFloatMemo * fEditMemo;
  void __fastcall SetEditMemo(TFloatMemo* Memo);
  DYNAMIC void __fastcall DblClick(void);
  void __fastcall EditMemoMouseLeave(TObject *Sender);
   void __fastcall EditMemoMouseUp(TObject *Sender,TMouseButton Button, TShiftState Shift, int X, int Y);
   void __fastcall EditMemoLoseFocus(TObject *Sender);
protected:
   void __fastcall Paint(void);
   virtual void __fastcall Loaded(void);
   MESSAGE void __fastcall WMSetText(TMessage &Msg);
public:
  __fastcall TNoteLabel(TComponent* Owner);
__published:
  __property TFloatMemo *EditMemo={read=fEditMemo,write=SetEditMemo};
   __property Align  = {default=0};
 __property Alignment  = {default=0};
 __property Anchors  = {default=3};
 __property AutoSize  = {default=0};
 __property BiDiMode ;
 __property Caption ;
 __property Color  = {default=-2147483643};
 __property Constraints ;
 __property DragCursor  = {default=-12};
 __property DragKind  = {default=0};
 __property DragMode  = {default=0};
 __property Enabled  = {default=1};
 __property FocusControl ;
 __property Font ;
 __property ParentBiDiMode  = {default=1};
 __property ParentColor  = {default=1};
 __property ParentFont  = {default=1};
 __property ParentShowHint  = {default=1};
 __property PopupMenu ;
 __property ShowAccelChar  = {default=1};
 __property ShowHint ;
 __property Transparent  = {default=0};
 __property Layout  = {default=0};
 __property Visible  = {default=1};
 __property WordWrap  = {default=0};
 __property OnClick ;
 __property OnContextPopup ;
 __property OnDblClick ;
 __property OnDragDrop ;
 __property OnDragOver ;
 __property OnEndDock ;
 __property OnEndDrag ;
 __property OnMouseDown ;
 __property OnMouseMove ;
 __property OnMouseUp ;
 __property OnMouseEnter ;
 __property OnMouseLeave ;
 __property OnStartDock ;
 __property OnStartDrag ;

    BEGIN_MESSAGE_MAP
        MESSAGE_HANDLER(WM_SETTEXT, TMessage, WMSetText)
    END_MESSAGE_MAP(TControl)

};
//---------------------------------------------------------------------------
#endif



//---------------------------------------------------------------------------

#include

#pragma hdrstop

#include "NoteLabel.h"
#pragma package(smart_init)
/* Standard DrawText flags */
#define LV_ML_DT_FLAGS  (DT_TOP | DT_NOPREFIX | DT_EDITCONTROL | DT_CENTER | DT_WORDBREAK | DT_WORD_ELLIPSIS | DT_END_ELLIPSIS)
#define LV_FL_DT_FLAGS  (DT_TOP | DT_NOPREFIX | DT_EDITCONTROL | DT_CENTER | DT_WORDBREAK | DT_NOCLIP)
#define LV_SL_DT_FLAGS  (DT_TOP | DT_EDITCONTROL | DT_SINGLELINE | DT_WORD_ELLIPSIS | DT_END_ELLIPSIS)

//---------------------------------------------------------------------------
// ValidCtrCheck is used to assure that the components created do not have
// any pure virtual functions.
//

static inline void ValidCtrCheck(TNoteLabel *)
{
  new TNoteLabel(NULL);
}
//---------------------------------------------------------------------------
__fastcall TNoteLabel::TNoteLabel(TComponent* Owner)
  : TCustomLabel(Owner)
{
   AutoSize =false;
}
//---------------------------------------------------------------------------
namespace Notelabel
{
  void __fastcall PACKAGE Register()
  {
     TComponentClass classes[1] = {__classid(TNoteLabel)};
     RegisterComponents("Additional", classes, 0);
  }
}
//---------------------------------------------------------------------------

void __fastcall TNoteLabel::Paint(void)
{
  Canvas->Font =Font;
  Canvas->Brush->Color =Color;
  if (Transparent)
    SetBkMode(Canvas->Handle,TRANSPARENT);
  else
  {
    SetBkMode(Canvas->Handle,OPAQUE);
    Canvas->FillRect(Rect(0, 0, Width, Height));
  }
  DrawTextEx(Canvas->Handle, Caption.c_str(), Caption.Length(), &Rect(0, 0, Width
  , Height),LV_ML_DT_FLAGS,NULL);
}
//---------------------------------------------------------------------------
void __fastcall TNoteLabel::WMSetText(TMessage &Msg)
{
  TControl::Dispatch(&Msg);
  Invalidate();
}
//---------------------------------------------------------------------------
void __fastcall TNoteLabel::SetEditMemo(TFloatMemo* Memo)
{
  fEditMemo = Memo;
}
//---------------------------------------------------------------------------
 void __fastcall TNoteLabel::DblClick()
{
 if (fEditMemo!=NULL)
 {

    fEditMemo->OnMouseUp = EditMemoMouseUp;
    fEditMemo->OnMouseLeave = EditMemoMouseLeave;
    fEditMemo->OnLoseFocus = EditMemoLoseFocus;
    fEditMemo->BoundsRect = BoundsRect;
    fEditMemo->Text = Caption;
    fEditMemo->Show();
    ::SetFocus(fEditMemo->Handle);
    fEditMemo->SelectAll();
 }
}
//---------------------------------------------------------------------------
void __fastcall TNoteLabel::Loaded()
{
//
}
//---------------------------------------------------------------------------
void __fastcall TNoteLabel::EditMemoLoseFocus(TObject *Sender)
{
  TMemo* Ctl=dynamic_cast(Sender);
  if (Ctl==0) return ;
  Ctl->Hide();
  Caption = Ctl->Text;
}
//---------------------------------------------------------------------------
void __fastcall TNoteLabel::EditMemoMouseLeave(TObject *Sender)
{
  TWinControl* Ctl=dynamic_cast(Sender);
  if (Ctl==0) return ;
  if (GetCapture()!=Ctl->Handle) SetCapture(Ctl->Handle);

}
//---------------------------------------------------------------------------
void __fastcall TNoteLabel::EditMemoMouseUp(TObject *Sender,TMouseButton Button, TShiftState Shift, int X, int Y)
{
  TWinControl* Ctl=dynamic_cast(Sender);
  if (Ctl==0) return;
  if(!PtInRect(&Rect(0,0,Ctl->Width,Ctl->Height),Point(X,Y)))
  {
    ReleaseCapture();
    ::SetFocus(NULL);
  }
}

//---------------------------------------------------------------------------

阅读更多
个人分类: BCB Sky
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭