Как заставить вашу программу на vb работать быстрее


Содержание

Как я могу заставить программу запускаться автоматически в определенное время в день (VB.NET)

Приложение, которое я разрабатываю прямо сейчас, позволяет пользователю обновлять лист Excel или базу данных Sql для установки показателей дважды в день. Программа делает это, выскакивая в определенное время (например, 6:00 AM, 5:00 PM, 3:42 PM, независимо от того, что пользователь устанавливает). Когда программа появляется в определенное время, программа («Auto Excel It . «) позволяет вам отслеживать установленные данные (например, звонки продаж, презентации продаж, собрания, количество часов кодирования, количество jalepeño burritos eaten и т.д.).

Как разработчик может заставить эту программу «всплывать»/запускать/выполнять автоматически в определенное время с помощью API Scheduler Windows (или что-то лучше)?

Вот как мое понимание развивалось в последнее время:

Nothing → Использовать таймеры, поскольку программа работает в фоновом режиме → Использовать API-интерфейс Scheduler для автоматического запуска (текущего) → Возможное новое понимание из вашего ответа

Например, я знаю: DispatcherTimers, Timers, другой таймер, о котором я не знаю, Sleep(), Планировщик Windows. Но имея в виду, я не знаю, что делать в отношении следующего: автоматический запуск программы через Windows Scheduler; Сохранение ресурсов компьютера, если используется таймер; или даже как получить эту вершину автоматически.

Обновление 1:

@nfell2009: Ваша логика очень помогла мне. Сначала мне пришлось поиграть с конвертированием своего таймера сюда в DispatcherTimer (кажется, стандартный стандарт WPF). Затем я переключил «Ручки» для Sub tCheckTime на «AddHandler tCheckTime.Tick, AddressOf tCheckTime_Tick». Почему я должен был сделать это, это хороший вопрос.

Затем, когда я установил базовые настройки EventHandlers, ваша идея сравнить текст пользователя (As Date) с System.Date хороша — когда я что-то прикрутил и не смог заставить код работать, я включил его и преобразовал System.Date в String- — я перешел из String-> Date To Date-> String. Это, когда я получил таймер для работы. Когда мое System.Time отметит до 3:12 вечера, MsgBox появился с «Your Message Here».

(Быстрое (злое) спасибо! Я потратил четыре с лишним часа на то, чтобы это работало)

От использования «Ручки» В tCheckTime_Tick (Кажется, что он должен «работать»)

Для AddHandler blah, AddressOf tCheckTime_Tick (работает)

Как заставить вашу программу на vb работать быстрее ?

Вот я например изучаю и пишу программы на Microsoft c++ и Visual Basic .Net.
Все раньше говорили и я в том числе что он медленный, не поддерживает наследие.

Но достаточно написать теперь на платформе Net любую тестувую програму обсчета, как мы видим капитальный отрыв в производительности от того же самого Visual Basic 6, и даже легендарного Power Basic.
По быстродействию однаково что С++ и Visual Basic. Net. Также теперь есть настоящее ООП со всеми вытекающими возможностями.

Если писать программу по Windows то я отдаю предпочтению Visual Basic, программа выходит намного быстрее, и по скорости и функцианальности ничем не отличаеться о С++ Так зачем писать тоже самое, только намного дольше на этом же С++ ведь от этого она быстрее ничуть станет?

Ну что теперь вам не нравиться в Визуал Бэйсике на платформе нет, ведь теперь есть все что было нужно и давно нехватало, и скорость компилятора, так что еще не нравится вам?

не поддерживает наследие

Наследие, говоришь. :) Может быть все-таки наследование?

Я работал в последний раз на VB когда еще была версия 4.0. Нормальный был язык для выполнения конкретных задач. Как там сейчас с возможностями VB не очень в курсе, но подозреваю что чего-нить как всегда в нем нет.
Т.е. объективно на данный момент языки Delphi, C++ и им подобные предоставляют программисту больше возможностей чем VB (тот который был до .NET, насчет VB.NET не знаю). Пересаживаться-же на другой язык, когда к этому нет каких-то предпосылок смысла особого нет. К тому-же у народа есть куча наработок.

Вообще конечно флейм, но я тоже поддерживаю что большие проекты на нем писать — клиника.

Клиника не клиника, а финансовые программы я писал на нем довольно успешно. Реестр акционеров (в составе команды) и программы по регистрации и оформлению сделок с ЦБ. Сюда докинуть акцессовские и MS SQL Server-овские базы. Имею мнение что те кто негативно отзываются о VB в 9 из 10 случаях его просто не знают. Нахватались чужих фраз черт-те знает где и повторяют как попугаи.

Очень хороший и продуктивный язык не смотря на то что многого в нем нет, чего есть в других языках.

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

В .NET все теперь есть, и указатели и полноценное наследие, и самое главное скорость.
Микрософт заявляет, что по функциональности, эти два языка идентичны (с++ бейсик) и различия только в лексике языка.

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

Отнюдь. Серьезных игрушек нет на бейсике потому что достоверно известно что производительность программ написанных на VB ниже чем например на C++ или Delphi. Что касается .NET, то игры на этой платформе еще не скоро появятся. Независимо от языка. Во первых потому что все равно медленнее чем Win32, во вторых потому что нужно кучу всего переписывать, в третьих потому что для того чтобы создание игр для .NET было экономически оправдано нужно чтобы она получила широкое распространение чего пока-что не наблюдается.

Майкрософт сама заявляет на своем сайте что различий в скорости никаких нет, что на с++ что на бейские.
В .NET все теперь есть, и указатели и полноценное наследие, и самое главное скорость.
Микрософт заявляет, что по функциональности, эти два языка идентичны (с++ бейсик) и различия только в лексике языка.
Не верь всему что пишет Microsoft. Любые слова marketroid-ов надо воспринимать со здоровым скептицизмом.

Объясните мне как может более простой язык работать на одинаковой скорости с языком более машинным. Ведь с++ — это почти ассэмблер, только там эти дурацкие «mov data jump start», а с++ нормальный алгоритмический язык, где при компиляции почти всегда почти прямая ассоциация с асээмблерно командой, только уже с заданными парамаметрами (исключениями явяются многие процедуры и некоторые функции). Это же оптимальнее может быть только сам ассэмблер. А VB это в каждую функцию напихано куча-куча ассэмблеросовских команд, ради того чтобы с этой командой было проще обращаться юзеру. А даже если работает с такой скоростью как и с++, во что я уже не верю, дак как-же у нас с возможностями. До сих пор нехера дельного ненапишешь из-за нехватка операторов?

P.S.:(исключениями явяются многие процедуры и некоторые функции)
Там сделан маленький код. В меньше чем в 10 строк ассэблера обычно.

А в Vb, там операция деления или умножения уже больше десяти строк ассэмблера (куча каких-то проверок). По крайней мере так было раньше. Или он стал непростой, либо в нём элементарные вещи выполняються через жопу (неоптимально)

Напишие хоть одно название программы, которая обязательно присутчвует на вашем компе написанной на VB?! Все проги на нем по сравнению с другими тормозят. Они требуют левых всяких библиотек. если прога написана на Vb лет пять назад, то уже вряд ли ее удасться запустить с первого раза. Это приходит постепенно — ненависть, я имею ввиду!

Родимый, внутрикорпоративного софта, написанного на VB, не меньше чем на Delphi. Причем если у нас перекос в сторону Delphi, то у буржуев в сторону VB.
ender1102189302
До сих пор нехера дельного ненапишешь из-за нехватка операторов?

Плохому танцору всегда яйца мешают.

>>Ведь с++ — это почти ассэмблер, только там эти дурацкие «mov data jump start», а с++ нормальный

Нет в асме «jump»

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

Возьми дебагер и посмотри, чего генерит С++.. ты будешь удивлен

>>(исключениями явяются многие процедуры и некоторые функции)
Там сделан маленький код. В меньше чем в 10 строк ассэблера обычно.

вообще в одну — call xxxxxxxx :)

>>А в Vb, там операция деления или умножения уже больше десяти строк ассэмблера (куча каких-то проверок). По крайней мере так было раньше. Или он стал непростой, либо в нём элементарные вещи выполняються через жопу (неоптимально)

Процедура деления на асме это примерно 7 инструкций (с проверкой на ноль)

Попробуйте написать драйвер на VB. Попробуйте написать примочку к БД на асме. Потом ругайтесь.

Значит оформление сделок с ЦБ у нас на Бейсике написано, да ещё с Access-ными базами? Может поэтому бюджет на 2 порядка меньше чем американский? :) А ещё я слышал что на АС компьютеры под управлением Windows NT4 стоят. :)

p.s. воспринимать как шутку :)

Значит оформление сделок с ЦБ у нас на Бейсике написано, да ещё с Access-ными базами? Может поэтому бюджет на 2 порядка меньше чем американский? :) А ещё я слышал что на АС компьютеры под управлением Windows NT4 стоят. :)
p.s. воспринимать как шутку :)

А вот законы у нас вообще написаны на русском языке. Может быть поэтому с бюджетом такая ситуация? Кстати, внимательнее смотри передачи из ЦУП-а, там вообще винда много где светится. Ракеты летают, странно, не правда-ли?

dk_Ghost
VB .Net — неплохой язык. Я работал с версией 2002 — там нету только перегрузки операций.. По мне — лучше C# — оба компилируют в MSIL-код.. в принципе, одинаковы по возможностям(это изменится в VisualStudio 2005), но, прошу обратить внимание, разнятся по самой идее..

Программировать на managed C++ для .Net Framework — это по-моему чистить зубы через нос.. всё равно в итоге выйдет то же самое :-)

Если сравнивать Visual Basic .Net (например, самый первый релиз — 2002) с предыдущим Visual Basic 6 — небо и земля.. Многие авторы (например Джесс Либерти) пишут, что это абсолютно разные языки, на самом деле человеку, знакомому с VB6, всё-таки проще начать писать программы на VB .Net чем на чём-либо другом..

VB6 — я бы не назвал объектно-ориентированным языком ( он скорее дизориентированный :-) ), в VB .Net — всё стройно и красиво (конечно не так, как в C#, но всё же..)

Самое лучшее, что было в VB6 — Ide (инструментальная среда разработки) перенесена в VB .Net (кстати и в C#), конечно же с усовершенствованиями. ещё называют это RAD — но у Microsoft вообще по-моему больше названий, чем толку :-)

To All
Извините конечно, но для всех тех, кто высказывался очень резко в сторону BASIC выше на ум приходят очень ёмкие выражения.
Кстати, VB — не для игр, Delphi — тоже, вся платформа .Net — не для игр! Нормальные игры пишутся на c/c++.
Кстати новый Delphi тоже подсадили на .Net Framework ха-ха-ха (ему ещё и J# runtime надо — вообще цирк)

Как заставить компьютер работать быстрее

Опубликовано Михаил Непомнящий в 06.02.2020

Самый простой способ ускорить работу компьютера – это приобрести новый более современный. Однако столь кардинальные меры требуются не так часто. Компьютерная грамота предлагает 8 советов по ускорению работы ПК.

Ускорить загрузку

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

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

Для выполнения этого действия в Windows 10 откройте Диспетчер задач – либо сочетанием клавиш Ctrl+Shift+Esc, либо через контекстное меню с Панели задач. В самом Диспетчере перейдите во вкладку «Автозагрузка» и здесь выберите лишние приложения, отключая их по кнопке «Отключить». В крайнем случае можно отключить все доступные здесь программы, так как жизненно важные компоненты сюда всё равно не попадают.

Далее можно попробовать отключить опцию Быстрого старта. Предполагается, что данная опция немного ускоряет процесс загрузки, однако зачастую оказывает больше вреда для ряда пользователей. Как вариант, можно отключить и проверить какие будут изменения, а при необходимости включить обратно.

Сделать это можно через конфигурацию управления питанием. Через поиск Windows найдите раздел «Электропитание» и в левой колонке перейдите по ссылке «Действия кнопок питания». По умолчанию снять чекбокс со значения «Включить быстрый запуск (рекомендуется)» не получится. Перед этим нужно выше нажать на ссылку «Изменение параметров, которые сейчас недоступны».

Активировать наилучшее быстродействие

Вся красота в Windows 10 ежесекундно потребляет ресурсы процессора и оперативной памяти. Однако при желании можно пожертвовать красивыми эффектами переключения окон и прочими фишками, активировав минималистический вид операционной системы.

Делается это через «Дополнительные параметры системы», которые доступны в колонке слева в окне «Система» (вызывается сочетанием Win+Break). В области «Быстродействие» кликните на кнопку «Параметры» и в новом окне выберите пункт «Обеспечить наилучшее быстродействие». По нажатию на кнопку «Применить» у вас будет возможность оценить изменения. Если они вас не устраивают, то можно опционально вернуть какие-то эффекты.

Ускорить открытие меню Пуск

Если открытие Пуска стало притормаживать, можно вручную ускорить этот процесс. По умолчанию в реестре операционной системы прописана небольшая задержка на открытие данного меню. И если сам компьютер притормаживает, то это значение можно уменьшить. Однако помните, что без надобности лезть в настройки реестра не стоит, и уж тем более экспериментировать со значениями, в которых вы не разбираетесь.

Чтобы открыть редактор реестра, нажмите сочетание Win+R и в строке «Выполнить» наберите команду regedit. Нажмите Ok и у вас откроется окно редактора. Перейдите в раздел HKEY_CURRENT_USER\Control Panel\Desktop.

Здесь вам нужна запись, которая называется MenuShowDelay. Кликните на нее дважды, чтобы отредактировать значение. Здесь указано количество миллисекунд, которое уходит на задержку перед открытием Пуска. Изначальное значение – 400. Не рекомендуется менять его на 0, но, как вариант, снизить значение в два раза – до 200 – вполне приемлемо.

Убрать лишние команды из контекстного меню

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

Аналогично с программами из автозагрузки, эти команды контекстного меню также можно отключить. Разве что стандартными средствами Windows здесь не обойтись. Одним из решений является бесплатная программа CCleaner, которая не только чистит реестр, но и занимается другими видами очистки системы.

Данная программа доступна даже без установки (так называемая Portable версия). В ней необходимо перейти в раздел «Сервис», выбрать пункт «Автозагрузка» и перейти во вкладку «Контекстное меню». Здесь просто выбираете соответствующую программу и нажимаете на кнопку «Выключить».

Дефрагментация жесткого диска

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

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

«Этот компьютер» по умолчанию

Раньше при открытии проводника мы попадали в раздел «Мой компьютер», который ныне называется «Этот компьютер». Теперь же при нажатии сочетания клавиш Win+E открывается так называемый «Быстрый доступ», который, по мнению разработчиков, будет удобнее. Однако часто используемые папки, приведенные здесь, отображаются в списке слева, а по-старинке получить доступ к жестким дискам в один клик уже не получится.

Поэтому исправляем это недоразумение и возвращаем привычный вид Проводника. Для этого через его меню «Вид» выбираем команду «Параметры» и кнопку «Изменить параметры папок и поиска». В открывшемся окне из выпадающей области «Открыть проводник для:» меняем значение с «Быстрого доступа» на «Этот компьютер».

Проделать данную операцию будет полезно даже тем, у кого нет проблем со скоростью работы самого компьютера. Банально сократить ежедневное путешествие до нужного диска в Проводнике будет существенным ускорением рутинного действа.

Удаление лишних программ

Установка каждой программы заполняет системный реестр и занимает место на жестком диске. Поэтому, когда счет приложений перевалил уже за сотню, имеет смысл удалить всё ненужное. Ведь почти каждый найдет у себя с десяток-другой программ, которые не использовались годами.

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

Отключение зависших программ

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

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

Что делает компьютер быстрее?

Приведенные выше рекомендации не гарантируют существенного ускорения работы вашего ПК. Проблемы со скоростью могут иметь более глобальные причины. Если вашему компьютеру уже добрый десяток лет, то для адаптации к современным реалиям он просто окажется не готов, как ты его не настраивай. Тем не менее, если у вас есть проблемы с областями, описанными выше, советы Компьютерной грамоты могут оказаться полезными.

Как заставить мою программу работать при запуске?

Я программирую настольное приложение, похожее на Google Desktop, но с моим собственным гаджетом на vb.net 2008, как я могу сделать свое приложение, когда пользователь установит его на свой компьютер, для запуска во время запуска?

Давайте предположим, что мое приложение называется windowsAplication1, и я использую Windows XP, и программа будет установлена на диске C?

6 ответов

Вы можете добавить его в реестр с помощью следующего кода

Вы можете удалить его, используя

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

Или вы можете добавить ссылку на ваше приложение в папке «Автозагрузка».

Я предлагаю вам не делать это автоматически, это может раздражать пользователя. Я ненавижу, когда приложения автоматически добавляют их в автозагрузку Windows. Дайте возможность пользователю запускать программу при запуске Windows.

Как заставить вашу программу на vb работать быстрее ?

За последние 60 дней 2 выпусков (1-2 раза в 2 месяца)

Статистика

Программирование на Visual Basic и Active Server Pages #2

Служба Рассылок Subscribe.Ru проекта Citycat.Ru

VBS
http://vbs.pp.ru
>>> В этом выпуске:

1) Новости сайта
2) Результаты всенародного голосования
3) Новые темы обсуждения на http://vbs.pp.ru/forum
4) Статья: Как заставить Вашу программу на VB работать быстрее ?

>>> Новости сайта

  • 12.12.2000
    Обновлен раздел «Жители — Наши проекты«. В разделе «Исходники программ«: ещё один Mp3 проигрыватель. В разделе «FAQ — Статьи» новый материал: «Как заставить Вашу программу на VB работать быстрее?», автор: Рут Глушкина.
  • 08.12.2000
    Раздел «FAQ — Статьи» был полностью реорганизован: теперь в конце каждой статьи Вы можете найти форму для Ваших комментариев автору. Обновлен раздел «Ссылки«. В разделе «ASP» я опубликовал свою новую статью «Вставка на стороне сервера».

>>> Результаты всенародного голосования

Интернет — это средство .

а) Обогащения — 5 (10%)
б) Общения — 9 (19%)
в) Издевательства — 7 (15%)
г) Для жизни — 19 (40%)
д) От скуки — 8 (17%)

Всего приняло участие: 48 человек(а)

>>> Как заставить Вашу программу на VB работать быстрее ?

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

Существует множество способов ускорения вашей VB программы. К сожалению, большинство из них не приводят к особо впечатляющим результатам. Даже если ваша программа работает с огромными коллекциями, преобразование их в массивы, возможно, спасет вам какой-то процент или два в процессе выполнения программы. С другой стороны, переписывание основных алгоритмов программы может сократить процесс выполнения в сотни раз.

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

1. Производя арифметические операции, оперируйте целыми числами и используйте целочисленные операторы, где это возможно. Используйте оператор «\» — целочисленного деления вместо «/» — деления с плавающей точкой. Используйте «* .5» вместо «/ 2», поскольку команда ассемблера «MUL» быстрее, чем «FDIV».

2. Где только это возможно, не применяйте квадратные корни, например:
If a * a + b * b = 4 Then .
гораздо быстрее, чем
If Sqr(a * a + b * b) = 2 Then .

3. Если Вам необходимо производить повторяющиеся вычисления как можно быстрее, наиболее эффективно создать таблицу значений функции, и просто заменять исходные данные на соответствующие результаты из этой таблицы. Например, если заранее указать в таблице x и y как координаты каждой точки на окружности на расстоянии 1-2 градуса, это будет достаточно точно и гораздо быстрее, чем вычислять их значения, используя функции SIN, COS и TAN.

4. Перепишите вашу программу на C++ или Delphi. (Это, конечно, не всегда возможно, но это — единственное решение, когда несмотря ни на что, ваша программа работает невыносимо медленно).

5. Установите у себя 5 или 6 версию VB. Программы, откомпилированные в VB с опцией Native, конечно, работают медленнее, чем программы, написанные на C++ или Delphi, но они намного быстрее, чем неоткомпилированные программы, создаваемые более ранними версиями VB.

6. Создавайте шаблоны. Пользуйтесь средствами контроля производительности для того, чтобы определить, где именно ваша программа проводит больше всего времени. Эти средства встроены в VB 4 и 5, и VB 6 Enterprise Edition. Не теряйте времени по улучшению того кода, который и так достаточно быстрый.

7. Распаковывайте графику. Всегда пользуйтесь файлами с расширением .bmp, а не запакованными .jpg или .gif файлами. Эти файлы хранятся в программе в запакованном виде, и требуется дополнительное время для их раскрытия.

8. Используйте Set your_form = Nothing, когда данная форма вам больше не нужна. Это экономит память и может сэкономить массу времени, когда у вас много форм, которые вы должны хранить в памяти. Если же у вас немного форм, гораздо эффективнее загружать их все в начале программы. Затем они будут появляться на экране быстрее, когда они вам понадобятся. Не закрывайте их до конца, вместо этого применяйте методы Hide/Show по мере необходимости.

9. Используйте массивы вместо коллекций. Массивы намного быстрее. Используйте коллекции только тогда, когда вам нужны их особые свойства, например, просмотр по ключу. Заранее определяйте массивы максимально возможного размера, чтобы не пришлось динамически выделять под них память в процессе выполнения программы — ReDim.

10. Если вам нужно обнулить все элементы динамического массива, используйте ReDim. Это займет больше времени, чем оставить массив в покое, но это гораздо быстрее, чем обнуление элементов массива в цикле.

11. Если вам нужно обнулить все элементы массива фиксированной длины, объявленного с применением Dim, используйте Erase. Это уничтожит динамический массив, но обнулит массив фиксированной длины.

12. Пользуйтесь функциями API MemCopy или RtlMoveMemory для копирования массивов вместо копирования их элементов в цикле.

13. Всегда указывайте определенные типы данных вместо Variant. Всегда объявляйте переменную вместе с ее типом. Если вы не укажете тип переменных, она по умолчанию будет Variant.

14. Всегда указывайте определенные типы объектов вместо объявления переменной типа Object. Будьте настолько точны, насколько это возможно.
Например,
Object — плохо
Control — лучше
TextBox — лучше всего.

15. Никогда не очищайте коллекцию, удаляя ее элементы. Уничтожайте их, используя Set элемент = Nothing.

16. Объявляйте объект и выделяйте под него память на отдельных строках кода. Строка «Dim obj As New My >
17. Для проверки строки нулевой длины «» используйте функцию Len. То есть:
If Len(my_string) = 0 Then . гораздо быстрее, чем:
If my_string = «» Then

18.
Используйте With для длинных последовательностей указаний свойств объектов, повторяемых несколько раз. Это выполняется быстрее, чем если вы повторите серии объектов в каждой отдельной команде.

19. Применяйте как можно меньше операций с переменными типа String, эти операции медленные.

20. Упорядочивайте команды внутри Select Case таким образом, чтобы наиболее часто встречающиеся значения были вначале.

21.
Ощущаемое быстродействие гораздо важнее фактического. Представьте себе, что вы нажали на кнопку, и в течение 10 секунд ничего не происходит. Эти 10 секунд покажутся вам часом. Добавьте ProgressBar, и тогда пользователь даже не заметит, что прошло 10 секунд.

22. Когда у вас в программе множество динамически меняющихся картинок, поместите их все в невидимые Images на первую загружаемую форму, а затем загружайте их по мере необходимости. Никогда не работайте с файлами. Строка
Form2.Image1.Picture = LoadPicture(«yourfile.bmp»)
выполняется в десятки раз медленнее, чем
Form2.Image1.Picture = Form1.Image1.Picture

23. Если вам нужно производить множество операций с файлами или с переменными типа String, всегда добавляйте знак $ после имени команды, например, Mid$ вместо Mid, потому что Mid работает с параметрами типа Variant, в то время, как Mid$ работает с параметрами типа String, что в 3 раза быстрее.

24. Чтобы создать ощущение, что ваша программа выполняется быстро, показывайте первую форму как можно быстрее. Вставьте команду Show в процедуру Form1_Load(), чтобы она появилась на экране до окончания выполнения долгих начальных настроек и вычислений. Помещайте в процедуру каждой формы Load как можно меньше кода для того, чтобы она появлялась как можно быстрее. Если требуется много времени для загрузки начальной формы, создайте дополнительную форму с ProgressBar и загружайте ее немедленно. Эта форма должна быть на экране все время выполнения начальных настроек, она убирается с экрана в конце процедуры Form1_Load().

25. Распределяйте функции и процедуры по модулям. Когда одна процедура вызывает другую, загружается весь модуль второй процедуры. Если одна процедура вызывает несколько процедур из разных модулей, все эти модули загружаются в память. Если же все процедуры находятся в одном модуле, они все загружаются одновременно.

26.
Не тратьте память бездумно. Иногда вы можете заставить вашу программу выполняться быстрее, используя больше памяти, но иногда применение большей памяти сильно замедляет вашу программу. В частности, если вы используете так много памяти, что ваша программа требует больше оперативной памяти, чем есть в системе, система будет загружать программу постранично, что сильно замедлит ее выполнение.

27. Для сокращения требуемой оперативной памяти присваивайте Form1.AutoRedraw = False.
Но для ускорения сложных графических операций присваивайте Form1.AutoRedraw = True.

28. Присваивайте Object.ClipControls = False, где это возможно (прочтите Help для более подробной информации).

29. Для изменения местоположения контролек используйте команду Move вместо изменений значений Left и Top.

30. Если вам нужно изменить серию свойств, связанных с внешним видом (Appearance) объекта, вначале сделайте его невидимым, и только по завершении всех операций, сделайте его снова видимым.

31. Кэшируйте свойства, которые вы применяете много раз. Например, если ваша программа несколько раз обращается к свойству txtLastName.Left, поместите это значение в переменную, и работайте с ней. Обращение к переменной намного быстрее, чем к свойствам объекта.

32. Для того, чтобы нарисовать прямоугольник, вместо четырех команд Line, используйте:
Line (x1, y1)-(x2, y2), , B

33. Вместо PictureBoxes применяйте, где это возможно, Images, поскольку Image требует гораздо меньше памяти.

34. Используйте Frames для хранения других объектов вместо PictureBoxes, так как Frame требует меньше памяти.

35. Неважные объекты помещайте в массивы. Например, множество форм содержат множество Labels. Поместите их все в один массив. Массив, содержащий 10 объектов, требует меньше памяти, чем 10 отдельных объектов.

36. Выполняйте длинные вычисления на фоне выполнения других операций, используя Timer.

37. Используйте комментарии и значимые имена переменных. Длинные комментарии и имена переменных, а также пустые строки не увеличивают размера вашей программы, так что нет никакого вреда в их применении.

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

39. Убирайте неиспользуемые переменные и участки кода, так как они остаются в программе, и увеличивают как ее размер, так и выделяемую под нее оперативную память.

40. Используйте DoEvents, чтобы позволить пользователю выполнять другие операции, пока ваша программа выполняет какой-то длительный процесс. Это уменьшит недовольство пользователя даже, если это не заставит вашу программу выполняться быстрее.

41. Используйте функции API FindFirstFile, FindNextFile, и FindClose для быстрого поиска файлов и папок. Но помните, что не всегда обращение к функциям API быстрее. Это всегда сложнее, и иногда весьма рискованно, чем применение стандартных функций VB.

42. Функции UCase$ и LCase$ позволяют вам осушествлять сравнения вне зависимости от регистра текста, но нижеследующие функции API гораздо быстрее:

Declare Function CharLower Lib «user32» _
Alias «CharLowerA» (ByVal lpsz As String) As String

Declare Function CharUpper Lib «user32» _
Alias «CharUpperA» (ByVal lpsz As String) As String

43. Используйте временные переменные для многократного обращения к сложным выражениям. Например, вам нужно присвоить различные значения объекту
SelectedEmployee.NextOfKin.HomeInformation.Address. Вместо того, чтобы обращаться к этому длинному выражению несколько раз, используйте:

Dim addr As AddressInfo
Set addr = SelectedEmployee.NextOfKin.HomeInformation.Address
addr.Street = txtStreet.Text
addr.City = txtCity.Text
addr.State = txtState.Text
addr.Phone = txtPhone.Text

Команда With дает такое же ускорение, поэтому вы можете использовать:

With SelectedEmployee.NextOfKin.HomeInformation.Address
.Street = txtStreet.Text
.City = txtCity.Text
.State = txtState.Text
.Phone = txtPhone.Text
End With

44. При вызове процедуры или функции, где это возможно, передавайте параметры ByRef, а не ByVal. Когда вы используете ByRef, программа передает только небольшой адрес переменной. Когда же вы используете ByVal, программа должна создать новую копию передаваемой переменной. Обычно гораздо быстрее передать адрес, чем создать копию переменной. Однако, когда вы формируете вызов функций, относящихся к разным процессам, ByVal выполняется быстрее. При таком вызове, VB должен в любом случае запаковать значение переменной для передачи ее другому процессу. Если вы используете ByRef, VB должен затем распаковать результат, и это отнимает больше времени.

45. Для вычисления степеней используйте оператор «*» вместо «^».
Например, A = B * B быстрее, чем A = B ^ 2.

46. Если вам нужно сформировать длинную строку, формируйте ее по частям, и затем собира йте все части воедино. Например, у вас есть процедуры AddText1, AddText2, и т.д., которые добавляют текст к переменной типа String.
Тогда этот код:

Dim txt As String
txt = AddText1(txt)
txt = AddText2(txt)
txt = AddText3(txt)

будет выполняться медленнее, чем следующий:

Dim txt As String
Dim txt1 As String
Dim txt2 As String
Dim txt3 As String
AddText1(txt1)
AddText2(txt2)
AddText3(txt3)
txt = txt1 & txt2 & txt3

В первом примере, процедуры AddText должны манипулировать длинными строками. Во втором примере они работают с относительно короткими строками.

47. Запоминайте промежуточные результаты математических вычислений.
Например, этот код:

Xsquare = x * x
Ysquare = y * y
a = 2 * Xsquare + 3 * Ysquare
b = 3 * Xsquare + 5 * Ysquare
If a + b > 50 Then .

выполняется быстрее, чем следующий:

If 2 * x * x + 3 * y * y + _
3 * x * x + 5 * y * y > 50 _
Then .

48. Не вставляйте в цикл проверку со значением, возвращаемым функцией.
Например, этот код:

87 Хитростей и трюков для Visual Basic’a

Cодержание

1 УПРАВЛЕНИЕ СОБЫТИЯМИ В КОМБОБОКСЕ

Две проблемы могут приключиться, когда смущенный юзер ползает по комбобоксу при помощи мышки вверх и вниз, а затем нажатием на Enter делает свой юзерский выбор. Во-первых, нажатие на серую стрелочку вызывает два события: Change и Click. Во-вторых, нажатие на Enter перемещает фокус к следующему элементу формы, тогда как нажатие на кнопку мыши не вызывает подобного эффекта (т.е. фокус остается на комбобоксе). Поэтому, если Ваш код помещен в секцию события Change, то на стрелочки вверх/вниз (клавиатурой) вызовет это событие, чего Вы, естественно, не хотите. Напротив, если Вы помещаете свой код только в секцию события Lost Focus и юзер щелкает мышью на своем выборе, то фокус не уйдет из комбобокса, а юзер будет созерцать текст, который он выбрал своей мышью, и думать, почему это ничего не происходит. Нижеприведенное решение «фильтрует базар» событий Click, генерирующихся нажатиями на стрелочки клавиатуры, и вынуждает контрол потерять фокус.В секции Declarations формы введите следующее

‘ В VB3 надо поменять тип флага на integer
Dim bNoise as Boolean
‘ True означает, что происходит «шум», на который не следует реагировать

А этот код введите в секции события Form_Load:

Этот код введите в событии KeyDown комбобокса:

Private Sub cbTest_KeyDown(KeyCode As _
Integer, Shift As Integer)
‘ если юзер использует стрелки для езды по списку комбобокса
‘ игнорировать события Click
If KeyCode = vbKeyDown Or KeyCode _
= vbKeyUp Then bNoise = True
End Sub

Этот код вводится в событии Click комбобокса:

Private Sub cbTest_Click()
If bNoise Then
‘ Ignore Noise events
‘ (up or down arrow)
bNoise = False
Else
‘ Увести фокус с контрола
SendKeys ««, True
End If
End Sub

Теперь Вам остается написать код, содержащий реакцию на выбор юзера, и занести его в секцию события LostFocus комбика.

Назад к СОДЕРЖАНИЮ

2. КОММЕНТИРОВАНИЕ И РАСКОММЕНТИРОВАНИЕ БЛОКОВ КОДА

VB5
Level: Beginning

VB 5.0 позволяет Вам разом закомментировать целый блок кода, а затем также быстро раскомментировать его. Это очень полезно при отладке, когда Вам не нужно исполнять целый ряд операторов, и в то же время Вы не можете их удалить вот так вот просто за здорово живешь. Между тем, пара кнопарей Comment/Uncomment присутствует только в тулбаре Edit, который надо специально вызывать :-(. Чтобы быстро вызвать тулбар Edit, кликните правой кнопкой мыши на любом тулбаре в VB, и выберите затем команду Edit.

Назад к СОДЕРЖАНИЮ

3. ЗНАЧЕНИЯ ПО УМОЛЧАНИЮ ДЛЯ НЕОБЯЗАТЕЛЬНЫХ ПАРАМЕТРОВ

VB5
Level: Beginning

Если Вы когда-либо программили на VB4, то Вы возможно пользовались мощной фишкой под названием Необязательные параметры (Optional parameters). VB5 пошел еще дальше: теперь эти параметры могут быть любого типа (не только Variants), и могут появляться в процедурах Property. Интересно, что Вы можете теперь задавать для них значение по умолчанию.

Property Get Value _
(Optional index As Long = 1)
End Property

Вы можете теперь делать это без бывшего ранее обязательным (и жутко тормозным) тестом IsMissing:

Property Get Value _
(Optional index As Long)
If IsMissing(index) Then index = 1
.
End Property


Назад к СОДЕРЖАНИЮ

4. НЕ СОЗДАВАЙТЕ ALIAS-НЫХ ПЕРЕМЕННЫХ

VB5
Level: Beginning

Никогда не передавайтe глобальную переменную в качестве аргумента в процедуру, которая также напрямую обращается к этой переменной из себя (зачем??). Если Вы на 100% уверены, что следуете этому правилу в Ваших программах, то зачеркните опцию Assume No Aliasing в диалоговом окне Advanced Optimizations, которое вызывается из пункта Compile диалога Project Properties (уф, надеюсь, понятно). Если компилятор native code знает, что этих самых alias-ных переменных нет, то он спокойно копирует значения переменных в шустрые регистры ЦПУ, и переписывает их значения обратно в RAM только при выходе из процедуры. Это увеличивает скорость исполнения скомпилированных программ.

Назад к СОДЕРЖАНИЮ

5. ЦЕНТРИРОВАНИЕ ФОРМЫ НА ЭКРАНЕ

VB5
Level: Beginning

Все знают о маленьком кодике, позволяющем Вам центрировать форму на экране вне зависимости от графического разрешения. Теперь Вы можете достичь того же результата, всего лишь присвоив значение vbStartUpScreen (=2) новому свойству StartUpPosition формы (появилось в версии 5). Вы даже можете отцентрировать форму относительно ее родительского окна, присвоив значение vbStartUpOwner (=1). Присвоение можно сделать в окне Property соответствующей формы. Когда Вы центрируете форму внутри родительского окна, не забудьте добавить второй аргумент в методе Show.

Form2.Show vbModal, Me

Назад к СОДЕРЖАНИЮ

6. НЕ УВЛЕКАЙТЕСЬ АВТООПТИМИЗИЦИЕЙ FAST CODE

VB5
Level: Beginning

Если взглянуть на опции native code оптимизации, то сперва так и подмывает щелкнуть на «Optimize for Fast Code». Однако, как ни странно это может прозвучать, данное действие далеко не всегда гарантирует ожидаемый эффект. Аппликухи, оптимизированные на скоростное исполнение, как правило, не оптимизируются (пардон за каламбур), а лишь получают большее количество памяти при загрузке. Это обращается для них более медленной загрузкой, что особенно заметно на машинах с недостаточным количеством RAM, и в итоге создает впечатление, что Ваша аппликуха работает медленнее, нежели оптимизированная под компактный код. По той же самой причине, советуется компилить аппликухи в P-code. В случае объемных, UI- и базоданских аппликух, выигрыш от компиляции в native-code отнюдь не перевесит увеличения размера аппликухи. Вообще, чтобы точно знать, какая компиляция нужна Вам, юзайте VB Application Performance Explorer (APE), который лежит на VB CD.

Назад к СОДЕРЖАНИЮ

7. НЕ ВСЕ ШАБЛОНЫ СОЗДАНЫ ОДИНАКОВО

VBA5
Level: Beginning

В отличие от других продуктов Office 97, шаблоны Word 97 содержат business-application engine, который хранится отдельно от документов, использюущих этот engine. Основанные на шаблонах книги Excel и презентации PowerPoint хранят в себе шаблоны, на основе которых они созданы. На практике, все документы Word состоят из 2х VBA проектов: первый проект создан на базе основного(оригинального, хранящегося в Word) шаблона (все документы Word основаны на шаблонах), а второй проект принадлежит самому документу Word. С другой стороны, книги Excel и презентации PowerPoint, созданные на шаблонах, содержат только один VBA проект. Каждый файл содержит свою собственную копию проекта оригинального шаблона. Изменения, производимые в этом шаблоне, не затрагивают основной шаблон, хранящийся в приложении.

Назад к СОДЕРЖАНИЮ

8. НАСТРОЙКА ТУЛБАРОВ В VB

VB5
Level: Beginning

Вот несколько предложений по настройке IDE в VB5:
Добавить закладки в тулбокс можно, кликнув правой кнопкой мыши на кнопке General (что на тулбоксе), и выбрав Add Tab. Вы можете также перемещать и удалять закладки, и перемещать иконы контролов с одной закладки на другую, используя обычный метод drag-and-drop.
Вытащить кнопку любого пункта меню на тулбар можно, кликнув правой кнопкой на любом тулбаре и выбрав пункт Customize. Перейдите на закладку Commands, выберите нужный пункт меню в правом окошке, и перетащите его на тулбар. Первыми кандидатами на добавление являются пункты Project-References,Project-Properties, и Tools-Add Procedure.
Как создать совершенно новый тулбар на вкладке Toolbars диалогового окна Customize. После того, как Вы определили содержимое будущего тулбара, для добавления кнопок на этот тулбар используйте описанную абзацем выше процедуру. Когда у Вас на экране активизировано диалоговое окно Customize, кликните правой кнопкой на любой кнопке тулбара и Вы сможете поменять рисунок кнопки, создать разделитель, спрятать/показать текст и т.д.

Назад к СОДЕРЖАНИЮ

9. КАК СПРЯТАТЬ ВСЕ ОКОШКИ ПРОЕКТА

VB5
Level: Beginning

Когда Вы работаете с несколькими пректами сразу, можно запутаться в нагромождении туевой хучи окошек из разных проектов. Однако, Вы можете временно спрятать все окошки, относящиеся к данному проекту, щелкнув по пиктограмме проекта в окошке Project Explorer так, чтобы все ветви, торчащие из него, исчезли. Тогда же свернутся и все окна, относящиеся к данному проекту. Эту возможность можно отменить, щелкнув на сответствующем квадратике на закладке General в меню Tools-Options.

Назад к СОДЕРЖАНИЮ

10. STANDALONE БИБЛИОТЕКИ ТИПОВ

VB4 16/32, VB5 (Enterprise Edition)
Level: Intermediate

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
Level: Intermediate
Если кликнуть правой кнопкой мыши в правом окошке Object Browser’а (там, где нарисованы члены классов), то выскочит контекстное меню с командой Show Hidden Members. Если щелкнуть на этой команде, то отныне Object Browserбудет показывать все hidden-свойства и методы (а также и классы) любой библиотеки, и Вы можете использовать это для более детального исследования библиотек объектов.
Например, в библиотеке VBA есть hidden класс под названием _HiddenModule, в который входят многие известные функции VBA плюс три недокументированные: ObjPtr, StrPtr, и VarPtr. ObjPtr возвращает адрес private area экземпляра объекта, StrPtr возвращает адрес первого символа в строке, VarPtr возвращает адрес переменной или дескриптора строки (string descriptor), если имеем случай переменной типа string.

Назад к СОДЕРЖАНИЮ

12. АДРЕС ПЕРЕМЕННОЙ

VB4 16/32
Level: Advanced

В VB5 есть встроенная функция VarPtr (см. Совет «ИСПОЛЬЗОВАНИЕ OBJECT BROWSER’a длЯнахождениЯ недокументированных возможностей»), но этой функции нет в VB4. Runtime library в VB4 включает эту функцию, но перед использованием ее нужно сначала объявить:

#If Win16 Then
Declare Function VarPtr Lib «VB40016.DLL» (variable As Any) As Long
#Else
Declare Function VarPtr Lib «VB40032.DLL» (variable As Any) As Long
#End If

Эта функция полезна при передаче пользовательских типов (Type structure) во внешнюю процедуру API, и в этом типе какое-либо из полей является адресом другой переменной или записи.

Назад к СОДЕРЖАНИЮ

13. КОГДА BENCHMARK’и (ИЗМЕРЕНИЯ СКОРОСТИ РАБОТЫ ПРОГИ) ДЛЯТСЯ СУТКАМИ

VB4 16/32, VB5
Level: Intermediate

Обычно, программисты на VB измеряют скорость выполнения кода при помощи Timer функции. Однако, если Ваша программа должна завершиться на следующий день, то Вы должны учесть, что значение, возвращаемое функцией Timer, ресетится в полночь. Если же Вас устроит значение с точностью до одной секунды, Вы можете упростить Ваш код с помощью функции Now.

Dim startTime As Date
StartTime = Now
‘ the code to be benchmarked
‘ .
Print «elapsedSeconds = » & Format$ ((Now — startTime) * 86400, «#####»)

Вам понадобится функция Format$ для округления результата до целого.

Назад к СОДЕРЖАНИЮ

14. APP.PATH МОЖЕТ ВОЗВРАЩАТЬ UNC-ПУТИ

VB5
Level: Intermediate

В отличие от VB4, App.Path в VB5 может возвращать UNC-путь, типа «\\server\programs\. «, в зависимости от обстоятельств, от того как запущена программа и запущена она из VB IDE или скомпилирована в EXE-файл. Эта особенность может сильно испортить вам жизнь, если Вы используете App.Path для установки текущего каталога при старте программы.

ChDrive App.Path
ChDir App.Path

Поскольку ChDrive на умеет обрабатывать UNC-пути, этот код может вызвать фатальную ошибку времени выполнения, но можт быть защищен использованием On Error Resume Next. Однако этот фикс не защитит Вас от всех невзгод, могущих произойти. Наилучшее решение состоит в том, чтоюы предоставить юзеру самому ввести каталог во время исполнения программы, затем записать полученный путь в регистр или INI-файл. Для более подробной инфы, см. статью Q167167 в Microsoft Knowledge Base.

Назад к СОДЕРЖАНИЮ

15 ЕЩЕ ОБ УНИВЕРСАЛЬНЫХ ПАРАМЕТРАХ МАССИВОВ

VB4 16/32, VB5
Level: Advanced
Вы можете написать единую процедуру для любых типов массива с любым типом в качестве аргумента, используя параметр типа Variant. Внутри процедуры, адресация элементов массива происходит обычным способом:

‘ return the number of items
Function ItemCount(anArray As Variant) As Long
ItemCount = UBound(anArray) — LBound(anArray) + 1
‘ the first element is
‘ anArray(LBound(anArray))
End Function

Вы можете даже запулить в процедуру многомерный массив с любым колическтвом измерений, а чтобы разобраться, сколько же у этого массива измерений, нужно производить обращения к функциям UBound и Lbound до возникновения ошибки:

Function ItemCount(anArray As Variant)As Long
Dim items As Long, i As Integer
On Error Resume Next
items = UBound(anArray) — LBound(anArray) + 1
For i = 2 to 999
items = items * (UBound(anArray, _
i) — LBound(anArray, i) + 1)
If Err Then Exit For
Next
ItemCount = items
End Function

Назад к СОДЕРЖАНИЮ

16. УМЕНЬШИТЬ РАЗМЕР КОДА, ИСПОЛЬЗУЯ ОПЕРАТОРЫ IIF И SWITCH

VB4 16/32, VB5
Level: Intermediate
Часто бывает целесообразным заменить блок If. Then. Else более компактной функцией Iif:

‘ возвращает большую из двух сравниваемых величин
maxValue = IIf(first >= second,first, second)

Switch — редко используемая функция, даже в тех многочисленных случаях, когда она более полезна нежели длиннющий блок If. ElseIf:

‘ надо узнать, х полижительный, отрицательный, или равен 0?
Print Switch(x 0, _
«positive», True, «Null»)

Заметим, что значение последней проверки всегда True, так как три условия являются взаимно исключающими и избыточными.

Назад к СОДЕРЖАНИЮ

17. УСКОРЬТЕ ВАШ КОД ИСПОЛЬЗОВАНИЕМ CHOOSE

VB3, VB4 16/32, VB5
Level: Beginning

Вы можете использовать Choose там, где можно заменить массив или построить таблицы результатов, на стадии компиляции (compile-time), вместо того, чтобы делать это на стадии выполнения (run time). Например, если Вам надо знать значения факториалов чисел от 1 до 10, попробуйте следующий пример (Choose производит выбор факториала из набора имеющихся значений всесто того, чтобы высчитывать факториал каждый раз заново):

Function Factorial(number As Integer) _
As Long
Factorial = Choose(number, 1, 2, 6, _
24, 120, 720, 5040, 40320, _
362880, 3628800)
End Function

Назад к СОДЕРЖАНИЮ

18. GOSUBS РАБОТАЮТ МЕДЛЕННО В ОТКОМПИЛИРОВАННЫХ ПРОГРАММАХ

VB5
Level: Intermediate

Поскольку использование GoSubs относится к неструктурированному стилю программирования, то многие программисты стараются избегать его. Если Вы компилируете Вашу VB5 аппликуху в native code, у Вас появится еще одна причина избегать этот оператор, поскольку вызовы через GoSubs могут происходить в пять раз медленнее, чем вызовы обычной процедуры или функции.

Назад к СОДЕРЖАНИЮ

19. «ARRAY» — ОТНЫНЕ ЭТО ОШИБОЧНОЕ ИМЯ ДЛЯ ПЕРЕМЕННЫХ

VB5
Level: Intermediate

Если Вы, как и я, часто используете имя «array» для переменных, Вам придется пересмотреть Ваш код при переносе его под VB5. Это слово является теперь зарезервированным (reserved keyword) и не может быть использовано в качестве имени переменной. Вы можете легко переделать Ваш код при помощи команды Replace в IDE VB5, не забудьте при этом черкнуть «Find whole words only».

Назад к СОДЕРЖАНИЮ

20. ЗАПУСК AUTOMATION MANAGER КАК HIDDEN ЗАДАЧИ

VB4 16/32, VB5 Enterprise Edition
Level: Advanced

Если Вы мспользуете OLE Remote Automation, Вы должны заранее запустить Automation Manager на сервере до того как случится первая OLE remote communication. По умолчанию, это приложение visible, но Вы можете его спрятать, чтобы оно не мозолило глаза на таскбаре Чикаги. Для этого создайте ярлык для Automation Manager, который бы включал в командной строке переключатель /Hidden:
C:\Windows\System\AutMgr32.Exe /Hidden
С другой стороны, Вы можете поменять значение соответствующего ключа в регистре. Для более полной инфы, см. Статью Q138067 in the Microsoft Knowledge Base.

Назад к СОДЕРЖАНИЮ

21. ПРОБЛЕМЫ СО ВСПЛЫВАЮЩИМИ МЕНЮ

VB4 16/32, VB5
Level: Advanced

Если Вы используете всплывающие меню (popup menus) в Ваших прогах, то опасайтесь бага, имеющегося в VB4 16/32 и VB5. Если у Вас есть две формы и одна из них вызывает вторую модальную через всплывающее меню, то из этой второй модальной Вы не сможете вызвать ни одного всплывающего меню, сколько бы их на ней ни было. Чтобы пофиксить это дело, используйте таймер на первой форме. Вместо показа фторой формы из всплывающего меню по событию Click, активизируйте таймер так, чтобы он показал эту вторую форму через несколько миллисекунд. Для более полной инфы, см. Статью Q167839 in the Microsoft Knowledge Base.

22. ИСПОЛЬЗОВАНИЕ КОЛЛЕКЦИИ ДЛЯ ОТФИЛЬТРОВЫВАНИЯ ДУБЛИРОВАННЫХ ЗНАЧЕНИЙ

VB4 16/32, VB5
Level: Intermediate
Этот код иллюстрирует, как использовать коллекции (Collection) для генерации уникального набора величин из набора, содержащего дубликаты. В этом примере, сканируется массив строк и сортируются все уникальные с использованием list-box контрола:

Sub Remove_Duplicates(arr() As String)
Dim i As Long
Dim RawData As String
Dim DataValues As New Collection

On Error Resume Next
‘ это вставлено для игнорирования ошибки 457 — Duplicate key
For i = LBound(arr) To UBound(arr)
RawData = arr(i)
DataValues.Add RawData, RawData
‘ Если Run-time error 457 случилась, то повторяющееся значение игнорируется
Next
On Error GoTo 0

‘ Сохранение в List Box
‘ (свойство Sorted выставлено True)
lstSortedData.Clear
For Each DataValue In DataValues
lstSortedData.AddItem DataValue
Next
End Sub

Назад к СОДЕРЖАНИЮ

23. СОЗДАНИЕ «УДАЛЕННО КОНТРОЛИРУЕМЫХ» ФОРМ

VB3
Level: Intermediate

Иногда мне требуется котролировать одну форму, когда фокус находится на другой. Например, когда я жму «ОК» на форме А, мне надо сделать resize на форме В. Итак, на каждой форме, которую мне надо «удаленно контролировать», я делаю невидимый text box, назовем его TextCommand, в событии Change которого находится следующий код:

Sub TextCommand_Change ()
Dim msg as string
msg = Trim$(Me.TextCommand.Text)
If Len(msg) = 0 Then Exit Sub

Select Case msg
Case «COMMAND_RESIZE»
Call MyFormResize
Case «COMMAND_REPAINT»
Call MyFormPaint
.
End Select
Me.TextCommand = «»
End Sub

Вы можете удаленно контролировать форму, засылая соответствующее значение в ее TextCommand:

Sub Command1_Click ()
formB.TextCommand = «COMMAND_RESIZE»
DoEvents
End Sub

Этот код можно использовать для отсылки мессагов из MDI формы к потомкам:

Dim f As Form
Set f = Me.ActiveForm
f.TextCommand = «COMMAND_RESIZE»

Если Вы сидите под VB4 или VB5, Вы можете также использовать Public-свойства и методы формы.

Назад к СОДЕРЖАНИЮ

24. ЗАПИСЬ ТЕКУЩЕЙ ПОЗИЦИИ И РАЗМЕРА ФОРМЫ ПРИ ПОМОЩИ SAVESETTING

VB4 16/32, VB5
Level: Intermediate
Функции SaveSetting и GetSetting облегчают написание сеттингов в аппликухах. Эти две функции восстанавливают и запоминают текущие позиции формы:

Public Sub FormPosition_Get(F As Form)
‘ Считывает позицию формы F из
‘ ini/reg файла и соответственно
‘ позиционирует форму
Dim buf As String
Dim l As Integer, t As Integer
Dim h As Integer, w As Integer
Dim pos As Integer

buf = GetSetting(app.EXEName, _
«FormPosition», F.Tag, «»)
If buf = «» Then
‘ defaults для центрирования фромы
F.Move (Screen.Width — F.Width) \ _
2, (Screen.Height — F.Height) \ 2
Else
‘ выделить l,t,w,h и выставить форму
pos = InStr(buf, «,»)
l = CInt(Left(buf, pos — 1))
buf = Mid(buf, pos + 1)
pos = InStr(buf, «,»)
t = CInt(Left(buf, pos — 1))
buf = Mid(buf, pos + 1)
pos = InStr(buf, «,»)
w = CInt(Left(buf, pos — 1))
h = CInt(Mid(buf, pos + 1))
F.Move l, t, w, h
End If
End Sub

Public Sub FormPosition_Put(F As Form)
‘ Пишет op,left,height и
‘ width позиции формы F в reg/ini файл аппликухи
Dim buf As String
buf = F.left & «,» & F.top & «,» & _
F.Width & «,» & F.Height
SaveSetting app.EXEName,_
«FormPosition», F.Tag, buf
End Sub

Вам следует поместить эти процедуры в модуль и вызывать их из событий Load и Unload форм. Вы должны написать имя формы в ее свойство Tag, чтобы эти процедуры работали корректно

Sub Form_Load()
FormPosition_Get Me
End Sub
Sub Form_Unload()
FormPosition_Put Me
End Sub

25. ЭФФЕКТИВНОЕ ИСПОЛЬЗОВАНИЕ ВНУТРЕННИХ VB КОНСТАНТ

VB4 16/32, VB5
Level: Beginning

Мне приходилось видеть некоторые советы по использованию числовых значений вместо соответствующих VB констант. Например, Вы можете вывести message box, используя числовые константы:

rc = MsgBox(msg, 4 + 32 + 256, «Confirm Delete»)

Но не легче ли прочесть следующее?

rc = MsgBox(msg, vbYesNo + vbQuestion _
+ vbDefaultButton2, _
«Confirm Delete»)

Вы можете использовать следующие константы для check box:

VbUnchecked =0
VbChecked =1
VbGrayed =2

Также полезно знать строковые константы вместо соответствующих chr$(символы ASCII):

vbTab instead of Chr$(9)
vbCr instead of Chr$(13)
vbLf instead of Chr$(10)
vbCrLf instead of Chr$(13)+Chr$(10)

26 ПРАВИЛЬНЫЙ ТЕСТ НА «FILE EXIST»

VB3, VB4 16/32, VB5
Level: Intermediate

Dir$ генерирует runtime error, если ему суют несуществующее имя диска. Например, Dir$ («d:\win\himems.sys») умирает , если драйв d: не существует. Для проверки существования файла, добавьте обработчик ошибки:

Function FileExist(filename As String) _
As Boolean
On Error Resume Next
FileExist = Dir$(filename) <> «»
If Err.Number <> 0 Then FileExist _
= False
On Error GoTo 0
End Function

Назад к СОДЕРЖАНИЮ

27. ПРОЦЕДУРЫ, РАБОТАЮЩИЕ С ГРУППАМИ КОНТРОЛОВ

VB4 16/32, VB5
Level: Intermediate

Вы можете использовать почти забытую возможность VB иметь процедуру или функцию, работающую с неограниченным числом аргументов, что может быть полезно при работе с множеством контролов. Например, Вы можете enable/disable группу контролов одним вызовом процедуры:

EnableAll True, Text1, Text2, _
Command1, Command2

Эта процедура проходит по всем контролам, передаваемым в качестве аргументов:

Sub EnableAll(Enabled As Boolean, _
ParamArray objs() As Variant)
Dim obj As Variant
For Each obj In objs
obj.Enabled = Enabled
Next obj
End Sub

Назад к СОДЕРЖАНИЮ

28 УЛУЧШЕНИЕ СКРОЛЛИНГА РИСУНКОВ

VB3, VB4 16/32, VB5
Level: Intermediate
Во-первых, сделайте, чтобы событие Scroll скроллбара картинки обновляло координаты картинки (как будто бы она движется) когда Вы возите мышой по картинке. Затем, объявите следующие переменные на уровне формы:

Dim StartX As Long, StartY As Long
Dim Moving As Boolean

Finally, declare these three events for PicPicture:
Наконец, объявите эти три события для PicPicture:

Private Sub PicPicture_MouseDown_
(Button As Integer, Shift As _
Integer, x As Single, y As Single)
StartX = x
StartY = y
Moving = True
End Sub

Private Sub PicPicture_MouseMove_
(Button As Integer, Shift As _
Integer, x As Single, y As Single)
If Moving Then
PicPicture.Move _
PicPicture.Left + x — StartX, PicPicture.Top + y — StartY
End If
End Sub

Private Sub PicPicture_MouseUp_
(Button As Integer, Shift As _
Integer, x As Single, y As Single)
Moving = False
End Sub

Теперь Вы можете скроллить картинку мышой. Не забудьте проверить границы картинки.

29. ЗАШИФРОВАННЫЕ ПАРОЛИ

VB3, VB4 16/32, VB5
Level: Intermediate

Следующие две функции легко и эффективно шифрут/дешифруют текстовый пароль. Функции имеют два аргумента: число от 1 до 10 чтобы сдвигать позицию символа ASCII в пароле, и собственно строка пароля. Функция EncryptPassword проходит через каждый символ строки DecryptedPassword, проверяет символ на четность/нечетность, и сдвигает его вверх/вниз согласно параметру Number. Эту делает зашифрованную строку нечитабельной. Зашифрованный пароль «укатывается» затем оператором XOR, который еще более запутывает строку. Я ограничил параметр Number числом 10, поскольку мне не надо делать проверку на «неправильные» символы ASCII. Функция DecryptPassword повторяет в обратном порядке процесс шифрования, применяя XOR, а затем сдвиг.

Function EncryptPassword(Number As _
Byte, DecryptedPassword As String)
Dim Password As String, Counter As Byte
Dim Temp As Integer

Counter = 1
Do Until Counter = _
Len(DecryptedPassword) + 1
Temp = Asc(Mid(DecryptedPassword, _
Counter, 1))
If Counter Mod 2 = 0 Then
‘see if even
Temp = Temp — Number
Else
Temp = Temp + Number
End If
Temp = Temp Xor (10 — Number)
Password = Password & Chr$(Temp)
Counter = Counter + 1
Loop
EncryptPassword = Password
End Function

Function DecryptPassword(Number As _
Byte, EncryptedPassword As String)
Dim Password As String, Counter As Byte
Dim Temp As Integer

Counter = 1
Do Until Counter = _
Len(EncryptedPassword) + 1
Temp = Asc(Mid(EncryptedPassword, _
Counter, 1)) Xor (10 — Number)
If Counter Mod 2 = 0 Then ‘see if even
Temp = Temp + Number
Else
Temp = Temp — Number
End If
Password = Password & Chr$(Temp)
Counter = Counter + 1
Loop
DecryptPassword = Password
End Function

30. ПРОПИСНЫЕ-СТРОЧНЫЕ БУКВЫ — СОВЕТ ПО СЛЕЖЕНИЮ ЗА РЕГИСТРОМ БУКВ

VB4 16/32, VB5
Level: Intermediate
Если Вы используете левую стрелку на клаве, чтобы перейти к началу слова, а затем нажимаете букву, то в итоге Вы получаете две заглавных буквы (первая уже была, а вторую ввели Вы — я так понимаю??). Применив код, который использует преимущества встроенной в VB4/VB5 функции StrConv(), Вы получите автоматическое приведение букв в нужный регистр во время ввода:

Private Sub Text1_Change()
If Text1.Tag = «» Then
Text1.Tag = Text1.SelStart
Text1.Text = StrConv(Text1.Text, vbProperCase)
Text1.SelStart = Text1.Tag
Text1.Tag = «»
End If
End Sub

31. ОТСЛЕЖИВАНИЕ DOUBLE CLICK ДЛЯ КНОПОК НА ТУЛБАРЕ

VB4 32, VB5
Level: Intermediate
VB4 поддерживает встроенный в Win95 контрол Toolbar, позволяющий юзерам добавлять кнопки на Тулбар. У этих кнопок есть событие ButtonClick, но если Вы хотите отлавливать double-click, то стандартного события ButtonDoubleClick нет. Чтобы исправить это, объявите две переменные уровня формы:

Private mbSingleClicked As Boolean
Private mbDoubleClicked As Boolean

In the Toolbars ButtonClick event, add this code:
В событии ButtonClick Тулбара добавьте следующий код:

Private Sub Toolbar1_ButtonClick_
(ByVal Button As Button)
Dim t As Single
t = Timer
If mbSingleClicked = True Then
mbDoubleClicked = True
MsgBox «Double Clicked»
Else
mbSingleClicked = True
‘ позволить юзеру кликнуть еще раз, если он хочет дабл-кликнуть
Do While Timer — t Назад к СОДЕРЖАНИЮ

32. ОБЪЕМ КАТАЛОГА В БАЙТАХ

VB3, VB4 16/32, VB5
Level: Intermediate

Эта функция возвращает число байт, занятых файлами в каталоге:

Function DirUsedBytes(ByVal dirName As _
String) As Long
Dim FileName As String
Dim FileSize As Currency

‘ добавить \, если не было
If Right$(dirName, 1) <> «\» Then
dirName = dirName & «\»
Endif
FileSize = 0
FileName = Dir$(dirName & «*.*»)

Do While FileName <> «»
FileSize = FileSize + _
FileLen(dirName & FileName)
FileName = Dir$
Loop
DirUsedBytes = FileSize

Пример вызова такой функции:

Назад к СОДЕРЖАНИЮ

33. ПОЛЕЗНАЯ ДИСКОВАЯ ИНФОРМАЦИЯ

VB4 32, VB5
Level: Advanced

Эта функция возвращает количество свободного пространства на диске, общий объем диска, долю свободного пространства н адиске, и использванное пространство. Перед вызовом функции, присвойте первому полю структуры DISKSPACEINFO («RootPath») имя диска:

Dim dsi As DISKSPACEINFO
dsi.RootPath = «C:\»
GetDiskSpace dsi

Функция возвращает все результаты в других полях записи(структуры):

‘ *** Declaratiosn Section ******
Declare Function GetDiskFreeSpace Lib _
«kernel32» Alias _
«GetDiskFreeSpaceA» _
(ByVal lpRootPathName As String, _
lpSectorsPerCluster As Long, _
lpBytesPerSector As Long, _
lpNumberOfFreeClusters As Long, _
lpTotalNumberOfClusters As Long) _
As Long

Type DISKSPACEINFO
RootPath As String * 3
FreeBytes As Long
TotalBytes As Long
FreePcnt As Single
UsedPcnt As Single
End Type

‘ ****** МОДУЛЬ КОДА ******
Function GetDiskSpace(CurDisk As _
DISKSPACEINFO)
Dim X As Long
Dim SxC As Long, BxS As Long
Dim NOFC As Long, TNOC As Long

X& = GetDiskFreeSpace_
(CurDisk.RootPath, SxC, BxS, _
NOFC, TNOC)
GetDiskSpace = X&

If X& Then
CurDisk.FreeBytes = BxS * _
SxC * NOFC
CurDisk.TotalBytes = BxS * _
SxC * TNOC
CurDisk.FreePcnt = ((CurDisk._
TotalBytes CurDisk._
FreeBytes) / CurDisk._
TotalBytes) * 100
CurDisk.UsedPcnt = _
(CurDisk.FreeBytes / _
CurDisk.TotalBytes) * 100
Else
CurDisk.FreeBytes = 0
CurDisk.TotalBytes = 0
CurDisk.FreePcnt = 0
CurDisk.UsedPcnt = 0
End If
End Function

В таком виде, функция работает с драйвами размера где-то до 2Гб, для больших дисков надо использовать переменные типа Single.

Назад к СОДЕРЖАНИЮ

34. КАК СЫМИТИРОВАТЬ НАЖАТИЕ КЛАВИШИ CTRL ДЛЯ ВЫДЕЛЕНИЯ НЕСВЯЗАННЫХ КУСКОВ В LIST BOX

VB4 32, VB5
Level: Advanced

Когда свойство MultiSelect обычного listboxа установлено в 1 — Simple или в 2 — Extended, то юзеру надо жать Ctrl при кликании внутри этого listboxа, чтобы выделять несвязанные (идущие неподряд) элементы. Мой метод позволяет юзеру выбирать несколько элементов, не нажимая при этом Ctrl. Поместите нижеприведенный код в модуль.

Declare Function GetKeyboardState Lib _
«user32» (pbKeyState As Byte) _
As Long
Declare Function SetKeyboardState Lib _
«user32» (lppbKeyState As Byte) _
As Long
Public Const VK_CONTROL = &H11
Public KeyState(256) As Byte

Этот код засуньте в событие MouseDown Вашего listboxа (назовем его List1), у которого свойство MultiSelect установлено в Simple или Extended:

‘ «нажимает» Ctrl
GetKeyboardState KeyState(0)
KeyState(VK_CONTROL) = _
KeyState(VK_CONTROL) Or &H80
SetKeyboardState KeyState(0)

Этот код поместите в процедуру, в которой надо «отжать» Ctrl, например, List1_LostFocus:

‘ «отжимает» Ctrl
GetKeyboardState KeyState(0)
KeyState(VK_CONTROL) = _
KeyState(VK_CONTROL) And &H7F
SetKeyboardState KeyState(0)

35. ВЫБРАТЬ ВСЕ ФАЙЛЫ ПО МАСКЕ В ПОДДЕРЕВЕ КАТАЛОГОВ

VB3, VB4 16/32, VB5
Level: Intermediate

Поскольку этот код не использует API, Вы можете легко перенести его с 16- на 32-разрядную платформу и обратно. Процедура DirWalk позводит Вам просмотреть все поддерево, начиная с заданнного места:

ReDim sArray(0) As String
Call DirWalk(«OLE*.DLL», «C:\», sArray)

Эта процедура принимает * и ? в первом аргументе, который задает маску поиска. Вы можете задать несколько масок, разделяя их символом «;», например, «OLE*.DLL; *.TLB». Второй аргумент — место старта, третий аргумент — массив строк.
Эта процедура рекурсивно проходит по всем каталогам и кладет все файлы, удовлетворяющие условию, в массив sArray с указанием полного пути. Этот массив меняет свои размеры в зависимости от количества файлов, удовлетворяющих условиям поиска.
Для использовния DirWalk, пихните два контрола, FileListBox и DirListBox, на форму. Эта процедура подразумевает, что она работает с контролами на текущей форме: : FileListBox по имени File1, и DirListBox по имени Dir1. Для увеличения скорости работы сделайте эти контролы невидимыми. Использование этих контролов не требует приобретения дополнительных тулзов, так как они (контролы) содержатся в базовой библиотеке контролов VB.

Sub DirWalk(ByVal sPattern As String, _
ByVal CurrDir As String, sFound() _
As String)
Dim i As Integer
Dim sCurrPath As String
Dim sFile As String
Dim ii As Integer
Dim iFiles As Integer
Dim iLen As Integer

If Right$(CurrDir, 1) <> «\» Then
Dir1.Path = CurrDir & «\»
Else
Dir1.Path = CurrDir
End If
For i = 0 To Dir1.ListCount
If Dir1.List(i) <> «» Then
DoEvents
Call DirWalk(sPattern, _
Dir1.List(i), sFound())
Else
If Right$(Dir1.Path, 1) = «\» _
Then
sCurrPath = Left(Dir1.Path, _
Len(Dir1.Path) — 1)
Else
sCurrPath = Dir1.Path
End If
File1.Path = sCurrPath
File1.Pattern = sPattern
If File1.ListCount > 0 Then
‘ нужные файлы найдены в каталоге
For ii = 0 To File1._
ListCount — 1
ReDim Preserve _
sFound(UBound(sFound) _
+ 1)
sFound(UBound(sFound) — _
1) = sCurrPath & _
«\» & File1.List(ii)
Next ii
End If
iLen = Len(Dir1.Path)
Do While Mid(Dir1.Path, iLen, _
1) <> «\»
iLen = iLen — 1
Loop
Dir1.Path = Mid(Dir1.Path, 1, _
iLen)
End If
Next i
End Sub

36. ИМЯ ТЕКУЩЕГО КОМПЬЮТЕРА В WINDOWS 95/NT

VB4 32, VB5
Level: Advanced

Часто Вам надо знать имя текущего компа под WINDOWS 95/NT из Вашей VB проги. Используйте эту простенькую функцию API из kernel32.dll:

Private Declare Function GetComputerNameA Lib «kernel32″_
(ByVal lpBuffer As String, nSize _
As Long) As Long

Public Function GetMachineName() As _
String
Dim sBuffer As String * 255
If GetComputerNameA(sBuffer, 255&) _
<> 0 Then
GetMachineName = Left$(sBuffer, _
InStr(sBuffer, vbNullChar) _
— 1)
Else
GetMachineName = «(Not Known)»
End If
End Function


Назад к СОДЕРЖАНИЮ

37. КАК ПОКАЗАТЬ ШРИФТЫ, КОГДА ВЫ ВЫБИРАЕТЕ ИХ

VB3, VB4 16/32, VB5
Level: Intermediate
Чтобы юзер мог изменить имя шрифта, загрузите все шрифты в комбобокс:

Private Sub Form_Load()
‘ определить количество экранных шрифтов.
For I = 0 To Screen.FontCount — 1
‘ засунуть все шрифты в листбокс.
cboFont.AddItem Screen.Fonts(I)
Next I
End Sub

Украсьте процедуру, позволив юзеру сразу видеть результат своего выбора, без необходимости печатать «что-нибудь» в качестве теста:

Private Sub cboFont_Click()
‘ сделать выбранный FontName шрифтом combobox
cboFont.FontName = cboFont.Text
End Sub

Назад к СОДЕРЖАНИЮ

38. ПЕРЕХВАТ ПРАВЫХ КЛИКОВ НА УЗЛАХ TREEVIEW

VB4 32, VB5
Level: Intermediate

Контрол TreeView придает Вашей аппликухе законченный вид Windows 95. Однако, в учебниках по VB не сказано, как перехватывать правый мышиный клик на узле (node) дерева. Событие Treeview_MouseDown происходит до события NodeClick. Чтобы показать контекстное меню над узлом, используйте этот код и определите ключ (Key) для для каждого узла в виде буквы и идущим за ней числом.

+ Root (R01) ‘ the letter gives
|— Child 1 (C01) ‘ the indication to
|—+ Child 2 (C02) ‘ the context menu
| |— Child 2.1 (H01)
| |— Child 2.2 (H02)

Dim bRightMouseDown as Boolean

Private Sub Form_Load()
bRightMouseDown = False
End Sub

Private Sub treeview1_MouseDown_
(Button As Integer, Shift As _
Integer, X As Single, Y As Single)
If Button And vbRightButton Then
bRightMouseDown = True
Else
bRightMouseDown = False
End If
End Sub

Private Sub treeview1_MouseUp_
(Button As Integer, Shift As _
Integer, X As Single, Y As Single)
bRightMouseDown = False
End Sub

Private Sub treeview1_NodeClick_
(ByVal Node As Node)
Select Case Left(Node.Key, 1)
Case «R»
If Not bRightMouseDown Then
‘ do the normal node click,
‘ so you must here the code
‘ for the node code click
Else
‘ выбор узла
treeview1.Nodes(Node.Key).Selected = True
‘ показать контекстное меню
PopupMenu mnuContext1
End If

Case «C»
If Not bRightMouseDown Then
‘ do the normal node click,
‘ so you must here the code
‘ for the node code click
Else
‘ выбор узла
treeview1.Nodes(Node.Key).Selected = True
‘ показать контекстное меню
PopupMenu mnuContext2
End If

‘ то же с остальными узлами
‘ .
End Select
End Sub

39. ЗАПУСК VB ПРИ ПОМОЩИ МЕНЮ SENDTO

VB3, VB4 16/32, VB5
Level: Intermediate
Добавление ярлыка «Shortcut to VB.exe» и «Shortcut to VB32.exe» в меню «Send To» позволяет Вам right-clickом на любом VBP проекте открывать его в VB4 16/32 или в VB5 — на выбор.
Зайдите в Ваш VB каталог, right-clickните на VB32.exe, и выберите «Create shortcut.». Когда ярлык будет создан, переместите его в каталог C:\Windows\Sendto. Теперь при right-clickе на проекте Вы сможете выбрать, куда «переслать» Ваш проект. Вы можете добавить ярлыки для WordPad, Word, Excel или любой другой программы, допускающей использование входного файла в качестве параметра запуска.

40. НОВЫЕ “ГОРЯЧИЕ КНОПКИ” ДЛЯ VB

VB4 16/32, VB5
Level: Intermediate

1) В VB5, нажмите Ctrl-F3 когда курсор находится над каким-либо словом. При этом автоматически будет найдено следующее вхождение этого слова в тексте, минуя диалог поиска. Курсор должен стоять как минимум за первой буквой слова, чтобы эта фича работала правильно.

2) В VB4/5 нажатием Ctrl-Tab можно перемещаться между всеми открытыми окнами в IDE, это часто оказывается быстрее, чем идти в меню Window.

41. КАК ПОЛУЧИТЬ USERID ПОД WINDOWS 95/NT

VB4 32, VB5
Level: Intermediate

Часто Вам надо получить userID текущего юзера, работающего с Вашей программой. Используйте для этого модификацию одной из функций API:

Private Declare Function WNetGetUserA _
Lib «mpr» (ByVal lpName As String, _
ByVal lpUserName As String, _
lpnLength As Long) As Long

Function GetUser() As String
Dim sUserNameBuff As String * 255
sUserNameBuff = Space(255)
Call WNetGetUserA(vbNullString, _
sUserNameBuff, 255&)
GetUser = Left$(sUserNameBuff, _
InStr(sUserNameBuff, _
vbNullChar) — 1)
End Function

42 ВЫВОД ПЕСОЧНЫХ ЧАСОВ ВО ВРЕМЯ ОБРАБОТКИ ДАННЫХ

VB4 32, VB5
Level: Advanced

Нижеуказанная методика упрощает переключение MousePointerа, без добавления спец. кода в конце каждой процедуры/функции. Когда Вы созадете объект из какого-либо класса, генерируется событие Initialize. Затем исполняется код соответствующей процедуры. Это первый код, исполняемый для данного объекта, он исполняется до присвоения каких-либо свойств объекту и до выполнения методов объекта. Когда переменная выходит из области видимости, все ссылки на объект уничтожаются, и выполняется код для события Terminate.

Declare Sub Sleep Lib «kernel32» _
(ByVal dwMilliseconds As Long)

‘ пример процедуры, использующей класс CHourGlass
Private Sub ProcessData()
Dim MyHourGlass As CHourGlass
Set MyHourGlass = New CHourGlass
‘ здесь вставляется код обработки данных
Sleep 5000 ‘ Это моделирует обработку данных
‘ продолжение кода
End Sub

‘ создание класса CHourGlass:
Private Sub Class_Initialize()
‘ Показать HourGlass
Screen.MousePointer = vbHourglass
End Sub

Private Sub Class_Terminate()
‘ Восстановить MousePointer
Screen.MousePointer = vbDefault
End Sub

Назад к СОДЕРЖАНИЮ

43. ОЦЕНКА ПРОМЕЖУТКА ВРЕМЕНИ(в минутах) МЕЖДУ ДВУМЯ ДАТАМИ

VB4 16/32, VB5
Level: Beginning
Вам может понадобиться число прошедших минут между двумя событиями. Код:

lTotalMinutes = Minutes(Now) — _
Minutes(datStartTime)

Эта функция возвращает количество минут с 01/01/1900:

Public Function Minutes(d As Date) _
As Long
‘ Минуты, прошедшие с 1900
Dim lPreviousDays As Long
Dim lTotalMinutes As Long

lPreviousDays = d — #1/1/1900#
lTotalMinutes = _
(lPreviousDays * 24) * 60
lTotalMinutes = lTotalMinutes + _
Hour(d) * 60
lTotalMinutes = lTotalMinutes + _
Minute(d)

Minutes = lTotalMinutes
End Function

Назад к СОДЕРЖАНИЮ

44. ХВАТИТ ПЕЧАТАТЬ!

VB3, VB4 16/32, VB5
Level: Beginning

Иногда мне хочется распечатать данные из recordsetа, строка за строкой. Однако, довольно трудно пркратить этот процесс до того как весь recordset уйдет в очередь принтера. Используйте кнопку Cancel, которая устанавливает флаг. Кроме кнопки, посылающей задание на печать, создайте еще одну, под названием Cancel. Вы также можете присвоить ее свойству Cancel значение True, чтобы юзер мог остановить печать нажатием на Esc. Добавьте еще одну переменную в модуль:

Dim CancelNow As Integer

Put this code in the Click event of the Cancel button:
Добавьте этот код в событие Click кнопки Cancel:

Sub cCancel_Click ()
CancelNow = -1
DoEvents
End Sub

Вы можете даже обойтись без кнопки и ловить только нажатие на Escape. В этом случае, установите свойство KeyPreview формы в True и вставьте следующий код:

Sub Form_KeyPress (KeyAscii As Integer)
‘ если юзер жмет ESC
If KeyAscii = (27) Then
CancelNow = -1
DoEvents
End If
End sub

Наконец, вставьте проверку флага внутри цикла печати:

‘. какой-то код.
‘ печать recordset из database
Do While Not MyRecordSet.EOF
Printer.Print MyRecordSet!SomeRecord
MyRecordSet.MoveNext
DoEvents
‘ остановка, если был нажат Cancel
If CancelNow then Exit Do
Loop
Printer.EndDoc
‘. код далее.

45. ПОМЕНЯТЬ ЗНАЧЕНИЯ ДВУХ ПЕРЕМЕННЫХ

VB3, VB4 16/32, VB5
Level: Intermediate

Use this algorithm to swap two integer variables:
Собственно, вот:

a = a Xor b
b = a Xor b
a = a Xor b

46. БЫСТРЫЙ ОБСЧЕТ МНОГОЧЛЕНОВ

VB3, VB4 16/32, VB5
Level: Intermediate

Хорошо известная формула Горнера позволяет быстро считать полиномиальные выражения. Для того, чтобы посчитать
A*x^N + B*x^(N-1) + … + Y*x + Z ( ^ означает степень ), напишите :
(…((A*x + B)*x + C)*x + … +Y)*x + Z.

Назад к СОДЕРЖАНИЮ

47. ФОРМАТИРОВАНИЕ И КОПИРОВАНИЕ ДИСКЕТ ЧЕРЕЗ ФУНКЦИИ API

VB4 32, VB5
Level: Advanced

В Win32 API есть парочка функций, позволяющих форматировать и копировать дискеты из программы:

Private Declare Function SHFormatDrive _
Lib «shell32» (ByVal hwnd As Long, _
ByVal Drive As Long, _
ByVal fmtID As Long, _
ByVal options As Long) As Long
Private Declare Function GetDriveType _
Lib «kernel32» _
Alias «GetDriveTypeA» _
(ByVal nDrive As String) As Long

Добавьте две command buttons в форму, назовите их cmdDiskCopy и cmdFormatDrive, и засуньте в их события Click следующие фрагменты кода:

Private Sub cmdDiskCopy_Click()
‘ DiskCopyRunDll требует два параметра — From и To
Dim DriveLetter$, DriveNumber&, _
DriveType&
Dim RetVal&, RetFromMsg&
DriveLetter = UCase(Drive1.Drive)
DriveNumber = (Asc(DriveLetter) — _
65)
DriveType = GetDriveType_
(DriveLetter)
If DriveType = 2 Then ‘Floppies, _
etc
RetVal = Shell_
(«rundll32.exe » & _
«diskcopy.dll,» _
& «DiskCopyRunDll » & _
DriveNumber & «,» & _
DriveNumber, 1)
Else ‘ Just in case
RetFromMsg = MsgBox_
(«Only floppies can be » & _
«copied», 64, _
«DiskCopy Example»)
End If
End Sub

Private Sub cmdFormatDrive_Click()
Dim DriveLetter$, DriveNumber&, _
DriveType&
Dim RetVal&, RetFromMsg%
DriveLetter = UCase(Drive1.Drive)
DriveNumber = (Asc(DriveLetter) — _
65)
‘ Заменить букву на цифру: A=0
DriveType = GetDriveType_
(DriveLetter)
If DriveType = 2 Then _
‘ т.е. флоп
RetVal = SHFormatDrive(Me.hwnd, _
DriveNumber, 0&, 0&)
Else
RetFromMsg = MsgBox_
(«This drive is NOT a » & _
«removeable drive! » & _
«Format this drive?», _
276, «SHFormatDrive Example»)
If RetFromMsg = 6 Then
‘ Раскомментируйте и увидите.
‘RetVal = SHFormatDrive_
(Me.hwnd, _
‘ DriveNumber, 0&, 0&)
End If
End If
End Sub

Добавьте контрол DriveListBox под именем Drive1:

Private Sub Drive1_Change()
Dim DriveLetter$, DriveNumber&, _
DriveType&
DriveLetter = UCase(Drive1.Drive)
DriveNumber = (Asc(DriveLetter) — _
65)
DriveType = GetDriveType_
(DriveLetter)
If DriveType <> 2 Then _
‘Floppies, etc
cmdDiskCopy.Enabled = False
Else
cmdDiskCopy.Enabled = True
End If
End Sub

Будьте осторожны: так недолго и винт запороть.

Назад к СОДЕРЖАНИЮ

48. ПОСЛЕДОВАТЕЛЬНЫЕ НОМЕРА ВЕРСИЙ

VB4 16/32, VB5
Level: Intermediate

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

Public Function GetMyVersion() As String
‘ конвертирует номер версии в нечто вроде»1.02.0001″
Static strMyVer As String
If strMyVer = «» Then
strMyVer = Trim$(Str$(App.Major)) & «.» & _
Format$(App.Minor, «##00») _
& «.» Format$(App.Revision, «000»)
End If
GetMyVersion = strMyVer
End Function

49. ВЫРАВНИВАНИЕ КОНТРОЛОВ ПО ПРАВОМУ КРАЮ

VB3, VB4 16/32, VB5
Level: Beginning

При создании форм с нефиксированными размерами, я предпочитаю помещать все контролы в правый нижний и правый верхний углы. Например, на формах, где вводятся данные, я ставлю кнопки навигации по записям в левую нижнюю часть формы вместе с кнопками Add New Record, Delete Record, и Find Record. В нижнем правом углу я ставлю кнопки print preview и закрытия формы. Поместите эту процедуру в модуль или general declarations формы. Параметром Offset Вы можете изменять дистанцию от правого края формы, то есть Вы можете выравнивать по правому краю Ваши контролы.

Sub ButtonRight(X As Control, _
Frm As Form, Offset as Integer)
X.Left = Frm.ScaleWidth — _
X.Width — Offset
End Sub

Поместите два command buttonа на форму. В событии Form_Resize, добавьте примерно такой код:

Private Sub Form_Resize()
ButtonRight Command1, Me, 0
ButtonRight Command2, Me, _
Command1.Width
End Sub

50. VAL( ) НЕ РАБОТАЕТ НА ФОРМАТИРОВАННЫХ ЧИСЛАХ

VB3, VB4 16/32, VB5
Level: Intermediate

Осторожнее с функцией Val(). Она некорректно распознает форматированные числа. Используйте вместо этого CInt(), CDbl().

FormattedString = Format(1250, _
«General»)
‘ = «1,250.00»
Debug.Print Val(FormattedString)
‘ напечатает 1 !
Debug.Print cDbl(FormattedString)
‘ напечатает 1250

51. CМЫШЛЕНЫЙ ГЕНЕРАТОР ID

VB3, VB4 16/32, VB5
Level: Intermediate

Я написал генератор для создания уникальных номиров , типа номера акаунта, или ID в вашеи приложении. Я использую это вместе с фенкцией CheckForValid, например CheckForValid вернет True для номера «203931.» И вернет False для «209331.»

Function CheckForValid(Num As Long) _
As Boolean
‘ Check for valid number
Result = Num Mod 13
If Result <> 0 Then
CheckForVal > ‘ if false then the number is wrong
Else
CheckForVal > ‘if true the number is OK
End If
End Function

Function Generate(Num As Long) As Long
‘Generates the successor of a valid
‘number
If CheckForValid(Num) Then
Generate = Num + 13
‘if valid Generate
Else
Generate = -1
‘ Otherwise return -1
End If
End Function

52. ИЗМЕНЕНИЕ РАЗМЕРА ВЫПАДАЮЩЕЙ ОБЛАСТИ НА COMBOBOXE

VB4 32, VB5
Level: Advanced
В VB нет свойства ListRows, т.е. если Вам надо изобразить более чем 8 дефолтовых строк на выпадающем списке comboboxа, то используйте эту процедуру для увеличения размера окна comboboxа:

Type POINTAPI
x As Long
y As Long
End Type

Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type

Declare Function MoveWindow Lib _
«user32» (ByVal hwnd As Long, _
ByVal x As Long, ByVal y As Long, _
ByVal nWidth As Long, _
ByVal nHeight As Long, _
ByVal bRepaint As Long) As Long
Declare Function GetWindowRect Lib _
«user32» (ByVal hwnd As Long, _
lpRect As RECT) As Long
Declare Function ScreenToClient Lib _
«user32» (ByVal hwnd As Long, _
lpPoint As POINTAPI) As Long

Public Sub Size_Combo(rForm As Form, _
rCbo As ComboBox)
Dim pt As POINTAPI
Dim rec As RECT
Dim iItemWidth As Integer
Dim iItemHeight As Integer
Dim iOldScaleMode As Integer

‘ Смена Scale Mode формы на Pixels
iOldScaleMode = rForm.ScaleMode
rForm.ScaleMode = 3
iItemW >

‘ Установка новой высоты comboboxа
iItemHeight = rForm.ScaleHeight — rCbo.Top — 5
rForm.ScaleMode = iOldScaleMode

‘ Получение координат по отношению к экрану
Call GetWindowRect(rCbo.hwnd, rec)
pt.x = rec.Left
pt.y = rec.Top

‘ затем координаты в форме
Call ScreenToClient(rForm.hwnd, pt)

‘ Изменение размера comboboxа
Call MoveWindow(rCbo.hwnd, pt.x, _
pt.y, iItemWidth, iItemHeight, 1)
End Sub

Назад к СОДЕРЖАНИЮ

53. КОЛИЧЕСТВО СВОБОДНОЙ ПАМЯТИ С ПОМОЩЬЮ WIN32

VB4 32, VB5
Level: Advanced

Если Вам надо показать юзерам, сколько свободной памяти доступно на машине, и Вы перешли с 16бит на 32 бит платформу, то Вы заметите, что функция API GetFreeSystemResources исяезла. Но это не беда. Вам надо всего лишь объявить API функцию и следующий тип в модуле:

Declare Sub GlobalMemoryStatus Lib _
«kernel32» (lpBuffer As _
MEMORYSTATUS)

Type MEMORYSTATUS
dwLength As Long
dwMemoryLoad As Long
dwTotalPhys As Long
dwAvailPhys As Long
dwTotalPageFile As Long
dwAvailPageFile As Long
dwTotalVirtual As Long
dwAvailVirtual As Long
End Type

Занесите в поле dwlength размер типа MEMORYSTATUS. Переменная типа Long берет 4 байта, так что всего выйдет 4*8=32 байта:

Dim ms As MEMORYSTATUS

ms.dwLength = Len(ms)
GlobalMemoryStatus ms
MsgBox «Total physical memory:» & _
ms.dwTotalPhys & vbCr _
& «Available physical memory:» & _
ms.dwAvailPhys & vbCr & _
«Memory load:» & ms.dwMemoryLoad

Вы можете даже написать класс, в котором инкапсулировать все вышеизложенное.

Назад к СОДЕРЖАНИЮ

54. СКОЛЬКО ВАМ ЛЕТ?

VB5
Level: Intermediate

Эта функция возвращает разницу между двумя датами в годах, месяцах и днях:

Function GetAge(dtDOB As Date, _
Optional dtDateTo As Date = 0) _
As String
‘ dtDateto передана?
If dtDateTo = 0 Then
dtDateTo = Date
End If
GetAge = Format$(dtDateTo — _
dtDOB, «yy — mm — dd»)
End Function

55. УЗЕЛОК, О КОТОРОМ НЕВОЗМОЖНО ЗАБЫТЬ

VB3, VB4 16/32, VB5
Level: Intermediate

Я часто работаю над несколькими проектами одновременно. Прыгая с одного проекта на другой и обратно, иногда я теряю след, в какой программе в каком месте я остановился. Для решения этой проблемы, возьмите да и напечатайте какую-нибудь фразу без кавычек комментария.
В следующий раз, когда Вы запустите проект, выберите пункт «Start With Full Compile». Если эта фраза будет первой ошибкой в проекте, Вы сразу увидите ее подсвеченной и Ваша память освежится.

56. СОЗДАТЬ НА ЛЕТУ МАССИВ ПРИ ПОМОЩИ ФУНКЦИИ ARRAY

VB4 16/32, VB5
Level: Intermediate

Метод GetRows копирует строки Recordsetа (JET) или rdoResultsetа (RDO) в массив. Я часто использую эту фичу для передачи данных между OLE Serverом и клиентскими аппликухами. Этот метод использует переменную типа Variant в качестве параметра для хранения возвращаемых данных. Это двумерный массив (по внутреннему представлению VB)

Dim A As Variant
A = Array(10,2)

Назад к СОДЕРЖАНИЮ

57. НАЙТИ ВЫБРАННЫЙ КОНТРОЛ В МАССИВЕ OPTION BUTTONS

VB4 16/32, VB5
Level: Intermediate
Используйте этот код для нахождения индекса выбранного контрола из массива option buttons

Function WhichOption(Options As _
Object) As Integer

‘ Эта функция возвращает индекс Option Button, чье значение true.

Dim i
‘ Если Options — не тот объект, или не объект вообще
On Error GoTo WhichOptErr
‘ Default to failed
WhichOption = -1
‘ проверяет каждый OptionButton в массиве. Прошу отметить, что функция выдает
‘ неправильное значение, если индексы идут не подряд
For i = Options.lbound To _
Options.ubound
If Options(i) Then
‘ запомнить значение найденного индекса
WhichOption = i
‘ и выйти
Exit For
End If
Next
WhichOptErr:

Учтите, что iCurOptIndex имеет тип integer, а Option1 это имя массива контролов OptionButton.

Важно: параметр функции — объект. Она будет работать только с параметрами-объектами или типа variant.

Назад к СОДЕРЖАНИЮ

58. УПАКОВКА ЗНАЧЕНИЙ CHECK-BOX В ОДНУ ПЕРЕМЕННУЮ ТИПА INTEGER

VB4 16/32, VB5
Level: Intermediate

Используя следующий код, можно вывести двоичное представление зачеркнутых check boxов:

Function WhichCheck(ctrl As Object) As _
Integer
‘ Эта функция возвращает двоичное представление массива контролов,
‘ где каждый зачеркнутый чекбокс представляется двойкой в степени своего индекса в
‘ массиве, напр.элемент 0 : 2 ^ 0 = 1,
‘элементы 0 и 2 : 2^0 + 2^2 = 5

Dim i
Dim iHolder
‘ если некорректный параметр передан в процедуру
‘ возвращается 0
On Error GoTo WhichCheckErr

‘ двоичное представление
‘ массива чекбоксов
For i = ctrl.LBound To ctrl.UBound
If ctrl(i) = 1 Then
‘ если зачеркнут, добавить его двоичное представление
iHolder = iHolder Or 2 ^ i
End If
Next
WhichCheckErr:
WhichCheck = iHolder

Функция вызывается следующим образом:

Check1 — массив чекбоксов, iCurChecked — переменная integer. Ниже приведена «двойственная» процедура, устанавливающая все чекбоксы согласно переменной, в которой хранятся их двоичные представления.

Sub SetChecked(ctrl As Object, _
iCurCheck%)
‘ This sub sets the binary value of an
‘ array of controls where iCurChecked is
‘ 2 raised to the index of each checked
‘ control
Dim i
‘ in case ctrl is not a valid object
On Error GoTo SetCheckErr
‘ use the binary representation to
‘ set individual check box controls
For i = ctrl.LBound To ctrl.UBound
If iCurCheck And (2 ^ i) Then
‘ if it is checked add in its
‘ binary value
ctrl(i).Value = 1
Else
ctrl(i).Value = 0
End If
Next
SetCheckErr:

Эта процедура вызывается так:

Call SetChecked(Check1, iDesired)

Check1 — массив чекбоксов, iDesired- переменная, хранящая двоичное представление состояния чекбоксов.

59. УСЛОВНАЯ КОМПИЛЯЦИЯ КОДА

VB4 16/32, VB5
Level: Intermediate

Большинству разработчиков известна фича Conditional Compilation из VB4, когда Вы можете объявлять процедуры Windows API для 16- или 32-разрядных ОС:

#If Win#32 then
‘ если 32-разрядная ОС
Declare SomeApi.
#Else
‘ если запущена 16-разрядная ОС
Declare SomeApi
#End IF
Эта же фича может работать не только с функциями Windows API, но и с Вашими собственными функциями:

#If Win32 Then
Dim lRc&
lRc& = ReturnSomeNumber(35000)
#Else
Dim lRc%
lRc% = ReturnSomeNumber(30000)
#End If

#If Win32 Then
Private Function ReturnSomeNumber_
(lVar&) As Long
ReturnSomeNumber = 399999
#Else
Private Function ReturnSomeNumber_
(lVar%) As Integer
ReturnSomeNumber = 30000
#End If

60. УМЕНЬШИТЬ МЕРЦАНИЕ ВО ВРЕМЯ ЗАГРУЗКИ ФОРМЫ

VB4, VB5
Level: Intermediate

Во время загрузки формы, следующий код поможет уменьшить мерцание и мелькание GUI при помощи функций API:

‘Declarations Section
#If Win32 Then
Declare Function LockWindowUpdate _
Lib «user32» _
(ByVal hwndLock As Long) As Long
#Else
Declare Function LockWindowUpdate _
Lib «User» _
(ByVal hwndLock As Integer) _
As Integer
#End If

Public Sub LoadSomeForm()

‘ Во время загрузки формы запрещает обновление состояния окна
‘ чтобы избавиться от мерцания.
‘ запрещаетобновление GUI
LockWindowUpdate frmTest.hWnd
‘ показывает форму
frmTest.Show
‘ здесь код, относящийся к загрузка формы и т.п.

‘ Никогда не забывайте разрешить обратно обновление окна
LockWindowUpdate 0
End Sub

61. СПРЯТАТЬ УКАЗАТЕЛЬ НА ТЕКУЩУЮ ЗАПИСЬ в DBGride

VB4 16/32, VB5
Level: Advanced

Для того, чтобы указатель записи на DBGride не скакал при перемещении между записями (строками grida), используйте функцию API LockWindowUpdate(gridname.hwnd) перед началом движения по gridу, и LockWindowUpdate(0) после окончания перемещений:

‘Declarations Section
#If Win32 Then
Declare Function LockWindowUpdate _
Lib «user32» _
(ByVal hwndLock As Long) As Long
#Else
Declare Function LockWindowUpdate _
Lib «User» _
(ByVal hwndLock As Integer) _
As Integer
#End If

Private Sub cmdHideSelector_Click()
LockWindowUpdate DBGrid1.hWnd
End Sub

Private Sub cmdShowSelector_Click()
LockWindowUpdate 0
End Sub

62. USE POPUP MENUS IN WINDOWS WITHOUT TITLE BAR

VB4 16/32
Level: Intermediate

Когда Вы устанавливаете свойство ControlBox в False и BorderStyle в fixed window, то можете получить окно(форму) без titlebar (поля заголовка). Если же вы добавите меню на эту форму — титул-бар появится снова. Чтобы измежать этой проблемму вы можете разместить меню на другой форме.

Private Sub Command1_Click()
Dim frm As New frmMenu
Load frm
frm.PopupMenu frm.mnutest
‘select specific code
Unload frm
End Sub

Такое поведение исправлено в VB5

Назад к СОДЕРЖАНИЮ

63. КАК УЗНАТЬ РАЗДЕЛИТЕЛИ ДАТЫ И ВРЕМЕНИ БЕЗ ФУНКЦИЙ API

VB3, VB4 16/32, VB5
Level: Intermediate

Вот простой алгоритм как узнать разделители даты, времени и десятичной точки в Windows, не залезая в Locale Settings или функции API.

DateDelimiter = Mid$(Format(Date, _
«General Date»), 3, 1)
TimeDelimiter = Mid$(Format(0.5, _
«Long Time»), 3, 1)
DecimalDelimiter = Mid$(Format(1.1, _
«General Number»), 2, 1)

Назад к СОДЕРЖАНИЮ

64. ПРЕДОТВРАЩЕНИЕ ОШИБОК ПРИ ИСПОЛЬЗОВАНИИ GETSETTING

VB4 16/32, VB5
Level: Intermediate

Использование функции GetSetting может породить ошибки, особенно в некоторых ситуациях при 16-разрядной ОС при работе с INI файлами. Если искомого параметра нет в INI файле, то Вы можете увидеть сообщение об ошибке «Invalid procedure call.». Используйте нижеприведенную процедуру, которая подменяет обработчик ошибок:

Public Function GetRegSetting(AppName _
As Variant, Section As Variant, _
Key As Variant, Optional Default _
As Variant) As Variant

‘ дефолтовое значение не имеет не-объектный тип , иначе придется
‘ использовать слово Set
Dim tmpValue As Variant

‘ установка величины по умолчанию
‘ если величина передана не была,
‘ получаем пустую переменную типа Variant
If Not IsMissing(Default) Then _
tmpValue = Default

‘ это отлавливает возможные ошибки
On Error Resume Next

‘ теперь можно использовать функцию из VB
tmpValue = GetSetting(AppName, _
Section, Key, tmpValue)

‘ после возможных ошибок вызов повторяется здесь
‘ с уже определенным значением tmpValue
GetRegSetting = tmpValue

65. ДУБЛИРОВАНИЕ СТРОК КОДА БЕЗ СИНТАКСИЧЕСКИХ ОШИБОК

VB3, VB4 16/32, VB5
Level: Beginning
Часто мне приходится переписывать сходный по смыслу код с небольшими изменениями в каждой строке; для облегчения проблемы я делаю шаблон того, что надо копировать, быстро вставляю копию в нужное место, и делаю добавления. Однако часто шаблонный текст вызывает ошибки со стороны VB редактора. Одолеть эту проблему можно, закомментировав шаблон перед использованием. Когда Вы закончите редактирование вставленного фрагмента, раскомментируйте его и он готов. Это особенно просто под VB5, в котором есть команда Block Uncomment. Ниже приведен пример добавления члена в коллекцию.

While Not mRS.EOF
oObject.FName = mRS!FName
oObject.LName = mRS!LName
oObject.Phone = mRS!Phone
.
.
cCollection.Add oObject, oObject.FName
Wend

Если у Вашего объекта 20 или 30 свойств, быстрее будет создать шаблон:

Скопируйте его, вставьте 20 или 30 раз, вернитесь к началу и впечатайте имена свойств и полей, и уберите символ комментария. Символ комментария позволяет Вам свободно бегать по всему фрагменту, не заботясь о синтаксических ошибках.

66. ЯРЛЫК ДЛЯ ЗАГРУЗКИ ПОСЛЕДНЕГО РАБОЧЕГО ПРОЕКТА В VB

VB4 32
Level: Intermediate
Часто я старутю VB и возобновляю работу с последним проектом, но мне не хочется загромождать desktop иконками для текущих работ. В качестве решения я предлагаю мою прогу, которую нужно скомпилировать и запустить на Вашем desktopе. Эту прогу можно применить и к другим, использующим INI файлы.


Declare Function GetPrivateProfile_
String Lib «kernel32» _
Alias «GetPrivateProfileStringA» _
(ByVal lpApplicationName As _
String, ByVal lpKeyName As Any, _
ByVal lpDefault As String, _
ByVal lpReturnedString As _
String, ByVal nSize As Long, _
ByVal lpFileName As String) _
As Long

Public Sub Main()
Dim temp As String, rVal$, tmp _
As Long
rVal$ = String$(256, 0)
tmp = GetPrivateProfileString_
(«Visual Basic», _
«vb32location», «», rVal$, _
ByVal Len(rVal$) — 1, _
«c:\windows\vb.ini»)
temp = Left$(rVal$, tmp)
rVal$ = String$(256, 0)
tmp = GetPrivateProfileString_
(«Visual Basic», «RecentFile1», _
«», rVal$, ByVal Len(rVal$) _
— 1, «c:\windows\vb.ini»)
temp = temp & » «»» & Left$(rVal$, _
tmp) & «»»»
Shell temp, 1
End
End Sub

Назад к СОДЕРЖАНИЮ

67. КАК ВЫВЕСТИ СИМВОЛ «&» В LABEL

VB4 16/32, VB5
Level: Beginning

Если Вы хотите выывести символ «&» на экран, установите свойство «UseMnemonic» в False. Это свойство бывает полезно, когда, например, Labelы используются для вывода данных из баз данных. Также Вы можете вывести символ «&» в свойстве Caption, написав &&.

Назад к СОДЕРЖАНИЮ

68. СОЗДАНИЕ ВРЕМЕННЫХ ФАЙЛОВ

VB3, VB4 16/32, VB5
Level: Beginning

Я пишу прогу с базами данных, использующую много вспомогательных файлов в одно и то же время. При программировании баз данных можно создавать временные файлы для, например, вывода результата инструкции SQL или из временной базы данных, чтобы более эффективно работать с записями. Я написал функцию FileAux, возварщающую имя временного файла. Если мне надо создать несколько временных файлов одновременно, я сохраняю их имена в заранее определенных переменных:

Function FileAux(Ext As String) _
As String
Dim i As Long, X As String
If InStr(Ext, «.») = 0 Then
Ext = «.» + Ext
End If

‘ Ищем уже имеющиеся файлы на винте
i = 0
Do
X = «Aux» + Format$(i, «0000») _
+ Ext
If FileExists(X) Then
i = i + 1
Else
Exit Do
End If
Loop
FileAux = X
End Function

Эта функция обращается к функции FileExists:

Function FileExist(filename As String) _
As Boolean
FileExist = Dir$(filename) <> «»
End Function

А вот пример использования:

Sub Test()
Dim File1 As String, File2 As _
String, File3 As String
Dim DB1 As database, DB2 As DataBase
Dim FileNum As Integer
File1 = FileAux(«MDB»)
Set DB1 = CreateDataBase(File1)
File2 = FileAux(«MDB»)
Set DB2 = CreateDataBase(File2)
File3 = FileAux(«TXT»)
FileNum = FreeFile
Open File3 For OutPut As FileNum
‘ Ваш код
‘ .
Close FileNum
End Sub

File1, File2, и File3 должны быть «Aux0001.MDB,» «Aux0002.MDB,»
и «Aux0001.TXT,» соответственно.

69. МЫШИНЫЕ СОБЫТИЯ НЕ СЛУЧАЮТСЯ ЕСЛИ ENABLE УСТАНОВЛЕНО В FALSE

VB3, VB4 16/32, VB5
Level: Beginning
События MouseMove не происходят, если свойство Enabled контрола установлено в False. Мой метод лечит эту проблему и он может быть полезен, если Вы хотите вывести Tooltips или Notes на статусбаре, вне зависимости от того, enabled контрол или disabled.
Если свойство Enabled контрола установлено в False, то контрол, помещенный за данным, тем не менее быдет отзываться на движения мыши. Скопируйте код из Command1_MoseMove в Label1_MouseMove. Теперь Ваш МаусМув работает даже если Command1 недоступна.

Command1(0), Command1(1)-Command1 — массив контролов.
Label1(0), Label1(1)- массив лабелов за контролами.
SSPanel1-Работает статусбаром.

Private Sub Form_Load()
Dim i As Integer
For i = 0 To 1
Label1(i).Left = Command1(i).Left
Label1(i).Top = Command1(i).Top
Label1(i).W > Label1(i).Height = _
Command1(i).Height
Next i
Command1(0).enabled = false
Command1(0).Tag = «Button to Add»
Command1(1).Tag = «Button to Modify»
Command1(0).Caption = «&Add»
Command1(1).Caption = «&Modify»

Private Sub Label1_MouseMove(Index As _
Integer, Button As Integer, Shift _
As Integer, X As Single, Y As _
Single)
SSPanel1.Caption = Command1(Index).Tag
End Sub

Private Sub Command1_MouseMove(Index _
As Integer, Button As Integer, _
Shift As Integer, X As Single, Y _
As Single)
SSPanel1.Caption = Command!(Index).tag
End Sub

70. КАК ВЫВЕСТИ СВОЕ POPUP MENU НА TEXT BOXES

VB4 16/32, VB5
Level: Intermediate

Некоторые контролы в VB4 и VB5 как, например, TextBox имеют по дефолту контекстное меню, выползающее при правом клике на указанном контроле. Если Вы хотите, чтобы выезжало другое котекстное меню, то стандартных методов или пропертей для этого не существует. Выход состоит в отлавливании события Mouse_Down, код которого будет делать контрол недоступным. Затем высвечивайте Ваше контекстное меню, энаблите контрол обратно. Процедура PopContextMenu описывает указанный метод

Sub PopContextMenu(argoControl As _
Control, argoMenu As Control)
argoControl.Enabled = False
PopupMenu argoMenu
argoControl.Enabled = True
End Sub

Пример вызова в событии MouseDown для текстбтокса по имени Text1 и меню MyMenu:

Private Sub Text1_MouseDown(Button As _
Integer, Shift As Integer, X As _
Single, Y As Single)
If Button = vbRightButton Then
PopContextMenu Text1, MyMenu
End If
End Sub

71. ЦЕНТРИРОВАТЬ ФОРМУ С УЧЕТОМ ТАСКБАРА

VB3, VB4 16/32, VB5
Level: Intermediate
Для центрирования формы Вам надо лишь вызвать API процедуру, и завести две константы. Это решение основано на том факте, что GetSystemMetrics возвращает истинное значение параметров экрана, который может быть на самом деле занят таскбаром и Microsoft Office shortcut barом:

Public Const SM_CXFULLSCREEN = 16
Public Const SM_CYFULLSCREEN = 17

#If Win32 then
Declare Function GetSystemMetrics _
Lib «user32» _
(ByVal nIndex As Long) As Long
#Else
Declare Function GetSystemMetrics _
Lib «User» _
(ByVal nIndex As Integer) _
As Integer
#End If

Public Sub CenterForm(frm As Form)
frm.Left = Screen.TwipsPerPixelX * _
GetSystemMetrics_
(SM_CXFULLSCREEN) / 2 _
— frm.Width / 2
frm.Top = Screen.TwipsPerPixelY * _
GetSystemMetrics_
(SM_CYFULLSCREEN) / 2 _
— frm.Height / 2
End Sub

72. ОЧИСТКА СТРОКИ ОТ НЕНУЖНЫХ СИМВОЛОВ

VB3, VB4 16/32, VB5
Level: Beginning
Иногда бывает полезно иметь функцию, которая очищает строку от нежелательных символов. Эта маленькая функция принимает в качестве параметров строку для очистки и символ, от которого ее надо очистить:

Function StringCleaner(s As String, _
Search As String) As String
Dim i As Integer, res As String
res = s
Do While InStr(res, Search)
i = InStr(res, Search)
res = Left(res, i — 1) & _
Mid(res, i + 1)
Loop
StringCleaner = res
End Function

Назад к СОДЕРЖАНИЮ

73. ПРОВЕРКА ОБЪЕКТОВ ПРИ ПОМОЩИ TYPENAME

VB4 16/32, VB5
Level: Beginning

Вы можете определить класс, к которому принадлежит объект, при помощи функции TypeName вместо использования блока If TypeOf. Используйте выражение TypeOf для определения типа объекта:

If TypeOf myObject is myType then
. делаем то-то
End If

Вы можете сделать то же савмое при помощи следующего кода:

if TypeName(myObject) = «myType» Then
. делаем то-то.
End If

Выгода моего решения в том, что Вам вовсе не обязательно включать в Ваш проект все классы (или OCXs), с которыми Вы работаете. Это неплохой прием для написания общих процедур (универсальных, общего назначения) и , более того, Вы можете использовать TypeName в сложных проверках и блоках Select Case.

Назад к СОДЕРЖАНИЮ

74. ДОБАВЛЕНИЕ СТРОКИ В TEXT BOX

VB4 16/32, VB5
Level: Intermediate

Используйте данный код, чтобы заставить скроллер TextBoxа автоматически передвинуться, когда Вы добавляете новый текст:

‘ Переход к концу текста
MyTextBox.SelStart = Len(MyTextBox.Text)
‘ Новый текст будет стоять здесь
MyTextBox.SelText = NewText$

Назад к СОДЕРЖАНИЮ

75. ПРОВЕРКА АРГУМЕНТОВ В ФУНКЦИИ VAL

VB3, VB4 16/32, VB5
Level: Beginning

При использовании функции Val, VB капризничает, порождая ошибку несоответствия типов. Например, Val(«25%») правильно возвращает 25, тогда как Val(«2.5%») неправильно интерпретирует входной параметр и возвращает ошибку несоответствия типов. Это случается только тогда, когда в строке присутствует десятичная точка и символ «%» или «&». Чтобы исправить это, уберите эти символы из строки перед ее передачей в Val.

76. ЯРЛЫКИ ДЛЯ INTERNET

VB4 32, VB5
Level: Advanced

VB5 App Wizard умеет создавать Web Browser-форму, но она работает только с Microsoft Internet Explorer и Вам приходится таскать за собой SHDOCVW.DLL при распространении проги. Если Вы используете функцию ShellExecute для запуска файла Internet Shortcut, то Windows запускает дефолтный браузер и переходит на указанный URL. Этот метод работает как Microsoft так и с Netscape браузерами, если они правильно прописаны в регистре, и Вам не нужно перетаскивать никаких DLL при распространении проги.

Private Declare Function ShellExecute _
Lib «shell32.dll» Alias _
«ShellExecuteA» _
(ByVal hwnd As Long, _
ByVal lpOperation As String, _
ByVal lpFile As String, _
ByVal lpParameters As String, _
ByVal lpDirectory As String, _
ByVal nShowCmd As Long) As Long
Private Const SW_SHOWNORMAL = 1

‘ frm : ShellExecute использует обработчик окна.
‘ Вы можете использовать обработчик главного окна проги
‘ sUrl : это имя и путь к файлу .url (файл Internet shortcut)
‘ указывающий на Вашу страницу , напр.
‘ c:\MyWebPage.url использует Internet Explorer
‘ для создания файла ярлыка

Public Sub GoToMyWebPage(frm as Form, _
sUrl as string)
Dim lRet as Long
lRet = ShellExecute(frm.hwnd, _
«open», sUrl, vbNull, _
vbNullString, SW_SHOWNORMAL)
If lRet Назад к СОДЕРЖАНИЮ

77. ПРОСМОТР СОДЕРЖАНИЯ HELP-ФАЙЛА

VB4 32, VB5
Level: Intermediate

Многие программеры любят добавлять к свои приложениям и хелп-файлы. Как открыть содержание хелп-файла Windows из Вашей программы? Вот пример кода с использованием Win32 API функции.

‘ —- Объявление
Const HELP_CONTENTS = &H3&
‘ Функции Вывода содержимого
Declare Function WinHelp Lib «user32» _
Alias «WinHelpA» _
(ByVal hwnd As Long, _
ByVal lpHelpFile As String, _
ByVal wCommand As Long, _
ByVal dwData As Long) As Long

‘ — Код
Sub OpenHelpFile(HelpFileName As String)
‘ HelpFileName — путь к хелп-файлу.
WinHelp hwnd, HelpFileName, _
HELP_CONTENTS, 0
End Sub

Назад к СОДЕРЖАНИЮ

78. ЗАДАНИЕ ГРАНИЦ MDI ФОРМЫ ТОЧНО КАК В DESIGN-TIME

VB3, VB4 16/32, VB5
Level: Beginning

Поскольку MDI-формы ни имеют свойства border, юзер может раздвигать их границы и менять размер MDI-форм. Если юзер пытается изменить размеры формы, а я этого не хочу (пусть остается такой как была создана мной), то процедура для события MDIForm_Resize() спасет (кого — по вкусу):

Private Sub MDIForm_Resize()
‘ Запрет resizingа MDI-формы (растягивания границ и перемещения ее мышой).
‘ Годитсятолько для тех MDI форм, которые выводятся как Normal Window
If WindowState = 0 Then
‘ заданная высота MDI формы
Me.Height = 6900
‘ заданная ширина MDI формы
Me.W > ‘ заданный левый край MDI формы
Me.Left = 1020
‘ заданный правый край MDI формы
Me.Top = 1176
‘ С таким же успехом можно использовать метод Move, чтобы объединить
‘ восстановление координат формы в одной команде
End If
End Sub

79. БЫСТРЫЙ ПОИСК В БАЗЕ ДАННЫХ

VB3, VB4 16/32, VB5
Level: Beginning
В VB нет встроенной процедуры типа DLookUp из Аксесса. Вы можете использовать нижеприведенный код для получения Name объекта по его ID:

Public Function MyDLookUp(Column As _
String, TableName As String, _
Condition As String) As Variant
Dim Rec As Recordset
On Error GoTo MyDlookUp_Err

‘ gCurBase — глобальная переменая, указывающая на текущкю БД
Set Rec = gCurBase.OpenRecordset_
(«Select * From » & TableName)
Rec.FindFirst Condition
If Not Rec.NoMatch Then
‘ возвращает искомое поле, если найдено
MyDLookUp = Rec(Column)
Exit Function
End If

‘ возврат, если не найдено, или произошла другая ошибка
MyDlookUp_Err:
MyDLookUp = -1
End Function

80. ЛЕГКОЕ ОТСЛЕЖИВАНИЕ ПОЛОЖЕНИЯ ФОКУСА

VB3, VB4 16/32, VB5
Level: Intermediate

Lost_Focus and Got_Focus events Часто используются для проверки правильности ввода текста. Вы можете использовать нижеприведенный код для отслеживания фокуса на форме не программирую каждый контрол отдельно.
Прместите timer control на форму , установите Interval property = 100 и Enabled = True. Name the control tmrFocusTracking.
Timer event должен содердать следующий код:

Private Sub tmrFocusTracking_Timer()
Dim strControlName As String
Dim strActive As String
strControlName = _
Me.ActiveControl.Name

Do
strActive = Me.ActiveControl.Name
If strControlName <> strActive _
Then
Print strControlName & _
» — Lost Focus», _
strActive & » — Got Focus»
strControlName = strActive
End If
DoEvents
Loop
End Sub

To implement universal highlighting, replace the Print statement with this code:

Me.Controls(strActive).SelStart = 0
Me.Controls(strActive).SelLength = _
Len(Me.Controls(strActive))

Для проверки (validation) правильности текста вместо Print statement используйте вызов процедуры проверки.
Используйте strActive in a Select Case structure
К моменту , когда случается команда Print , strActive равен контролу, имеющему фокус, и strControlName содержит имя контрола, который потерял фокус.
Не размещайте эту процедуру где-либо кроме таймера.

81. НЕЗАКРЫВАЮЩАЯСЯ ФОРМА

VB3, VB4 16/32, VB5
Level: Beginning

Если выставить свойство ControlBox на форме в False, то кнопки Minimize и Maximize тоже исчезнут. Предположим, что Вы хотите тем не менее давать возможность юзеру использовать кнопки Minimize и Maximize, но при этом чтобы он не мог закрыть форму кнопкой с крестиком. Добавьте следующий код в событие Query_Unload:

‘ если у Вас VB3, раскомментируйте следующую строку
‘ Const vbFormControlMenu = 0
Private Sub Form_QueryUnload(Cancel As _
Integer, UnloadMode As Integer)
If UnloadMode = vbFormControl_
Menu Then
Cancel = True
End If
End Sub

Назад к СОДЕРЖАНИЮ

82. ПОМЕНЯТЬ СВОЙСТВО ЦЕЛОЙ ГРУППЕ КОНТРОЛОВ

VB3, VB4 16/32, VB5
Level: Beginning

Вы можете легко сделать видимой/невидимой целую группу контролов. В режиме разработки, выделите все контролы, с которыми Вы будете производить данную операцию при выполнении программы. Нажмите F4, и присвойте свойству Tag имя группы, например Group1. Теперь при совершении групповой операции Вам поможет следующий код:

For ind = 0 To Formname.Controls.Count _
— 1
If Formname.Controls(ind).Tag = _
«Group1» Then
Formname.Controls(ind).Visible _
= True
End If
Next

Назад к СОДЕРЖАНИЮ

83. КАК ПРОСТО ОТФОРМАТИРОВАТЬ И ОКРУГЛИТЬ ЧИСЛО

VB3, VB4 16/32, VB5
Level: Intermediate

Пример округления с заданной точностью.

n = 12.345
Format(n, «0.00\0»)
‘ возвращает «12.350»
Format(n, «0.\0\0»)
‘ возвращает «12.00»
Format(0.55, «#.0\0») ‘ возвращает «.60»

84. БУДЬТЕ ОСТОРОЖНЫ, ЗДЕСЬ ВАМ НЕ С!

VB3, VB4 16/32, VB5
Level: Intermediate

VB программеры, привыкшие к С, могут быть введены в заблуждение следующей особенностью VB. Рассмотрим код:

Dim x As Integer
Dim y As Integer
Dim z As Integer

x = 10
y = 20
z = 0

‘ пусть функция max возвращает большее из двух чисел
if (z = max(x, y)) > 0 then
Msgbox CStr(z)
Else
Msgbox «How Come?»
End if

Вы ожидаете, что высветится 20, как должно бы было произойти в С? Однако, VB сравнит z с RHS (right-hand side)-правой стороной, даже перед присвоением, независимо от скобок. Будьте внимательны.

8.5 ИСПОЛЬЗОВАТЬ BACKQUOTES ВМЕСТО АПОСТРОФОВ

VB3, VB4 16/32, VB5
Level: Intermediate
Часто при использовании Transact-SQL мне надо перехватывать комментарии юзера из текстбокса и пересылать их в базу данных. Однако, если юзер нажимает апостроф в текстбоксе, происходит ошибка времени выполнения, поскольку SQL Server использует апостроф как признак конца строки. Чтобы обойти эту проблему, перехватите ввод юзера в событии KeyPress и замените апостроф на вот такую кавычку «‘»(ASCII(145)):

Private Sub Text1_Keypress_
(KeyAscii as Integer)
If KeyAscii = 39 Then
KeyAscii = 145
End If
End Sub

Также можно заменить все одинарные кавычки на «‘» перед отсылкой в SQL Server.

86. РАСПРОСТРАНЕНИЕ НОВЫХ ВЕРСИЙ ПРОГРАММЫ ПО СЕТИ

VB4 16/32, VB5
Level: Intermediate

Я пишу VB проги для сети с примерно 300 юзерами. Довольно трудно своевременно уследить за распространением каждой новой версии проги на всех машинах, поэтому я использую такую фичу VB автоинкрементирующаяся нумерация версий для проверки, требуется ли апгрейд проги на конкретной машине. При компиляции проги установите автоинкремент версий в On. Сохраните Ваши setup/upgrade файлы на сетевом диске (настоятельно рекомендую использовать UNC-пути (\\имя_машины\имя_диска) нежели просто имена дисков), и положите INI-файл проги, в котором указан номер новейшей версии. Затем вставьте следующий код в прогу, событие Form_Load:

Open IniFile$ For Input As #1
Line Input #1, sUpgradeVersion$
Close #1

If sUpgradeVersion > (Format(App.Major, «00») & «.» & _
Format(App.Minor, «00») & «.» & _
Format(App.Revision, «0000»)) Then
‘ запуск апгрейда с сетевого диска
End
End If

Если версия в INI-файле выше, чем версия, записанная в .exe, то прога автоматом запустит программу апгрейда по сети и закончит свое выполнение, то есть все нужные файлы смогут быть заменены. Это особенно полезно, когда Вы только начинаете писать прогу, то есть апгрейды и фиксы появляются чуть ли не раз в несколько дней.

Назад к СОДЕРЖАНИЮ

87. ЗАКРЫТЬ ОКНО ПРОГРАММЫ, КАК ЭТО ДЕЛАЕТ WINDOWS 95

VB3, VB4 16/32, VB5
Level: Intermediate

Разместите этот код в declaration section модуля:

Public Sub Win95Shrivel(xForm As Form)
‘ минимизирует окно
xForm.WindowState = 1
End Sub

Вызывайте ее из процедуры Unload формы

Private Sub Form_Unload(Cancel As _
Integer)
Win95Shrivel Me
End Sub

Каждый раз при unloade формы она сначала быренько сворачивается к таскбару, а затем исчезает. Это работает и в Windows 3.1x тоже.

Занятие 3. Разработка приложений на Visual Basic (обучающие и тестирующие программы) Текст научной статьи по специальности « Автоматика. Вычислительная техника»

Аннотация научной статьи по автоматике и вычислительной технике, автор научной работы — Панъгина Нина Николаевна, Паньгин Андрей Александрович

Статья посвящена созданию программ, которые можно использовать для обучения и проверки знаний учащихся. На нескольких примерах, связанных с преподаванием русского языка и математики, автор демонстрирует возможности Visual Basic и подает методические рекомендации.

Похожие темы научных работ по автоматике и вычислительной технике , автор научной работы — Панъгина Нина Николаевна, Паньгин Андрей Александрович,

Текст научной работы на тему «Занятие 3. Разработка приложений на Visual Basic (обучающие и тестирующие программы)»

Панъгина Нина Николаевна Наньгин Андрей Александрович

ЗАНЯТИЕ 3. РАЗРАБОТКА ПРИЛОЖЕНИЙ НА VISUAL BASIC (ОБУЧАЮЩИЕ И ТЕСТИРУЮЩИЕ ПРОГРАММЫ)

Вы хотите как можно быстрее научиться создавать программные приложения под Windows? Поверьте в свои силы и создайте первые «полезные» программы, то есть такие программы, которые могут использовать школьные учителя на своих уроках для обучения и проверки знаний учащихся.

ИСПОЛЬЗОВАНИЕ МАССИВА ОБЪЕКТОВ И ГЛОБАЛЬНЫХ ПЕРЕМЕННЫХ

Кроме обычных массивов, хранящих данные различного типа, в VB разрешается определять массивы объектов (control arrays) (элементов управления), что весьма удобно, если в программе имеются группы объектов, действующих примерно одинаково. Такие массивы позволяют «привязывать» разные элементы управления к одной процедуре обработки события. Например, если в программе создан массив из нескольких командных кнопок, щелчок на любой из этих объектов вызывает одну и ту же процедуру обработки события Click. В то же время VB дает возможность различать конкретные объекты в массиве — это достигается передачей в процедуру индекса нужного элемента.

Каким же образом создать массив объектов? Проще всего это сделать так:

• нанести объект на форму;

• скопировать его в буфер памяти (пункт Edit горизонтального меню, затем Copy);

• произвести вставку объекта из буфера памяти (Edit, Paste);

• при появлении диалогового окна с вопросом «У Вас уже есть объект с таким именем. Вы желаете создать массив объектов?» ответить Да (Yes).

В созданном массиве VB присвоил каждому объекту индекс по порядку. Это отразилось в значениях свойства Index у каждого объекта в окне Properties. Нумерация начинается с нуля. Чтобы обратиться к элементу массива объектов, необходимо указать имя массива, а за ним — индекс в круглых скобках, например:

Command1(0).Caption = «Кнопка 0», Command1(1).Caption = «Кнопка 1».

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

Задание 1. Тест по русскому языку.

Создать приложение, являющееся тестом по русскому языку на слова с безударными гласными в корне слова. Слова с пропущенными буквами должны выводиться в текстовом окне по очереди при каждом нажатии на кнопку «Введите слово». Тестируемый должен выбрать нужную букву-кнопку (А, О, Е, И) и нажать на нее. В окне метки слева внизу должен появляться комментарий в виде слов (Верно/ Неверно). По окончании теста в текстовом окне выводится оценка с указанием количества правильных ответов. Программа завершает работу по нажатию на кнопку «Выход».

Выполнение задания 1.

Первая часть — визуальное программирование.

1. Необходимо создать форму и переименовать ее в соответствии с рисунком 1, свойству Caption (название) присвоив значение «Русский язык».

2. Нанести на форму Метку 1, изменив ее свойство Caption на строку «Вставьте пропущенную букву», свойству Alignment (выравнивание) придать значение Center (по центру), изменить значения свойства Font (шрифт), выбрав название шрифта Times New Roman, размер 16, стиль полужирный курсив.

3. Нанести на форму Метку 2, очистить ее (свойству Caption присвоить пустую строку), изменить значения свойства Font по своему усмотрению.

4. Нанести на форму Текстовое окно, очистить его, свойству Alignment придать значение Center, не забыв присвоить свойству Multiline значение True, изменить значения свойства Font, выбрав название шрифта Times New Roman, размер 16, стиль полужирный.

5. Нанести на форму массив из четырех Командных кнопок 1, изменив их размеры и свойство Font, а также свойство Caption на «А», «О», «Е», «И».

6. Нанести на форму Командные кнопки 2 и 3, изменив их размеры и свойство Font, а также свойство Caption на

«Введите слово» и «Выход» соответственно.

Вторая часть — написание кода программы.

7. В данном приложении будут использоваться два глобальных массива: массив из 10 слов с пропущенными буквами SL$(10) и массив B(10), содержащий номера пропущенных букв (равные индексам элементов массива кнопок 1). В приложении также будут использоваться глобальные переменные: N — номер очередного слова, K — количество правильных ответов. Описываем все глобальные переменные в общем разделе описаний General Declarations:

Dim SL$(10), B(10), K, N

8. При событии загрузки формы выполняется инициализация переменных и объектов. Необходимо присвоить (или ввести из файла) значения элементам обоих массивов. Переменным N и K можно присвоить нулевые начальные значения.

Private Sub Form_Load () N = 0: K = 0

SL$(1) = «г-лова»: B(1) = 1 SL$(2) = «св-детель»: B(2) = 3 SL$(3) = «в-тражи»: B(3) = 3 SL$(4) = «ед-ница»: B(4) = 3 SL$(5) = «тр-ва»: B(5) = 0 SL$(6) = «сн-жинка»: B(6) = 2 SL$(7) = «адв-кат»: B(7) = 1 SL$(8) = «диск-тека»: B(8) = 1 SL$(9) = «м-шина»: B(9) = 0 SL$(10) = «св-тильник»: B(10) =2 End Sub

9. В процедуре обработки события Щелчок на кнопку «Введите слово» должен увеличиться на единицу номер очередного слова, а само слово должно появиться в текстовом окне (свойству text Текстового окна необходимо присвоить значение элемента массива SL с номером N). В случае, если номер слова превысил допустимое значение (в данном случае 10), необходимо вывести сообщение о количестве правильных ответов. Не забыть перед выводом очередного слова в Текстовое окно очистить его и Метку 2, предназначенную для комментариев.

Private Sub Command2_Click() Textl.Text = «» Label2.Caption = «» N = N + 1

If N > 10 Then Label2.Caption =_ «Из 10 вопросов верных ответов «_ + Str$(K): Exit Sub Textl.Text = SL$(N) End Sub

Примечание. Поскольку ширина страницы книги не бесконечна, некоторые операторы программы разбиты на несколько строк. В конце таких строк используется символ подчеркивания (_), который является стандартным символом продолжения языка Visual Basic. При вводе текста в окно редактора вы вполне можете опустить символы продолжения и записать оператор в одной строке. Обе записи правомерны, и компилятор правильно их воспримет.

10. Процедура обработки события Щелчок на кнопку-букву является одной для всего массива, информация о конкретном элементе массива содержится в параметре Index. В процедуре обработки данного события необходимо проверить, верная ли буква-кнопка нажата, а эта проверка заключается в том, чтобы сравнить значение индекса нажатой кнопки со значением элемента массива B с номером очередного слова. В случае верного ответа в метку занести слово «ВЕРНО» и увеличить на единицу количество правильных ответов, в случае неверного ответа — в метку занести слово «НЕВЕРНО».

Private Sub Command1_Click (Index As Integer)

If Index = B(N) Then Label2.Caption = «ВЕРНО» K = K + 1 Else

Label2.Caption = «НЕВЕРНО» End If End Sub

11. В процедуре обработки события Щелчок на кнопку «Выход» необходимо завершить работу программы.

Private Sub Command3_Click()

12. Для того чтобы после неверного выбора буквы нельзя было еще раз

нажимать кнопку, можно внести дополнение в код процедуры Command 1_Click, сделав буквы-кнопки недоступными.

Command1(i).Enabled = False Next I

13. Снова сделать их доступными (свойству Enabled присвоить значение True) нужно будет при вводе нового слова в процедуре Command2_Click.

14. Запустить программу на выполнение, протестировать ее и завершить.

Задание 2. Тест по арифметике

(для самостоятельного выполнения).

Создать приложение, согласно рисунку 2, представляющее собой тест по арифметике на действия сложения и вычитания с целыми числами в пределах от 0 до 99. Числа и знак операции формируются случайным образом. Примеры должны выводиться в текстовое окно по очереди при каждом нажатии на кнопку «Следующий пример». Ответ в текстовое окно можно набирать либо на клавиатуре, либо с помощью мышки, нажимая нужную цифру-кнопку и, если необходимо, знак «минус». Убедившись в правильности набора, нажать кнопку «Ввод ответа». В окне метки слева внизу должен появляться комментарий в виде слов (Правильно/Неправильно). По окончании теста в этом же окне метки появляется оценка. Программа завершает работу по нажатию на кнопку «Выход».

ФУНКЦИЯ И ОКНО INPUTBOX

Текстовое поле требуется для ввода разнообразной информации. Но иногда требуется ввести только краткую информацию, например, имя пользователя или значения даты и времени. Для ввода небольших фрагментов текста VB предлагает функцию вызова Окна ввода InputBox.

Окно InputBox состоит из четырех элементов (рисунок 3):

• приглашение к вводу;

• поле ввода со значением, предлагаемым по умолчанию;

• две кнопки (ОК и Cancel).

Функция вызова окна InputBox имеет следующий синтаксис с соответствующими именованными аргументами:

Возвращаемое значение = InputBox_ (prompt [,title] [,default] [,xpos]_ [,ypos])

Параметр prompt определяет текст, отображающийся в диалоговом окне как приглашение. Title отвечает за надпись заголовка; если этот параметр не указан, то отображается название приложения. Параметр default определяет значение по умолчанию, отображаемое в строке ввода. Параметры xpos и ypos указывают координаты верхнего левого угла окна (по умолчанию окно появляется посредине экрана). Параметры xpos и ypos нужно использовать совместно. Например:

strReturn = InputBox («Введите_ десятичное число», «Окно ввода»,_ «12345»)

Функция InputBox возвращает строку, введенную пользователем.

Для вывода различных сообщений имеется окно, подобное InputBox, — MessageBox. Почти все приложения Windows используют MessageBox, так как этот компонент входит в состав Windows, a VB только предоставляет возможность его вызова.

Вид окна MessageBox может быть различным (рисунок 4), но в его состав всегда входят:

• пиктограмма (может отсутствовать);

MessageBox можно вызывать как процедуру (или оператор) и как функцию. Синтаксис процедуры:

MsgBox Prompt [, Buttons] [, Title]

MsgBox «Десятичное число 12345 =» +_ Chr(13) + Chr(10) + «двоичному числу_ = 11000000111001», 1, «Окно вывода»

Возвращаемое_значение = MsgBox_ (Prompt [,Buttons] [,Title])


По определению, функция возвращает некоторое значение, а оператор —

нет. Поэтому для запросов у пользователей некоторой информации требуется вызывать MsgBox как функцию, так как возвращаемое значение используется для определения кнопки, нажатой пользователем, например:

Select Case MsgBox («Вопрос»,_ vbAbortRetrylgnore + vbQuestion,_ «Заглавие») Case vbAbort Call Abort Case vbRetry

Значения, возвращаемые функцией

Константа Значение Нажата кнопка

vbCancel 2 Отмена

vbRetry 4 Повторить

vblgnore 5 Пропустить

Окно MsgBox всегда требует реакции пользователя на отображенное сообщение, поэтому надо помнить, что, пока на экране находится Окно сообщения, программа переходит в состояние ожидания.

Задание 3. Перевод чисел из десятичной системы счисления в двоичную.

Создать приложение, представляющее собой программу по переводу чисел из десятичной системы счисления в двоичную. На форме расположить две командные кнопки с названиями «Перевод» и «Выход». При каждом нажатии на кнопку «Перевод», появляется Окно ввода, как на рисунке 3. Пользователь должен набрать десятичное число и нажать на кнопку ОК. После этого должно появиться Окно вывода, как на рисунке 4, с числом в двоич-

ном виде. Программа завершает работу по нажатию на кнопку «Выход».

Выполнение задания 3.

Первая часть — визуальное программирование.

1. Необходимо создать форму и свойству Caption присвоить значение «Перевод чисел из десятичной системы счисления в двоичную».

2. Нанести на форму Командные кнопки 1 и 2, изменив их размеры и свойство Font, а также свойство Caption на строки «Перевод» и «Выход», соответственно.

Вторая часть — написание кода программы.

3. В процедуре обработки события Щелчок на кнопку «Перевод» необходимо вызвать функцию InputBox, присвоить возвращаемое значение числовой переменной n и запомнить его в строковой переменной n1$. Перевод осуществить в цикле Do Loop Until, находя остатки от деления на 2 и накапливая их в строковой переменной n2$ справа налево. Вывод можно осуществить в Окно вывода с помощью оператора MsgBox. Для перехода на другую строку использовать символы перевода каретки и конца строки Chr(13) и Chr(10) или константу vbCrLf.

Private Sub Command1_Click()

n = InputBox («Введите десятичное_

число «, «Окно ввода»)

If n = «» Then Exit Sub

n2$ = Str(ost) + n2$ Loop Until n = 0

MsgBox «Десятичное число » + n1$_ + » =» + Chr (13) + Chr (10) + _ «двоичному числу = » + n2$,_ vbDefaultButton1, «Окно вывода» End Sub

4. В процедуре обработки события Щелчок на кнопку «Выход» необходимо

завершить программу оператором END.

Private Sub Command2_Click()

5. Запустить программу на выполнение, протестировать ее и завершить.

С НЕСКОЛЬКИМИ ФОРМАМИ

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

Для загрузки и выгрузки формы используются операторы Load и Unload.

Load FormName Unload FormName

Для отображения и скрытия формы используются методы Show и Hide.

Задание 4. Обучающая программа

по русскому языку.

Создать приложение, являющееся обучающей

программой по русскому языку по теме «Деепричастие и деепричастный оборот». Имеется следующий текст, который необходимо представить в качестве учебного материала:

1. «Деепричастие — это особая форма глагола, обозначающая добавочное действие основного глагола».

2. «Деепричастный оборот — это деепричастие вместе с зависимыми словами».

3. «Деепричастный оборот выделяется двумя запятыми, когда он находится в середине предложения, и одной запятой — в начале и в конце предложения».

4. «Не выделяется запятыми одиночное деепричастие, если оно стоит в конце предложения сразу после основного глагола».

5. «Не выделяется запятыми деепричастный оборот, если он является фразеологическим оборотом».

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

• разработать художественное оформление, то есть создать ряд рисунков, сопровождающих объяснения, расположить текст и рисунки на одной или нескольких формах, используя различные объекты управления и контроля;

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

Начало программы может выглядеть, например, как на рисунке 5. Страница, содержащая определение деепричастия, может выглядеть, как на рисунке 6.

Для того чтобы лучше объяснить деепричастный оборот, можно создать два поясняющих рисунка. На одном изобразить машину (деепричастие), а на втором — прицеп (зависимые слова), применить анимационный эффект (машина подъезжает, зацепляет прицеп и везет его). Это будет смотреться, как на рисунке 7.

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

Выполнение задания 4.

Первая часть — визуальное программирование.

При рассмотрении рисунков 5-11 можно заключить, что удобнее было бы создать не одну, как это делалось раньше, а две формы. Первая форма должна отражать начало программы (рис.5, 6), а вторая форма — основную часть (рис.7-11).

1. Переименовать первую форму в соответствии с рисунком 5, свойству Caption присвоив значение «Деепричастие и деепричастный оборот».

2. Нанести на форму Метки 1 и 2, Метку 1 очистить, а в Метку 2 поместить строку «Вам предлагается урок по русскому языку на тему ДЕЕПРИЧАСТИЕ». Свойству Alignment обеих меток придать значение Center, изменить значения свойства Font, выбрав название шрифта MS Serif, стиль полужирный, размер 18 и 14 для Меток 1 и 2, соответственно.

3. Нанести на форму Командную кнопку, изменив ее свойство Caption на строку «Начать урок».

4. Через пункт меню Add Form (Добавить Форму) добавить новую форму New Form (по умолчанию свойство Name этой формы — Form2), изменить свойство Caption, как в первой форме.

5. Нанести на вторую форму Метку, занести в нее текст «Деепричастный оборот», свойству Alignment придать значение Center, свойству Autosize — True, изменить значения свойства Font, выбрав название шрифта MS Serif, размер 16, стиль полужирный.

6. Нанести на форму три Окна рисунка 1, 2 и 3, придав свойству Autosize значение True.

7. Нанести на форму Командную кнопку, изменив ее свойство Caption на «Продолжить».

8. Для осуществления эффектов анимации (самая простая имитация движения — периодическая смена двух кадров) необходимо нанести на форму три таймера, по срабатыванию которых и будут меняться изображения.

Вторая часть — написание кода программы.

9. Алгоритм данной программы строится согласно последовательности действий пользователя, который, по мере обучения, щелкает на Командные кнопки с названиями «Начать урок», «Продолжить» и т.д. В зависимости от порядкового номера щелчка, должен меняться внешний вид формы, либо должна загрузиться другая форма. Глобальную переменную, известную для всех форм, необходимо объявлять как Public или Global в модуле (отдельном файле с расширением .bas). Для этого в пункте меню Add Module (Добавить модуль) открыть новый модуль New Module и записать в общем разделе объявлений модуля следующую строку:

10. В процедуре обработки события Щелчок на Командную кнопку «Начать урок» на первой форме должен увеличиться на единицу номер щелчка (переменная k). В зависимости от значения k выполняются различные действия.

• При k=1 свойству Caption Метки 1 присвоить слово «ОПРЕДЕЛЕНИЕ», а в Метку 2 занести само определение деепричастия, обвести его в рамку путем замены свойства BorderStyle, поменять название Командной кнопки на «Продолжить».

• При k=2 необходимо передать управление на Форму 2, для чего сначала выгрузить Форму 1, а затем показать Форму 2 (загрузка формы при методе Show про-

исходит автоматически). Во второе и третье Окна рисунков загрузить картинки машины и прицепа, расположив их по левую и правую стороны формы. Для осуществления движения машины по направлению к прицепу включить, то есть сделать доступным, Таймер 1, по которому и осуществляется именно это движение.

Private Sub Command1_Click() k = k + 1 Select Case k Case 1

Label1.Caption = «ОПРЕДЕЛЕНИЕ» Label2.Caption = «Деепричастие_ — это особая форма глагола,_ обозначающая добавочное_ действие основного глагола» Command1.Caption = «Продолжить» Label2.BorderStyle = 1 Case 2

Unload Form1 Form2.Show

Form2.Picture2.Picture =_ LoadPicture(«deepr1.bmp») Form2.Picture3.Picture =_ LoadPicture(«deepr2.bmp») Form2.Picture2.Left =_ -Form2.Picture2.W >

11. После выгрузки первой формы происходит показ второй формы. В общем разделе описаний для второй формы необходимо описать константу h — шаг для перемещения рисунков по экрану — и глобальную переменную n, используемую для смены рисунков при изображении движения.

1 2. В процедуре обработки события Timer для Таймера 1 должно перемещаться Окно рисунка 2, содержащее изображение машины. Это удобно делать, изменяя свойство Left на величину шага h до тех пор, пока Окно рисунка 2 (машина) не приблизится к Окну рисунка 3 (прицеп).

Private Sub Timer1_Timer()

If Picture2.Left 7 появляется Окно сообщения MSGBOX с вопросом «Вы хотите закончить обучение?» и предлагается два варианта ответа: Да (Yes) и Нет (No). При выборе первого варианта обучающая программа завершает свою работу, а при выборе второго варианта программа начинает свою работу с самого начала, для чего необходимо обнулить переменную k, выгрузить вторую форму и показать первую.

Private Sub Command1_Click() k = k + 1 Select Case k

Picture2.Left = Picture3.Left_ — Picture2.W ) Form2.Picture1.Visible = True Case 4

Timer2.Enabled = False Form2.Label1.Caption =_ «Выделение запятыми _ ДЕЕПРИЧАСТИЯ» + Chr(13) + _ » и ДЕЕПРИЧАСТНОГО ОБОРОТА» Form2.Picture1.Picture =_ LoadPicture(«deepr4.bmp») Form2.Picture2.Picture =_ LoadPicture(«Ris4-0.bmp») Form2.Picture3.Visible = False Form2.Picture2.Left =_ Form2.Width

Form2.Timer3.Enabled = True Case 5, 6, 7

a$ = «deepr» + Trim(Str (k)) + » .bmp» Picture1.Picture=LoadPicture(a$) Picture2.Left = Form2.Width Case Else

If MsgBox(«Вы хотите закончить_ обучение?», vbYesNo + vbQuestion,_ «») = vbYes Then End k = 0

Unload Form2 Form1.Show End Select End Sub

14. В процедуре обработки события Timer для Таймера 2 должны одновременно перемещаться Окна рисунков 2 и 3, содержащие изображение машины с прицепом. Движение осуществляется с шагом h справа налево до левой границы формы.

Private Sub Timer2_Timer() If Picture2.Left > 0 Then

Picture3.Left = Picture3.Left — h Picture2.Left = Picture2.Left — h End If End Sub

15. В процедуре обработки события Timer для Таймера 3 должно перемещаться справа налево Окно рисунка 2 с шагом h*5, содержащее изображение

мальчика с портфелем-«запятой», либо девочки с шариками в руках, в зависимости от текста-примера в Окне рисунка 1. Поддержка анимационного эффекта сменой рисунков-кадров производится с помощью переменной n, принимающей значение то равное нулю, то единице. Имена файлов с рисунками содержат, кроме порядкового номера (переменная k), также и номер кадра (переменная n), например, «Ris4-0.bmp» и «Ris4-1.bmp» (рисунки 12 и 13).

Private Sub Timer3_Timer() If Picture2.Left > 0 Then

Picture2. Left = Picture2. Left -h*5 n = (n + 1) Mod 2 a$ = «Ris» + Trim(Str(k)) + _ «-» + Trim(Str(n)) + «.bmp» Picture2.Picture = LoadPicture(a$) End If End Sub

16. После написания кода программы требуется запустить ее на выполнение и окончательно протестировать.

смотренное в задании 4. Имеются дополнительные сведения для представления в качестве учебного материала:

1. Деепричастие имеет признаки глагола и наречия.

2. Деепричастия бывают совершенного и несовершенного вида.

3. Частица НЕ с деепричастиями пишется раздельно, существуют исключения.

4. Имеются глаголы, от которых нельзя образовать деепричастий.

5. Существует замена деепричастному обороту — сложносочиненные и сложноподчиненные предложения.

• создать в графическом редакторе рисунки, отражающие данную тему, разработать интерфейс пользователя с программой, используя одну или несколько форм, а также различные объекты управления и контроля;

• разработать сценарий, то есть последовательность действий пользователя и последовательность событий.

И КОНТРОЛЯ FRAME

Объект Frame (Рамка) предназначен для помещения в него других объектов, или, как говорят, служит контейнером для других элементов управления. Изменение значения свойств объекта-контейнера будет влиять на соответствующие свойства всех составляющих его объектов. Чтобы поместить объекты в рамку (группу), необходимо проследить, чтобы перед выбором других объектов рамка находилась в активном состоянии. Нельзя поместить в группу уже существующие на форме элементы управления.

ричастие и деепричастный оборот», рас-

Caption, BorderStyle, Enabled, FontBold, Fontltalic, FontName, FontSize, Height, Left, Top, Width, Name — свойства, аналогичные свойствам других объектов.

СвойствоVisible, установленное в False, приведет к тому, что сама рамка и входящие в нее объекты исчезнут с экрана.

Задание 5. Дальнейшая разработка обучающей программы по русскому языку (для самостоятельного выполнения).

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

ОБЪЕКТ УПРАВЛЕНИЯ И КОНТРОЛЯ LISTBOX

ABS COS EXP LOG

Объект ListBox (Список) используется обычно в программах для наглядного представления информации, а также для предоставления пользователю возможности выбора одного (или нескольких) элемента из некоторого перечня.

Ниже перечислены основные элементы списка (рисунок 14).

• Выбранный элемент (либо подсвечивается, либо помечается флажком в зависимости от типа списка). Рисунок 14

Enabled, FontBold, Fontltalic, FontName, FontSize, Height, Left, Top, Width, Name — свойства, аналогичные свойствам других объектов. Columns (колонки) — количество колонок в списке, по умолчанию, равно нулю, что соответствует одной колонке. List (список) — представляет собой массив, состоящий из элементов списка. ListCount — количество элементов в списке. Listlndex (индекс текущего элемента в списке) — соответствует номеру последнего подсвеченного элемента списка. Индекс первого элемента списка равен нулю.

Sorted (сортировка). Если это свойство приравнено True, то элементы в списке располагаются по алфавиту. Style (вид списка). По умолчанию, равен нулю, при задании значения 1 список приобретает вид с элементами-флажками.

Addltem — включает элемент в список (синтаксис: List1.AddItem текст[,индекс]).

Removeltem — удаляет элемент из списка (синтаксис: Listl.Removeltem индекс). Clear — удаляет из списка все элементы. (синтаксис: Listl. Clear).

ДОПОЛНИТЕЛЬНЫЕ ОБЪЕКТЫ УПРАВЛЕНИЯ И КОНТРОЛЯ

При создании Visual Basic были предусмотрены специальные средства для расширения набора элементов управления и контроля, доступных программе. Для этого Вы можете выбрать пункт меню Components (контекстное меню Окна инструментария Toolbox, либо в пункте Project главного меню). В появившемся списке вкладки Controls поставьте галочку против нужного элемента управления. Дополнительные стандартные элементы управления и контроля расположены в следующих группах:

• Microsoft Windows Common Controls 6.0 (содержит, например, такие объекты, как ImageList — Список изображений, StatusBar — Строка состояния, TreeView

— Дерево просмотра, ProgressBar — Индикатор процесса и другие);

• Microsoft Windows Common Controls-2 6.0 (содержит такие объекты, как UpDown

— Счетчик, Month View — Календарь);

• Microsoft Windows Common Controls-3 6.0 (содержит объект CoolBar — Панель инструментов).

Кроме стандартных компонент, можно подключать к своим разработкам и другие интересные компоненты, с некоторыми из которых Вы познакомитесь далее.

ИСПОЛЬЗОВАНИЕ ТЕХНОЛОГИИ MICROSOFT AGENT

Microsoft Agent — средство, которое позволяет использовать анимированных персонажей (типа помощников в пакете

Microsoft Office) для создания оригинальных интерфейсных форм Ваших приложений. Microsoft Agent входит в состав операционной системы Windows-2000. Основной компонент ActiveX, персонажи (Characters) и синтезатор речи (text-to-speech, TTS) находятся в свободном распространении на http://www.microsoft.com/ products/msagent.

Персонажи можно выбрать из галереи на http ://allcharacters.chat.ru. С их помощью можно проводить мультимедийные презентации, озвучивать текст (в том числе и по-русски) сообщений в Ваших программах, забавной анимацией скрасить обучающую программу, протянуть руку помощи в тестирующей программе. При этом можно учесть психологические аспекты общения пользователя с Вашей программой, выбирая соответствующий тип персонажа: «Джина» (Genie) — покорного слугу Ваших действий или «Мага» (Merlin), чье могущество позволяет преодолеть преграды на пути познания. Установка дополнительных компонент: SAPI (Speech API) и BalloonDialog (http:// www.sommytech.com.ar/balloondialog) обеспечит общение с агентом голосовыми командами и интерфейсом помощника MS Office. Дополнительная информация содержится в электронной документации VB по MS Agent.

АГЕНТ: — ДАВАЙТЕ ПОЗНАКОМИМСЯ

Создадим программу для первого знакомства с Агентом. Первая часть — визуальное программирование.

1. Поместим компонент Агента (после установки его основных модулей) в Toolbox -стандартный блок инструментов VB. Для этого, выберем опцию Components в меню Project. В появившемся списке вкладки Controls поставим галочку против элемента управления Microsoft Agent Control 2.0.

2. Добавим появившийся значок Агента на форму.

Данный объект Agentl содержит коллекцию объектов Characters для управления отдельным персонажем (может поддерживаться одновременно несколько персонажей с их взаимодействием). Каждый объект Character определяется строкой-именем и содержит объекты Commands (Команды) и Balloon (специальное окно для вывода текстовой информации). Объект Commands служит для распознавания отдельным персонажем как голосовых команд, так и выбираемых из контекстного меню, которое вызывается по нажатию правой кнопки мыши на персонаже. Каждый персонаж задается отдельным файлом (с расширением *.acs) и имеет своеобразный набор анимации. На рисунке 15 в качестве Агента выбран Бобик (Rocky.acs) — помощник MS Office. Для синхронизации действий агента и других операторов программы служит объект Request, позволяющий получать информацию о состоянии выполнения Агентом различных методов.

3. Поместим на форму Командную кнопку 1 с надписью «Вызвать агента» и Командную кнопку 2 с надписью «Список команд». Для содержимого списка используем элемент управления ListBox.

Вторая часть — написание кода программы.

4. Используем глобальную переменную MyAgent для обозначения персонажа.

Dim MyAgent As IAgentCtlCharacterEx

5. В процедуре обработки события Щелчок на кнопке 1 выполним следующие действия:

Загрузим (Load) файл персонажа в коллекцию Characters под именем «merlin» (файл «merlin.acs» или «genie.acs» или «rocky.acs» или какой-либо другой, присутствующий в системе).

• Добавим с помощью метода Add в раздел «Мои команды» пользовательские ко-Рисунок 15 манды (в том числе и голосо-

вые при установленном SAPI).

• Переместим без анимации персонаж в заданную точку экрана (Move).

• Покажем персонаж (Show), текст (Speak) и анимацию его приветствия (Play).

Private Sub Command1_Click() Agent1.Characters.Load «merlin»,_ «merlin.acs»

Set MyAgent = Agent1. Characters («merlin»)

MyAgent.Commands.Caption =»Мои_ команды»

MyAgent.Commands.Voice = «Voice_ commands»

MyAgent.Commands.Add «Cmd1»,_ «Запустить Explorer», «Explorer» MyAgent.Commands.Add «Cmd2»,_ «Спрятаться в углу», «Move» MyAgent.Commands.Add «Cmd3»,_ «Давайте знакомиться!» MyAgent.Commands.Add «Options»,_ «Параметры агента», «Options» MyAgent.Commands.Add «Sing», «Спой», «Spoi», True, True

MyAgent.MoveTo 450, 120, 0 MyAgent.Show

‘ Для выбора приветствия в случайном_ порядке используется знак «|» MyAgent . Speak ( «Hello ,_ friend!|Greetings!|Here I am!») MyAgent.Play «Wave» MyAgent.Play «RestPose» End Sub

6. В процедуре обработки события Щелчок на кнопке 2 делаем видимым список List1 и добавляем в него всевозможные для данного персонажа анимации.

Private Sub Command2_Click() List1.Visible = True For Each Animation In_

List1.AddItem Animation Next End Sub

7. В процедуре обработки команд агента определяем его действия по пользовательским командам с именами:

• Cmd1 — запустить программу Explorer.

• Cmd2 — переместить программно агента в верхний левый угол (голосовая команда «move»).

• Cmd3 — показать в Balloon-окне стандартное имя и описание агента.

• Options — показать окно дополнительных параметров персонажа, в котором можно выбрать клавишу (по умолчанию -CapsLock), по нажатию которой персонаж переходит в режим прослушивания микрофона в течение задаваемого времени (в настройке — 2 секунды), когда команда может быть озвучена голосом (третий параметр метода Commands.Add).

• Sing — персонаж проигрывает заданный wav файл (голосовой аналог команды «spoi»).

Private Sub Agent1_Command(ByVal_ UserInput As Object)

Select Case UserInput.Name Case «Cmdl»

MyAgent.Think ( «Выполняю_ команду»)

Shell «explorer», vbNormalFocus Case «Cmd2»

MyAgent.MoveTo 1, 1 Case «Cmd3»

MyAgent. Speak MyAgent. Name +_ «. » + MyAgent.Description Case «Options» Agentl.PropertySheet.Visible_ = True

Case «Sing» ‘merlin «говорит»_ звуковой файл

Path$ = «c:\windows\media_ \crialarm.wav» ‘укажите_ полный путь к файлу MyAgent.Speak «», Path$ End Select End Sub

8. В процедуре обработки события Щелчок на элементе списка Listl персонаж останавливает свои предыдущие действия и выполняет заданную анимацию (аналог команды «Мотор!» из локального меню помощника MS Office).

Private Sub List1_Click() MyAgent.Stop MyAgent.Play List1.Text End Sub

9. Запустите проект, вызовите соответствующей кнопкой агента и список анимации. Пронаблюдайте действия агента для каждого элемента списка (они мо-

Как я могу заставить программу запускаться автоматически в определенное время в день (VB.NET)

Приложение, которое я разрабатываю прямо сейчас, позволяет пользователю обновлять лист Excel или базу данных Sql для установки показателей дважды в день. Программа делает это, выскакивая в определенное время (например, 6:00 AM, 5:00 PM, 3:42 PM, независимо от того, что пользователь устанавливает). Когда программа появляется в определенное время, программа («Auto Excel It . «) позволяет вам отслеживать установленные данные (например, звонки продаж, презентации продаж, собрания, количество часов кодирования, количество jalepeño burritos eaten и т.д.).

Как разработчик может заставить эту программу «всплывать»/запускать/выполнять автоматически в определенное время с помощью API Scheduler Windows (или что-то лучше)?

Вот как мое понимание развивалось в последнее время:

Nothing → Использовать таймеры, поскольку программа работает в фоновом режиме → Использовать API-интерфейс Scheduler для автоматического запуска (текущего) → Возможное новое понимание из вашего ответа

Например, я знаю: DispatcherTimers, Timers, другой таймер, о котором я не знаю, Sleep(), Планировщик Windows. Но имея в виду, я не знаю, что делать в отношении следующего: автоматический запуск программы через Windows Scheduler; Сохранение ресурсов компьютера, если используется таймер; или даже как получить эту вершину автоматически.

Обновление 1:

@nfell2009: Ваша логика очень помогла мне. Сначала мне пришлось поиграть с конвертированием своего таймера сюда в DispatcherTimer (кажется, стандартный стандарт WPF). Затем я переключил «Ручки» для Sub tCheckTime на «AddHandler tCheckTime.Tick, AddressOf tCheckTime_Tick». Почему я должен был сделать это, это хороший вопрос.

Затем, когда я установил базовые настройки EventHandlers, ваша идея сравнить текст пользователя (As Date) с System.Date хороша — когда я что-то прикрутил и не смог заставить код работать, я включил его и преобразовал System.Date в String- — я перешел из String-> Date To Date-> String. Это, когда я получил таймер для работы. Когда мое System.Time отметит до 3:12 вечера, MsgBox появился с «Your Message Here».

(Быстрое (злое) спасибо! Я потратил четыре с лишним часа на то, чтобы это работало)

От использования «Ручки» В tCheckTime_Tick (Кажется, что он должен «работать»)

Для AddHandler blah, AddressOf tCheckTime_Tick (работает)

Как заставить вашу программу на vb работать быстрее ?

В этой маленькой статье я дам несколько собранных мною советов как сделать ваш программный код для DirectX более быстрым.

Во-первых, если вы хотите работать с DirectX, переходите на VB6. Сама программа шестого бейсика работает быстрее, чем программа пятого (спасибо компилятору). Во-вторых, библиотека седьмого DirectX от Microsoft работает ГОРАЗДО (!) быстрее, чем Patrice Scribe TLB (неполная функциональность это уже отдельный разговор).

Итак, про компилятор вроде бы сказал. Вам не потребуется компилировать всю программу, если вы хотите посмотреть только маленькое изменение, так как делает это Си. Однако сама программа Visual Basic работает во много раз медленнее программы на Си — и опять это заслуга компилятора, ну не может он отучить прогу от родной msvbvm60 библиотеки. :(

Вот некоторые советы, которые помогут вам сделать вашу DirectX игру более быстрой:

  • Если вы совершаете блиттинг в DirectX с помощью программного драйвера, а не аппаратного ускорения, то используйте функцию BltFast, если вам надо просто перенести спрайт, а не использовать растяжение, вращение и т. п. BltFast работает примерно на 10% быстрее, чем функция Blt, а также и просто удобнее в использовании, потому что вам надо передавать меньше структур.
  • DirectDraw и Direct3D гораздо быстрее в полноэкранном режиме, чем в оконном
  • Избегайте очень много операций блиттинга.
  • Избегайте создания большого количества поверхностей. Не создавайте массивы поверхностей. Старайтесь размещать как можно больше спрайтов на одной поверхности.
  • Если вы делаете игру с большим количеством спрайтов и/или тайлов, попробуйте размещать их в массивы структур, создавать классы или что-нибудь в этом роде. Таким образом, когда вам надо будет вывести все спрайты, вы можете нарисовать их в один цикл типа этого:
  • В тайловых играх старайтесь не прорисовывать всю карту (я имею в виду видимую часть) каждый раз, когда спрайт героя двигается. Постарайтесь сделать процедуру, которая будет прорисовывать за один раз одну колонку или строку.
  • Избегайте большого количества циклов. Старайтесь сделать как можно больше работы за один цикл.
  • Попробуйте сделать несколько «процессов». Операции блиттинга и флиппинга, а также ожидания нового цикла обновления экрана занимают время и в это время компьютер ничего не делает. Постарайтесь сделать параллельный процесс, который будет в это время обсчитывать, ну скажем следующую позицию спрайта.
  • Если вы создаете Direct3D игру, выполните поиск устройства, наиболее подходящего для D3D
  • Ramp эмуляция всегда лучше RGB эмуляции, однако ни одна из них не сравнится с HAL (Hardware Acceleration Layer — рендеринг через аппаратное ускорение).
  • В Direct3D Retained Mode при рендеринге большого количества многоугольников без использования HAL используйте Flat shading. Этот эффект гораздо быстрее Gouraud shading.
  • Без аппаратного ускорения избавляйтесь от эффекта Dithering (сглаживания пикселей). Конечно игра быдет выглядеть с ним лучше, но это очень сильно тормозит программу. Если используете HAL, тогда верните Dithering на место :)
  • Не надо все время инициализировать объекты, как только они вам понадобятся. Инициализировать объект один раз — гораздо лучше, чем делать это дважды и трижды. Во-первых, вам не надо второй раз беспокоится об ошибках, которые могут быть при инициализации, а во-вторых знаете как раздражает, когда игра при выходе из меню начинает жевать винчестером.
  • Избегайте множества переменных Public и длинных массивов. Они жрут больше стэкового места на протяжении всего сеанса запуска программы и они могут затормозить программу.

Старайтесь не делать чего-то если можно этого не делать. VB еще не настолько быстр, чтобы позволять себе много эффектов. Старайтесь делать программу меньше, а код быстрее.

Вобщем посмотрите на Unreal и скажите сами себе: Я НЕ ХОЧУ, ЧТОБЫ МОЯ ПРОГА СТОЛЬКО ГРУЗИЛАСЬ.

Как заставить мою программу работать при запуске?

Я программирую настольное приложение, похожее на Google Desktop, но с моим собственным гаджетом на vb.net 2008, как я могу сделать свое приложение, когда пользователь установит его на свой компьютер, для запуска во время запуска?

Давайте предположим, что мое приложение называется windowsAplication1, и я использую Windows XP, и программа будет установлена на диске C?

6 ответов

Вы можете добавить его в реестр с помощью следующего кода

Вы можете удалить его, используя

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

Или вы можете добавить ссылку на ваше приложение в папке «Автозагрузка».

Я предлагаю вам не делать это автоматически, это может раздражать пользователя. Я ненавижу, когда приложения автоматически добавляют их в автозагрузку Windows. Дайте возможность пользователю запускать программу при запуске Windows.

Илон Маск рекомендует:  Как в Excel использовать формулу Если и Сумм
Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL