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

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

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

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

Windows Forms

Windows Forms(WinForms)はMicrosoft .NET フレームワークに含まれる視覚的なアプリケーションのプログラミングインターフェイス(API)です。WinFormsは管理されているコードの既存のWindowsのAPIをラップすることで元のMicrosoft Windowsのインターフェイスのエレメントにアクセスすることができます。

Q&A

解決済

1回答

5207閲覧

C# テキストボックスのスクロールバーの位置を取得したい

moko2

総合スコア13

C#

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

Windows Forms

Windows Forms(WinForms)はMicrosoft .NET フレームワークに含まれる視覚的なアプリケーションのプログラミングインターフェイス(API)です。WinFormsは管理されているコードの既存のWindowsのAPIをラップすることで元のMicrosoft Windowsのインターフェイスのエレメントにアクセスすることができます。

0グッド

0クリップ

投稿2019/06/12 13:43

編集2019/06/12 14:02

プログラム初心者です。
Visual Studio 2019 で C# を使用して Windowsフォームアプリでオリジナルのテキストエディタを作成中です。

テキストボックスのスクロールバーの位置を記憶しておいて、再起動後などに復元したいと思ったので下記の記事を参考に試してみましたが、リッチテキストボックスでは正常に動作して、テキストボックスでは動作しませんでした。
http://pineplanter.moo.jp/non-it-salaryman/2017/11/23/csharp-scroll-control/

しかし同じようなことを試している別の記事ではテキストボックスで実装されています。
http://seshikanai.blog.fc2.com/blog-entry-4.html

ということは何か私の方に問題があるのでしょうか‥
とは言えコードは参考記事そのままになります。

csharp

1// スクロールバーの位置を取得&復元するための関数 2[DllImport("USER32.dll")] 3public static extern IntPtr SendMessage( 4 IntPtr hWnd, Int32 Msg, Int32 wParam, ref Point lParam); 5 6private Point pos = new Point(0, 0); 7 8// GET 9private void Button1_Click(object sender, EventArgs e) 10{ 11 // スクロール位置を取得 12 SendMessage(this.textBox1.Handle, 0x04DD, 0, ref pos); 13 //NativeMethods.SendMessage(this.richTextBox1.Handle, 0x04DD, 0, ref pos); 14 label1.Text = pos.X.ToString(); 15 label2.Text = pos.Y.ToString(); 16} 17 18// SET 19private void Button2_Click(object sender, EventArgs e) 20{ 21 // スクロール位置を復元 22 SendMessage(this.textBox1.Handle, 0x04DE, 0, ref pos); 23 //NativeMethods.SendMessage(this.richTextBox1.Handle, 0x04DE, 0, ref pos); 24 label1.Text = pos.X.ToString(); 25 label2.Text = pos.Y.ToString(); 26}

イメージ説明

こちらについて何かお分かりの方いらっしゃいましたら、ご教授いただけましたらありがたく思います。

よろしくお願いします。m(_ _)m

追記:
代替案として「キャレットの位置を保存して、復元時にキャレットの位置までスクロールする」という実装も試してみました。
ただしこちらの場合、キャレットがある行がテキストボックスに表示されている範囲での最下行までしかスクロールダウンしてくれず、とても不格好な上に結局少し手でスクロールダウンさせる必要があり不便です。。

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

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

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

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

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

papinianus

2019/06/12 22:18

代替案はキャレットの位置+15までスクロールする、ではだめなのですか?
moko2

2019/06/13 02:27 編集

papinianusさんコメントありがとうございます! キャレットの位置までスクロールするメソッドは「textBox1.ScrollToCaret();」なのですが、こちらにはどうも引数が無いようでそれ以上の指定ができません。。 https://docs.microsoft.com/ja-jp/dotnet/api/system.windows.forms.textboxbase.scrolltocaret?view=netframework-4.8 こちらのメソッド、見えている範囲の上までスクロールするというような指定ができれば便利ですよね。
papinianus

2019/06/13 10:00

回答でたんでいいですが、キャレット位置を保存してるのですよね?それを15行下にしてスクロールして位置を戻せるかと思いました。もちろん縦が固定のときなので、実用的ではないでしょうが。
moko2

2019/06/13 11:16

はい、キャレット位置の保存は途中で軽く試しました。 ただ、こちらに質問した段階ではそもそもスクロール位置を制御することができなかったので、キャレットの位置からさらにスクロール位置を変えてやるにも方法が分からない‥という感じです。。
guest

回答1

0

ベストアンサー

0x04DD(EM_GETSCROLLPOS)や0x04DE(EM_SETSCROLLPOS)はリッチエディット用のメッセージのようなので、他の方法でやる必要がありそうです。

ちょっと作ってみたので試してみてください。
GetTextBoxScrollPosで取得、SetTextBoxScrollPosでセットができます。

csharp

1 const int SB_HORZ = 0x00; 2 const int SB_VERT = 0x01; 3 const int WM_HSCROLL = 0x0114; 4 const int WM_VSCROLL = 0x0115; 5 const int SB_THUMBPOSITION = 4; 6 7 [DllImport("USER32.DLL", CharSet = CharSet.Auto)] 8 static extern int GetScrollPos(IntPtr hWnd, Int32 nBar); 9 [DllImport("user32.dll")] 10 static extern int SetScrollPos(IntPtr hWnd, Int32 nBar, int nPos, bool bRedraw); 11 [DllImport("user32.dll")] 12 static extern int SendMessage(IntPtr hWnd, int wMsg, int wParam, int lParam); 13 14 public static Point GetTextBoxScrollPos(TextBox textBox) 15 { 16 return new Point(GetScrollPos(textBox.Handle, SB_HORZ), GetScrollPos(textBox.Handle, SB_VERT)); 17 } 18 19 public static void SetTextBoxScrollPos(TextBox textBox, Point newPos) 20 { 21 SendMessage(textBox.Handle, WM_HSCROLL, (newPos.X << 16) + SB_THUMBPOSITION, 0); 22 SendMessage(textBox.Handle, WM_VSCROLL, (newPos.Y << 16) + SB_THUMBPOSITION, 0); 23 }

投稿2019/06/13 00:51

編集2019/06/13 02:02
takabosoft

総合スコア8356

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

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

takabosoft

2019/06/13 01:51

あ、SetでXの位置が正しく設定されてなかった...
takabosoft

2019/06/13 02:02

今度こそ大丈夫のはず・・・
moko2

2019/06/13 02:32

takabosoftさんご回答ありがとうございます! 早速試したところバッチリ動作しました! 件のコードはリッチエディット用だったのですね。 実装をあきらめるところだったので大変感謝しています。。 ありがとうございました!
takabosoft

2019/06/13 02:35

どういたしまして!私も勉強になりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問