API и FreeBasic. (дочерние окна-гиперссылки)
Microsoft создавала свои контролы исходя из первоначальной задачи: сделать их простыми. И можно сказать им это удалось, но все же есть вещи в которых они не преуспели. Одна из них это контрол SysLink. Для того чтобы использовать этот контрол, нужно обязательное включение стиля XP (нужен файл manifest.xml в ресурсах программы) . Зависимость одного от другого не есть хорошо, поскольку включение стиля не даст использовать ручные установки цвета для некоторых других контролов( напр. Tooltip). Даже если вас устроит включение манифеста, все равно убогий вид контрола у которого при наведении не меняется ни вид курсора ни цвет ссылки, вряд ли порадует. Именно поэтому разработчики прибегнули к простому, но эффективному способу: изготовить контрол самим вручную. Главное что потребуется, это контрол Static. Я не буду останавливаться на вопросе , касающегося изменения цвета, поскольку для цвета и шрифтов решил написать отдельные статьи. Но остальное в примере постараюсь объяснить. И так пример:
#INCLUDE "windows.bi" #INCLUDE Once "win/shellapi.bi" Dim msg As MSG 'структурированная переменная MSG Dim As WNDCLASSEX wc 'структурированная переменная WNDCLASSEX Dim As String NameClass="MyClass" ' переменная имени класса Dim As HINSTANCE Hinst=GetModuleHandle(0) ' хендл модуля Function IsMouseOver(Byval wnd As HWND) As Integer Export Dim As RECT re Dim As Point pt GetWindowRect(wnd,@re) GetCursorPos(@pt) If pt.x<re.left Then Return 0 If pt.x>re.right Then Return 0 If pt.y<re.top Then Return 0 If pt.y>re.bottom Then Return 0 Return 1 End Function ' функция класса Function wndproc(hwnd As HWND, msg As Uinteger,_ wparam As WPARAM, lparam As LPARAM) As Integer Static As Integer a,col=&hff Static Hyper As HWND Static hBrush As HBRUSH=1 Select Case msg Case WM_MOUSEMOVE If IsMouseOver(Hyper) Then SetCursor(LoadCursor(0,IDC_HAND)) If a=0 Then col=&hff0000 InvalidateRect(Hyper,0,1) a=1 Endif Else If a=1 Then col=&h0000ff InvalidateRect(Hyper,0,1) a= 0 Endif Endif Case WM_CTLCOLORSTATIC DeleteObject(hBrush) hBrush= CreateSolidBrush(&hffffff) SetBkColor(Cast(HDC,wparam),&hffffff) SetTextColor(Cast(HDC,wParam),col) Return Cast(Long,hBrush) Case WM_DESTROY PostQuitMessage(0) Case WM_CREATE Hyper=CreateWindowEx(0, "Static", "Перейти на сайт",_ WS_VISIBLE Or WS_CHILD,30,20,120,20, hwnd, Cast(HMENU,1), 0, 0) Case WM_LBUTTONDOWN If IsMouseOver(Hyper) Then ShellExecute(0,@"Open" , @"http://users.freebasic-portal.de/freebasicru/","","" ,1 ) col=&hff InvalidateRect(Hyper,0,1) Endif End Select Return DefWindowProc(hwnd,msg,wparam,lparam) End Function ' Заполнение структуры WNDCLASSEX With wc .cbSize=SizeOf(WNDCLASSEX) .style=CS_HREDRAW Or CS_VREDRAW .lpfnWndProc=@wndproc .hInstance=Hinst .hIcon=LoadIcon(0,IDI_WINLOGO) .hCursor=LoadCursor(0,IDC_ARROW) .hbrBackground=Cast(HBRUSH,COLOR_WINDOWFRAME) .lpszClassName=StrPtr(NameClass) .hIconSm=.hIcon End With ' Регистрация класса окна If RegisterClassEx(@wc)=0 Then Print "Register error, press any key" Sleep End Endif 'Создание окна CreateWindowEx(0,NameClass,"HyperLink",_ WS_VISIBLE Or WS_OVERLAPPEDWINDOW,100,100,200,100,0,0,Hinst,0) ' Цикл сообщений While GetMessage(@msg,0,0,0) TranslateMessage(@msg) DispatchMessage(@msg) Wend
Вот что примерно должно получится:
- В сообщении WM_CREATE создаем обычный контрол Static.
- В сообщении WM_MOUSEMOVE отлавливаются перемещения мыши.Для того, чтобы
определить находится или нет мышь над контролом Static, создана
специальная функция IsMouseOver, которая вернет единичку при положительном
результате. В этой процедуре уже знакомые нам по прошлым статьям две
структуры RECT и POINT, а так же функция GetWindowRect ,
определяющая координаты окна. Незнакомая до сих пор функция GetCursorPos,
имеющая в своем параметре адрес на структуру POINT, как наверно ясно из
названия, определяет позицию курсора и сохраняет результат в структуре POINT.
Далее идет банальное сравнение соответствия результатов координат. После
определения соответствия координат, в одном из случаев загружаем курсор
изображения руки с помощью LoadCursor и устанавливаем его с помощью SetCursor.
Описание этих функций:
- LoadCursor(
HINSTANCE hInstance, // Дескриптор экземпляра модуля
LPCTSTR lpCursorName // Указатель на строку с ресурсом или предопределенный системой курсор
); - SetCursor(
HCURSOR hCursor // загруженный курсор с помощью LoadCursor
);
- LoadCursor(
- Сообщение WM_CTLCOLORSTATIC отвечает за цвет контрола Static. И как я и говорил, рассматривать его сейчас не будем
- В сообщении WM_LBUTTONDOWN (нажатие на левую кнопку мыши) так же
определяется расположение при нажатии с помощью IsMouseOver и с помощью
ShellExecute запускаем страницу интернета. Функция ShellExecute очень мощная и
многофункциональная, способная запускать любые файлы с
указанием параметров командной строки и директории по
умолчанию. Вот ее описание:
- ShellExecute(
HWND hwnd, // указатель на окно (откуда вызвано)
LPCTSTR lpOperation, // Указатель но определенные операции для выполнения
LPCTSTR lpFile, // Указатель на имя фала или папки
LPCTSTR lpParameters, // Параметры выполнения операции
LPCTSTR lpDirectory, // Указатель на каталог по умолчанию
INT nShowCmd // Тип окна для вывода.
);
Описание ее констант и декларация находятся в файле shellapi.bi . Именно поэтому в начале файла мы включили его. Более подробно о ней можете почитать в справочнике WINAPI
- ShellExecute(
Вот собственно и все, удачи!
содержание | назад | вперед