首页 > 编程 > Delphi > 正文

Delphi 在窗体上创建自己光标的实例

2020-01-31 20:50:14
字体:
来源:转载
供稿:网友

Delphi 在窗体上创建自己光标的实例

我们知道在文本框等可以接收输入的组件中,我们可以看到闪烁的光标,并可以输入文字,如果我们在,比如窗体上时,因为不支持输入,也无法显示闪烁的光标,那我们 有办法做自己的输入吗?当然可以,下面我们演示在Form上来输入文字。

    用到的API函数如下

  • GetTextMetrics:获取程序当前的字体信息,存放到TEXTMETRIC结构中
  • CreateCaret:为系统插入标记创建一个新的形状,并且将插入标记的属主关系指定给特定的窗口。插入标记的形状。可以是线、块或位图
  • ShowCaret:显示光标
  • SetCaretPos:设置光标的位置

Delphi代码

unit Unit1;  interface  uses  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,  Dialogs, StdCtrls;  type  TForm1 = class(TForm)  procedure FormCreate(Sender: TObject);  procedure FormKeyPress(Sender: TObject; var Key: Char);  procedure FormPaint(Sender: TObject);  private  { Private declarations }  s:string;  public  { Public declarations }  end;  var  Form1: TForm1;  implementation  {$R *.dfm}  procedure TForm1.FormCreate(Sender: TObject); var  //TTextMetric存放字体信息  tm:TTextMetric; begin  s := '';  GetTextMetrics(Self.Canvas.Handle,tm);  {  注意 CreateCaret 的第二个参数是HBITMAP类型,所以你可以使用自己的图形作为光标形状,这里采用默认  后面两个参数是光标的宽度和高度,可以自定义  }  CreateCaret(Self.Handle,HBITMAP(nil),tm.tmAveCharWidth div 2,tm.tmHeight);  ShowCaret(Self.Handle);  //在(10,,10)这个点上显示  SetCaretPos(10,10); end;  //窗体按键事件,每次按一个键后,重写s的值,在OnPaint事件中会把s的值 画到窗体上 procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char); begin  //如果是退格键,则删除前一个字符  if Ord(Key) = VK_BACK then  begin  if (s <> '') then   Delete(s,Length(s),1);  end  else  s := s + Key;  //重绘  Self.Invalidate; end;  procedure TForm1.FormPaint(Sender: TObject); begin  Self.Canvas.TextOut(10,10,s);  //重新设置光标位置  SetCaretPos(Self.Canvas.TextWidth(s)+10,10); end;  end.  

VC代码

//全局字符串变量 CString s;  //初始化时,设置光标 BOOL CTest_MFCDlg::OnInitDialog() {  CDialog::OnInitDialog();   ShowSelfCaret();    ...... }  //为窗体添加函数,初始化光标 void CTest_MFCDlg::ShowSelfCaret(void) {  CClientDC dc(this);  TEXTMETRIC tm;  dc.GetTextMetrics(&tm);  CreateSolidCaret(tm.tmAveCharWidth/2,tm.tmHeight);  ShowCaret();  POINT p;  p.x = 0;  p.y = 0;  SetCaretPos(p); }  //重载PreTranslateMessage BOOL CTest_MFCDlg::PreTranslateMessage(MSG* pMsg) {  //如果是按键按下  if (pMsg->message == WM_KEYDOWN)  {   //如果是退格键,删除末尾字符   if (pMsg->wParam == VK_BACK)   {    if (s.GetLength() != 0)    {     s.Delete(s.GetLength() - 1,1);    }   }   else    //追加字符    s.Insert(s.GetLength(),(TCHAR)pMsg->wParam);   Invalidate(true);  }  return CDialog::PreTranslateMessage(pMsg); }  //自画,将s的内容画到窗体上 void CTest_MFCDlg::OnPaint() {  CPaintDC dc(this);  CRect rect;  GetClientRect(&rect);   CSize size = dc.GetTextExtent(s);  POINT p;  p.x = size.cx;  p.y = 0;  SetCaretPos(p);  dc.DrawText(s,s.GetLength(),rect,DT_LEFT); }  

如有疑问请留言或者到本站社区交流讨论,感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

图片精选