Подготовка на среда за програмиране на WinAPI, Бележки на програмист
Подготовка на среда за програмиране на WinAPI
Нещо, с което реших да си спомня младостта. Преди да се увлека в посоката на Perl, Unix-и и всякаква функционалност, играх доста време със sami, асемблер и WinAPI. Сега всичко това лека-полека започва да се забравя, което е жалко, защото, както вече разбрахме, е полезно да се знаят всякакви долни неща.
Ще използвам Windows XP с Ubuntu Linux във VirtualBox и средата за разработка на Visual Studio 2005, за да напиша кода.Ако не използвате и Windows, препоръчвам да изберете същата конфигурация, тъй като по-късните версии на Visual Studio и Windows изискват изключително много ресурси. Не забравяйте да инсталирате добавките за гости, това ще позволи на Windows да използва същата разделителна способност на екрана като хост системата. Дори ако WinXP е твърде тежък за вас, Windows 2000 и Visual C++ 6.0 ще свършат работа. Въпреки че няма да използвам най-новите Windows и Visual Studio, на теория всичко трябва да работи добре в по-късните им версии. Също така, не би трябвало да е твърде трудно да възпроизведа моите действия в някои wxDev-C++ или дори Borland Delphi. Ще пишем на C, може би само от време на време прибягвайки до някои C ++ чипове.
Допълнение: Трябва да отдадем почит на Microsoft, най-актуалните за средата на 2017 г. Windows 10 и общността на Visual Studio работят доста бързо в условия на ограничени ресурси под VirtualBox. Нещо повече, общността на Visual Studio е напълно безплатна за изтегляне.
Инсталирането на Visual Studio е лесно. Да приемем, че сте го направили. Нека създадем нов проект. Стартирайте Visual Studio и изберете File → New → Project от менюто. В диалоговия прозорец, който се появява, изберете Visual C++ → Win32 → Win32 Project. В полето Име въведете някоинякакво име на проекта, например First. Щракнете върху OK, Next, Finish. В резултат на това ще бъде създадена рамката на проекта. Обърнете внимание на падащия списък с конфигурации на проекта в центъра на екрана. Изберете конфигурацията Release в него:
Натиснете F7, за да компилирате програмата. Натиснете Ctrl+F5, за да го стартирате. Ако използвате VirtualBox, имайте предвид, че десният клавиш Ctr се използва в клавишни комбинации, които контролират виртуалната машина. Например комбинацията Ctr+F се използва за превключване между режим на прозорец и цял екран. Следователно, ако решите да използвате VirtualBox, използвайте клавиша Ctr, разположен вляво в клавишните комбинации на Visual Studio.
Сега, ако влезете в директорията на проекта и намерите изградената програма (тя е в поддиректория, наречена release), ще откриете, че е с размер 64 KB. По днешните стандарти това не е толкова много, но все пак е нещо прекалено много за програма, която просто рисува прозорец с меню. Ще пишем на C и WinAPI и едно от предимствата на този подход е възможността да пишем много компактни програми.
Да видим как се прави:
- Затворете текущия проект: File → Close Solution;
- Създайте нов проект с име Project, поставете отметка в квадратчето Допълнителни опции → Празен проект в съветника;
- Изберете конфигурацията Release;
- Създайте нов файл с изходен код, като кажете Project → Add New Item… → Visual C++ → Code → C++ File (.cpp), наречен Main;
- Отворете свойствата на проекта: Проект → Свойства на проекта…;
- Деактивирайте проверката за сигурност на буфера: C/C++ → Генериране на код → Проверка на сигурността на буфера → Не;
- Уведомете ни, че пишем C код: C/C++ → Advanced → Compile As → Compile As C Code;
- Игнорирайте библиотеките по подразбиране: Linker → Input →Игнориране на всички библиотеки по подразбиране → Да;
- Посочете основната процедура като входна точка: Linker → Advanced → Entry Point → main;
- Деактивирайте информацията за отстраняване на грешки: Linker → Debugger → Генериране на информация за отстраняване на грешки → Не;
- Деактивиране на генерирането на манифест: Liner → Файл на манифест → Генериране на манифест → Не;
- Щракнете върху Прилагане, след това върху OK;
Сега, ако напишете в Main.cpp кода:
... и го компилирате, получавате изпълним файл Project.exe, който не прави абсолютно нищо и е с размер точно 1 KB. Програмата се оказа толкова малка, защото изхвърлихме системата за изпълнение на C ++, както и информацията за отстраняване на грешки и други „боклуци“ от нея. Всъщност това е минималният размер на изпълним файл в Windows, тъй като той трябва да съдържа някаква служебна информация (DOS мъниче, PE хедър, таблица на секции) и да има известно подравняване. Можете да го свиете още малко, но по този начин рискуваме да нарушим съвместимостта с някои версии на Windows.
За да не повтаряте описаните по-горе стъпки при създаване на всеки нов проект, затворете проекта и го запазете в архив с име като project_template.zip. Сега нека се опитаме да създадем програма, базирана на този проект, която прави нещо. Разархивирайте проекта, преименувайте директорията му от Project на MsgBox, отворете проекта във Visual Studio. Въведете следния код:
void main() < Кутия за съобщения (0, L "Здравей!", L "Кутия за съобщения", 0); Изход от процеса (0); >
Обърнете внимание, че VisualStudio може да допълва имена на процедури, като натиска Ctr+Space, докато ги въвежда. Използвайте Ctrl+S, за да запазите кода. Когато въвеждате аргументи на процедурата, се показва подсказка.
Ако сега стартирате програмата, ще видите нещо подобно:
Размерът на exe файла беше2 Kb. Можете да го намалите до 1 KB, като добавите ред в самото начало на кода:
С това казваме на компилатора да обедини няколко раздела от изпълнимия файл в един. Но ми се струва, че това вече е твърде много, така или иначе файлът се оказа малък. Има и други методи, но описаните по-горе ще ни бъдат достатъчни.
Префиксът L преди началната кавичка показва, че низът е съхранен в unicode. Всъщност има две версии на процедурата MessageBox - MessageBoxA, която работи с ascii низове, и MessageBoxW, която работи с unicode низове. Подобна ситуация е типична за повечето други WinAPI процедури. По подразбиране свойствата на проекта казват да се използват unicode версии на процедурите, така че компилаторът замества извикването на MessageBox с MessageBoxW, когато проектът е изграден. На ниско ниво ascii процедурите са просто обвивки на unicode версии (Windows използва процедурите MultiByteToWideChar и WideCharToMultiByte за преобразуване на низове от unicode в ascii и обратно). Работейки с процедури, чиито имена завършват на "W", получаваме по-бързи програми.
В заключение бих искал да отбележа, че горният код е успешно компилиран от MinGW и се изпълнява под Wine:
Вярно е, че резултатът е exe файл, съдържащ "боклук", премахването на който е извън обхвата на тази публикация.
Всъщност това е всичко, за което исках да говоря днес. За домашна работа можете да прочетете документацията на MessageBox в MSDN. Опитайте да покажете прозорци с различни икони и бутони и да използвате кода за връщане, за да определите кой бутон е бил натиснат.
Както винаги, ще се радвам да отговоря на вашите въпроси. И в същото време ми кажете колко ви е интересно всичко това?