tagCANDY CGI VBレスキュー(花ちゃん)の Visual Basic 6.0用 掲示板 [ツリー表示へ]   [Home]
一括表示(VB6.0)
タイトルユーザーコントロールのプロパティ
記事No15407
投稿日: 2012/01/22(Sun) 15:11
投稿者テキーラ
VB6 EnterpriseEdition ver8176
WindowsXP SP3
VB歴2年


ユーザーコントロールを作成したいのですが、既存のListBoxを利用してBorderLineの色を変更可能にするにはどのように記述したらよいですか?

ListBoxに他の既存のコントロールを組み合わせてトライしましたができませんでした

ListBoxの外枠に対してWin32APIで色を指定すればできるような気もするのですが、その場合どのようにして枠をはんべつしたらよいのかわかりません

ご教示よろしくお願いします

[ツリー表示へ]
タイトルRe: ユーザーコントロールのプロパティ
記事No15408
投稿日: 2012/01/23(Mon) 10:32
投稿者VBレスキュー(花ちゃん)
> 既存のListBoxを利用してBorderLineの色を変更可能にするにはどのように記述したらよいですか?

なぜそのような処理が必要なのでしょうか?
VB6.0 の標準のListBox コントロールには BorderLine どころか BorderStyle プロパティ
さえもありませんし
又、それだけの変更だけでいいのでしょうか(各行毎にバックカラーを設定したいとか)

> ListBoxに他の既存のコントロールを組み合わせてトライしましたができませんでした
どのようにされたのでしょうか?
Shape コントロールを使ったのではだめと言う事でしょうか?

> ListBoxの外枠に対してWin32APIで色を指定すればできるような気もするのですが、その場合どのようにして枠をはんべつしたらよいのかわかりません

下記のようなListBox なら外枠を判別 ? する事もできますが、色設定となると OS レベルの
話になってくるので、画面のプロパティ等が変更されたり OS が変わると変更されてしまう
事になるかも。
色んなスタイルのリストボックス
http://www.hanatyan.sakura.ne.jp/samplepic/vb6_151.htm

お勧めはしませんが、簡単な方法としては 1 番 と2番位かと後は今の段階で他人に聞いて
いるようでは無理かと思いますのであきらめた方が得策かと(私ならしない、できない)
1.ListBoxの外形にShape コントロールをかぶせる。
2.Microsoft Forms 2.0 Object Library のListBox を使用する
  (個人的に使用するような場合にかぎるが)
3.VB2010 等の最新の開発環境で作成する
4.自分でそのようなコントロールを作成する(私にはできませんが)
    昔あるサイトで公開されていましたが、今は閉鎖されてありません。
   

[ツリー表示へ]
タイトルRe^2: ユーザーコントロールのプロパティ
記事No15409
投稿日: 2012/01/23(Mon) 15:13
投稿者テキーラ
> なぜそのような処理が必要なのでしょうか?
標準?のListBoxの機能にForms2.0の機能を付加したいからです。
配布先にも全端末Officeが入っているのでForms2.0を使用しても構わないのでしょうけど、hWndが使用できないのが今回引っかかりまして、それなら標準コントロールにForms2.0の機能を追加しようかと思いました。
作成するアプリケーションの外見上の理由でBorderLineがあったら困るので自分で作ろうと試みました。BorderStyle=Noneでも構わないのですが、あとあと色を変更できるほうがいいのではないかと考えました。
現在PictureBoxを使用してBorderStyleをなくすことは出来ることを確認しましたが、やはりBorderLineは無理なようです。

> VB6.0 の標準のListBox コントロールには BorderLine どころか BorderStyle プロパティ
> さえもありませんし
> 又、それだけの変更だけでいいのでしょうか(各行毎にバックカラーを設定したいとか)
Forms2.0のListBoxの機能でほしいのはBorderLineです。できればBorderStyleもとも思いますが。各行ごとにバックカラーを変える方法はこのHP上にあった記憶がありますのでそちらを参照させていただこうかと思います。逆にそれを変更の要望に書いてしまうと書いてあるだろうと怒られてしまいそうなので(^^;

> Shape コントロールを使ったのではだめと言う事でしょうか?
ShapeコントロールはListBoxの上に張れなかったと思います
Zorderを変更してもListBoxの上にはきませんでした。
その後ListBoxのIntegralHeightをFalseにすることでPictureBoxに張れる(はみ出すことができる)ことを知りましたのでこれを使用しようかと思います。


そこでなのですが、UserControlにPictureBoxを張りその中にListBoxを張る方法について質問させてください。
PictureBoxのBorderStyleを使用してUserControlのBorderStyleは変更できるようになりました。BackColorはListBoxのPropertyを使用しようと考えているのですが、Property Letの時にエラーが発生します。変数のデータ型をLongにしているのですがそれがだめなようです。
MSDNではOLE_COLORとなっていますがそのようなデータ型の登録がなくどうしたものかと悩んでおります。
その他のPropertyも同様にLetのところでエラーになりまったく前に進めません。
原因がお分かりでしたらご教示いただけますでしょうか?
あとUserControlのPropertyやMethodの追加について詳しい(かつ簡単)な本がありましたら教えていただけないでしょうか?

[ツリー表示へ]
タイトルRe^3: ユーザーコントロールのプロパティ
記事No15410
投稿日: 2012/01/23(Mon) 17:40
投稿者魔界の仮面弁士
> hWndが使用できないのが今回引っかかりまして、
取り出すだけなら、WindowFromAccessibleObject するなり
FindWindowEx するなりすれば拾えます。まぁ、それらの
ウィンドウハンドルを取り出したとて、それが
どこまで役に立つのかは少々疑問ですが。


> 外見上の理由でBorderLineがあったら困るので
枠線の変更は Appearance ぐらいしか無いですね。

隠すだけなら Region を切り取るか、少し小さめの
Frame / PictureBox / UserControl に載せて隠すぐらい…。

なお PictureBox は「フォーカスを受け取れるコントロール」のため、
クリックによってアクティブなコントロールが変化してしまいます。
余計なフォーカス遷移をさせたくない場合は、Frame の方が良いかも知れません。

その逆に枠線の描画なら、LineTo API などを使って、コントロールの上に
直接描画することはできます。再描画タイミングの制御は必要ですが。


>> VB6.0 の標準のListBox コントロールには BorderLine どころか
>> BorderStyle プロパティさえもありませんし
ListBox 以外のコントロールでも、BorderLine というプロパティは見当たらないですね。
BorderColor とか BorderSize などを持ったものはあるようですが。


> Forms2.0のListBoxの機能でほしいのはBorderLineです。
手元の Office 2010 では、MSForms.ListBox に BorderLine が
見当たりませんでしたが、BorderLine とはどういうプロパティなのでしょうか?


> ShapeコントロールはListBoxの上に張れなかったと思います
> Zorderを変更してもListBoxの上にはきませんでした。
Shape はフォームの中層に描画されますが、ListBox は上層に配置されるためですね。
(ZOrder が影響を与えるのはそれぞれの層内だけで、別の層への移動はできません)

とはいえコントロールの上ではなく、周辺に配置するだけならできますね。
たとえば UserControl の中に、それより一回り小さい Frame を貼って
その周りに Shape を配置。あとは、BorderStyle なしの Frame の上に
それより一回りはみ出すような ListBox を載せるとか。


> その後ListBoxのIntegralHeightをFalseにすることでPictureBoxに
> 張れる(はみ出すことができる)ことを知りましたので
IntegralHeight は、はみ出せるかどうかを制御するためのものというよりも、
コントロールの高さ指定をリスト項目の高さ単位にするか、1ドット単位で
設定できるようにするかを指定するための物ですね。


> MSDNではOLE_COLORとなっていますがそのようなデータ型の登録がなく
普通に As OLE_COLOR で良いと思いますよ。


Option Explicit

Public Property Get BackColor() As OLE_COLOR
    BackColor = UserControl.Picture1.BackColor
End Property

Public Property Let BackColor(ByVal newColor As OLE_COLOR)
    UserControl.Picture1.BackColor = newColor
    UserControl.BackColor = newColor
    UserControl.PropertyChanged "BackColor"
End Property

Private Sub UserControl_InitProperties()
    On Error Resume Next
    'Me.BackColor = UserControl.Ambient.BackColor
    Me.BackColor = UserControl.Extender.Container.BackColor
End Sub

Private Sub UserControl_ReadProperties(PropBag As PropertyBag)
    On Error Resume Next
    'Me.BackColor = PropBag.ReadProperty("BackColor", UserControl.Ambient.BackColor)
    Me.BackColor = PropBag.ReadProperty("BackColor", UserControl.Extender.Container.BackColor)
End Sub

Private Sub UserControl_WriteProperties(PropBag As PropertyBag)
    PropBag.WriteProperty "BackColor", Me.BackColor, vbButtonFace
End Sub


> あとUserControlのPropertyやMethodの追加について詳しい(かつ簡単)な本が
VB6 付属の MSDN Library にあるチュートリアルを一通り試しておくと良いですよ。

[ツリー表示へ]
タイトルRe^3: ユーザーコントロールのプロパティ
記事No15411
投稿日: 2012/01/24(Tue) 08:07
投稿者VBレスキュー(花ちゃん)
> > Shape コントロールを使ったのではだめと言う事でしょうか?
> ShapeコントロールはListBoxの上に張れなかったと思います
上ではなくふちに配置すれば。

個人の好みの問題にこれ以上立ち入るつもりはありませんが(これもだめ、あれもいやと
いわれれそうなので)

私なら、ListBox に拘る必要もなさそうなので、MSFlexGrid と Shape コントロールを
使って下記のようにつくりますが(結構、色々融通が利きそうなので)

 http://www.hanatyan.sakura.ne.jp/samplepic/20120124_01.gif

[ツリー表示へ]
タイトルRe^4: ユーザーコントロールのプロパティ
記事No15412
投稿日: 2012/01/24(Tue) 13:57
投稿者テキーラ
何を作っているのか、簡単に説明させていただきます。

まずカレンダーをイメージしてください。
各日付はボタンになっています。
そしてそのボタンの裏にはリストボックスが配置されています。
ボタンは透明でリストボックスの内容が見れる状態です。
この状態でリストボックスのBorderLineが見えると非常に不細工なので消します。もしくはFormのBackColorと同じ色にします。
この画面ではその日の簡単な予定が確認でき、ボタンを押すことで詳細画面が開きます。
ここではどちらのコントロールもForms2.0を使用しています。


今ここで困っているのが、リストボックスに表示される行数が10行程度しかないためボタンの裏に配置していながらもスクロ−ル出来るようにならないかということです。
(詳細画面を開けば見れるのですけどユーザーにとって便利だと思える機能は付加するのが作り手の役割だと考えていますので)
そこでかんがえたのが、リストボックスのhWndを取得できればスクロールできるだろうということです。
しかしForms2.0のリストボックスにはhWndがないためそれは不可能です。
そこで、標準コントローラーにBorderColorもしくはBorderStyleを付加すればいいだろうという考えです。

この仕様で他にいい考えがありましたら教えていただけると幸いです


魔界の仮面弁士さんへ
おっしゃる通りBorderLineではなくBorderColorでした
Propertyの追加方法ありがとうございます
MSDNを読んでいる最中なのですが、ここまで細かく書いてありませんので。
ほかにも通らないPropertyがあるので勉強してみてわからないときはまた教えて下さい。

[ツリー表示へ]
タイトルRe^5: ユーザーコントロールのプロパティ
記事No15413
投稿日: 2012/01/24(Tue) 16:02
投稿者魔界の仮面弁士
> リストボックスのhWndを取得できればスクロールできるだろうということです。
TopIndex プロパティではいけないのでしょうか。
あるいは Active Accessibility とか。


> ボタンの裏に配置していながらもスクロ−ル出来るように
スクロ−ル ではなく スクロール という突っ込みはさておき。

思いつく案としては:
(1) コントロールを重ねず、リストボックス自体にボタン的機能を持たせるとか。
(2) VScroll コントロールをボタンの手前に配置して TopIndex 連動させるとか。
(3) ボタン右クリックなどで ZOrder を入れ替えられるようにするとか。
(4) ボタンの上にリスト項目を“描画”するとか。
(5) マウスホイールを取得して TopIndex 連動するとか。


> Propertyの追加方法ありがとうございます
なお、BackColor をアンビエントプロパティにする場合には
AmbientChanged イベントも実装する必要があります。
(そうしないと、コンテナの変更に追従できないため)


> MSDNを読んでいる最中なのですが、ここまで細かく書いてありませんので。
あれは基本的にリファレンスなので、一か所にまとまってはいないのですよね。
個々の機能ごとのサンプルやチュートリアルはあるのですけれども。

[ツリー表示へ]
タイトルRe^6: ユーザーコントロールのプロパティ
記事No15414
投稿日: 2012/01/26(Thu) 09:19
投稿者テキーラ
> TopIndex プロパティではいけないのでしょうか。
なるほど、そういうのがあったのですね、知りませんでした。
マウスホイールの回転を取得してTopindexの値を変えるという理解でよろしいのでしょうか?

> スクロ−ル ではなく スクロール
これどういう意味でしょう(^^;?

> (4) ボタンの上にリスト項目を“描画”するとか。
この方法を教えていただけないでしょうか

[ツリー表示へ]
タイトルRe^7: ユーザーコントロールのプロパティ
記事No15416
投稿日: 2012/01/26(Thu) 12:26
投稿者魔界の仮面弁士
> マウスホイールの回転を取得してTopindexの値を変えるという理解でよろしいのでしょうか?
ホイールメッセージを API で取得するのであれば、そうなるでしょうね。
スクロールさせるために何をトリガーとするのかは、お使いのアプリの
仕様に応じて決めてやればよいと思います。
(ListBox を手前に配置するだけでは駄目なのでしょうか?)

> > スクロ−ル ではなく スクロール
> これどういう意味でしょう(^^;?
文字通りの意味ですよ。

スクロ、マイナス、ル ではなく、
スクロ、長音記号、ル ということで。

> > (4) ボタンの上にリスト項目を“描画”するとか。
> この方法を教えていただけないでしょうか
UserControl でボタン機能を実装して、Print メソッド等で描画するとか、
あるいは既存のボタンの上に DrawTextW API とか。

[ツリー表示へ]
タイトルRe^6: ユーザーコントロールのプロパティ
記事No15415
投稿日: 2012/01/26(Thu) 11:41
投稿者テキーラ
標準のListBoxではTopIndexで動きましたがForms2.0のほうではダメでした。
使用するために何か制限を外さなければいけないのでしょうか?

[ツリー表示へ]
タイトルRe^7: ユーザーコントロールのプロパティ
記事No15417
投稿日: 2012/01/26(Thu) 12:37
投稿者魔界の仮面弁士
> 標準のListBoxではTopIndexで動きましたが
当方では MSForms.ListBox / VB.ListBox ともに、TopIndex で制御できました。

Private Sub Command1_Click()
    ListBox1.TopIndex = ListBox1.TopIndex + 1
End Sub

Private Sub Command2_Click()
    ListBox1.TopIndex = ListBox1.TopIndex - 1
End Sub


> Forms2.0のほうではダメでした。
環境依存性の強いコントロールですし、そういうこともあるのでしょう。

> 使用するために何か制限を外さなければいけないのでしょうか?
どうでしょうね。もともと VB6 での利用が想定されたものではありませんから、
全ての動作について at your own risk であるという制限はあると思いますけれども。

どうしてもというなら、フォーム側も VB.Form を利用せず、Office に倣って
MSForms.UserForm に貼って使うというのはどうでしょうか。
標準コントロールは使えなくなりますが、ActiveX コントロールならば利用可能です。

もっとも、それで解決するかどうかは分かりませんけれども。

[ツリー表示へ]
タイトルRe^8: ユーザーコントロールのプロパティ
記事No15418
投稿日: 2012/01/26(Thu) 14:03
投稿者テキーラ
> > 標準のListBoxではTopIndexで動きましたが
> 当方では MSForms.ListBox / VB.ListBox ともに、TopIndex で制御できました。

TopIndexが機能しない原因がわかりました。
手動でスクロールバーを動かしても強制的にTopに戻ってしまう現象が起きていました。
スクロールバー自体は一度下に動くのですが表示はそのままで、マウスを離すスクロールバーはTopに戻ってしまいます。

− 以下投稿後修正 −
ExcelでよくあるみたいなListBoxが最終行までいかない症状だったようです。
回避策がわからないので表示可能な行数を超える場合に最終行に空行を1行追加してみました。
ただ見た目が気に入らないので表示させる方法をご存知でしたら教えていただけますでしょうか?

[ツリー表示へ]