• 在窗体上创建自己的光标并输入文字


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

     

  • 相关阅读:
    详解学习C#的方法和步骤
    将今天写进历史,即可得出现在的世界是数字的
    60秒,我们可以干什么?
    《每个人都会死,但我总以为自己不会》让我直面死亡
    介绍Ext JS 4.2的新特性的《深入浅出Ext JS》上市
    十一阅读攻略:和土豪做朋友,告别穷屌丝,迎接高富帅,成功逆袭!
    超低成本----音视频通讯+共享屏幕+电子白板
    Hbase split的三种方式和split的过程
    分布式数据库 HBase
    Sqoop-1.4.6.bin__hadoop-2.0.4-alpha 环境搭建
  • 原文地址:https://www.cnblogs.com/qingtianhua/p/3723144.html
Copyright © 2020-2023  润新知