ПРОГРАМУВАННЯ ЗА ДОПОМОГОЮ ФУНКЦІЙ 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 ; якщо код <ESC>, то 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, інакше перелік припиниться. В наступній програмі наведений приклад використання функції для отримання всіх підключів відкритого ключа реєстру ”Software\Microsoft\Internet 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 'Software\Microsoft\Internet 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:\TASM\INCLUDE\Win119.inc). Переробити другу програму таким чином, щоб вона видавала всі назви атрибутів та їх значення для підключа реєстру “Software\Microsoft\Internet Explorer\Main” за допомогою функції 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_ROOT\Interface\. Кожен підключ даного ключа є кодом інтерфейсу, а значення підключа є ім’ям інтерфейсу. Наприклад, підключ {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_ROOT\Interface\ 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-

Коментарі

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

Ділись своїми роботами та отримуй миттєві бонуси!

Маєш корисні навчальні матеріали, які припадають пилом на твоєму комп'ютері? Розрахункові, лабораторні, практичні чи контрольні роботи — завантажуй їх прямо зараз і одразу отримуй бали на свій рахунок! Заархівуй всі файли в один .zip (до 100 МБ) або завантажуй кожен файл окремо. Внесок у спільноту – це легкий спосіб допомогти іншим та отримати додаткові можливості на сайті. Твої старі роботи можуть приносити тобі нові нагороди!
Нічого не вибрано
0%

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

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

Подякувати Студентському архіву довільною сумою

Admin

26.02.2023 12:38

Дякуємо, що користуєтесь нашим архівом!