47816 (597361), страница 4

Файл №597361 47816 (Ознакомление с приложениями Windows) 4 страница47816 (597361) страница 42016-07-30СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла (страница 4)

Внимательнее разберемся с типом HANDLE (и со всеми “производными” от него): Дело в том, что Windows создает специальные структуры данных, описывающих требуемые объекты (например окно). Эта структура данных зачастую принадлежит не вашему приложению, а самой системе. Для того, что бы этот объект можно было идентифицировать, вводится специальное понятие хендл (дескриптор, handle). Хендл в Windows — это просто целое число, иногда номер, присвоенный данному объекту, причем значение NULL указывает на несуществующий объект. Единственное исключение — HFILE, для которого определено специальное значение — HFILE_ERROR, равное -1 (это связано с тем, что хендл файла первоначально был заимствован у DOS, где хендл 0 обозначает стандартное устройство вывода stdout). Понятие хендла в Windows используется очень широко, а для облегчения контроля типов используется большое количество производных от хендла типов.


Win32

Здесь же надо еще раз отметить, что для Win32 API всегда применяется 32х разрядная flat–модель памяти. В этом случае модификаторы far и near не применяются. Кроме того хендл, соответствующий типу unsigned int, становится 32х разрядным. Это на самом деле приводит к изрядным сложностям при переходе с платформы на платформу. Дело в том, что в Windows API хендл часто объединяется с какими–либо дополнительными данными и размещается в одном двойном слове, передаваемом в качестве параметра функции или сообщения, а в Win32 такое уже не получится — хендл сам занимает все двойное слово.

Кроме того, в Win32 API для работы с файлами используется опять–таки хендл, но уже не типа HFILE, а HANDLE. При этом нулевое значение по–прежнему является допустимым и обозначает стандартное устройство вывода, а значение -1 — неверный хендл. Для обозначения неверного хендла файла определен символ INVALID_HANDLE_VALUE, равный -1. Для других хендлов, кроме хендлов файлов, этот символ не применяется, так как для индикации ошибки применяется значение 0. При этом тип HFILE и символ HFILE_ERROR определены также, как и в 16ти разрядных Windows — в виде 16ти разрядного целого числа. В принципе допустимо простое приведение типов, однако в будущих реализациях Windows API ситуация может измениться, так как тип HANDLE соответствует 32х разрядному числу.

Венгерская нотация

При чтении текстов C—программ и документации Вы обратите внимание на несколько странное написание имен переменных и функций. Например:

lpszFileName, wNameLength

Разработчики Windows рекомендуют применять специфичные правила описания имен переменных, которые получили название “венгерская нотация” по национальности программиста Charles Simonyi из Microsoft, предложившего ее. Применение венгерской нотации улучшает читаемость программ и уменьшает вероятность ошибки. Хотя, конечно, это дается ценой увеличения длины имен переменных.

Хорошим программистским правилом является использование мнемонических имен переменных. Венгерская нотация предполагает не только применение мнемоники для определения смысла переменной (как, например, FileSize), но и включение ее типа в имя. Например lpszFileName обозначает дальний указатель на ASCIIZ7 строку символов, содержащую имя файла.

Как видно из примера, перед мнемоническим именем переменной пишется небольшой префикс, указывающий ее тип. Каким образом строится префикс? Из небольшой таблицы можно получить представление об обозначении основных типов данных:

обозначающий символ

название обозначаемого типа

пояснение

c

char

символ

by

BYTE

байт

n

int

целое число

x

short

координата или размер

y

short

координата или размер

i

int

целое число

f, b

BOOL

логическая величина

w

WORD

слово без знака

h

HANDLE

хендл

l

LONG

длинное целое со знаком

dw

DWORD

длинное целое без знака

e

FLOAT

число с плавающей запятой

*fn

функция

s

строка

sz

строка, оканчивающаяся '\0' (ASCIIZ)

p

*

указатель на ...

lp

far*

дальний указатель на ...

np

near*

ближний указатель на ...

Зная эту таблицу легко самим понять или составить имена переменных в венгерской нотации. Даже если Вы не будете сами применять венгерскую нотацию при написании программ, то знать ее все равно надо, так как она принята во всей документации, сопровождающий Windows. К сожалению даже здесь разработчики оказались не совсем последовательны и Вам придется столкнуться в документации с некорректным (с точки зрения приведенной таблицы) применением венгерской нотации.

Так, в качестве примера можно привести название поля cbWndExtra в структуре WNDCLASS. В данном случае префикс cb расшифровывается как Count of Bytes.



Структура приложения Windows

Итак, еще раз посмотрим на приложение 1a.cpp и вспомним, что надо сделать для написания приложения:

  • написать оконную функцию;

  • зарегистрировать эту функцию в Windows;

  • создать окно, принадлежащее данному классу;

  • обеспечить работу приложения, обрабатывая поступающие окну сообщения.

В рассматриваемом нами примере выполняются все эти действия. Исходный код содержит следующие функции: WinProc, init_instance и WinMain. Здесь WinProc является оконной процедурой, init_instance регистрирует класс окон (оконную процедуру), а WinMain создает окно и обеспечивает работу всего приложения.

Можно коротко рассмотреть основную последовательность действий, происходящих в системе при запуске приложения. Пока, что бы не вникать в сложности, ограничимся обзором работы 16ти разрядного приложения.

  1. Операционная система загружает исполняемый файл в память и выделяет требуемые для первоначальной загрузки ресурсы.

  2. Управление передается специально написанному разработчиками компиляторов startup–коду, который инициализирует приложение, получает необходимую информацию (как, например, командная строка, хендл копии приложения и пр.), запускает конструкторы статических объектов.

  3. startup–код вызывает функцию WinMain, передавая ей полученные от операционной системы данные. Функция WinMain разрабатывается для каждого приложения.

  4. WinMain обычно осуществляет регистрацию класса окон.

  5. Далее WinMain создает и отображает главное окно приложения.

  6. WinMain обеспечивает функционирование приложения, организуя цикл обработки сообщений. В этом цикле приложение извлекает поступающие к нему сообщения, выполняет их предварительную обработку и затем передает их окну–получателю (то есть вызывает необходимую оконную процедуру).

  7. Оконная процедура выполняет обработку сообщений, направленных окну, обеспечивая реакцию задачи на действия пользователя.

  8. Приложение работает, пока пользователь не закроет главное окно этого приложения. В момент закрытия этого окна оконная процедура принимает специальные меры для завершения цикла обработки сообщений, организованного WinMain.

  9. Когда цикл обработки сообщений завершается, WinMain продолжает исполнение своего кода, выполняя, при необходимости, деинициализацию и уничтожение созданных объектов, после чего завершает работу.

  10. Возврат управления из функции WinMain происходит опять–же в промежуточный exit–код, созданный разработчиками компиляторов. Он запускает деструкторы статических объектов, деинициализирует приложение и возвращает управление в систему.

  11. Система освобождает оставшиеся занятыми ресурсы, закрепленные за этим приложением.

Теперь, перед тем как перейти к рассмотрению непосредственно кода приложения, надо сделать последнее замечание. Windows API разрабатывался тогда, когда систем виртуальной памяти на персональном компьютере еще не существовало. Первые версии Windows могли работать на XT с 640K оперативной памяти. Из–за очень ограниченного объема памяти приходилось идти на различные ухищрения. Так один из способов экономии памяти связан с тем, что код приложений обычно не изменяется. Если запустить две копии одного и того–же приложения (скажем, два Notepad’а для редактирования двух разных файлов), то код этих приложений будет одинаковым. В этом случае его можно загружать только один раз, но для необходимости как–то различать разные копии приложения и возникло понятие хендл копии приложения (instance handle, HINSTANCE).


Функция WinMain

Обычная программа на C (C++) содержит так называемую главную процедуру main. При создании программ для Windows тоже необходимо описать такую процедуру, правда она называется WinMain и имеет другие аргументы:

int PASCAL WinMain( HANDLE hInstance, HANDLE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow )
{
// ...
}

Описание главной функции ключевым словом PASCAL указывает на применение соглашений языка Pascal при передаче аргументов и вызове функции (так делается в большинстве функций Windows, потому что вызов pascal–декларированной функции осуществляется чуть быстрее и занимает меньше места, чем C–декларированной).

Рассмотрим ее аргументы:

HANDLE hInstance — этот параметр является хендлом, указывающим конкретную копию приложения. Знание этого хендла потребуется для связи тех или иных данных с конкретной копией.

HANDLE hPrevInstance — описывает хендл предыдущей копии приложения. Если данная копия является первой, то эта переменная содержит NULL. Использование этой информации несколько специфично:

Во–первых, Windows связывает некоторые данные с конкретной копией приложения (например: экспортированные функции, окна и пр.). При связывании необходимо указывать хендл копии приложения.

Внимание: при использовании C++ иногда удобно описать статический объект. Однако в этом случае может потребоваться информация о hInstance для конструктора статического объекта. По странной причине мы ее не можем узнать до вызова WinMain — эта информация известна с самого начала (еще до вызова каких–либо конструкторов): startup–код в самых первых инструкциях обращается к процедуре INITTASK, которая возвращает системную информацию, в том числе hInstance. После этого hInstance копируется в статическую переменную, используемую startup– и exit– кодом, однако эта переменная является локальной (?!) и недоступна для остальных модулей приложения. Причина такого поступка со стороны разработчиков компиляторов остается непонятной.

Во–вторых, некоторые операции должны выполняться только при запуске первой копии приложения, а все остальные копии должны игнорировать эти операции или выполнять вместо них другие. Для пояснения этого обратим внимание на оконную функцию. Когда мы создаем приложение, то мы описываем специфичные оконные функции и регистрируем классы окон. После запуска первой копии (пока она активна) эти классы окон известны Windows. Значит при запуске последующих копий нам не надо их регистрировать.

В–третьих, иногда нам надо получить данные от предыдущей копии приложения (например, если наши приложения организуют обмен данными между собой). С помощью hPrevInstance мы можем сделать это (только в Windows API, в Win32 API это не получится)8.

В–четвертых, 32х битовые приложения Win32 API всегда предполагают, что запущена только одна копия приложения (так как в виртуальном адресном пространстве приложения кроме нее других приложений, в том числе копий, не находится). При этом hInstance указывает начальный адрес загрузки модуля (и для большинства приложений он совпадает), а hPrevInstance всегда равен NULL.

LPSTR lpszCmdLine — как и обычная C–программа, приложение Windows может получать командную строку. Параметр lpszCmdLine является указателем на эту строку.

int nCmdShow — этот параметр указывает, в каком виде должно быть изображено окно приложения. Для описания значений этой переменной существует целый набор #define’ов, начинающихся с префикса SW_. Например, значение nCmdShow равное SW_SHOWMINNOACTIVE указывает на то, что окно должно быть отображено в минимизированном состоянии, а значение SW_SHOWNORMAL указывает на необходимость отображения окна в нормальном состоянии. Пользователь может указать, в каком виде показывать главное окно приложения, настраивая характеристики ярлыка (shortcut).


Регистрация класса окон

После аргументов функции WinMain мы начнем рассматривать непосредственно тело этой процедуры. В самом начале мы должны зарегистрировать класс нашего окна, убедившись в том, что это первая копия приложения. Для этого мы должны заполнить структуру WNDCLASS и передать ее функции RegisterClass:

WNDCLASS WC;

Характеристики

Тип файла
Документ
Размер
2,36 Mb
Тип материала
Учебное заведение
Неизвестно

Список файлов книги

Свежие статьи
Популярно сейчас
Как Вы думаете, сколько людей до Вас делали точно такое же задание? 99% студентов выполняют точно такие же задания, как и их предшественники год назад. Найдите нужный учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
7140
Авторов
на СтудИзбе
254
Средний доход
с одного платного файла
Обучение Подробнее