Категория > Новости > Заплатка на асме. Создаем панель инструментов для Windows на Flat Assembler - «Новости»

Заплатка на асме. Создаем панель инструментов для Windows на Flat Assembler - «Новости»


24-01-2022, 00:01. Автор: Ефросиния
ин­женеры NASA обна­ружи­ли, что основная антенна ради­освя­зи запущен­ного к Юпи­теру зон­да не рас­кры­лась пол­ностью. Раз­ве они бро­сили неис­прав­ное устрой­ство на про­извол судь­бы и обра­тились к пра­витель­ству за финан­сирова­нием нового? Нет, они про­яви­ли наход­чивость и тех­ничес­кую сме­кал­ку, в резуль­тате чего пусть и не без тру­да, но успешно про­вели мно­голет­нюю иссле­дова­тель­скую мис­сию.
 

Выбор цели и средства


Рас­смат­рива­емая в статье ситу­ация находит­ся где‑то меж­ду эти­ми край­ними слу­чаями. Наиболь­шие неудобс­тва опи­сан­ный дефект дос­тавля­ет при исполь­зовании раз­верну­тых на весь экран прог­рамм, потому что попада­ет либо на адресную стро­ку бра­узе­ра, либо на глав­ное меню при­ложе­ния. Исполь­зование же прог­рамм в окон­ном режиме, с под­гонкой их мес­тополо­жения пос­ле каж­дого запус­ка, гро­зит нер­вным расс­трой­ством. Я готов пожер­тво­вать частью полез­ной пло­щади экра­на, если изоб­ражение не будет попадать на дефек­тную область.


Ос­новная опе­раци­онная сис­тема на моем компь­юте­ре — Windows. Как исклю­чить полосу в вер­хней час­ти экра­на из дос­тупно­го прос­транс­тва рабоче­го сто­ла, что­бы окна при­ложе­ний при раз­верты­вании не попада­ли на нее? Идею мне под­ска­зала панель задач: она монопо­лизи­рует ниж­нюю часть экра­на и никог­да не перек­рыва­ется окна­ми прог­рамм. Может быть, дос­таточ­но будет прик­репить ее к вер­хней час­ти экра­на? Нет, во‑пер­вых, она не сов­сем под­ходит по раз­меру, а во‑вто­рых, сама при­обре­тает неп­ригляд­ный вид из‑за дефек­та. А нель­зя ли сде­лать «зап­латку» с такими же свой­ства­ми, но что­бы поль­зователь мог кон­тро­лиро­вать ее раз­мер и цвет?


Ока­зыва­ется, мож­но, и ответ быс­тро нашел­ся в спра­воч­нике по Win32 API — это па­нель инс­тру­мен­тов рабоче­го сто­ла. Нап­равле­ние работы про­ясни­лось, оста­лось выб­рать под­ходящий инс­тру­мент для ее выпол­нения. Основное средс­тво раз­работ­ки с исполь­зовани­ем Win32 API — ком­пилятор С. Но для вызова нес­коль­ких фун­кций опе­раци­онной сис­темы хочет­ся вос­поль­зовать­ся чем‑то более прос­тым и изящ­ным. Поэто­му я отпра­вил­ся в тем­ную кла­довую сво­ей памяти и нашел там пыль­ную шка­тул­ку с плос­ким мон­тажни­ком. Если кто‑то еще не догадал­ся, то так зву­чит по‑рус­ски Flat Assembler в вари­анте Яндекс‑перевод­чика. Уди­витель­но, но про­дукт, с которым я поз­накомил­ся еще в середи­не 2000-х, про­дол­жает жить и здравс­тво­вать.


 

Что умеет Flat Assembler?


Да­вай пря­мо сей­час раз­берем­ся со сре­дой, в которой будем работать. На стра­нице заг­рузки выбери архив с пос­ледней вер­сией сбор­ки для Windows, заг­рузи его и рас­пакуй куда‑нибудь на диск. В трех мегабай­тах пап­ки FASMW есть все, что нам пот­ребу­ется.


Соз­дай пус­тую пап­ку Appbar для рабоче­го про­екта и ско­пируй в нее исходный текст шаб­лона типово­го при­ложе­ния Windows FASMWEXAMPLESTEMPLATETEMPLATE.ASM. Запус­ти интегри­рован­ную сре­ду раз­работ­ки FASMWFASMW.EXE и с помощью пун­кта меню File → Open... заг­рузи в нее этот файл. Обра­ти вни­мание, что в нашем рас­поряже­нии есть тек­сто­вый мно­гоокон­ный редак­тор с под­свет­кой син­такси­са ассем­бле­ра.


Заплатка на асме. Создаем панель инструментов для Windows на Flat Assembler - «Новости»
Тек­сто­вый редак­тор интегри­рован­ной сре­ды FASMW

Шаб­лон Windows-при­ложе­ния на ассем­бле­ре сос­тоит из сле­дующих основных час­тей:



  • за­голов­ка с ука­зани­ем фор­мата целево­го исполня­емо­го фай­ла и точ­ки вхо­да в при­ложе­ние;

  • сек­ции кода .text, где мет­ка start ука­зыва­ет коман­ду, с которой дол­жно начинать­ся выпол­нение прог­раммы;

  • сек­ции дан­ных .data, содер­жащей гло­баль­ные перемен­ные прог­раммы;

  • сек­ции импорта .idata, в которой перечис­лены исполь­зуемые прог­раммой динами­чес­кие биб­лиоте­ки и под­клю­чают­ся объ­явле­ния содер­жащих­ся в них фун­кций.


В целом текст прог­раммы дол­жен быть понятен любому, кто исполь­зовал Win32 API. Во‑пер­вых, сам API пре­дель­но прост. Парамет­ры всех фун­кций ожи­дают 32-бит­ных зна­чений аргу­мен­тов, а если дан­ные не укла­дыва­ются в этот раз­мер, то переда­ется 32-бит­ный ука­затель на мас­сив или струк­туру опять же 32-бит­ных зна­чений. Исклю­чение, пожалуй, толь­ко стро­ки. Воз­вра­щаемое фун­кци­ей зна­чение (нап­ример, код завер­шения) переда­ется через регистр EAX или, если оно пре­выша­ет 32 бита, через струк­туру, на которую ука­зывал один из аргу­мен­тов.


Во‑вто­рых, Flat Assembler на осно­ве сво­его набора мак­роинс­трук­ций пред­лага­ет син­такси­чес­кий сахар, который дела­ет исполь­зование API мак­сималь­но приб­лижен­ным к высоко­уров­невым язы­кам прог­рамми­рова­ния. Ска­жем, доволь­но слож­ный вызов фун­кции соз­дания окна опи­сыва­ется одной стро­кой:


invoke CreateWindowEx,0,_class,_title,WS_VISIBLE+WS_DLGFRAME+WS_SYSMENU,128,128,256,192,NULL,NULL,[wc.hInstance],NULL

Здесь invoke — это коман­да вызова под­прог­раммы в соот­ветс­твии с сог­лашени­ем STDCALL, CreateWindowEx — имя вызыва­емой API-фун­кции, а далее через запятую сле­дуют аргу­мен­ты в том поряд­ке, в котором они опи­саны в докумен­тации. С‑прог­раммис­ты могут счи­тать, что име­на всех перемен­ных здесь — это ука­зате­ли (_class, _title), для разыме­нова­ния которых исполь­зуют­ся квад­ратные скоб­ки ([wc.hInstance]). Отме­тим при­выч­ную «точеч­ную» нотацию дос­тупа к эле­мен­там струк­туры.


Опи­сание окон­ной про­цеду­ры WindowProc тоже не дол­жно выз­вать зат­рудне­ний:


proc WindowProc uses ebx esi edi, hwnd,wmsg,wparam,lparam
...
ret
endp

Сог­лашение Win32 API тре­бует, что­бы пос­ле воз­вра­та из про­цедур обратно­го вызова (callback-про­цедур) зна­чения регис­тров EBX, ESI и EDI были такими же, как и перед вызовом. Для это­го в заголов­ке при­сутс­тву­ет ука­зание на сох­ранение этих регис­тров в виде фра­зы uses ebx esi edi. А даль­ше через запятую идет спи­сок фор­маль­ных парамет­ров про­цеду­ры, которые соот­ветс­тву­ют докумен­тации.


Те­перь ты можешь ском­пилиро­вать и выпол­нить эту прог­рамму. Но сна­чала ука­жи путь к пап­ке с под­клю­чаемы­ми дирек­тивой include фай­лами в пун­кте меню Options → Compiler setup так, что­бы он соот­ветс­тво­вал фак­тичес­кому мес­тополо­жению FASMWINCLUDE. Пос­ле это­го выпол­ни пункт меню Run → Run или прос­то наж­ми кла­вишу F9. Если все было сде­лано пра­виль­но, то в рабочей пап­ке Appbar появит­ся све­жесоб­ранный файл TEMPLATE.EXE, а на экра­не отоб­разит­ся кро­шеч­ное окно Win32 program template.


Нас­трой­ка пути к под­клю­чаемым фай­лам 

Создание обработчика сообщения WM_CREATE


Со сре­дой раз­работ­ки разоб­рались, прис­тупим к работе над прог­раммой. Если рань­ше ты никог­да не прог­рамми­ровал панели рабоче­го сто­ла Windows, то сей­час самое вре­мя изу­чить докумен­тацию. Но перед этим хочу обра­тить вни­мание на основные момен­ты. Панель рабоче­го сто­ла не явля­ется каким‑то уни­каль­ным объ­ектом опе­раци­онной сис­темы. Роль панели может играть любое окно, соз­данное фун­кци­ей CreateWindowEx. Все средс­тва Windows, обес­печива­ющие фун­кци­они­рова­ние панели, сос­редото­чены в единс­твен­ной фун­кции SHAppBarMessage, с помощью которой мож­но:



  • уз­нать гра­ницы области рабоче­го сто­ла, в пре­делах которых мож­но раз­местить новую панель инс­тру­мен­тов;

  • за­резер­вировать на этой области учас­ток для раз­мещения новой панели;

  • ука­зать манипу­лятор (handle) окна с панелью, которо­му будут отправ­лять­ся сис­темные уве­дом­ления, свя­зан­ные с изме­нени­ем обста­нов­ки на рабочем сто­ле.


Пос­ле резер­вирова­ния новой области опе­раци­онная сис­тема зап­реща­ет ее исполь­зование окна­ми при­ложе­ний при их мак­симиза­ции, осво­бож­дает от знач­ков рабоче­го сто­ла (если таковые на ней были) — и, в общем‑то, всё. За внеш­ний вид панели отве­чает ассо­цииро­ван­ное с нею окно, которое теоре­тичес­ки дол­жно зак­рыть собой осво­бож­денное прос­транс­тво и при­нять соот­ветс­тву­ющий стиль. Но по боль­шому сче­ту может это­го и не делать.


С помощью пун­кта меню File → Save as... сох­рани откры­тый в редак­торе файл под име­нем appbar.asm. В нашей прог­рамме панелью будет глав­ное окно при­ложе­ния. Зарезер­виру­ем для нее полосу в вер­хней час­ти рабоче­го сто­ла. Это мож­но сде­лать в обра­бот­чике со­обще­ния WM_CREATE, которое отправ­ляет­ся опе­раци­онной сис­темой окну при­ложе­ния непос­редс­твен­но перед тем, как отоб­разить его на экра­не. Для это­го в начале окон­ной про­цеду­ры WindowProc вста­вим стро­ки перехо­да к обра­бот­чику сооб­щения:


cmp [wmsg],WM_CREATE
je.wmcreate

и напишем сам обра­бот­чик перед мет­кой .wmdestroy:


.wmcreate:
stdcall wmCreateProc, [hwnd]
jmp .finish


info


Мет­ки, которые начина­ются с точ­ки, явля­ются локаль­ными по отно­шению к про­цеду­ре, где они исполь­зуют­ся (в дан­ном слу­чае — WindowProc). Это еще одна фиш­ка Flat Assembler, которая поз­воля­ет не бес­поко­ить­ся о том, что в раз­ных про­цеду­рах име­на меток могут пов­торять­ся.



Наш обра­бот­чик вызыва­ет пока еще не сущес­тву­ющую про­цеду­ру wmCreateProc и переда­ет ей зна­чение манипу­лято­ра соз­данно­го окна. В этой про­цеду­ре надо опи­сать дей­ствия по резер­вирова­нию полосы и позици­они­рова­нию глав­ного окна, пос­ле чего обну­лить регистр EAX для сиг­нализи­рова­ния об успешном завер­шении про­цеду­ры. Если пос­ле обра­бот­ки сооб­щения WM_CREATE зна­чение регис­тра EAX будет рав­но (-1), опе­раци­онная сис­тема вос­при­мет это как сиг­нал о проб­леме, что при­ведет к завер­шению работы прог­раммы. Текст про­цеду­ры wmCreateProc мож­но раз­местить пос­ле опе­рато­ра endp, зак­рыва­юще­го блок опи­сания окон­ной про­цеду­ры WindowProc:


proc wmCreateProc,hwnd
invoke MessageBox,[hwnd],_title,_class,MB_OK+MB_ICONINFORMATION
xor eax,eax
ret
endp


info


Вот про­межу­точ­ный вари­ант прог­раммы, который выводит отла­доч­ное сооб­щение: appbar-ver1.asm.



Про­цеду­ра wmCreateProc в таком виде не дела­ет ничего полез­ного, но при запус­ке прог­раммы выводит окно с информа­цион­ным сооб­щени­ем, которое дает понять, что на этом эта­пе все работа­ет так, как ожи­дает­ся.



info


Вни­матель­но сле­ди за тем, что­бы количес­тво и порядок аргу­мен­тов в коман­де вызова про­цеду­ры всег­да соот­ветс­тво­вали количес­тву и поряд­ку парамет­ров в ее опи­сании. FASMW это не кон­тро­лиру­ет, и, если допус­тить неб­режность, мож­но получить труд­но обна­ружи­ваемые ошиб­ки.



Перейти обратно к новости