• 15 апреля стартует «Курс «SQL-injection Master» ©» от команды The Codeby

    За 3 месяца вы пройдете путь от начальных навыков работы с SQL-запросами к базам данных до продвинутых техник. Научитесь находить уязвимости связанные с базами данных, и внедрять произвольный SQL-код в уязвимые приложения.

    На последнюю неделю приходится экзамен, где нужно будет показать свои навыки, взломав ряд уязвимых учебных сайтов, и добыть флаги. Успешно сдавшие экзамен получат сертификат.

    Запись на курс до 25 апреля. Получить промодоступ ...

копирование данных из ЛистБокса в КомбоБокс

  • Автор темы Alex77777
  • Дата начала
A

Alex77777

есть код, но он работает только если Лист- и комбоБоксы находятся на одной форме. Вопрос:как сделать так чтобы данные из листбокса формы1 копировались в комбобокс формы2.

Visual Basic:
Private Declare Function SendMessageStr Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As String) As Long
Private Declare Function SendMessageLong Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

Private Sub Command1_Click()
Dim success As Long

success = CopyListToCombo(List1, Combo1)
If success Then Combo1.ListIndex = 0
End Sub

Private Function CopyListToCombo(source As ListBox, target As ComboBox) As Long
Dim c As Long
Const LB_GETCOUNT = &H18B
Const LB_GETTEXT = &H189
Const CB_GETCOUNT = &H146
Const CB_ADDSTRING = &H143

Dim numitems As Long
Dim sItemText As String * 255

numitems = SendMessageLong(source.hWnd, LB_GETCOUNT, 0&, 0&)
If numitems > 0 Then
For c = 0 To numitems - 1
Call SendMessageStr(source.hWnd, LB_GETTEXT, c, ByVal sItemText)
Call SendMessageStr(target.hWnd, CB_ADDSTRING, 0&, ByVal sItemText)
Next
End If

numitems = SendMessageLong(target.hWnd, CB_GETCOUNT, 0&, 0&)
CopyListToCombo = numitems
End Function

Private Sub Form1_Load()
List1.AddItem "1"
List1.AddItem "2"
List1.AddItem "3"
End Sub

этот код работает в пределах одной формы

Пытался сделать так:
в Form1

Public success As Long 'глобальная переменная
Private Declare Function SendMessageStr Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As String) As Long
Private Declare Function SendMessageLong Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

Private Function CopyListToCombo(source As ListBox, target As ComboBox) As Long
Dim c As Long
Const LB_GETCOUNT = &H18B
Const LB_GETTEXT = &H189
Const CB_GETCOUNT = &H146
Const CB_ADDSTRING = &H143
Dim numitems As Long
Dim sItemText As String * 255
numitems = SendMessageLong(source.hWnd, LB_GETCOUNT, 0&, 0&)
If numitems > 0 Then
For c = 0 To numitems - 1
Call SendMessageStr(source.hWnd, LB_GETTEXT, c, ByVal sItemText)
Call SendMessageStr(target.hWnd, CB_ADDSTRING, 0&, ByVal sItemText)
Next
End If
numitems = SendMessageLong(target.hWnd, CB_GETCOUNT, 0&, 0&)
CopyListToCombo = numitems
End Function

а в Form2
Private Sub Form1_Load()
Dim success As String
success = Form1.success
cboExpert.AddItem success
End Sub

в итоге в комбобокс Form2 у меня добавляется только цифра равная кол-ву введенных строк в листбокс Form1.

кто знает в чем здесь запинка, подскажите как ее исправить.

при этом нужно чтобы при нажатии на клавишу "очистить" листбокса на Form1 очищался комбобокс на Form2
 
Последнее редактирование модератором:
T

Tanya

используй полные имена контролов, то есть со ссылкой на родительскую форму

Допустим List1 и Command1 на форме Form1, а Combo1 на Form2
тогда

Private Sub Command1_Click()
Dim success As Long
success = CopyListToCombo(List1, Form2.Combo1)
If success Then Form2.Combo1.ListIndex = 0

End Sub

ну и соответственно очистка обоих элементов:
Form1.List1.Clear
Form2.Combo1.Clear
 
A

Alex77777

все работает, только вот какая штука, нажимая на кнопку копировать в комбобокс - открывается сразу Form2, а мне нужно чтобы при нажатии кнопки копировать Form2 не открывалась, а данные из листбокса копировались в комбокосе были при каждом открытии Form2. то есть сначала я открываю Form1, вношу в листбокс данные, затем открываю Form2, и в комбобоксе д.б. данные, затем открываю вторую Form2, третью Form2 и т.д.

пробовал вставить
Dim success As String
success = frmMyInstallations.success
cboExpert.AddItem success
success = CopyListToCombo(frmMyInstallations.lstFIO, frmNewVisit.cboExpert)
If success Then frmNewVisit.cboExpert.ListIndex = 0

в этом случае пишет ошибка компиляции: Sub or Function not defined

по другому пробовал в Form2_Load() весь код запихать, но он ругается, пишет: "обнаружено не однозначное имя SendMessageLong" (подсвечивает "CopyListToCombo" в Form2).
 
T

Tanya

Конечно нужно список combo заполнять при каждой загрузке окна Form2

При этом функцию CopyListToCombo лучше сделать Public и разместить в отдельном модуле,
где так же продекларировать только 1 раз все SendMessage
(тут уже на твое усмотрение как она будет использоваться: как Private или Public)

А затем в событии Form_Load формы Form2 использовать CopyListToCombo

Кнопка копирования в комбобокс, скорее всего не нужна, поскольку, действительно,
будет либо открываться окно Form2 (если использовать Form2.Show),
либо окно будет загружено в память, но не будет отображаться (если испльзовать Load Form2)
что в обоих случаях не очень хорошо.

Такая кнопка может быть необходима для изменения списков комбобоксов открытых окон Form2
то есть при добавлении в список List1 нужно добавить во все списки Form2.Combo1
Но даже здесь можно обойтись без такой кнопки, а автоматически добавлять строку во все списки:
Form1.List1.AddItem "NewLine"
For Each F In Forms
if F.Name = "Form2" then
F.Combo1.AddItem "NewLine"
End If​
Next F
 
A

Alex77777

я что-то совсем не могу здесь разобраться
я не умею работать с модулями, пытался применять их в работе, но ничего неполучается.
объявляю
Public Function CopyListToCombo(source As ListBox, target As ComboBox) As Long в Form1
а в Form_Load формы Form2 пишу
Dim success As String
success = Form1.CopyListToCombo
Combo1.AddItem success

он ругается Ошибка компиляции: Argument not optional

пробовал и так в Form_Load формы Form2

Dim success As Long
Function CopyListToCombo(List1, Combo1)
If success Then Combo1.ListIndex = 0
End Function

пишет Expected End Sub
 
T

Tanya

По второму варианту :
обрати внимание на то что Form_Load это Sub, а не Function
поэтому и пишет Expected End Sub

Код:
Dim success As Long
Function CopyListToCombo(List1, Combo1)
If success Then Combo1.ListIndex = 0
End Sub
 
A

Alex77777

я понимаю что пытаюсь в процедуру Form_Load запихнуть функцию. только вот никак не получается.
не могу понять как здесь быть. :blink:
 
T

Tanya

эта функция может быть вынесена в отдельный модуль и объявлена
как глобальная (то есть возможно она может быть объявлена глобальной
и в модуле формы, наверно ..., я не уверена :))

Function CopyListToCombo(List1, Combo1)
If success Then Combo1.ListIndex = 0
End function

а затем вызвана из модуля формы (любой формы)
например

Private Sub Form_Load()
Dim success As String
success = CopyListToCombo(Form1.List1, Form2.Combo1)
Form2.Combo1.AddItem success
End Sub
 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!