Лекция № 10-1 Дочернее...
TRANSCRIPT
111
Презентация не содержит весь
материал лекции. И, поэтому, не
может заменить посещение лекции
студентом
Лекция № 10-1Дочернее окно
1. Основы создания дочернего окна
2. Создание кнопок через функцию CreateWindowEx
3. Кнопки разного типа
4. Использование строки состояния Status Bar
5. Створення кнопки через BmpButton изmasm32lib
Лектор: к.т.н., проф. НТУ ХПИ Рысованый Александр Николаевич
[email protected], http://blogs.kpi.kharkov.ua/v2/asm/
«Системное программирование»
НАЦИОНАЛЬНЫЙ ТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ
“Харьковский политехнический институт”
Кафедра “Вычислительная техника и программирование”
Литература:
1. Рисований О.М. Системне програмування [Текст]: підручник для студентів напрямку “Комп'ютерна
інженерія” вищих навчальних закладів в 2-х томах. Том 1. – Видання четверте: виправлено та доповнено
– Х.: “Слово”, 2015. – 576 с.
2. Рисований О.М. Системне програмування [Текст]: підручник для студентів напрямку “Комп'ютерна
інженерія” вищих навчальних закладів в 2-х томах. Том 2. – Видання четверте: виправлено та доповнено
– Х.: “Слово”, 2015. – 368 с.
3. http://blogs.kpi.kharkov.ua/v2/asm/knigi/
Дочірнє вікно – це таке вікно, яке використовує дочірні
елементи керування діалогового вікна (кнопки (buttons),
прапорці (check boxes), перемикачі (radio buttons), текст
(text strings), смуги прокрутки (scroll bars), вікна
редагування (edit boxes), списки (list boxes)).
Таблиця Стандартні органи управління
Орган
управління
Ім’я
класу
Стиль
вікна
Коди
сповіщення
Повідомлення для органу
управленія
Кнопка “button” BS_* BN_* BM_*
Статичне вікно “static” SS_* STN_* STM_*
Смуга перегляду “scrollbar” SBS_* SB_* SBM_*
Простій редактор тексту “edit” ES_* EN_* EM_*
Простій список вибору “listbox” LBS_* LBN_* LB_*
Список вибору з вікном
редагування
“combo-
box”
CBS_* CBN_* CB_*
2
1. Основи створення дочірнього вікна
к.т.н., проф. НТУ ХПИ Рысованый Александр Николаевич, [email protected]
Для створення дочірнього вікна використовується функція CreateWindowEx.
3
2. Створення кнопок через функцію CreateWindowEx
Функція CreateWindowEx має такий вигляд:invoke CreateWindowEx, \ ; створення вікна з розширеним стилем
NULL, \ ; додатковий стиль
ADDR ClassName, \ ; адреса імені класу
ADDR AppName, \ ; адреса імені вікна
WS_OVERLAPPEDWINDOW,\ ; базовий стиль
CW_USEDEFAULT, \ ; горизонтальна координата вікна
CW_USEDEFAULT, \ ; вертикальна координата вікна
CW_USEDEFAULT, \ ; ширина вікна
CW_USEDEFAULT, \ ; висота вікна
NULL, \ ; дескриптор батьківського вікна
NULL, \ ; дескриптор меню
hInstance, NULL ; дескриптор програми
Для определения стиля окна используются символические константы с
префиксом WS_, определенные в файле windows.h. С помощью этих констант
можно определить примерно два десятка стилей окна, однако чаще всего
используются несколько основных стилей:
Cтили не всегда совместимы друг с другом. Например, перекрывающееся окно не может
быть одновременно еще и временным.
invoke CreateWindowEx,NULL, ADDR ButtonClassName,ADDR ButtonText,WS_CHILD or WS_VISIBLE or
BS_DEFPUSHBUTTON, 190,10,15,15,hWnd,ButtonID,hInstance,NULL
к.т.н., проф. НТУ ХПИ Рысованый Александр Николаевич, [email protected]
4
Пользуясь приведенной
таблицей, можно определить
совместимость стилей. В этой
таблице символом "+"
отмечены стили, которые
можно использовать для
создания перекрывающихся,
временных и дочерних окон.
Базовый стиль дочерних
окон определяется при
помощи константы
WS_CHILD.
к.т.н., проф. НТУ ХПИ Рысованый Александр Николаевич, [email protected]
5
Для введення або виведення інформації (так званого контрола)
використовується функція CreateWindowEx з ім’ям Edit.
А при створенні кнопки у функції CreateWindowsEx необхідно вказувати
ім’я Button.
invoke CreateWindowEx,NULL, ADDR ButtonClassName, ADDR ButtonText,\
WS_CHILD or WS_VISIBLE or BS_DEFPUSHBUTTON,\
6,10,15,15,hWnd,ButtonID,hInstance,NULL
mov hwndButton,eax
Дочірнє вікно при натисненні на кнопку посилає повідомлення
WM_COMMAND батьківському вікну зі своїм ідентифікатором ID у
молодшому слові wParam, з кодом повідомлення в старшому слові wParam та з
її хендлом в параметрі lParam. При відпусканні миші кнопка посилає
батьківському вікну повідомлення WM_COMMAND з кодом повідомлення
BN_CLICKED.
Батьківське вікно також може посилати команди дочірнім вікнам,
викликаючи функцію SendMessage. Функція SendMessage відсилає
повідомлення із значеннями в wParam та lParam вікну, чий хендл передається
функції.
Тому після створення дочірніх вікон батьківське вікно повинне обробляти
повідомлення WM_COMMAND для аналізу кодів повідомлення від дочірніх
вікон. к.т.н., проф. НТУ ХПИ Рысованый Александр Николаевич, [email protected]
Створення кнопки у вікні полягає у створенні дочірнього вікна як нового
вікна за допомогою функції у повідомленні WM_CREATE:
invoke CreateWindowEx,NULL, ADDR ButtonClassName,\
\ADDR ButtonText,WS_CHILD or WS_VISIBLE or BS_DEFPUSHBUTTON,
190,10,15,15,hWnd,ButtonID,hInstance,NULL
Перший параметр – 0 – reserve;
Другий параметр – ADDR ButtonClassName - ButtonClassName db "button",0
Третій – ADDR ButtonText – текст у кнопці
Четвертий – видимість та дочірність:
BS_DEFPUSHBUTTON – різновид кнопки:
BS_DEFPUSHBUTTON – звичайна
BS_RADIOBUTTON – радіо кнопка
BS_AUTOCHECKBOX – у виді галки
П’ятий та шостий параметри – координати положення
Сьомий та восьмий – розмір кнопки
Дев'ятий – hWnd – дескриптор материнського вікна
Десятий – ButtonID – IDM-ідентифікатор
Одинадцятий – hInstance – параметр материнського вікна
Дванадцятий – має бути 0. 6
к.т.н., проф. НТУ ХПИ Рысованый Александр Николаевич, [email protected]
Використання кнопки checkbox
Checkbox з погляду програмування є кнопкою. Як стиль у функції CreateWindows
треба вказати BS_AUTOCHECKBOX (в цьому випадку галочка в checkbox’е
автоматично ставитиметься / забиратися) або BS_CHECKBOX (в цьому випадку
галочка сама ставитися не буде - і це буде завдання програміста).
Приклад створення checkbox у функції WinMain після виклику CreateWindow для
головного вікна може бути таким:
invoke CreateWindowEx,NULL, addr button_class, addr button_title ,\
WS_CHILD OR WS_VISIBLE OR BS_AUTOCHECKBOX,\
10, 60, 160, 50, hwnd, checkbox_iden, hInstance, NULL
7
3. Кнопки різного типу
к.т.н., проф. НТУ ХПИ Рысованый Александр Николаевич, [email protected]
Використання радіокнопок
Фрагмент коду створення трьох радіо кнопок може бути таким:
...
invoke CreateWindowEx,NULL, addr button_class, addr auto1,\
WS_CHILD OR WS_VISIBLE OR BS_AUTORADIOBUTTON,\
10,120, 150,30 , hwnd, radiobutton1, hInstance, NULL
invoke CreateWindowEx,NULL, addr button_class, addr auto2,\
WS_CHILD OR WS_VISIBLE OR BS_AUTORADIOBUTTON,\
10,145, 150,30 , hwnd, radiobutton2, hInstance, NULL
invoke CreateWindowEx,NULL, addr button_class, addr auto3,\
WS_CHILD OR WS_VISIBLE OR BS_AUTORADIOBUTTON,\
10,170, 150,30 , hwnd, radiobutton3, hInstance, NULL
Радіокнопки створюються подібно до звичайних кнопок - для цього треба
викликати функцію CreateWindows, вказавши в потрібному місці стиль
BS_AUTORADIOBUTTON (або BS_RADIOBUTTON
8
к.т.н., проф. НТУ ХПИ Рысованый Александр Николаевич, [email protected]
invoke CreateWindowEx,NULL, ADDR ClassName,\
ADDR ClassName, WS_OVERLAPPEDWINDOW,\
0, 0,\ ; горизизонтальні та вертикальні координати вікна
450,300,NULL,NULL, hInstance,NULL
mov hwnd,eax
invoke ShowWindow, hwnd,SW_SHOWNORMAL
; Создаём кнопку
invoke CreateWindowEx,NULL, addr button_class, addr button_title1 ,\
WS_CHILD OR WS_VISIBLE OR BS_PUSHBUTTON,\
10, 20, 150, 30, hwnd, button_iden, hInstance, NULL
; Создаём чекбокс
invoke CreateWindowEx,NULL, addr button_class, addr button_title2 ,\
WS_CHILD OR WS_VISIBLE OR BS_AUTOCHECKBOX,\
10, 60, 150, 50, hwnd, checkbox_iden, hInstance, NULL
; Создаём радиокнопки
invoke CreateWindowEx,NULL, addr button_class, addr button_title3,\
WS_CHILD OR WS_VISIBLE OR BS_AUTORADIOBUTTON,\
10,120, 150,30 , hwnd, radiobutton1, hInstance, NULL
invoke CreateWindowEx,NULL, addr button_class, addr button_title3,\
WS_CHILD OR WS_VISIBLE OR BS_AUTORADIOBUTTON,\
10,145, 150,30 , hwnd, radiobutton2, hInstance, NULL
invoke CreateWindowEx,NULL, addr button_class, addr button_title3,\
WS_CHILD OR WS_VISIBLE OR BS_AUTORADIOBUTTON,\
10,170, 150,30 , hwnd, radiobutton3, hInstance, NULL9
к.т.н., проф. НТУ ХПИ Рысованый Александр Николаевич, [email protected]
.ELSEIF uMsg==WM_COMMAND
mov eax,wParam
.IF ax==IDM_HELLO
invoke MessageBox,0,addr Hello_string,offset MenuName,MB_OK
.ELSEIF ax==IDM_CHECKED
.IF (menuchecked==1)
invoke CheckMenuItem,hMainMenu, IDM_CHECKED, MF_UNCHECKED
.ELSE
invoke CheckMenuItem,hMainMenu, IDM_CHECKED, MF_CHECKED
.ENDIF
xor menuchecked,1
10
к.т.н., проф. НТУ ХПИ Рысованый Александр Николаевич, [email protected]
xor menuchecked,1
.ELSEIF ax==10000 ; обрабатываем кнопку
invoke MessageBox,0,addr About_string,offset MenuName,MB_OK
.ELSEIF ax==10001 ; обрабатываем чекбокс
invoke GetDlgItem,hwnd,10001
mov hwndCheck,eax
invoke SendMessage, hwndCheck, BM_GETCHECK, 0, 0
mov BX,AX
.IF (BX==BST_CHECKED) ; если нажат, то меняем заголовок на Checked
invoke SetWindowText,hwnd, addr txt1
.ENDIF
.IF (BX==BST_UNCHECKED) ; если снят, то меняем заголовок на Unchecked
invoke SetWindowText,hwnd, addr txt2
.ENDIF
.ELSEIF ax==10002 ; меняем заголовки окна при выборе радиокнопки
invoke SetWindowText,hwnd, addr button_title3_1
.ELSEIF ax==10003
invoke SetWindowText,hwnd, addr button_title3_2
.ELSEIF ax==10004
invoke SetWindowText,hwnd, addr button_title3_3
.ELSE
invoke DestroyWindow,hWnd
.ENDIF 11
к.т.н., проф. НТУ ХПИ Рысованый Александр Николаевич, [email protected]
12
x0 dd ?
y0 dd ?
x1 dd 400
y1 dd 300
invoke GetSystemMetrics,SM_CXSCREEN ; отримання ширини екрана в пікселях
shr eax, 1
mov ebx, x1
shr ebx, 1
sub eax, ebx
mov x0, eax
invoke GetSystemMetrics,SM_CYSCREEN ; отримання висоти екрана пікселях
shr eax, 1
mov ebx, y1
shr ebx, 1
sub eax, ebx
mov y0, eax
invoke CreateWindowEx,NULL, ADDR ClassName,\
ADDR ClassName, WS_OVERLAPPEDWINDOW,\
x0,y0,x1,y1,0,0,hInstance,NULL
Размещение окна посередине экрана монитора
к.т.н., проф. НТУ ХПИ Рысованый Александр Николаевич, [email protected]
#define IDM_HELLO 1
#define IDM_EXIT 2
#define IDM_CHECKED 3
FirstMenu MENU {
POPUP "Справка"{
MENUITEM "Про автора",IDM_HELLO
MENUITEM SEPARATOR
MENUITEM "Пункт для выбора", IDM_CHECKED
MENUITEM "Выход",IDM_EXIT
}
MENUITEM "Выход",IDM_EXIT
}
13
Файл ресурсов
#define IDR_MENU1 10000
#define IDM_ 10001
#define IDM_ 10002
#define IDM_ 10003
#define IDM_ 10004
IDR_MENU1 MENU
BEGIN
POPUP "Справка"
BEGIN
MENUITEM "Про автора",IDM_
MENUITEM "Выход",IDM_
END
MENUITEM "Выход",IDM_
END
ResEd
к.т.н., проф. НТУ ХПИ Рысованый Александр Николаевич, [email protected]
4. Використання рядка стану Status BarРядок стану (status bar) – це панель в нижній частині вікна, призначена для виведення допоміжної
інформації
14
Можно создать Statusbar либо с помощью функции CreateWindowEx на основе класса окна STATUSCLASSNAME , либо
воспользоваться специально предназначенной для этого функцией CreateStatusWindow.
В первом случае вы можете создать Statusbar, например, так:
CreateWindowEx(
0L, // расширенный стиль окна
STATUSCLASSNAME, // класс окна для Statusbar
"", // заголовок окна отсутствует
WS_CHILD | WS_BORDER | // стиль окна
WS_VISIBLE | SBARS_SIZEGRIP,
0, 0, 0, 0, // координаты, ширина, высота
hWnd, // идентификатор родительского окна
(HMENU)IDS_STATUSBAR, // идентификатор Statusbar
hInst, // идентификатор приложения
NULL ); // доп. данные для окна
Стиль SBARS_SIZEGRIP - выделен правый нижний угол
Во втором случае вызывается функция CreateStatusWindow , прототип которой приведен ниже:
HWND CreateStatusWindow(
LONG style, // стиль окна
LPCTSTR lpszText, // текст для первой области Statusbar
HWND hwndParent, // идентификатор родительского окна
UINT wID // идентификатор Statusbar
);
Обычно создание органов управления Statusbar и Toolbar выполняется приложением при обработке функцией главного окна
сообщения WM_CREATE.
Если при создании Statusbar использовать стиль CCS_TOP , то окно Statusbar будет расположено в верхней части
родительского окна. Очевидно, этот стиль нельзя комбинировать со стилем SBARS_SIZEGRIP , так как во-первых, такой орган
управления будет выглядеть очень странно, а во-вторых, он не будет работать так, как этого ожидает пользователь.
http://frolov-
lib.ru/books/bsp/v22/ch2_2.html
- разделение Statusbar на области
к.т.н., проф. НТУ ХПИ Рысованый Александр Николаевич, [email protected]
15
Для виведення простого рядка стану з однією панеллю необхідно зробити в
програмі додавання такі, як наприклад:
include \masm32\include\comctl32.inc
includelib \masm32\lib\comctl32.lib
…
IDC_STATUS equ 6
Msg2 db " Строка состояний НТУ ХПІ"
…
invoke InitCommonControls ; реєструє і ініціалізує загальні контрольні
; віконні класи
…
.ELSEIF uMsg==WM_CREATE ;
invoke CreateStatusWindow,WS_CHILD+WS_VISIBLE,addr Msg2,hWnd,
IDC_STATUS
к.т.н., проф. НТУ ХПИ Рысованый Александр Николаевич, [email protected]
16
Замечание №1: функция CreateStatusWindow является устаревшей, и пользоваться ей не
рекомендуется. Вместо нее используется CreateWindow: код C++
hStatusWindow = CreateWindow(STATUSCLASSNAME, L"",
WS_CHILD | WS_VISIBLE | WS_BORDER | SBARS_SIZEGRIP | CCS_BOTTOM,
0, 0, 0, 0, hwnd, (HMENU)wID, hInstA, NULL);
Замечание №2: чтобы WM_PAINT не затирала строку состояния, надо использовать связку
BeginPaint/EndPaint
Замечание №3: чтобы при изменении размеров окна изменялось также расположение статусбара -
надо переслать ему сообщение:
код C++
case WM_SIZE:
SendMessage(hStatusWindow, WM_SIZE, 0, 0);
break;
Если в статусбаре несколько частей - то пересчитывать их размеры нужно здесь же, в обработчике
WM_SIZE, и после пересчета отсылать статусбару еще и SB_SETPARTS.
к.т.н., проф. НТУ ХПИ Рысованый Александр Николаевич, [email protected]
Функция BmpButton необходима для создания кнопки из двух BMP-файлов. В начальном
состоянии отображается один BMP рисунок, а при нажатии на эту кнопку - второй. Эта
функция по координатам х и y загружает BMP рисунки и идентифицирует их своими ID
номерами. При нажатии на кнопку загружается второе изображение и посылается сообщение
WM_COMMAND с параметром ID этого контрола. По этому ID контролу в wParam проводятся
действия по обработку этого нажатия. Функция BmpButton расположенная в библиотеке
masm32lib, а описана в masm32\help\masmlib.Функция BmpButton имеет синтаксис :
hParent:DWORD, \ ; хендл вікна, в якому обробляється WM_COMMAND
topX:DWORD, \ ; х-координата кнопки
topY:DWORD, \ ; y-координата кнопки
rnum1:DWORD, \ ; ресурс ID для UP точечного рисунка bmp1
rnum2:DWORD, \ ; ресурс ID для DOWN точечного рисунка bmp2
ID:DWORD ; ідентифікаційний номер, який приписується контролю
5. Создание кнопки через BmpButton изmasm32lib
Наприклад:
Uselib masm32;
…
win32asm dd 0 ; початкове встановлення тригеру натискання на кнопку
…
.IF uMsg==WM_INITDIALOG ;
invoke SendMessage,hWin,WM_SETICON,1,FUNC(LoadIcon, 0, IDI_ASTERISK)
invoke BmpButton, hWin, 32, 40, 203, 204, 2;
.ELSEIF uMsg==WM_COMMAND ;
…
.ELSEIF wParam==2 ;
inc win32asm
.if win32asm == 1
invoke MessageBox,0,addr szInf0,addr szTitle0,MB_ICONINFORMATION
mov win32asm,0
.endif
Фрагмент файлу ресурсів може бути таким:
203 BITMAP MOVEABLE PURE LOADONCALL DISCARDABLE "up_11.BMP"
204 BITMAP MOVEABLE PURE LOADONCALL DISCARDABLE "up_22.BMP"
17
к.т.н., проф. НТУ ХПИ Рысованый Александр Николаевич, [email protected]
18
Программа DeKnop представляет собой
графический редактор, который предназначен для
создания кнопок. Программа позволяет выбирать
шрифт текста, цвета, 3D формы, размеры,
градиенты и многие другие аспекты.
Изображения кнопки могут быть сохранены в
PNG, JPG, BMP или GIF формате. DeKnop также
поддерживает проекты, что позволяет сохранить
свою работу и продолжить его позднее или
повторное использовать на другую работу.
Особенности
* создание множества вариантов кнопок
* префиксы и суффиксы для имен создаваемых
файлов
* градиенты
* стиль текста: поднят или встраиваемые
* 3D вид
* глянцевая границы
* перетаскивание (drag and drop) цвета
* лупа и определитель цвета (Color Picker)
* сохранить кнопки в форматы PNG, JPG, GIF
* текстуры для кнопки и текста
* предопределенный путь для загрузки из /
сохранить
* прозрачность цвета, анти псевдоним шрифт
Программа DeKnop
к.т.н., проф. НТУ ХПИ Рысованый Александр Николаевич, [email protected]
19
Задание:
Відобразити вікно з включенням BMP-файлу зі своєю фотографією та іконкою
для вікна. В якості іконки теж взяти свою фотографію. Розмір вікна повинен
відповідати розміру BMP-файлу. Створити меню та відобразити у вікні свої
прізвище, навчальну групу та електронну адресу. Створити кнопки з використанням
BMP-файлів та з надписом на одній з кнопок свого прізвища. Використати функцію
MessageBoxIndirect з відображенням в якості власної іконки своєї фотографії.
Задание:
http://frolov-lib.ru/books/bsp/v22/ch2_2.html
- разделение Statusbar на области
к.т.н., проф. НТУ ХПИ Рысованый Александр Николаевич, [email protected]
2020202020202020
«Системное программирование»
к.т.н., проф. НТУ ХПИ Рысованый Александр Николаевич,
личный сайт: http://blogs.kpi.kharkov.ua/v2/asm/
НАЦИОНАЛЬНЫЙ ТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ
“Харьковский политехнический институт”
Кафедра “Вычислительная техника и программирование”