独自に作成したウィンドウコントロールにキャレットを表示するコードを紹介します。
独自に作成したウィンドウコントロールにキャレットを表示します。
キャレットの表示にはWindows APIを用います。
利用するAPIは以下になります。
API | 用途 |
---|---|
CreateCaret | キャレットを作成します |
DestroyCaret | キャレットを廃棄します |
SetCaretpos | キャレットの表示位置を設定します |
ShowCaret | キャレットを表示します |
HideCaret | キャレットを非表示にします |
Windows Formアプリケーションを作成します。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace CaretShow
{
public partial class CustomControl : Control
{
//public const int WM_LBUTTONDOWN = 0x00000201;
[DllImport("user32.dll")]
static extern bool CreateCaret(IntPtr hWnd, IntPtr hBitmap, int nWidth, int nHeight);
[DllImport("user32.dll")]
static extern bool DestroyCaret();
[DllImport("user32.dll")]
static extern bool SetCaretPos(int X, int Y);
[DllImport("user32.dll")]
static extern bool ShowCaret(IntPtr hWnd);
[DllImport("user32.dll")]
static extern bool HideCaret(IntPtr hWnd);
public CustomControl()
{
InitializeComponent();
}
protected override void OnHandleCreated(EventArgs e)
{
base.OnHandleCreated(e);
CreateCaret(this.Handle, IntPtr.Zero, 2, 16);
}
protected override void OnPaint(PaintEventArgs pe)
{
base.OnPaint(pe);
}
public void ShowCaret(int x, int y)
{
SetCaretPos(x, y);
ShowCaret(this.Handle);
}
public void CaretHide()
{
HideCaret(this.Handle);
}
protected override void OnMouseClick(MouseEventArgs e)
{
base.OnMouseClick(e);
ShowCaret(e.X, e.Y);
}
protected override void OnGotFocus(EventArgs e)
{
base.OnGotFocus(e);
ShowCaret(this.Handle);
}
protected override void OnLostFocus(EventArgs e)
{
base.OnLostFocus(e);
CaretHide();
}
}
}
フォーム側にはコードは記述しません。
namespace CaretShow
{
public partial class FormMain : Form
{
public FormMain()
{
InitializeComponent();
}
}
}
フォームにはカスタムコントロールのみを配置します。
コントロールが作成され、ハンドルが作成されたタイミングで、 CreateCaret APIを呼び出し、キャレットを作成します。 第一引数にキャレットを表示するコントロールのウィンドウハンドル、第二引数はNULLを第三引数はキャレットの幅、 第四引数はキャレットの高さを与えます。キャレットの作成後SetCaretPos APIを呼び出しキャレットの表示位置を設定します。
protected override void OnHandleCreated(EventArgs e)
{
base.OnHandleCreated(e);
CreateCaret(this.Handle, IntPtr.Zero, 2, 16);
}
コントロールでマウスのクリックがされると、SetCaretPos関数で表示位置を設定し、
ShowCaret関数を呼び出しキャレットをコントロールに表示します。
protected override void OnMouseClick(MouseEventArgs e)
{
base.OnMouseClick(e);
ShowCaret(e.X, e.Y);
}
public void CreateShowCaret()
{
SetCaretPos(x, y);
ShowCaret(this.Handle);
}
今回のコードではコントロールがフォーカスを失った際にキャレットを非表示にするため、
OnLostFocusイベントでCaretHide()メソッドを呼び出しキャレットを非表示にしています。
protected override void OnLostFocus(EventArgs e)
{
base.OnLostFocus(e);
CaretHide();
}
public void CaretHide()
{
HideCaret(this.Handle);
}
フォーカスを再度受け取った際には、SetCaretPos()
関数を呼び出さずに、キャレットの作成とキャレットの表示をします。
protected override void OnGotFocus(EventArgs e)
{
base.OnGotFocus(e);
ShowCaret();
}
プロジェクトを実行します。下図のウィンドウが表示されます。起動時にはコントロールにフォーカスが設定されるため、
コントロールの左上にキャレットが表示されます。
コントロール内をクリックするとキャレットの位置が移動します。
フォームからフォーカスが失われるとキャレットは非表示になります。
再度フォームにフォーカスが設定されると、元の位置にキャレットが表示されます。
カスタムコントロールにキャレットを表示できました。