VisualStudio 2008: Аналіз стартовою заготовки, Різне, Програмування, статті

Перші два рядки є директивами препроцесора, які повідомляють йому, що до того, як почати процес компіляції модуля, слід вставити у вказане місце файли заголовків (stdafx.h і API.h). Перший файл ми обговорювали в уроці 1. Він містить директиви підключення бібліотечних файлів-заголовків. Директива

/ / ======== Виключає рідко використовуються елементи

/ / ======== Windows-заголовків

#define WIN32_LEAN_AND_MEAN

зменшує розмір виконуваного модуля, оскільки виключає ті фрагменти каркаса додатки, які рідко використовуються. Другий файл (API.h) створив майстер. Ви можете відкрити його за допомогою вікна Solution Explorer і побачити, що він містить лише два рядки:

#pragma once

#include“resource.h”

Директива fpragma once повідомляє компілятору, що даний файл (API.h) повинен бути використаний при побудові коду програми лише один раз, незважаючи на можливі повтори (виду # include “API.h”). Друга директива підключає файл з ідентифікаторами ресурсів. Самі ресурси ви бачите у вікні Resource View. Всі ресурси програми та їх окремі елементи повинні бути ідентифіковані, тобто пронумеровані. Новачкам рекомендується відкрити файл resource.h за допомогою вікна Solution Explorer і переглянути його вміст. У цьому файлі символічним іменам (код) IDS_APP_TITLE, IDR_MAINFRAME і т. д. відповідають числові константи, які препроцесор вставить замість ідентифікаторів ще до процесу компіляції. В кінці файлу містяться позначки Studio.Net, що визначають подальший спосіб нумерації ресурсів різного типу. Розглянутий файл не рекомендується редагувати вручну, так як в разі помилок ви отримаєте труднолокалізуемие відмови. Studio.Net сама стежить за станом resource.h, вставляючи і видаляючи макропідстановки # Def ine в міру того, як ви редагуєте ресурси за допомогою спеціальних редакторів.

Повертаючись до коду заготівки, відзначимо, що далі слід оголошення глобальних змінних

HINSTANCE hlnst; / / Поточний примірник

TCHAR szTitle[MAX_LOADSTRING];

/ / Текст заголовка вікна

TCHAR szWindowClass[MAX_LOADSTRING];

/ / Текст реєстрації

Розглядайте описувач hlnst як адреса виконуваного модуля в просторі процесу, відповідного додатку. Якщо ви не знайомі з поняттями потік і процес, то зверніться до останнього уроку цієї книги, де наведені деякі відомості про архітектуру Windows. Текст реєстрації szWindowClass буде завантажений з ресурсів при виконанні winMain (див. виклик LoadString).

Примітка

Цей текст є рядком символів “API”, яка зберігається в ресурсах. Її можна побачити, розкривши дерево ресурсів у вікні Resource View, вузол String Table і двічі клацнувши на елементі String Table (Group). За допомогою цього рядка ваше застосування реєструється в операційній системі.

При виконанні функції winMain система передає їй параметри:


Раніше в Win 16 другий параметр використовувався в цілях економії ресурсів, але в Win32 – це NULL, оскільки кожен примірник додатка тепер виконується в своєму власному віртуальному адресному просторі процесу ємністю 4 Гбайт. Всі екземпляри процесу завантажуються починаючи з одного і того ж адреси в цьому просторі (див. останній урок). Тепер розглянемо алгоритм функції WinMain:


Основні атрибути головного вікна додатка задаються в структурі типу WNDCLASSEX. Поняття клас вікна з’явилося до того, як з’явилися класи C + +. Тому структура WNDCLASSEX не має нічого спільного з класами MFC. Вона є типом структур мови С. Справа в тому, що кожне Windows-додаток повинен зареєструвати атрибути свого вікна, а система використовує їх при створенні вікна. Структура WNDCLASSEX своїми полями визначає якийсь шаблон або модель для створення вікон даного класу. У полях структури ви вказуєте необхідні атрибути вікна: адреса виконуваного модуля програми,. Адреса віконної процедури, ім’я ресурсу меню, набір бітів для опису стилю вікна, місцезнаходження зображення курсора, значка і т. д. Цю “нецікаву” роботу виконує велика частина кодів функції MyRegisterClass. Використовуючи класи MFC, ви позбавляєте себе від подібної рутинної роботи.

При реєстрації класу вікон (точніше, змінної типу WNDCLASSEX) операційна система пов’язує віконну процедуру (WndProc) з додатком. В winMain ви повинні зареєструвати головне вікно програми, інші ж вікна, якщо вони потрібні, можуть бути зареєстровані і в інших місцях програми. Адреса заповненої структури передається у функцію RegisterClassEx, яка говорить Windows, що від неї очікується, коли вікна подібного класу з’являються на екрані. Тепер система знає, який вигляд курсора використовувати при попаданні покажчика миші в межі вікна, кому посилати повідомлення про події, що відбуваються в області вікна, які значки (великий 32 х 32 і маленький 16 х 16) будуть пов’язані з додатком і т. д. Функція RegisterClassEx повертає число типу АТОМ (16-ти бітове ціле без знака), яке відповідає рядку реєстрації в таблиці атомів, підтримуваної системою.

Після реєстрації класу головного вікна йде виклик функції Initlnstance, яка намагається створити вікно (CreateWindow) зареєстрованого класу. Якщо система знайшла клас вікна в трьох підтримуваних нею списках зареєстрованих класів вікон, то функція CreateWindow повертає описувач вікна (HWND). Ми запам’ятовуємо його для того, щоб використовувати як параметр при виклику інших функцій. Якщо ні, то функція поверне нульове значення і додаток мовчки завершує свою роботу. Спробуйте при виклику CreateWindow вставити порожній рядок, замість szWindowClass. Запустивши програму, ви зрозумієте, що в гілку if (ihwnd) непогано б вставити виклик:

MessageBox (0, “Не знайшла клас вікна”, “Помилка”, МВ_ОК);

При успішному створенні вікна відбувається виклик функцій

/ / ====== Показати вікно

ShowWindow(hWnd, nCmdShow);

/ / ====== Зробити це, минаючи чергу

UpdateWindow(hWnd);

Далі в коді winMain завантажується таблиця акселераторів (відповідностей клавіатурних комбінацій командам меню), яка використовується в циклі очікування та обробки повідомлень. Функція GetMessage вибирає повідомлення з черги повідомлень потоку і поміщає його в структуру типу MSG, що служить для зберігання інформації про повідомлення Windows. Функція TranslateAccelerator намагається транслювати (перетворити) повідомлення WM_KEYDOWN (Натиснута клавіша) або WM_SYSKEYDOWN (натиснута F10 або ALT + інша клавіша) в повідомлення WM_COMMAND або WM_SYSCOMMAND, але тільки в тому випадку, якщо в таблиці акселераторів присутній код клавіші.

Перетворене повідомлення надсилається безпосередньо у віконну процедуру. Характерно те, що TranslateAccelerator чекає завершення обробки повідомлення. Функція TranslateMessage транслює повідомлення, що надійшли у вигляді віртуальних кодів клавіш, в символьні повідомлення і знову відправляє їх у чергу повідомлень потоку для того, щоб відреагувати на нього на наступній ітерації циклу. Наприклад, повідомлення WM_KEYDOWN (Virtual key message) вона може перетворити в WM_CHAR (character message) або в WM_DEADCHAR (див. MSDN). Функція DispatchMessage відправляє повідомлення віконної процедури.

Коротко алгоритм роботи winMain може бути сформульований так. Після виконання ініціюючих дій функція WinMain входить в цикл обробки повідомлень. Після виходу з цього циклу робота додатка завершується. Вихід відбувається, коли прийде повідомлення WM_QUIT. Зазвичай його посилає віконна процедура, коли користувач закриває головне вікно.

Стартова заготівля ілюструє стандартну послідовність дій при створенні Windows-додатки на базі API-функцій. Зверніть увагу на те, що функція WndProc ніде явно не викликається, хоча саме вона виконує всю корисну роботу. Для перевірки засвоєння прочитаного відповідайте на питання: “Коли і ким вона викликається?”

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*