2009-12-16 3 views
1

Я застрял в VB6, и я использую Form.Controls.Add(...), чтобы создать кучу элементов управления во время выполнения.Как ускорить массовое создание элементов управления во время выполнения?

К сожалению, это, по-видимому, очень медленный процесс с сильным мерцанием.

Есть ли способ ускорить процесс? Возможно, можно как-то уведомить VB6, что я делаю массовый ввод новых элементов управления.

+1

.net эквивалент будет приостановлен/возобновлен; –

ответ

5

Вы можете использовать скрытую PictureBox для контейнера, как этот

Set oCtl = Controls.Add("VB.TextBox", "txtMy1", picHidden) 

После этого вы можете либо показать контейнер, который будет так же быстро, как может быть или скрыть элементы управления и сброса контейнера, как это

oCtl.Visible = False 
Set oCtl.Container = Form1 ' or picHidden.Container 

В любом случае вы можете уменьшить мерцание, используя скрытый контейнер.

3

Я использовал контрольные массивы для этого. Создайте один экземпляр каждого типа управления, который вам понадобится - текстовое поле, ярлык, раскрывающийся список и т. Д. Установите для свойства Index каждого элемента управления значение 0 (которое превращает каждый элемент управления в базовый элемент управления для массива управления) , Теперь задайте другим свойствам то, что имеет смысл для каждого типа элементов управления в вашем приложении. Эти свойства будут применены к каждому новому элементу управления по мере его создания. Убедитесь, что свойство Visible установлено False.

Затем добавьте элементы управления во время выполнения с инструкцией Load. Расположите их соответствующим образом, задайте любые уникальные свойства, загрузите свои данные и т. Д., Затем, когда все это будет прокручиваться через каждый массив управления по индексу и установите для свойства Visible для каждого элемента управления значение True. Это достаточно быстро, что позволяет избежать мерцания, по крайней мере, для разумного количества элементов управления. Таким образом я обработал почти 200 элементов управления без мерцания.

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

Действительно, вам нужно управлять индексом для длины каждого массива управления, чтобы сообщить вам, можете ли вы повторно использовать или создать новый, но несколько вспомогательных функций могут значительно помочь упростить необходимое отслеживание. Что-то вроде этого:

Set newTextBox = GetNextTextBox 

где функция GetNextTextBox обрабатывает отслеживание общего количества элементов управления TextBox доступны, и который один является «следующим», чтобы он мог решить, можно ли повторно использовать существующую или должно создать новую.

У вас могут быть такие функции, как, например, ResetTextBoxes, что делает все текстовые поля невидимыми и сбрасывает счетчик «следующий доступный».

3

Отключение формы при создании элементов управления помогает. Если это практично, это еще больше поможет установить Visible = False в этой форме.

+1

Если вы решили сделать форму невидимой, просто имейте в виду, что некоторые элементы управления имеют проблемы с этим состоянием. Одна вещь, которую мы раньше делали, заключалась в том, чтобы позиционировать форму при отрицательных координатах. – CMH

1

Я часто использую вызов API LockWindowUpdate, чтобы отключить рисование в списке при добавлении большого количества элементов. Это значительно ускоряет загрузку и прост для объявления и использования. Я предполагаю, что это будет так же хорошо для формы. Но так как Кен Уайт указал мне на this article, что объясняет, почему использование LockWindowUpdate ошибочно, я начал модифицировать свой код, чтобы вместо этого использовать SendMessage. Пока это работает, как в LockWindowUpdate, так и в программе.

Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long 
Public Const WM_SETREDRAW = &HB 

Private Sub AddMyControls() 

    ' The SendMessage function returns 0 for this message if successful, 
    ' instead of using Call assign the return to a variable to check the success 

    Call SendMesssage(Me.hwnd, WM_SETREDRAW, False, 0) ' prevent re-drawing while adding controls 
    ' .... add controls 

    ' It might be nice to know if the function was successful here 
    ' or re-drawing might not be re-enabled and the user would wonder what's up 
    Call SendMesssage(Me.hwnd, WM_SETREDRAW, True, 0) ' re-enable drawing 

End Sub 
+1

Это последняя вещь, о которой вы должны думать. http://blogs.msdn.com/oldnewthing/archive/2007/02/22/1742084.aspx –

+0

Хорошо, кое-что, чего я раньше не знал. Теперь мне нужно заменить LockWindowUpdate на SendMessage и сравнить функциональность. – jac

Смежные вопросы