Добавление иконки в SystemTray средствами Visual Basic. Пример от Alexander Shherbakov. Единственная функция для работы с иконкой Shell_NotifyIcon. Ее описание на VB выглядит так: Declare Function Shell_NotifyIcon Lib "shell32.dll" Alias "Shell_NotifyIconA" _ (ByVal dwMessage As dwMess, lpData As NOTIFYICONDATA) 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.TwipsPerPixelX Как же узнать, что событие произошло с иконкой, а не с формой? Просто, по значению Y, равному нулю. Но есть и другой способ, если используется двухкнопочная мышь то параметр Button в событиях MouseDown и MouseUp формы, будет принимать значения 1 и 2, и при uCallbackMessage равно WM_MBUTTONDOWN=&H207 или WM_MBUTTONUP = &H208 Button равен 4, если событие с иконкой. Само собой разумеется, что возвращаемые X значения следуют одно за другим, как и события (Down->Up->bClick),поэтому невозможно на одну кнопку мыши назначить два события, к примеру, 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 для иконки указанной параметром lpIconName в библиотеке. Этот параметр может быть String или Long, в зависимости от данного вами наименования в Res файле, соответственно надо изменить декларацию. Можно передать и число как строку, для этого перед числом ставится знак #, а все это берется в кавычки. Следует заметить, что использование срокового параметра не желательно из за значительно большего размера занимаемой памяти и соответственно, большего времени на передачу параметра. Функция возвращает ноль в случае ошибки Понадобится так же функция: Declare Function FreeLibrary Lib "kernel32" (ByVal hLibModule As Long) As Long Выгружающая библиотеку из памяти. Параметр hLibModule это hInstanse, возвращаемое LoadLibrary. Возвращает ноль в случае ошибки. Обязательно надо не забыть выгрузить из памяти библиотеку, для освобождения памяти. Выгрузку можно произвести сразу же после добавления иконки в SystemTray. Обязательно надо не забыть выгрузить из памяти библиотеку, для освобождения памяти. Выгрузку можно произвести сразу же после добавления иконки в SystemTray. Declare Function GetModuleHandle Lib "kernel32" Alias "GetModuleHandleA" _ (ByVal lpModuleName As String) As Long Возвращающей hInstanse нашего приложения. В качестве lpModuleName передается имя EXE файла с расширением. Следует быть внимательным, так как имя процесса в TaskMenager не всегда соответствует имени процесса для Windows. Я использую для определения имени DLLView, можно воспользоваться, встроенным в VB System Information. Функция возвращает действительное значение только при работе скомпилированного приложения, а в режиме отладки возвращает ноль, ведь реального процесса при отладке не существует. Свойство hInstanse объекта App всегда возвращает действительное значение, однако при отладке из за отсутствия процесса LoadIcon возвращает 0, и создается "пустая" иконка, тем не менее годная для отладки (реагирующая на все события). Полученное hInstanse передаем LoadIconA, в качестве lpIconName указываем н
Ответить
|