|
Последнее обновление 11/27/02. |
87 Хитростей и трюков для Visual Basic'a. Cодержание
1 УПРАВЛЕНИЕ СОБЫТИЯМИ В КОМБОБОКСЕ
Две проблемы могут приключиться, когда смущенный юзер ползает по комбобоксу при помощи мышки вверх и вниз, а затем нажатием на Enter делает свой юзерский выбор. Во-первых, нажатие на серую стрелочку вызывает два события: Change и Click. Во-вторых, нажатие на Enter перемещает фокус к следующему элементу формы, тогда как нажатие на кнопку мыши не вызывает подобного эффекта (т.е. фокус остается на комбобоксе). Поэтому, если Ваш код помещен в секцию события Change, то на стрелочки вверх/вниз (клавиатурой) вызовет это событие, чего Вы, естественно, не хотите. Напротив, если Вы помещаете свой код только в секцию события Lost Focus и юзер щелкает мышью на своем выборе, то фокус не уйдет из комбобокса, а юзер будет созерцать текст, который он выбрал своей мышью, и думать, почему это ничего не происходит. Нижеприведенное решение «фильтрует базар» событий Click, генерирующихся нажатиями на стрелочки клавиатуры, и вынуждает контрол потерять фокус.В секции Declarations формы введите следующее ' В VB3 надо поменять тип флага на integer А этот код введите в секции события Form_Load: bNoise = False Этот код введите в событии KeyDown комбобокса: Private Sub cbTest_KeyDown(KeyCode As _ Этот код вводится в событии Click комбобокса: Private Sub cbTest_Click() Теперь Вам остается написать код,
содержащий реакцию на выбор юзера, и
занести его в секцию события LostFocus комбика. Назад к СОДЕРЖАНИЮ
2. КОММЕНТИРОВАНИЕ И РАСКОММЕНТИРОВАНИЕ БЛОКОВ КОДАVB5 VB 5.0 позволяет Вам разом закомментировать
целый блок кода, а затем также быстро
раскомментировать его. Это очень полезно
при отладке, когда Вам не нужно исполнять
целый ряд операторов, и в то же время Вы не
можете их удалить вот так вот просто за
здорово живешь. Между тем, пара кнопарей
Comment/Uncomment присутствует только в тулбаре Edit,
который надо специально вызывать :-(. Чтобы
быстро вызвать тулбар Edit, кликните правой
кнопкой мыши на любом тулбаре в VB, и
выберите затем команду Edit. Назад к СОДЕРЖАНИЮ
3. ЗНАЧЕНИЯ ПО УМОЛЧАНИЮ ДЛЯ НЕОБЯЗАТЕЛЬНЫХ ПАРАМЕТРОВVB5 Если Вы когда-либо программили на VB4, то Вы возможно пользовались мощной фишкой под названием Необязательные параметры (Optional parameters). VB5 пошел еще дальше: теперь эти параметры могут быть любого типа (не только Variants), и могут появляться в процедурах Property. Интересно, что Вы можете теперь задавать для них значение по умолчанию. Property Get Value _ Вы можете теперь делать это без бывшего ранее обязательным (и жутко тормозным) тестом IsMissing: Property Get Value _
Назад к СОДЕРЖАНИЮ4. НЕ СОЗДАВАЙТЕ ALIAS-НЫХ ПЕРЕМЕННЫХVB5 Никогда не передавайтe глобальную
переменную в качестве аргумента в
процедуру, которая также напрямую
обращается к этой переменной из себя (зачем??).
Если Вы на 100% уверены, что следуете этому
правилу в Ваших программах, то зачеркните
опцию Assume No Aliasing в диалоговом окне Advanced
Optimizations, которое вызывается из пункта Compile
диалога Project Properties (уф, надеюсь, понятно).
Если компилятор native code знает, что этих самых
alias-ных переменных нет, то он спокойно
копирует значения переменных в шустрые
регистры ЦПУ, и переписывает их значения
обратно в RAM только при выходе из процедуры.
Это увеличивает скорость исполнения
скомпилированных программ. Назад к СОДЕРЖАНИЮ5. ЦЕНТРИРОВАНИЕ ФОРМЫ НА ЭКРАНЕVB5 Все знают о маленьком кодике, позволяющем Вам центрировать форму на экране вне зависимости от графического разрешения. Теперь Вы можете достичь того же результата, всего лишь присвоив значение vbStartUpScreen (=2) новому свойству StartUpPosition формы (появилось в версии 5). Вы даже можете отцентрировать форму относительно ее родительского окна, присвоив значение vbStartUpOwner (=1). Присвоение можно сделать в окне Property соответствующей формы. Когда Вы центрируете форму внутри родительского окна, не забудьте добавить второй аргумент в методе Show. Form2.Show vbModal, Me
Назад к СОДЕРЖАНИЮ6. НЕ УВЛЕКАЙТЕСЬ АВТООПТИМИЗИЦИЕЙ FAST CODEVB5 Если взглянуть на опции native code
оптимизации, то сперва так и подмывает
щелкнуть на "Optimize for Fast Code". Однако, как
ни странно это может прозвучать, данное
действие далеко не всегда гарантирует
ожидаемый эффект. Аппликухи,
оптимизированные на скоростное исполнение,
как правило, не оптимизируются (пардон за
каламбур), а лишь получают большее
количество памяти при загрузке. Это
обращается для них более медленной
загрузкой, что особенно заметно на машинах
с недостаточным количеством RAM, и в итоге
создает впечатление, что Ваша аппликуха
работает медленнее, нежели
оптимизированная под компактный код. По той
же самой причине, советуется компилить
аппликухи в P-code. В случае объемных, UI- и
базоданских аппликух, выигрыш от
компиляции в native-code отнюдь не перевесит
увеличения размера аппликухи. Вообще, чтобы
точно знать, какая компиляция нужна Вам,
юзайте VB Application Performance Explorer (APE), который
лежит на VB CD. Назад к СОДЕРЖАНИЮ7. НЕ ВСЕ ШАБЛОНЫ СОЗДАНЫ ОДИНАКОВОVBA5 В отличие от других продуктов Office 97,
шаблоны Word 97 содержат business-application engine,
который хранится отдельно от документов,
использюущих этот engine. Основанные на
шаблонах книги Excel и презентации PowerPoint
хранят в себе шаблоны, на основе которых они
созданы. На практике, все документы Word
состоят из 2х VBA проектов: первый проект
создан на базе основного(оригинального,
хранящегося в Word) шаблона (все документы Word
основаны на шаблонах), а второй проект
принадлежит самому документу Word. С другой
стороны, книги Excel и презентации PowerPoint,
созданные на шаблонах, содержат только один
VBA проект. Каждый файл содержит свою
собственную копию проекта оригинального
шаблона. Изменения, производимые в этом
шаблоне, не затрагивают основной шаблон,
хранящийся в приложении. Назад к СОДЕРЖАНИЮ8. НАСТРОЙКА ТУЛБАРОВ В VBVB5 Вот несколько предложений по настройке IDE
в VB5: Назад к СОДЕРЖАНИЮ9. КАК СПРЯТАТЬ ВСЕ ОКОШКИ ПРОЕКТАVB5 Когда Вы работаете с несколькими пректами
сразу, можно запутаться в нагромождении
туевой хучи окошек из разных проектов.
Однако, Вы можете временно спрятать все
окошки, относящиеся к данному проекту,
щелкнув по пиктограмме проекта в окошке
Project Explorer так, чтобы все ветви, торчащие из
него, исчезли. Тогда же свернутся и все окна,
относящиеся к данному проекту. Эту
возможность можно отменить, щелкнув на
сответствующем квадратике на закладке General
в меню Tools-Options. Назад к СОДЕРЖАНИЮ10. STANDALONE БИБЛИОТЕКИ ТИПОВ VB4 16/32, VB5 (Enterprise Edition) Koгда Вы создаете Ваш out-of-process OLE сервер, то
VB встраивает библиотеку типов сервера (companion
type library) в EXE-файл, не генерируя при этом .TLB
файл. Однако, если у Вас Enterprise Edition VB4 или VB5,
то зачеркнув квадратик Remote Server File, Вы
заставите VB создавать standalone билиотеку
типов. В VB5, эта опция находится на вкладке
Component диалогового окна Properties меню Project. Назад к СОДЕРЖАНИЮ11. ИСПОЛЬЗОВАНИЕ OBJECT BROWSER’a длЯ нахождениЯ недокументированных возможностейVB5 Назад к СОДЕРЖАНИЮ12. АДРЕС ПЕРЕМЕННОЙ VB4 16/32 В VB5 есть встроенная функция VarPtr (см. Совет «ИСПОЛЬЗОВАНИЕ OBJECT BROWSER’a длЯнахождениЯ недокументированных возможностей»), но этой функции нет в VB4. Runtime library в VB4 включает эту функцию, но перед использованием ее нужно сначала объявить: #If Win16 Then Эта функция полезна при передаче
пользовательских типов (Type structure) во внешнюю
процедуру API, и в этом типе какое-либо из
полей является адресом другой переменной
или записи. Назад к СОДЕРЖАНИЮ13. КОГДА BENCHMARK’и (ИЗМЕРЕНИЯ СКОРОСТИ РАБОТЫ ПРОГИ) ДЛЯТСЯ СУТКАМИ VB4 16/32, VB5 Обычно, программисты на VB измеряют скорость выполнения кода при помощи Timer функции. Однако, если Ваша программа должна завершиться на следующий день, то Вы должны учесть, что значение, возвращаемое функцией Timer, ресетится в полночь. Если же Вас устроит значение с точностью до одной секунды, Вы можете упростить Ваш код с помощью функции Now. Dim startTime As Date Вам понадобится функция Format$ для
округления результата до целого. Назад к СОДЕРЖАНИЮ14. APP.PATH МОЖЕТ ВОЗВРАЩАТЬ UNC-ПУТИ В отличие от VB4, App.Path в VB5 может возвращать UNC-путь, типа "\\server\programs\...", в зависимости от обстоятельств, от того как запущена программа и запущена она из VB IDE или скомпилирована в EXE-файл. Эта особенность может сильно испортить вам жизнь, если Вы используете App.Path для установки текущего каталога при старте программы. ChDrive App.Path Поскольку ChDrive на умеет обрабатывать UNC-пути,
этот код может вызвать фатальную ошибку
времени выполнения, но можт быть защищен
использованием On Error Resume Next. Однако этот
фикс не защитит Вас от всех невзгод, могущих
произойти. Наилучшее решение состоит в том,
чтоюы предоставить юзеру самому ввести
каталог во время исполнения программы,
затем записать полученный путь в регистр
или INI-файл. Для более подробной инфы, см.
статью Q167167 в Microsoft Knowledge Base. Назад к СОДЕРЖАНИЮ15 ЕЩЕ ОБ УНИВЕРСАЛЬНЫХ ПАРАМЕТРАХ МАССИВОВ VB4 16/32, VB5 ' return the number of items Вы можете даже запулить в процедуру многомерный массив с любым колическтвом измерений, а чтобы разобраться, сколько же у этого массива измерений, нужно производить обращения к функциям UBound и Lbound до возникновения ошибки: Function ItemCount(anArray As Variant)As Long Назад к СОДЕРЖАНИЮ16. УМЕНЬШИТЬ РАЗМЕР КОДА, ИСПОЛЬЗУЯ ОПЕРАТОРЫ IIF И SWITCHVB4 16/32, VB5 ' возвращает большую из двух сравниваемых
величин Switch - редко используемая функция, даже в тех многочисленных случаях, когда она более полезна нежели длиннющий блок If...ElseIf: ' надо узнать, х полижительный,
отрицательный, или равен 0? Заметим, что значение последней проверки
всегда True, так как три условия являются
взаимно исключающими и избыточными. Назад к СОДЕРЖАНИЮ17. УСКОРЬТЕ ВАШ КОД ИСПОЛЬЗОВАНИЕМ CHOOSEVB3, VB4 16/32, VB5 Вы можете использовать Choose там, где можно заменить массив или построить таблицы результатов, на стадии компиляции (compile-time), вместо того, чтобы делать это на стадии выполнения (run time). Например, если Вам надо знать значения факториалов чисел от 1 до 10, попробуйте следующий пример (Choose производит выбор факториала из набора имеющихся значений всесто того, чтобы высчитывать факториал каждый раз заново): Function Factorial(number As Integer) _ Назад к СОДЕРЖАНИЮ18. GOSUBS РАБОТАЮТ МЕДЛЕННО В ОТКОМПИЛИРОВАННЫХ ПРОГРАММАХ VB5 Поскольку использование GoSubs относится к
неструктурированному стилю
программирования, то многие программисты
стараются избегать его. Если Вы
компилируете Вашу VB5 аппликуху в native code, у
Вас появится еще одна причина избегать этот
оператор, поскольку вызовы через GoSubs могут
происходить в пять раз медленнее, чем
вызовы обычной процедуры или функции. Назад к СОДЕРЖАНИЮ19. «ARRAY» - ОТНЫНЕ ЭТО ОШИБОЧНОЕ ИМЯ ДЛЯ ПЕРЕМЕННЫХVB5 Если Вы, как и я, часто используете имя
"array" для переменных, Вам придется
пересмотреть Ваш код при переносе его под
VB5. Это слово является теперь
зарезервированным (reserved keyword) и не может
быть использовано в качестве имени
переменной. Вы можете легко переделать Ваш
код при помощи команды Replace в IDE VB5, не
забудьте при этом черкнуть "Find whole words
only". Назад к СОДЕРЖАНИЮ20. ЗАПУСК AUTOMATION MANAGER КАК HIDDEN ЗАДАЧИVB4 16/32, VB5 Enterprise Edition Если Вы мспользуете OLE Remote Automation, Вы должны
заранее запустить Automation Manager на сервере до
того как случится первая OLE remote communication. По
умолчанию, это приложение visible, но Вы можете
его спрятать, чтобы оно не мозолило глаза на
таскбаре Чикаги. Для этого создайте ярлык
для Automation Manager, который бы включал в
командной строке переключатель /Hidden: Назад к СОДЕРЖАНИЮ21. ПРОБЛЕМЫ СО ВСПЛЫВАЮЩИМИ МЕНЮ VB4 16/32, VB5 Если Вы используете всплывающие меню (popup
menus) в Ваших прогах, то опасайтесь бага,
имеющегося в VB4 16/32 и VB5. Если у Вас есть две
формы и одна из них вызывает вторую
модальную через всплывающее меню, то из
этой второй модальной Вы не сможете вызвать
ни одного всплывающего меню, сколько бы их
на ней ни было. Чтобы пофиксить это дело,
используйте таймер на первой форме. Вместо
показа фторой формы из всплывающего меню по
событию Click, активизируйте таймер так, чтобы
он показал эту вторую форму через несколько
миллисекунд. Для более полной инфы, см.
Статью Q167839 in the Microsoft Knowledge Base. 22. ИСПОЛЬЗОВАНИЕ КОЛЛЕКЦИИ ДЛЯ ОТФИЛЬТРОВЫВАНИЯ ДУБЛИРОВАННЫХ ЗНАЧЕНИЙVB4 16/32, VB5 Sub Remove_Duplicates(arr() As String) On Error Resume Next ' Сохранение в List Box Назад к СОДЕРЖАНИЮ23. СОЗДАНИЕ «УДАЛЕННО КОНТРОЛИРУЕМЫХ» ФОРМVB3 Иногда мне требуется котролировать одну форму, когда фокус находится на другой. Например, когда я жму «ОК» на форме А, мне надо сделать resize на форме В. Итак, на каждой форме, которую мне надо «удаленно контролировать», я делаю невидимый text box, назовем его TextCommand, в событии Change которого находится следующий код: Sub TextCommand_Change () Select Case msg Вы можете удаленно контролировать форму, засылая соответствующее значение в ее TextCommand: Sub Command1_Click () Этот код можно использовать для отсылки мессагов из MDI формы к потомкам: Dim f As Form Если Вы сидите под VB4 или VB5, Вы можете
также использовать Public-свойства и методы
формы. Назад к СОДЕРЖАНИЮ24. ЗАПИСЬ ТЕКУЩЕЙ ПОЗИЦИИ И РАЗМЕРА ФОРМЫ ПРИ ПОМОЩИ SAVESETTINGVB4 16/32, VB5 Public Sub FormPosition_Get(F As Form) buf = GetSetting(app.EXEName, _ Public Sub FormPosition_Put(F As Form) Вам следует поместить эти процедуры в модуль и вызывать их из событий Load и Unload форм. Вы должны написать имя формы в ее свойство Tag, чтобы эти процедуры работали корректно Sub Form_Load() 25. ЭФФЕКТИВНОЕ ИСПОЛЬЗОВАНИЕ ВНУТРЕННИХ VB КОНСТАНТVB4 16/32, VB5 Мне приходилось видеть некоторые советы по использованию числовых значений вместо соответствующих VB констант. Например, Вы можете вывести message box, используя числовые константы: rc = MsgBox(msg, 4 + 32 + 256, "Confirm Delete") Но не легче ли прочесть следующее? rc = MsgBox(msg, vbYesNo + vbQuestion _ Вы можете использовать следующие константы для check box: VbUnchecked =0 Также полезно знать строковые константы вместо соответствующих chr$(символы ASCII): vbTab instead of Chr$(9)
26 ПРАВИЛЬНЫЙ ТЕСТ НА "FILE EXIST"VB3, VB4 16/32, VB5 Dir$ генерирует runtime error, если ему суют несуществующее имя диска. Например, Dir$ ("d:\win\himems.sys") умирает , если драйв d: не существует. Для проверки существования файла, добавьте обработчик ошибки: Function FileExist(filename As String) _ Назад к СОДЕРЖАНИЮ27. ПРОЦЕДУРЫ, РАБОТАЮЩИЕ С ГРУППАМИ КОНТРОЛОВVB4 16/32, VB5 Вы можете использовать почти забытую возможность VB иметь процедуру или функцию, работающую с неограниченным числом аргументов, что может быть полезно при работе с множеством контролов. Например, Вы можете enable/disable группу контролов одним вызовом процедуры: EnableAll True, Text1, Text2, _ Эта процедура проходит по всем контролам, передаваемым в качестве аргументов: Sub EnableAll(Enabled As Boolean, _ Назад к СОДЕРЖАНИЮ28 УЛУЧШЕНИЕ СКРОЛЛИНГА РИСУНКОВVB3, VB4 16/32, VB5 Dim StartX As Long, StartY As Long Finally, declare these three events for PicPicture: Private Sub PicPicture_MouseDown_ Private Sub PicPicture_MouseMove_ Private Sub PicPicture_MouseUp_ Теперь Вы можете скроллить картинку мышой. Не забудьте проверить границы картинки. 29. ЗАШИФРОВАННЫЕ ПАРОЛИ VB3, VB4 16/32, VB5 Следующие две функции легко и эффективно шифрут/дешифруют текстовый пароль. Функции имеют два аргумента: число от 1 до 10 чтобы сдвигать позицию символа ASCII в пароле, и собственно строка пароля. Функция EncryptPassword проходит через каждый символ строки DecryptedPassword, проверяет символ на четность/нечетность, и сдвигает его вверх/вниз согласно параметру Number. Эту делает зашифрованную строку нечитабельной. Зашифрованный пароль «укатывается» затем оператором XOR, который еще более запутывает строку. Я ограничил параметр Number числом 10, поскольку мне не надо делать проверку на «неправильные» символы ASCII. Функция DecryptPassword повторяет в обратном порядке процесс шифрования, применяя XOR, а затем сдвиг. Function EncryptPassword(Number As _ Counter = 1 Function DecryptPassword(Number As _ Counter = 1 30. ПРОПИСНЫЕ-СТРОЧНЫЕ БУКВЫ - СОВЕТ ПО СЛЕЖЕНИЮ ЗА РЕГИСТРОМ БУКВVB4 16/32, VB5 Private Sub Text1_Change() 31. ОТСЛЕЖИВАНИЕ DOUBLE CLICK ДЛЯ КНОПОК НА ТУЛБАРЕVB4 32, VB5 Private mbSingleClicked As Boolean In the Toolbars ButtonClick event,
add this code: Private Sub Toolbar1_ButtonClick_ 'пример обработки этих событий 'при выходе из процедуры надо реинитить
переменные, иначе мы упремся в SingleClickи 32. ОБЪЕМ КАТАЛОГА В БАЙТАХ VB3, VB4 16/32, VB5 Эта функция возвращает число байт, занятых файлами в каталоге: Function DirUsedBytes(ByVal dirName As _ ' добавить \, если не было Do While FileName <> "" End Function Пример вызова такой функции: MsgBox DirUsedBytes("C:\Windows") Назад к СОДЕРЖАНИЮ33. ПОЛЕЗНАЯ ДИСКОВАЯ ИНФОРМАЦИЯVB4 32, VB5 Эта функция возвращает количество свободного пространства на диске, общий объем диска, долю свободного пространства н адиске, и использванное пространство. Перед вызовом функции, присвойте первому полю структуры DISKSPACEINFO ("RootPath") имя диска: Dim dsi As DISKSPACEINFO Функция возвращает все результаты в других полях записи(структуры): ' *** Declaratiosn Section ****** Type DISKSPACEINFO ' ****** МОДУЛЬ КОДА ****** X& = GetDiskFreeSpace_ If X& Then В таком виде, функция работает с драйвами
размера где-то до 2Гб, для больших дисков
надо использовать переменные типа Single. Назад к СОДЕРЖАНИЮ34. КАК СЫМИТИРОВАТЬ НАЖАТИЕ КЛАВИШИ CTRL ДЛЯ ВЫДЕЛЕНИЯ НЕСВЯЗАННЫХ КУСКОВ В LIST BOX VB4 32, VB5 Когда свойство MultiSelect обычного listboxа установлено в 1 - Simple или в 2 - Extended, то юзеру надо жать Ctrl при кликании внутри этого listboxа, чтобы выделять несвязанные (идущие неподряд) элементы. Мой метод позволяет юзеру выбирать несколько элементов, не нажимая при этом Ctrl. Поместите нижеприведенный код в модуль. Declare Function GetKeyboardState Lib _ Этот код засуньте в событие MouseDown Вашего listboxа (назовем его List1), у которого свойство MultiSelect установлено в Simple или Extended: ' «нажимает» Ctrl Этот код поместите в процедуру, в которой надо «отжать» Ctrl, например, List1_LostFocus: ' «отжимает» Ctrl 35. ВЫБРАТЬ ВСЕ ФАЙЛЫ ПО МАСКЕ В ПОДДЕРЕВЕ КАТАЛОГОВVB3, VB4 16/32, VB5 Поскольку этот код не использует API, Вы можете легко перенести его с 16- на 32-разрядную платформу и обратно. Процедура DirWalk позводит Вам просмотреть все поддерево, начиная с заданнного места: ReDim sArray(0) As String Эта процедура принимает * и ? в первом
аргументе, который задает маску поиска. Вы
можете задать несколько масок, разделяя их
символом «;», например, "OLE*.DLL; *.TLB".
Второй аргумент - место старта, третий
аргумент - массив строк. Sub DirWalk(ByVal sPattern As String, _ If Right$(CurrDir, 1) <> "\" Then
36. ИМЯ ТЕКУЩЕГО КОМПЬЮТЕРА В WINDOWS 95/NTVB4 32, VB5 Часто Вам надо знать имя текущего компа под WINDOWS 95/NT из Вашей VB проги. Используйте эту простенькую функцию API из kernel32.dll: Private Declare Function GetComputerNameA Lib "kernel32"_ Public Function GetMachineName() As _ Назад к СОДЕРЖАНИЮ37. КАК ПОКАЗАТЬ ШРИФТЫ, КОГДА ВЫ ВЫБИРАЕТЕ ИХVB3, VB4 16/32, VB5 Private Sub Form_Load() Украсьте процедуру, позволив юзеру сразу видеть результат своего выбора, без необходимости печатать «что-нибудь» в качестве теста: Private Sub cboFont_Click() Назад к СОДЕРЖАНИЮ38. ПЕРЕХВАТ ПРАВЫХ КЛИКОВ НА УЗЛАХ TREEVIEW Контрол TreeView придает Вашей аппликухе законченный вид Windows 95. Однако, в учебниках по VB не сказано, как перехватывать правый мышиный клик на узле (node) дерева. Событие Treeview_MouseDown происходит до события NodeClick. Чтобы показать контекстное меню над узлом, используйте этот код и определите ключ (Key) для для каждого узла в виде буквы и идущим за ней числом. + Root (R01)
' the letter gives Dim bRightMouseDown as Boolean Private Sub Form_Load() Private Sub treeview1_MouseDown_ Private Sub treeview1_MouseUp_ Private Sub treeview1_NodeClick_
' то же с остальными узлами 39. ЗАПУСК VB ПРИ ПОМОЩИ МЕНЮ SENDTOVB3, VB4 16/32, VB5 40. НОВЫЕ “ГОРЯЧИЕ КНОПКИ” ДЛЯ VBVB4 16/32, VB5 1) В VB5, нажмите Ctrl-F3 когда курсор находится над каким-либо словом. При этом автоматически будет найдено следующее вхождение этого слова в тексте, минуя диалог поиска. Курсор должен стоять как минимум за первой буквой слова, чтобы эта фича работала правильно. 2) В VB4/5 нажатием Ctrl-Tab можно перемещаться
между всеми открытыми окнами в IDE, это часто
оказывается быстрее, чем идти в меню Window. 41. КАК ПОЛУЧИТЬ USERID ПОД WINDOWS 95/NTVB4 32, VB5 Часто Вам надо получить userID текущего юзера, работающего с Вашей программой. Используйте для этого модификацию одной из функций API: Option Explicit Private Declare Function WNetGetUserA _ Function GetUser() As String 42 ВЫВОД ПЕСОЧНЫХ ЧАСОВ ВО ВРЕМЯ ОБРАБОТКИ ДАННЫХVB4 32, VB5 Нижеуказанная методика упрощает переключение MousePointerа, без добавления спец. кода в конце каждой процедуры/функции. Когда Вы созадете объект из какого-либо класса, генерируется событие Initialize. Затем исполняется код соответствующей процедуры. Это первый код, исполняемый для данного объекта, он исполняется до присвоения каких-либо свойств объекту и до выполнения методов объекта. Когда переменная выходит из области видимости, все ссылки на объект уничтожаются, и выполняется код для события Terminate. Declare Sub Sleep Lib "kernel32" _ ' пример процедуры, использующей класс
CHourGlass ' создание класса CHourGlass: Private Sub Class_Terminate() Назад к СОДЕРЖАНИЮ43. ОЦЕНКА ПРОМЕЖУТКА ВРЕМЕНИ(в минутах) МЕЖДУ ДВУМЯ ДАТАМИVB4 16/32, VB5 lTotalMinutes = Minutes(Now) - _ Эта функция возвращает количество минут с 01/01/1900: Public Function Minutes(d As Date) _ lPreviousDays = d - #1/1/1900# Minutes = lTotalMinutes Назад к СОДЕРЖАНИЮ44. ХВАТИТ ПЕЧАТАТЬ!VB3, VB4 16/32, VB5 Иногда мне хочется распечатать данные из recordsetа, строка за строкой. Однако, довольно трудно пркратить этот процесс до того как весь recordset уйдет в очередь принтера. Используйте кнопку Cancel, которая устанавливает флаг. Кроме кнопки, посылающей задание на печать, создайте еще одну, под названием Cancel. Вы также можете присвоить ее свойству Cancel значение True, чтобы юзер мог остановить печать нажатием на Esc. Добавьте еще одну переменную в модуль: Dim CancelNow As Integer Put this code in the Click event of the Cancel button: Sub cCancel_Click () Вы можете даже обойтись без кнопки и ловить только нажатие на Escape. В этом случае, установите свойство KeyPreview формы в True и вставьте следующий код: Sub Form_KeyPress (KeyAscii As Integer) Наконец, вставьте проверку флага внутри цикла печати: '... какой-то код... 45. ПОМЕНЯТЬ ЗНАЧЕНИЯ ДВУХ ПЕРЕМЕННЫХVB3, VB4 16/32, VB5 Use this algorithm to swap two integer variables: a = a Xor b
46. БЫСТРЫЙ ОБСЧЕТ МНОГОЧЛЕНОВVB3, VB4 16/32, VB5 Хорошо известная формула Горнера
позволяет быстро считать полиномиальные
выражения. Для того, чтобы посчитать Назад к СОДЕРЖАНИЮ47. ФОРМАТИРОВАНИЕ И КОПИРОВАНИЕ ДИСКЕТ ЧЕРЕЗ ФУНКЦИИ APIVB4 32, VB5 В Win32 API есть парочка функций, позволяющих форматировать и копировать дискеты из программы: Private Declare Function SHFormatDrive _ Добавьте две command buttons в форму, назовите их cmdDiskCopy и cmdFormatDrive, и засуньте в их события Click следующие фрагменты кода: Private Sub cmdDiskCopy_Click() Private Sub cmdFormatDrive_Click() Добавьте контрол DriveListBox под именем Drive1: Private Sub Drive1_Change() Будьте осторожны: так недолго и винт
запороть. Назад к СОДЕРЖАНИЮ48. ПОСЛЕДОВАТЕЛЬНЫЕ НОМЕРА ВЕРСИЙVB4 16/32, VB5 Для слежения за последовательностью версий, используйте эту процедуру, если Вы используете номер версии: Public Function GetMyVersion() As String 49. ВЫРАВНИВАНИЕ КОНТРОЛОВ ПО ПРАВОМУ КРАЮVB3, VB4 16/32, VB5 При создании форм с нефиксированными размерами, я предпочитаю помещать все контролы в правый нижний и правый верхний углы. Например, на формах, где вводятся данные, я ставлю кнопки навигации по записям в левую нижнюю часть формы вместе с кнопками Add New Record, Delete Record, и Find Record. В нижнем правом углу я ставлю кнопки print preview и закрытия формы. Поместите эту процедуру в модуль или general declarations формы. Параметром Offset Вы можете изменять дистанцию от правого края формы, то есть Вы можете выравнивать по правому краю Ваши контролы. Sub ButtonRight(X As Control, _ Поместите два command buttonа на форму. В событии Form_Resize, добавьте примерно такой код: Private Sub Form_Resize() 50. VAL( ) НЕ РАБОТАЕТ НА ФОРМАТИРОВАННЫХ ЧИСЛАХVB3, VB4 16/32, VB5 Осторожнее с функцией Val(). Она некорректно распознает форматированные числа. Используйте вместо этого CInt(), CDbl(). FormattedString = Format(1250, _ 51. CМЫШЛЕНЫЙ ГЕНЕРАТОР IDVB3, VB4 16/32, VB5 Я написал генератор для создания
уникальных номиров , типа номера акаунта,
или ID в вашеи приложении. Я использую это
вместе с фенкцией CheckForValid, например CheckForValid
вернет True для номера "203931." И вернет
False для "209331." Function CheckForValid(Num As Long) _ Function Generate(Num As Long) As Long 52. ИЗМЕНЕНИЕ РАЗМЕРА ВЫПАДАЮЩЕЙ ОБЛАСТИ НА COMBOBOXEVB4 32, VB5 Option Explicit Type POINTAPI Type RECT Declare Function MoveWindow Lib _ Public Sub Size_Combo(rForm As Form, _ ' Смена Scale Mode формы
на Pixels ' Установка новой
высоты comboboxа ' Получение
координат по отношению к экрану ' затем координаты
в форме ' Изменение
размера comboboxа Назад к СОДЕРЖАНИЮ53. КОЛИЧЕСТВО СВОБОДНОЙ ПАМЯТИ С ПОМОЩЬЮ WIN32 VB4 32, VB5 Если Вам надо показать юзерам, сколько свободной памяти доступно на машине, и Вы перешли с 16бит на 32 бит платформу, то Вы заметите, что функция API GetFreeSystemResources исяезла. Но это не беда. Вам надо всего лишь объявить API функцию и следующий тип в модуле: Declare Sub GlobalMemoryStatus Lib _ Type MEMORYSTATUS Занесите в поле dwlength размер типа MEMORYSTATUS. Переменная типа Long берет 4 байта, так что всего выйдет 4*8=32 байта: Dim ms As MEMORYSTATUS ms.dwLength = Len(ms) Вы можете даже написать класс, в котором
инкапсулировать все вышеизложенное. Назад к СОДЕРЖАНИЮ54. СКОЛЬКО ВАМ ЛЕТ?VB5 Эта функция возвращает разницу между двумя датами в годах, месяцах и днях: Function GetAge(dtDOB As Date, _ 55. УЗЕЛОК, О КОТОРОМ НЕВОЗМОЖНО ЗАБЫТЬVB3, VB4 16/32, VB5 Я часто работаю над несколькими проектами
одновременно. Прыгая с одного проекта на
другой и обратно, иногда я теряю след, в
какой программе в каком месте я остановился.
Для решения этой проблемы, возьмите да и
напечатайте какую-нибудь фразу без кавычек
комментария.
56. СОЗДАТЬ НА ЛЕТУ МАССИВ ПРИ ПОМОЩИ ФУНКЦИИ ARRAYVB4 16/32, VB5 Метод GetRows копирует строки Recordsetа (JET) или rdoResultsetа (RDO) в массив. Я часто использую эту фичу для передачи данных между OLE Serverом и клиентскими аппликухами. Этот метод использует переменную типа Variant в качестве параметра для хранения возвращаемых данных. Это двумерный массив (по внутреннему представлению VB) Dim A As Variant Назад к СОДЕРЖАНИЮ57. НАЙТИ ВЫБРАННЫЙ КОНТРОЛ В МАССИВЕ OPTION BUTTONS
VB4 16/32, VB5 Function WhichOption(Options As _ ' Эта функция возвращает индекс Option Button, чье значение true. Dim i End Function Учтите, что iCurOptIndex имеет тип integer, а Option1 это имя массива контролов OptionButton. iCurOptIndex = WhichOption(Option1) Важно: параметр функции - объект. Она будет
работать только с параметрами-объектами
или типа variant. Назад к СОДЕРЖАНИЮ58. УПАКОВКА ЗНАЧЕНИЙ CHECK-BOX В ОДНУ ПЕРЕМЕННУЮ ТИПА INTEGERVB4 16/32, VB5 Используя следующий код, можно вывести двоичное представление зачеркнутых check boxов: Function WhichCheck(ctrl As Object) As _ Dim i ' двоичное
представление End Function Функция вызывается следующим образом: iCurChecked = WhichCheck(Check1) Check1 - массив чекбоксов, iCurChecked - переменная integer. Ниже приведена «двойственная» процедура, устанавливающая все чекбоксы согласно переменной, в которой хранятся их двоичные представления. Sub SetChecked(ctrl As Object, _ End Sub Эта процедура вызывается так: Call SetChecked(Check1, iDesired) Check1 - массив чекбоксов, iDesired- переменная, хранящая двоичное представление состояния чекбоксов. 59. УСЛОВНАЯ КОМПИЛЯЦИЯ КОДАVB4 16/32, VB5 Большинству разработчиков известна фича Conditional Compilation из VB4, когда Вы можете объявлять процедуры Windows API для 16- или 32-разрядных ОС: #If Win#32 then #If Win32 Then #If Win32 Then End Function 60. УМЕНЬШИТЬ МЕРЦАНИЕ ВО ВРЕМЯ ЗАГРУЗКИ ФОРМЫ VB4, VB5 Во время загрузки формы, следующий код поможет уменьшить мерцание и мелькание GUI при помощи функций API: 'Declarations Section Public Sub LoadSomeForm() ' Во время загрузки
формы запрещает обновление состояния окна 61. СПРЯТАТЬ УКАЗАТЕЛЬ НА ТЕКУЩУЮ ЗАПИСЬ в DBGride Для того, чтобы указатель записи на DBGride не скакал при перемещении между записями (строками grida), используйте функцию API LockWindowUpdate(gridname.hwnd) перед началом движения по gridу, и LockWindowUpdate(0) после окончания перемещений: 'Declarations Section Private Sub cmdHideSelector_Click() Private Sub cmdShowSelector_Click() 62. USE POPUP MENUS IN WINDOWS WITHOUT TITLE BAR VB4 16/32 Когда Вы устанавливаете свойство ControlBox в
False и BorderStyle в fixed window, то можете получить
окно(форму) без titlebar (поля заголовка). Если
же вы добавите меню на эту форму - титул-бар
появится снова. Чтобы измежать этой
проблемму вы можете разместить меню на
другой форме. Private Sub Command1_Click() Такое поведение исправлено в VB5 Назад к СОДЕРЖАНИЮ63. КАК УЗНАТЬ РАЗДЕЛИТЕЛИ ДАТЫ И ВРЕМЕНИ БЕЗ ФУНКЦИЙ APIVB3, VB4 16/32, VB5 Вот простой алгоритм как узнать разделители даты, времени и десятичной точки в Windows, не залезая в Locale Settings или функции API. DateDelimiter = Mid$(Format(Date, _ Назад к СОДЕРЖАНИЮ64. ПРЕДОТВРАЩЕНИЕ ОШИБОК ПРИ ИСПОЛЬЗОВАНИИ GETSETTINGVB4 16/32, VB5 Использование функции GetSetting может породить ошибки, особенно в некоторых ситуациях при 16-разрядной ОС при работе с INI файлами. Если искомого параметра нет в INI файле, то Вы можете увидеть сообщение об ошибке "Invalid procedure call.". Используйте нижеприведенную процедуру, которая подменяет обработчик ошибок: Public Function GetRegSetting(AppName _ ' дефолтовое значение не имеет не-объектный
тип , иначе придется ' установка величины по умолчанию ' это отлавливает возможные ошибки ' теперь можно использовать функцию из VB ' после возможных ошибок вызов
повторяется здесь End Function 65. ДУБЛИРОВАНИЕ СТРОК КОДА БЕЗ СИНТАКСИЧЕСКИХ ОШИБОКVB3, VB4 16/32, VB5 While Not mRS.EOF Если у Вашего объекта 20 или 30 свойств, быстрее будет создать шаблон: ' oObject. = mRS! Скопируйте его, вставьте 20 или 30 раз,
вернитесь к началу и впечатайте имена
свойств и полей, и уберите символ
комментария. Символ комментария позволяет
Вам свободно бегать по всему фрагменту, не
заботясь о синтаксических ошибках.
66. ЯРЛЫК ДЛЯ ЗАГРУЗКИ ПОСЛЕДНЕГО РАБОЧЕГО ПРОЕКТА В VBVB4 32 Option Explicit Declare Function GetPrivateProfile_ Public Sub Main() Назад к СОДЕРЖАНИЮ67. КАК ВЫВЕСТИ СИМВОЛ "&" В LABELVB4 16/32, VB5 Если Вы хотите выывести символ «&» на экран, установите свойство "UseMnemonic" в False. Это свойство бывает полезно, когда, например, Labelы используются для вывода данных из баз данных. Также Вы можете вывести символ "&" в свойстве Caption, написав &&.
Назад к СОДЕРЖАНИЮ68. СОЗДАНИЕ ВРЕМЕННЫХ ФАЙЛОВ Я пишу прогу с базами данных, использующую много вспомогательных файлов в одно и то же время. При программировании баз данных можно создавать временные файлы для, например, вывода результата инструкции SQL или из временной базы данных, чтобы более эффективно работать с записями. Я написал функцию FileAux, возварщающую имя временного файла. Если мне надо создать несколько временных файлов одновременно, я сохраняю их имена в заранее определенных переменных: Function FileAux(Ext As String) _ ' Ищем уже
имеющиеся файлы на винте Эта функция обращается к функции FileExists: Function FileExist(filename As String) _ А вот пример использования: Sub Test() File1, File2, и File3 должны быть "Aux0001.MDB,"
"Aux0002.MDB," 69. МЫШИНЫЕ СОБЫТИЯ НЕ СЛУЧАЮТСЯ ЕСЛИ ENABLE УСТАНОВЛЕНО В FALSEVB3, VB4 16/32, VB5 Command1(0), Command1(1)-Command1 - массив контролов. Private Sub Form_Load() End Sub Private Sub Label1_MouseMove(Index As _ Private Sub Command1_MouseMove(Index _ 70. КАК ВЫВЕСТИ СВОЕ POPUP MENU НА TEXT BOXES VB4 16/32, VB5 Некоторые контролы в VB4 и VB5 как, например, TextBox имеют по дефолту контекстное меню, выползающее при правом клике на указанном контроле. Если Вы хотите, чтобы выезжало другое котекстное меню, то стандартных методов или пропертей для этого не существует. Выход состоит в отлавливании события Mouse_Down, код которого будет делать контрол недоступным. Затем высвечивайте Ваше контекстное меню, энаблите контрол обратно. Процедура PopContextMenu описывает указанный метод Sub PopContextMenu(argoControl As _ Пример вызова в событии MouseDown для текстбтокса по имени Text1 и меню MyMenu: Private Sub Text1_MouseDown(Button As _ 71. ЦЕНТРИРОВАТЬ ФОРМУ С УЧЕТОМ ТАСКБАРАVB3, VB4 16/32, VB5 Public Const SM_CXFULLSCREEN = 16 #If Win32 then Public Sub CenterForm(frm As Form) 72. ОЧИСТКА СТРОКИ ОТ НЕНУЖНЫХ СИМВОЛОВ VB3, VB4 16/32, VB5 Function StringCleaner(s As String, _ Назад к СОДЕРЖАНИЮ73. ПРОВЕРКА ОБЪЕКТОВ ПРИ ПОМОЩИ TYPENAMEVB4 16/32, VB5 Вы можете определить класс, к которому принадлежит объект, при помощи функции TypeName вместо использования блока If TypeOf. Используйте выражение TypeOf для определения типа объекта: If TypeOf myObject is myType then Вы можете сделать то же савмое при помощи следующего кода: if TypeName(myObject) = "myType" Then Выгода моего решения в том, что Вам вовсе
не обязательно включать в Ваш проект все
классы (или OCXs), с которыми Вы работаете. Это
неплохой прием для написания общих
процедур (универсальных, общего назначения)
и , более того, Вы можете использовать TypeName в
сложных проверках и блоках Select Case. Назад к СОДЕРЖАНИЮ74. ДОБАВЛЕНИЕ СТРОКИ В TEXT BOXVB4 16/32, VB5 Используйте данный код, чтобы заставить скроллер TextBoxа автоматически передвинуться, когда Вы добавляете новый текст: ' Переход к концу текста Назад к СОДЕРЖАНИЮ75. ПРОВЕРКА АРГУМЕНТОВ В ФУНКЦИИ VALVB3, VB4 16/32, VB5 При использовании функции Val, VB капризничает, порождая ошибку несоответствия типов. Например, Val("25%") правильно возвращает 25, тогда как Val("2.5%") неправильно интерпретирует входной параметр и возвращает ошибку несоответствия типов. Это случается только тогда, когда в строке присутствует десятичная точка и символ "%" или "&". Чтобы исправить это, уберите эти символы из строки перед ее передачей в Val. 76. ЯРЛЫКИ ДЛЯ INTERNETVB4 32, VB5 VB5 App Wizard умеет создавать Web Browser-форму, но она работает только с Microsoft Internet Explorer и Вам приходится таскать за собой SHDOCVW.DLL при распространении проги. Если Вы используете функцию ShellExecute для запуска файла Internet Shortcut, то Windows запускает дефолтный браузер и переходит на указанный URL. Этот метод работает как Microsoft так и с Netscape браузерами, если они правильно прописаны в регистре, и Вам не нужно перетаскивать никаких DLL при распространении проги. Private Declare Function ShellExecute _ ' frm : ShellExecute использует обработчик окна. Public Sub GoToMyWebPage(frm as Form, _ 77. ПРОСМОТР СОДЕРЖАНИЯ HELP-ФАЙЛА Многие программеры любят добавлять к свои приложениям и хелп-файлы. Как открыть содержание хелп-файла Windows из Вашей программы? Вот пример кода с использованием Win32 API функции. ' ---- Объявление ' --- Код
Назад к СОДЕРЖАНИЮ78. ЗАДАНИЕ ГРАНИЦ MDI ФОРМЫ ТОЧНО КАК В DESIGN-TIME VB3, VB4 16/32, VB5 Поскольку MDI-формы ни имеют свойства border, юзер может раздвигать их границы и менять размер MDI-форм. Если юзер пытается изменить размеры формы, а я этого не хочу (пусть остается такой как была создана мной), то процедура для события MDIForm_Resize() спасет (кого - по вкусу): Private Sub MDIForm_Resize() 79. БЫСТРЫЙ ПОИСК В БАЗЕ ДАННЫХ VB3, VB4 16/32, VB5 Public Function MyDLookUp(Column As _ ' gCurBase - глобальная переменая, указывающая
на текущкю БД ' возврат, если не найдено, или произошла
другая ошибка 80. ЛЕГКОЕ ОТСЛЕЖИВАНИЕ ПОЛОЖЕНИЯ ФОКУСАVB3, VB4 16/32, VB5 Lost_Focus and Got_Focus events Часто используются для
проверки правильности ввода текста. Вы
можете использовать нижеприведенный код
для отслеживания фокуса на форме не
программирую каждый контрол отдельно. Private Sub tmrFocusTracking_Timer() Do To implement universal highlighting, replace the Print statement with this code: Me.Controls(strActive).SelStart = 0 Для проверки (validation) правильности текста
вместо Print statement используйте вызов
процедуры проверки. 81. НЕЗАКРЫВАЮЩАЯСЯ ФОРМАVB3, VB4 16/32, VB5 Если выставить свойство ControlBox на форме в False, то кнопки Minimize и Maximize тоже исчезнут. Предположим, что Вы хотите тем не менее давать возможность юзеру использовать кнопки Minimize и Maximize, но при этом чтобы он не мог закрыть форму кнопкой с крестиком. Добавьте следующий код в событие Query_Unload: ' если у Вас VB3, раскомментируйте следующую
строку Назад к СОДЕРЖАНИЮ82. ПОМЕНЯТЬ СВОЙСТВО ЦЕЛОЙ ГРУППЕ КОНТРОЛОВVB3, VB4 16/32, VB5 Вы можете легко сделать видимой/невидимой целую группу контролов. В режиме разработки, выделите все контролы, с которыми Вы будете производить данную операцию при выполнении программы. Нажмите F4, и присвойте свойству Tag имя группы, например Group1. Теперь при совершении групповой операции Вам поможет следующий код: For ind = 0 To Formname.Controls.Count _ Назад к СОДЕРЖАНИЮ83. КАК ПРОСТО ОТФОРМАТИРОВАТЬ И ОКРУГЛИТЬ ЧИСЛО VB3, VB4 16/32, VB5 Пример округления с заданной точностью. n = 12.345 84. БУДЬТЕ ОСТОРОЖНЫ, ЗДЕСЬ ВАМ НЕ С!VB3, VB4 16/32, VB5 VB программеры, привыкшие к С, могут быть введены в заблуждение следующей особенностью VB. Рассмотрим код: Dim x As Integer Вы ожидаете, что высветится 20, как должно бы было произойти в С? Однако, VB сравнит z с RHS (right-hand side)-правой стороной, даже перед присвоением, независимо от скобок. Будьте внимательны. 8.5 ИСПОЛЬЗОВАТЬ BACKQUOTES ВМЕСТО АПОСТРОФОВ VB3, VB4 16/32, VB5 Private Sub Text1_Keypress_ Также можно заменить все одинарные
кавычки на «‘» перед отсылкой в SQL Server.
86. РАСПРОСТРАНЕНИЕ НОВЫХ ВЕРСИЙ ПРОГРАММЫ ПО СЕТИVB4 16/32, VB5 Я пишу VB проги для сети с примерно 300 юзерами. Довольно трудно своевременно уследить за распространением каждой новой версии проги на всех машинах, поэтому я использую такую фичу VB автоинкрементирующаяся нумерация версий для проверки, требуется ли апгрейд проги на конкретной машине. При компиляции проги установите автоинкремент версий в On. Сохраните Ваши setup/upgrade файлы на сетевом диске (настоятельно рекомендую использовать UNC-пути (\\имя_машины\имя_диска) нежели просто имена дисков), и положите INI-файл проги, в котором указан номер новейшей версии. Затем вставьте следующий код в прогу, событие Form_Load: Open IniFile$ For Input As #1 If sUpgradeVersion > (Format(App.Major, "00") &
"." & _ Если версия в INI-файле выше, чем версия,
записанная в .exe, то прога автоматом
запустит программу апгрейда по сети и
закончит свое выполнение, то есть все
нужные файлы смогут быть заменены. Это
особенно полезно, когда Вы только начинаете
писать прогу, то есть апгрейды и фиксы
появляются чуть ли не раз в несколько дней. Назад к СОДЕРЖАНИЮ87. ЗАКРЫТЬ ОКНО ПРОГРАММЫ, КАК ЭТО ДЕЛАЕТ WINDOWS 95VB3, VB4 16/32, VB5 Разместите этот код в declaration section модуля: Public Sub Win95Shrivel(xForm As Form) Вызывайте ее из процедуры Unload формы Private Sub Form_Unload(Cancel As _ Каждый раз при unloade формы она сначала
быренько сворачивается к таскбару, а затем
исчезает. Это работает и в Windows 3.1x тоже. Назад к СОДЕРЖАНИЮ
|
|