Программы Win32: консольная (CUI) и оконная (GUI)

Автор работы: Пользователь скрыл имя, 03 Ноября 2014 в 16:17, лекция

Описание работы

Windows поддерживает два типа приложений: основанные на графическом интерфейсе (graphical user interface, GUI) и консольные (console user interface, CUI). У приложений первого типа внешний интерфейс графический, GUI-приложения создают окна, имеют меню, взаимодействуют с пользователем через диалоговые. Почти все стандартные программы Windows — Notepad, Calculator, Wordpad и др — являются GUI-приложениями. Приложения консольного типа работают в текстовом режиме: они не формируют окна, не обрабатывают сообщения и не требуют GUI. И хотя консольные приложения на экране тоже размещаются в окне, в нем содержится только текст. Командные процессоры вроде Cmd.exe (в Windows 2000) или Command.com (в Windows 98) — типичные образцы подобных приложений.

Файлы: 1 файл

2.Программы Win32.doc

— 64.00 Кб (Скачать файл)

 



Системное программирование

Лекция № 2

Программы Win32: консольная (CUI) и оконная (GUI)

План лекции

 

  1. Различия консольной и оконной программ

Windows поддерживает два типа приложений: основанные на графическом интерфейсе (graphical user interface, GUI) и консольные (console user interface, CUI). У приложений первого типа внешний интерфейс графический, GUI-приложения создают окна, имеют меню, взаимодействуют с пользователем через диалоговые. Почти все стандартные программы Windows — Notepad, Calculator, Wordpad и др — являются GUI-приложениями. Приложения консольного типа работают в текстовом режиме: они не формируют окна, не обрабатывают сообщения и не требуют GUI. И хотя консольные приложения на экране тоже размещаются в окне, в нем содержится только текст. Командные процессоры вроде Cmd.exe (в Windows 2000) или Command.com (в Windows 98) — типичные образцы подобных приложений.

Вместе с тем граница между двумя типами приложений весьма условна. Можно, например, создать консольное приложение, способное отображать диалоговые окна. Скажем, в командном процессоре вполне может быть специальная команда, открывающая графическое диалоговое окно со списком команд. В то же время можно создать и GUI-приложение, выводящее текстовые строки в консольное окно.

Когда создается проект приложения, Microsoft Visual C++ устанавливает такие ключи для компоновщика, чтобы в исполняемом файле был указан соответствующий тип подсистемы. Для CUI-программ используется ключ /SUBSYSTEM:CONSOLE, а для GUI-приложений — /SUBSYSTEM:WINDOWS. Когда пользователь запускает приложение, загрузчик операционной системы проверяет номер подсистемы, хранящийся в заголовке образа исполняемого файла, и определяет, что это за программа — GUI или CUI. Если номер указывает на приложение последнего типа, загрузчик автоматически создает текстовое консольное окно, а если номер свидетельствует о противоположном — просто загружает программу в память. После того как приложение начинает работать, операционная система больше не интересуется, к какому типу оно относится.

Во всех Windows-приложениях должна быть входная функция. Существует четыре такие функции:

int WINAPI WinMain (HINSTANCE hinstExe, HINSTANCE,

                    PSTR pszCmdLine, int nCmdShow);

int WINAPT wWinMain (HINSTANCE hinstExe, HINSTANCE,

                     PWSTR pszCmdLine, int nCmdShow);

int _cdecl main (int argc, char*argv[], char*envp[]);

int _cdecl wmain (int argc, wchar_t*argv[], wchar_t*envp[]);

На самом деле входная функция операционной системой не вызывается. Вместо этого происходит обращение к стартовой функции из библиотеки С++. Она инициализирует библиотеку С++, а также обеспечивает корректное создание любых объявленных глобальных и статических С++-объектов до того, как начнется выполнение кода. В следующей таблице показано, в каких случаях реализуются те или иные входные функции.

Тип приложения

Входная функция

Стартовая функция

GUI-приложение, работающее с ANSI-символами и строками

WinMain

WinMainCRTStartup

GUI-приложение, работающее с Unicode-символами и строками

wWinMain

wWinMainCRTStartup

GUI-приложение, работающее с ANSI-символами и строками

main

mainCRTStartup

GUI-приложение, работающее с Unicode-символами и  строками

wmain

wmainCRTStartup


В проекте можно вообще не указывать ключ /SUBSYSTEM компоновщика, тогда компоновщик будет сам определять подсистему для приложения. При компоновке он проверит, какая из четырех функций (WinMain, wWinMain, main или wmain) присутствует в коде, и на основании этого выберет подсистему и стартовую функцию из библиотеки С++.

Все стартовые функции из библиотеки С++ делают практически одно и то же. Разница лишь в том, какие строки они обрабатывают (в ANSI или Unicode) и какую входную функцию вызывают после инициализации библиотеки. А теперь рассмотрим, какие операции они выполняют:

  1. считывают указатель на полную командную строку нового процесса;
  2. считывают указатель на переменные окружения нового процесса;
  3. инициализируют глобальные переменные из библиотеки С++, доступ к которым из кода обеспечивается включением файла StdLib.h.
  4. инициализируют кучу (динамически распределяемую область памяти), используемую С-функциями выделения памяти (malloc и calloc) и другими процедурами низкоуровневого ввода-вывода;
  5. вызывают конструкторы всех глобальных и статических объектов С++-классов.

Когда входная функция возвращает управление, стартовая обращается к функции exit библиотеки С++ и передает ей значение nMainRetVal. Функция exit выполняет следующие операции:

  1. вызывает все функции, зарегистрированные вызовами функции _onexit;
  2. вызывает деструкторы всех глобальных и статических объектов С++-классов;
  3. вызывает Windows-функцию ExitProcess, передавая ей значение nMainRetVal. Это заставляет операционную систему уничтожить процесс и установить код его завершения.
  1. Командная строка процесса

При создании новому процессу передается командная строка. В этой строке как минимум содержится имя исполняемого файла, использованного при создании этого процесса. Параметр pszCmdLine, передаваемый в функцию (w)WinMain представляет собой командную строку без имени исполняемого файла. Причем для функции WinMain – это ANSI-строка, а для wWinMain - Unicode-строка. Указатель на полную командную строку можно получить вызвав функцию

PTSTR GetCommandLine();

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

unsigned int __argc;    //количество компонентов

char**__argv;          //массив указателей на ANSI-строки

wchar_t**__wargv;      //массив указателей на Unicode-строки

  1. Переменные окружения

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

DWORD GetEnvironmentVariable (LPCTSTR lpName,

                              LPTSTR lpBuffer, DWORD nSize);

Через параметр lpName в функцию передается имя переменной окружения, lpBuffer – это указатель на буфер, в который будет помещено значение указанной переменной. Размер передаваемого буфера задается параметром nSize. Многие переменные окружения и строки в реестре имеют формат

%USERPROFILE%\My Documents

Для подстановки действительных значений переменных окружения в таких строках используется функция ExpandEnvironmentStrings:

DWORD ExpandEnvironmentStrings (LPCTSTR lpSrc, LPTSTR lpDst,

                                DWORD nSize);

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

C:\Documents and Settings\Administrator\My Documents

Кроме получения значений переменных окружения и использования их для подстановки в строки программа может изменять их значения. Для этого предназначена функция SetEnvironmentVariable:

DWORD SetEnvironmentVariable(PCTSTR pszName,

                             PCTSTR pszValue);

Эта функция устанавливает переменной окружения pszName значение pszValue. Если значение параметра pszValue равно NULL, то соответствующая переменная удаляется из блока.

  1. Текущие диск и каталог для процесса

Текущий каталог текущего диска – это то место, где системные функции ищут файлы и подкаталоги, если не указаны полные пути к файлам. Поток может получать и устанавливать текущие диск и каталог с помощью следующих функций:

DWORD GetCurrentDirectory(DWORD cchCurDir, PTSTR pszCurDir);

BOOL SetCurrentDirectory(PCTSTR pszCurDir);

  1. Вопросы для самоконтроля

  1. Назовите два типа приложений, поддерживаемых Windows
  2. В каком приложении и с какими строками работает функция WinMain
  3. В каком приложении и с какими строками работает функция main
  4. В каком приложении и с какими строками работает функция wWinMain
  5. В каком приложении и с какими строками работает функция wmain
  6. Что содержится в нулевом элементе массива char*argv[] в функции main (int argc, char*argv[], char*envp[])
  7. Укажите функцию изменения переменных окружения
  8. Что обязательно содержится в передаваемой процессу командной строке
  9. Укажите функцию получения переменных окружения
  10. Что делает функция SetCurrentDirectory()

Информация о работе Программы Win32: консольная (CUI) и оконная (GUI)