API и FreeBasic. (дочерние окна-Up-Down)
Up-Down - контрол, чаще всего используемый для изменения числовых значений с помощью подобия scrollbar , в котором как будто вырезали саму полосу и оставили только крайние кнопки. Я ни разу не видел , чтобы его использовали в таком виде. Обычно данный контрол комбинируют с другим контролом. Больше скажу, практически во всех случаях в паре с ним идут контролы EDIT или TAB . Прикрепив таким способом, оба контрола действуют как одно целое. Что касается примеров практического использования, то я не припомню ни один графический редактор без этого контрола. В частности, изменение размеров всегда возлагают на этот контрол.
Создать комбинированный контрол (Edit+Up-Down) можно как с помощью двух функций CreateWindowEx, так и связкой CreateWindowEx + CreateUpDownControl. Второй способ я считаю чуть более удобным, поскольку позволяет в параметрах CreateUpDownControl указать минимальный и максимальный диапазоны, а так же начальное текущее значение.
Приклепляемый контрол (EDIT) создается как обычно. Его создание описывалось в этой статье. Что касается Up-Down , то он создается на базе класса msctls_updown32. Если мы его создаем после прикрепляемого контрола EDIT и в стиле контрола Up-Down укажем UDS_AUTOBUDDY , то контрол автоматически прикрепится. Если нужно прикрепить независимо от порядка создания контролов, то можно послать сообщение UDM_SETBUDDY и в параметре WPARAM передать хендл приклеплямого контрола. Для того , чтобы не канителиться с координатами , важно указать автовыравнивание контрола с помощью стилей UDS_ALIGNRIGHT или UDS_ALIGNLEFT. В этом случае контрол прикрепится справа или слева соответственно , а параметры ( x , y , nWidth , nHeight) функции CreateWindowEx можно обнулить. Кроме того, при создании обоих контролов, неплохо указать стиль WS_CLIPSIBLINGS , который не даст конролу Edit рисоваться поверх Up-Down. Если для контрола Up-Down указать стиль UDS_SETBUDDYINT , то при изменении его значений, они автоматически будут записываться в EDIT.
Функция CreateUpDownControl так же позволяющая создать Up-Down , представляет из себя удобную обертку над CreateWindowEx. В ней нет необходимости прописывать класс контрола и как я и писал есть дополнительные возможности. Декларация функции:
CreateUpDownControl(_ dwStyle As DWORD,_ 'стиль окна x As Integer,_ ' расположение по X y As Integer,_ ' расположение по Y cx As Integer,_ ' ширина окна cy As Integer,_ ' высота окна hParent As HWND,_ ' хендл родительского окна nID As Integer,_ ' идентификатор контрола Up-Down hInst As HINSTANCE,_ ' хендл приложения hBuddy As HWND,_ ' хендл приклепляемого контрола nUpper As Integer,_ ' верхняя граница диапазона значений nLower As Integer,_ ' нижняя граница диапазона значений nPos As Integer _ ' стартовое значение ) As HWND
По декларации должно быть понятно, что и куда прописывать.
Для того чтобы выставить\изменить диапазоны, нужно послать сообщение UDM_SETRANGE и в параметре LPARAM передать макрос:
MAKELPARAM(valMax, valMin)
Для того чтобы установить текущее значение, нужно послать сообщение
UDM_SETPOS (для 16х битных чисел) или UDM_SETPOS32 (для 32х битных чисел) и в
параметре LPARAM передать новое значение.
Для того чтобы получить текущее значение, нужно послать сообщение UDM_GETPOS. Параметры WPARAM и LPARAM при этом должны быть равны нулю.
Отлавливаются события контрола в сообщениях WM_VSCROLL , WM_HSCROLL (при стиле UDS_HORZ) и WM_NOTIFY. Важно отметить, что сообщение WM_NOTIFY обрабатывается в первую очередь. В результате есть возможность отменить\изменить значение до того, как придут сообщения WM_VSCROLL , WM_HSCROLL. При отлове сообщения WM_NOTIFY с кодом извщения UDN_DELTAPOS в параметре LPARAM оказывается структура NM_UPDOWN:
Type NM_UPDOWN hdr As NMHDR ' вложенная структура NMHDR , в параметре code которой проверяют извещение UDN_DELTAPOS iPos As Integer ' текущее состояние до изменения iDelta As Integer ' целое число, на которое изменится число (дельта) End Type
Из комментариев к декларации структуры должно быть все предельно ясно, но
в любом случае, в примере ниже, для понимания я использовал отлов событий.
Сообщения для контрола (расширенная инфомация ЗДЕСЬ):
- UDM_GETACCEL - Возвращает информацию для ускорения вверх-вниз
- UDM_GETBASE - Определение текущей системы счисления (десятичная или шестнадцатеричная), используемой для контрола
- UDM_GETBUDDY - Возвращает хендл , пркрепленный к контролу
- UDM_GETPOS - Возвращает текущую позицию (макс. 16-bit)
- UDM_GETPOS32 - Возвращает текущую позицию (макс. 32-bit)
- UDM_GETRANGE - Возвращает максимальный и минимальный диапазоны значений (16-bit)
- UDM_GETRANGE32 - Возвращает максимальный и минимальный диапазоны значений (32-bit)
- UDM_GETUNICODEFORMAT - Возвращает флаг определящий использования Unicode символов
- UDM_SETACCEL - Устанавливает информацию для ускорения вверх-вниз
- UDM_SETBASE - Установка текущей системы счисления (десятичная или шестнадцатеричная), используемой для контрола
- UDM_SETBUDDY - Устанавливает хендл , для приклепления к контролу
- UDM_SETPOS - Устанавливает текущую позицию (макс. 16-bit)
- UDM_SETPOS32 - Устанавливает текущую позицию (макс. 32-bit)
- UDM_SETRANGE - Устанавливает максимальный и минимальный диапазоны значений (16-bit)
- UDM_SETRANGE32 - Устанавливает максимальный и минимальный диапазоны значений (32-bit)
- UDM_SETUNICODEFORMAT - Устанавливает флаг определящий использования Unicode символов
Стили для контрола:
- UDS_ALIGNLEFT - Размещение Up-Down справа от приклепленного окна
- UDS_ALIGNRIGHT - Размещение Up-Down справа от приклепленного окна
- UDS_ARROWKEYS - Управление стрелками на клавиатуре
- UDS_AUTOBUDDY - Родительское окно выбирается автоматически
- UDS_HORZ - Горизонтальное расположение
- UDS_NOTHOUSANDS - Используется вместе со стилем
- UDS_SETBUDDYINT. Указывает, что при отображении текущего значения не нужно разделять разряды тысяч десятичной точкой
- UDS_SETBUDDYINT - Автоматически изменяется текст в приклепленном окне
- UDS_WRAP - Сквозная прокрутка - при достижении максимума, начинаем опять с нуля и наоборот
#INCLUDE "windows.bi" #INCLUDE "win/commctrl.bi" InitCommonControls() #DEFINE UDN_DELTAPOS (UDN_FIRST-1) Dim msg As MSG Dim As WNDCLASSEX wc Dim As String NameClass="MyClass" Dim As HINSTANCE Hinst=GetModuleHandle(0) Function wndproc(hwnd As HWND, msg As Uinteger,_ wparam As WPARAM, lparam As LPARAM) As Integer Static As HWND UpDown,Edit Select Case msg Case WM_CREATE Edit = CreateWindowEx(0,"edit","",WS_VISIBLE+WS_CHILD+WS_CLIPSIBLINGS,_ 10,10,80,20,hwnd,Cast(HMENU,1),0,0) UpDown = CreateWindowEx(0,"msctls_updown32","",_ WS_VISIBLE+WS_CHILD+UDS_ALIGNRIGHT+UDS_AUTOBUDDY+UDS_SETBUDDYINT+WS_CLIPSIBLINGS,_ 0,0,0,0,hwnd,Cast(HMENU,2),0,0) Case WM_NOTIFY Dim hdr As NMHDR Ptr = Cast(NMHDR Ptr,LPARAM) If hdr->code = UDN_DELTAPOS Then Dim NMUP As NM_UPDOWN Ptr = Cast(NM_UPDOWN Ptr,LPARAM) Dim iPos As Integer = NMUP->iDelta+NMUP->iPos If NMUP->iDelta+NMUP->iPos > 100 Then iPos = 100 Elseif NMUP->iDelta+NMUP->iPos <0 Then iPos = 0 Else iPos = NMUP->iDelta+NMUP->iPos Endif 'Получаем значения ? "Value before change = ";NMUP->iPos ? "Value before change = ";iPos ' Устанавливаем новое значение SendMessage(UpDown,UDM_SETPOS,0,NMUP->iPos+10) Endif Case WM_VSCROLL ? "Value in message WM_VSCROLL = ";SendMessage(UpDown,UDM_GETPOS,0,0) Case WM_DESTROY PostQuitMessage(0) End Select Return DefWindowProc(hwnd,msg,wparam,lparam) End Function With wc .cbSize=SizeOf(WNDCLASSEX) .style=CS_HREDRAW Or CS_VREDRAW .lpfnWndProc=@wndproc .hInstance=Hinst .hIcon=LoadIcon(0,IDI_QUESTION) .hCursor=LoadCursor(0,IDC_ARROW) .hbrBackground=Cast(HBRUSH,COLOR_WINDOW) .lpszClassName=StrPtr(NameClass) .hIconSm=.hIcon End With If RegisterClassEx(@wc)=0 Then Print "Register error, press any key" Sleep End Endif CreateWindowEx(0,NameClass,"Up-Down контрол",_ WS_VISIBLE Or WS_OVERLAPPEDWINDOW ,10,10,300,200,0,0,Hinst,0) While GetMessage(@msg,0,0,0) TranslateMessage(@msg) DispatchMessage(@msg) Wend
содержание | назад | вперед