unloading items from popup menu error - vb6

i have am getting this error
"Unable to unload within this context"
when ever i try to unload a menu item from the popupmenu like his
For i = mnuTCategory.Count - 1 To 1 Step -1
Unload mnuTCategory(i)
Next
Is there any way to do this without this error>?
Thanks

In order to be able to remove controls from a Form, when triggered by a ComboBox, you will need to execute the deletion operation through a Timer.
So, when the ComboBox event is to be triggered, start (enable) a Timer that when triggered, calls the subroutine that you wanted to call in the first place.
This is how the code would look like:
Private Sub MyCombo_Change()
MyTimer.Enabled = False
MyTimer.Enabled = True
End Sub
Private Sub MyTimer_Timer()
MyTimer.Enabled = False
DeleteMenuItems
End Sub
Private Sub DeleteMenuItems()
Dim i As Intener
For i = mnuTCategory.Count - 1 To 1 Step -1
Unload mnuTCategory(i)
Next
End Sub

my test project below works without errors for me, does it work for you ?
'1 form with :
' 1 command button : name=Command1
' 1 main menu item : name=mnuMain
' 1 sub menu item : name=mnuSub index=0
Option Explicit
Private Sub Command1_Click()
Dim intIndex As Integer
For intIndex = mnuSub.Count - 1 To 1 Step -1
Unload mnuSub(intIndex)
Next intIndex
End Sub
Private Sub Form_Load()
Dim intIndex As Integer
For intIndex = 1 To 3
Load mnuSub(intIndex)
mnuSub(intIndex).Caption = "Sub" & CStr(intIndex)
Next intIndex
End Sub
Edit
funny!
the testproject below gives the same error : it is indeed caused by calling the unload from an combobox ..
'1 form with :
' 1 combobox : name=Combo1
' 1 main menu item : name=mnuMain
' 1 sub menu item : name=mnuSub index=0
Option Explicit
Private Sub Combo1_Click()
Dim intIndex As Integer
With Combo1
Select Case .ListIndex
Case 0 'add
For intIndex = 1 To 3
Load mnuSub(intIndex)
mnuSub(intIndex).Caption = "Sub" & CStr(intIndex)
Next intIndex
Case 1 'del
For intIndex = mnuSub.Count - 1 To 1 Step -1
Unload mnuSub(intIndex)
Next intIndex
End Select
End With 'Combo1
End Sub
Private Sub Form_Load()
With Combo1
.AddItem "add"
.AddItem "del"
End With 'Combo1
End Sub

this intrigues me but i can't find a cleaner solution than using another control, this control can be an control which you already have on your form, or a dummy control just for this purpose. you can then use the lostfocus event of the combobox
see the testproject below :
'1 form with :
' 1 combobox : name=Combo1
' 1 textbox : name=Text1
' 1 main menu item : name=mnuMain
' 1 sub menu item : name=mnuSub index=0
Option Explicit
Private Sub Combo1_Click()
Dim intIndex As Integer
With Combo1
Select Case .ListIndex
Case 0 'add
For intIndex = 1 To 3
Load mnuSub(intIndex)
mnuSub(intIndex).Caption = "Sub" & CStr(intIndex)
Next intIndex
Case 1 'del
Text1.SetFocus
End Select
End With 'Combo1
End Sub
Private Sub Combo1_LostFocus()
'use the lostfocus event to unload stuff
Dim intIndex As Integer
For intIndex = mnuSub.Count - 1 To 1 Step -1
Unload mnuSub(intIndex)
Next intIndex
End Sub
Private Sub Form_Load()
With Combo1
.AddItem "add"
.AddItem "del"
End With 'Combo1
End Sub
Private Sub Text1_GotFocus()
Combo1.SetFocus
End Sub

Related

Using variable as a label control name

In VB 6 How can I refer to control label using a variable instead of a fixed name such as LUH01 (as below) which does not allow a Loop.
Frm_Dispo_Prof_Grille.LUH01.BackColor = &HFF00&
You can refer to it via the Controls Collection:
Frm_Dispo_Prof_Grille.Controls("LUH01").BackColor = &HFF00&
Be careful, however. If you need to refer to a property/method that is not one of the standard/built-in ones, you'll have to cast the control to a type:
Dim lbl as Label
Set lbl = Frm_Dispo_Prof_Grille.Controls("LUH01")
lbl.BackColor = &HFF00
I think you want to create a control array
You can do that by creating 1 control, and set its Index property to 0 (instead of empty)
You can then Load new controls and use them all in a loop
For example to load some command buttons and position them in a loop:
'1 form with :
' 1 command button: name=Command1 index=0
'Number of command buttons to use in the loop
Private Const NRBUTTONS As Integer = 5
Option Explicit
Private Sub Form_Load()
Dim intIndex As Integer
'change the caption of the default button
Command1(0).Caption = "Button 0"
For intIndex = 1 To NRBUTTONS - 1
'load an extra command button
Load Command1(intIndex)
'change the caption of the newly loaded button
Command1(intIndex).Caption = "Button " & CStr(intIndex)
'newly load command buttons are invisible by deafult
'make the new command button visible
Command1(intIndex).Visible = True
Next intIndex
End Sub
Private Sub Form_Resize()
'arrange all loaded command buttons via a loop
Dim intIndex As Integer
Dim sngWidth As Single
Dim sngHeight As Single
sngWidth = ScaleWidth
sngHeight = ScaleHeight / NRBUTTONS
For intIndex = 0 To NRBUTTONS - 1
Command1(intIndex).Move 0, intIndex * sngHeight, sngWidth, sngHeight
Next intIndex
End Sub

Errror when trying to set the text of a ComboBox control

This is my code that tries to set the text of a ComboBox when I click an item in a ListView.
Private Sub ListView1_Click()
If ListView1.ListItems.Count > 0 Then
Text1.Text = ListView1.ListItems(ListView1.SelectedItem.Index).Text
Text2.Text = ListView1.ListItems(ListView1.SelectedItem.Index).ListSubItems(1).Text
Sql = "SELECT A.AID,B.LOC_NAME,C.SNAME FROM ASSET A,LOCATION B,SUPPLIER C WHERE "
Sql = Sql + "A.LOC_ID=B.LOC_ID AND A.SUP_ID=C.SUP_ID AND AID=" & Text1.Text
RS.Open Sql, CON, 1, 2
COM1
Combo1.Text = RS!LOC_NAME //combo with style - 2
COM5
Combo5.Text = RS!SNAME //combo with style - 2
End If
End Sub
Private Sub COM5()
If Combo5.ListIndex = -1 Then
For I = 0 To Combo5.ListCount - 1
Combo5.ListIndex = I
Next
End If
End Sub
Private Sub COM1()
If Combo1.ListIndex = -1 Then
For I = 0 To Combo1.ListCount - 1
Combo1.ListIndex = I
Next
End If
End Sub
However, when I click on the ListView1, I get this error:
'text' property is read only
Can anyone explain why?
For a combobox with the dropdown list style you can only select an item with .text if that item already exists, so combo1.text = "xxx" errors if "xxx" is not present in the list.
To select or add based on existence you can;
Private Sub SelectOrAddToCombo(combo As ComboBox, value As String)
Dim i As Long
With combo
For i = 0 To combo.ListCount - 1
If StrComp(.List(i), value, vbTextCompare) = 0 Then
combo.ListIndex = i
Exit Sub
End If
Next
.AddItem value
.ListIndex = .NewIndex
End With
End Sub
...
SelectOrAddToCombo Combo1, RS!LOC_NAME
SelectOrAddToCombo Combo5, RS!SNAME
It's not clear what the point of your COM5()/COM1() routines are.
For the listview, rather than click look at the
ListView1_ItemClick(ByVal Item As MSComctlLib.ListItem)
event which passes you the clicked item negating the need for ListView1.SelectedItem (which can cause errors if its Nothing).
yes, you must populate the combobox with the array(using additem value) before set the .text propierty, if the text that you want to set on the combobox does not exits in the array you get this error

vb6 check if multiple timers

In my application I got few timers, timer1 too timer5. timer1 activates timer2 and so on setting the previous timer to false.
so I want to make another timer that follow these, like "timer6"
if timer1.enabled = true then 'then it should check if the timer2 now is enabled
if timer2.enabled = true then 'and so on to it reaches timer5..
Need any example to achieve this because I am at a stop point and basically just need this part to work.
my idea was just to do this in the timer6
if timer1.enabled = true then
if timer2.enabled = true then
if etc etc
else
timer6.enabled = true
timer6.enabled = false
end if
end if
end if
end sub
any ideas how to accomplish this?
So.. I am looking for a way to check all the timers are enabled in one condition and disable the last one.
I am not sure you can check al the timers at once but what you can do is to keep array of all the timers corresponding Boolean field.
array = collection[timerState{timer1,true},timerState{timer2,false}]
Then on each timer enabled/disabled event you keep this state array updated.
and lastly wherever you want you will have the state for all the timers.
have a look at the following test project
click the form to start the first timer, click the button to check which timer is active
'1 form with
' 1 timer : name=Timer1 Index=0
' 1 command button : name=Command1
Option Explicit
Private Sub Form_Load()
Dim intIndex As Integer
Timer1(0).Enabled = False
Timer1(0).Interval = 1000
For intIndex = 1 To 5
Load Timer1(intIndex)
Timer1(intIndex).Interval = intIndex * 1000
Next intIndex
End Sub
Private Sub Form_Click()
Timer1(0).Enabled = True
End Sub
Private Sub Timer1_Timer(Index As Integer)
Print CStr(Now)
Timer1(Index).Enabled = False
If Index < Timer1.Count - 1 Then
Timer1(Index + 1).Enabled = True
Else
Print "done"
End If
End Sub
Private Sub Command1_Click()
Dim intIndex As Integer
For intIndex = 0 To Timer1.Count - 1
If Timer1(intIndex).Enabled Then
Caption = "active timer : " & CStr(intIndex)
Exit For
End If
Next intIndex
End Sub

Applying a command on many objects ? VB6

thanks for reading.
I'm writing a program to create a list consisting of 8 cols. so there are8 listboxes and a textbox under each one.
I want to check each textbox one by one if anyone is empty or not. ...and dunno how to do that!
I need your help!
thanks
instead of using 8 listboxes you might consider using a flexgrid control
but using 8 listboxes and 8 textboxes, you can create them as an array and check them as follows :
'1 form with with
' 1 listbox : name=List1 index=0
' 1 textbox : name=Text1 index=0
' 1 commandbutton : name=Command1
Option Explicit
Private Sub Command1_Click()
If IsEmpty Then
MsgBox "Textboxes are all empty", vbInformation, "IsEmpty"
Else
MsgBox "At least 1 Textbox is not empty", vbInformation, "IsEmpty"
End If
End Sub
Private Sub Form_Load()
Dim intIndex As Integer
For intIndex = 1 To 7
Load List1(intIndex)
Load Text1(intIndex)
List1(intIndex).Visible = True
Text1(intIndex).Visible = True
Next intIndex
Move 0, 0, 10000, 10000
End Sub
Private Function IsEmpty() As Boolean
Dim intIndex As Integer
Dim blnEmpty As Boolean
blnEmpty = True
For intIndex = 0 To Text1.Count - 1
If Len(Text1(intIndex).Text) > 0 Then
blnEmpty = False
Exit For
End If
Next intIndex
IsEmpty = blnEmpty
End Function
Private Sub Form_Resize()
Dim intIndex As Integer
Dim sngWidth As Single
Dim sngListWidth As Single, sngListHeight As Single
Dim sngTextHeight As Single
Dim sngCmdHeight As Single
sngWidth = ScaleWidth
sngListWidth = sngWidth / List1.Count
sngTextHeight = 315
sngCmdHeight = 315
sngListHeight = ScaleHeight - sngTextHeight - sngCmdHeight
For intIndex = 0 To List1.Count - 1
List1(intIndex).Move intIndex * sngListWidth, 0, sngListWidth, sngListHeight
Text1(intIndex).Move intIndex * sngListWidth, sngListHeight, sngListWidth, sngTextHeight
Next intIndex
Command1.Move 0, sngListHeight + sngTextHeight, sngWidth, sngCmdHeight
End Sub

Handling up- and down-arrow keys in a ListBox in VB6

Public Sub subkeydown(txt As TextBox, lst As ListBox, KeyCode As Integer)
On Error Resume Next
lstfstrec = True
If txt.Text = "" Then lst.Visible = False: Exit Sub
If KeyCode = 40 Then
lst.Selected(lst.ListIndex + 1) = True ': Exit Sub
'MsgBox lstMedicine.ListIndex
End If
If KeyCode = 38 Then lst.Selected(lst.ListIndex - 1) = True ': Exit Sub
End Sub
I have a function named subkeydown() in my project (see above), which is called when the user presses the up-arrow or down-arrow keys. When the function is called, the ListBox's click event is fired. The ListBox contains medicine product name and is bound to a database, so I want to call the Click event when the user clicks on the ListBox but not automatically.
You can set a flag "isUpDownClicked" to true when clicking the up/down button, and in your Sub List_Click you exit sub when flag is true, like:
Option Explicit
Dim lstfstrec As Boolean
Dim isUpDownClicked As Boolean
Public Sub subkeydown(txt As TextBox, lst As ListBox, KeyCode As Integer)
On Error Resume Next
lstfstrec = True
If txt.Text = "" Then lst.Visible = False: Exit Sub
If KeyCode = 40 Then
lst.Selected(lst.ListIndex + 1) = True ': Exit Sub
'MsgBox lstMedicine.ListIndex
End If
If KeyCode = 38 Then lst.Selected(lst.ListIndex - 1) = True
End Sub
Private Sub CommandUp_Click()
isUpDownClicked = True
subkeydown Text1, lstMedicine, 38
End Sub
Private Sub CommandDown_Click()
isUpDownClicked = True
subkeydown Text1, lstMedicine, 40
End Sub
Private Sub Form_Load()
lstMedicine.AddItem "1"
lstMedicine.AddItem "2"
lstMedicine.AddItem "3"
End Sub
Private Sub lstMedicine_Click()
If isUpDownClicked Then
isUpDownClicked = False
Label1.Caption = "no"
Exit Sub
End If
Label1.Caption = "lst_Click"
End Sub

Resources