Windows Formで独自に作成したウィンドウコントロールのコンポーネントにキャレットを表示する

独自に作成したウィンドウコントロールにキャレットを表示するコードを紹介します。

概要

独自に作成したウィンドウコントロールにキャレットを表示します。
キャレットの表示にはWindows APIを用います。

利用するAPIは以下になります。

API 用途
CreateCaret キャレットを作成します
DestroyCaret キャレットを廃棄します
SetCaretpos キャレットの表示位置を設定します
ShowCaret キャレットを表示します
HideCaret キャレットを非表示にします


プログラム例

Windows Formアプリケーションを作成します。

コード

CustomControl.cs (コントロール)
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();
    }

  }
}


フォーム側にはコードは記述しません。

FormMain.cs
namespace CaretShow
{
  public partial class FormMain : Form
  {
    public FormMain()
    {
      InitializeComponent();
    }
  }
}

UI

フォームにはカスタムコントロールのみを配置します。
Windows Formで独自に作成したウィンドウコントロールのコンポーネントにキャレットを表示する:画像1

解説

コントロールが作成され、ハンドルが作成されたタイミングで、 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();
    }

実行結果

プロジェクトを実行します。下図のウィンドウが表示されます。起動時にはコントロールにフォーカスが設定されるため、 コントロールの左上にキャレットが表示されます。
Windows Formで独自に作成したウィンドウコントロールのコンポーネントにキャレットを表示する:画像2

コントロール内をクリックするとキャレットの位置が移動します。
Windows Formで独自に作成したウィンドウコントロールのコンポーネントにキャレットを表示する:画像3
Windows Formで独自に作成したウィンドウコントロールのコンポーネントにキャレットを表示する:画像4

フォームからフォーカスが失われるとキャレットは非表示になります。
Windows Formで独自に作成したウィンドウコントロールのコンポーネントにキャレットを表示する:画像5

再度フォームにフォーカスが設定されると、元の位置にキャレットが表示されます。
Windows Formで独自に作成したウィンドウコントロールのコンポーネントにキャレットを表示する:画像6

カスタムコントロールにキャレットを表示できました。


AuthorPortraitAlt
著者
iPentecのメインプログラマー
C#, ASP.NET の開発がメイン、少し前まではDelphiを愛用
作成日: 2011-12-01
改訂日: 2024-12-21
Copyright © 1995–2025 iPentec all rights reserverd.