TextBoxのテキストカーソルの設定を変更したいです。
例えば、色や幅の大きさです。
試したこと
長方形を塗りつぶしたのを描画し、テキストカーソルと見立てようと思いましたが、
TextBoxのキャレットの位置が取得できないため、描画できませんでした。
環境
Windows10 Home
Visual Studio2022
FrameWork4.7
WindowsForm
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答2件
0
キャレットの色と幅を変更するには、以下のようにします。
ただ、Color.Red のビットマップを作成して CreateCaret に渡しているのですが、なぜか水色で表示されちゃいます。
~~反転とかしてるんですかね。(^^;)
~~
反転してたようです。(^^;)
C#
1using System; 2using System.Diagnostics; 3using System.Drawing; 4using System.Runtime.InteropServices; 5using System.Windows.Forms; 6 7public partial class Form1 : Form 8{ 9 [DllImport("User32")] 10 private static extern bool CreateCaret(IntPtr hwnd, IntPtr hbitmap, 11 int width, int height); 12 13 [DllImport("User32")] 14 private static extern bool ShowCaret(IntPtr hwnd); 15 16 [DllImport("User32")] 17 private static extern bool DestroyCaret(); 18 19 [DllImport("gdi32.dll")] 20 private static extern bool DeleteObject(IntPtr hObject); 21 22 private const int CaretWidth = 5; 23 24 private IntPtr hbmpCaret; 25 26 public Form1() 27 { 28 InitializeComponent(); 29 textBox1.GotFocus += TextBox1_GotFocus; 30 using (var bmp = new Bitmap(CaretWidth, textBox1.Font.Height)) 31 { 32 using (var g = Graphics.FromImage(bmp)) 33 { 34 g.Clear(CreateCaretColor(Color.Red)); 35 } 36 hbmpCaret = bmp.GetHbitmap(); 37 } 38 } 39 40 private static Color CreateCaretColor(Color color) 41 { 42 int A = color.A; 43 int R = color.R ^ 0xff; 44 int G = color.G ^ 0xff; 45 int B = color.B ^ 0xff; 46 return Color.FromArgb(A, R, G, B); 47 } 48 49 protected override void OnFormClosed(FormClosedEventArgs e) 50 { 51 base.OnFormClosed(e); 52 DeleteObject(hbmpCaret); 53 } 54 55 private void TextBox1_GotFocus(object sender, EventArgs e) 56 { 57 DestroyCaret(); 58 CreateCaret(textBox1.Handle, hbmpCaret, CaretWidth, textBox1.Font.Height); 59 ShowCaret(textBox1.Handle); 60 } 61}
キャレットの位置は GetGUIThreadInfo で取得できます。
C#
1[DllImport("user32.dll", SetLastError = true)] 2private static extern bool GetGUIThreadInfo(int hTreadID, ref GUITHREADINFO lpgui); 3 4[DllImport("user32.dll")] 5private static extern int GetWindowThreadProcessId(IntPtr hwnd, out int lpdwProcessId); 6 7[StructLayout(LayoutKind.Sequential)] 8private struct RECT 9{ 10 public int Left; 11 public int Top; 12 public int Right; 13 public int Bottom; 14 public Rectangle ToRectangle() 15 { 16 return Rectangle.FromLTRB(Left, Top, Right, Bottom); 17 } 18} 19 20[StructLayout(LayoutKind.Sequential)] 21private struct GUITHREADINFO 22{ 23 public int cbSize; 24 public int flags; 25 public IntPtr hwndActive; 26 public IntPtr hwndFocus; 27 public IntPtr hwndCapture; 28 public IntPtr hwndMenuOwner; 29 public IntPtr hwndMoveSize; 30 public IntPtr hwndCaret; 31 public RECT rcCaret; 32} 33 34private Rectangle GetCaretRectangle(IntPtr hwnd) 35{ 36 int processId; 37 int threadId = GetWindowThreadProcessId(hwnd, out processId); 38 39 var info = new GUITHREADINFO(); 40 info.cbSize = Marshal.SizeOf(info); 41 GetGUIThreadInfo(threadId, ref info); 42 return info.rcCaret.ToRectangle(); 43}
ですが、文字の選択色についてはシステムカラーで定義されていて、変更するには OS の設定を変更する必要があります。
WPF だと変更できるようですけど。
「Change the TextBox highlight color when a user selects text?」
https://stackoverflow.com/questions/34666064/change-the-textbox-highlight-color-when-a-user-selects-text
投稿2021/11/21 12:15
編集2021/11/24 08:17総合スコア2707
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
ベストアンサー
System.Windows.Forms.TextBox から派生させて、そういう機能を持った TextBox を作ってしまうのもありです。
私はプレースホルダ(何も入れていない場合に何らかの説明文を表示する)機能も欲しくて作ったことがあります。
C#
1 public partial class TextBoxEx : System.Windows.Forms.TextBox { 2 private int _caretSize = 1; 3 private string _placeholderText = String.Empty; 4 private Font _placeholderFont = SystemFonts.DefaultFont; 5 private Color _placeholderColor = Color.Black; 6 7 public int CaretSize { 8 get { 9 return _caretSize; 10 } 11 set { 12 _caretSize = value; 13 SetBoldCaret(); 14 Invalidate(); 15 } 16 } 17 public string PlaceholderText { 18 get { 19 return _placeholderText; 20 } 21 set { 22 _placeholderText = value; 23 Invalidate(); 24 } 25 } 26 public Font PlaceholderFont { 27 get { 28 return _placeholderFont; 29 } 30 set { 31 _placeholderFont = value; 32 Invalidate(); 33 } 34 } 35 public Color PlaceholderColor { 36 get { 37 return _placeholderColor; 38 } 39 set { 40 _placeholderColor = value; 41 Invalidate(); 42 } 43 } 44 45 46 public TextBoxEx() { 47 InitializeComponent(); 48 } 49 50 public TextBoxEx(IContainer container) { 51 container.Add(this); 52 53 InitializeComponent(); 54 } 55 56 protected override void WndProc(ref Message m) { 57 base.WndProc(ref m); 58 if (m.Msg == 15) { 59 if (this.Enabled && !this.ReadOnly && (_placeholderText != null) && (_placeholderText.Length != 0) && (this.Text.Length == 0)) { 60 using(Graphics g = this.CreateGraphics()) { 61 g.FillRectangle(new SolidBrush(this.BackColor), this.ClientRectangle); 62 g.DrawString(_placeholderText, _placeholderFont, new SolidBrush(_placeholderColor), 1, 1); 63 } 64 } 65 } 66 } 67 68 private void SetBoldCaret() { 69 Win32API.CreateCaret(this.Handle, IntPtr.Zero, _caretSize, this.Height); 70 Win32API.ShowCaret(this.Handle); 71 } 72 73 protected override void OnGotFocus(EventArgs e) { 74 base.OnGotFocus(e); 75 SetBoldCaret(); 76 } 77 78class Win32API { 79 [DllImport("USER32.dll")] 80 internal static extern bool CreateCaret(IntPtr hWnd, IntPtr hBitmap, int nWidth, int nHeight); 81 [DllImport("USER32.dll")] 82 internal static extern bool DestroyCaret(); 83 [DllImport("USER32.dll")] 84 internal static extern bool ShowCaret(IntPtr hWnd); 85} 86
投稿2021/11/21 12:29
総合スコア13703
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/11/21 12:51 編集
2021/11/22 10:16
2021/11/22 10:38
2021/11/22 14:31 編集
2021/11/22 22:54
2021/11/23 02:01
2021/11/23 04:41
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。