コントロールの消し方について

解決


qam  2009-11-10 18:48:20  No: 142811  IP: [192.*.*.*]

Option Explicit
Dim maxand As Integer

Private Sub Command1_Click()

    maxand = maxand + 1
    Set and_d = Form1.Controls.Add("VB.Label", "and_d" & maxand,Form1)
    and_d.Left = 400
    and_d.Visible = True
    and_d.Caption = and_d.Name
    and_d.DragMode = 1

End Sub

上のプログラムで
生成されたコントロールにマウスを持って行き、
右クリックでそのコントロールを削除する方法がわかりません。
そうすればよいのでしょうか?

編集 削除
qam  2009-11-10 18:50:02  No: 142812  IP: [192.*.*.*]

Option Explicit
Dim maxand As Integer

Private Sub Command1_Click()

    maxand = maxand + 1
    Set and_d = Form1.Controls.Add("VB.Label", "and_d" & maxand,Form1)
    and_d.Left = 400
    and_d.Visible = True
    and_d.Caption = and_d.Name
    and_d.DragMode = 1

End Sub

上のプログラムで
生成されたコントロールにマウスを持って行き、
右クリックでそのコントロールを削除する方法がわかりません。
そうすればよいのでしょうか?
言語はvb6です。

編集 削除
魔界の仮面弁士  2009-11-10 20:15:08  No: 142813  IP: [192.*.*.*]

イベントを拾うには、WithEvents を使います。

Option Explicit

Private WithEvents and_d As VB.Label

Private Sub and_d_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
    If CBool(Button And vbRightButton) Then
        Controls.Remove and_d.Name
        Set and_d = Nothing
        Command1.Enabled = True
    End If
End Sub

Private Sub Command1_Click()
    Set and_d = Controls.Add("VB.Label", "and_d1")
    and_d.Move 400, 720, 720, 240
    and_d.Visible = True
    and_d.Caption = and_d.Name
    and_d.DragMode = vbAutomatic
    Command1.Enabled = False
End Sub


なお、WithEvents は配列化出来ない事に注意してください。
もしも複数のコントロールを必要とする場合には、下記のような手法があります。

案1) 必要個数分の WithEvents 変数を予め用意しておく。
案2) WithEvents 変数を持ったクラスをコレクションで管理して、
  個々のイベントをコレクションクラス側で中継するような実装にする。
案3) Controls.Add で追加していく方法ではなく、
  コントロール配列を Load/Unload する手法を利用する。
案4) VB の標準コードで処理する代わりに、コントロールまたはフォームを
  サブクラス化して、API で制御する。
案5) DirectX 用タイプライブラリを利用して、マウス操作を
  DirectInput で受け取るようにする。

編集 削除
qam  2009-11-10 21:56:43  No: 142814  IP: [192.*.*.*]

初心者なのでいまいちわからないです。
すみません。
案1は私が示したプログラムでは役に立たない感じでした。
案3は
コントロール配列を使わないで実現したいので…


少し質問を変えます。
Set and_d1 = Form1.Controls.Add("VB.Label", "and_d" & maxand, Form1)
ボタンを押すごとに
and_d1の「1」の部分が増えていくプログラムは可能のでしょうか?

ボタンクリックで
set and_d1 = Form1.Controls.Add("VB.Label", "and_d" & maxand, Form1)
ボタンクリックで
set and_d2 = Form1.Controls.Add("VB.Label", "and_d" & maxand, Form1)

編集 削除
魔界の仮面弁士  2009-11-10 22:43:30  No: 142815  IP: [192.*.*.*]

> コントロール配列を使わないで実現したいので…
それは何故でしょうか?
今回の条件を満たすためには、もっとも簡単な実装方法だと思いますけれども。

> ボタンを押すごとに
> and_d1の「1」の部分が増えていくプログラムは可能のでしょうか?
それだと、たとえば 3 個追加した場合、
  and_d1
  and_d2
  and_d3
ができますよね。この時、and_d2 を右クリックで削除すると、
  and_d1
  and_d3
と「抜け」ができるかと思います。
この時、ボタンを押してコントロールを増やした場合、次回増分は
  and_d1
  and_d3
  and_d4
となって欲しいのでしょうか。それとも
  and_d1
  and_d2
  and_d3
なのでしょうか? それによってコードも異なってくるかと。


> and_d1の「1」の部分が増えていくプログラムは可能のでしょうか?

and_d1 を WithEvents 変数にしないのであれば、配列にして
  and_d(0) = Controls.Add(……)
  and_d(1) = Controls.Add(……)
とすることができます。コレクションにしても良いでしょう。

しかし WithEvents 変数として管理したいのであれば、
先に示した 案1 か 案2 で対応する事になります。

編集 削除
魔界の仮面弁士  2009-11-10 23:32:44  No: 142816  IP: [192.*.*.*]

> しかし WithEvents 変数として管理したいのであれば、
> 先に示した 案1 か 案2 で対応する事になります。

一応、実装例を挙げておきます。
ボタンを押すとラベル増加、そのラベルを右クリックで削除です。


> 案2) WithEvents 変数を持ったクラスをコレクションで管理

http://www.vb-user.net/junk/replySamples/2009.11.10.23.26/CustomLabel.zip



> 案1) 必要個数分の WithEvents 変数を予め用意

Option Explicit

Private Const Max As Integer = 5

Public WithEvents and_d1 As Label
Public WithEvents and_d2 As Label
Public WithEvents and_d3 As Label
Public WithEvents and_d4 As Label
Public WithEvents and_d5 As Label

Private Sub Command1_Click()
    Dim n As Integer
    Dim lblName As String, lbl As Label
    For n = 1 To Max
        lblName = "and_d" & CStr(n)
        Set lbl = CallByName(Me, lblName, VbGet)
        If lbl Is Nothing Then
            Set lbl = Controls.Add("VB.Label", lblName)
            lbl.Caption = lblName
            lbl.Move 400, n * 360, 720, 240
            lbl.Visible = True
            CallByName Me, "and_d" & CStr(n), VbSet, lbl
            Exit Sub
        End If
    Next
End Sub

Private Sub Remove(ByVal Button As MouseButtonConstants, ByVal Index As Integer)
    If CBool(Button And vbRightButton) Then
        Dim lblName As String
        lblName = "and_d" & CStr(Index)
        Dim lbl As Label
        Set lbl = CallByName(Me, lblName, VbGet)
        Controls.Remove lbl
        CallByName Me, lblName, VbSet, Nothing
    End If
End Sub

Private Sub and_d1_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
    Remove Button, 1
End Sub

Private Sub and_d2_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
    Remove Button, 2
End Sub

Private Sub and_d3_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
    Remove Button, 3
End Sub

Private Sub and_d4_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
    Remove Button, 4
End Sub

Private Sub and_d5_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
    Remove Button, 5
End Sub

編集 削除
qam  2009-11-11 18:44:52  No: 142817  IP: [192.*.*.*]

懇切丁寧な説明ありがとうございました。
案2で無事に対応することができました。

編集 削除