API и FreeBasic. (замена стиля окна часть 1)
Создав окно, может так получиться, что нужно будет поменять его атрибуты в процессе выполнения программы. Многие установленные вами поля структуры WNDCLASSEX можно менять. Для этого существуют великолепные функции SetWindowLong (изменение атрибутов для одного окна) и SetClassLong(изменение атрибутов для всех окон класса). У каждой из них три параметра. Давайте рассмотрим для функции SetClassLong:
- hWnd - хендл окна, у которого следует делать замену атрибута
- nIndex - индекс заменяемого атрибута, может быть:
- GCL_CBCLSEXTRA Устанавливает размер дополнительной памяти, связанной с классом, в байтах.
- GCL_CBWNDEXTRA Устанавливает размер дополнительной памяти окна, связанной с каждым окном в классе, в байтах. Установка этого значения не изменяет число дополнительных байт, назначенных ранее. За информацией о том, как получить доступ к этой памяти, обратитесь к функции GetWindowLong.
- GCL_HBRBACKGROUND Заменяет дескриптор кисти фона, связанной с классом.
- GCL_HCURSOR Заменяет дескриптор курсора, связанного с классом.
- GCL_HICON Заменяет дескриптор значка, связанного с классом.
- GCL_HICONSM Заменяет дескриптор маленького значка, связанного с классом.
- GCL_HMODULE Заменяет дескриптор модуля, который зарегистрировал класс.
- GCL_MENUNAME Заменяет адрес строки с именем меню. Строка идентифицирует ресурс меню, связанный с классом.
- GCL_STYLE Заменяет данные о битах стиля класса окна.
- GCL_WNDPROC Заменяет адрес оконной процедуры связанной с классом .
- dwNewLong - новый атрибут
А теперь для функции SetWindowLong:
- hWnd - хендл окна, у которого следует делать замену атрибута
- nIndex - индекс заменяемого атрибута, может быть:
- GWL_EXSTYLE - Устанавливает новый расширенный стиль окна.
- GWL_STYLE - Устанавливает новый стиль окна.
- GWL_WNDPROC - Устанавливает новый адрес для оконной процедуры.
- GWL_HINSTANCE - Устанавливает новый дескриптор экземпляра прикладной программы.
- GWL_ID - Устанавливает новый идентификатор окна.
- GWL_USERDATA - Устанавливает 32-разрядное значение, связанное с окном.
Каждое окно имеет соответствующее 32-разрядное значение, предназначенное для
использования прикладной программой, которая создала окно.
Следующие значения также доступны, когда параметр hWnd идентифицирует диалоговое окно:
- DWL_DLGPROC - Устанавливает новый адрес процедуры диалогового окна.
- DWL_MSGRESULT - Устанавливает возвращаемое значение сообщения, обработанного в процедуре диалогового окна
- DWL_USER - Устанавливает новую дополнительную информацию, которая является частной для прикладной программы, типа дескрипторов или указателей.
- dwNewLong - новый атрибут
Функции возвращают старый атрибут. Так если мы назначим окну новый цвет с помощью кисти, функция вернет нам старую кисть, на случай желаемого возврата старого цвета.
А теперь давайте с помощью этих функций превратим рассмотренное нами ранее диалоговое окно класса #32770 в практически полноценное окно. Ведь разница была только в обработке сообщений. То есть нам нужно создать свою процедуру и с помощью SetWindowLong установить для диалогового окна новую процедуру. В результате мы уже сами будем отвечать за обработку сообщений этого окна. А так же поменяем цвет окна. Ведь в нащей процедуре нет ограничений на используемый цвет диалога(в отличии от системной процедуры)
#INCLUDE "windows.bi" Dim msg As MSG 'структурированная переменная MSG Dim hwnd As HWND 'хендл окна Dim hbr As HBRUSH 'кисть ' функция класса Function wndproc(hwnd As HWND, msg As Uinteger, wparam As WPARAM, lparam As LPARAM) As Integer Select Case msg Case WM_DESTROY PostQuitMessage(0) End Select Return DefWindowProc(hwnd,msg,wparam,lparam) End Function 'Создание окна hwnd=CreateWindowEx(0,"#32770","Первое окно",WS_VISIBLE Or WS_OVERLAPPEDWINDOW, _ 100,100,300,300,0,0,0,0) 'Заменяем процедуру на свою SetWindowLong(hwnd,GWL_WNDPROC,Cast(Long,@wndproc)) 'Создаем кисть синего цвета hbr=CreateSolidBrush(&hff0000) 'Меняем цвет окна SetClassLong(hwnd,GCL_HBRBACKGROUND,Cast(Long,hbr)) 'Перерисовываем окно InvalidateRect (hwnd,NULL,TRUE) 'Обработка сообщений в цикле While GetMessage(@msg,0,0,0) DispatchMessage(@msg) Wend 'удаляем кисть DeleteObject(hbr)
В данном примере мы создали кисть с помощью CreateSolidBrush , у которой
один параметр: значение цвета в формате BGR (BLUE , GREEN, RED). А далее
передали созданную нами кисть в 3 параметр функции SetClassLong , а во втором
параметре передали индекс GCL_HBRBACKGROUND. Для того, чтобы изменения вступили
в силу немедленно, окно надо перерисовать. Это мы сделали с помощью функции
InvalidateRect. Она имеет три параметра:
- hWnd - хендл окна, которое надо перерисовать
- lpRect - прямоугольник перерисовки, если 0, то всю область окна
- bErase - режим перерисовки. Если 1 , то стирать фон, если 0, то не стирать
Для замены процедуры мы использовали функцию SetWindowLong, у которой во втором параметре передали атрибут GWL_WNDPROC , а в третьем адрес нашей процедуры. Для замены процедуры мы не можем применить функцию SetClassLong, поскольку она меняет процедуру только для следующих созданных окон с этим классом.
Очень часто требуется дополнить стиль окна. Делается это с помощью двух функций GetWindowLong и SetWindowLong. У функции GetWindowLong имеющиеся два параметра такие же как два первых параметра SetWindowLong. Ее назначение - получать значения заданного атрибута. В примере ниже, для изменения стиля окна, надо щелкнуть левой кнопкой мыши по клиентской области окна.
#INCLUDE "windows.bi" Dim msg As MSG 'структурированная переменная MSG Dim hwnd As HWND 'хендл окна Dim Shared style As Integer ' стиль окна ' функция класса Function wndproc(hwnd As HWND, msg As Uinteger, wparam As WPARAM, lparam As LPARAM) As Integer Select Case msg Case WM_LBUTTONDOWN ' получаем стиль нашего окна style=GetWindowLong(hwnd,GWL_STYLE) ' установим новый стиль нашего окна SetWindowLong(hwnd,GWL_STYLE,style Or WS_OVERLAPPEDWINDOW) Case WM_DESTROY PostQuitMessage(0) End Select Return DefWindowProc(hwnd,msg,wparam,lparam) End Function 'Создание окна hwnd=CreateWindowEx(0,"#32770","Первое окно",WS_VISIBLE,100,100,300,300,0,0,0,0) 'Заменяем процедуру на свою SetWindowLong(hwnd,GWL_WNDPROC,Cast(Long,@wndproc)) 'Обработка сообщений в цикле While GetMessage(@msg,0,0,0) DispatchMessage(@msg) Wend
В примере сначала создается окно со стилем видимое, но без кнопочек
(свернуть, максимизировать и закрыть). Далее в оконной процедуре сделан
обработчик левой кнопки мыши. В результате нажатия левой кнопки мышки,
происходит изменение стиля окна и появляется возможность закрыть окно. Как вы
поняли, мы попросту получили имеющийся стиль с помощью GetWindowLong и
объединили его с новым стилем при помощи функции SetWindowLong и оператора
OR.
И конечно давайте поменяем курсор и иконку у окна:
#INCLUDE "windows.bi" Dim msg As MSG 'структурированная переменная MSG Dim hwnd As HWND 'хендл окна Dim Shared style As Integer ' стиль окна ' функция класса Function wndproc(hwnd As HWND, msg As Uinteger, wparam As WPARAM, lparam As LPARAM) As Integer Select Case msg Case WM_DESTROY PostQuitMessage(0) End Select Return DefWindowProc(hwnd,msg,wparam,lparam) End Function 'Создание окна hwnd=CreateWindowEx(0,"#32770","Первое окно",WS_VISIBLE Or WS_OVERLAPPEDWINDOW,100,100,300,300,0,0,0,0) 'Заменяем процедуру на свою SetWindowLong(hwnd,GWL_WNDPROC,Cast(Long,@wndproc)) ' загружаем иконку и курсор Var icon=LoadIcon(0,IDI_EXCLAMATION) Var cursor=LoadCursor(0,IDC_CROSS) ' устанавливаем иконку и курсор SetClassLong(hwnd,GCL_HICON,icon) SetClassLong(hwnd,GCL_HCURSOR,cursor) 'Обработка сообщений в цикле While GetMessage(@msg,0,0,0) DispatchMessage(@msg) Wend
В следующей статье мы рассмотрим как можно сделать окно полупрозрачным, а
так же как сделать окно поверх всех окон. Всего доброго!
содержание | назад | вперед