Главная страница

Леонтьев Б.К. Я изучаю Microsoft Office Visio 2003 (PDF). Удк 004. 738. 5 Ббк 32. 973. 26 018. 2


Скачать 0.88 Mb.
НазваниеУдк 004. 738. 5 Ббк 32. 973. 26 018. 2
АнкорЛеонтьев Б.К. Я изучаю Microsoft Office Visio 2003 (PDF).pdf
Дата25.04.2017
Размер0.88 Mb.
Формат файлаpdf
Имя файлаЛеонтьев Б.К. Я изучаю Microsoft Office Visio 2003 (PDF).pdf
ТипДокументы
#4822
КатегорияИнформатика. Вычислительная техника
страница33 из 35
1   ...   27   28   29   30   31   32   33   34   35
BackgroundFuncApt! Например, вы могли бы иметь фоновый поток, вы полняющий фоновые вычисления или операцию ожидания системы.
Когда они будут завершены, вы можете вызывать метод объекта, кото рый сгенерирует событие в клиенте. Храня количество вызовов метода,
небольшое относительно количества работы, выполняемой в фоновой функции, вы можете достигать очень эффективных результатов.
Что, если вы хотите выполнить фоновую операцию, которая не должна использовать объект? Очевидно, проблемы с соглашением COM
Использование редактора Visual Basic
345 346
Использование редактора Visual Basic
о потоках исчезают. Но появляются другие проблемы. Как фоновый по ток сообщит о своем завершении приоритетному потоку? Как они обме ниваются данными? Как два потока будут синхронизированы? Все это возможно выполнить с помощью соответствующих вызовов API.
Вы сможете использовать глобальные переменные, чтобы обме ниваться данные, но надо знать, что такое поведение не гарантируется
Visual Basic (другими словами, даже если это сейчас работает, не имеется никаких гарантий, что это будет работать в будущем). В этом случае мож но использовать для обмена данными методики, основанные на API. Од нако, преимуществом показанного здесь подхода, основанного на объек тах, является то, что этот подход делает проблему обмена данными между потоками тривиальной, просто делайте это через объект.
Глава 14.
Создание справочных систем
Рано или поздно встает необходимость создания справочной сис темы для вашего приложения. В конце концов, наличие справочной си стемы придает программе завершенность и, в некотором роде, поднима ет ваш имидж, как программиста профессионала.
Приготовления
В большинстве случаев работа с WinHelp из вашего приложения осуществляется посредством вызовов функций
WinAPI, являющихся ча стью операционной системы Windows. Перед использованием
WinAPI
функций их следует объявить в
BAS модуле вашего проекта. Например,
можно использовать следующие объявления:
Public Declare Function WinHelpStr Lib "user32" Alias "WinHelpA"
_ (ByVal hWnd As Long, ByVal lpHelpFile As String,
_ByVal wCommand As Long, ByVal dwData As String) As Long Public
Declare Function WinHelpNum Lib "user32" Alias "WinHelpA"
_(ByVal hWnd As Long, ByVal lpHelpFile As String,
_ByVal wCommand As Long, ByVal dwData As Long) As Long
Как вы видите, функция объявлена дважды. Последний параметр в списке объясняет причину. В зависимости от параметра
wCommand па раметр
dwData может быть либо типа integer (32 битное значение типа
long), либо строкой или структурой (32 битный указатель). Несмотря на то, что вы можете использовать одно и тоже объявление для обоих типов вызова, вам придется явно преобразовывать передаваемые параметры к соответствующему типу. Легче иметь два разных вызова для разных пара метров (один для параметра типа
integer и другой для строк). Вам также понадобятся следующие константы, которые следует поместить в тот же модуль, где объявлена функция
WinHelpAPublic
Const HELP_CONTEXT = &H1Public
Const HELP_QUIT = &H2 Public
Const HELP_INDEX = &H3Public
Const HELP_CONTENTS = &H3& Public
Const HELP_HELPONHELP = &H4 Public
Const HELP_SETINDEX = &H5 Public
Const HELP_SETCONTENTS = &H5& Public
Const HELP_CONTEXTPOPUP = &H8& Public
Const HELP_FORCEFILE = &H9& Public
Const HELP_KEY = &H101 Public
Const HELP_COMMAND = &H102& Public
Const HELP_PARTIALKEY = &H105& Public
Const HELP_MULTIKEY = &H201& Public
Const HELP_SETWINPOS = &H203& Public
Const HELP_FINDER = &HB
Вызов справочной системы из меню
Стандартный интерфейс приложений для Windows XP предпола гает (в соответствии с требованиями фирмы Microsoft), что единствен ной точкой для вызова справочной системы, является пункт меню
Help
одноименного меню
Help (в приложениях MS Office пункт меню Help за менен на
?).
После этого должно отобразится окно с содержанием файла справки. Эти действия могут быть выполнены вот таким кодом:
lReturn=WinHelpNum (hWnd, sHelpFile, HELP_FINDER, 0&)
Первый параметр,
hWnd, должен быть указателем (handle) на глав ное окно вашего приложения (или MDI формы в случае MDI интерфей са). Вам следует использовать одно и тоже значение
hWnd при всех вызо вах. Второй параметр,
sHelpFile, — это строка, содержащая имя файла справочной системы (расширение HLP). Обычно, файл справки нахо дится в том же каталоге, в котором находится
EXE файл вашего приложе ния. В связи с этим вы можете не указывать путь к файлу, либо исполь зовать следующие строки для формирования полного пути к HLP файлу:
sHelpFile=App.Path & "\myfile.hlp"
Вызов справки по нажатию кнопки
В сообществе разработчиков справочных систем такой вид помо щи принято называть «контекстно зависимая помощь на уровне диало га». Обычно, каждое окно диалога (
BorderStyle Fixed Dialog) должно со держать кнопку
Помощь. После нажатия кнопки пользователь получает
Использование редактора Visual Basic
347 348
Использование редактора Visual Basic
справку, описывающую отображаемый в настоящий момент диалог. В те времена, когда справочной системы
What's This (справка, отображаемая после того, как пользователь нажимает кнопку
?, расположенную в пра вом верхнем углу диалога, а затем щелкает по непонятному элементу формы) не было, отображаемое окно помощи содержало экранный сни мок диалога.
В случае, если вы используете режим
What's This, то нет необходи мости помещать в файл справки экранный снимок окна диалога. Вот та кой пример кода может использоваться для вызова справки:
lReturn=WinHelpNum (hWnd, sHelpFile, HELP_CONTEXT, lContextID)
Параметр
hWnd мы уже рассмотрели, sHelpFile содержит имя фай ла справочной системы (и может также указывать наименование окна, в котором следует отобразить помощь). Параметр
lContextID содержит но мер топика, который обычно указан в свойстве
HelpContextID формы.
Справочная система What's This
Справочная система
What'sThis — это новшество, представленное впервые в новом пользовательском интерфейсе Windows XP. В сообще стве разработчиков справочных систем такой вид помощи принято назы вать «контекстно зависимая помощь на уровне элемента формы». Вы можете использовать этот вид помощи в качестве расширенных
tooltip
(подсказки, возникающие при задержке указателя мыши над каким ли бо элементом на панели инструментов). Однако, в отличие от
tooltip,
справка
What's This может содержать графические изображения. Для
Visual Basic 6.3 программистов нет необходимости использовать
WinAPI
для реализации помощи типа
What's This. Следует лишь выполнить ряд простых действий.
В событие
Form_Load (или в процедуре Sub Main) добавьте вот та кой код:
App.HelpFile=App.Path & "\helpfile.hlp"
Для каждого элемента экранной формы создайте топик, описыва ющий его назначение. Каждому топику следует присвоить уникальный номер. Некоторые элементы формы (к примеру, кнопки
ОК или Отмена)
могут иметь одинаковые топики. Как вы знаете, некоторые элементы формы могут выступать в качестве контейнеров (к примеру, элемент
FRAME). Каждый элемент, помещенный в контейнер, может иметь свой собственный контекстный ID, а контейнер — свой. Свойству
WhatThis
HelpID (есть практически у всех элементов) каждого элемента формы присвойте номер топика, в котором описывается данный элемент фор мы. Затем установите свойства формы:
WhatThisHelp=True WhatThisButton=True
Для вызова подсказки
What's This программно, используйте такой код:
lReturn=WinHelpNum (hWnd, sHelpFile, _HELP_CONTEXTPOPUP,
lContextID)
lContextID указывает номер топика в HLP файле. Этот код можно использовать при нажатии кнопки
F1. Есть одна маленькая неприят ность, которую придется обойти. В случае, если вы установили свойство формы
WhatThisHelp=True, то клавиша F1 (в соответствии с документа цией) должна перестать работать. Однако, она продолжает работать и при нажатии отображает контекстную подсказку по элементу формы,
над которым расположен указатель мыши. Поэтому, если вы хотите обеспечить контекстную подсказку именно по тому элементу формы, на который установлен фокус (а не по тому, над которым указатель мыши),
то следует поступить так:

Установите свойство формы
KeyPreview=True. Таким образом, форма первой получает возможность обработать нажатие кнопки.

В событии
KeyDown формы отследите клавишу F1. Как только клавиша перехвачена, установите свойство
key pre
view в значение 0. Затем используйте вызов WinAPI
функции, в котором значение
lContextID можно определить следующим образом:
Form.ActiveControl.WhatsThisHelpID
ActiveForm.ActiveControl.WhatsThisHelpID Screen.
ActiveControl.WhatsThisHelpID
Если вы хотите полностью запретить справку
What'sThis
для некоторого элемента формы, то установите
WhatsThisHelpID= 1
Завершаем работу
Когда приложение завершает работу, вам следует вызвать функ цию
WinAPI, в последний раз для завершения работы справочной систе мы. В случае, если пользователь ни разу не обращался к системе помощи во время работы приложения, то ничего и не произойдет. В случае, если же к справочной системе обращались, и окно программы
WinHelp откры то, то следующий код завершит работу справочной системы:
lReturn=WinHelpNum (hWnd, sHelpFile, HELP_QUIT, 0&)
В этом вызове важно учитывать, что значения
hWnd и sHelpFile
должны быть теми же, что и при вызове
WinAPI функций.
Использование редактора Visual Basic
349 350
Использование редактора Visual Basic

Добавление иконки в SystemTray средствами
Visual Basic 6.3
Единственная функция для работы с иконкой
Shell_NotifyIcon. Ее описание на Visual Basic 6.3 выглядит так:
Declare Function Shell_NotifyIcon Lib "shell32.dll" Alias
"Shell_NotifyIconA" _ (ByVal dwMessage As dwMess, lpData As NOTI
FYICONDATA) As Long
Возвращает ноль в случае ошибки.
Тип
dwMess описывается так:
Public Enum dwMess
NIM_ADD = &H0 ' Добавление иконки
NIM_DELETE = &H2 ' Удаление иконки
NIM_MODIFY = &H1 ' Изменение параметров иконки
End Enum
Переменная
dwMessage должна иметь одно из этих значений.
Тип
NOTIFYICONDATA имеет следующую структуру:
Type NOTIFYICONDATA
cbSize As Long ' Размер переменной типа NOTIFYICONDATA
hwnd As Long ' Указатель окна создающего иконку uID As Long ' Указатель на иконку в пределах приложения uFlags As uF ' Маска для следующих параметров uCallbackMessage As CallMess ' Возвращаемое событие hIcon As Long ' Указатель на изображение для иконки szTip As String * 64 ' Всплывающий над иконкой текст
End Type
Где тип
uF имеет вид:
Public Enum uF
NIF_MESSAGE = &H1 ' Значение имеет uCallbackMessage
NIF_ICON = &H2 ' Значение имеет hIcon
NIF_TIP = &H4 ' Значение имеет szTip
End Enum
Эти константы можно применять в любых сочетаниях, для опре деления какой из параметров имеет значение.
Тип
CallMess:
Public Enum CallMess
WM_MOUSEMOVE = &H200
WM_LBUTTONDOWN = &H201
WM_LBUTTONUP = &H202
WM_LBUTTONDBLCLK = &H203
WM_RBUTTONDOWN = &H204
WM_RBUTTONUP = &H205
WM_RBUTTONDBLCLK = &H206
WM_MBUTTONDOWN = &H207
WM_MBUTTONUP = &H208
WM_MBUTTONDBLCLK = &H209
WM_SETFOCUS = &H7
WM_KEYDOWN = &H100
WM_KEYFIRST = &H100
WM_KEYLAST = &H108
WM_KEYUP = &H101
End Enum
Эти константы обозначают, какое событие возвращается вызыва ющей форме. Буквально, все, что будет происходить с иконкой, будет вызывать у формы одно из перечисленных событий. Ясно, что самое ча стое событие самой иконки это
MouseMove, но для формы оно будет вы глядеть как событие заданное переменной
uCallbackMessage. Как же уз нать, что в действительности произошло с иконкой? Это можно узнать через переменные
X и Y событий MouseMove, MouseDown и MouseUp вы зывающей формы. При этом
Y, если событие произошло с иконкой, а не формой, всегда будет равно нулю, а
X несет информацию о событии с иконкой.
О параметре
X следует сказать отдельно. Действительно, он пере дает информацию о событиях с иконкой, однако эти значения зависят от масштабного коэффициента системного шрифта, но не напрямую, а че рез параметр свойства
TwipsPerPixelX объекта Screen. То есть, для одной и той же системы, при разных величинах системного шрифта, значения будут разными. Начальными значениями событий являются следующие:

MouseMove — 512

LeftButtonDown — 513

LeftButtonUp — 514

LeftButtonDblClick — 515

RightButtonDown — 516

RightButtonUp — 517

RightButtonDblClick — 518
Для того, чтобы узнать действующие в данной системе значения,
их следует умножить на
Screen.
Как же узнать, что событие произошло с иконкой, а не с формой?
Просто, по значению
Y, равному нулю. Но есть и другой способ, если ис пользуется двухкнопочная мышь, то параметр
Button в событиях Mo
Использование редактора Visual Basic
351 352
Использование редактора Visual Basic

useDown и MouseUp формы, будет принимать значения 1 и 2, и при
uCallbackMessage равно
WM_MBUTTONDOWN=&H207 или WM_MBUTTONUP = &H208
Button равен 4, если событие с иконкой. Само собой разумеется,
что возвращаемые
X значения следуют одно за другим, как и события
(
Down

Up
DbClick),поэтому невозможно на одну кнопку мыши на значить два события, к примеру,
Click и DbClick. События, не связанные с мышью, не несут практически никакой информации, и обычно не ис пользуются, следует также отметить, что количество констант
uCallbackMessage намного больше и здесь приведена лишь небольшая часть.
Из описанного видно, что с иконкой можно совершить одно из следующих действий: добавить, модифицировать и удалить, при этом,
модифицируя можно заменить возвращаемое событие, картинку (указа тель при этом останется тем же) и всплывающую надпись (
ToolTips).
Следующий момент, который нужно осветить — это получение
hIcon (указателя на картинку). Предполагается, что иконка будет нахо диться в исполняемом файле или в DLL с ресурсами, но ни в коем случае не является в виде ICO файла. В случае, если иконка запакована в DLL,
то нам понадобятся две функции:
Declare Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA"
(ByVal _ lpLibFileName As String) As Long возвращающая
hInstance библиотеки с именем lpLibFileName. До статочно указать только имя файла с расширением, без пути. Возвраща ет ноль в случае ошибки.
Declare Function LoadIconA Lib "user32" (ByVal hInstance As Long,
ByVal _ lpIconName As String) As Long возвращающая
hIcon для иконки указанной параметром lpIcon
Name в библиотеке. Этот параметр может быть String или Long, в зависи мости от данного вами наименования в
Res файле, соответственно надо изменить декларацию. Можно передать и число как строку, для этого пе ред числом ставится знак
#, а все это берется в кавычки. Следует заме тить, что использование строкового параметра не желательно из за зна чительно большего размера занимаемой памяти и соответственно,
большего времени на передачу параметра. Функция возвращает ноль в случае ошибки.
Понадобится так же функция:
Declare Function FreeLibrary Lib "kernel32" (ByVal hLibModule As
Long) As Long выгружающая библиотеку из памяти. Параметр
hLibModule — это
hInstanse, возвращаемое LoadLibrary. Возвращает ноль в случае ошибки.
Обязательно надо не забыть выгрузить из памяти библиотеку, для освобождения памяти. Выгрузку можно произвести сразу же после до бавления иконки в
SystemTray:
Declare Function GetModuleHandle Lib "kernel32" Alias
"GetModuleHandleA" _ (ByVal lpModuleName As String) As Long возвращающей
hInstanse нашего приложения.
В качестве
lpModuleName передается имя EXE файла с расшире нием. Следует быть внимательным, так как имя процесса в
TaskMenager
не всегда соответствует имени процесса для Windows. Модно использо вать для определения имени
DLLView, можно воспользоваться встроен ным в Visual Basic 6.3
System Information. Функция возвращает действи тельное значение только при работе скомпилированного приложения, а в режиме отладки возвращает ноль, ведь реального процесса при отладке не существует. Свойство
hInstanse объекта App всегда возвращает дейст вительное значение, однако при отладке из за отсутствия процесса
LoadIcon возвращает 0, и создается «пустая» иконка, тем не менее годная для отладки (реагирующая на все события).
Полученное
hInstanse передаем LoadIconA, в качестве lpIconName
указываем номер или имя иконки в
Res файле, как и в случае с DLL. Вы гружать в этом случае ничего не надо.
Создание иконки можно проиллюстрировать следующим приме ром. Считается, что иконка с номером 101 находится в файле Pro ject1.exe. Понятно, что пока мы его не скомпилировали, ее там нет (да и самого файла нет). Форма приложения называется
Form1.
Dim NID As NOTIFYICONDATA
Sub AddIcon()
Dim IDLib As Long ' Указатель на библиотеку
Dim IDIcon As Long ' Указатель на иконку
Const IDMyIcon = 101 ' Идентификатор иконки внутри приложения
Dim AddResult As Long ' Результат добавления иконки
IDLib = GetModuleHandle("Project1.exe") ' Получаем hInstanse
IDIcon = LoadIcon(IDLib, "#101") ' Получаем hIcon
' Заполняем структуру NID типа NOTIFYICONDATA
NID.cbSize = Len(NID) ' Размер структуры
NID.hwnd = Form1.hWnd ' Указатель на форму
NID.uID = IDMyIcon ' Идентификатор иконки
NID.uFlags = NIF_MESSAGE + NIF_ICON + NIF_TIP
' Указываем, что действующими являются поля uCallBackMessage,
hIcon и szTip
NID.uCallbackMessage = WM_LBUTTONDOWN
' Указываем, что событием возвращаемым в форму является MouseDown с параметром Button = 2
Использование редактора Visual Basic
353 354
Использование редактора Visual Basic

NID.hIcon = IDIcon ' Указатель на иконку в файле
NID.szTip = Left$(«MyIcon», 63) & Chr(0)
' Передаем всплывающую фразу "MyIcon", при этом обрезаем ее до 63
символов и добавляем 64 й символ с кодом ноль
AddResult = Shell_NotifyIcon(NIM_ADD, NID)
' Вызываем функцию, через параметр dwMessage указываем, что сле дует добавить иконку, и передаем заполненный NID
End Sub
Удаление созданной иконки можно сделать так:
Sub DeleteIcon()
Dim DeletResult As Long
DeleteResult = Shell_NotifyIcon(NIM_DELETE, NID)
' Вызываем функцию, через dwMessage указываем, что следует уда лить иконку, при этом, раз переменная NID описана на уровне моду ля, не следует заполнять ее заново
End Sub
Размер структуры достаточно указывать один раз, так как за время жизни переменной он измениться не может, и в данном виде составляет
88 байт.
Даже при изменении всплывающей строки ее длина (строки) не будет больше 64 байт.
Для модификации иконки надо вызвать
1   ...   27   28   29   30   31   32   33   34   35


написать администратору сайта