- ベストアンサー
【.NET】VScrollBarクラスを追加して、VScrollbarの色を変更する方法
- VScrollBarクラスを使用してVScrollbarの色を変更する方法について質問します。
- VB.NET初心者ですが、VScrollBarの色を変えるためにコードを追加しましたが、何故か横向きのHScrollBarが表示されます。
- 調べた限りでは、VScrollBarクラスはScrollBarを継承しており、色の変更はWM_CTLCOLORSCROLLBARのCase内で行うようですが、うまく動作しません。アドバイスをお待ちしています。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
> 何故か横向きのHSCrollBarが現れます HScrollbarとVScrollbarでは、ウィンドウスタイルが異なります。どちらもWindows標準のスクロールバークラスと思われますが、ウィンドウのスタイルには次の項目があります。 #define SBS_HORZ 0x0000L // 水平スクロールバー #define SBS_VERT 0x0001L // 垂直スクロールバー .NETのScrollBarクラスは、簡単に言えばWindowsのスクロールバークラスの.NET用ラッパーであり、必要最低限のスタイルだけが定義されたもの。つまり、スタイルの最下位ビットは 0 であり、SBS_HORZ が採用されるため水平スクロールバーになります。 > 目的の「Case WM_CTLCOLORSCROLLBAR」の中にも入ってきておらず WM_CTLCOLORSCROLLBARメッセージは“スクロールバークラスを配置したウィンドウ”に送られるメッセージです。すなわち、VScrollBarクラスを配置したFormに送られます。スクロールバーの中で待ち続けても、そのメッセージがやってくることはありません。 【解決策】 垂直スクロールバーにするには、ScrollBar基底クラスのウィンドウスタイルに SBS_VERT を適用します。ウィンドウスタイルの変更は、CreateParamsメソッドをオーバーライドし、MyBase.CreateParamsで得られるCreateParams構造体のStyleプロパティに SBS_VERT をOR演算で加えてください。 スクロールバーの背景色は、フォーム側で行えばよいのですが、あくまでコントロール側で処理するのであれば、サブクラス化によって親ウィンドウのメッセージ処理を監視する必要があります。コントロールが配置されるウィンドウハンドルは、オーバーライドしたCreateParamsメソッドのParentプロパティで取れると思います(未検証)。取得したウィンドウハンドルを、NativeWindowクラスを継承したクラスでAssignHandleし、WndProcをオーバーライドすればWM_CTLCOLORSCROLLBARを捕えることが出来るはず。 > VB.NET初心者に少し毛が生えた程度のレベル おそらく、回答の内容には分からない点や初見の単語などもあると思いますが、あえて置き換えずに説明しました。というのも、ウィンドウメッセージを直接扱うのであれば、それ相応の知識が必要だからです。 サンプルのコードに沿って、その通りにやれば出来るかもしれませんが、このあたりはちゃんと理解してから扱ったほうが良いと思います。分からない単語はきちんと調べ、これを期にしっかり習得してみてください。
その他の回答 (1)
- うぃず(@Wizard_Zero)
- ベストアンサー率69% (344/495)
> 今回のようなレベルの内容については専門書か何かを手に入れておくべきなのでしょうか...? > それとも,コードの自己検証やネット検索から経験で得られるレベルなのでしょうか?? 参考までに、#1の回答を出すまでの経緯を。 事前知識として次の4つがありました。 1. スクロールバーだけのコントロールがWindowsに存在することを知っていた。 2. CreateParamsをオーバーライドすれば、ウィンドウスタイルを変えることができることを知っていた。 3. 他のウィンドウのメッセージを監視するサブクラス化の仕組みを知っていた。 4. .NETではサブクラス化を行うためにNativeWindowクラスが用意されていることを知っていた。 ScrollBarクラスを継承しても垂直にはならず、垂直にするためのプロパティもない。この状況から、ScrollBarクラスがWindowsに備わっているスクロールバーコントロールのラッパーではないか、という推測を立てる。(事前知識1) 次にこの推測に基づいて検証。 スクロールバーコントロールについてMSDNでウィンドウスタイルを調べてみると、SBS_HORZ/SBS_VERTの2つを発見。そこで、ScrollBarクラスのウィンドウスタイルにSBS_VERTを加えてみる。(事前知識2)すると、垂直スクロールバーに変化したことから、「ScrollBarクラスはスクロールバーコントロールの.NET用ラッパーである」という確信を得る。また、SBS_HORZ の値は 0 であり、これが既定値となるため水平スクロールバーが表示されていた、という原因解明に至る。 「WM_CTLCOLORSCROLLBAR」については知らなかったため、ネットでメッセージの意味・使い方を検索。メッセージがコントロールではなく親ウィンドウに送られることを知る。この時点で、メッセージが飛んでこない原因が判明。 コントロール内部ではなくフォームでWndProcを監視したところ、メッセージを捕らえる事と背景色を変えることに成功。さらに、事前知識3・4から、NativeWindowクラスによるサブクラス化でコントロール内部からウィンドウメッセージを監視する方法を思いつき、回答に提案。これについては検証はしていないため(未検証)とした。 こんな感じです。 > ブログも少し前に読ませていただきました 壁|▽//)ゝ お読みいただきありがとうございます。ぐでぐでなブログで申し訳ない・・・。
お礼
Wizard_Zero 様 どうもありがとうございます!! 垂直バー表示までいけました^^ が,Fom1上のTabControl1(上のTabpage1)に配置しております 当初のVScrollBarのカラー変更はまだ出来ておりません... しかしアドバイスいただけたおかげでForm1直上でテストしてみた VScrollbarは色変更もできました^^どうもありがとうございます. (アドバイスいただいた後,Form1内でオーバーライドしてみましたが TabPage上のVScrollBarのWM_CTLCOLORSCROLLBARが取れず,悩んだ後 Form1直上にVScrollBarを配置してみましたところ,色を変えることが できました^^ そういえば本質問前にもオーバーライドを Form1 Class内でしてみてダメだったので,VScrollBar Class内に移した気が...) もしかするとWM_CTLCOLORSCROLLBARを取れるのが,VScrollBar直下の コントロールのみ,なのかな(?)などと考えまして,TabControl Classや TabPage Classを作成して同様にオーバーライドしてみましたが, WM_CTLCOLORSCROLLBARが出てきません そこで >あくまでコントロール側で処理するのであれば、~ の方にトライすべきかな?と考えましてコーディングしております. まだビルド出来るレベルにすら到達しておりませんが(orz), お礼をあまり遅くしたくないので,ご報告させていただきます. >2. CreateParamsをオーバーライドすれば、ウィンドウスタイルを変えることができることを知っていた。 >3. 他のウィンドウのメッセージを監視するサブクラス化の仕組みを知っていた。 >4. .NETではサブクラス化を行うためにNativeWindowクラスが用意されていることを知っていた。 ↑3つとも存じませんでした..orz まだまだ勉強不足という事ですねー・・・^^; お詳しい回答をどうもありがとうございます.イメージ&勉強用HPが湧くので 非常に嬉しいでございます. もう少し実験・検証してみます.m(_ _)m 本当にどうもありがとうございます.
お礼
Wizard_Zero 様 どうもありがとうございます!! 本当にいつもどうもありがとうございます.今回などは夜分にもかかわらず このようなしっかりとしたアドバイスをいただくことができて, 勉強することが一気に増えるので嬉しい限りでございます. 特に知らない単語がたくさんあるのが非常に嬉しいです.^^ >分からない点や初見の単語などもあると思いますが~ おっしゃられる通りでございますorz 一通り手元の一冊の参考書を読みながらコーディングいたしておりますが, .NETでのコーディングが非常に楽しいあまり(休日なども朝から)Google検索で 見つかったコードをたくさん動かしてみるなど,その構文を実際に書き換えてみたり msgboxから得られる検証結果による実体験ばかりが自分の力になっております^^; >これを期にしっかり習得してみてください どうもありがとうございます!!是非細かいところまで理解したいです. 最近のコーディングにおいてGoogle検索だけでは自分が理解にいたらない ケースが多くなってきているイメージがあるのですが,今回のような レベルの内容については専門書か何かを手に入れておくべきなのでしょうか...? それとも,コードの自己検証やネット検索から経験で得られるレベルなのでしょうか?? いつも,コードも分からない単語もすべてGoogle検索だけに頼っておりますが, 基礎知識のようなものはまた大学受験勉強の時のように,一度 参考書を読む時間をまとめて作った方が良いのかな(?)などとも 考えている次第でございますが... Wizard_Zero様のブログも少し前に読ませていただきましたが, 未知の世界でございましたorz ^^; 早く理解できるようになりたいです. では調べてまいります(`ー´)ゞ どうもありがとうございました!!