質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

2回答

2309閲覧

C# TextBoxのIbeamの設定

.......

総合スコア23

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

0クリップ

投稿2021/11/21 08:04

編集2021/11/22 07:30

TextBoxのテキストカーソルの設定を変更したいです。
例えば、色や幅の大きさです。

試したこと

長方形を塗りつぶしたのを描画し、テキストカーソルと見立てようと思いましたが、
TextBoxのキャレットの位置が取得できないため、描画できませんでした。

環境

Windows10 Home
Visual Studio2022
FrameWork4.7
WindowsForm

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

KOZ6.0

2021/11/21 12:03

Ibeam ていうとマウスカーソルのことになるのでは?
guest

回答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
KOZ6.0

総合スコア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

tacsheaven

総合スコア13703

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

KOZ6.0

2021/11/21 12:51 編集

プレースホルダを指定すると、マウスがうろうろしたときにチラつきませんか? 対応方法としては 「WM_PAINTでTextBoxがちらつく」 https://social.msdn.microsoft.com/Forums/ja-JP/d5ac1426-1082-43a1-a02f-677dad1ee3ca/wmpaint12391textbox1236412385124251238812367?forum=csharpgeneralja というのがあります。 あと、MultiLine のテキストボックスを考慮すると、CreateCaret の高さは Font.Height にしたほうが良いと思います。
.......

2021/11/22 10:16

ご回答ありがとうございます。 無事解決できました。
.......

2021/11/22 10:38

キャレットの色を変更する方法というのはありますか?
KOZ6.0

2021/11/22 14:31 編集

色を変える方法なら私の回答にあるのですが、読んでないのでしょうか?
.......

2021/11/22 22:54

回答が1つしかないと勘違いしていて、見ていませんでした。 本当に申し訳ございません。 あと、ちゃんと赤色にできました! ありがとうございます。
KOZ6.0

2021/11/23 02:01

> 回答が1つしかないと勘違いしていて、見ていませんでした。 高評価をつけるとログに残るのでごまかさないほうがいいです。 昨日高評価をつけていただきましたが、今日取り消して再度つけなおしていますね。
.......

2021/11/23 04:41

すいません。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問