Visual C++ MFC в подробностях

ОГЛАВЛЕНИЕ

Подробная справочная информация и примеры использования объектов Visual C++ MFC.


#if !defined()

Конструкция типа (директива препроцессора)

#if !defined(MyClass_H)
#define MyClass_H
......
#endif

Позволяет исключить двойные включения описания классов, и тем самым избежать ошибок типа error C2011, вот например таких:

--------------------Configuration: Test - Win32 Debug--------------------
Compiling...
test.cpp
d:\project\test\myclass.h(6) : error C2011: 'MyClass' : 'class' type redefinition
Error executing cl.exe.

test.obj - 1 error(s), 0 warning(s)

Идея октлючения повторов заключена в операторе #define вот как можно сделать.

#define My 1

С этого момента существует понятие My это как константа. Везде где вы не поставите My при компиляции на её место будет поставлена единица (1). Наличие подобных определений можно проверять. Вот так:

#if defined(My)	// если определена My то что-то сделать
......
#end if

Вот на основе этого механизма и действует предупреждения повторных включений. Создайте приложение Win32 console, как пустой проект (An empry project) с именем Test. Добавьте в проект файл Test.cpp и код его:

#include "myclass.h"
#include "myclass.h"


void main()
{
MyClass my;
my.GetInt();
}

Файл myclass.h и код к нему.

//#if !defined(MyClass_H)
// #define MyClass_H


class MyClass
{
public:
int GetInt();
int intmy;
};

//#endif

Файл myclass.cpp и код к нему:

#include "myclass.h"

int MyClass::GetInt()
{
return 1;
}

Запустите проект на компиляцию и выполнение, Вы получите ошибку о двойном включении класса.

А теперь раскомментируйте конструкции #if !defined в файле myclass.h и всё сработает.

Ну и что скажете Вы :-) да подобные ситуации видны. Современные каркасные библиотеки да и любая сложная структура классов часто требует перекрестных включений классов. Вот и думай потом как и что описывать, а подобным образом просто. Если класс описан, то он просто пропустится :-), а если нет, то описание будет включено. Подобные консрукции использует AppWizard для создаваемых приложений. Кроме того подобным образом можно работать с разными версиями классов. Например, сделать объявление константы, а при создании кода учитывать её установку.

Вот так проверяется в istream.h на тип операционной среды.

#if     !defined(_WIN32) && !defined(_MAC)
#error ERROR: Only Mac or Win32 targets supported!
#endif


#pragma message

Данная директива выводит сообщение в окно Build не влияя на компиляцию. Ее применение сообщить о ходе компиляции или установленных параметрах. Общий вид у нее такой.

#pragma message( строка сообщения )

Давайте посмотрим как можно ее применить. Вот, например, для информирования о том, что режим компиляции Win 32 и что это режим отладки.

#include "stdafx.h"

int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// TODO: Place code here
#if WIN32
#pragma message("Compiling Win32")
#endif

#if _DEBUG
#pragma message("Compiling Debug")
#endif

return 0;
}

Вот такой результат в окне Build.

--------------------Configuration: testpragma - Win32 Debug--------------------
Compiling...
testpragma.cpp
Compiling Win32
Compiling Debug
Linking...

testpragma.exe - 0 error(s), 0 warning(s)

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

#include "stdafx.h"

int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// TODO: Place code here
#pragma message("Compiling " __FILE__ )
#pragma message("Modified " __TIMESTAMP__ )

return 0;
}

А вот и результат:

--------------------Configuration: testpragma - Win32 Debug--------------------
Compiling...
testpragma.cpp
Compiling E:\Project\testpragma\testpragma.cpp
Modified Tue Jul 18 10:04:40 2000
Linking...
testpragma.exe - 0 error(s), 0 warning(s)

Используя эту директиву Вы можете значительно расширить информативность вывода компилятора.


AfxMessageBox

Из переменной:

int AfxMessageBox( LPCTSTR lpszText, UINT nType = MB_OK, 
UINT nIDHelp = 0 );

Из ресурсов:

int AFXAPI AfxMessageBox( UINT nIDPrompt, UINT nType = MB_OK,
UINT nIDHelp = (UINT) -1 );
  • lpszText - текстовая строка для вывода
  • nType - тип сообщения
  • nIDHelp - идентификатор помощи

Пример 1.

Совершенно простой вызов только строка для вывода и кнопка OK:

AfxMessageBox(" Key Button Down ");

Пример 2.

В принципе результат тот же - смотри обьявление функции MB_OK по умолчанию.

AfxMessageBox(" Rigth Button Click ",MB_OK);

Пример 3.

Две кнопки Ок и Cancel.

AfxMessageBox(" Rigth Button Click ",MB_OKCANCEL);

И так далее в любом варианте из:

  • MB_ABORTRETRYIGNORE - Кнопки Abort, Retry, и Ignore
  • MB_OK - Кнопка OK
  • MB_OKCANCEL - Кнопки OK и Cancel
  • MB_RETRYCANCEL - Кнопки Retry и Cancel
  • MB_YESNO - Кнопки Yes и No
  • MB_YESNOCANCEL - Кнопки Yes, No, и Cancel
  • MB_HELP - Добавить кнопку HELP ( в документации VC++ 5 по AfxMessageBox нет в перечислении !?)

Пример 4.

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

AfxMessageBox(" Rigth Button Click ", 
MB_RETRYCANCEL | MB_ICONSTOP );
Пример 5

Здесь показана техника обработки возврата функцией

if (AfxMessageBox(" Rigth Button Click ", MB_RETRYCANCEL )==IDCANCEL)
{
AfxMessageBox("Cancel");
} else {
AfxMessageBox("Retry");
}

Данная функция может возвращать:

  • IDABORT - Abort нажата была
  • IDCANCELM - Cancel нажата была
  • IDIGNORE - Ignore нажата была
  • IDNO - No нажата была
  • IDOK - OK нажата была
  • IDRETRY - Retry нажата была

Пример 6

Надпись в 2 строки в окне сообщения! Для этого между строками поставить код 10.

CString cs = "Test"+(CString)10+ "Hello";
AfxMessageBox(cs, MB_RTLREADING );

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

Реакция на клавишу ESC, если только есть кнопка CANCEL.


BITMAPFILEHEADER

Эта структура описана в файле wingdi.h. Эта структура идет самой первой в файле BMP. Вот её описание.

typedef struct tagBITMAPFILEHEADER {
WORD bfType;
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits;
} BITMAPFILEHEADER, FAR *LPBITMAPFILEHEADER, *PBITMAPFILEHEADER;

Первой переменной идет bfType - эта переменная содержит тип файла. В нормальном растре первыми буквами идет BM в виде ASCII или 4D42 в шестнадцатеричном виде.

Дальше bfSize должен содержать размер файла в байтах. Говорят, что это значение ненадежно и использовать его не стоит.

bfReserved1 & bfReserved2 зарезервированы и использовать их не нужно.

bfOffBits смещение в байтах от начала растра до массива данных. Этим можно пользоваться.

Прочитать заголовок можно примерно так.

CString filename;
CFileDialog fil(TRUE,"bmp","*.bmp");
if (fil.DoModal()==IDOK)
{
filename=fil.GetPathName();
CFile cf(filename,CFile::modeRead);
BITMAPFILEHEADER bf;
cf.Read((void *)&bf,sizeof(bf));
cf.Close();
}


BITMAPINFO

В прошлый раз мы рассмотрели структуру BITMAPFILEHEADER. Она идет первая в файле. Вобщем набор структур в заголовке файла выглядит так.

BITMAPFILEHEADER

BITMAPINFO
BITMAPINFOHEADER
RGBQUAD

Как видите структура BITMAPINFO - это просто набор двух структур. Она объявлена в файле wingdi.h,

typedef struct tagBITMAPINFO {
BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiColors[1];
} BITMAPINFO, FAR *LPBITMAPINFO, *PBITMAPINFO;

Итак, первая структура у нас это BITMAPINFOHEADER, она содержит информацию о растре и вот её содержание.

typedef struct tagBITMAPINFOHEADER{
DWORD biSize;
LONG biWidth;
LONG biHeight;
WORD biPlanes;
WORD biBitCount;
DWORD biCompression;
DWORD biSizeImage;
LONG biXPelsPerMeter;
LONG biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
} BITMAPINFOHEADER, FAR *LPBITMAPINFOHEADER, *PBITMAPINFOHEADER;
  • biSize - размер структуры в байтах и должен быть равен 40 байтам.
  • biWidth & biHeight - содержат высоту и ширину растра в байтах.
  • biPlanes - смысл непонятен, так как здесь всегда 1.
  • biBitCount - число битов на пиксель может быть разное и зависит от типа палитры. Могут быть числа 1,2,4,8,24
  • biCompression - алгоритм сжатия, вот значения:
    0 нет
    1 RLE-8
    2 RLE-4
  • biSizeImage - размер растра в байтах и бывает нужно только для сжатых растров.
  • biXPelsPerMeter & biYPelsPerMeter - показывают сколько пикселей на метр, обычно 0 ;-)
  • biClrUsed & biClrImportant - количество используемых цветов и количество значимых цветов. Обычно 0 :-)

Следующая структура - это RGBQUAD описанная в файле wingdi.h. Это не одна структура, а набор структур, которые представляют из себя паритру.

typedef struct tagRGBQUAD {
BYTE rgbBlue;
BYTE rgbGreen;
BYTE rgbRed;
BYTE rgbReserved;
} RGBQUAD;

Кто знаком с понятием цветов, то это набор цветов RGB, то есть интенсивности составляющей красной, зеленой и синей. Количество структур зависит от типа растра. Если растр на 256 цветов, то и структур будет 256. Цветовая таблица вообще отсутсвует в растрах с 24 битным изображением Hi Color.

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

lpInfo=(LPBITMAPINFO)ptrBmp;
lpHeader=(LPBITMAPINFOHEADER)ptrBmp;
lpRGB = (RGBQUAD*)(ptrBmp+lpHeader->biSize);

Ну и правильно, так как BITMAPINFO и BITMAPINFOHEADER начинаются с одного места и только начало структуры RGBQUAD необходимо вычислить.


CDC::GetDeviceCaps( )

Прототип:

int GetDeviceCaps (int nIndex) const;

С помощью этой функции можно получить специфическую информацию относительно экранного устройства. Этим устройством может быть как экран монитора, так и принтер с плоттером.

nIndex - Тип возвращаемой информации. Может быть любой из следующих величин:

  • DRIVERVERSION - Номер версии; например, 0x100 для 1.0
  • DT_PLOTTER - Векторный плоттер
  • DT_RASDISPLAY - Растровый дисплей
  • DT_RASPRINTER - Растровый принтер
  • DT_RASCAMERA - Растровая камера
  • DT_CHARSTREAM - Поток знаков
  • DT_METAFILE - Метафайл
  • DT_DISPFILE - Дисплейный файл
  • HORZSIZE - Ширина физического дисплея (в миллиметрах)
  • VERTSIZE - Высота дисплея (в миллиметрах)
  • HORZRES - Ширина дисплея (в пикселях)
  • VERTRES - Высота дисплея (в линиях растра)
  • LOGPIXELSX - Число пикселей на горизонтальный логический дюйм
  • LOGPIXELSY - Число пикселей на вертикальный логический дюйм
  • BITSPIXEL - Число смежных цветовых битов для каждого пикселя
  • PLANES - Число цветовых плоскостей
  • NUMBRUSHES - Число зависимых от устройства кистей
  • NUMPENS - Число зависимых от устройства перьев
  • NUMFONTS - Число зависимых от устройства шрифтов
  • NUMCOLORS - Число элементов в таблице цветов устройства
  • ASPECTX - Относительная ширина пикселя устройства, которая используется для линий рисунка
  • ASPECTY - Относительная высота пикселя устройства, которая используется для линий рисунка
  • ASPECTXY - Диагональная ширина пикселя устройства, которая используется для линии рисунка
  • PDEVICESIZE - Размер внутренней структуры данных PDEVICE
  • CLIPCAPS - Возможности усечения устройства
  • SIZEPALETTE - Число элементов в палитре системы. Этот индекс имеет силу, только если драйвер устройства устанавливает бит RC_PALETT в индексе RASTERCAPS
  • NUMRESERVED - Число зарезервированных элементов в палитре системы. Этот индекс имеет силу, только если драйвер устройства устанавливает бит RC_PALETT в индексе RASTERCAPS
  • COLORRES - Фактическое цветовое разрешение устройства в битах на пиксель. Этот индекс имеет силу, только если драйвер устройства устанавливает бит RC_PALETT в индексе RASTERCAPS
  • RASTERCAPS - Значение, указывающее растровые возможности устройства

RASTERCAPS может быть комбинацией следующих значений:

  • RC_BANDING - Требует поддержки связи
  • RC_BIGFONT - Поддерживает шрифты, большие чем 64 Кбайт
  • RC_BITBLT - Способен к пересылке битовых карт
  • RC_BITMAP64 - Поддерживает битовые карты, большие чем 64 Кбайт
  • RC_DEVBITS - Поддерживает битовые карты устройства
  • RC_DI_BITMAP - Способен поддерживать функции Windows SetDIBits и GetDIBits
  • RC_DIBTODEV - Способен поддерживать функцию Windows SetDIBitsToDevice
  • RC_FLOODFILL - Способен к выполнению полного заполнения
  • RC_GD120_OUTPUT - Способен к поддержке особенностей версии Windows 2.0
  • RC_GD120_STATE - Включает блок состояния в контекст устройства
  • RC_NONE - Не поддерживает растровые операции
  • RC_OP_DX_OUTPUT - Поддерживает непрозрачность и DX массив
  • RC_PALETTE - Определяет устройство базовой палитры
  • RC_SAVEBITMAP - Способен к локальному хранению битовых карт
  • RC_SCALING - Способен к масштабированию
  • RC_STRETCHBLT - Способен к выполнению функции - члена StretchBlt
  • RC_STRETCHDIB - Способен к выполнению функции Windows StretchDIBits
  • CURVECAPS - Возможность построения кривых

CURVECAPS может быть комбинацией следующих значений:

  • CC_NONE - Поддерживает кривые
  • CC_CIRCLES - Поддерживает круги
  • CC_PIE - Поддерживает секторные диаграммы
  • CC_CHORD - Поддерживает хорды
  • CC_ELIPSES - Поддерживает эллипсы
  • CC_WIDE - Поддерживает широкие грани
  • CC_STYLED - Поддерживает стилизованные границы
  • CC_WIDESTYLED - Поддерживает широкие стилизованные границы
  • CC_INTERIORS - Поддерживает внутреннее заполнение
  • CC_ROUNDRECT - Поддерживает прямоугольники со скругленными углами
  • LINECAPS - Возможности построения линий

LINECAPS может быть комбинацией следующих значений:

  • LC_NONE - Не поддерживает никакие линии
  • LC_PLYUNE - Поддерживает полилинии
  • LC_MARKER - Поддерживает метки
  • LC_POLYMARKER - Поддерживает полимаркеры
  • LC_WIDE - Поддерживает широкие линии
  • LC_STYLED - Поддерживает стилизованные линии
  • LC_WIDESTYLED - Поддерживает широкие стилизованные линии
  • LC_INTERIORS - Поддерживает внутреннее заполнение
  • POLYGONALCAPS - Возможности построения прямоугольников

POLYGONALCAPS может быть комбинацией следующих значений:

  • PC_NONE - Не поддерживает многоугольники
  • PC_POLYGON - Поддерживает заполненные прямоугольники
  • PC_RECTANGLE - Поддерживает прямоугольники
  • PC_WINDPOLYGON - Поддерживает многоугольники с волнистой штриховкой
  • PC_SCANLINE - Поддерживает одинарные линии
  • PC_WIDE - Поддерживает широкие границы
  • PC_STYLED - Поддерживает стилизованные границы
  • PC_WIDESTYLED - Поддерживает широкие стилизованные границы
  • PC_INTERIORS - Поддерживает внутреннее заполнение
  • TEXTCAPS - Поддерживает текстовые возможности

TEXTCAPS может быть комбинацией следующих значений:

  • TC_OP_CHARACTER - Поддерживает точный вывод символов, то есть устройство может размещать свои шрифты в любом месте пикселя. Эта возможность требуется для любого устройства со шрифтами
  • TC_OP_STROKE - Поддерживает точный вывод штриха, то есть устройство может опускать любой штрих своего шрифта
  • TC_CP_STROKE - Поддерживает точную отсечку штрихов, то есть устройство может обрезать свои шрифты на границе пикселя
  • TC_CR_90 - Поддерживает поворот знака на 90 градусов, то есть устройство может вращать знаки только на 90 градусов единовременно
  • TC_CR_ANY - Поддерживает вращение знака на любой угол, то есть устройство может вращать свои шрифты на любой угол
  • TC_SF_X_YINDEP - Поддерживает масштабирование по x и y, то есть устройство может независимо масштабировать свои шрифты по осям x и y
  • TC_SA_DOUBLE - Поддерживает двойное масштабирование, то есть устройство может удвоить размер своего шрифта
  • TC_SA_INTEGER - Поддерживает масштабирование в целое число раз, то есть устройство может масштабировать размер своего шрифта в любое целое число раз
  • TC_SA_CONTIN - Поддерживает масштабирование в любое число раз, то есть устройство может масштабировать свои шрифты в любое число раз, сохраняя горизонтальные и вертикальные пропорции
  • TC_EA_DOUBLE - Поддерживает вывод жирных символов, то есть устройство может делать свои шрифты полужирными. Если для драйвера принтера бит не установлен, GDI пытается создать полужирные шрифты устройства, печатая их дважды
  • TC_IA_ABLE - Поддерживает вывод курсива, то есть устройство может делать свои шрифты курсивными. Если этот бит не установлен, GDI предполагает, что курсив не доступен
  • TC_UA_ABLE - Поддерживает подчеркивание, то есть устройство может подчеркивать свои шрифты. Если этот бит не установлен, GDI создает подчеркивание под шрифтом устройства
  • TC_SO_ABLE - Поддерживает перечеркивание, то есть устройство может перечеркивать свои шрифты. Если этот бит не установлен, GDI создает перечеркивание для шрифтов устройства
  • TC_RA_ABLE - Поддерживает рисование растровых шрифтов, то есть при вызове функций Windows EnumFonts или EnumFontFamilies GDI должен перечислить все растровые или TrueType шрифты, доступные для устройства. Если этот бит не установлен, поставляемые GDI растровые или TrueType шрифты не перечисляются при вызове вышеуказанных функций
  • TC_VA_ABLE - Поддерживает векторные шрифты, то есть при вызове функций Windows EnumFonts или EnumFontFamilies GDI должен перечислить все векторные шрифты, доступные для устройства. Это важно только векторных устройств (то есть графопостроителей). Драйвер дисплея (который должен быть способен использовать растровые шрифты) и растрового принтера всегда перечисляют векторные шрифты, потому что GDI растеризирует их перед передачей драйверу
  • TC_RESETVED - Зарезервировано; должно быть 0

 

CPoint

Этот класс является необходимым для многих классов. Используется очень часто.

Он является оболочкой для структуры Windows - POINT.

typedef struct tagPOINT 
{
LONG x; // координата Х
LONG y; // координата Y
} POINT;

У этого класса нет папы - он сирота.

Для работы необходимо создать класс и объект класса. Все примеры Win32 Console!

Пример 1

Создает класс с неинициализированными Х и Y

CPoint MyPoint();		// и класс и объект
CPoint *MyPoint(); // только класс
MyPoint=new CPoint(); // а это только объект на

Пример 2

Создает обьект со значениями

CPoint MyPoint(1,2);	// догадались теперь х=1 а y=2 

Пример 3

Конструктор копий создает точнуб копию исходного CPoint, брата близнеца:

CPoint InPoint(1,2);
CPoint OutPoint(InPoint);

Пример 4

Из объекта CSize, это естественно, так как в объекте CSize тоже всего x и y.

#include <iostream.h>
#include <afxwin.h>
void main()
{
CPoint InPoint(CSize(10,10));
cout << InPoint.x << " " << InPoint.y << endl;
}

результат 10 и 10, а вы что подумали ?

Пример 5

Из двойного слова. Удобно писать на диск и востанавливать.

При записи на диск записываются только данные, а при чтении обьект восстанавливается.

#include <iostream.h>
#include <afxwin.h>
void main()
{
DWORD d;
d=10;
CPoint InPoint(d);
cout << InPoint.x << " " << InPoint.y << endl;
}

Ну , что будет ? 10 и 0.

Пример 6

Смещает точку с использованием разных классов, а точнее изменяет х и y. Именно смещает, прибавляя значения к х и y:

#include <iostream.h>
#include <afxwin.h>
void main()
{
CPoint MyPoint(10,10);
CPoint OfPoint(3,3);
CSize OfSize(4,-4);
MyPoint.Offset(-5,-5); // непосредственным значением
cout << MyPoint.x << " " << MyPoint.y << endl;
MyPoint.Offset(OfPoint); // другой точкой
cout << MyPoint.x << " " << MyPoint.y << endl;
MyPoint.Offset(OfSize); // классов CSize
cout << MyPoint.x << " " << MyPoint.y << endl;
}

Пример 7

Точки можно сравнивать

#include <iostream.h>
#include <afxwin.h>

void main()
{
CPoint C1Point(10,10);
CPoint C2Point(3,3);
CPoint C3Point(10,10);
cout << "C1== C2 ";
if (C1Point==C2Point)
cout << " равны ";
else
cout << " не раны " << endl;
cout << "C1==C3 ";
if (C1Point==C3Point)
cout << " равны ";
else
cout << " не равны " << endl;
}

Пример 8

Сравнивать можно и так:

#include 
#include
void main()
{
CPoint C1Point(10,10);
CPoint C2Point(3,3);
CPoint C3Point(10,10);
if (!(C1Point!=C3Point))
cout << " равны ";
else
cout << " не равны " << endl;
}  

Пример 9

Можно складывать точки вот так:

#include <iostream.h>
#include <afxwin.h>
void main()
{
CPoint C1Point(10,10);
CPoint C2Point(3,3);
C1Point+=C2Point;
cout << C1Point.x << " " << C1Point.y << endl;
}

Пример 10

И так тоже можно:

#include <iostream.h>
#include <afxwin.h>
void main()
{
CPoint C1Point(10,10);
CSize C2Point(3,3);
C1Point+=C2Point;
cout << C1Point.x << " " << C1Point.y << endl;
}

Пример 11

Так тоже можно:

#include <iostream.h>
#include <afxwin.h>
void main()
{
CPoint C1Point(10,10);
CSize C2Point(3,3);
C1Point=C1Point+C2Point;
cout << C1Point.x << " " << C1Point.y << endl;
}

Пример 12

#include <iostream.h>
#include <afxwin.h>
void main()
{
CPoint C1Point(10,10);
CPoint C2Point(3,3);
C1Point=C1Point+C2Point;
cout << C1Point.x << " " << C1Point.y << endl;
}

Пример 13

Вычитать так:

#include <iostream.h>
#include <afxwin.h>
void main()
{
CPoint C1Point(10,10);
CPoint C2Point(3,3);
C1Point-=C2Point;
cout << C1Point.x << " " << C1Point.y << endl;
}

Пример 14

И так !

#include <iostream.h>
#include <afxwin.h>
void main()
{
CPoint C1Point(10,10);
CSize C2Point(3,3);
C1Point-=C2Point;
cout << C1Point.x << " " << C1Point.y << endl;
}

Пример 15

Вычитать так:

#include <iostream.h>
#include <afxwin.h>
void main()
{
CPoint C1Point(10,10);
CPoint C2Point(3,3);
C1Point=C1Point-C2Point;
cout << C1Point.x << " " << C1Point.y << endl;
}

Пример 16

И так !

#include <iostream.h>
#include <afxwin.h>
void main()
{
CPoint C1Point(10,10);
CSize C2Point(3,3);
C1Point=C1Point-C2Point;
cout << C1Point.x << " " << C1Point.y << endl;
}

Пример 17

Запись и чтение CPoint в файл.

#include <fstream.h>	// файловый поток
#include <iostream.h> // стандартный поток
#include <afxwin.h> // без коментариев
void main()
{
// переменные
DWORD *dwTest;
WORD wTest[2];
CPoint CTestPoint(1234,1119); // Создали класс точки
//Запись
wTest[0]=(WORD)CTestPoint.x; //
wTest[1]=(WORD)CTestPoint.y; //Перенесли в WORD + WORD =DWORD !
ofstream ofs("test.dat",ios::binary); // открыли на запись
ofs.write((char*)&wTest,sizeof(wTest)); // записали
ofs.close(); // закрыли
// Чтение
ifstream ifs("test.dat",ios::binary); // открыли на чтение
ifs.read((char*)&wTest,sizeof(wTest)); // прочитали
ifs.close(); // закрыли
dwTest=(DWORD*)&wTest; // Адреса равны !
// проверка
CPoint TestPoint(*dwTest); // Востановить класс
cout << TestPoint.x << " " << TestPoint.y << endl; //Вывести на экран
}

 

Compiler Error C2065

Эта ошибка связана с отсутствием определения переделенной. Смотрим пример:

#include "stdafx.h"

int main(int argc, char* argv[])
{
for (int x=0;x<y;x++) //y не объявлена
{
}
return 0;
}

Переменная y не определена:

D:\VС\TestError\TestError.cpp(12) : error C2065: 'y' : undeclared identifier 

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

#include "stdafx.h"

int main(int argc, char* argv[])
{
int X; // надо бы нижнем регистром
for (int x=0;x<y;x++)
{
}
return 0;
}

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

#include "stdafx.h"

int main(int argc, char* argv[])
{
BOOL i;
return 0;
}

Она просто не определена в заголовочном файле:

D:\VС\TestError\TestError.cpp(11) : error C2065: 'BOOL' : undeclared identifier 

Она просто не определена в заголовочном файле. Надо включить windows.h и все станет на свое место.

Область видимости переменной может привести к появлению этой ошибки.

#include "stdafx.h"

int main(int argc, char* argv[])
{
for (int x=0;x<10;x++)
{
for (int y=0;y<10;y++)
{
}
}
y=20;
return 0;
}

И та же ошибка:

D:\VС\TestError\TestError.cpp(15) : error C2065: 'y' : undeclared identifier

 

Compiler Error C2143

Это ошибка синтаксиса. Связана она с отсутствием необходимых разделителей между элементами языка. Компилятор ожидает, что некоторые элементы языка появятся прежде или после других элементов. Если этого не происходит, то он выдаем ошибку. Будем пробовать ее получить. Пишем код:

#include "stdafx.h"
int main(int argc, char* argv[])
{
int x;
int y;
if (x<y) : // двоеточие здесь совсем не нужно
{
}
}

Результат работы компилятора:

D:\VС\TestError\TestError.cpp(10) : error C2143: syntax error : missing ';' before ':' 

Второй наиболее частый вариант это забыть поставить ";" после объявления класса.

#include "stdafx.h"

class CMy
{
} // забыли ";"

class CMy2
{
}

int main(int argc, char* argv[])
{
}

Опять та же ошибка.

D:\VС\TestError\TestError.cpp(12) : error C2236: unexpected 'class' 'CMy2'
D:\VС\TestError\TestError.cpp(12) : error C2143: syntax error : missing ';' before '{'

Еще один вариант с лишней скобки:

#include "stdafx.h"

int main(int argc, char* argv[])
{
} // это лишнее
return 0;
}

Опять та же ошибка:

D:\VС\TestError\TestError.cpp(11) : warning C4508: 'main' : function should return a value; 'void' return type assumed
D:\VС\TestError\TestError.cpp(12) : error C2143: syntax error : missing ';' before 'return'

Отсутствие закрывающей скобки может привести к такой же ошибке:

#include "stdafx.h"

int main(int argc, char* argv[])
{
for (int x=0;x<10;x++ // не хватает ")"
{
}
return 0;
}

Как видите это ошибка связанна с синтаксисом. Если она у Вас появляется внимательно просмотрите код на предмет соответствия требованиям C++ (лишние знаки, забытые ;)

 

IDR_MAINFRAME формат строкового ресурса

Строковый ресурс IDR_MAINFRAME формируется автоматически MFC AppWizard. Эта стока включает ряд параметров разделенных \n.

Вот такой формат имеет этот строковый ресурс.

IDR_MAINFRAME < windowTitle >  \n < docName >  \n < fileNewName >  \n
< filterName > \n < filterExt > \n < regFileTypeID > \n
< regFileTypeName > \n \n
< filterMacName(filterWinName) >

Далее мы определим каждый параметр:

< windowTitle >  

Имя приложения. Например, вы запускаете приложение и в строке приложения справа от имени файла имя приложения. Запустите Pr2.exe. Справа от безымянного (имя файла) будет выведен этот первый параметр.

Безымянный - pr2

< docName >

Имя документа по умолчанию. Если незаполнено, то вы увидите безымянный. Поменяйте строку в проекте Pr2 на

pr2\nNew001\nPr2\nPr2 Files (*.pr2)\n.pr2\nPr2.Document\nPr2 Document

И при запуске программы Вы увидите название файла New001.

< fileNewName >  

Имя типа документа. Используется если программа работает с несколькими классами документов. Появляется при использовании меню File New при создании документа.

< filterName >    

Фильтр для диалога открытия файла. В диалоговом окне открытия файла отображается в окне Files of Types

< filterExt > 

Расширение файла документа.

< regFileTypeId > 

Тип документа. Это поле только для внутреннего использования. Тип документа необходим для связывания файла в File Manager

< regFileTypeName > 

Имя приложения для регистрации в базе данных Windows. На основе этого имени в реестре Windows создается раздел. Посмотреть его вы можете используя RegEdit.

 

INI файл из любого каталога

INI файлы можно находить где угодно и к ним можно прописать путь. Вот пример написанный мною:

CString strFile;

strFile = ReadFromIni(strFile, "PATH", "OutputDir"); //strFile- Сюда запишется строка из INI файла
//"PATH" - Название секции
//"OutputDir"- Название ключа

CString CDeliveryCreatorDlg::ReadFromIni(CString strString, CString strSection, CString strKey)
{
char* pIniFileName = "C:\\Program Files\\INI.ini";
LPTSTR pstrString = strString.GetBuffer(200);
if(!GetPrivateProfileString(
strSection,
strKey,
"",
pstrString,
200,
pIniFileName //Адрес INI
))
MessageBox("[" + strSection + "] or KEY \"" + strKey + "\" is not found", "Error");
strString.ReleaseBuffer(strlen(pstrString));
return strString;
}

 

STUB заглушка для MS DOS

Ваша программа может запускаться не только в Windows. Совсем не тяжело представить ситуацию, когда пользователь может запустить программу из MS DOS. Тогда он получит сообщение, что якобы эту программу запускать надо в Windows. Это стандартная реакция, как это делается ??? В код компилированной программы добавляется еще один код для сеанса MS DOS.

      Это Win32 ?
|
-------------------
| |
нет да
заглушка основная программа

Так вот заглушка есть стандартная, но Вы можете ее и поменять используя директиву линковщику (Link) - STUB. Мало того, что Вы можете сделать красивое объяснение пользователю куда ему обратиться, чтобы работать с Вашей программой :-) и что надо сделать, например, запустить Windows. Вы можете сделать круче.

Для того, чтобы Вам сделать приложение заглушку в данной версии VC вам придется использовать недокументированную опцию линковщика /KNOWEAS. После того как создана подобная заглушка ее надо подключить в Project - Setting - Link - Project Options, например, так:

/stub:Noname.exe 

Если заглушка будет созданна не по правилам, то вы получите примерно такое сообщение:

Linking...
Noname.exe : warning LNK4060: stub file missing full MS-DOS header; rebuild stub with /KNOWEAS 16-bit LINK option

В книге "Программирование на Borland C++ для Windows", которую писал Том Сван, а как мне кажется это очень хороший автор, написано, что некоторые программисты используют данную возможность для того, чтобы сделать две версии программы в одном EXE файле для Windows и для DOS. Мне эта идея понравилась :-) Классно пользователю вообще все равно просто запустил откуда запускается и работай :-).

 

Union

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

union Имя объединения
{
Тип 1;
Тип 2;
Тип 3;
......

} Конкретное имя переменной;

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

#include "iostream.h"
#include "afxwin.h"

union MyUninon
{
double unVal;
int unInt;
BOOL unBool;
} MyUnionTypes;

void main()
{
MyUnionTypes.unVal=0.3;
cout << MyUnionTypes.unVal << endl;
cout << "__________________" << endl;
MyUnionTypes.unInt=1;
cout << MyUnionTypes.unVal << endl;
cout << MyUnionTypes.unInt << endl;
cout << "__________________" << endl;
MyUnionTypes.unBool=false;
cout << MyUnionTypes.unVal << endl;
cout << MyUnionTypes.unInt << endl;
cout << MyUnionTypes.unBool << endl;
}

Создайте этот пример, как Win32 Console, скомпилируйте и запустите.

В последнем присвоении вы увидите как установка unBool повлияла на unInt.

 

memset

Функция memset заполняет буфер указанным символом.

void *memset( void *dest, int c, size_t count );

Эта функция определена в memory.h и string.h.

Параметры:

  • dest - указатель на буфер
  • c - символ заполнения
  • count - количество символов

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

#include "stdafx.h"
#include "string.h"
#include "stdio.h"
#include "iostream.h"

struct MyStruct
{
char test[4];
int i;
};

void main()
{
char buffer[9];
strcpy(buffer,"123456789");
cout << buffer << " not memcpy" << endl;
memset(buffer,'1',sizeof(buffer));
cout << buffer << " memset" << endl;
}

Так же эту функцию можно применять для обнуления структур.

#include "stdafx.h"
#include "string.h"
#include "stdio.h"
#include "iostream.h"

struct MyStruct
{
char test[5];
int i;
};

void main()
{
MyStruct mm;
strcpy(mm.test,"hello");
mm.i=5;
cout << mm.i << " " << mm.test << " not memset " << endl;
memset(&mm,0,sizeof(mm));
cout << mm.i << " " << mm.test << "memset " << endl;
}

 

Исключительные ситуации

Знакомство с исключительными ситуациями начнем с примера:

#include "iostream.h"
#include "afxwin.h"

void funct1();
void funct2();
void funct3();


void main()
{
try
{
funct1();
funct2();
funct3();
}
catch(CString cs)
{
cout << "Error Detecting" << endl;
cout << cs << endl;
}
}


void funct1()
{
}

void funct2()
{
CString s="Error funct 2";
int x;
cin >> x;
if (x==1) throw (s);
}

void funct3()
{
}

Создавайте приложение Win32 Console запускайте. Программа попросит ввести Вас число. Если Вы введете 1, то увидите на экране:

1
Error Detecting
Error funct 2
Press any key to continue

Итак, в чем суть данного кода. У нас есть комплекс функций, в каждой из которых может произойти ошибка. Вот эти функции мы и защищаем блоком try. Если ошибка произойдет то управление передается в блок catch и сообщается о том, что произошла ошибка.

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

Условный пример. Ваша программа должна установить связь с базой данный используя ODBC.

Database db;		// объект базы данных
db.Open("x.db"); // имя файла
db.OpenTable("table1"); // имя таблицы

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

Выходы из этой ситуации придуманы давно. Заводить переменную как флаг ошибки и обрабатывать её.

Вот так например

Database db;	
if (db.Initial())
{
db.Open("x.db");
if (db.Open())
{
if (db.OpenTable("table1"))
{
}
}
}

Но еще ошибку надо проверить на тип, например отсутсвует файл или нет доступа. И всё это в коде функции, обрастая if , case и т.д. не тяжело и потерять смысл, о чем вообще функция :-).

Обработка исключительных ситуаций позволяет крассиво решить эту проблемму. Вот так:

try
{
Database db;
db.Open("x.db");
db.OpenTable("table1");
}
catch(...)
{
cout << "Error detected " << end;
}

Как видите обработка ошибок стекается в одну функцию. Внимание для того чтобы пользоваться этими возможностями функции классы должны быть ориентированны на обработку исключительных ситуаций. Обработка исключительных ситуаций входит в стандарт ANSI C++, и её должны поддерживать компиляторы. Ниже приведен пример, который работает на VC++ 5.

#include "iostream.h"
#include "afxwin.h"

void main()
{
try
{
int x=1;
int y=0;
x=x/y;
cout << " Hello bad cod ";
}
catch(...)
{
cout << "Error detecting" << endl;
}
}

При выполнении этой программы программа не завершится ошибкой Windows, и надпись Hello bad cod Вы не увидите. На экране будет зловещее Error detecting. Но реакция на ошибку в Вашей власти.

Итак давайте разберемся с обьявлениями. Защищается блок кода так.

try
{
// защищаемый код
}
catch(...)
{
// реакция на ошибку
}

Если Вам самом необходимо вызвать исключительную ситуацию Воспользуйтесь throw:

// Действие
// Если ошибка вызвать

throw "Error"

Обработка ошибок и из вызов основаны на классах. В примере ниже вы получите abnormal terminated так как тип возбуждаемой ошибки не соответсвует классу обработки. throw type_error и catch (type_error) должны совпадать.

#include "iostream.h"
#include "afxwin.h"
void main()
{
try
{

throw 23.34;
}
catch(int i)
{
cout << "Error detecting" << endl;
}
}

Для обработки этой ошибки необходимо обьявить catch(double i)

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

 

Классы Видов

В MFC уже предусмотрены классы видов (View) нескольких типов:

CView Базовый класс вида.
CCtrlView Базовый класс вида для элементов управления Win 95
CDaoRecordView Класс вида для работы с DAO
CEditView Класс вида обеспечивающий основные функции редактирования
CFormView Класс вида на основе диалогового окна
CListView Класс вида на основе окна списка
COleDBRecordView Класс вида для работы с базами данных
CRecordView Класс вида для работыс базами данных ODBC
CRithEditView Класс вида обеспечивающий расширенный набор функций по редактирования текста
CScrollView Класс вида олбеспечивающий полосы прокрутки
CTreeView Класс вида, который использует для отображения элемент TREE

 

Коментарии ClassWizard

При генерации приложений AppWizard генерирует некоторое количество комментариев. Эти комментарии позволяют ClassWizard определять места кода для локализации объектов и трассировки. Конечно Вы их не используете и трогать не должны. Но интересно же знать, что они означают :-). Мне так интересно.

  • AFX_DATA - Ограничивает места объявления переменных в файлах загаловках имеющих отношения к обмену данными с диалоговым окном DDX.
  • AFX_DATA_INIT - Ограничивает обмен данных с диалогом при инициализации переменных в конструкторе диалогового окна.
  • AFX_DATA_MAP - Ограничивает последовательность вызовов функций обмена данными с диалоговым окном.
  • AFX_DISP - Ограничивает объявления автоматов в файлах заголовков
  • AFX_DISP_MAP - Ограничивает секцию автоматов в файлах реализации
  • AFX_EVENT - Ограничивает объявление событий ActiveX в файлах заголовоков
  • AFX_EVENT_MAP - Ограничивает секцию автоматов ActiveX в файлах реализации
  • AFX_FIELD - Ограничивает объявление переменных связанных с базами данных в файлах заголовков.
  • AFX_FIELD_INIT - Ограничивает инициализацию переменных связанных с базами данных
  • AFX_FIELD_MAP - Ограницивает функции обмена данными переменных с полями БД
  • AFX_MSG - Ограничивает элементы карты сообщений, которые вставляет ClassWizard в файлы заголовков.
  • AFX_MSG_MAP - Ограничивает область обработки карты сообщений.
  • AFX_VIRTUAL - Ограничивает область виртуальных функций в файлах заголовоков.

Ну что это дает. Вообщем-то ничего. Но вот пример. Если вы решили перегрузить событие Create в ответ на сообщение WM_CREAT, то функция обработки будет помещена в раздел функций обработки сообщений ограниченная разделом AFX_MSG в файле загаловка в классе, для которого это сообщение обрабатывается.

protected:
//{{AFX_MSG(CMy1View)
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};

 

Константы пространства имен для SHGetSpecialFolderLocation

  • CSIDL_DESKTOP - Рабочий стол (Desktop) для данного пользователя. Виртуальная папка, являющаяся корнем основного пространства имен оболочки.
  • CSIDL_INTERNET - Интернет (Internet). Виртуальная папка, представляющая пространство Интернет.
  • CSIDL_PROGRAMS - Программы (Programs) для данного пользователя. Каталог файловой системы, содержащий в себе группы программ пользователя, также являющиеся каталогами файловой системы.
  • CSIDL_CONTROLS - Панель управления (Control Panel).
  • CSIDL_PRINTERS - Принтеры (Printers). Виртуальная папка, содержащая в себе инсталлированные принтеры.
  • CSIDL_PERSONAL - Мои документы (My Documents). Каталог файловой системы, служащий общим хранилищем для документов.
  • CSIDL_FAVORITES - Избранное (Favorites) для данного пользователя. Каталог файловой системы, служащий общим хранилищем избранных пользователем элементов.
  • CSIDL_STARTUP - Автозагрузка (Startup) для данного пользователя. Каталог файловой системы, который является пользовательской папкой программ "Автозагрузка". Система запускает эти программы каждый раз, когда данный пользователь входит в Windows NT или когда стартует Windows 95/98.
  • CSIDL_RECENT - Документы (Documents). Каталог файловой системы, содержащий в себе ссылки на самые последние документы, с которыми недавно работал пользователь.
  • CSIDL_SENDTO - Отправить (Send To). Каталог файловой системы, содержащий в себе пункты меню Send To.
  • CSIDL_BITBUCKET - Корзина (Recycle Bin).
  • CSIDL_STARTMENU - Главное меню (Start menu) для данного пользователя. Каталог файловой системы, содержащий в себе пункты меню Start.
  • CSIDL_DESKTOPDIRECTORY - Каталог файловой системы, хранящий файловые объекты "Рабочего стола" (Desktop directory) для данного пользователя.
  • CSIDL_DRIVES - Мой компьютер (My computer). Виртуальная папка, содержащая в себе все, что находится на локальном компьютере: устройства хранения, принтеры и панель управления. Эта папка может также содержать в себе спроецированные сетевые диски.
  • CSIDL_NETWORK - Сетевое окружение (Network Neighborhood). Виртуальная папка, представляющая верхний уровень иерархии сети.
  • CSIDL_NETHOOD - Каталог файловой системы, хранящий файловые объекты "Сетевого окружения" (Network Neighborhood).
  • CSIDL_FONTS - Шрифты (Fonts). Виртуальная папка, содержащая шрифты.
  • CSIDL_TEMPLATES - Шаблоны (Templates). Каталог файловой системы, служащий общим хранилицем шаблонов документов (пункт контекстного меню оболочки "Создать").
  • CSIDL_COMMON_STARTMENU - Каталог файловой системы, содержащий в себе общие пункты меню Start, которые появляются у всех пользователей.
  • CSIDL_COMMON_PROGRAMS - Каталог файловой системы, содержащий в себе общие группы программ пользователя, которые появляются у всех пользователей.
  • CSIDL_PROGRAM_FILES - Каталог файловой системы, в котором должны располагаться программные продукты.
  • CSIDL_PROGRAM_FILES_COMMON - Каталог файловой системы, в котором должны располагаться компоненты, общие для группы продуктов.
  • CSIDL_COMMON_STARTUP - Каталог файловой системы, содержащий в себе общие программы, которые появляются в папке Startup для всех пользователей.
  • CSIDL_COMMON_DESKTOPDIRECTORY - Каталог файловой системы, хранящий общие файловые объекты "Рабочего стола" (Desktop directory), которые появляются на рабочих столах всех пользователей.
  • CSIDL_APPDATA - Каталог файловой системы, служащий общим хранилищем данных, специфичных для приложения.
  • CSIDL_PRINTHOOD - Каталог файловой системы, служащий общим хранилищем ссылок на принтеры.
  • CSIDL_ALTSTARTUP - Каталог файловой системы, который является нелокализованной пользовательской папкой программ "Автозагрузка".
  • CSIDL_COMMON_ALTSTARTUP - Каталог файловой системы, содержащий в себе общие программы, которые появляются в нелокализованной папке Startup для всех пользователей.
  • CSIDL_COMMON_FAVORITES - Каталог файловой системы, содержащий в себе общие избранные элементы, которые появляются в папке "Избранное" у всех пользователей.
  • CSIDL_INTERNET_CACHE - Каталог файловой системы, служащий общим хранилищем для временного хранения файлов, кэшируемых при работе с Интернет.
  • CSIDL_COOKIES - Каталог файловой системы, служащий общим хранилищем для Internet Cookies.
  • CSIDL_HISTORY - Каталог файловой системы, служащий общим хранилишем для хранения истории работы с Интернет.

 



Методы класса CDialog

  • CDialog - Конструирует объект CDialog
  • Create - Инициализирует объект CDialog
  • CreateIndirect - Создает немодальное диалоговое окно по шаблону находящемуся в памяти
  • DoModal - Вызывает модальное диалоговое окно и завершает работу после его закрытия
  • EndDialog - Закрывает модальное диалоговое окно
  • GetDefID - Получает идентификатор кнопки, используемой по умолчанию
  • GotoDlgCtrl - Передает фокус определенному управляющему элементу диалогового окна
  • InitModalIndirect - Создает модальное диалоговое окно по шаблону, находящемуся в памяти; параметры сохраняются до вызова DoModal()
  • MapDialogRect - Преобразует координаты в единицах диалогового окна в экранные
  • NextDlgCtrl - Передает фокус следующему управляющему элементу диалогового окна
  • OnCancel - Переопределяется для обработки кнопки Cancel или клавиши Esc
  • OnInitDialog - Переопределяется для проведения дополнительной инициализации диалогового окна
  • OnOK - Переопределяется для обработки кнопки OK в модальном диалоговом окне
  • OnSetFont - Переопределяется для задания шрифта, используемого элементом диалогового окна при отображении текста
  • PrevDlgCtrl - Передает фокус предыдущему управляющему элементу диалогового окна
  • SetDefID - Назначает кнопку диалогового окна используемой по умолчанию
  • SetHelpID - Задает идентификатор контекстной справки

 


 

Методы класса CEdit

  • CanUndo - Указывает, можно ли отменить операцию редактирования в текстовом поле
  • CEdit - Создает объект CEdit
  • CharFromPos - Получает индексы строки и символа, расположенных как можно ближе к заданной точке
  • Clear - Удаляет текущий выделенный фрагмент текстового поля
  • Copy - Копирует текущий выделенный фрагмент текстового поля в буфер обмена
  • Create - Создает текстовое как управляющий элемент Windows и связывает его с объектом CEdit
  • Cut - Удаляет текущий выделенный фрагмент текстового поля и копирует текст в буфер обмена
  • EmptyUndoBuffer - Сбрасывает флаг отмены для текстового поля
  • FmtLines - Разрешает/запрещает включение "мягких" разрывов строк
  • GetFirstVisibleLine - Определяет верхнюю видимую строку текстового поля
  • GetHandle - Получает логический номер области памяти, которая в настоящий момент выделена для многострочного текстового поля
  • GetLimitText - Получает максимальный объем текста, который может храниться в объекте CEdit
  • GetLine - Получает строку текста из текстового поля
  • GetLineCount - Определяет количество строк в многострочном текстовом поле
  • GetMargins - Получает размеры левого и правого полей
  • GetModify - Показывает, изменилось ли содержимое текстового поля
  • GetPasswordChar - Получает символ, отображаемый в текстовом поле при вводе текста
  • GetRect - Получает размеры форматного прямоугольника
  • GetSel - Получает позицию начального и конечного символов для текущего выделенного фрагмента
  • LimitText - Ограничивает длину текста, который может быть введен пользователем
  • LineFromChar - Получает номер строки, содержащий символ с заданным индексом
  • LineIndex - Получает символьный индекс (то есть смещение в символах от начала текста) для заданной строки
  • LineLenght - Получает длину строки
  • LineScroll - Прокручивает текст в многострочном текстовом поле
  • Paste - Вставляет в текстовое поле данные из буфера обмена
  • PosFromChar - Получает координаты левого верхнего угла символа с заданным индексом
  • ReplaceSel - Заменяет текущий выделенный фрагмент текстового поля заданным текстом
  • SetHandle - Задает логический номер локальной области памяти, которая будет использоваться для многострочного текстового поля
  • SetLimitText - Задает максимальный объем текста, который может храниться в объекте CEdit
  • SetMargins - Задает размеры левого и правого полей
  • SetModify - Устанавливает или сбрасывает флаг изменений
  • SetPasswordChar - Задает или отменяет специальный символ, отображаемый при вводе текста
  • SetReadOnly - Устанавливает или отменяет для текстового поля режим "только для чтения"
  • SetRect - Задает размеры форматного прямоугольника для многострочного текстового поля и обновляет его изображение
  • SetRectNP - Задает размеры форматного прямоугольника для многострочного текстового поля без перерисовки
  • SetSel - Задает текущий выделенный фрагмент
  • SetTabStops - Задает позиции табуляции для многострочного текстового поля
  • Undo - Отменяет последнюю операцию с текстовым полем

 


    Методы класса CFile

    Метод Назначение
    CFile( )
    Конструктор
    Создает экземпляр (объект) класса CFile. Если передать аргумент, (имя файла) открывает заданный файл
    ~CFile( )
    Деструктор
    Уничтожает экземпляр класса CFile, Если соответствующий файл открыт, закрывает его перед удалением экземпляра класса (объекта)
    Abort( ) Немедленно, не обращая внимания на ошибки, закрывает файл
    Close( ) Закрывает файл
    Dublicate( ) Создает экземпляр класса для дубликата класса
    Flush( ) Сбрасывает данные из потока
    GetFileName( ) Считывает имя файла
    GetFilePath( ) Считывает полный путь к файлу
    GetFileTitle( ) Считывает имя файла (без расширения)
    GetLength( ) Считывает длину файла
    GetPosition( ) Считывает текущую позицию в файле
    GetStatus( ) Считывает статус файла
    LockRange( ) Блокирует фрагмент файла для доступа со стороны других процессов
    Open( ) Открывает файл
    Read( ) Считывает данные из файла
    Remove( ) Стирает файл
    Rename( ) Переименовывает файл
    Seek( ) Переставляет указатель текущей позиции в файле
    SeekToBegin( ) Переставляет указатель текущей позиции в начало файла
    SeekToEnd( ) Переставляет указатель текущей позиции в конец файла
    SetFilePath( ) Устанавливает путь к файлу
    SetLength( ) Устанавливает длину файла
    SetStatus( ) Устанавливает статус файла
    UnlockRange( ) Снимает блокировку фрагмента файла
    Write( ) Записывает данные в файл

    Если вызов конструктора происходит с аргументом - (именем файла), то нет необходимости явно вызывать функцию открытия файла. 

    Аргументы конструктора: Имя файла и флаги режима доступа к файлу. Флаги можно комбинировать с учетом пожелания программиста с помощью оператора ИЛИ ( | ), главное чтобы они не противоречили друг другу.

    Флаги режима доступа к файлу:

    Флаг Описание
    CFile::modeCreate Создается новый файл или обнуляется существующий
    CFile::modeNoInharit Запрещает наследование файла порожденным процессом
    CFile::modeNoTruncate Если файл уже создан, его содержимое не удаляется
    CFile::modeRead Файл открывается только для чтения
    CFile::modeReadWrite Файл открывается для чтения и записи
    CFile::modeWrite Файл открывается только для записи
    CFile::shapeCombat Позволяет любому другому процессу открывать этот файл
    CFile::shapeDenyNone Позволяет другим процессам читать и выполнять запись в файл
    CFile::shapeDenyRead Запрещает чтение файла другим процессам
    CFile::shapeDenyWrite Запрещает запись в файл другим процессам
    CFile::shapeExclusive Запрещает доступ к файлу другим процессам
    CFile::typeBinary Устанавливает для файла двоичный режим
    CFile::typeText Устанавливает для файла текстовой режим

    Работать с файлами можно, используя объекты класса CFile, однако можно создать свой собственный объект класса CArchive, который позволит использовать функции Serialize( ), написанные для объектов других классов, передавая им просто ссылку на ваш собственный объект класса CArchive.

     

    О записи INI файлов в другие каталоги

    Русский MSDN  
    Дата 26.02.01 04:57
    От кого Anton <Адрес электронной почты защищен от спам-ботов. Для просмотра адреса в вашем браузере должен быть включен Javascript.>
    Кому <Адрес электронной почты защищен от спам-ботов. Для просмотра адреса в вашем браузере должен быть включен Javascript.>

    GetProfileString(WriteProfileString) - работает непосредственно с Win.ini.

    GetPrivateProfileString(WritePrivateProfileString) - работают с ini файлами, но находящимися непосредственно в каталоге Windows.

    А вот так можно работать с ini файлом из текущейго каталога. Причем EXE файл можно переименовывать и все будет работать. Создаем проект на основе диалогов. На диалоге кнопка. Кнопка делает следующее:

    void CWINIDlg::OnButton1() 
    {
    CWinApp* myap = AfxGetApp();
    char r1[20];char r2[20];
    strcpy(r1, ".\\"); // эта строка и говорит о текущем каталоге
    strcpy(r2, myap->m_pszProfileName);
    strcat(r1, r2);
    AfxMessageBox(r1); // покажем не экране
    WritePrivateProfileString("Moth", "Test", "Wanted", r1);
    }

    Для Записи в INI файл это работает. А вот при чтении необходима еще одна строка:

    strcat(r1, r2);
    strcat(r1, ".ini");
    AfxMessageBox(r1); // покажем не экране

     

    О классах окон

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

    typedef struct tagWNDCLASS {    
    UINT style;
    WNDPROC lpfnWndProc;
    int cbClsExtra;
    int cbWndExtra;
    HINSTANCE hInstance;
    HICON hIcon;
    HCURSOR hCursor;
    HBRUSH hbrBackground;
    LPCSTR lpszMenuName;
    LPCSTR lpszClassName;
    } WNDCLASS;

    Каждое окно имеет класс. И перед созданием окна класс окна необходимо зарегистрировать. Регистрировать можно только для использования в своем приложении или для общего использования в системе всеми приложениями. Windows предоставляет много готовых классов для общего использования приложениями. Вот некоторые основные классы:

    Edit
    Listbox
    ComboBox
    ScrollBar
    Button
    Static

    Кроме того, Windows предоставляет другие глобальные классы для общего доступа:

    Класс меню
    Класс рабочего стола
    Класс диалогового окна
    Класс задач
    Класс икон
    ComboBox
    MDIClient

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

    Можно создавать свои прикладные глобальные классы. Это можно использовать для создания специальных элементов управления. Для этого описание класса необходимо поместить в DLL и класс будет доступен пока DLL находится в памяти. Описывать такой класс необходимо со стилем CS_GLOBALCLASS. Для автоматической загрузки DLL есть ключи реестра куда помещаются DLL автоматически загружаемые вместе с приложением WIN 32:

    HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\ 
    CurrentVersion\Windows\APPINIT_DLLS

    Кроме того Вы можете зарегистрировать свой класс в процессе инициализации приложения скажем с помощью LoadLibrary.

    Вы можете создавать подклассы, используя функцию SetClassLong с индексом GCL_WNDPROC. Приложение может создать свои подклассы всех стандартных классов окон.

    Для доступа к структуре класса окна есть несколько функций

    GetClassLong 
    GetWindowLong
    SetClassLong
    SetWindowLong

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

    GCL_CURSOR 
    GCL_HBRBACKGROUND
    GCL_HICON
    GWL_HINSTANCE
    GWL_HWNDPARENT
    GWL_ID
    GWL_USERDATA

    Получить данные GWL_HWNDPARENT можно и по другому, воспользовавшись функциями API, такой как GetParent например.

     

    О палитрах

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

    Итак, а что же реально палитра представляет ??? Это таблица соответствия кода цвету примерно так.

    номер  Reb Green Blue
    1 0 0 0
    2 100 0 0
    .......

    Самое главное, что пользуясь палитрой Вы не даете конкретный цвет, а даете код (его положение) в палитре. Вот и вся идея. Каждый рисунок, если он создан в формате 256 цветов, содержит свою таблицу, которая и позволяет его отображать близко к реальности. Исключения составляют 24 битовые рисунки, им палитра не нужна, но и размер они имеют внушительный, так что дело за Вами. Применение палитры втрое уменьшает размер файла.

    Паритр несколько, то есть две

    системная
    логическая

    Системная палитра - это палитра Windows и её трогать не надо. Она отнимает некоторое количество цветов (20) и поэтому у Вас в распоряжении их несколько меньше 236. Логическая - это же палитра вашего приложения. В GDI есть функции, которые позволяют изменять эти 20 палитр. Можно попробовать, только Вы потом точно узнаете свой Windows ????

    MFC имеет несколько функций, которые должны облегчить Вам жизнь - это CPalette и CDC. Несмотря на всё это думать над палитрами надо постоянно. Точное отображения двух картинок с разными палитрами возможно только в режиме TRUE COLOR. То есть если Вы захотите одновременно просматривать две картинки с разными палитрами полностью заполнеными, то не сможете это сделать в режиме 256. Только в TRUE COLOR.

    В Windows есть понятие менеджера палитр. Это, как бы сказать, программа чтоли или лучше модуль, который производит операции с палитрами при этом он наделен некоторыми навыками. То есть, например, что если Вы определили палитру, в которой всего 4 дополнительных цвета и запустили приложение, а во втором приложении тоже определено 4 цвета, то оба они будут отражаться без искажений. Этот менеджер просто объединит эти палитры. Но всему етсь предел и этот предел 256 цветов.

    Откуда взялось это проклятое 256 ? Да вот откуда, код цвета хранится в одном байте. А один байт может хранить число от 0 до 255, всего 256 комбинаций. Вот и все.

     

    О полосах прокрутки

    Есть два вида полос прокрутки:

    1. Стандартные - являются составной частью окна (включая диалоговое окно). Базовый класс CWnd.
    2. Независимые - существуют независимо от окон (включая диалоговые окна). Базовый класс CScrollBar.

    Обработка сообщений полосы прокрутки:

    В отличие от других элементов управления, полосы прокрутки не генерируют сообщение WM_COMMAND. Вместо этого могут посылаться следующие сообщения: WM_VSCROLL и WM_HSCROLL для вертикальной и горизонтальной полос соответственно. Эти сообщения обрабатываются функциями OnVScroll( ) и OnHScroll( ), прототипы которых таковы:

    afx_msg void CWnd::OnVScroll(UINT SBCode, INT Pos, CScrollBar *SB);
    afx_msg void CWnd::OnHScroll(UINT SBCode, INT Pos, CScrollBar *SB);

    Параметр SBCode содержит код выполненного над полосой прокрутки действия. Наиболее распространенные его значения таковы:

    • SB_LINEUP - Изменение позиции ползунка на одну позицию вверх.
    • SB_LINEDOWN - Изменение позиции ползунка на одну позицию вниз.
    • SB_PAGEUP - Изменение позиции ползунка на одну страницу вверх.
    • SB_PAGEDOWN - Изменение позиции ползунка на одну страницу вниз.
    • SB_LINELEFT - Изменение позиции ползунка на одну позицию влево.
    • SB_LINERIGHT - Изменение позиции ползунка на одну позицию вправо.
    • SB_PAGELEFT - Изменение позиции ползунка на одну страницу влево.
    • SB_PAGERIGHT - Изменение позиции ползунка на одну страницу вправо.
    • SB_THUMBPOSITION - Генерируется при перемещении ползунка на новую позицию.
    • SB_THUMBTRACK - В дополнение к SB_THUMBPOSITION, это сообщение генерируется если при перемещении ползунка на новое место, удерживается кнопка мышки. Это позволяет отслеживать позицию ползунка прежде чем он будет отпущен.

    Pos - Указывает на текущую позицию ползунка. SB - Если сообщение сгенерировано стандартной полосой прокрутки, то параметр SB буде равен NULL. Если же оно было сгенерированно независимой полосой прокрутки, то параметр SB будет содержать указатель на объект полосы. 

    Задание и получение диапазона полосы прокрутки:

    (По умолчанию) Стандартная полоса прокрутки имеет диапазон от 0 до 100. Независимая, имеет диапазон от 0 до 0, что означает необходимость предварительного задания диапазона.SetScrollRange( ) - эта функция служит для задания диапазона, и имеет два варианта: один для стандартных полос, другой для независимых.

    Прототип для стандартной полосы:

    void CWnd::SetScrollRange(int Which, int Min, int Max, BOOL Redraw = TRUE);
    • Which - Определяет, для какого типа полос прокрутки задается диапазон: SB_VERT или SB_HORZ.
    • Min - Нижняя граница диапазона.
    • Max - Верхняя граница диапазона.
    • Redraw - Если равен TRUE, то полоса прокрутки будет перерисована.

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

    void CScrollBar::SetScrollRange(int Min, int Max, BOOL Redraw = TRUE;)

    При необходимости получения диапазона полосы прокрутки используется функция GetScrollRange(). Эта функция так же существует в двух вариантах:

    void CWnd::GetScrollRange(int Which, LPINT lpMin, LPINT lpMax) const;
    void CScrollBar::GetScrollRange(LPINT lpMin, LPINT lpMax) const;

    В первом варианте значением параметра Which должно быть либо SB_VERT, либо SB_HORZ. В обоих случаях значения нижней и верхней границы диапазона возвращаются в переменных, на которые указывают параметры lpMin и lpMax, соответственно.

    Задание и получение позиции ползунка:

    Управление полосами прокрутки осуществляется программно. Это означает, что программа должна изменять положение ползунка при необходимости. С этой целью используется функция SetScrollPos( ). Для стандартных полос прокрутки такая функция определена в классе CWnd, и её прототип таков:

    int CWnd::SetScrollPos(int Which, int Pos, BOOL Redraw = TRUE);

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

    int CScrollBar::SetScrollPos(int Pos, BOOL Redraw = TRUE);

    Получить текущую позицию ползунка можно при помощи функции GetScrollPos( )

    int CWnd::GetScrollPos(int Which) const;
    int CScrollBar::GetScrollPos( ) const;

    В обеих функциях возвращается значение текущей позиции ползунка.

    Функции SetScrollInfo( ) и GetScrollInfo( ) - "Только для Windows-95 и выше"

    В среде Windows-95 функции GetScrollInfo( ) и SetScrollInfo( ), позволяют заменить такие функции, как GetScrollPos( ) и SetScrollPos( ). Новые функции работают с 32-разрядными данными, тогда как старые - только с 16-разрядными.

    Для стандартных полос прокрутки используются функции:

    BOOL CWnd::SetScrollInfo(int Which, LPSCROLLINFO lpSI, BOOL Redraw = TRUE);
    BOOL CWnd::GetScrollInfo(int Which, LPSCROLLINFO lpSI, UINT Mask = SIF_ALL);

    Для независимых полос прокрутки используются функции:

    BOOL CScrollBar::SetScrollInfo(LPSCROLLINFO lpSI, BOOL Redraw = TRUE);
    BOOL CScrollBar::GetScrollInfo(LPSCROLLINFO lpSI, UINT Mask = SIF_ALL);

    Все функции возвращают ненулевое значение в случае успешного выполнения и ноль в противном случае.

    • Which - Это SB_VERT или SB_HORZ
    • Redraw - Отвечает за перерисовку полосы прокрутки.
    • Mask - Указывает на то, какая именно информация должна быть получена.
    • lpSI - Отвечает за установку атрибутов. Во всех вариантах функций параметр lpSI указывает на структуру типа SCROLLINFO.

    Структура SCROLLINFO:

    typedef struct tagSCROLLINFO
    {
    UINT cbSize; // размер структуры SCROLLINFO
    UINT fMask; // сведения о полученных атрибутах
    int nMin; // нижняя граница диапазона
    int nMax; // верхняя граница диапазона
    UINT nPage; // размер страницы
    int Pos; // позиция ползунка
    int nTrackPos; // текущая позиция ползунка при перемещении
    } SCROLLINFO;

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

    • SIF_ALL - То же, что SIF_PAGE | SIF_POS | SIF_RANGE | SIF_TRACKPOS
    • SIF_DISABLENOSCROLL - Если диапазон полосы прокрутки равен нулю, то она станет недоступной, но не будет удалена
    • SIF_PAGE - Поле nPage содержит информацию
    • SIF_POS - Поле nPos содержит информацию
    • SIF_RANGE - Поля nMin и nMax содержат информацию
    • SIF_TRACKPOS - Поле nTrackPos содержит информацию

    Можно объединять сразу несколько из перечисленных констант с помощью операции побитового ИЛИ. Те же самые значения можно указывать в параметре Mask функции GetScrollInfo( ). В поле nPage содержится текущий размер страницы для пропорциональных полос прокрутки. Поле nPos определяет позицию ползунка. Поля nMin и nMax содержат нижнюю и верхнюю границу диапазона полосы прокрутки. В поле nTrackPos содержится позиция ползунка, но не статическая, а динамическая, т.е. меняющаяся в процессе его перемещения. Это значение не может быть установлено.

     

    Описание меню в ресурсах

    Прототип: Имя меню MENU [Опции] {Элементы меню}

    Имя меню:
    Обозначает имя меню. (Это может быть просто целое число, идентифицирующее меню).

    MENU - Этот оператор указывает компилятору ресурсов на то, что создается меню.

    Опции:
    DISCARABLE - Меню может быть удалено из памяти, если оно больше не используется.
    FIXED - Меню постоянно находится в памяти.
    LOADONCALL - Меню загружается при обращении.
    MOVEABLE - Меню может быть перемещено в другую область памяти.
    PRELOAD - Меню загружается при запуске программы.
    Элементы меню:
    При создании меню могут использоваться два типа операторов: MENUITEM - Определяет конечный пункт меню. POPUP - Определяет выпадающее меню, которое может содержать подпункты, также задаваемые с помощью MENUITEM и POPUP

    Общий вид операторов следующий:

    MENUITEM "ItemName", MenuID [Опции]
    POPUP "PopupName", [Опции]

    ItemName - Задает название пункта меню, например File или Help.
    MenuID - Это уникальное целое значение, которое связано с пунктом меню и посылается приложению при выборе данного пункта. (Обычно эти значения содержатся в виде констант в библиотечном файле, который затем включается как в программный файл, так и в RC-файл ресурсов.
    PopupName - Определяет название выпадающего меню. 

    Опции используемые с операторами MENUITEM и POPUP

    CHECKED
    РЯДОМ С НАЗВАНИЕМ ПУНКТА МЕНЮ МОЖЕТ СТОЯТЬ МЕТКА ВЫБОРА. (НЕ ИСПОЛЬЗУЕТСЯ ДЛЯ МЕНЮ ВЕРХНЕГО УРОВНЯ.)
    GRAYED
    Название пункта меню выделяется серым цветом и не может быть выбрано.
    HELP
    Может быть связана с коммандой вызова помощи. Применяется с MENUITEM.
    INACTIVE
    Пункт меню не может быть выбран.
    MENUBARBREAK
    Если используется для меню верхнего уровня, то название пункта будет записано с новой строки. Если используется для выпадающих меню, то название пункта будет размещено в новом столбце. В этом случае оно будет отделено чертой.
    MENUBREAK
    То же, что и MENUBARBREAK, но разделительная черта не используется.

    Пример создания меню: MENU1.RC

    #include "id.h"	
    MYMENU MENU
    {
    POPUP "&One"
    {
    MENUITEM "&Alpha", IDM_ALPHA
    MENUITEM "&Beta", IDM_BETA
    }
    POPUP "&Two"
    {
    MENUITEM "&Gamma", IDM_GAMMA
    POPUP "&Delta"
    {
    MENUITEM "&Epsillon", IDM_EPSILON
    MENUITEM "&Zeta", IDM_ZETA
    }
    MENUITEM "&Eta", IDM_ETA
    MENUITEM "&Theta", IDM_THETA
    }
    MENUITEM "&Help", IDM_HELP
    }

    // ID.H
    #define IDM_ALPHA 100
    #define IDM_BETA 101
    #define IDM_GAMMA 102
    #define IDM_DELTA 103
    #define IDM_EPSILON 104
    #define IDM_ZETA 105
    #define IDM_ETA 106
    #define IDM_THETA 107
    #define IDM_HELP 108

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

    Пример:

    Create(NULL, "Пример меню",WS_OVERLAPPEDWINDOW, rectDefault, NULL,"MYMENU");

    Остальное за обработчиком сообщений WM_COMMAND.

     

    Организация клавиш акселераторов

    Прототип: Имя таблицы ACCELERATORS

    {
    Key1, MenuID1, [тип], [опции]
    Key2, MenuID1, [тип], [опции]
    Key1, MenuID1, [тип], [опции]
    и.т.д.
    }

    Имя таблицы - Определяет имя таблицы. Key - Задает клавишу выбора элемента меню. MenuID - Содержит идентификатор требуемого элемента. Тип - Определяет, является ли клавиша стандартной (значение по умолчанию) или виртуальной.

    Опции:

    NOINVERT
    При нажатии клавиши быстрого доступа выделенный элемент меню не будет выделен другим цветом.
    ALT
    Дополнительно должна быть нажата клавиша ALT.
    SHIFT
    Дополнительно должна быть нажата клавиша SHIFT.
    CONTROL
    Дополнительно должна быть нажата клавиша CONTROL.
    ASCII
    Значение Key может быть либо символ в кавычках, либо ASCII-код клавиши (или виртуальной клавиши). Если задан символ в кавычках, то подразумевается, что это ASCII-символ. Если задано целое значение, то необходимо явно указать компилятору ресурсов, что это ASCII-код, определяя параметр тип равным ASCII.
    VIRTKEY
    Если вышеперечисленное относится к виртуальной клавише, то параметр тип должен иметь значение VIRTKEY.

    Если в качестве параметра Key дана заглавная литера в кавычках, то соответствующий пункт меню будет выбран при одновременном нажатии указанной клавиши и клавиши SHIFT. Если указан строчный символ, то для выбора пункта меню достаточно нажать саму клавишу. При задании строчного символа и опции ALT, необходимо одновременно с символом нажать ALT. (Если указан заглавный символ и опция ALT, то дополнительно нужно будет нажать и ALT, и SHIFT.) И наконец, если пользователь должен нажимать клавишу CTRL, то перед символом нужно поставить знак ^. Все константы виртуальных клавиш определены в файле afxres.h и начинаются с префикса VK_. Ниже примеры

    "A",	IDM_x			Выбор по нажатию [Shift-A]
    "a", IDM_x Выбор по нажатию [a]
    "^a", IDM_x Выбор по нажатию [Ctrl-a]
    "a", IDM_x, ALT Выбор по нажатию [Alt-a]
    VK_F2, IDM_x, VIRTKEY Выбор по нажатию [F2]
    VK_F2, IDM_x VIRTKEY, SHIFT Выбор по нажатию [Shift-F2]

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

    Например:

    MENUITEM "&Alpha", IDM_ALPHA а MENUITEM "&Alpha\tF2", IDM_ALPHA

    Здесь \t - Это символ горизонтальной табуляции, а F2 - это подсказка в меню о горячей клавише.

    MYMENU ACCELERATORS
    {
    VK_F2, IDM_ALPHA,VIRTKEY
    VK_F3, IDM_BETA, VIRTKEY
    "G", IDM_GAMMA
    "^E", IDM_EPSILON
    "^Z", IDM_ZETA
    VK_F4, IDM_ETA, VIRTKEY,
    VK_F5, IDM_THETA, VIRTKEY
    VK_F1, IDM_HELP, VIRTKEY
    "^T", IDM_TIME
    }
      

    Здесь "^T", IDM_TIME - не относится к меню, а в файл ID.H следует добавить идентификатор. Например:

     #define IDM_TIME	500

    Загрузка таблицы клавиш быстрого доступа происходит с помощью функции: CONTROL LoadAccelTable( ). Она имеет такой прототип:

    BOOL CFrameWnd::LoadAccelTable(LPCSTR lpszName);

    Вот загрузка в конструкторе окна:

     if(!LoadAccelTable("MYMENU"))
    MessageBox("Не могу загрузить акселераторы");

     

    Параметры GetDeviceCaps

    DRIVERVERSION - номер версии

    DT_
    Определение технологии TECHNOLOGY

    • DT_PLOTTER - векторный плоттер
    • DT_RASDISPLAY - растровый дисплей
    • DT_RASPRINTER - растровый принтер
    • DT_RASCAMERA - растровая камера
    • DT_CHARSTREAM - текстовый поток
    • DT_METAFILE - метафайл
    • DT_DISPFILE - Файл дисплея
    • HORZSIZE - физическая ширина дисплея в мм
    • VERTSIZE - физическая высота дисплея в мм
    • HORZRES - размер дисплея по горизонтали в элементах изображения
    • VERTRES - размер дмсплея по вертикали в строках развертки
    • LOGPIXELSX - число элементов в логическом дюйме по горизонтали
    • LOGPIXELSY - число элементов в логическом дюйме по вертикали
    • BITSPIXEL - количество битов для кодирования цвета
    • PLANES - количество битовых плоскойстей
    • NUMBRUSHES - количество кистей
    • NUMPENS - количество перьев
    • NUMFONTS - количество шрифтов
    • NUMCOLORS - количество цветов в таблице цветов устройства
    • ASPECTX - относительная ширина элемента изображеия устройства
    • ASPECTY - относительная высота
    • ASPECTXY - размер элемента по диаганали
    • PDEVICESIZE - размер внутреней структуры PDEVICE

    CP_
    возможности задания плоскостей отсечки CLIPCAPS

    • CP_NONE - не поддерживаеться отсечка
    • CP_RECTANGLE - прямоугольная область отсечки
    • CP_REGION - произвольная область отсечки
    • SIZEPALETTE - количество цветов в системной палитре
    • NUMRESERVED - количество зарезирвированных цветов в системной палитре
    • COLORRES - текущее цветовое разрешение

    RC_
    Возможности растеризации RASTERCAPS

    • RC_BANDING - требует поддержки обьединения
    • RC_BIGFONT - способность устройтсва работать с битовыми образами шрифтов более 64КБ
    • RC_BITBLT - подддержка возможностей битовых образов
    • RC_BITMAP64 - поддержка битовых образо более 64 КБ
    • RC_DEVBITS - способность работыс аппаратно зависимым битовыми образами
    • RC_DI_BITMAP - способность работ с SetDIBits, GetDIBits функциями Windows
    • RC_DIBTODEV - сопособность работы с SetDIBitsToDevice функцией Windows
    • RC_FLOODFILL - устройство может осуществлять потоковое заполнение
    • RC_GDI20_OUTPUT - поддерка функций Windows ver 2.0
    • RC_GDI20_STATE - включат блок состояния в контекст устройства.
    • RC_NONE - нет поддержки растровых операций
    • RC_OP_DX_OUTPUT - устройство может работать с массивами DX и выводить прозрачное изображение
    • RC_PALETTE - устройство может работать с палитрами
    • RC_SAVEBITMAP - устройство способно локально хранить битовые образы
    • RC_SCALING - устройство поддерживает масштабирование изображения
    • RC_STRETCHBLT - устройство может работать с функцией StretchBlt
    • RC_STRETCHDIB - устройство может работать с функцией StretchDIBits

    CC_
    Возможность устройтсва вычерчивать кривые CURVECAPS

    • CC_NONE - устройство не может чертить кривые
    • CC_CIRCLES - устройство может чертить окружности
    • CC_PIE - устройство может чертить векторные диаграммы.
    • CC_CHORD - устройство может чертить хорды
    • CC_ELLIPSES - устройство может чертить элипсы
    • CC_WIDE - устройство может чертить жирные рамки
    • CC_STYLED - устройство может чертить рамки с использованием стилей
    • CC_WIDESTYLED - устройство может чертить жирные рамки с использованием стилей
    • CC_INTERIORS - устройство может заполнять внутренее пространство
    • CC_ROUNDRECT - устройство может вычерчивать прямоугольники с закруглеными углами

    LL_
    Способность устройства вычерчивать линии LINECAPS

    • LC_NONE - устройство не чертит линии
    • LC_POLYLINE - устройство может вычерчивать несколько связанных линий
    • LC_MARKER - устройство может выводить маркером
    • LC_POLYMARKER - устройство может выводить множественные маркеры
    • LC_WIDE - устройство вычерчивает широкие линии
    • LC_STYLED - устройство вычерчивает линии с поддеркой стилей
    • LC_WIDESTYLED - устройство вычерчивает ширование линии с использованием стилей
    • LC_INTERIORS - устройство способно заполнять внутренее пространство

    PC_
    Способность вычерчивания полигонов POLYGONALCAPS

    • PC_NONE - устройство не чертит полигоны
    • PC_POLYGON - устройство может чертить многоугольники с различным заполнением
    • PC_RECTANGLE - устройство выерчивает многоугольники
    • PC_WINDPOLYGON - устройство вычерчивает многоугольники со спиральным заполнением
    • PC_SCANLINE - устройство может использовать построчную развертку
    • PC_WIDE - устройство способно вычерчивать широкие рамки
    • PC_STYLED - устройство способно вычерчивать границы с использованием стилей
    • PC_WIDESTYLED - устройство способно вычерчивать широкие рамки с использование стилей
    • PC_INTERIORS - устройство способно заполнять внутренее пространство
    TC_
    Способность устройства работать с TEXTCAPS
    • TC_OP_CHARACTER - определяет разрешение при выводе текстов позволяющий поместить свой шрифт в любой элемент изображения
    • TC_OP_STROKE - определяет разрешения для вывода штрихов, указывая что устройство может пропустить любой штрих в своем шрифте
    • TC_CP_STROKE - определяет точночть отсечки шрифта.
    • TC_CR_90 - устройство способно поварачивать шрифты на 90 градусов
    • TC_CR_ANY - устройство способно поворачивать шрифты на любой градус
    • TC_SF_X_YINDEP - устройсвто поддерживает независимое масштабирование по ширине и высоте
    • TC_SA_DOUBLE - устройство может удваивать размер шрифта
    • TC_SA_INThEGER - устройство может увеличивать размер своих шрифтов в любое количестов раз
    • TC_SA_CONTIN - устройство может свободно менять размер шрифтов сохраняя пропорции
    • TC_EA_DOUBLE - создание жирного шрифта за счет двойной печати
    • TC_IA_ABLE - устройство может работать с курсивным шрифтом
    • TC_UA_ABLE - устройство позволяет использовать подчеркнутый текст
    • TC_SO_ABLE - устройство позволяет использовать зачеркивание текста
    • TC_RA_ABLE - устройство позволяет использовать растровые шрифты
    • TC_VA_ABLE - устройство позволяет использовать векторные шрифты
    • TC_RESERVED - зарезирвировано


     

    Параметры вызова функций

    Существуют три механизма вызова параметров в функции: вызов по величине, вызов по ссылке и вызов по постоянной ссылке.

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

    void f(int, int)
    main(){
    int a,b;
    a=5;
    b=6;
    f(a,b);
    cout << a << b << endl;
    }

    В .срр файле укажем, как функция f работает:

    void f(int x,int y)
    {
    x=x+1;
    y=y+1;
    }

    Таким образом, параметры в функции f я вызвала по величине. Что же наша main функция выведет на экран? Рассмотрим, что происходит когда мы вызываем функию f.

    Как только мы объявили а и b, в стеке (специальная память для местных переменных) выделилось достаточное количество места для типа integer(2-4 байта на каждую) и каждой переменной присвоен свой собственный адрес в памяти.

    x и y - местные переменные для функции f, при их появлении стек опять выделяет им место и присваивает адрес.

    После кода :x=x+1;
    y=y+1;

    Нашим переменным соответсвенно присваиваются значения 6 и 7. Когда функция f выполнила своё назначение по правилам С++ все местные переменные стираются из памяти компьютера, то есть при выполнении нашей программы, когда дело доходит до вывода результата на экран ...... Какими будут значения a и b ?

    Если вы поняли мои объяснения, то ваш ответ должен быть 5 и 6.

    Соответвенно, функция f не изменила первоначальные величины.

    Что же сделать, чтобы после выполнения расчётов функции результат не был бы утерян? Надо всего лишь вызвать наши параметры не по величине, а по ссылке. Изменения в коде минимальные:

    В .срр файле:

    void f(int &x,int &y)

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

    Теперь в стеке при появлении y и х не выделяется особое место, им присваивается тот же адрес, что у а и b. Таким образом, мы не теряем результаты подсчётов.

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

    Разобрав первый два механизма, можно прийти к выводу. Если мы хотим, чтобы функция не изменила наши параметры, вызываем их по величине. Если, на против, мы хотим чтобы им было присвоено новое значение, используем вызов по ссылке. Остаётся последний вопрос, когда же применять вызов по постоянной ссылке!

    Этот механизм имеет тот же эффект что и вызов по величине, а так же экономит память, как и вызов по ссылке.

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

    friend ostream & operator<<(ostream & out, const int  &VALUE);

    В данном случае, мы хотим получить гарантию, что данная функция выполнит свою роль и не сделать нежелательных изменений параметров. Особенности кода при вызове по постоянной ссылке: ставим const перед типом переменной и знак "&" перед именем.

     

    Перехват ошибок set_terminate

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

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

    // eh.h
    typedef void (*terminate_function)();
    terminate_function set_terminate( terminate_function term_func );

    Вот как можно это сделать просто:

    #include "stdafx.h"
    #include "iostream.h"
    #include "eh.h"


    void Error()
    {
    cout << "Error !!!!! " << endl;
    }

    void main()
    {
    set_terminate(Error);
    throw "df";
    cout << "Cancel" << endl;
    }

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

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

    typedef void (*TERMINATE_FN)();
    TERMINATE_FN old_terminate = NULL;
    ......
    old_terminate = set_terminate(my_terminate);
    ......
    set_terminate(old_terminate);
     

    Разница между bool и BOOL

    Запустите следующий пример.

    // BoolTest.cpp : Defines the entry point for the console application.
    //


    #include "stdafx.h"
    #include "windows.h"
    #include "iostream.h"

    void main()
    {
    cout << sizeof(bool) << endl;
    cout << sizeof(BOOL) << endl;
    }

    На экране появится примерно такой ответ:

    1
    4
    Press any key to continue

    Как видите, размер для хранения данных разный. Ну и правильно. Объявления то их разные.

    typedef int                 BOOL;

    То есть BOOL в Windows это просто переопределенный int по принципу то 0 и все остальное. bool же это тип данных C++.

     

    Растровые операции CDC

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

    Перед прорисовкой необходимо установить режим рисования. Этот режим определяет как цвет кисти сочетается с цветами контекста устройства. Этот режим можно установить функцией CDC с именем SetROP2(), вот она какая:

    int SetROP2( int nDrawMode );

    Она вернет нам предыдущий режим рисования. Этот ROP означает типа Raster Operation. Эти операции и приведены ниже:

    • R2_BLACK - Элемент отображения всегда черный.
    • R2_NOTMERGEPEN - Элемент отображения является инверсией цвета R2_MERGEPEN.
    • R2_MASKNOTPEN - Элемент отображения является комбинацией цветов общих как дисплея, так и инверсии цвета пера.
    • R2_NOTCOPYPEN - Элемент отображения является инверсией цвета пера.
    • R2_MASKPENNOT - Элемент отображения является комбинацией цветов общих как для пера, так и инверсии цвета дисплея.
    • R2_NOT - Элемент отображения является инверсией цвета дисплея.
    • R2_XORPEN - Элемент отображения является исключающей комбинации цветов пера и дисплея.
    • R2_NOTMASKPEN - Элемент отображения является инверсией цвета R2_MASKPEN.
    • R2_MASKPEN - Элемент отображения является комбинацией цветов общих для пера и экрана.
    • R2_NOTXORPEN - Элемент отображения является инверсией цвета R2_XORPEN.
    • R2_NOP - Элемент отображения остается без изменений.
    • R2_MERGENOTPEN - Элемент отображения является комбинацией цвета экрана и инверсией цвета пера.
    • R2_COPYPEN - Элемент отображения отражает цвет пера.
    • R2_MERGPENNOT - Элемент отображения является комбинацией пера и инверсии цвета дисплея.
    • R2_MERGPEN - Элемент отображения является комбинацией пера и цвета дисплея.
    • R2_WHITE - Элемент отображения всегда белый.
     

     

    Растры

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

    Ратровые изображения бывают двух типов.

    • DDB (device-dependent bitmap) - аппаратно зависимые растры
    • DIB (device-independent bitmap) - аппаратно независимые растры

    Чем они отличаются ? Это наличием цветовых таблиц. В аппаратно независымых растрах есть цветовые таблицы, что и позволяет им отражаться на любых устройствах. Кроме того аппаратно зависимые растры не могут быть на диске. Точнее не должны сохраняться в файл. Обычно растровые кратинки хранятся на диске в виде файлов BMP. Они переносимые между разными системами, например Windows -> OS/2 -> DOS.

    В комплект Windows входит программа Paint, которая позволяет создавать подобные файлы. И сама среда VC позволяет создавать и редактировать эти файлы. Для того, чтобы в VC создать подобный файл выберите меню File/New. Переключитесь на вкладку File и найдите там раздел Bitmap file, он позволит Вам создать подобный файл.

    Растры хранятся в BMP файлах. Этот формат поддерживается всеми графическими редакторами под Windows, он может хранить как изображение в виде палитр, так и RGB цвета. Возможно сжатие по алгоритму RLE, но оно применяется редко да и сама программа Paint не умеет работать с такими изображениями. Если вы создадите растр сжатый RLE, то при открытии в Paint увидите чистый лист.

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

     

    Системные цвета Windows

    В Windows на панели инструментов у Вас есть возможность получить доступ к системным цветам Windows. Для работы с системными цветами есть функции Windows:

    DWORD GetSysColor(
    int nIndex // идентифкатор
    );

    BOOL WINAPI SetSysColors(
    int cElements, // номер элемента
    CONST INT *lpaElements, // адрес массива элементов
    CONST COLORREF *lpaRgbValues // адрес массива RGB
    );

    Идентификаторы их такие:

    • COLOR_3DDKSHADOW - Темная тень для трехмерных элементов.
    • COLOR_3DFACE, COLOR_BTNFACE - Поверхности трехмерных элементов.
    • COLOR_3DHILIGHT, COLOR_3DHIGHLOIGHT, COLOR_BTNHILIGHT, COLOR_BTNHIGHLIGHT - Выделение трехмерных элементов.
    • COLOR_3DLIGHT - Свет для трехмерных элементов.
    • COLOR3DSHADOW,BTNHIGHLIGHT - Тень для трехмерных элементов.
    • COLOR_ACTIVEBORDER - Рамка вокруг активного окна.
    • COLOR_ACTIVECAPTION - Заголовок активного окна.
    • COLOR_APPWORKSPACE - Фон окна приложения MDI (приложение, использующее многооконный интерфейс).
    • COLOR_BACKGROUND,COLOR_DESKTOP - Рабочий стол.
    • COLOR_BTNFACE - Кнопка.
    • COLOR_BTNHIGHLIGHT - Выбранная кнопка.
    • COLOR_BTNSHADOW - Тень, "отбрасываемая" кнопкой.
    • COLOR_BTNTEXT - Текст надписи на поверхности кнопки.
    • COLOR_CAPTIONTEXT - Текст заголовка окна, кнопки изменения размера, кнопки полосы просмотра.
    • COLOR_GRAYTEXT - Текст серого цвета.
    • COLOR_HIGHLIGHT - Фон выбранного элемента в органе управления.
    • COLOR_HIGHLIGHTTEXT - Текст для выбранного органа управления.
    • COLOR_INACTIVEBORDER - Рамка вокруг неактивного окна.
    • COLOR_INACTIVECAPTION - Заголовок неактивного окна.
    • COLOR_INACTIVECAPTIONTEXT - Текст заголовка для неактивного окна.
    • COLOR_INFONK - Фон элемента подсказка.
    • COLOR_INFOTEXT - Текст элемента подсказка.
    • COLOR_MENU - Фон меню.
    • COLOR_MENUTEXT - Текст меню.
    • COLOR_SCROLLBAR - Полоса просмотра.
    • COLOR_WINDOW - Фон окна.
    • COLOR_WINDOWFRAME - Рамка окна.
    • COLOR_WINDOWTEXT - Текст в окне.

     



    Стили окна

    При создании окна, в конструкторе будущего окна мы делаем примерно следующее:

    CMainWin::CMainWin( )
    {
    Create(NULL, "My Programm", WS_OVERLAPPEDWINDOW);
    }

    Что же такое это WS_ ?

    На самом деле за приставкой WS_ скрывается стиль будущего окна. Ниже идет набор стилей. При задании набора стилей нужно использовать оператор побитового сложения OR ( | );

    • WS_BORDER - Создание окна с рамкой.
    • WS_CAPTION - Создание окна с заголовком (невозможно использовать одновременно со стилем WS_DLGFRAME).
    • WS_CHILD
      WS_CHILDWINDOW
      - Создание дочернего окна (невозможно использовать одновременно со стилем WS_POPUP).
    • WS_CLIPCHILDREN - Исключает область, занятую дочерним окном, при выводе в родительское окно.
    • WS_CLIPSIBLINGS - Используется совместно со стилем WS_CHILD для отрисовки в дочернем окне областей клипа, перекрываемых другими окнами.
    • WS_DISABLED - Создает окно, которое недоступно.
    • WS_DLGFRAME - Создает окно с двойной рамкой, без заголовка.
    • WS_GROUP - Позволяет объединять элементы управления в группы.
    • WS_HSCROLL - Создает окно с горизонтальной полосой прокрутки.
    • WS_MAXIMIZE - Создает окно максимального размера.
    • WS_MAXIMIZEBOX - Создает окно с кнопкой развертывания окна.
    • WS_MINIMIZE
      WS_ICONIC
      - Создает первоначально свернутое окно (используется только со стилем WS_OWERLAPPED).
    • WS_MINIMIZEBOX - Создает окно с кнопкой свертывания.
    • WS_OVERLAPPED - Создает перекрывающееся окно (которое, как правило, имеет заголовок и WS_TILED рамку).
    • WS_OVERLAPPEDWINDOW - Создает перекрывающееся окно, имеющее стили WS_OVERLAPPED, WS_CAPTION, WS_SYSMENU, WS_THICKFRAME, WS_MINIMIZEBOX, WS_MAXIMIZEBOX.
    • WS_POPUP - Создает popup-окно (невозможно использовать совместно со стилем WS_CHILD.
    • WS_POPUPWINDOW - Создает popup-окно, имеющее стили WS_BORDER, WS_POPUP, WS_SYSMENU.
    • WS_SYSMENU - Создает окно с кнопкой системного меню (можно использовать только с окнами имеющими строку заголовка).
    • WS_TABSTOP - Определяет элементы управления, переход к которым может быть выполнен по клавише TAB.
    • WS_THICKFRAME - Создает окно с рамкой, используемой для изменения
    • WS_SIZEBOX - размера окна.
    • WS_VISIBLE - Создает первоначально неотображаемое окно.
    • WS_VSCROLL - Создает окно с вертикальной полосой прокрутки.

    Ниже идет программа реализующая окно Windows. При помощи неё поэкспериментируйте со стилями, названными выше.

    // My.h
    class CMainWin : public CFrameWnd // Класс создания окна
    {
    public:
    CMainWin(); // Конструктор
    DECLARE_MESSAGE_MAP() // Объявление очереди сообщений
    };

    class CMainApp : public CWinApp // Класс создания приложения
    {
    public:
    BOOL InitInstance(); // Точка начала работы приложения
    };

    // My.cpp
    #include <afxwin.h> // Подключение библиотеки MFC
    #include "skelet.h" // Содержит определения классов

    CMainWin::CMainWin() // Реализация конструктора
    {
    CRect r; // Отвечает за размер и позицию окна
    r.top = r.left = 10; // Расположение окна на экране (сверху и слева)
    r.bottom = r.right = 200; // Размеры окна

    Create(NULL, "Скелет окна", WS_OVERLAPPEDWINDOW, r); // Создание окна
    }

    BOOL CMainApp::InitInstance() // Вместо функции WinMain() (Только для MFC)
    {
    m_pMainWnd = new CMainWin; // Создание объекта окна
    m_pMainWnd -> ShowWindow(m_nCmdShow); // Вывод окна
    m_pMainWnd -> UpdateWindow(); // Обновление окна

    return TRUE; // TRUE, если окно создано
    }

    // Реализация очереди сообщений. (пока она пустая)
    BEGIN_MESSAGE_MAP(CMainWin, CFrameWnd)

    END_MESSAGE_MAP()

    // Создание экземпляра приложения
    CMainApp App;
     

    Структура ENUMLOGFONT

    Служит для определения стиля шрифта:

    typedef struct tagENUMLOGFONT 
    {
    LOGFONT elfLogFont;
    \\ Ссылка на структуру LOGFONT с информацией
    BCHAR elfFullName[LF_FULLFACESIZE];
    \\ Полное имя шрифта
    BCHAR elfStyle[LF_FACESIZE];
    \\ Определяет стиль шрифта
    } ENUMLOGFONT;


    Структура HELPINFO

    В эту структуру помещается информация о темах контестной справки.

    typedef  struct  tagHELPINFO 
    {
    UINT cbSize; // размер структуры в байтах
    int iContextType; // тип справки
    int iCtrlId; // идинтификатор окна либо меню
    HANDLE hItemHandle; // идентификатор дочернего
    // окна либо связанного меню
    DWORD dwContextId; // контекстный идентификатор либо
    // окна либо элемента упраления
    POINT MousePos; // Позиция мыши
    } HELPINFO, FAR *LPHELPINFO;

    Поле тип справки iContextType может принимать следующие значения:

    • HELPINFO_MENUITEM - справка о команде меню
    • HELPINFO_WINDOW - справка по элементу упраления

     

    Структура LOGFONT

    Шрифты в Windows описываются в структуре LOGFONT, поля которой перечислены ниже. Большинство из них может иметь значение 0 или значение по умолчанию - все зависит от конкретной ситуации в приложении.

    Поле Описание
    lfHeight Высота шрифта, логических единиц
    lfWidth Ширина шрифта, логических единиц
    lfEscapement Угол нанесения текста - угол между базовой линией текста и горизонталью (десятые доли градуса)
    lfOrientation Наклон символов (десятые доли градуса)
    lfWeight Толщина линий начертания шрифта ("жирность")
    lfItalic Ненулевое значение означает курсив
    lfUnderline Ненулевое значение означает подчеркивание
    lfStrikeOut Ненулевое значение означает перечеркнутый шрифт
    lfCharSet Номер набора символов шрифта - таблицы кодировки
    lfOutPrecision Параметр, определяющий соответствие запрашиваемого шрифта и имеющегося в наличии
    lfClipPrecision Параметр, определяющий способ "обрезания" изображения литер при их выходе за пределы области ограничения вывода
    lfQuality Качество воспроизведения шрифта
    lfPitchAndFamily Это поле определяет, будет ли шрифт иметь фиксированную или переменную ширину литер, а также семейство, к которому принадлежит шрифт
    lfName Имя шрифта

    Какой высоты, например, будут литеры шрифта, для которого в поле lfHeight задано значение 8 логических единиц? Значение логической единицы определяется режимом наложения (mapping mode). Соответствие между режимом наложения и значением логической единицы видно ниже.

    Режимы наложения (mapping mode):

    Режим Логическая единица Координата X Координата Y
        Возрастание координат
    MM_HIENGLISH 0,001 дюйма Слева направо Снизу вверх
    MM_HIMETRIC 0,01 мм Слева направо Снизу вверх
    MM_ISOTROPIC Произвольное Определяется Определяется
    MM_LOENGLISH 0,01 дюйма Слева направо Снизу вверх
    MM_LOMETRIC 0,1 мм Слева направо Снизу вверх
    MM_TEXT Пиксель устройства Слева направо Сверху вниз
    MM_TWIPS 1/1440 дюйма Слева направо Снизу вверх

    Толщина шрифта есть параметр, характеризующий некоторым посредственным образом толщину контурных линий литер. Для этого поля определен набор констант: FW_DONTCARE, FW_THIN, FW_EXTRALIGHT, FW_NORMAL, FW_ULTRALIGHT, FW_LIGHT, FW_REGULAR, FW_MEDIUM, FW_SEMIBOLD, FW_DEMIBOLD, FW_BOLD, FW_EXTRABOLD, FW_ULTRABOLD, FW_BLACK, FW_HEAVY. Не все шрифты могут принимать любое из указанных значений толщины.

    Существует четыре возможных варианта шрифтов: ANSI_CHARSET, OEM_CHARSET, SYMBOL_CHARSET, UNICODE_CHARSET

    Например, для написания только английским шрифтом следует воспользоваться вариантом ANSI_CHARSET.

     

    Структура NMHDR

    Эта структура используется в функциях обработки сообщений в формате WM_NOTIFY. Вот её описание:

    typedef struct tagNMHDR 
    {
    HWND hwndFrom;
    UINT idFrom;
    UINT code;
    } NMHDR;
    • hwndFrom - дескриптор окна элемента управления, от которого пришло извещение. Его можно преобразовать в указатель на объект CWnd, если воспользоваться функцией From Handle.
    • idFrom - это идентификатор элемента управления пославщего сообщение.
    • code - это код извещения. Он может быть каким.
      • NM_CLICK - щелкнули левой кнопкой
      • NM_DBLCLK - двойной щелчок левой
      • NM_RCLICK - щелкнули правой кнопкой
      • NM_RDBLCLK - двойной щелчок правой
      • NM_RETURN - нажали Enter
      • NM_KILLFOCUS - потеря фокуса элементом управления
      • NM_SETFOCUS - элемент управления получил фокус
      • NM_OUTOFMEMORY - элемент управления сообщает о нехватке памяти

    Для полной картины сообщения могут определяться еще и элементом управления. Напомню, что эта структура используется в CWnd::OnNotify и имеет вот такую карту сообщения.

    ON_NOTIFY( код, идентификатор, функция)

     

    Структура TEXTMETRIC

    Структура TEXTMETRIC содержит основную информацию о физическом шрифте. Все размеры даются на логических устройствах; то есть, они зависят от текущего распределения режима дисплейного контекста.

    typedef struct tagTEXTMETRIC 
    {
    LONG tmHeight; //Полная высота шрифта
    LONG tmAscent; //Высота над основной линией
    LONG tmDescent; //Высота подстрочных элементов
    LONG tmInternalLeading; //Пустое пространство над символами
    LONG tmExternalLeading; //Интервал между строками
    LONG tmAveCharWidth; //Средняя ширина символов
    LONG tmMaxCharWidth; //Максимальная ширина символов
    LONG tmWeight; //Насыщенность (жирность) символов
    LONG tmOverhang; //Дополнительная жирность для специальных шрифтов
    LONG tmDigitizedAspectX; //Горизонтальный коэффициент сжатия
    LONG tmDigitizedAspectY; //Вертикальный коэффициент сжатия
    BCHAR tmFirstChar; //Первый символ шрифта
    BCHAR tmLastChar; //Последний символ шрифта
    BCHAR tmDefaultChar; //Символ, выбираемый по умолчанию
    BCHAR tmBreakChar; //Символ, используемый для разделения слов
    BYTE tmItalic; //Не ноль, если шрифт курсивный
    BYTE tmUnderlined; //Не ноль, если шрифт подчеркнутый
    BYTE tmStruckOut; //Не ноль, если шрифт перечеркнутый
    BYTE tmPitchAndFamily; //Тип и семейство шрифта
    BYTE tmCharSet; //Идентификатор базового набора символов
    } TEXTMETRIC;

    Получить информацию о текущем шрифте можно с помощью функции GetTextMetrics(). Её прототип таков:

    BOOL CDC::GetTextMetrics(LPTEXTMETRIC lpTextAtrib) const;

    Здесь параметр lpTextAtrib является указателем на структуру типа TEXTMETRIC, в которой после выполнения функции будут содержаться текстовые установки текущего шрифта, связанного с данным контекстом устройства. Функция возвращает ненулевое значение при успешном завершении и ноль - в противном случае.

     

    Структура WNDCLASS

    Эта структура содержит атрибуты класса окна. Вот её описание

    typedef struct tagWNDCLASS {  
    UINT style;
    WNDPROC lpfnWndProc;
    int cbClsExtra;
    int cbWndExtra;
    HINSTANCE hInstance;
    HICON hIcon;
    HCURSOR hCursor;
    HBRUSH hbrBackground;
    LPCSTR lpszMenuName;
    LPCSTR lpszClassName;
    } WNDCLASS;

    При создании класса окна эту структуру использует функция Register Class. Итак, описание параметров.

    style определяет стиль класса. Стили можно объединять используя | (OR). Вот какие они бывают:

    • CS_BYTEALIGNCLIENT - (по горизонтали) выравнивание рабочей области окна по границе байта. Влияет на ширину окна и его горизонтальное положение на экране.
    • CS_BYTEALIGNWINDOW - (по вертикали) выравниает окна по границе байта.
    • CS_CLASSDC - контекст устройства, который будет разделяться всеми окнами класса. При нескольких потоках операционная система разрешит доступ только одному потоку.
    • CS_DBLCLKS - посылать сообщение от мыши при двойном щелчке в пределах класса окна.
    • CS_GLOBALCLASS - Создавать глобальный класс, который можно поместить в динамическую библиотеку DLL
    • CS_HREDRAW - перерисовывать всё окно при изменении ширины.
    • CS_NOCLOSE - отключить команду Закрыть
    • CS_OWNDC - у каждого окна уникальный контекст устройства.
    • CS_PARENTDC - У дочернего окна будет область отсечки от родительского. Повышает производительность.
    • CS_SAVEBITS - Позволяет сохранять область экрана в виде битовой матрицы закрытую в данный момент другим окном, используется для восстановления экрана.
    • CS_VREDRAW - перерисовывать окно при изменении вертикальных размеров

    WNDPROC указатель на процедуру окна вызываемую функцией CallWindowProc.
    cbClsExtra объем памяти выделяемый за структурой класса.
    cbWndExtra объем дополнительной памяти за экземпляром окна.
    hInstance дескриптор экземпляра.
    hIcon дескриптор эконы окна
    hCursor дескриптор курсора окна
    hbrBackground дескриптор для закраски фона.
    lpszMenuName имя меню в ресурсах
    lpszClassName имя класса.

     

    Флаги атрибутов файлов для CComboBox

    Эти флаги описаны для CComboBox и используются в функции DIR для задания атрибутов:

    int Dir( UINT attr, LPCTSTR lpszWildCard );
    • DDL_READWRITE - Файл может быть открыт только для чтения или записи.
    • DDL_READONLY - Возможно чтение из файла но не запись.
    • DDL_HIDDEN - Файл скрыт.
    • DDL_SYSTEM - Файл системный.
    • DDL_DIRECTORY - Это каталог.
    • DDL_ARCHIVE - Файл архивный.
    • DDL_DRIVES - Включить все диски задаваемые по имени.
    • DDL_EXCLUSIVE - Для получения списка файлов заданого типа.

     

    Флаги закрепления панели инструментов

    Эти флаги используются для указания как прикреплять панель инструментов в классе CFrameWnd при вызове функции EnableDocking.

    void EnableDocking( DWORD dwDockStyle );

    Эта функция при использовании AppWizard находится в функции OnCreate:

    int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
    {
    ......
    m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
    EnableDocking(CBRS_ALIGN_ANY);
    DockControlBar(&m_wndToolBar);
    return 0;
    }
    • CBRS_ALIGN_TOP - Разрешает закрепление у верхней стороны клиентской области.
    • CBRS_ALIGN_BOTTOM - Разрешает закрепление у нижней стороны клиентской области.
    • CBRS_ALIGN_LEFT - Разрешает закрепление у левой стороны клиентской области.
    • CBRS_ALIGN_RIGHT - Разрешает закрепление у правой стороны клиентской области.
    • CBRS_ALIGN_ANY - Разрешает закрепление у любой строны.

     


      Функции для работы с реестром

      Функция CWinApp::SetRegistryKey:

      void SetRegistryKey( LPCTSTR lpszRegistryKey );
      void SetRegistryKey( UINT nIDRegistryKey );

      Параметры:

      • lpszRegistryKey - Указатель на строку содержащую имя ключа реестра.
      • nIDRegistryKey - ID/индекс ключа в реестре.

      Заставляет приложение сохранять установки в реестр вместо INI файлов. Эта функция устанавливает m_pszRegistryKey, которая затем используется в следующих функциях-членах CWinApp: GetProfileInt, GetProfileString, WriteProfileInt, и WriteProfileString. Если эта функция была вызвана, список недавно используемых файлов (list of most recently-used - MRU) также сохраняется в реестре. Ключ реестра обычно является именем компании. Ключ реестра имеет следующий вид: HKEY_CURRENT_USER\Software\<company name>\<application name>\<section name>\<value name>.

      Функция CWinApp::GetProfileInt:

      UINT GetProfileInt( LPCTSTR lpszSection, LPCTSTR lpszEntry, int nDefault );

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

      Если функция успешно отработала - целое значение строки определенной записи. Возвращаемое значение - значение параметра nDefault, если функция не нашла записи. Возвращаемое значение - 0 если значение, которое соответствует заданной записи не целое.

      Эта функция поддерживает шестнадцатеричную нотацию для значений в .INI файле. Когда вы получаете знаковое целое, вы должны перевести значение в int.

      Параметры:

      • lpszSection - Указатель на строку завершенную нулем, которая определяет секцию, содержащую запись в реестре.
      • lpszEntry - Указатель на строку завершенную нулем, которая содержит запись, значение которой будет возвращено.
      • nDefault - Определяет значение по умолчанию для возвращения, если система не сможет найти запись. Это значение может быть беззнаковым целым (unsigned) в диапазоне от 0 до 65535 или знаковым (signed) в диапазоне от -32768 до 32767.

      Вызывайте эту функцию для получения целого значения записи из определенной секции из реестра или .INI файла.

      Записи сохраняются следующим образом:

      • В Windows NT, значение сохраняется в ключ реестра.
      • В Windows 3.x, значение сохраняется в WIN.INI файл.
      • В Windows 95, значение сохраняется в скрытую версию WIN.INI файла.

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

      Функция CWinApp::GetProfileString:

      CString GetProfileString( LPCTSTR lpszSection, LPCTSTR lpszEntry,
      LPCTSTR lpszDefault = NULL );

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

      Возвращаемое значение - строка из .INI файла приложения или lpszDefault, если строка не найдена. Максимальная длинна строки, которую поддерживает система, определена в _MAX_PATH. Если lpszDefault равно NULL, возвращаемое значение - пустая строка.

      Параметры:

      • lpszSection - Указатель на строку завершенную нулем, которая определяет секцию содержащую запись в реестре.
      • lpszEntry - Указатель на строку завершенную нулем, которая содержит запись, строка из которой будет возвращена. Это значение не должно быть равно NULL.
      • lpszDefault - Указатель на значение строки по умолчанию для заданной записи, если запись не найдена в инициализирующем (INI) файле.

      Вызывайте эту функцию для получения строки связанной с записью в заданной секции реестра приложения или .INI файла.

      Записи сохраняются следующим образом:

      • В Windows NT, значение сохраняется в ключ реестра.
      • В Windows 3.x, значение сохраняется в WIN.INI файл.
      • В Windows 95, значение сохраняется в скрытую версию WIN.INI файла.

      Пример:

      CString strSection       = "Моя секция";
      CString strStringItem = "Мой строковый элемент";
      CString strIntItem = "Мой целый элемент";

      CWinApp* pApp = AfxGetApp();

      pApp->WriteProfileString(strSection, strStringItem, "test");

      CString strValue;
      strValue = pApp->GetProfileString(strSection, strStringItem);
      ASSERT(strValue == "test");

      pApp->WriteProfileInt(strSection, strIntItem, 1234);
      int nValue;
      nValue = pApp->GetProfileInt(strSection, strIntItem, 0);
      ASSERT(nValue == 1234);

      Функция CWinApp::WriteProfileInt:

      BOOL WriteProfileInt( LPCTSTR lpszSection, LPCTSTR lpszEntry, int nValue );

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

      Не 0 в случае удачного вызова функции, иначе 0.

      Параметры:

      • lpszSection - Указатель на строку завершенную нулем, которая определяет секцию, содержащую запись. Если секция не найдена, она создается. Имя секции не зависит от регистра; строка может сочетать как заглавные, так и прописные буквы.
      • lpszEntry - Указатель на строку завершенную нулем, которая содержит запись, в которую будет записано значение. Если запись не найдена в заданной секции, она создается.
      • nValue - Содержит значение для записи.

      Вызывайте эту функцию для записи заданного значения в заданную секцию реестра или .INI файл. 

      Записи сохраняются следующим образом:

      • В Windows NT, значение сохраняется в ключ реестра.
      • В Windows 3.x, значение сохраняется в WIN.INI файл.
      • В Windows 95, значение сохраняется в скрытую версию WIN.INI файла.

      Пример:

      CString strSection       = "Моя секция";
      CString strStringItem = "Мой строковый элемент";
      CString strIntItem = "Мой целый элемент";

      CWinApp* pApp = AfxGetApp();

      pApp->WriteProfileString(strSection, strStringItem, "test");

      CString strValue;
      strValue = pApp->GetProfileString(strSection, strStringItem);
      ASSERT(strValue == "test");

      pApp->WriteProfileInt(strSection, strIntItem, 1234);
      int nValue;
      nValue = pApp->GetProfileInt(strSection, strIntItem, 0);
      ASSERT(nValue == 1234);

      Функция CWinApp::WriteProfileString:

      BOOL WriteProfileString( LPCTSTR lpszSection, 
      LPCTSTR lpszEntry, LPCTSTR lpszValue );

      Возвращаемое значение: Не 0 в случае удачного вызова функции, иначе 0.

      Параметры:

      • lpszSection - Указатель на строку завершенную нулем, которая определяет секцию, содержащую запись. Если секция не найдена, она создается. Имя секции не зависит от регистра; строка может сочетать как заглавные, так и прописные буквы.
      • lpszEntry - Указатель на строку завершенную нулем, которая содержит запись, в которую будет записано значение. Если запись не найдена в заданной секции, она создается.
      • lpszValue - Указатель на строку, предназначенную для записи. Если этот параметр NULL, запись определенная параметром lpszEntry удаляется.

      Вызывайте эту функцию для записи заданной строки в заданную секцию реестра или .INI файл.

      Записи сохраняются следующим образом:

      • В Windows NT, значение сохраняется в ключ реестра.
      • В Windows 3.xWIN.INI файл.
      • В Windows 95, значение сохраняется в скрытую версию WIN.INI файла.

      Пример:

      CString strSection       = "Моя секция";
      CString strStringItem = "Мой строковый элемент";
      CString strIntItem = "Мой целый элемент";

      CWinApp* pApp = AfxGetApp();

      pApp->WriteProfileString(strSection, strStringItem, "test");

      CString strValue;
      strValue = pApp->GetProfileString(strSection, strStringItem);
      ASSERT(strValue == "test");

      pApp->WriteProfileInt(strSection, strIntItem, 1234);
      int nValue;
      nValue = pApp->GetProfileInt(strSection, strIntItem, 0);
      ASSERT(nValue == 1234);
       

      Функции для работы с сервисами NT

      • ChangeServiceConfig - Изменяет параметры конфигурации сервиса
      • ChangeServiceConfig2 - Изменяет параметры конфигурации сервиса
      • CloseServiceHandle - Освобождает объект менеджера сервисов
      • ControlService - Посылает сервису управляющий сигнал
      • CreateService - Создает сервисный объект
      • DeleteService - Удаляет сервис из базы данных диспетчеров сервисов
      • EnumDependentServices - Перечисляет сервисы
      • EnumServicesStatus - Перечисляет сервисы
      • Handler - Функция обработки управляющих сигналов
      • LockServiceDatabase - Блокирует базу данных сервисов
      • NotifyBootConfigStatus - Уведомляет о приеме загрузочной информации
      • OpenSCManager - Подключает приложение к менеджеру сервисов
      • OpenService - Открывает сервис
      • QueryServiceConfig - Запрашивает параметры конфигурации
      • QueryServiceConfig2 - Запрашивает параметры конфигурации
      • QueryServiceLockStatus - Запрашивает статус блокировки
      • QueryServiceObjectSecurity - Запрашивает дискриптор безопасности
      • QueryServiceStatus - Запрашивает статус сервиса
      • RegisterServiceCtrlHandler - Регистрирует обработчик запросов
      • ServiceMain - Главная функция сервиса
      • SetServiceBits - Обноволяет статус сервиса для диспетчера сервисов
      • SetServiceObjectSecurity - Модифицирует дискриптор безопасности сервисного объекта
      • SetServiceStatus - Устанавливает статус сервиса
      • StartService - Запускает сервис
      • StartServiceCtrlDispatcher - Запускает поток
      • UnlockServiceDatabase - Разблокирование базы данных

       



      Языковые установки Базы данных

      dbLangGeneral - Английский, немецкий, французкий, португальский, итальянский и современный испанский

      dbLangArabic - Арабский

      dbLangCyrillic - Русский

      dbLangCzech - Чешский

      dbLangDutch - Голландский

      dbLangGreek - Греческий

      dbLangHebrew - Иврит

      dbLangHungarian - Болгарский

      dbLangIcelandic - Исландский

      dbLangNordic - Северные языки :-) (MS Jet 1.0 только)

      dbLangNorwdan - Норвежский и датский

      dbLangPolish - Польский

      dbLangSpanish - Испанский

      dbLangSwedfin - Шведский и финский

      dbLangTurkish - Турецкий


       

      макрос ASSERT

      Макрос задается в виде:

      ASSERT(value)

      Прерывает программу с указанием строки есть значение FALSE (0 то есть).

      Этот макрос не будет работать, если отладка DEBUG не определена.

      Срабатывает на ASSERT(FALSE)

      #include "iostream.h"
      #include "afxwin.h"
      void main()
      {
      cout << "This test ASSERT makro" << endl;
      ASSERT(TRUE);
      cout << "ASSERT(TRUE);" << endl;
      cout << "WARNINGH ASSERT(FALSE) terminate programm !!!" << endl;
      cout << "Pess key and Enter" << endl;
      char c;
      cin >> c;
      ASSERT(FALSE);

      }

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

      #include "iostream.h"
      #include "afxwin.h"

      void main()
      {
      for (int x=1;x<10;x++)
      {
      cout << x << endl;
      ASSERT(x<3);
      }
      }


      макрос RGB

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

      Из этих трех составляющих можно получить любой цвет.

      При использовании палитры RGB цвета могут изменять значения в диапазоне 0-255.

      COLORREF RGB(
      BYTE bRed, // красный
      BYTE bGreen, // зеленый
      BYTE bBlue // синий
      );

      Вы наверно догадались что, COLORREF это просто число.

      А вот так он реализован. Как видите числа помещаются со смешением 0,8,16.

      #define RGB(r, g ,b)  ((DWORD) (((BYTE) (r) | ((WORD) (g) << 8)) | 
      (((DWORD) (BYTE) (b)) << 16)))

      1999 год. Действие происходит где-то в районе OnPaint(), красные опять наступают.

      CPaintDC dc(this);
      CPen pen(PS_SOLID,3,RGB(200,0,0)); // Настроили перо как красное(почти)
      dc.SelectObject(pen); // выбрали перо
      dc.LineTo(600,105);
      dc.MoveTo(300,300); // провели красную линию

       

      Методы класса CMenu

      m_hMenu Указатель на Windows меню, присоединенное к объекту Cmenu.
      CMenu Конструктор объекта CMenu.
      Attach Присоединить указатель Windows меню к объекту Cmenu.
      Detach Отсоединить указатель Windows меню от объекта CMenu и вернуть указатель.
      FromHandle Вернуть указатель на объект CMenu полученный из указателя на Windows меню.
      GetSafeHmenu Вернуть m_hMenu используемое этим объектом Cmenu.
      DeleteTempMap Удалить любые временные объекты Cmenu созданные функцией FromHandle.
      CreateMenu Создать пустое меню и присоединить его к объекту Cmenu.
      CreatePopupMenu Создать пустое всплывающее меню и присоединить его к объекту Cmenu.
      LoadMenu Загрузить меню из ресурсов и присоединить его к объекту Cmenu.
      LoadMenuIndirect Закрузить меню из шаблона в памяти и присоединить его к объекту Cmenu.
      DestroyMenu Разрушить меню присоединенное к объекту CMenu и освободить все память, которую это меню занимало.
      DeleteMenu Удалить определенный пункт меню. Если пункт меню связан с выпадающим меню, то разрушить указатель на выпадающее меню и освободить занимаемую им память.
      TrackPopupMenu Показать всплывающее меню на указанном месте и следить за выбором пунктов во всплывающем меню.
      AppendMenu Добавить новый пункт в конец меню.
      CheckMenuItem Установть или снять флаг состояния на пункт всплывающего меню.
      CheckMenuRadioItem Установить радиокнопку на пункт меню и снять радиокнопки со всех пунктов меню, входящих в группу.
      SetDefaultItem Установить пункт "по умолчанию" для указанного меню.
      GetDefaultItem Получить пункт "по умолчанию" для указанного меню.
      EnableMenuItem Разрешить, запретить или сделать неактивным пункт меню.
      GetMenuItemCount Получить количество пунктов меню в выпадающем меню, или главном меню.
      GetMenuItemID Получить идентификатор пункта меню, расположенного в указанном месте.
      GetMenuState Вернуть статус указанного пункта меню или количество пунктов в выпадающем меню.
      GetMenuString Вернуть метку указанного пункта меню.
      GetMenuItemInfo Вернуть информацию о пункте мнею.
      GetSubMenu Вернуть указатель на выпадающее меню.
      InsertMenu Вставить новый пункт меню в указанное место, переместив все остальные пункт вниз.
      ModifyMenu Изменить существующий пункт меню, расположенный на указанной позиции.
      RemoveMenu Удалить пункт меню вместе со связанным выпадающим меню из указанного меню.
      SetMenuItemBitmaps Связать указанные изображения состояния с пунктом меню.
      GetMenuContextHelpId Возвращает ID контекста помощи, ассоциированный с меню.
      SetMenuContextHelpId Устанавливает ID контекста помощи, который ассоциируется с меню.
      DrawItem Вызывается каркасом, когда визуализация owner-drawn меню изменяется.
      MeasureItem Вызывается каркасом при создании для определения измерений owner-drawn меню.

       

      Стили CTreeView

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

      Стиль TVS_HASLINES говорит о необходимости связи линиями родителей с детьми(подчиненные элементы). Этот пункт не влияет на корневые элементы. Вот так его можно установить. В данный момент открываются деревья двойным щелчком на пункте дерева.
      BOOL CLeftView::Create(LPCTSTR lpszClassName,
      LPCTSTR lpszWindowName,
      DWORD dwStyle, const RECT& rect,
      CWnd* pParentWnd, UINT nID,
      CCreateContext* pContext)
      {
      dwStyle=dwStyle | TVS_HASLINES
      return CWnd::Create(lpszClassName, lpszWindowName,
      dwStyle, rect, pParentWnd, nID, pContext);
      }
      Стиль TVS_HASBUTTONS добавляет кнопку справа от каждого элемента дерева, нажатием на которую есть возможность открывать деревья. Использовать эту кнопку можно вместо двойного щелчка на каждом из пунктов. Давайте добавим этот стиль и посмотрим результат.
      dwStyle=dwStyle | TVS_HASLINES | TVS_HASBUTTONS;
      Стиль TVS_LINESATROOT позволяет добавлять линии к корневому дереву. Вот пример кода.
      dwStyle=dwStyle | TVS_HASLINES | TVS_HASBUTTONS | TVS_LINESATROOT;
      Cтиль TVS_EDITLABELS позволяет организовать редактирование пункта элемента по месту.

      Стиль TVS_SHOWSELALWAYS разрешает пункту быть выбранным когда дерево теряет фокус.