Visual C для начинающих

         

Первая программа на C++, типы данных и их размер


Что бы начать изучать C++ сначала создадим простое консольное приложение. Для этого запустите Visual C++. Выберите 'New' в меню 'File'. Проверте, что бы в диалоговой панеле 'New' была выбрана закладка 'Projects'. В списке типов проектов выберите 'Win32 Console Application'. Выберите каталог для проекта( лучше оставить по умолчанию ) и имя проекта, например, 'First' и нажмите 'OK'. У вас создатся 'First classes'. После этого выберите опять 'New', но с закладкой 'Files' и выберите 'C++ Source File'. Далее нажмите 'OK' и создастся файл 'First.cpp'. Всё, теперь можно писать программу. Но перед тем, как писать программу, давайте разберёмся какие типы данных существуют в C++.

В C++ существуют несколько часто используемых типов данных( не все ):

1. Численные знаковые целые( int, short, char )

2. Численные знаковые дробные( float, double, long( в С ), long double( в С ) )

3. Численные без знаковые - все перечисленные выше типы с добавлением Unsigned

4. Char так же может использоваться как символьный тип.

Теперь напишем программыу, которая будет выводить размер типов данных в байтах.

#include <iostream.h>


void main( void )

{

cout

cout

cout

cout

cout

cout

cout

}

[ Назад | Оглавление | Далее ]

//

hotlog_js="1.0";hotlog_d=document; hotlog_n=navigator;hotlog_rn=Math.random(); hotlog_n_n=(hotlog_n.appName.substring(0,3)=="Mic")?0:1 hotlog_r=""+hotlog_rn+"&s=7004&r="+escape(hotlog_d.referrer)+"&pg="+ escape(window.location.href) hotlog_d.cookie="hotlog=1"; hotlog_r+="&c="+(hotlog_d.cookie?"Y":"N"); hotlog_d.cookie="hotlog=1; expires=Thu, 01-Jan-70 00:00:01 GMT"

hotlog_js="1.1";hotlog_r+="&j="+(navigator.javaEnabled()?"Y":"N")

hotlog_js="1.2";hotlog_s=screen; hotlog_r+="&wh="+hotlog_s.width+'x'+hotlog_s.height+"&px="+((hotlog_n_n==0)? hotlog_s.colorDepth:hotlog_s.pixelDepth)



Первый способ использования таймера


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

Этот способ самый простой. Вначале вам надо вызывать функцию SetTimer, указав ей в качестве параметров идентификатор окна, идентификатор таймера и период, с которым от таймера должны приходить сообщения: #define FIRST_TIMER 1 int nTimerID; nTimerID = SetTimer(hwnd, FIRST_TIMER, 1000, NULL);

В данном примере создается таймер с идентификатором FIRST_TIMER, который будет посылать сообщения примерно раз в секунду.

Для уничтожения таймера, созданного этим способом, следует вызвать функцию KillTimer, указав параметры следующим образом: KillTimer(hwnd, FIRST_TIMER);

Для изменения интервала посылки сообщений вам следует вначале уничтожить таймер, а потом создать новый, работающий с другим периодом времени: KillTimer(hwnd, FIRST_TIMER); nTimerID = SetTimer(hwnd, FIRST_TIMER, 100, NULL);



Полная компиляция DLL


Если проект динамической библиотеки создан с помощью AppWizard и .def-файл модифицирован соответствующим образом — этого достаточно. Если же файлы проекта создаются вручную или другими способами без помощи AppWizard, в командную строку редактора связей следует включить параметр /DLL. В результате вместо автономного выполняемого файла будет создана библиотека DLL.

Если в .def-файле есть строка LIBRART, указывать явно параметр /DLL в командной строке редактора связей не нужно.

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



Преимущества использования MFC


Как уже упоминалось, MFC – это базовый набор (библиотека) классов, написанных на языке С++ и предназначенных для упрощения и ускорения процесса программирования для Windows. Библиотека содержит многоуровневую иерархию классов, насчитывающую около 200 членов. Они дают возможность создавать Windows-приложения на базе объектно-ориентированного подхода. С точки зрения программиста, MFC представляет собой каркас, на основе которого можно писать программы для Windows.

Библиотека MFC разрабатывалась для упрощения задач, стоящих перед программистом. Как известно, традиционный метод программирования под Windows требует написания достаточно длинных и сложных программ, имеющих ряд специфических особенностей. В частности, для создания только каркаса программы таким методом понадобится около 75 строк кода. По мере же увеличения сложности программы ее код может достигать поистине невероятных размеров. Однако та же самая программа, написанная с использованием MFC, будет примерно в три раза меньше, поскольку большинство частных деталей скрыто от программиста.

Одним из основных преимуществ работы с MFC является возможность многократного использования одного и того же кода. Так как библиотека содержит много элементов, общих для всех Windows-приложений, нет необходимости каждый раз писать их заново. Вместо этого их можно просто наследовать (говоря языком объектно-ориентированного программирования). Кроме того, интерфейс, обеспечиваемый библиотекой, практически независим от конкретных деталей, его реализующих. Поэтому программы, написанные на основе MFC, могут быть легко адаптированы к новым версиям Windows (в отличие от большинства программ, написанных обычными методами).

Еще одним существенным преимуществом MFC является упрощение взаимодействия с прикладным программным интерфейсом (API) Windows. Любое приложение взаимодействует с Windows через API, который содержит несколько сот функций. Внушительный размер API затрудняет попытки понять и изучить его целиком. Зачастую даже сложно проследить, как отдельные части API связанны друг с другом! Но поскольку библиотека MFC объединяет (путем инкапсуляции) функции API в логически организованное множество классов, интерфейсом становится значительно легче управлять.

Поскольку MFC представляет собой набор классов, написанных на языке С++, поэтому программы, написанные с использованием MFC, должна быть в то же время программами на С++. Для этого необходимо владеть соответствующими знаниями. Для начала необходимо уметь создавать собственные классы, понимать принципы наследования и уметь переопределять виртуальные функции. Хотя программы, использующие библиотеку MFC, обычно не содержат слишком специфических элементов из арсенала С++, для их написания тем не менее требуются солидные знания в данной области.

Замечание

. Небольшое число классов, определенных в библиотеке, не связанно непосредственно с программированием под Windows. Это, в частности, классы, предназначенные для создания строк, управления файлами и обработки особых ситуаций. Иногда называемые классами общего назначения, они могут использоваться как Windows-, так и не- Windows-приложениями.



Преимущества мастеров проектов


Рассмотрим преимущества использования мастеров в процессе создания приложений. Прежде всего, нужно отметить, что создание проекта - это не только творчество, но и большой объем технической работы, требующей внимания и аккуратности.

Например, все Windows-приложения имеют достаточно общую структуру, и, следовательно, можно построить некоторые шаблонные заготовки, подходящие для того или иного типа проектов. Построению таких заготовок способствует то, что приложения, создаваемые на основе MFC, строятся из элементов фиксированных классов. Логическим развитием этой идеи было введение специальных классов и специальной архитектуры построения приложения, которая подходила бы широкому классу приложений. О такой архитектуре уже упоминалось, когда речь шла о библиотеке MFC, - это архитектура Document-View. Она является основной, но не единственной при построении проектов в среде Visual C++.

Суть этой архитектуры в том, что работу многих приложений можно рассматривать как обработку документов. При этом можно отделить сам документ, отвечающий за представление и хранение данных, от образа этого документа, видимого на экране и допускающего взаимодействие с пользователем, который просматривает и (или) редактирует документ. В соответствии с этой архитектурой библиотека MFC содержит два семейства классов, производных от базовых классов CDocument и CView.

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

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

Термин остов (приложения, класса, функции) применяется для заготовок, создаваемых инструментальными средствами AppWizard и ClassWizard. Нужно подчеркнуть - остов приложения и каркас приложения - разные понятия.

Создаваемый остов приложения составлен так, что в дальнейшей работе с проектом можно использовать другое инструментальное средство - ClassWizard (мастер классов).



Для получения адреса узла сети


Для получения адреса узла сети TCP/IP по его символическому имени используется библиотечная функция

типа Windows Application


Что бы создать приложение типа Windows Application с использованиеи MFC нужно сделать следующие шаги( создадим для простоты приложение основанное на диалогах ):

1. Запустите Visual C++.

2. Выберите File / New.

3. Выберите закладку "Projects" / "MFC AppWizard( exe )", введите имя проекта( Project name ) и место для проекта( Location ) и нажмите кнопку "OK". В ответ будут выводится диалоговые панели.

4. MFC AppWizard - Step 1. Выберите интересующий тип проекта( простой документ, мулти-документ или документ, основанный на диалогах ) и нажмите кнопку "Next>" ( Вам надо выбрать "Dialog based").

5. MFC AppWizard - Step 2. Нажмите кнопку "Next>".

6. MFC AppWizard - Step 3. Нажмите кнопку "Finish".

7. New Project Information. Нажмите кнопку "OK".

Ну вот и всё, у Вас есть уже готовая программа, потдерживающая MFC.

[ Назад | Оглавление | Далее ]

//



Применение указателей в C++


Напишем следующую программу, которая использует указатели. Предположим, что значение iNum1 равно 2, а адрес iNum1 — 1000. INum1 будет занимать байты с адресами 1000, 1001, 1002 и 1003. Если значение iNum2 было равно, то переменная iNum2 могла бы занимать ячейки с адресами 1004, 1005, 1006 и 1007. Следовательно, iNumI начинается с адреса 1000, а iNum2 начинается с адреса 1004. Однако, хотя iNumI занимает четыре адреса, в С/С++ адресом iNumI называется адрес 1000, а адресом iNum2 называется адрес 1004. Теперь объявим две переменные как указатели — pNum1 и pNum2. Ваша цель состоит в том, чтобы сохранить число 1000 (адрес iNumI) в pNum1 и число 1004 (адрес iNum2) в pNum2.

Внесите следующие изменения в main(void):

void main(void)

{

int iNum1;

int iNum2;

int iResult;

int* pNum1;

int* pNum2;

iNum1 = 2;

iNum2 = 3;

pNum1 = &iNum1;

pNum2 = &iNum2;

iResult = *pNum1 + *pNum2;

cout << "The result is: ";

cout << iResult << endl;

}

Код, который вы ввели, объявляет три целых переменных:

int iNum1;

int iNum2 ;

int iResult;

Затем объявляются еще две переменные:

int* pNum1;

int* pNum2;

Обратите внимание, что в объявлении использована запись int*. К какому же типу относится переменная pNum1? Можете ли вы сохранить целое значение в pNum1? Нет. В pNum1 вы можете сохранить адрес переменной типа int. Вы должны сохранить в переменной pNum1 число 1000, поскольку 1000 является адресом iNum1. Точно так же вы должны сохранять адрес целого значения и в переменной pNum2. После этого вы присваиваете значения переменным iNum1 и iNum2:

iNum1 = 2;

iNum2 = 2;

Затем вы присваиваете значения переменным pNumI и pNum2:

pNum1 = &iNum1;

pNum2 = &iNum2;

Эти два оператора сохраняют адрес переменной iNum1 в pNum1 и адрес iNum2 в pNum2. Далее вам нужно вычислить результат сложения iNum1 с iNum2. Вы могли бы бы просто написать оператор

iResult = iNum1 + iNum2;

Однако попробуем выполнить вычисления, применив указатели, а не переменные. Например, чтобы вычислить результат сложения iNuml и iNum2, вы пишете следующий оператор:



iResult = *pNum1 + *pNum2;


Когда вы используете указатель с предшествующим символом *, вы извлекаете значение, хранящееся по данному адресу. *pNum1 — это то же, что и *1000, так что программа обращается к значению, хранящемуся по адресу 1000. Поскольку переменная pNum1 была объявлена как int* (а компилятор знает, что целое значение занимает четыре байта памяти), программа обращается к адресам 1000, 1001, 1002 и 1003. Она находит по этим адресам значение 2, так как *pNum1 равно 2. Аналогично, *pNum2 равно 3, поскольку pNum2 равно 1004, а ячейки памяти 1004, 1005, 1006 и 1007 содержат целое со значением. И, наконец, выполняется оператор cout, который выводит на экран значение переменной iResult:

cout << "The result is: " << endl;


cout << iResult;

Сохраните свою работу, выполните компиляцию и компоновку программы. Запустите программу и убедитесь, что значение iResult равно 5 (2+3=5).

<


Пример графической программы с оптимизацией


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

Во многих книжках работа с графикой описывается следующим образом:

1. Все графические функции описывабтся в OnPaint().

2. Далее в другом месте программы вызываются функции Invalidate, InvalidateRect или InvalidateRgn.

3. Такой тип построения программы не совсем верен, так как в таком случае обычно всё мигает и это нервирует.

4. Есть немного другой способ работы с графикой и ниже он будет описан.

Этот метод заключается в следующем :

1. Вся графика рисуется в какой-то функции F().

2. По событию таймера или по другим событиям вызывается F().

3. Эдементы графики рисуются сначала в памяти, а потом выводятся на экран.

4. Предворительные расчёты можно вести как в F() так и в других частях программы.

5. Функция OnPaint() содержит копию функции F(), это нужно только для перерисовки окна при изменении его положения или размера.

[ Назад | Оглавление | Далее ]

//



Пример использования MFC в Visual C++


В этой главе будет показано как включить потдержку MFC в Visual C++ на примере двух типов приложений:

1. Консольное приложение

2. Приложение типа Windows Application



Пример обычной DLL и способов загрузки


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

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

MyDLL.h #define EXPORT extern “C” __declspec (dllexport) EXPORT int CALLBACK MyFunction(char *str);

Файл библиотеки также несколько отличается от обычных файлов на языке C для Windows. В нем вместо функции WinMain имеется функция DllMain. Эта функция используется для выполнения инициализации, о чем будет рассказано позже. Для того, чтобы библиотека осталась после ее загрузки в памяти, и можно было вызывать ее функции, необходимо, чтобы ее возвращаемым значением было TRUE:

MyDLL.c #include <windows.h> #include “MyDLL.h”

int WINAPI DllMain(HINSTANCE hInstance, DWORD fdReason, PVOID pvReserved) { return TRUE; } EXPORT int CALLBACK MyFunction(char *str) { MessageBox(NULL,str,”Function from DLL”,MB_OK); return 1; }

После трансляции и компоновки этих файлов появлятся два файла – MyDLL.dll (сама динамически подключаемая библиотека) и MyDLL.lib (ее библиотека импорта).

Пример неявного поключения DLL приложением

Приведем теперь исходный код простого приложения, которое использует функцию MyFunction из библиотеки MyDLL.dll:

#include <windows.h> #include “MyDLL.h”

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { int iCode=MyFunction(“Hello”); return 0; }

Эта программа выглядит как обычная программ для Windows, чем она в сущности и является. Тем не менее, следует обратить внимание, что в исходный ее текст помимо вызова функции MyFunction из DLL-библиотеки включен и заголовочный файл этой библиотеки MyDLL.h. Также необходимо на этапе компоновки приложения подключить к нему библиотеку импорта MyDLL.lib (процесс неявного подключения DLL к исполняемому модулю).


Чрезвычайно важно понимать, что сам код функции MyFunction не включается в файл MyApp.exe. Вместо этого там просто имеется ссылка на файл MyDLL.dll и ссылка на функцию MyFunction, которая находится в этом файле. Файл MyApp.exe требует запуска файла MyDLL.dll.
Заголовочный файл MyDLL.h включен в файл с исходным текстом программы MyApp.c точно так же, как туда включен файл windows.h. Включение библиотеки импорта MyDLL.lib для компоновки аналогично включению туда всех библиотек импорта Windows. Когда програма MyApp.exe работает, она подключается к библиотеке MyDLL.dll точно так же, как ко всем стандартным динамически подключаемым библиотекам Windows.
Пример динамической загрузки DLL приложением
Приведем теперь полностью исходный код простого приложения, которое использует функцию MyFunction из библиотеки MyDLL.dll, используя динамическую загрузку библиотеки:
#include <windows.h> typedef int (WINAPI *PFN_MyFunction)(char *);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { HINSTANCE hMyDll; if((hMyDll=LoadLibrary(“MyDLL”))==NULL) return 1;
PFN_MyFunction pfnMyFunction; pfnMyFunction=(PFN_MyFunction)GetProcAddress(hMyDll,”MyFunction”); int iCode=(*pfnMyFunction)(“Hello”);
FreeLibrary(hMyDll); return 0; }

Пример проекта


Отсюда можно взять рабочую программу под MFC, в которой проигрываются Wave-файлы.

[ Назад | Оглавление | Далее ]

//



Пример Windows-приложения, использующего стандартные ресурсы


Отсюда можно взять рабочую программу в диалоговом режиме, использующего стандартные ресурсы.

[ Назад | Оглавление | Далее ]

//



Пример Windows-приложения, использующего таймер


Отсюда можно взять рабочую программу в диалоговом режиме, использующую таймер. После загрузки программы вы можете нажать на кнопку "Start timer" и услышать периодические звуковые сигналы( 1 сек. ). После нажатия кнопки "End timer" или при закрытие приложения таймер будет уничтожен.

[ Назад | Оглавление | Далее ]

//



Примеры записи и чтения из файла


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

Открытие файла и чтение из него

CString m_Text; …… // создание стандартной панели выбора файла Open CFileDialog DlgOpen(TRUE,(LPCSTR)"txt",NULL, OFN_HIDEREADONLY,(LPCSTR)" Text Files (*.txt) |*.txt||");

// отображение стандартной панели выбора файла Open if(DlgOpen.DoModal()==IDOK) { // создание объекта и открытие файла для чтения CStdioFile File(DlgOpen.GetPathName(),CFile::modeRead|CFile::typeBinary);

// чтение из файла строки CString& ref=m_Text; File.ReadString(ref); // передается ссылка на строку m_Text }

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

Запустите программу - Build / Rebuild all ( будут ошибки ), выберите Build / Set active configuration - Win 32 Realise, выберите пункт меню "Project", далее "Settings...", закладку "C/C++", Category - Code Generation и в пункте "Use run-time library" выберите "Multithreaded". После этого сделайте опять Build / Rebuild all и программа будет работать.

Открытие файла и запись из него

CString m_Text; …… // создание стандартной панели выбора файла SaveAs CFileDialog DlgSaveAs(FALSE,(LPCSTR)"txt",NULL, OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT, (LPCSTR)" Text Files (*.txt) |*.txt||");

// отображение стандартной панели выбора файла SaveAs if(DlgSaveAs.DoModal()==IDOK) { // создание объекта и открытие файла для записи CStdioFile File(DlgSaveAs.GetPathName(), CFile::modeCreate|CFile::modeWrite|CFile::typeBinary);

// запись в файл строки File.WriteString((LPCTSTR)m_Text); }

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

Запустите программу - Build / Rebuild all ( будут ошибки ), выберите Build / Set active configuration - Win 32 Realise, выберите пункт меню "Project", далее "Settings...", закладку "C/C++", Category - Code Generation и в пункте "Use run-time library" выберите "Multithreaded". После этого сделайте опять Build / Rebuild all и программа будет работать.



Проект приложения


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

В среде Visual C++ можно строить различные типы проектов. Такие проекты после их создания можно компилировать и запускать на исполнение. Фирма Microsoft разработала специальный инструментарий, облегчающий и ускоряющий создание проектов в среде Visual C++. Например, мастер MFC AppWizard (exe) позволяет создать проект Windows-приложения которое имеет однодокументный, многодокументный или диалоговый интерфейс и использует библиотеку MFC.

Создаваемый остов приложения составлен так, что в дальнейшей работе с проектом можно использовать другое инструментальное средство - ClassWizard (мастер классов), предназначенное для создания остовов новых производных классов. Еще одно основное назначение ClassWizard в том, что он создает остовы для переопределяемых методов. Он позволяет показать все сообщения, приходящие классу, и создать остов обработчика любого из этих сообщений. Это только две основные функции ClassWizard. Он не всесилен, но его возможности довольно велики.



Программная среда Windows


Рассмотрим наиболее важные моменты работы Windows и принципы взаимодействия программ с ней.

Интерфейс вызовов функций в Windows

Благодаря данному интерфейсу доступ к системным ресурсам осуществляется через целый рад системных функций. Совокупность таких функций называется прикладным программным интерфейсом, или API (Application Programming Interfase). Для взаимодействия с Windows приложение запрашивает функции API, с помощью которых реализуются все необходимые системные действия, такие как выделение памяти, вывод на экран, создание окон и т.п.

Библиотека MFC инкапсулирует многие функции API. Хотя программам и разрешено обращаться к ним напрямую, все же чаще это будет выполняться через соответствующие функции-члены. Как правило, функции-члены либо аналогичны функциям API, либо непосредственно обращаются к нужной части интерфейса.

Библиотеки динамической загрузки (DLL)

Поскольку API состоит из большого числа функций, может сложиться впечатление, что при компиляции каждой программы, написанной для Windows, к ней подключается код довольно значительного объема. В действительности это не так. Функции API содержатся в библиотеках динамической загрузки (Dynamic Link Libraries, или DLL), которые загружаются в память только в тот момент, когда к ним происходит обращение, т.е. при выполнении программы. Рассмотрим, как осуществляется механизм динамической загрузки.

Динамическая загрузка обеспечивает ряд существенных преимуществ. Во-первых, поскольку практически все программы используют API-функции, то благодаря DLL-библиотекам существенно экономится дисковое пространство, которое в противном случае занималось бы большим количеством повторяющегося кода, содержащегося в каждом из исполняемых файлов. Во-вторых, изменения и улучшения в Windows-приложениях сводятся к обновлению только содержимого DLL-библиотек. Уже существующие тексты программ не требуют перекомпиляции.

Win16 или Win32

В настоящее время широко распространены две версии API. Первая называется Win16 и представляет собой 16-разрядную версию, используемую в Windows 3.1. Вторая, 32-разрядная версия, называется Win32 и используется в Windows 95 и Windows NT. Win32 является надмножеством для Win16 (т.е. фактически включает в себя этот интерфейс), так как большинство функций имеет то же название и применяется аналогичным образом. Однако, будучи в принципе похожими, оба интерфейса все же отличаются друг от друга. Win32 поддерживает 32-разрядную линейную адресацию, тогда как Win16 работает только с 16-разрядной сегментированной моделью памяти. Это привело к тому, что некоторые функции были модифицированы таким образом, чтобы принимать 32-разрядные аргументы и возвращать 32-разрядные значения. Часть из них пришлось изменить с учетом 32-разрядной архитектуры. Была реализована поддержка потоковой многозадачности, новых элементов интерфейса и прочих нововведений Windows.


Так как Win32 поддерживает полностью 32-разрядную адресацию, то логично, что целые типы данных (intergers) также объявлены 32-разрядными. Это означает, что переменные типа int и unsignerd будут иметь длину 32 бита, а не 16, как в Windows 3.1. Если же необходимо использовать переменную или константу длиной 16 бит, они должны быть объявлены как short. (дальше будет показано, что для этих типов определены независимые typedef-имена.) Следовательно, при переносе программного кода из 16-разрядной среды необходимо убедиться в правильности использования целочисленных элементов, которые автоматически будут расширены до 32 битов, что целочисленных элементов, которые автоматически будут расширены до 32 битов, что может привести к появлению побочных эффектов.

Другим следствием 32-разрядной адресации является то, что указатели больше не нужно объявлять как near и far. Любой указатель может получить доступ к любому участку памяти. В Windows 95 и Windows NT константы near и far объявлены (с помощью директивы #define)пустыми.

Интерфейс GDI

Одним из подмножеств API является GDI (Graphics Device Interfase – интерфейс графического устройства). GDI – это та часть Windows, которая обеспечивает поддержку аппаратно-независимой графики. Благодаря функциям GDI Windows-приложение может выполняться на самых различных компьютерах.

Многозадачность в Windows

Как известно, все версии Windows поддерживают многозадачность. В Windows 3.1 имеется только один тип многозадачности – основанный на процессах. В более передовых системах, таких как Windows 95 и Windows NT, поддерживается два типа многозадачности: основанный на процессах и основанный на потоках. Давайте рассмотрим их чуть подробнее.

Процесс

– это программа, которая выполняется. При многозадачности такого типа две или более программы могут выполняться параллельно. Конечно, они по очереди используют ресурсы центрального процессора и с технической точки зрения, выполняются неодновременно, но благодаря высокой скорости работы компьютера это практически незаметно.



Поток

– это отдельная часть исполняемого кода. Название произошло от понятия “направление протекания процесса”. В многозадачности данного типа отдельные потоки внутри одного процесса также могут выполняться одновременно. Все процессы имеют по крайней мере один поток, но в Windows 95 и Windows NT их может быть несколько.

Отсюда можно сделать вывод, что в Windows 95 и Windows NT допускается существование процессов, две или более частей которых выполняются одновременно. Оказывается, такое предположение верно. Следовательно, при работе в этих операционных системах возможно параллельное выполнение, как программ, так и отдельных частей самих программ. Это позволяет писать очень эффективные программы.

Есть и другое существенное различие между многозадачностями Windows 3.1 и Windows 95/NT. В Windows 3.1 используется неприоритетная многозадачность. Это означает, что процесс, выполняющийся в данный момент, получает доступ к ресурсам центрального процессора и удерживает их в течение необходимого ему времени. Таким образом, неправильно выполняющаяся программа может захватить все ресурсы процессора и не давать выполняться другим процессам. В отличие от этого в Windows 95 и Windows NT используется приоритетная многозадачность. В этом случае каждому активному потоку предоставляется определенный промежуток времени работы процессора. По истечению данного промежутка управление автоматически передается следующему потоку. Это не дает возможность программам полностью захватывать ресурсы процессора. Интуитивно должно быть понятно, что такой способ более предпочтителен.

Взаимодействие программ и Windows

Во многих операционных системах взаимодействие между системой и программой инициализирует программа. Например, в DOS программа запрашивает разрешение на ввод и вывод данных. Говоря другими словами, не- Windows-программы сами вызывают операционную систему. Обратного процесса не происходит. В Windows все совершенно наоборот: именно система вызывает программу. Это осуществляется следующим образом: программа ожидает получения сообщения от Windows. Когда это происходит, то выполняется некоторое действие. После его завершения программа ожидает следующего сообщения.

Windows может посылать программе сообщения множества различных типов. Например, каждый раз при щелчке мышью в окне активной программы посылается соответствующее сообщение. Другой тип сообщений посылается, когда необходимо обновить содержимое активного окна. Сообщения посылаются также при нажатии клавиши, если программа ожидает ввода с клавиатуры. Необходимо запомнить одно: по отношению к программе сообщения появляются случайным образом. Вот почему Windows-программы похожи на программы обработки прерываний: невозможно предсказать, какое сообщение появиться в следующий момент.


Проигрывание Wave-файла с диска


Для проигрывания WAVE-файла с диска можно использовать функцию :

BOOL sndPlaySound( LPCTSTR lpszSoundName; UINT fuOptions; );

Параметры функции:

lpszSoundName

Имя файла. Если этот параметр NULL, то проигрывание файла останавливается.

fuOptions

Специальные опции для проигрывания музыки. Они могут быть следующими:

Значение Описание

SND_SYNC Музыка играется синхронно, и функция не возвращает указатель пока не будет конца файла. SND_ASYNC Музыка играется асинхронно, и функция возвращает указатель сразу после начала проигрывания файла. Чтобы остановить проигрывание, надо вызвать функцию SndPlaySound с параметром lpszSoundName установленным в NULL. SND_NODEFAULT Если файл не найден, то функция возвращает указатель сразу и не проигрывает стандартный звуковой эффект Windows. SND_MEMORY Этот параметр нужен для проигрывания Wave-файла в виде ресурса( из памяти ). SND_LOOP Этот параметр нужен для проигрывания Wave-файла в циклическом режиме. Также при этом вы должны использовать влаг SND_ASYNC. Чтобы остановить проигрывание, надо вызвать функцию SndPlaySound с параметром lpszSoundName установленным в NULL. SND_NOSTOP Если музыка уже проигрывается, то функция возврвщает FALSE.

Возвращаемое значение:

Если музыка проигрывается правильно, то функция возврвщает TRUE, иначе FALSE.

Пример использования:

BOOL bOk = sndPlaySound( "test.wav", SND_SYNC);

if (!bOk) { AfxMessageBox("Error ! Can not play the sound. !!!"); }



Проигрывание Wave-файла в виде ресурса


Первым делом надо создать ресурс, для этого в файле mysound.rc2 надо вписать строчку IDSOUND_CORRECT sound res\correct.wav, где IDSOUND_CORRECT - индефикатор ресурса, sound - тип ресурса( название можно менять ), res\correct.wav - файл ресурса. После этого в файле Resource.h надо зарегистрировать ресурс: #define IDSOUND_CORRECT 130. Число 130 не должно совпадать с другими числами.

Как только ресурс зарегистрирован можно написать в файле mysoundDlg.cpp функции проигрывания этого ресурса :



Проигрывание Wave-файлов под MFC


1. Введение

2. Проигрывание Wave-файла в виде ресурса

3. Проигрывание Wave-файла с диска

4. Пример проекта



Простая программа, использующая MDI интерфейс


В этом разделе рассматривается программа использующая MDI ( интерфейс многих документов )

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



Работа с библиотеками динамической компоновки (DLL)


Использование DLL

Библиотеки импортирования

Согласование интерфейсов

Загрузка неявно подключаемой DLL

Динамическая загрузка и выгрузка DLL

Пример обычной DLL и способов загрузки

Создание DLL

Функция DllMain

Экспортирование функций из DLL

Экспортирование классов

Память DLL

Полная компиляция DLL

DLL и MFC

Обычные MFC DLL

Динамические расширения MFC

Загрузка динамических расширений MFC

Экспортирование функций из динамических расширений

С самого рождения (или чуть позже) операционная система Windows использовала библиотеки динамической компоновки DLL (Dynamic Link Library), в которых содержались реализации наиболее часто применяемых функций. Наследники Windows — NT и Windows 95, а также OS/2 — тоже зависят от библиотек DLL в плане обеспечения значительной части их функциональных возможностей.

Рассмотрим ряд аспектов создания и использования библиотек DLL:

как статически подключать библиотеки DLL;

как динамически загружать библиотеки DLL;

как создавать библиотеки DLL;

как создавать расширения МFC библиотек DLL.



Работа с COM портами( CreateFile )


В этой главе будет написана программа, которая работает с COM портом.
Для этого будут использоваться следующие функции:

HANDLE CreateFile(LPCTSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDistribution, DWORDdwFlagsAndAttributes, HANDLE hTemplateFile);

и

BOOL WriteFile( HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped );

Первый параметр функции CreateFile - имя файла, но если вы поставите там имя COM1, то эта функция будет работать с первым COM портом. Также можно поставить: COM2, COM3, COM4, LPT, CON, AUX.

Ниже приведён кусок кода записи данных в COM порт.



Работа с файлами с помощью MFC( классы CFile, CStdioFile, ) и стандартный класс MFC CFileDialog


Класс CFile

Класс CMemFile

Класс CStdioFile

Примеры записи и чтения из файла

В библиотеку MFC включено несколько классов для обеспечения работы с файлами. Рассматриваемые ниже классы наследуются от базового класса CFile.



Работа с файлами в C ( работает и в C++ )


#include <iostream.h>

#include <stdio.h>

void main( void )

{

FILE *file;

char* file_name = "file.txt";

char load_string[50] = "none";

file = fopen( file_name, "w" );

fputs( "string", file );

fclose( file );

file = fopen( file_name, "r" );

if( file != 0 )

{

fgets( load_string, 50 , file );

cout }

else

{

cout

}

fclose(file);
}

Описание функций работы с файломи находятся в библиотеке stdio.h

Сначала надо создать указатель на переменную типа FILE ( FILE* file; ).

Открытие файла производится вызовом функции fopen ( file = fopen( file_name, "w" ); )

Первый параметр этой функции - имя файла, второй - указывает в каком режиме должен быть открыт файл. "w" - открыть для записи, "r" - открыть для чтения, "a" - дополнение файла( это наиболее используемые режимы, хотя есть и другие ). Запись и считывание данных из файла осуществляется следующими функциями : fputc, fputs, fgetc, fgets, fprintf, fscanf( описание этих функций смотрите в stdio.h).

Закрытие файла осуществляется вызовом функции fclose ( fclose( file ); ).



Работа с некоторыми Win API функциями( информация о системе )


В этой главе будет рассмотрены некоторые Win API функции:



Работа с WinSocket


Socket (гнездо, разъем) - абстрактное программное понятие, используемое для обозначения в прикладной программе конечной точки канала связи с коммуникационной средой, образованной вычислительной сетью. При использовании протоколов TCP/IP можно говорить, что socket является средством подключения прикладной программы к порту локального узла сети.

Socket-интерфейс представляет собой просто набор системных вызовов и/или библиотечных функций языка программирования СИ, разделенных на четыре группы:

Ниже рассматривается подмножество функций socket-интерфейса, достаточное для написания сетевых приложений, реализующих модель "клиент-сервер" в режиме с установлением соединения. Все функции сокетов содержаться в wsock32.dll перед тем как написать программу с использование функций сокетов необходимо задать компилятору чтобы он включил в программу файл wsock32.lib. В меню Рroject выберите пункт settings а там укажите раздел Link, wsock32.lib можно ввести в поле Library modules или project options. Не забудьте поставить #include "Winsock2.h".



Работа со стандартными ресурсами


1. Методы класса CButton
2. Методы класса CEdit
3. Методы класса CListBox

4. Методы класса CComboBox

5. Методы класса CProgressCtrl

6. Методы класса CSliderCtrl

7. Методы класса CSpinButtonCtrl

8. Пример Windows-приложения, использующего стандартные ресурсы



Сначала создадим проект tab_control




Для начала сделайте первые три пункта, создайте переменную m_ctrTab класса CTabCtrl. После этого в функцие BOOL CTab_controlDlg::OnInitDialog() добавте следующее:



SOCKADDR_IN anAddr; anAddrsin_family


Заполнение структуры производится почти также но нeжно указать теперь IP адрес сервера ( пример 127.0.0.1 ) .Дальше сразу можно соединятся:

connect(s, (struct sockaddr *)&anAddr, sizeof(struct sockaddr));

Для обращения программы-клиента к серверу с запросом на установление логической соединения используется системный вызов connect, имеющий следующий вид



SOCKADDR_IN from; int fromlen=sizeof(from); s= accept(s,(struct sockaddr*)&from, &fromlen);


Это зделано для того что бы узнать IP адрес и порт удаленного компьютера. Что бы вывести на экран IP адрес и порт удаленного компа просто вставить в программу такие строки:

printf("accepted connection from %s, port %d\n", inet_ntoa(from.sin_addr), htons(from.sin_port)) ;

Для приема запросов от программ-клиентов на установление связи в программах-серверах используется системный вызов accept, имеющий следующий вид:



SOCKADDR_IN sin; sinsin_family = AF_INET; sinsin_port = htons(); sinsin_addrs_addr = INADDR_ANY;


Структура SOCKADDR_IN используется несколькими системными вызовами и функциями socket-интерфейса и определена в include-файле in.h следующим образом:



Соглашение об именах


Если Вы не знакомы с программированием под Windows, некоторые имена и описания, употребляемые в каркасной программе, могут показаться несколько необычными. Однако они соответствуют соглашениям, представленным фирмой Microsoft для программирования под Windows. Для функций используются имена, построенные из глаголов и существительных, причем первые буквы этих слов — заглавные.

Для имен переменных Microsoft предлагает более сложную систему, предусмат ривающую обозначение именуемых типов данных. Для этого используется неболь шой префикс из строчных букв, а собственно имя начинается с заглавной буквы, Типы префиксов представлены в нижеследующей таблице. Откровенно говоря, использование префиксов, обозначающих тип данных, спорно и не всегда адекватно. Большинство Windows-программистов прибегают к такой системе имено вания, но Вы в своих программах можете поступать по своему усмотрению.

Префикс - Тип данных

-------------------------------------------------------

b - Булевский (байт).

с - Символ (байт).

s - Строка ( char или CString ).
dw - Длинное беззнаковое целое (DWORD).

f - 16-битный флаг (битовая карта).

fn - Функция.

h - Дескриптор (handle).

l - Длинное целое (long).

i - Данные типа Int.

lр - Длинный указатель (long pointer).

n - Целое (16 бит).

р - Указатель (pointer).

pt - Точка (два 32-битных целых).

w - Целое без знака (WORD, 16 бит).

sz - Указатель на строку, заканчивающуюся 0 (string>zero).

Ipsz - Длинный указатель на sz (long pointer string zero).

rgb - Длинное целое, содержащее цветовую комбинацию RGB.

[ Назад | Оглавление | Далее ]

//

hotlog_js="1.0";hotlog_d=document; hotlog_n=navigator;hotlog_rn=Math.random(); hotlog_n_n=(hotlog_n.appName.substring(0,3)=="Mic")?0:1 hotlog_r=""+hotlog_rn+"&s=7004&r="+escape(hotlog_d.referrer)+"&pg="+ escape(window.location.href) hotlog_d.cookie="hotlog=1"; hotlog_r+="&c="+(hotlog_d.cookie?"Y":"N"); hotlog_d.cookie="hotlog=1; expires=Thu, 01-Jan-70 00:00:01 GMT"



Согласование интерфейсов


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

Если бы мир был совершенен, то программистам не пришлось бы беспокоиться о согласовании интерфейсов функций при подключении библиотек — все они были бы одинаковыми. Однако мир далек от совершенства, и многие большие программы написаны с помощью различных библиотек без C++.

По умолчанию в Visual C++ интерфейсы функций согласуются по правилам C++. Это значит, что параметры заносятся в стек справа налево, вызывающая программа отвечает за их удаление из стека при выходе из функции и расширении ее имени. Расширение имен (name mangling) позволяет редактору связей различать перегруженные функции, т.е. функции с одинаковыми именами, но разными списками аргументов. Однако в старой библиотеке С функции с расширенными именами отсутствуют.

Хотя все остальные правила вызова функции в С идентичны правилам вызова функции в C++, в библиотеках С имена функций не расширяются. К ним только добавляется впереди символ подчеркивания (_).

Если необходимо подключить библиотеку на С к приложению на C++, все функции из этой библиотеки придется объявить как внешние в формате С:

extern "С" int MyOldCFunction(int myParam);

Объявления функций библиотеки обычно помещаются в файле заголовка этой библиотеки, хотя заголовки большинства библиотек С не рассчитаны на применение в проектах на C++. В этом случае необходимо создать копию файла заголовка и включить в нее модификатор extern "C" к объявлению всех используемых функций библиотеки. Модификатор extern "C" можно применить и к целому блоку, к которому с помощью директивы #tinclude подключен файл старого заголовка С. Таким образом, вместо модификации каждой функции в отдельности можно обойтись всего тремя строками:

extern "С" { #include "MyCLib.h" }

В программах для старых версий Windows использовались также соглашения о вызове функций языка PASCAL для функций Windows API. В новых программах следует использовать модификатор winapi, преобразуемый в _stdcall. Хотя это и не стандартный интерфейс функций С или C++, но именно он используется для обращений к функциям Windows API. Однако обычно все это уже учтено в стандартных заголовках Windows.



Сообщение WM_TIMER


Параметр wParam сообщения WM_TIMER содержит идентификатор таймера, который был указан или получен от функции SetTimer при создании таймера.

С помощью параметра lParam можно определить адрес функции, которая обрабатывает сообщения таймера.

После обработки этого сообщения приложение должно возвратить нулевое значение.

Заметим, что сообщение WM_TIMER является низкоприоритетным. Это означает, что функция DispatchMessage посылает это сообщение приложению только в том случае, если в очереди приложения нет других сообщений. В этом отличие таймера Windows от аналогичных средств MS-DOS, реализованных с помощью перехвата прерывания INT8h.

Выполнение программы MS-DOS прерывается синхронно с приходом аппаратного прерывания таймера и программа MS-DOS, перехватившая это прерывание, немедленно оповещается о нем. Выполнение приложения Windows тоже, разумеется, прерывается по аппаратному прерыванию таймера, но оповещение об этом событии приходит не всегда, и как правило, позже, вместе с сообщением WM_TIMER.



Создание DLL


Теперь, познакомившись с принципами работы библиотек DLL в приложениях, рассмотрим способы их создания. При разработке приложении функции, к которым обращается несколько процессов, желательно размещать в DLL. Это позволяет более рационально использовать память в Windows.

Проще всего создать новый проект DLL с помощью мастера AppWizard, который автоматически выполняет многие операции. Для простых DLL, таких как рассмотренные в этой главе, необходимо выбрать тип проекта Win32 Dynamic-Link Library. Новому проекту будут присвоены все необходимые параметры для создания библиотеки DLL. Файлы исходных текстов придется добавлять к проекту вручную.

Если же планируется в полной мере использовать функциональные возможности MFC, такие как документы и представления, или намерены создать сервер автоматизации OLE, лучше выбрать тип проекта MFC AppWizard (dll). В этом случае, помимо присвоения проекту параметров для подключения динамических библиотек, мастер проделает некоторую дополнительную работу. В проект будут добавлены необходимые ссылки на библиотеки MFC и файлы исходных текстов, содержащие описание и реализацию в библиотеке DLL объекта класса приложения, производного от CWinApp.

Иногда удобно сначала создать проект типа MFC AppWizard (dll) в качестве тестового приложения, а затем — библиотеку DLL в виде его составной части. В результате DLL в случае необходимости будет создаваться автоматически.



Создание и уничтожение таймера


Для создания виртуального таймера приложение должно использовать функцию SetTimer: UINT WINAPI SetTimer(HWND hwnd, UINT idTimer, UINT uTimeout, TIMERPROC tmprc);

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

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

Если первый параметр указан как NULL, второй параметр функции игнорируется, так как для таймера задана специальная функция, получающая сообщения только от этого таймера.

Третий параметр (uTimeout) определяет период следования сообщений от таймера в миллисекундах. Учтите, что физический таймер тикает приблизительно 18,21 раза в секунду (точное значение составляет 1000/54,925). Поэтому, даже если вы укажете, что таймер должен тикать каждую миллисекунду, сообщения будут приходить с интервалом не менее 55 миллисекунд.

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

Тип TIMERPROC описан в файле windows.h следующим образом: typedef void (CALLBACK* TIMERPROC)(HWND hwnd, UINT msg, UINT idTimer, DWORD dwTime);

Сравните это с описанием типа WNDPROC, который используется для знакомой вам функции окна: typedef LRESULT (CALLBACK* WNDPROC)(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);

Как видно из описания, функция таймера не возвращает никакого значения, имеет другие (по сравнению с функцией окна) параметры, но описана с тем же ключевым словом CALLBACK: #define CALLBACK _far _pascal


Возвращаемое функцией SetTimer значение является идентификатором созданного таймера (если в качестве первого параметра функции было указано значение NULL). В любом случае функция SetTimer возвращает нулевое значение, если она не смогла создать таймер. В Windows версии 3.0 максимальное количество созданных во всей системе таймеров было 16. Для Windows версии 3.1 это ограничение снято.

Тем не менее, если приложение больше не нуждается в услугах таймера, оно должно уничтожить таймер, вызвав функцию KillTimer: BOOL WINAPI KillTimer (HWND hwnd, UINT idTimer);

Первый параметр функции (hwnd) определяет идентификатор окна, указанный при создании таймера функцией SetTimer.

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

Функция KillTimer возвращает значение TRUE при успешном уничтожении таймера или FALSE, если она не смогла найти таймер с указанным идентификатором.


Создание клиента


Программа клиента делается аналогично до момента создания сокетов. Cоздайте сокет так как описано выше, но не пользуйтесь командой bind:



Создание проекта программы


1. Создайте новый проект( у меня MDI ), использующая MDI интерфейс с поддержкой MFC. Все шесть шагов в MFC AppWizard оставте без изменения.

2. Если вы сделали всё правильно, то создадутся пять классов : CMDIApp, CMainFrame, CChildFrame, CMDIDoc и CMDIView. В классе документов CMDIDoc вы пишите код для поддержки данных программы, а в классе представления CMDIView - код, отвечающий за то, что вы видите на экране. Вы будете писать код в функциях-элементах только этих двух классов.

3. Объявляем элементы данных класса документа. Их будет два : координаты круга по X

и по Y. Для этого открываем файл CMDIDoc.h и изменяем объявление класса CMDIDoc следующим образом:



Создание простого FTP-клиента


В этой главе будет написана программа, которая может считывать файлы из Internet по FTP протоколу и записывать их на диск.
Для связи с Internet в Visual C++ существует так называемый WinInet Class. В него входят несколько подклассов.

Далее представлены ксассы WinInet:

CHttpConnection.

CGopherFile and

CHttpFile.

CFtpFileFind and

CGopherFileFind.

Наша программа будет использовать три класса WinInet: CInternetSession, CFtpFileFind и CFtpConnection

Далее будут описаны методы( функции ) этих классов:

Методы ( функции ) класса CInternetSession

Классы Описание
CInternetSession Создаёт Internet сессию. Все MFC WinInet приложения должны создавать CInternetSession объект перед использрванием других WinInet классов.
CInternetConnection Создаёт коннект с Internet. Это базовый класс для классов CFtpConnection, CGopherConnection, и
CFtpConnection Устанавливает соединение по FTP протоколу.
CGopherConnection Создаёт Gopher коннект.
CHttpConnection Устанавливает соединение по HTTP протоколу.
CInternetFile Разрешает удалённый доступ к файлам на Internet серверах. Это базовый класс для классов
CGopherFile Разрешает удалённый доступ к файлам на Gopher серверах.
CHttpFile Разрешает удалённый доступ к файлам на HTTP серверах.
CFileFind Разрешает поиск файлов в Internet. Это базовый класс для классов
CFtpFileFind Разрешает поиск файлов на FTP серверах.
CGopherFileFind Разрешает поиск файлов на Gopher серверах.
CGopherLocator Отыскивает Gopher устройство ввода позиций от gopher сервера.
CInternetException Управляет исключениями, сгенерированными WinInet классом.

<


br>

Методы ( функции ) класса CFtpConnection

Функции Описание
Close() Закрывает Internet сессию.
EnableStatusCallback() Разрешает использование функции повторного вызова, которая используется для асинхронных действий.
GetContext() Получает значение контекста Internet сессии.
GetFtpConnection() Устанавливает подключение по FTP протоколу.
GetGopherConnection() Устанавливает подключение с Gopher серверами.
GetHttpConnection() Устанавливает подключение по HTTP протоклолу.
OnStatusCallback() Модифицирует состояние операции.
OpenURL() Соединяется с данным URL.
QueryOption() Сервис проверки ошибки провайдера.
ServiceTypeFromHandle() Получает тип сервиса от Internet дескриптора.
SetOption() Устанавливает опции Internet сессии.
Методы ( функции ) класса CFtpFileFind

Функции Описание
BOOL SetCurrentDirectory( LPCTSTR pstrDirName ) Устанавливает текущую FTP директорию.
BOOL GetCurrentDirectory( CString& strDirName ) const Записывает в strDirName текущую FTP директорию .
BOOL RemoveDirectory( LPCTSTR pstrDirName ) Удаляет директорию на сервере.
BOOL CreateDirectory( LPCTSTR pstrDirName ) Создаёт директорию на сервере.
BOOL Rename( LPCTSTR pstrExisting, LPCTSTR pstrNew ) Переименовывает файл на сервере.
BOOL Remove( LPCTSTR pstrFileName ) Удаляет файл на сервере.
BOOL PutFile( LPCTSTR pstrLocalFile, LPCTSTR pstrRemoteFile, DWORD dwFlags = FTP_TRANSFER_TYPE_BINARY, DWORD dwContext = 1 ) Кладёт локальный файл на сервер.
BOOL GetFile( LPCTSTR pstrRemoteFile, LPCTSTR pstrLocalFile, BOOL bFailIfExists = TRUE, DWORD dwAttributes = FILE_ATTRIBUTE_NORMAL, DWORD dwFlags = FTP_TRANSFER_TYPE_BINARY, DWORD dwContext = 1 ) Записывает файл с сервера на локальный диск.
CInternetFile* OpenFile( LPCTSTR pstrFileName, DWORD dwAccess = GENERIC_READ, DWORD dwFlags = FTP_TRANSFER_TYPE_BINARY, DWORD dwContext = 1 ) Открывает файл по FTP протоколу.
virtual void Close( ) Закрывает коннект с FTP сервером.
Далее напишем код программы и разберём каждую строчку:


Создание простого HTTP-клиента


Функции Описание
virtual BOOL FindFile( LPCTSTR pstrName = NULL, DWORD dwFlags = INTERNET_FLAG_RELOAD ) Включает функцию поиска файла, если pstrName = NULL, то ишет все файлы(*.*) .
virtual BOOL FindNextFile( ) Ишет следующий файл. До вызова этой функции должна быть вызвана ф-я FindFile()
CString GetFileURL( ) const Возвращает URL найденного файла.
CString GetFileName( VOID ) Возвращает имя файла.
unsigned long GetLength( VOID ) const Возвращает длину файла.

В этой главе будет написана программа, которая может считывать файлы из Internet по HTTP протоколу и записывать их на диск.
Для связи с Internet в Visual C++ существует так называемый WinInet Class. В него входят несколько подклассов.

Далее представлены ксассы WinInet:

CHttpConnection.

CGopherFile and

CHttpFile.

CFtpFileFind and

CGopherFileFind.

Наша программа будет использовать четыре класса WinInet: CInternetSession, CInternetFile, CHttpFile и CHttpConnection

Далее будут описаны методы( функции ) этих классов:

Методы ( функции ) класса CInternetSession

Классы Описание
CInternetSession Создаёт Internet сессию. Все MFC WinInet приложения должны создавать CInternetSession объект перед использрванием других WinInet классов.
CInternetConnection Создаёт коннект с Internet. Это базовый класс для классов CFtpConnection, CGopherConnection, и
CFtpConnection Устанавливает соединение по FTP протоколу.
CGopherConnection Создаёт Gopher коннект.
CHttpConnection Устанавливает соединение по HTTP протоколу.
CInternetFile Разрешает удалённый доступ к файлам на Internet серверах. Это базовый класс для классов
CGopherFile Разрешает удалённый доступ к файлам на Gopher серверах.
CHttpFile Разрешает удалённый доступ к файлам на HTTP серверах.
CFileFind Разрешает поиск файлов в Internet. Это базовый класс для классов
CFtpFileFind Разрешает поиск файлов на FTP серверах.
CGopherFileFind Разрешает поиск файлов на Gopher серверах.
CGopherLocator Отыскивает Gopher устройство ввода позиций от gopher сервера.
CInternetException Управляет исключениями, сгенерированными WinInet классом.

<


br>

Методы ( функции ) класса CInternetFile

Функции Описание
Close() Закрывает Internet сессию.
EnableStatusCallback() Разрешает использование функции повторного вызова, которая используется для асинхронных действий.
GetContext() Получает значение контекста Internet сессии.
GetFtpConnection() Устанавливает подключение по FTP протоколу.
GetGopherConnection() Устанавливает подключение с Gopher серверами.
GetHttpConnection() Устанавливает подключение по HTTP протоклолу.
OnStatusCallback() Модифицирует состояние операции.
OpenURL() Соединяется с данным URL.
QueryOption() Сервис проверки ошибки провайдера.
ServiceTypeFromHandle() Получает тип сервиса от Internet дескриптора.
SetOption() Устанавливает опции Internet сессии.
Методы ( функции ) класса CHttpFile

Функции Описание
Abort() Закрывает файл и игнорирует все ошибки.
Close() Закрывает файл.
Flush() Сбрасывает файл на диск.
Read() Счатывает байт из файла.
ReadString() Считывает строку символов из файла.
Seek() Переустанавливает указатель внутри файла.
SetReadBufferSize() Устанавливает размер буфера для чтения.
SetWriteBufferSize() Устанавливает размер буфера для записи.
Write() Записывает байт в файл.
WriteString() Записывает строку с нулевым символом в конце в файл.
Далее напишем код программы и разберём каждую строчку:


Создание сервера


Прежде чем воспользоваться функцией socket необходимо проинициализировать процесс библиотеки wsock32.dll вызвав функцию WSAStartup например:



Создание собственных ActiveX элементов


Функции Описание
AddRequestHeaders() Добавляет заголовок к HTTP запросу.
Close() Закрывает CHttpFile объект.
GetFileURL() Получает URL файла.
GetObject() Получает объект по HTTP запросу.
GetVerb() Получает заголовок запроса.
QueryInfo() Получает ответ или заголовок запроса.
QueryInfoStatusCode() Получает код состояния HTTP запроса.
SendRequest() Посылает HTTP запрос.

1. Введение

2. Создание проекта

3. Настройка значка инструмента MyClock

4. Рисование в элементе управления MyClock

5. Вывод текущего времени в непрерывном режиме

6. Включение базовых свойств в ActiveX MyClock

7. Включение специального свойства в ActiveX MyClock

1. Введение

Элементов управления ActveX — это файл с расширением ОСХ (например, MyButton.OCX), который вы можете использовать в своем приложении Visual C++. Visual C++ и другие визуальные языки программирования дают вам возможность включить элемент управления ActiveX в свою программу и пользоваться им так же, как и стандартным элементом управления Visual C++. Вы помещаете элемент управления ActiveX в диалоговую панель, задаете его свойства и связываете код с его событиями. После того как ы создали собственный элемент управления ActiveX, вы ожете передавать его другим программистам, которые могут вводить его в свои программы.

Поскольку расширением файла элемента управления ActiveX является .ОСХ, то иногда элементы управления ActiveX называют элементами ОСХ.

В этой главе вы разработаете свой собственный элемент управления ActiveX — MyClock.ОСХ, который выполняет задачу вывода текущего времени. Когда программист помещает элемент управления MyClock.ОСХ в форму или в диалоговую панель, MyClock. ОСХ будет непрерывно отображать текущее время.

2. Создание проекта

Чтобы создать проект элемента управления MyClock.OCX :

1) Выберите New в меню File.

В ответ Visual C++ выведет диалоговую панель New.

2) Выберите закладку Projects диалоговой панели New.

3) Выберите MFC ActiveX ControlWizard из списка типов проектов

4) Напечатайте MyClock в окне Project Name.

5) Щелкните на кнопке, которая расположена с правой стороны окна Location, и выберите каталог для проекта.

6) Щелкните на кнопке ОК.

В ответ Visual C++ выведет окно MFC ActiveX ControlWizard Step 1 of 2

В окне ActiveX ControlWizard Step 1 оставьте все установки в состоянии по умолчанию и щелкните на кнопке Next.

В окне ActiveX ControlWizard Step 2 оставьте все установки в состоянии по умолчанию и щелкните на кнопке Finish.



В ответ Visual C++ выведет диалоговую панель New Project Information.

Щелкните на кнопке ОК в диалоговой панели New Project Information и выберите Set Active Configuration в меню Build.

В ответ Visual C++ выведет диалоговую панель Set Active Project Configuration.

Выберите MyClock - Win32 Release в диалоговом окне Set Active Project Configuration и щелкните на кнопке ОК.

Это все! Вы завершили создание файла проекта и каркасов файлов элемента управления ActiveX MyClock.ОСХ.

3. Настройка значка инструмента MyClock

Значок инструмента MyClock отображает буквы ОСХ. Вам нужно настроить элемент управления MyClock таким образом, чтобы значок его инструмента представлял собой рисунок часов. Для настройки значка инструмента MyClock вы должны отредактировать растровое изображение IDB_MYCLOCK. Это изображение было создано Visual C++.

Чтобы вывести растровое изображение IDB_MYCLOCK в режиме проектирования, сделайте следующее:



1) Выберите закладку ResourceView в окне Project Workspace, раскройте пункт MyClock resources, раскройте пункт Bitmap и дважды щелкните на пункте IDB_MYCLOCK.

В ответ Visual C++ выведет растровое изображение IDB_MYCLOCK в режиме проектирования.

2) Используя визуальные инструменты Visual C++, замените растровое изображение IDB_MYCLOCK букв ОСХ на рисунок простейших часов (окружность и две линии в качестве стрелок).

4. Рисование в элементе управления MyClock

Пока элемент управления MyClock выводит эллипс. Вам нужно, чтобы MyClock отображал текущее время, так что вы должны написать соответствующий код:

Откройте файл MyClockCtl.cpp.

Файл MyClockCtl.cpp — это файл реализации элемента управления МуСlock, созданный для вас Visual C++; в этом файле вы будете писать свой код для настройки MyClock.

Найдите функцию OnDraw() в файле MyClockCtl.cpp и напишите следующий код:


Создание собственных диалоговых окон


Для того, что бы создать собственное диалоговое окно надо сделать следующее:

1) Создайте программу в диалоговом режиме ( с поддежкой MFC )

2) Назовите её TEST, что бы было лучше сравнивать с моей рабочей программой

3) Главный класс вашей программы будет CTestDlg

4) Что бы создать другую диалоговую панель нужно создать новый класс, для этого выбери закладку ResourceView -> правой кнопкой на Dialog -> Insert Dialog -> создастся новый диалог.

5) Имя диалога можно менять, поставте IDD_MY_DIALOG

6) Дальше надо зарегистрировать новый класс, для этого: при открытом новом диалоге( это обязательно ) надо вызвать ClassWizard( в верхнем меню) -> Create new class -> надо ввести имя класса ( введите CMyDialog( MyDialog.cpp), имя должно начинаться с C, что означает class ) -> два раза ОК

7) Теперь надо, чтобы выша главная программа "узнала" новый класс -> в начале файла TestDlg.cpp напишите строчку

#include "MyDialog.h"

8) Ну вот и всё, теперь можно использовать новое диалоговое окно ->

CMyDialog MyDlg;

MyDlg.DoModal();

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

[ Назад | Оглавление | Далее ]

//

hotlog_js="1.0";hotlog_d=document; hotlog_n=navigator;hotlog_rn=Math.random(); hotlog_n_n=(hotlog_n.appName.substring(0,3)=="Mic")?0:1 hotlog_r=""+hotlog_rn+"&s=7004&r="+escape(hotlog_d.referrer)+"&pg="+ escape(window.location.href) hotlog_d.cookie="hotlog=1"; hotlog_r+="&c="+(hotlog_d.cookie?"Y":"N"); hotlog_d.cookie="hotlog=1; expires=Thu, 01-Jan-70 00:00:01 GMT"

hotlog_js="1.1";hotlog_r+="&j="+(navigator.javaEnabled()?"Y":"N")

hotlog_js="1.2";hotlog_s=screen; hotlog_r+="&wh="+hotlog_s.width+'x'+hotlog_s.height+"&px="+((hotlog_n_n==0)? hotlog_s.colorDepth:hotlog_s.pixelDepth)



Стандартные диалоговые панели


1. Введение
2. Панель выбора цвета (класс CColorDialog)
3. Панель выбора файлов (класс CFileDialog)
4. Панель выбора шрифта (класс CFontDialog
5. Панель для вывода документов на печать (класс CPrintDialog)
6. Панель для выполнения поиска и замены (класс CFindReplaceDialog)

7. Пример Windows-приложения, использующего стандартные панели



Static void PlayResource(LPCTSTR


В фунции ::FindResource(AfxGetResourceHandle(), lpszSound, _T("sound")) третий параметр - тип ресурса, который был описан выше.

Теперь можно проиграть ресурс : PlayResource( IDSOUND_CORRECT );



Struct hostent { char *h_name; char **h_aliases; int h_addrtype; int h_lenght; char *h_addr; };


Поле h_name указывает на официальное (основное) имя узла.

Поле h_aliases указывает на список дополнительных имен узла (синонимов), если они есть.

Поле h_addrtype содержит идентификатор используемого набора протоколов, для сетей TCP/IP это поле будет иметь значение AF_INET.

Поле h_lenght содержит длину адреса узла.

Поле h_addr указывает на область памяти, содержащую адрес узла в том виде, в котором его используют системные вызовы и функции socket-интерфейса.

Для "экстренного" закрытия связи с партнером (путем "сброса" еще не переданных данных) используется системный вызов shutdown, выполняемый перед close и имеющий следующий вид



Struct hostent *gethostbyname (name) char *name;


Аргумент name задает адрес последовательности литер, образующих символическое имя узла сети.

При успешном завершении функция возвращает указатель на структуру hostent, определенную в include-файле netdb.h и имеющую следующий вид



Struct in_addr { union { u_long


Структура SOCKADDR_IN должна быть полностью заполнена перед выдачей системного вызова bind. При этом, если поле sin_addr.s_addr имеет значение INADDR_ANY, то системный вызов будет привязывать к socket'у номер (адрес) локального узла сети.

Для подключения socket'а к коммуникационной среде, образованной вычислительной сетью, необходимо выполнить системный вызов bind, определяющий в принятом для сети формате локальный адрес канала связи со средой. В сетях TCP/IP socket связывается с локальным портом. Системный вызов bind имеет следующий синтаксис:



Struct SOCKADDR_IN { short sin_family; u_short sin_port; struct in_addr sin_addr; char sin_zero[; };


Поле sin_family определяет используемый формат адреса (набор протоколов), в нашем случае (для TCP/IP) оно должно иметь значение AF_INET.

Поле sin_addr содержит адрес (номер) узла сети.

Поле sin_port содержит номер порта на узле сети.

Поле sin_zero не используется.

Определение структуры in_addr (из того же include-файла) таково:



Структуры в С++


Как вы уже знаете, переменная в C/C++ объявляется следующим образом:

int iMyVariable;

В приведенном операторе iMyVariable объявлена как целая переменная. А вот объявление переменной типа char:

char cMyChar;

Такие типы данных, как int, float, char и long, являются неотъемлемой частью C/C++ и вам не нужно писать никакого кода, чтобы сообщить компилятору о том, что означают эти слова. C/C++ позволяет вам также объ-являть свои собственные, специальные типы данных. В следующем разделе вы узнаете, как объявлять структуры, которые можно отнести к специальным типам данных.

Напишите следующий исходный код:

#include <iostream.h>

#include <string.h>

// Объявление структуры.
struct MYSTRUCTURE

{

char sName[100];

int iAge;

};

void main( void )

{

MYSTRUCTURE MyStructure;

strcpy(MyStructure.sName, "Andy" );

MyStructure.iAge = 13;

cout

cout

cout

cout

cout

)

В коде, который вы написали, имеются два оператора #include:

#include <iostream.h>

#include <string.h>

Файл iostream.h включен в код, поскольку в main(void) используется cout. Файл string.h включается потому, что в main(void) используется функция strcpy() (объявленная в файле string.h). Затем вы объявляете структуру:

Struct MYSTRUCTURE

{

char sName[100];

int iAge;

};

Обратите внимание на синтаксис объявления структуры. Оно начинается с ключевого слова struct, за которым следует имя типа-структуры. В этой программе типу структуры присвоено имя MYSTRUCTURE. Затем следует собственно определение структуры, заключенное в фигурные скобки. Не забудьте поставить точку с запятой после закрывающей фигурной скобки. Теперь посмотрите на код внутри фигурных скобок:

char sName[100];

int iAge;

Это означает, что MYSTRUCTURE состоит из строки с именем sName и целого с именем iAge, sName и iAge называются элементами данных структуры; Вы объявили их "Внутри" cтруктуры MYSTRUCTURE. Код в main(void) объявляет переменную с именем MyStructure типа MYSTRUCTURE:

MYSTRUCTORE MyStructure;



Вспомните, что в объявляли переменную iNum1 следующим образом:



int iNum1;

Когда вы объявляете MyStructure , которая будет структурой типа MYSTRUCTURE, рассматривайте переменную MyStructure аналогично переменной iNum1. MyStructure - это имя переменной, а ее типом является MYSTRUCTURE точно так же, как типом переменной iNum1 является int. (Обратите внимание, что по традиции имя структуры составлено из символов нижнего регистра или в нем смешаны символы нижнего и верхнего регистров, как, например, в имени MyStructure, но в имени типа структуры используются только символы верхнего регистра, как, например, в MYSTRUCTURE.)

Следующий оператор в main(void) копирует строку 'Andy' в элемент данных MyStructure.sName:



strcpy ( MyStructure.sName, "Andy" );

В этом операторе обращение к элементу данных sName записано как MyStructure.sName Следующий оператор присваивает значение 13 элементу данных iAge cтруктуры MyStructure: MyStructure.iAge - 13; Затем выполняется ряд операторов вывода cout:



cout

cout

cout

cout

cout

Сложив все вместе, мы видим, что программа MyStruct выводит сообщение My name is Andy and I am 13 years old. (Меня зовут Andy и мне 13 лет)

<


TC_ITEM TabItem; TabItemmask




Это код инициализации Tab Control, мы создаём три закладки. Теперь нам надо, чтобы при нажатие на любую закладку, на экране появлялось то, что нам нужно. Самый простой вариант - это использовать на каждую закладку по диалогу - и потом просто в области Tab Control'а - выводить нужный диалог, в зависимости от текущей закладки.

Сделаем это. Добавим три диалога в редакторе ресурсов и создадим каждому из них по классу - наследнику от CDialog. Назовем эти классы CPage1, CPage2 и CPage3( файлы Page1.cpp(h), Page2.cpp(h), Page3.cpp(h) ) .

В свойствах этих трёх диалогов поставте Style как "Child" и Border как "none" - это очень важно, а в самих диалогах создайте какие либо элементы ( например, типа Static Text ), чтобы было видно отличие.

Напишите эти три строчки в начале файла tab_controlDlg.cpp



Типы мастеров проектов


В среде Visual C++ можно строить различные типы проектов. Такие проекты после их создания можно компилировать и запускать на исполнение. Фирма Microsoft разработала специальный инструментарий, облегчающий и ускоряющий создание проектов в среде Visual C++.

Рассмотрим некоторые типы проектов, которые можно создавать при помощи различных средств (мастеров проектов) Microsoft Visual C++:

MFC AppWizard (exe)

– при помощи мастера приложений можно создать проект Windows-приложения которое имеет однодокументный, многодокументный или диалоговый интерфейс. Однодокументное приложеие может предоставлять пользователю в любой момент времени работать только с одним файлом. Многодокументное приложение, напротив, может одновременно представлять несколько документов, каждый в собственном окне. Пользовательский интерфейс диалогового приложения представляет собой единственное диалоговое окно.

MFC AppWizard (dll) –

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

AppWizard ATL COM

– это средство позволяет создать элемент управления ActiveX или сервер автоматизации, используя новую библиотеку шаблонов ActiveX (ActiveX Template Library - ATL). Опции этого мастера дают возможность выбрать активный сервер (DLL) или исполняемый внешний сервер (exe-файл).

Custom AppWizard

– при помощи этого средства можно создать пользовательские мастера AppWizard. Пользовательский мастер может базироваться на стандартных мастерах для приложений MFC или DLL, а также на существующих проектах или содержать только определеямые разработчиком шаги.

DevStudio Add-in Wizard

– мастер дополнений позволяет создавать дополнения к Visual Studio. Библиотека DLL расширений может поддерживать панели инструментов и реагировать на события Visual Studio.

MFC ActiveX ControlWizard

- мастер элементов управления реализует процесс создания проекта, содержащего один или несколько элементов управления ActiveX, основанных на элементах управления MFC.


Win32 Application

– этот мастер позволяет создать проект обычного Window-приложения. Проект создается незаполненным, файлы с исходным кодом в него следует добавлять вручную.

Win32 Console Application

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

Win32 Dynamic-Link Library

– создание пустого проекта динамически подключаемой библиотеки. Установки компилятора и компоновщика будут настроены на создание DLL. Исходные файлы следует добавлять вручную.

Win32 Static Library

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


Visual C для начинающих


1. Введение ( очень советую прочитать )

2. Первая программа на C++, типы данных и их размер

3. Адресация в С++

4. Применение указателей в C++

5. Соглашение об именах

6. Структуры в С++

7. Классы в С++

8. Пример использования MFC в Visual C++

9. Запись и считывание данных (работа с файлами)

10. Использование таймера

11. Работа со стандартными ресурсами

12. Работа с библиотеками динамической компоновки (DLL)

13. Стандартные диалоговые панели

14. Оптимизация вывода графики на экран

15. Создание собственных диалоговых окон

16. Работа с WinSocket

17. Простая программа, использующая MDI интерфейс

18. Проигрывание Wave-файлов под MFC

19. Создание собственных ActiveX элементов

20. Использование класса CTabCtrl

21. Создание простого HTTP-клиента

22. Создание простого FTP-клиента

24. Работа с COM портами( CreateFile )

25. Работа с некоторыми Win API функциями( информация о системе )

//


1. Введение ( очень советую прочитать )

2. Первая программа на C++, типы данных и их размер

3. Адресация в С++

4. Применение указателей в C++

5. Соглашение об именах

6. Структуры в С++

7. Классы в С++

8. Пример использования MFC в Visual C++

9. Запись и считывание данных (работа с файлами)

10. Использование таймера

11. Работа со стандартными ресурсами

12. Работа с библиотеками динамической компоновки (DLL)

13. Стандартные диалоговые панели

14. Оптимизация вывода графики на экран

15. Создание собственных диалоговых окон

16. Работа с WinSocket

17. Простая программа, использующая MDI интерфейс

18. Проигрывание Wave-файлов под MFC

19. Создание собственных ActiveX элементов

20. Использование класса CTabCtrl

21. Создание простого HTTP-клиента

22. Создание простого FTP-клиента

24. Работа с COM портами( CreateFile )

25. Работа с некоторыми Win API функциями( информация о системе )

//



Void CMDIDoc::Serialize(CArchive&


9. Часто бывает нужно изменить некоторые параметры программы, такие как заголовок главного окна или тип файла по умолчанию, который выводится в диалоговых панелях SAVE и OPEN. Для этого нужно выбрать закладку ResourceView и открыть пункт String Table. Вы увидите список переменных проекта( три колонки : ID, Value и Caption ).

IDR_MAINFRAME - заголовок главного окна (изменяется в поле Caption)

IDR_MCIRCLTYPE - тип файла по умолчанию, вы увидите 6 подстрок разделёнными знаком \n. Третья и четвёртая подстроки определяют тип документа по умолчанию. У меня CIR FILES( *.cir ) и .cir соответственно. Вы можете поставить свои значения.

10. Теперь создадим кнопку в панеле инструментов. Для этого нужно выбрать закладку ResourceView и открыть пункт Toolbar. Вы увидите панель инструментов в режиме редактирования. Нажмите на самую правую кнопку( пунктирный квадрат ), ниже нарисуйте кнопку по вашему усмотрению. Теперь дважды нажмете на вашу кнопку и введите ID: ID_MYBUTTON и Prompt: Изменение координат круга\nИзменение координат круга. Ну вот и всё, кнопка готова. Теперь нужно создать функцию, которая будет выполняться при нажатии на вашу кнопку :

Выберите пункт меню View далее ClassWizard, выберите закладку Message Maps, Project: MDI, Class name: CMDIView, Object IDs: ID_MYBUTTON, Message: COMMAND и нажмите на кнопку Add Function. В ответ создастся функция void CMDIView::OnMybutton().

11. Теперь по аналогии с главой 15 создадим собственное диалоговое окно с ID: IDD_MY_DIALOG и классом CMyDialog и разместим в нём четыре Edit Box с переменными типа INT: m_DX - текущая позиция по X, m_DY - текущая позиция по Y, m_DXN - новая позииция по X, m_DYN - новая позииция по Y. Не забудте написать #include "MyDialog.h" в файлах MDIDoc.cpp и MDIView.cpp.

12. Теперь напишем код в функцие OnMybutton().



Void CMDIView::OnDraw(CDC* pDC)


8. Напишем код для сохранения и считывания данных из файла.

Откройте файл MDIDoc.cpp, найдите в нём функцию Serialize() и измените её:



Void CMDIView::OnInitialUpdate()


7. Теперь напишем код для вывода круга на экран.

Функция OnDraw() класса представления автоматически выполняется всякий раз, когда нужно вывести окно документа.

Напишите следующий код в функции OnDraw() :



Void CMDIView::OnMybutton() {


13. Ну вот и всё, программа готова. Отсюда можно взять рабочую программу, использующую MDI, в которой используется собственное диалоговое окно.

[ Назад | Оглавление | Далее ]

//



Void CMyClockCtrl::OnDraw( CDC*


5. Вывод текущего времени в непрерывном режиме

Чтобы отображать время непрерывно, вам нужно сделать следующее:

1) Написать код, который устанавливает таймер с 1000-миллисекундным периодом для элемента управления MyClock.

2) Связать код с событием WM_TIMER элемента управления MyClock.

После установки таймера каждые 1000 миллисекунд (каждую секунду) Windows будет посылать сообщение WM_TIMER элементу управления MyClock, в ответ на которое будет выполняться код, который вы свяжете с этим событием элемента управления. Этот код будет просто выводить текущее время, так что значение времени будет непрерывно обновляться.

Таймер необходимо установить сразу после создания элемента управления, так что вам нужно связать код, устанавливающий таймер, с событием WM_CREATE элемента управления:

Выведите диалоговую панель ClassWizard, выбрав ClassWizard в меню View. На странице Message Maps выберите следующее событие:

Class Name: CMyClockCtrl

Object ID: CMyClockCtrl

Message: WM_CREATE

Щелкните на кнопке Add Function.

В ответ Visual C++ добавит в класс CMyClockCtrl функцию-элемент ОпСreate().

Щелкните на кнопке Edit Code в ClassWizard.

В ответ Visual C++ откроет файл MyClockCtrl.cpp с функцией OnCreate() в режиме редактирования.

Напишите следующий код в функции OnCreate():


Ну вот и всё, теперь элемент управления MyClock имеет свойства BackColor и ForeColor.

7. Включение специального свойства в ActiveX MyClock

Во многих случаях вам понадобится включить в свой элемент управления такие свойства, которые не входят в список стандартных. Эти свойства называются специальными.

Для примера включем в MyClock специальное свойство UpdateInterval - период обновления:

View -> ClassWizard -> Automation( проверте, чтобы в окне Class name установлен класс CMyClockCtrl )

Нажмите на кнопку Add Property

В окне External name наберите UpdateInterval

В окне Type выберите Long

В окне Variable name должно быть m_updateinterval

В окне Notification function поставьте OnUpdateIntervalChanged

Проверте, что в камке Implementation выбрана кнопка Member variable и нажмите OK

Тем самым мы определили, что со свойством UpdateInterval будет связана переменная m_updateinterval и всякий раз, когда значение свойства UpdateInterval будет именяться, автоматически выполнится функция OnUpdateIntervalChanged.

Теперь надо проинициализировать свойство UpdateInterval:

Откройте файл MyClockCtl.cpp

Найдите функцию DoPropExchange() и напишиет в ней следующее:

// Инициализация свойства UpdateInterval значением 1000

PX_Long( pPX, _T("UpdateInterval"), m_updateinterval, 1000 );

Теперь надо модернизировать функции OnUpdateIntervalChanged:

// проверка на отризательность

if( m_updateinterval < 0 )

{

MessageBox( "This property cannot be negative !!!" );

m_updateinterval = 1000;

}

// Установка таймера

SetTimer( 1, (UINT)m_updateinterval, NULL );

и OnCreate:

// Установка таймера

SetTimer( 1, (UINT)m_updateinterval, NULL );



Void CMyClockCtrl::OnTimer(UINT


6. Включение базовых свойств в ActiveX MyClock

Базовые свойства( Stock properties ) - преопределены.

Ниже приведён список базовых свойств:

Appearance - Внешний вид( 3-х мерный или плоский )

BackColor - Цвет фона

BorderStyle - Стиль рамки

Caption - Заголовок

Enabled - Состояние доступен/недоступен

Font - Шрифт

ForeColor - Цвет переднего плана

hWnd - Маркер окна

ReadyState - Состояние готовности

Text - Текст

Для практики включим два базовых свойства в ActiveX MyClock: BackColor и ForeColor.

Выполните следующие действия:

View -> ClassWizard -> Automation( проверте, чтобы в окне Class name установлен класс CMyClockCtrl )

Нажмите на кнопку Add Property

Выберите из списка BackColor и нажмите OK

Также добавьте и свойство ForeColor.

Элемент управления MyClock имеет сейчас свойства BackColor и ForeColor, но пока не использует значения, хранящиеся в этих свойствах. Вам надо написать код в функции OnDraw(), который выполняет эту задачу:



Void CTab_controlDlg::OnDestroy()


Ну вот и всё, приложение готово.

Отсюда можно взять рабочую программу под MFC, с использованием CTabCtrl.

[ Назад | Оглавление | Далее ]

//



Void CTab_controlDlg::OnSelchangeTab(NMHDR*


Здесь используются те самые указатели, которые мы спрятали в OnInitDialog

Теперь освободим память и разрушим диалоговые окна при выходе из приложения.

Добавим функцию OnDestroy:



Второй способ использования таймера


Второй способ работы с таймером заключается в использовании для таймера специальной функции, которая будет получать сообщения WM_TIMER. Эта функция является функцией обратного вызова, определяется с ключевым словом _export и, так же как и функция окна, имеет специальный пролог и эпилог: void CALLBACK _export TimerProc(HWND hwnd, UINT msg, UINT idTimer, DWORD dwTime);

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

Первый параметр функции таймера - идентификатор окна, с которым связан таймер. Если при создании таймера в качестве идентификатора было указано значение NULL, это же значение будет передано функции таймера.

Второй параметр представляет собой идентификатор сообщения WM_TIMER.

Третий параметр является идентификатором таймера, пославшего сообщение WM_TIMER.

И наконец, последний параметр - текущее время по системным часам компьютера. Это время выражается в количестве тиков таймера с момента запуска Windows. Вы можете узнать текущее системное время в любой момент, если воспользуетесь функцией GetCurrentTime или GetTickCount: DWORD WINAPI GetCurrentTime(void); DWORD WINAPI GetTickCount(void);

Эти функции совершенно аналогичны, однако название функции GetTickCount более точно отражает выполняемое ей действие.

Если для создания приложения вы пользуетесь современными средствами разработки, такими, как Borland C++ версии 3.1, Microsoft С++ версии 7.0, Microsoft Visual C++, для определения функции обратного вызова достаточно использовать ключевое слово _export. В этом случае вы можете создать таймер, например, так: nTimerID = SetTimer(hwnd, 0, 1000, (TIMERPROC)TimerProc);

Для удаления таймера в этом случае необходимо использовать идентификатор, возвращенный функцией SetTimer: KillTimer(hwnd, nTimerID );

Если же используемые вами средства разработки не позволяют указать ключевое слово _export, для подключения функции таймера придется использовать более сложный способ.


Когда вы не можете ограничиться использованием ключевого слова _export, для работы с функциями обратного вызова нужно сделать специальный переходник (thunk), вызвав функцию MakeProcInstance: FARPROC WINAPI MakeProcInstance(FARPROC lpProc, HINSTANCE hinst);

В качестве первого параметра функции (lpProc) необходимо передать адрес функции, для которой создается переходник, а в качестве второго (hinst) - идентификатор приложения hInstance, полученный функцией WinMain при запуске приложения.

Функция MakeProcInstance для указанной функции создает функцию-переходник, возвращая ее адрес, а также обеспечивает функции доступ к сегменту данных приложения, загружая соответствующим образом сегментные регистры.

Процедура создания таймера с использованием функции MakeProcInstance может выглядеть следующим образом: TIMERPROC lpfnTimerProc; lpfnTimerProc = (TIMERPROC)MakeProcInstance( (FARPROC)TimerProc, hInstance); nTimerID = SetTimer(hwnd, 0, 1000, (TIMERPROC)lpfnTimerProc);

После уничтожения таймера следует уничтожить созданный функцией MakeProcInstance переходник, для чего следует вызвать функцию FreeProcInstance: void WINAPI FreeProcInstance(FARPROC lpProc);

Этой функции необходимо передать адрес уничтожаемой функции-переходника: FreeProcInstance(lpfnTimerProc);

Функции MakeProcInstance и FreeProcInstance можно использовать совместно с современными средствами разработки, понимающими ключевое слово _export. Это не приведет к неправильной работе приложения.

Старые средства разработки приложений Windows требуют, чтобы все функции обратного вызова, такие, как функции окон и функции таймеров, были описаны в файле определения модуля, имеющем расширение .def, при помощи оператора EXPORTS, например: EXPORTS WndProc TimerProc

Транслятор Borland C++ версии 3.1 распознает ключевое слово _export и автоматически формирует нужный пролог и эпилог для функций обратного вызова. То же самое относится и к трансляторам Microsoft C++ версии 7.0 и Microsoft Visual C++. Поэтому в наших примерах функции MakeProcInstance и FreeProcInstance, а также оператор файла определения модуля EXPORTS не используются.


Эти главы являются некоторым пособием



Эти главы являются некоторым пособием для тех, кто хочет познакомиться с языком программирования C++ и Visual C++.

Некоторые сведения о Windows-программировании

Программная среда Windows
Основы программирования для Windows
Преимущества использования библиотеки MFC
Обзор средств Microsoft Developer Studio

Библиотека MFC
Архитектура приложения
Каркас приложения
Каркас приложений
Проект приложения
Использование средств разработки

Типы мастеров проектов
Преимущества мастеров проектов
Обзор возможностей ClassWizard
Имена, используемые в MFC
В связи с тем, что сегодня уровень сложности программного обеспечения очень высок, разработка приложений Windows с использованием только какого-либо языка программирования (например, языка C) значительно затрудняется. Программист должен затратить массу времени на решение стандартных задач по созданию многооконного интерфейса. Реализация технологии связывания и встраивания объектов - OLE - потребует от программиста еще более сложной работы.
Чтобы облегчить работу программиста практически все современные компиляторы с языка C++ содержат специальные библиотеки классов. Такие библиотеки включают в себя практически весь программный интерфейс Windows и позволяют пользоваться при программировании средствами более высокого уровня, чем обычные вызовы функций. За счет этого значительно упрощается разработка приложений, имеющих сложный интерфейс пользователя, облегчается поддержка технологии OLE и взаимодействие с базами данных.
Современные интегрированные средства разработки приложений Windows позволяют автоматизировать процесс создания приложения. Для этого используются генераторы приложений. Программист отвечает на вопросы генератора приложений и определяет свойства приложения - поддерживает ли оно многооконный режим, технологию OLE, трехмерные органы управления, справочную систему. Генератор приложений, создаст приложение, отвечающее требованиям, и предоставит исходные тексты. Пользуясь им как шаблоном, программист сможет быстро разрабатывать свои приложения.


Подобные средства автоматизированного создания приложений включены в компилятор Microsoft Visual C++ и называются MFC AppWizard. Заполнив несколько диалоговых панелей, можно указать характеристики приложения и получить его тексты, снабженные обширными комментариями. MFC AppWizard позволяет создавать однооконные и многооконные приложения, а также приложения, не имеющие главного окна, -вместо него используется диалоговая панель. Можно также включить поддержку технологии OLE, баз данных, справочной системы.
Конечно, MFC AppWizard не всесилен. Прикладную часть приложения программисту придется разрабатывать самостоятельно. Исходный текст приложения, созданный MFC AppWizard, станет только основой, к которой нужно подключить остальное. Но работающий шаблон приложения - это уже половина всей работы. Исходные тексты приложений, автоматически полученных от MFC AppWizard, могут составлять сотни строк текста. Набор его вручную был бы очень утомителен.
Нужно отметить, что MFC AppWizard создает тексты приложений только с использованием библиотеки классов MFC (Microsoft Foundation Class library). Поэтому только изучив язык C++ и библиотеку MFC, можно пользоваться средствами автоматизированной разработки и создавать свои приложения в кратчайшие сроки.

WSADATA WsaData; int err = WSAStartup


Здесь 0х0101 версия библиотеки которую следует использовать.

Теперь объявление переменную типа SOCKET например s : s = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);

Создание socket'а осуществляется следующим системным вызовом



Загрузка динамических расширений MFC


Начиная с версии 4.0 MFC позволяет динамически загружать и выгружать DLL, в том числе и расширения. Для корректного выполнения этих операций над создаваемой DLL в ее функцию DllMain в момент отключения от процесса необходимо добавить вызов AfxTermExtensionModule. Последней функции в качестве параметра передается уже использовавшаяся выше структура AFX_EXTENSION_MODULE. Для этого в текст DllMain нужно добавить следующие строки.

if(dwReason == DLL_PROCESS_DETACH) { AfxTermExtensionModule(MyExtDLL); }

Кроме того, следует помнить, что новая библиотека DLL является динамическим расширением и должна загружаться и выгружаться динамически, с помощью функций AfxLoadLibrary и AfxFreeLibrary,а не LoadLibrary и FreeLibrary.



Загрузка неявно подключаемой DLL


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

Каталог, в котором находится ЕХЕ-файл.

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

Системный каталог Windows.

Если библиотека DLL не обнаружена, приложение выводит диалоговое окно с сообщением о ее отсутствии и путях, по которым осуществлялся поиск. Затем процесс отключается.

Если нужная библиотека найдена, она помещается в оперативную память процесса, где и остается до его окончания. Теперь приложение может обращаться к функциям, содержащимся в DLL.



Запись и считывание данных ( работа с файлами )


В этом разделе будут рассотрены два способа работы с фыйлами и стандартный класс MFC CFileDialog.

1. Работа с файлами в C ( работает и в C++ ).

2. Работа с файлами с помощью MFC( классы CFile, CStdioFile, ... ) и стандартный класс MFC CFileDialog.