ПРОГРАМУВАННЯ ЗА ДОПОМОГОЮ ФУНКЦІЙ WIN32 API (частина 2).

Інформація про навчальний заклад

ВУЗ:
Національний університет Львівська політехніка
Інститут:
Інститут комп’ютерних наук та інформаційних технологій
Факультет:
Не вказано
Кафедра:
Автоматизовані Системи Управління

Інформація про роботу

Рік:
2003
Тип роботи:
Збірник лабораторних робіт
Предмет:
Системне програмування

Частина тексту файла

Міністерство освіти та науки України
Національний університет “Львівська політехніка”
Інститут комп’ютерних наук та інформаційних технологій
Кафедра автоматизованих систем управління
EMBED Word.Picture.8

ПРОГРАМУВАННЯ ЗА ДОПОМОГОЮ ФУНКЦІЙ WIN32 API
(частина 2)
ЗБІРНИК ЛАБОРАТОРНИХ РОБІТ
Методичні вказівки
з курсу “Сиcтемне програмування та операційні системи”
для студентів базової вищої освіти
за напрямком 6.08.04 “Комп’ютерні науки”
та курсу “Операційні системи в комп’ютерній поліграфії”
для студентів базової вищої освіти
за напрямком 6.09.27 “Видавничо-поліграфічна справа”
Львів - 2003
Програмування за допомогою функцій Win32 API, част.2.
Методичні вказівки з курсу “Сиcтемне програмування та операційні системи” для студентів базової вищої освіти за напрямком 6.08.04 “Комп’ютерні науки” та курсу “Операційні системи в комп’ютерній поліграфії” для студентів базової вищої освіти за напрямком 6.09.27 “Видавничо-поліграфічна справа”, Львів, НУ “Львівська політехніка”, 2003 р.
Рецензент:
Вальковський В.О., д.ф-м.н., проф.
Укладачі: Зербіно Д.Д., канд. техн. наук, доц.,
Марцишин Р.С., канд. техн. наук, доц.
Пелешко Д.Д. канд. техн. наук, доц.,
Різник О.Я., канд. техн. наук, доц.,
Цимбал Ю.В., асистент.
Відповідальний за випуск:
Дронюк І.М. к.ф-м.н., доц.
Лабораторна робота 5
Тема – Дочірні вікна: їх утворення та взаємодія, графічний контекст.
Мета – навчитись будувати ієрархічну структуру вікон та працювати з ними.
ТЕОРЕТИЧНІ ПОЛОЖЕННЯ
Для створення вікна (див. лаб. 4) будь-який процес, в тому числі і процеси операційної системи, викликають функцію CreateWindowExA. В параметрах цієї функції необхідно вказувати координати, розмір, а також клас та стилі вікна. Класи мають певні стандартні стилі. Існують спільні для всіх класів стилі вікон, які позначаються першими символами WS_ (від англійського window styles):
Також існують стилі для кожного класу, перші символи яких подані нижче:
Кодування кожного стилю можна знайти у файлі Win119.inc.
Дочірні вікна – це вікна типу “WS_CHILD”, які існують для відображення допоміжних органів керування або довідки. Основною властивістю цих вікон є те, що вони не мають меню і не можуть бути спливаючими вікнами (WS_POPUP). Дочірні вікна, як і всі вікна, створюються функцією API “CreateWindowExA”. При створенні дочірнього вікна в параметрах обов’язково вказується його власник. Параметр, який містить для звичайних вікон хендл меню, визначає ідентифікатор дочірнього вікна.
Події, що відбуваються у дочірніх вікнах передається у батьківське вікно як параметр повідомлення “WM_NOTIFY”. Друге важливе повідомлення, яке передається у батьківське вікно від дочірнього це WM_COMMAND. Це повідомлення є основним для дочірніх вікон класу Button.
Крім цього, кожний клас дочірнього вікна має свої власні додаткові повідомлення.
Існують повідомлення, через які вікна отримують інформацію про події в системі. Наприклад, якщо ви насуваєте одне вікно на інше, то вікно, яке знаходиться під іншим отримує повідомлення WM_CTLCOLORSTATIC. Таким чином, отримавши це повідомлення, ваша програма повинна відновити інформацію у вікні. Менш коректно для цієї мети можна використовувати повідомлення WM_PAINT.
Керувати дочірніми вікнами можна так само, як і звичайними вікнами, наприклад, посилаючи до них повідомлення функцією SendMessageA. У поданій нижче програмі дочірньому вікну класу msctls_trackbar32 після його створення надсилається повідомлення TBM_SETRANGE для встановлення кількості поділок до 255 (знаходиться у старшому слові параметра повідомлення).
Кожне вікно, в тому числі і дочірнє, має спеціальну керуючу структуру даних, яка називається графічним контекстом. Вона відповідає за графічні властивості вікна, наприклад, при виводі тексту, ліній чи фону. Для отримання графічного контексту вікна використовується функція GetDC. Ця функція нагадує відкриття файлу: поки файл відкритий, змінити його може лише той процес, який його відкрив.
Кожна графічна операція використовує графічний контекст як параметр. Драйвер принтера також забезпечує графічний контекст, тому ті самі графічні операції можуть виводити дані або у вікно, або на принтер. Графічний контекст містить також інформацію про шрифт, з яким працюють графічні функції (в даній програмі – функція TextOutA ).
Перейдемо до прикладу. Перед тим, як копіювати наступну програму, уважно прогляньте її коментарі.
.386
.model flat,STDCALL
extrn InitCommonControls:Proc, GetModuleHandleA:Proc, ExitProcess:Proc
extrn CreateWindowExA:Proc, RegisterClassA:Proc, GetMessageA:Proc
extrn DispatchMessageA:Proc, DefWindowProcA:Proc, _wsprintfA:Proc
extrn GetDC:Proc, SelectObject:Proc, ReleaseDC:Proc, CreateSolidBrush:Proc
extrn Rectangle:Proc, TextOutA:Proc,SendMessageA:Proc, lstrlen:Proc
WS_CHILD EQU 40000000h
WS_POPUP EQU 80000000h
WS_VISIBLE EQU 010000000h
WS_DLGFRAME EQU 400000h
WM_KEYDOWN EQU 100h
TBS_TOP EQU 0004h
WM_NOTIFY EQU 4Eh
WM_HSCROLL EQU 114h
TBM_SETRANGE EQU 1030
;=====================================================
.data
WC dd 4003h,offset WndProc,5 dup(0),1,0,offset WndClassName
msg dd 0
msMESSAGE dd 0
msWPARAM dd 0,0,0,0,0
AppHWnd dd 0
MainHWnd dd 0
CHILD_CLASS_NAME db 'msctls_trackbar32',0
WndClassName
db "ABBA",0
COLOR dd 0
Brush dd 0
HDC dd 0
TRACK_ID dd 0
TRACK_ID1 dd 0
FORMAT db 'Колiр = %X',0
PRINT_BUF db 20 dup(0)
;=======================================================
.code
Start: call
GetModuleHandleA,0
; отримати хендл програми для створення вікна;
mov
AppHWnd,eax
call
RegisterClassA,offset WC
; зареєструвати новий клас вікон;
call CreateWindowExA,0,eax,0,WS_POPUP or WS_VISIBLE or WS_DLGFRAME, 100,50,400,410,0,0,AppHWnd,0
mov
MainHWnd,eax
call CreateWindowExA,0,offset CHILD_CLASS_NAME,0,WS_CHILD or WS_VISIBLE or TBS_TOP, 5,360,380,35,MainHWnd,0,AppHWnd,0
call
SendMessageA,eax,TBM_SETRANGE,1,255*10000h
call CreateWindowExA,0,offset CHILD_CLASS_NAME,0,WS_CHILD or WS_VISIBLE or TBS_TOP, 5,320,380,35,MainHWnd,1,AppHWnd,0
call
SendMessageA,eax,TBM_SETRANGE,1,255*10000h
;==========================================================
msg_loop:
call GetMessageA,offset msg,MainHWnd,0,0
cmp msMESSAGE,WM_KEYDOWN ; Повідомлення клавіатури
jnz
CONTINUE_LOOP
cmp msWPARAM,1bh
; якщо код , то STOP
jz STOP
CONTINUE_LOOP:
Call DispatchMessageA,offset msg
Jmp msg_loop
STOP:
call ExitProcess,0
;==========================================================
WndProc proc
hwnd:DWORD, wmsg:DWORD, wparam:DWORD, lparam:DWORD
Cmp wmsg,WM_NOTIFY ; WM_NOTIFY надходить від кожного
Jnz NO_NOTIFY ; дочірнього вікна, при тому
Mov eax,wparam ; wparam містить ідентифікатор
Xchg eax,TRACK_ID1 ; дочірнього вікна від якого надійшло
Xchg eax,TRACK_ID ; повідомлення, який записуємо у TRACK_ID;
NO_NOTIFY: cmp wmsg,WM_HSCROLL ; WM_HSCROLL надходить від
Jnz
NO_CHILD ; вікон типу “горизонтальний скролінг”
Mov eax,wparam ; молодша частина wparam – дія,
Shr
eax,16 ; старша частина – позиція ковзуна;
Jz NO_CHILD ; якщо позиція = 0, то вийти з процедури;
Mov ebx,TRACK_ID ; TRACK_ID – поточний ідентифікатор, а
Cmp ebx,TRACK_ID1 ; TRACK_ID1 – попередній ідентифікатор
Jnz NO_CHILD ; дочірнього вікна, які повинні співпадати;
Add ebx,offset COLOR ; ідентифікатор використовується
Mov [ebx],al ; як індекс кольору;
Call CreateSolidBrush,COLOR ; створюється кисть заданого кольору
Mov Brush,eax ; записати хендл кисті;
PAINT1:
Call GetDC, hwnd ; одержуємо графічний контекст
Mov HDC,eax ; вікна і зберігаємо його;
Call SelectObject,HDC,Brush ; змінюємо поточну кисть;
Call Rectangle,HDC,0,0,400,270 ; малюємо прямокутник
Call _wsprintfA, offset PRINT_BUF,offset FORMAT,COLOR
Add esp,4*3 ; необхідно лише для _wsprintfA;
Call lstrlen,offset PRINT_BUF ; отримуємо довжину рядка
Call TextOutA, HDC, 10, 250, offset PRINT_BUF, eax
Call ReleaseDC,hwnd,HDC ; звільняємо графічний контекст;
NO_CHILD: ; мітка виходу з процедури;
Call DefWindowProcA,hwnd,wmsg,wparam,lparam ; стандартний вихід,
Ret ; повернення з процедури;
WndProc
endp
End Start
Для наглядного розуміння механізму повідомлень спробуйте зіпсувати зображення у вікні, насунувши на нього вікно іншої програми. Як ви бачите, зображення у вікні не відновлюється. Після цього вставте на початок WndProc перевірку надходження повідомлення: cmp wmsg, WM_CTLCOLORSTATIC
і після того:
jz PAINT1, що означає перехід на малювання. Тепер зображення у вікні не псується.
Одним з найважливіших параметрів графічного контексту є шрифт. Для вибору шрифту необхідно створити гарнітуру відповідного фонту заданого розміру. Така гарнітура створюється функцією CreateFontIndirectA. Коли створяться зображення букв, функції виводу тексту будуть працювати дуже швидко. Необхідно лише записати утворену гарнітуру шрифту у графічний контекст вікна за допомогою функції SelectObject. Щоб звільнити пам’ять від використаної гарнітури шрифту, кисті та іншого GDI-об’єкту використовуйте функцію DeleteObject.
Текст можна малювати різними кольорами, які утворюються сумішшю компонент червоного (1й байт), зеленого (2-й байт) та синього (3-й байт) в одній змінній, яка вказуються як параметр функції SetTextColor. Аналогічно вибирається код фону функцією SetBkColor. Після виводу букв заданої гарнітури функцією TextOutA, графічний контекст необхідно звільнити функцією ReleaseDC.
.386
.model flat,stdcall
Extrn CreateFontIndirectA:Proc, GetDC:Proc, SelectObject:Proc, SetTextColor:Proc
Extrn SetBkColor:Proc, TextOutA:Proc, ReleaseDC:Proc, ExitProcess:Proc
.data
HDC dd 0
LOGFONTA:
lfHeight
DD 70 ; Висота
lfWidth
DD 20 ; Ширина
lfEscapement
DD 3600-100 ; Кут нахилу * 10
lfOrientation
DD
0 ;
lfWeight
DD 1000 ; Жирнiсть (1000-Bold)
lfItalic
DB
1 ; Курсив
lfUnderline
DB
0 ; Пiдкреслення
lfStrikeOut
DB
0
lfCharSet
DB 1 ; 255 – шрифти DOS
lfOutPrecision
DB
0
lfClipPrecision
DB
0
lfQuality
DB
1
lfPitchAndFamily
DB
0
lfFaceName
DB
'Impact'
; Назва фонту
Reserv
DB 32-6 dup(0)
X_coord dd 80
Y_coord dd 80
Text1 db 'Програмування на Асемблерi '
EndText1 db 0
.code
Start: call GetDC,0
mov HDC,eax
call CreateFontIndirectA, offset LOGFONTA
call SelectObject,HDC,eax
call SetTextColor,HDC,0022FFh
call SetBkColor,HDC,00FFFFh
mov eax,offset EndText1
sub eax,offset Text1
call TextOutA, HDC, X_coord,Y_coord, offset Text1, eax
call ReleaseDC,0,HDC
call ExitProcess,0
End Start
ПОРЯДОК ВИКОНАННЯ РОБОТИ
Відкомпілювати та запустити подані програми.
Переробити першу програму таким чином, щоб вона мала три дочірніх вікна класу msctls_trackbar32, кожне з яких регулюватиме один з кольорів: червоний, зелений, синій.
Переробити програму так, щоб текст, який виводить значення кольору, виводився шрифтом “Comic Sans MS”. Створення гарнітури шрифту зробити перед створенням вікна.
Ввести в програму дочірнє вікно класу SysAnimate32 з стилем ACS_AUTOPLAY. Після створення вікна цього стилю надіслати йому повідомлення ACM_OPEN та ACM_PLAY. Формат повідомлень знайти в Win32.hlp.
Ввести в програму дочірнє вікно класу Edit з стилями ES_CENTER та ES_MULTILINE. За допомогою повідомлення EM_GETLINE переписати в буфер введену інформацію та вивести її за допомогою функції MessageBoxA. Для коректної роботи програми з вікном класу Edit в цикл прийому повідомлень вставити функцію TranslateMessage.
Створити в основній програмі таймер за допомогою функції SetTimer, який буде щосекунди надсилати повідомлення WM_TIMER у процедуру основного вікна. З приходом кожного такого повідомлення у процедурі вікна збільшувати змінну-лічильник і надсилати її текстове значення у дочірнє вікно класу Edit за допомогою повідомлення WM_SETTEXT.
Довідкова інформація по функціях API, що використовуються в роботі
SetTimer – створює таймер, який регулярно надсилає повідомлення
hWnd, // хендл вікна, яке буде отримувати повідомлення WM_TIMER;
nIDEvent, // ідентифікатор таймера (може бути 0);
uElapse, // час через який будуть надсилатися повідомлення (1000 = 1 сек.);
lpTimerFunc
// адреса процедури, яка буде отримувати повідомлення WM_TIMER (0).
КОНТРОЛЬНІ ЗАПИТАННЯ
Що таке дочірнє вікно ?
Як отримати інформацію від дочірнього вікна ?
Як керувати дочірнім вікном ?
Що таке графічний контекст ?
Що таке шрифт і для чого існує функція CreateFontIndirectA ?
Лабораторна робота 6
Тема – Спеціалізовані каталоги WINDOWS.
Мета – отримати інформацію про спеціалізовані каталоги та навчитись з ними працювати.
ТЕОРЕТИЧНІ ПОЛОЖЕННЯ
Операційна система – це середовище для “співіснування” багатьох програм, які взаємодіють між собою та використовують спільні ресурси. Для того, щоб уникнути протиріч між програмами та зберігати настройки системи, розробники WINDOWS ввели спеціальну базу даних, що називається реєстром. Реєстр зберігається у файлах user.dat та system.dat. У половині випадків крах операційної системи пов’язаний з невірною інформацією саме в цих файлах.
Реєстр нагадує дерево каталогів, кожний з яких називається ключем. Кожна програма, що користується спільними системними ресурсами робить записи в реєстр про те, які саме настройки та ресурси вона використовує, які початкові параметри давати при старті та як інші програми можуть використовувати дану програму.
Крім того, в операційній системі WINDOWS існують спеціальні каталоги, в яких файли зберігаються за певним призначенням та можуть відображатися у вигляді меню. За кожним таким спеціалізованим каталогом закріплений певний внутрішній індекс, який позначається певною стандартною константою. Нижче наведені деякі з цих констант, їх значення та зміст.
Користувач може отримати назву спеціалізованого каталогу за 2 кроки:
Отримати хендл спеціалізованої папки за допомогою функції SHGetSpecialFolderLocation по константі, що наведена у таблиці.
Отримати повний шлях до папки за допомогою функції SHGetPathFromIDList по її хендлу.
Нижче наведена програма, що демонструє ці кроки і знаходить всі спеціалізовані каталоги:
.386
.model flat,STDCALL
extrn SHGetSpecialFolderLocation:Proc
extrn MessageBoxA:Proc
extrn ExitProcess:Proc
extrn SHGetPathFromIDList:Proc
.data
INDEX dd 0
; індекс папки;
DIRECTORY_ID dd 0
; хендл папки;
DIRECTORY_NAME db 512 dup(0) ; ім’я папки;
T db ' Cпеціальний каталог:',0
.code
Start: push offset DIRECTORY_ID ; вихідний параметр;
push INDEX
; вхідний номер папки;
push 0
; хендл власника;
call SHGetSpecialFolderLocation
inc INDEX
cmp INDEX,65
; якщо індекс
перевищує 64,
jnc STOP
; то закінчити пошук.
or eax,eax
; Якщо папка з даним індексом не існує,
jnz Start
; то продовжувати пошук.
push offset DIRECTORY_NAME ; Адреса вихідного імені;
push DIRECTORY_ID
; вхідний хендл папки.
call SHGetPathFromIDList
; Вивід отриманої назви каталогу
call MessageBoxA,0,offset DIRECTORY_NAME,offset T,0
jmp Start
STOP: call ExitProcess,0
end Start
ПОРЯДОК ВИКОНАННЯ РОБОТИ
Відкомпілювати та запустити подану програму.
Переробити програму таким чином, щоб вона крім назви каталогу видавала значення його індексу та хендлу.
Використовуючи дану програму та функцію CopyFileA, написати програму для копіювання тексту програми на Робочий стіл.
Написати програму для встановлення картинки робочого стола з файлу Wallpaper.bmp, що знаходиться в папці “Избранное”. Для цього отримати ім’я спеціалізованого каталогу, приєднати до нього символ “” за допомогою функції lstrcat, та назву файлу. За допомогою функції SystemParametersInfoA (див. довідку) встановити нову картинку робочого стола.
Довідкова інформація по функціях API, що використовуються в роботі
lstrcat – з’єднує два рядка в один (кінець рядка позначено нулем):
lpString1 // адреса рядка до якого треба приєднати;
lpString2
// адреса рядка, що приєднується.
SystemParametersInfoA – змінює системні параметри та профіль користувача:
uiAction // номер параметру, який необхідно змінити (SPI_SETDESKWALLPAPER);
uiParam // додаткова інформація про параметр (NULL);
pvParam // уточнююча інформація (адреса рядка з повною назвою файлу);
fWinIni
// режим виконання (SPIF_SENDWININICHANGE + SPIF_UPDATEINIFILE).
КОНТРОЛЬНІ ЗАПИТАННЯ
Що таке спеціалізований каталог WINDOWS ?
Чим реєстр відрізняється від спеціалізованого каталогу ?
Які ви знаєте спеціалізовані каталоги ?
Як отримати назву спеціалізованого каталогу ?
Що робить функція SystemParametersInfoA ?
Лабораторна робота 7
Тема – Зворотній виклик та функції перебору системних об’єктів.
Мета – отримати інформацію про систему методом перебору її об’єктів.
ТЕОРЕТИЧНІ ПОЛОЖЕННЯ
В операційній системі WINDOWS існують спеціальні функції, які дозволяють робити перебір деяких системних об’єктів, наприклад, вікон, ключів реєстру, мережних з’єднань і т.д. В назви таких функцій включається слово “Enum” (від англійського слова enumerate-перелічувати). В процесі роботи таких функцій система знаходить хендл об’єкту, що підлягає перебору (переліку) та передає його у спеціальну процедуру зворотного виклику, яка має бути написана користувачем. Таке звернення до системної функції, яка в свою чергу викликає підпрограму користувача, називається технологією зворотного виклику (від англійського слова callback). Отже, процедура зворотного виклику отримує хендл об’єкта як параметр, тобто одержує до нього доступ. В процедурі зворотного виклику користувач може використовувати додаткові функції для отримання інформації про об’єкт, або змінити параметри самого об’єкту, пославши до нього відповідне повідомлення.
Деякі функції нумерації не використовують зворотного виклику. Такі функції вимагають звертатися до об’єкта по індексу, подібно до того, як це було зроблено у попередній лабораторній роботі. В наступній таблиці представлені деякі функції переліку та їх зміст.
Нижче наведений приклад для переліку всіх відкритих вікон вищого рівня в операційній системі:
.386
.model flat,STDCALL
extrn ExitProcess:Proc
extrn MessageBoxA:Proc
extrn EnumWindows:Proc
extrn GetWindowTextA:Proc
.data
TITLE1
db 'Перелiк вiкон',0
WND_NAME
db 200 dup(0)
;===============================
.code
Start: push 0
; додатковий параметр, що передається до CallBack – функції;
push offset PROG1 ; адреса CallBack – функції;
call EnumWindows
STOP:
call ExitProcess,0
;================================
PROG1 proc
hwnd:DWORD, wparam:DWORD ; CallBack – процедура;
push 200
; максимальна довжина назви;
push offset WND_NAME ; адреса назви вікна;
push hwnd
; хендл вікна;
call GetWindowTextA
; отримати назву вікна;
call MessageBoxA,0,offset WND_NAME,offset TITLE1,30h
; вивести назву;
or eax,1 ; 1 –
шукати далі, 0 – закінчити перебір.
Ret
; Повернутися до процедури EnumWindows.
Endp PROG1
End Start
В даному прикладі використана callback-процедура, яка отримує і виводить назву вікна. Кожна callback-процедура повинна повернути ненульове значення в регістрі eax, інакше перелік припиниться.
В наступній програмі наведений приклад використання функції для отримання всіх підключів відкритого ключа реєстру ”SoftwareMicrosoftInternet Explorer”, в якому не використовується callback-процедура, а підключі знаходяться по індексу:
.386
.model flat,STDCALL
extrn ExitProcess:Proc
extrn RegOpenKeyA: Proc
extrn RegEnumKeyExA:Proc
extrn MessageBoxA:Proc
HKEY_CURRENT_USER
equ 80000001h
.data
SizeKeyClassName dd 37 ; довжина назви ключа
KeyClassName
db 'SoftwareMicrosoftInternet Explorer',0
SizeSubKeyName
dd 260
SubKeyName
db 260 dup(0)
IndexKey
dd 0 ; індекс ключа;
KeyHandle
dd 0 ; хендл відкритого ключа;
KeyTime
dq 0,0,0,0
;===========================================
.code
Start: push offset KeyHandle ; адреса, де буде записаний хендл ключа;
push offset KeyClassName
; назва ключа;
push HKEY_CURRENT_USER ; стандартний розділ реєстру;
call RegOpenKeyA
; отримати хендл ключа;
or eax,eax
jnz STOP
; перейти на кінець, якщо ключ не існує.
mov eax,260
; Встановити максимальний розмір для назви підключа.
mov
SizeSubKeyName,eax
mov eax,37
; Встановити розмір для назви ключа.
mov
SizeKeyClassName,eax
push
offset KeyTime
; адреса часу створення та останньої зміни ключа;
push
offset SizeKeyClassName ; адреса розміру імені класу,
push
offset KeyClassName ; адреса назви класу ключів реєстру;
push
0
; зарезервовано;
push
offset SizeSubKeyName ; адреса розміру імені підключа,
push
offset SubKeyName ;
адреса назви піключа реєстру;
push
IndexKey
; індекс підключа,
push
KeyHandle
; хендл підключа.
call RegEnumKeyExA
; Отримати всі підключі;
cmp
eax,0
; якщо eax=0, то успішне виконання.
jnz STOP
call MessageBoxA,0,offset SubKeyName,offset KeyClassName,1 ; вивести;
inc IndexKey
; збільшити індекс підключа.
cmp eax,1 ; якщо натиснули “OK”,
jz NEXT_KEY ; то перейти на Start.
STOP:
call ExitProcess,0
End Start
ПОРЯДОК ВИКОНАННЯ РОБОТИ
Відкомпілювати та запустити подані програми.
Переробити першу програму таким чином, щоб вона видавала запит на закриття певного вікна у формі вікна повідомлень з двома кнопками “YES” та “NO”, і якщо користувач натисне “YES”, вікну надсилається повідомлення про закриття за допомогою функції SendMessageA з параметром WM_CLOSE (див. довідкову інформацію та файл H:TASMINCLUDEWin119.inc).
Переробити другу програму таким чином, щоб вона видавала всі назви атрибутів та їх значення для підключа реєстру “SoftwareMicrosoftInternet ExplorerMain” за допомогою функції RegEnumValueA (див. довідкову інформацію).
Зробити програму, яка встановлює стартову сторінку для Internet Explorer за допомогою функцій RegOpenKeyA та RegSetValueExA. Ключ взяти з п.3, а підключ – “Start Page”. Значенню підключа присвоїти будь-яку адресу.
Довідкова інформація по функціях API, що використовуються в роботі
SendMessageA – надсилає повідомлення вікну або пристрою:
hWnd // хендл вікна або пристрою, якому ви надсилаєте повідомлення;
Msg
// код повідомлення (що треба зробити у вікні);
wParam // параметр 1;
lParam
// параметр 2;
RegEnumValueA – отримує всі атрибути та їх значення для відкритого ключа реєстру:
hKey,
// хендл відкритого ключа реєстру;
dwIndex,
// індекс атрибуту, інформацію про який ви отримуєте;
lpValueName, // адреса буферу для назви атрибуту;
lpcbValueName // адреса розміру цього буферу;
lpReserved
// зарезервовано = 0;
lpType
// адреса змінної типу атрибуту;
lpData
// адреса буферу, в який запишеться значення атрибуту;
lpcbData
// адреса довжини цього буферу;
RegOpenKeyA – відкриває заданий ключ реєстру:
hKey,
// значення HKEY_CURRENT_USER;
lpSubKey,
// адреса рядка з назвою ключа реєстру;
phkResult
// адреса змінної, що буде містсти хендл відкритого ключа.
RegSetValueExA – встановлює значення заданого підключа відкритого ключа реєстру:
hKey,
// хендл відкритого ключа;
lpValueName, // адреса назви підключа цього ключа ;
Reserved,
// зарезервовано = 0;
dwType,
// прапорець типу значення підключа =1 (рядок символів);
lpData,
// адреса буферу, що містить значення;
cbData
// довжина рядка, що містить значення.
КОНТРОЛЬНІ ЗАПИТАННЯ
Як працюють функції переліку системних об’єктів ?
Які ви знаєте API-функції переліку ?
Як отримати назву вікна ?
Яка структура системного реєстру ?
Як отримати назви та значення атрибутів системного реєстру ?
Лабораторна робота 8
Тема – Використання технології OLE.
Мета – зрозуміти принципи виклику функцій OLE на асемблері.
ТЕОРЕТИЧНІ ПОЛОЖЕННЯ
Основна ідея OLE (object linking and embedding) полягає в систематизації структур даних та функцій роботи з ними. Такий підхід, де кожний об’єкт має в собі інформацію про себе називається об’єктно-орієнтованим програмуванням. Для роботи з об’єктами у WINDOWS введено поняття інтерфейс. Інтерфейси для роботи з об’єктами можна додавати в операційну систему. Але існують і стандартні інтерфейси для роботи зі стандартними об’єктами. Кожний стандартний інтерфейс має своє ім’я і обліковий код, який прописаний у реєстрі під ключем HKEY_CLASSES_ROOTInterface. Кожен підключ даного ключа є кодом інтерфейсу, а значення підключа є ім’ям інтерфейсу. Наприклад, підключ {7BF80980-BF32-101A-8BBB-00AA00300CAB} має значення IPicture.
Для використання бібліотеки OLE необхідно створити об’єкт типу “потік” (Stream), який представляє данні, що завантажені в нього у структурованому вигляді. Теоретично потік даних може бути необмеженим. Створення такого об’єкту виконує функція CreateStreamOnHGlobal, яка знаходиться у бібліотеці ole32.dll. Початковим станом цього об’єкту є вміст віртуальної пам’яті, блок якої передається як параметр функції. Оскільки опису бібліотеки ole32.dll немає у файлі import32.lib, програма tlink32.exe не зможе підключити виклик цієї функції, і ми повинні будемо робити це вручну. Для цього скористуємось комбінацією двох функцій: LoadLibraryA та GetProcAddress. Перша з них завантажує потрібну бібліотеку у пам’ять, а друга – отримує адресу потрібної функції API.
В даній лабораторній роботі використано два інтерфейси об’єктно-орієнтованого програмування: IStream та IPicture.
.386
.model flat,STDCALL
extrn LoadLibraryA:Proc, GetProcAddress:Proc, GlobalAlloc:Proc, GlobalLock:Proc
extrn GlobalUnlock:Proc, GetDeviceCaps:Proc, GetClientRect:Proc, ReadFile:Proc
extrn CreateFileA:Proc, GetFileSize:Proc, CloseHandle:Proc, MulDiv:Proc
extrn GetDC:Proc, ReleaseDC:Proc, ExitProcess: Proc
.data
HWnd
dd 0
HDC
dd 0
HMWidth
dd 0
Width
dd 0
HMHeight dd 0
Height
dd 0
RECT dd 0,0,0,0
;left,top,right,bottom
PICTURE_NAME db 'test.jpg',0
HFile
dd 0
File_Size dd 0
HGlobal
dd 0
NUM_READ dd 0
PSTM
dd 0
; iдентифiкатор iнтерфейсу IPicture, який взятий з реєстру:
IID_IPicture dd 7bf80980h
; HKEY_CLASSES_ROOTInterface
dw 0bf32h, 101ah
; {7BF80980-BF32-101A-8BBB-00AA00300CAB}
db 8bh, 0bbh
db 00h, 0aah, 00h, 30h, 0ch, 0abh
GPICTURE dd 0
LibName1
db 'ole32.dll',0
ProcName1
db 'CreateStreamOnHGlobal',0
CreateStreamOnHGlobal1 dd
offset STOP
LibName2
db 'oleaut32.dll',0
ProcName2
db 'OleLoadPicture',0
OleLoadPicture1
dd
offset STOP
.code
Start: call LoadLibraryA,offset LibName1
call GetProcAddress, eax, offset ProcName1
or eax,eax
jz STOP
mov CreateStreamOnHGlobal1,eax
call LoadLibraryA,offset LibName2
call GetProcAddress, eax, offset ProcName2
or eax,eax
jz STOP
mov OleLoadPicture1,eax
call CreateFileA, offset PICTURE_NAME, 80000000h,0,0,3,0,0
cmp eax,-1
jz STOP
mov HFile,eax
call GetFileSize,HFile,0 ; отримати довжину файлу
mov
File_Size,eax
call GlobalAlloc, 2, File_Size
mov
HGlobal,eax
call GlobalLock,eax
call ReadFile, HFile, eax, File_Size, offset NUM_READ,0
call GlobalUnlock, HGlobal
call CloseHandle, HFile
call [CreateStreamOnHGlobal1], HGlobal, 1, offset PSTM
mov eax,PSTM ; завантажити файл у потiк
or eax,eax
jz STOP
call [OleLoadPicture1],PSTM,File_Size,0,offset IID_IPicture,offset GPICTURE
or eax,eax ; скористатись інтерфейсом об'єкт IPicture
jnz STOP
mov edx,PSTM ; coinvoke PSTM,IUnknown,Release
mov edx,[edx]
push PSTM
call dword ptr [edx+8h]
mov edx, GPICTURE ; використання методу OLE
mov edx, [edx]
; IPicture::get_Width (18h)
push offset HMWidth
push GPICTURE
call Dword ptr [edx+18h]
mov edx, GPICTURE ; використання методу OLE
mov edx, [edx]
; IPicture::get_Height (1Ch)
push offset HMHeight
push GPICTURE
call Dword ptr [edx+1Ch]
call GetDC,HWnd
mov
HDC,eax
call GetDeviceCaps, HDC,88 ; LOGPIXELSX
call MulDiv, HMWidth,eax,254*8 ;9ECh ; HIMETRIC_INCH
mov
Width, eax
call GetDeviceCaps, HDC,90 ; LOGPIXELSY
call MulDiv, HMHeight,eax,254*8 ;9ECh ; HIMETRIC_INCH
mov
Height, eax
call GetClientRect, HWnd, offset RECT
mov edx, GPICTURE ; використання методу OLE
mov edx, [edx]
; IPicture::Render (20h)
mov eax, HMHeight
neg eax
call [edx+20h],GPICTURE,HDC,0,0,Width,Height,0,HMHeight,HMWidth,eax,offset RECT
call ReleaseDC,HWnd,HDC
STOP: call ExitProcess,0
end Start
ПОРЯДОК ВИКОНАННЯ РОБОТИ
Відкомпілювати та запустити подану програму.
У файлі компіляції замінити шлях до файлу Import32.lib на шлях до аналогічного файлу з каталогу CBUILDER5, що має довжину 710K і 2000-й рік створення. Після заміни переробити подану програму так, як було у всіх попередніх лабораторних роботах, тобто, без виклику LoadLibraryA та GetProcAddress, а функції CreateStreamOnHGlobal та OleLoadPicture викликати напряму, оголосивши їх в extrn.
Добавити у програму процедуру створення вікна класу Static. Після створення вікна вивести в нього зображення у зменшеному вигляді.
Довідкова інформація по функціях API, що використовуються в роботі
КОНТРОЛЬНІ ЗАПИТАННЯ
Що робить інтерфейс IPicture ?
Що робить інтерфейс IStream ?
Як отримати код інтерфейсу, якщо знати його назву ?
Як отримати адресу процедури виконання того чи іншого метода інтерфейсу ?
Що робить метод get_Width інтерфейсу IPicture ?
Що робить метод get_Height інтерфейсу IPicture ?
Що робить метод Render інтерфейсу IPicture ?
Як отримати адресу функції API з певної DLL-бібліотеки ?
ВМІСТ ЗВІТУ ПО РОБОТАХ
Звіт – це документ про те, що студент успішно виконав роботу, який включає:
Мету, що ставиться перед роботою;
Короткий зміст теоретичних відомостей;
Тексти всіх відлагоджених програм із коментарями;
Відповіді на контрольні запитання;
Висновки по особливостях застосування отриманих знань, зауваження по виконанню роботи та методичному забезпеченню.
ЛІТЕРАТУРА
Эпплман Д. Win32 API и Visual Basic. Для профессионалов (+CD). – СПб.: Питер, 2001. – 1120 с.: ил.
Юров В. Assembler: учебник. - СПб.: Питер, 2001. – 624 с.: ил.
Win32 Developer’s References (файл документації WIN32.HLP).
Антиботан аватар за замовчуванням

01.01.1970 03:01

Коментарі

Ви не можете залишити коментар. Для цього, будь ласка, увійдіть або зареєструйтесь.

Оголошення від адміністратора

Антиботан аватар за замовчуванням

пропонує роботу

Admin

26.02.2019 12:38

Привіт усім учасникам нашого порталу! Хороші новини - з‘явилась можливість кожному заробити на своїх знаннях та вміннях. Тепер Ви можете продавати свої роботи на сайті заробляючи кошти, рейтинг і довіру користувачів. Потрібно завантажити роботу, вказати ціну і додати один інформативний скріншот з деякими частинами виконаних завдань. Навіть одна якісна і всім необхідна робота може продатися сотні разів. «Головою заробляти» продуктивніше ніж руками! :-)

Завантаження файлу

Якщо Ви маєте на своєму комп'ютері файли, пов'язані з навчанням( розрахункові, лабораторні, практичні, контрольні роботи та інше...), і Вам не шкода ними поділитись - то скористайтесь формою для завантаження файлу, попередньо заархівувавши все в архів .rar або .zip розміром до 100мб, і до нього невдовзі отримають доступ студенти всієї України! Ви отримаєте грошову винагороду в кінці місяця, якщо станете одним з трьох переможців!
Стань активним учасником руху antibotan!
Поділись актуальною інформацією,
і отримай привілеї у користуванні архівом! Детальніше

Новини