Итерация управления VB6: один элемент управления дает мне ошибку; который из? - PullRequest
2 голосов
/ 29 октября 2009

Я пытаюсь перебрать все элементы управления в форме: Для каждого Ctrl в Me.Controls Для того, чтобы включить / отключить управление на основе некоторых условий. Но в форме есть элемент управления, который выдает ошибку, когда я пытаюсь получить к ней доступ. Что это за контроль и как мне его найти?

Ответы [ 6 ]

1 голос
/ 04 ноября 2009

Попробуйте это:

Dim ctr As Control
Dim CtrStatus Boolean

CtrStatus = False

For Each ctr In Me.Controls

  If (SSTab.hwnd = GetParent(ctr.hwnd)) Then
    Call CallByName(ctr, "Enabled", VbLet, CtrStatus)
  else
    ctr.Enabled = CtrStatus
  End If

Next
1 голос
/ 29 октября 2009

Когда вы получаете ошибку и нажимаете «Отладка», является ли ошибка в строке, устанавливающей свойство Enabled элемента управления?

Если это так, добавьте оператор Debug.Print, записав имя элемента управления. Сделайте это в строке перед установкой свойства Enabled.

Вот что я имею в виду:

Dim ctrl As Control
For Each ctrl In Me.Controls
    Debug.Print ctrl.Name
    ctrl.Enabled = True      
Next

Оператор Debug.Print запишет в Immediate Window имя элемента управления, который был последним обработан в цикле, предположительно тот, который вызвал вашу ошибку.

EDIT

Это может работать. Поместите этот элемент управления в элемент управления Panel и установите для свойства Enabled Panel значение False. Если я правильно помню, в VB6 установка свойства Enabled элемента управления контейнера на False также установит для дочерних элементов управления контейнера Enabled значение False. Если свойство Enabled вашего элемента управления действительно доступно только для чтения, мне интересно, что произойдет.

0 голосов
/ 10 июля 2014

Чтобы избежать таких проблем, следуйте приведенным правилам при именовании контролей

  • Когда вы называете элемент в приложении Visual Basic, первый символ этого имени должен быть буквенным символом или подчеркиванием.

  • ** Начинайте каждое отдельное слово в имени с заглавной буквы, как в FindLastRecord и RedrawMyForm.

  • Начинайте имена функций и методов с глагола, как в InitNameArray или CloseDialog. Начинайте имена классов, структур, модулей и свойств с существительного, как в EmployeeName или CarAccessory.

  • Начинайте имена интерфейсов с префикса «I», за которым следует существительное или именная фраза, например IComponent, или с прилагательным, описывающим поведение интерфейса, например IPersistable. Не используйте подчеркивание и экономно используйте сокращения, потому что сокращения могут вызвать путаницу.

  • Начинайте имена обработчиков событий с существительного, описывающего тип события, за которым следует суффикс «EventHandler», как в «MouseEventHandler».

  • В названиях классов аргументов событий включайте суффикс «EventArgs». Если событие имеет понятие «до» или «после», используйте суффикс в настоящем или прошедшем времени, как в «ControlAdd» или «ControlAdded».

  • Для длинных или часто используемых терминов используйте сокращения для сохранения разумной длины имен, например, «HTML» вместо «Язык разметки гипертекста». Как правило, имена переменных длиной более 32 символов трудно читать на мониторе с низким разрешением. Кроме того, убедитесь, что ваши сокращения согласованы во всем приложении. Случайное переключение в проекте между «HTML» и «Hypertext Markup Language» может привести к путанице.

  • Избегайте использования имен во внутренней области, которые совпадают с именами во внешней области. Ошибки могут возникнуть, если к неправильной переменной обращаются. Если возникает конфликт между переменной и ключевым словом с тем же именем, вы должны определить ключевое слово, поставив перед ним соответствующую библиотеку типов. Например, если у вас есть переменная с именем Date, вы можете использовать встроенную функцию Date только путем вызова DateTime.Date.

0 голосов
/ 04 марта 2010

Подавить отчеты об ошибках перед циклом, а затем вернуть его к стандартной обработке ошибок:

On Error Resume Next
 For Each ctrl In Me.Controls
      ctrl.Enabled = lIsEnabled
 Next
 On Error GoTo 0

ИЛИ присвойте своим элементам управления стандартный префикс / суффикс, который вы можете проверить по имени и пропустить в цикле.

For Each ctrl In Me.Controls
      If Left(ctrl.Name, 3) = "sst" Then
           ctrl.Enabled = lIsEnabled
      End If
 Next
0 голосов
/ 30 октября 2009

Tosa: из вашего комментария на Ответ AngryHacker , я думаю, что вы проверяете контейнер неправильно.

Ваш код такой

 ' BAD CODE '
 If ctrl.Container = fraMovies Then

Для меня это дает ошибку 450 Wrong number of arguments or invalid property assignment. Вы получаете ту же ошибку?

Код должен использовать Is вместо =, как это

 ' GOOD CODE '
 If ctrl.Container Is fraMovies Then

Объяснение. Вы хотите проверить, указывают ли две переменные на один и тот же элемент управления. Элементы управления являются объектами: вы должны использовать Is, а не =, чтобы проверить, указывают ли две переменные объекта на один и тот же объект. Это классическая ловушка в VB6.

Последнее слово. В следующий раз, не могли бы вы попытаться опубликовать 10 или менее строк фактического кода, воспроизводящего ошибку, и указать точный номер ошибки, сообщение и точную строку, в которой она произошла? Нам действительно легче решить вашу проблему - я знаю, что вам нужно сократить код, но вы получите лучшие ответы таким образом.

РЕДАКТИРОВАТЬ С возвращением! :) Вы сказали, что некоторые элементы управления не имеют свойства контейнера. Вы можете попробовать обернуть тест в On Error Resume Next, что-то вроде этого.

 ' GOOD CODE '
 Dim bMatch As Boolean  
 Dim ctrl As Control 
 For Each ctrl In Me.Controls 
   bMatch = False  
   On Error Resume Next  
   bMatch = (ctrl.Container Is fraMovies)  
   On Error Goto 0 
   If bMatch Then  
     ctrl.Enabled = True       
   End If
 Next 
0 голосов
/ 30 октября 2009

Другой подход заключается в следующем, который также работает во время выполнения (в отличие от только в IDE):

private sub SetEnabled()
  on error goto errHandle

  Dim ctrl As Control
  For Each ctrl In Me.Controls
    ctrl.Enabled = True      
  Next

  exitPoint:
    exit sub
  errHandle:
    MsgBox "Error " & err.Description & " with Control " & ctrl.Name
    resume exitPoint
end sub
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...