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

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

用到的API函数如下

GetTextMetrics:获取程序当前的字体信息,存放到TEXTMETRIC结构中

CreateCaret:为系统插入标记创建一个新的形状,并且将插入标记的属主关系指定给特定的窗口。插入标记的形状。可以是线、块或位图

ShowCaret:显示光标

SetCaretPos:设置光标的位置

 

Delphi代码

 

[delphi]  view plain copy
 
  1. unit Unit1;  
  2.   
  3. interface  
  4.   
  5. uses  
  6.   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,  
  7.   Dialogs, StdCtrls;  
  8.   
  9. type  
  10.   TForm1 = class(TForm)  
  11.     procedure FormCreate(Sender: TObject);  
  12.     procedure FormKeyPress(Sender: TObject; var Key: Char);  
  13.     procedure FormPaint(Sender: TObject);  
  14.   private  
  15.     { Private declarations }  
  16.     s:string;  
  17.   public  
  18.     { Public declarations }  
  19.   end;  
  20.   
  21. var  
  22.   Form1: TForm1;  
  23.   
  24. implementation  
  25.   
  26. {$R *.dfm}  
  27.   
  28. procedure TForm1.FormCreate(Sender: TObject);  
  29. var  
  30.   //TTextMetric存放字体信息  
  31.   tm:TTextMetric;  
  32. begin  
  33.   s := '';  
  34.   GetTextMetrics(Self.Canvas.Handle,tm);  
  35.   
  36.   注意 CreateCaret 的第二个参数是HBITMAP类型,所以你可以使用自己的图形作为光标形状,这里采用默认 
  37.   后面两个参数是光标的宽度和高度,可以自定义 
  38.   }  
  39.   CreateCaret(Self.Handle,HBITMAP(nil),tm.tmAveCharWidth div 2,tm.tmHeight);  
  40.   ShowCaret(Self.Handle);  
  41.   //在(10,,10)这个点上显示  
  42.   SetCaretPos(10,10);  
  43. end;  
  44.   
  45. //窗体按键事件,每次按一个键后,重写s的值,在OnPaint事件中会把s的值 画到窗体上  
  46. procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);  
  47. begin  
  48.   //如果是退格键,则删除前一个字符  
  49.   if Ord(Key) = VK_BACK then  
  50.   begin  
  51.     if (s <> '') then  
  52.       Delete(s,Length(s),1);  
  53.   end  
  54.   else  
  55.     s := s + Key;  
  56.   //重绘  
  57.   Self.Invalidate;  
  58. end;  
  59.   
  60. procedure TForm1.FormPaint(Sender: TObject);  
  61. begin  
  62.   Self.Canvas.TextOut(10,10,s);  
  63.   //重新设置光标位置  
  64.   SetCaretPos(Self.Canvas.TextWidth(s)+10,10);  
  65. end;  
  66.   
  67. end.  

 

 

VC代码

 

[cpp]  view plain copy
 
  1. //全局字符串变量  
  2. CString s;  
  3.   
  4. //初始化时,设置光标  
  5. BOOL CTest_MFCDlg::OnInitDialog()  
  6. {  
  7.     CDialog::OnInitDialog();      
  8.     ShowSelfCaret();  
  9.          ......  
  10. }  
  11.   
  12. //为窗体添加函数,初始化光标  
  13. void CTest_MFCDlg::ShowSelfCaret(void)  
  14. {  
  15.     CClientDC dc(this);  
  16.     TEXTMETRIC tm;  
  17.     dc.GetTextMetrics(&tm);  
  18.     CreateSolidCaret(tm.tmAveCharWidth/2,tm.tmHeight);  
  19.     ShowCaret();  
  20.     POINT p;  
  21.     p.x = 0;  
  22.     p.y = 0;  
  23.     SetCaretPos(p);  
  24. }  
  25.   
  26. //重载PreTranslateMessage  
  27. BOOL CTest_MFCDlg::PreTranslateMessage(MSG* pMsg)  
  28. {  
  29.     //如果是按键按下  
  30.     if (pMsg->message == WM_KEYDOWN)  
  31.     {  
  32.         //如果是退格键,删除末尾字符  
  33.         if (pMsg->wParam == VK_BACK)  
  34.         {  
  35.             if (s.GetLength() != 0)  
  36.             {  
  37.                 s.Delete(s.GetLength() - 1,1);  
  38.             }  
  39.         }  
  40.         else  
  41.             //追加字符  
  42.             s.Insert(s.GetLength(),(TCHAR)pMsg->wParam);  
  43.         Invalidate(true);  
  44.     }  
  45.     return CDialog::PreTranslateMessage(pMsg);  
  46. }  
  47.   
  48. //自画,将s的内容画到窗体上  
  49. void CTest_MFCDlg::OnPaint()  
  50. {  
  51.     CPaintDC dc(this);  
  52.     CRect rect;  
  53.     GetClientRect(&rect);     
  54.     CSize size = dc.GetTextExtent(s);  
  55.     POINT p;  
  56.     p.x = size.cx;  
  57.     p.y = 0;  
  58.     SetCaretPos(p);  
  59.     dc.DrawText(s,s.GetLength(),rect,DT_LEFT);  
  60. }  

 

 参考:

http://blog.csdn.net/bdmh/article/details/6456353

你可能感兴趣的:(创建)