贤小哥 發表於 2017-9-4 09:05:24

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

<p><strong>Delphi 在窗体上创建自己光标的实例</strong></p>
<p>我们知道在文本框等可以接收输入的组件中,我们可以看到闪烁的光标,并可以输入文字,如果我们在,比如窗体上时,因为不支持输入,也无法显示闪烁的光标,那我们 有办法做自己的输入吗?当然可以,下面我们演示在Form上来输入文字。</p>
<p>&nbsp;&nbsp;&nbsp; 用到的API函数如下</p>
<ul>
<li>GetTextMetrics:获取程序当前的字体信息,存放到TEXTMETRIC结构中</li>
<li>CreateCaret:为系统插入标记创建一个新的形状,并且将插入标记的属主关系指定给特定的窗口。插入标记的形状。可以是线、块或位图</li>
<li>ShowCaret:显示光标</li>
<li>SetCaretPos:设置光标的位置</li>
</ul>
<p>Delphi代码</p>
<div class="jb51code">
<pre class="brush: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 &lt;&gt; '') 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.

</pre>
</div>
<p>VC代码</p>
<div class="jb51code">
<pre class="brush:delphi;">
//全局字符串变量
CString s;

//初始化时,设置光标
BOOL CTest_MFCDlg::OnInitDialog()
{
CDialog::OnInitDialog();
ShowSelfCaret();
   ......
}

//为窗体添加函数,初始化光标
void CTest_MFCDlg::ShowSelfCaret(void)
{
CClientDC dc(this);
TEXTMETRIC tm;
dc.GetTextMetrics(&amp;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-&gt;message == WM_KEYDOWN)
{
//如果是退格键,删除末尾字符
if (pMsg-&gt;wParam == VK_BACK)
{
   if (s.GetLength() != 0)
   {
    s.Delete(s.GetLength() - 1,1);
   }
}
else
   //追加字符
   s.Insert(s.GetLength(),(TCHAR)pMsg-&gt;wParam);
Invalidate(true);
}
return CDialog::PreTranslateMessage(pMsg);
}

//自画,将s的内容画到窗体上
void CTest_MFCDlg::OnPaint()
{
CPaintDC dc(this);
CRect rect;
GetClientRect(&amp;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);
}

</pre>
</div>
<p><img src="https://img.jbzj.com/file_images/article/201709/20179490620600.png?2017849635" alt="" /></p>
<p>如有疑问请留言或者到本站社区交流讨论,感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!</p>
                           
                            <div class="art_xg">
                              <b>您可能感兴趣的文章:</b><ul><li>Delphi 用DLL实现插件的简单实例</li><li>Delphi 根据字符串找到函数并执行的实例</li><li>Delphi提取PDF文本实例</li><li>Delphi XE5 为Android应用制作签名的方法(图文)</li><li>ListView 百分比进度条(delphi版)</li><li>delphi制作wav文件的方法</li><li>Delphi基本图像处理方法汇总</li><li>Delphi实现截屏存盘的方法</li></ul>
                            </div>

                        </div>
                        <!--endmain-->
頁: [1]
查看完整版本: Delphi 在窗体上创建自己光标的实例