• Создание базы данных
  • MFC AppWizard и базы данных
  • Доводка приложения
  • Как устроено приложение Dater
  • Ресурсы приложения Dater
  • 5. Базы данных и библиотека MFC

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

    Такие системы позволяют хранить большие объемы данных (десятки и сотни тысяч записей) и обеспечивать быстрый поиск необходимой информации.

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

    До недавнего времени на рынке персональных компьютеров превалировали базы данных для операционной системы MS-DOS. Среди них наиболее распространены Clipper, Clarion, Dbase, FoxPro 2.0 и некоторые другие.

    С развитием операционной системы Windows практически все крупные производители программного обеспечения выпустили собственные системы управления базами данных для этой операционной системы. Так, Microsoft производит и распространяет две различные СУБД примерно одного класса – FoxPro for Windows и Access, Borland выпускает Object Vision и Paradox for Windows. Даже фирмы, производящие СУБД для больших и малых компьютеров, выпустили версии своих систем для операционной системы Windows.

    В этой книге рассматривается интерфейс ODBC (Open Database Connectivity), разработанный Microsoft. Этот интерфейс позволяет приложениям Windows получить доступ к данным различных систем управления базами данных, используя запросы на языке SQL. При этом можно получить доступ к данным любой СУБД, для которой существует ODBC драйвер. Так, например, в состав дистрибутива Visual C++ входят ODBC драйверы для баз данных в формате Access, Btrieve, dBase, FoxPro, Excel, Paradox, а также для обычных текстовых файлов. Кроме того, поставляются ODBC драйверы и для удаленных СУБД – SQL Server и Oracle.

    Библиотека классов MFC, поставляемая в составе Visual C++ содержит классы, предназначенные для упрощения взаимодействия с ODBC драйверами. Мы кратко расскажем про эти классы и расскажем как использовать систему автоматизированной разработки приложений AppWizard для создания приложений, поддерживающих работу с базами данных.

    Создание базы данных

    Итак, мы решили создать базу данных на основе обычного текстового файла. Запустите любой текстовый редактор, например Notepad. Вы также можете воспользоваться текстовым редактором среды Microsoft Visual C++. Наберите в нем файл TextBase.txt, представленный в листинге 5.1.

    Листинг 5.1. Файл TextBase.txt

    NAME;ADDRESS;PRIORITY;PHONE

    Фролов Григорий Вячеславович;frolov@glas.apc.org;1;(не известен)

    Фролов Александр Вячеславович;frolov@glas.apc.org;1;(не известен)

    Евсеев Святослав Олегович;sun@power.com;4;8783-77-35

    Николаев Петр Иванович;lis@nikol.com;4;1242-09-09

    Петров Евгений Николаевич;petr@power.com;7;5453-59-05

    Файл TextBase.txt содержит шесть записей (строк). Каждая запись состоит из четырех полей, разделенных символами ;. Самая первая строка отличается от остальных. Она содержит названия полей таблицы, котоорые мы будем использовать далее.

    После того, как файл создан, запишите его в каталоге TEXTBASE. Мы разместили каталог TEXTBASE на диске E:, но вы можете записать его на любом другом диске.

    Следующим шагом является создание так называемого источника данных, который заключается в подключении текстового драйвера ODBC к файлу TextBase.txt. Обраащаясь к этому источнику данных, программа получает доступ к базе даанных через соответствующий драйвер ODBC.

    Для подключения к базе данных драйвера ODBC и создания источника данных используйте приложение 32bit ODBC. Пиктограмма приложения 32bit ODBC находится в окне Control Panel

    Откройте Control Panel и запустите приложение 32bit ODBC. На экране появится диалоговая панель Data Source (рис. 5.1).

    Рис. 5.1. Диалоговая панель Data Source


    Нажмите кнопку Add в диалоговой панели Data Source. На экране появится диалоговая панель Add Data Source (рис. 5.2). В ней вы должны выбрать драйвер ODBC, который будет использоваться для доступа к базе данных.

    Если драйвер ODBC для текстовых файлов отсутствует в списке Installed ODBC Drivers, значит он не установлен на вашем компьютере. Чтобы подключить этот драйвер (а также другие драйверы ODBC) повторите установку Microsoft Visual C++ и укажите драйверы ODBC с которыми вы будете работать.

    Для первого приложения, использующего драйвера ODBC, мы используем базу данных, представляющую собой обычный текстовый файл. Поэтому выберите из списка Installed ODBC Drivers строку Microsoft Text Driver, представляющую текстовый драйвер ODBC. Нажмите кнопку OK.

    Рис. 5.2. Диалоговая панель Add Data Source


    Откроется диалоговая панель ODBC Text Setup (рис. 5.3). Эта панель позволяет выбрать базу данных, для дооступа к которой будет использоваться текстовый драйвер ODBC.

    В поле Data Source Name введите имя базы данных, под которым она будет использоваться. В поле Description можно занести текстовое описание базы данных.

    Так как мы знаем место расположения файла базы данных, убедитесь, что переключатель Use Current Directory выключен и нажмите кнопку Select Directory. На экране появится стандартная диалоговая панель для выбора файлов, но список файлов в ней будет заблокирован. Выберите из нее каталог, в котором записан файл базы данных TextBase.txt. В нашем примере этот файл расположен в каталоге TEXTBASE на диске E:.

    Рис. 5.3. Диалоговая панель ODBC Text Setup


    Нажмите кнопку OK. Стандартная диалоговая панель выбора файлов закроется. Теперь в поле Directory диалоговой панели ODBC Text Setup будет отображаться имя каталога нашей базы данных.

    Как только текстовая база данных (точнее каталог с файлами этой базы) будет выбрана, вы сможете воспользоваться кнопкой Options, расположенной в правом нижнем углу диаалоговой панели ODBC Text Setup. Когда вы нажмете на эту кнопку, внешний вид диалоговой панели ODBC Text Setup изменится (рис. 5.4). В нижней части панели появится новая группа органов управления, которая имеет название Files.

    Рис. 5.4. Расширенный вариант панели ODBC Text Setup


    В группе Extension List вы должны указать расширения файлов, которые входят в базу данных. Вы можете ввести расширение *.txt или использовать маску *.*. Так как в нашем примере каталог TEXTBASE содержит единственный файл TextBase.txt, то это не имеет значения. Заметим, что маска *.* используется по умолчанию, когда переключатель Default (*.*) установлен.

    Теперь надо определить формат таблииц, входящих в базу данных. Нажмите кнопку Define Format. На экране откроется диалоговая панель Define Text Format (рис. 5.5).

    Рис. 5.5. Диалоговая панель Define Text Format


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

    Выберите из списка Tables имя файла TextBase.txt. Теперь надо определить формат этого файла.

    Из списка Format выберите строку, соответствующую типу разделителей, которыми вы отделяете отдельные поля таблицы. Мы использовали в нашем примере разделитель ;. Поэтому выберите из списка Format строку Custom Delimited и введите в поле Delimiter символ ;.

    В зависимости от того, какой набор символов используется в вашей таблице, установите переключатель Characters в положение ANSI или OEM. Мы заполнили файл TextBase.txt в формате ANSI, поэтому переведите переключатель в соответствующее положение.

    В поле Rows to Scan определите количество строк таблицы, которые будут проверяться при выборе формата. Оставьте это значение без изменения.

    Если первая строка файла содержит названия полей соответствующей таблицы, установите переключатель Column Name Header. Обратите внимание на листинг 5.1 файла TextBase.txt. Первая строка этого файла как раз содержит названия полей таблицы. Поэтому переключатель Column Name Header надо установить.

    А теперь нажмите кнопку Guess в группе Columns и, … о чудо: программа установки сама определит формат полей таблицы. Названия этих полей, взятые из первой строки файла TextBase.txt появятся в списке группы Columns. Последовательно выбитите из этого списка названия всех полей таблицы. В полях Data Type, Name и Width будут отображаться тип, имя и максимальная ширина выбранного поля. В случае необходимости вы можете изменить эти значения.

    Поля NAME, ADDRESS и PHONE будут определены как символьные строки, имеющие максимальную длинну 255 символов. Поле PRIORITY будет определено как число Integer.

    Если первая строка файла таблицы не содержит имена полей, то переключатель Column Name Header должен быть выключен. Нажмите кнопку Guess в группе Columns. Программа установки определит формат полей таблицы и присвоит им имена F1, F2, F3 и т. д. В последствии вы можете изменить названия полей, изменив их в поле Name и нажав кнопку Modify.

    После того, как формат файла определен, вы можете закрыть все диалоговые панели приложения 32bit ODBC. Обратите внимание, что в диалоговой панели Data Source появится еще один источник данных – Address Pad (Microsoft Text Driver (*.txt; *.csv)).

    В каталоге TEXTBASE, содержащем файл базы данных TextBase.txt появится еще один файл – schema.ini . Этот файл содержит информацию о таблицах (в нашем случае об единственной таблице) базы данных. В принципе, вы можете изменять характеристики источника данных Address Pad через этот файл, но лучше использовать приложение 32bit ODBC из Control Panel. Для этого запустите приложение 32bit ODBC, выберите из списка имя источника и нажмие кнопку Setup. Откроется панель ODBC Text Setup, через которую можно полностью управлять всеми параметрами базы данных.

    Листинг 5.2. Файл schema.ini

    [textbase.txt]

    ColNameHeader=True

    Format=Delimited(;)

    MaxScanRows=25

    CharacterSet=ANSI

    Col1=NAME Char Width 255

    Col2=ADDRESS Char Width 255

    Col3=PRIORITY Integer

    Col4=PHONE Char Width 255

    MFC AppWizard и базы данных

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

    Создайте новый проект, присвоив ему имя Dater. Используйте для создания проекта средства MFC AppWizard. AppWizard предложит вам заполнить ряд панелей, перечислив в них свойства и характеристики создаваемого приложения.

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

    Рис. 5.6. Диалоговая панель MFC AppWizard – Step 2 of 6


    Переключатель с зависимой фиксацией, расположенный в панели MFC AppWizard – Step 2 of 6, определяет на каком уровне в приложении будет обеспечена поддержка баз данных. Следующая таблица кратко описывает этот переключатель.

    Положение переключателя Описание
    None Работа с базами данных не предусматривается
    Header files only К файлаам проекта подключаются файлы заголовков, необходимые для использования средств доступа к базам данных
    Database view without file support Обеспечивается работа с базами данных. Полученное приложение позволяет просматривать базу данных в окне просмотра. Приложения не работает с файлами документов. Меню File такого приложения содержит только строки, не имеющие отношения к работе с файлами, например строку Exit. Строки Open и Save (и некоторых других) в меню File отсутствуют
    Database view with file support Обеспечивается работа с базами данных. Полученное приложение позволяет просматривать базу данных в окне просмотра. Поддерживается работа приложения с файлами документов. Приложение имеет полное меню File

    Мы выбрали для нашего приложения режим работы с базами данных без поддержки файлов. Переключатель надо перевести в положение Database view without file support.

    Теперь надо указать MFC AppWizard какую базу данных и какую таблиицу из нее мы желаем просматривать в нашем приложении. Для этого мы должны нажать кнопку Data Source, также рассположенную в диаалоговой панели MFC AppWizard – Step 2 of 6.

    На экране появится диалоговая панель Database Options (рис. 5.7). В ней находится ряд органов управления, разделенных на три группы – Datasource, Recordset type и Advanced.

    Рис. 5.7. Диалоговая панель Database Options


    Группа Datasource предназначена для выбора базы данных (источника данных). Вы можете использовать для доступа к базе данных либо драйверы ODBC, либо средства DAO. В этой книге мы рассмотрим использование только драйверов ODBC. Переведите переключатель Datasource в положение ODBC. Из списка, расположенного справой стороны от переключателя ODBC выберите имя источника данных. В нашем случае вы должны выбрать строку Address Pad.

    В группе Recordset type отображается переключатель с зависимой фиксацией. Он может принимать одно из трех положений Snapshot, Dynaset или Table. Используйте этот переключатель, чтобы определить метод работы приложения с базой данных.

    Переключатель Recordset type Описание
    Snapshot Используется для представления статических данных, которые не изменяются во время работы приложения
    Dynaset Подразумевается, что база данных, представленная источником данных, может изменяться во время работы приложения. Такое изменение может выполнять другое приложение, если база данных используется в многопользовательском режиме

    Для нашего приложения Dater мы используем самый простой метод доступа к записям базы данных, поэтому переведите переключатель Recordset type в положение Snapshot.

    В последную группу Advanced входит только один переключатель Detect dirty columns. Этот переключатель используется средствами DAO и в этой книге не рассматривается.

    Когда панель Database Options заполнена, нажмите кнопку OK. На экране появится диалоговая панель Select Database Tables (рис. 5.8). Из нее вы должны выбрать имя таблицы базы данных, с которой будет работать приложение. Информация именно из этой таблицы будет отображаться нашим приложением. В нашем случае база данных (или источник данных) содержить только одну таблицу, поэтому выбор таблицы не составит труда. Просто щелкните мышью по строку TEXTBASE.TXT и нажмите кнопку OK.

    Рис. 5.8. Диалоговая панель Select Database Tables


    Если ваша база данных содержит несколько таблиц и приложение должно работать с ними со всеми, то уже после создания приложения средствами MFC AppWizard, вы можете воспользоваться ClassWizard, чтобы подключить остальные таблицы базы данных. Приложения, работающие одновременно с несколькими таблицами базы данных мы рассмотрим в одной из следующих книг серии “Библиотека системного программиста”.

    После выбора источника данных, вы можете завершить создание приложения и нажать кнопку Finish. Вы также можете продолжить заполнять диалоговые панели MFC AppWizard. В этом случае заполните панели MFC AppWizard, оставляя все предложения по умолчанию. Единственное, что вы можете изменить для упрощения приложения, это отменить все особенности приложения, связанные с печатью. Для этого отключите переключатель Print and print preview в диалоговой панели MFC AppWizard – Step 4 of 6.

    Когда вы дойдете до последней панели MFC AppWizard – Step 6 of 6 (рис. 5.9) вы можете просмотреть, какие классы составляют приложение Dater.

    Рис. 5.9. Диалоговая панель MFC AppWizard – Step 6 of 6

    Оказывается, в отличае от проектов, которые мы изучали ранее, класс окна просмотра приложения Dater наследуется от базового класса CRecordView, и в проект входит класс представляющий записи базы данных, который не имеет аналогов среди других изученных нами приложений. Этот класс наследуется от базового класса CRecordset.

    Доводка приложения

    Взгляните на ресурсы приложения Dater. Для этого откройте страницу ResourceView в окне Project Workspace.

    Обратите внимание на шаблон диалоговой панели IDD_DATER_FORM (рис. 5.10). Этот шаблон используется окном просмотра, созданным на основе класса CRecordView. Окно просмотра содержит в себе органы управления, определенные в шаблоне диалоговой панели.

    Рис. 5.10. Шаблон диалоговой панели IDD_DATER_FORM


    Сразу после того, как MFC AppWizard создаст проект, в этом шаблоне будет размещен одна только текстовая строка TODO: Place form controls on this dialog, предлагающая вам разместить на ней органы управления.

    Удалите с шаблона эту строку, а затем создайте на ней четыре текстовых редактора, по одному для каждого поля таблицы базы данных Address Pad. Присвойте им идентификаторы IDC_NAME, IDC_ADDRESS, IDC_PHONE и IDC_PRIORITY. Около текстовых редакторов поместите краткие строки описания — Name, e-Mail, Phone и Priority. Сохраните изменения в файле ресурсов. Доработанный шаблон диалоговой панели представлен на рисунке 5.11.

    Теперь вы можете выполнить наиболее интересную операцию в создании приложения Dater — привязать при помощи MFC ClassWizard к полям шаблона диалоговой панели IDD_DATER_FORM переменные, представляющие различные поля таблицы базы данных.

    Рис. 5.11. Доработанный шаблон диалоговой панели IDD_DATER_FORM


    Запустите MFC ClassWizard. В окне MFC ClassWizard выберите из списка ClassName имя класса окна просмотра - CDaterView и откройте страницу Member Variables. На этой странице вы увидите список идентификаторов полей редактирования шаблона диалоговой панели IDD_DATER_FORM.

    Выбериете один из идентификаторов и нажмите на кнопку Add Variable. На экране появится диалоговая панель Add Member Variable (рис. 5.12). В этой панели вы должны определить переменную, которая будет отображаться в поле с данным идентификатором. В списке Category отображается категория органа управления к которому вы добавляете переменную. Для полей редактирования из этого списка будет выбрана строка Value. В списске Variable type отображается тип переменной, выбранной в поле Member variable name. Нажмите кнопку OK.

    Рис. 5.12. Диалоговая панель Add Member Variable


    В нашем случае список Member variable name содержит строки, представляющие различные поля записи таблицы базы данных Address Pad. Выбирая остальные идентификаторы шаблона диалоговой панели IDD_DATER_FORM поставьте им в соответствие поля базы данных, как это показано на рисунке 5.13.

    Рис. 5.13. Диалоговая панель MFC ClassWizard


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

    Так например, если ваш компьютер настроен на работу с русским языком, диалоговая панель IDD_DATER_FORM также должна быть русской. Чтобы поменять язык, вызовите панель свойств для диалоговой панели IDD_DATER_FORM и выберите из списка Language строку Russian (рис. 5.14). Дополнительные сведения о выборе языка смотрите в разделе “Национальные ресурсы”.

    Рис. 5.14. Свойства диалоговой панели IDD_DATER_FORM


    Откройте для редактирования метод GetDefaultSQL класса CDaterSet:

    CString CDaterSet::GetDefaultSQL() {

     return _T("[TextBase].[txt]");

    }

    MFC AppWizard не совсем правильно работает с текстовым драйвером и этот метод содержит ошибку. Вы должны убрать из него две лишние квадратные скобки. Исправленный метод будет выглядеть следующим образом:

    CString CDaterSet::GetDefaultSQL() {

     return _T("[TextBase.txt]");

    }

    Все! Теперь можно построить проект и запустить полученное приложение. На экране откроется главное окно приложения Dater (рис. 5.15). В окне просмотра отображаются поля базы данных Address Pad. Вы можете просмотреть все записи базы, используя меню Record и панель управления приложения.

    Рис. 5.15. Приложение Dater

    Как устроено приложение Dater

    Список всех классов, входящих в проект Dater, а также их методов можно просмотреть в окне Project Workspace на странице ClassView (рис. 5.16).

    Рис. 5.16. Окно Project Workspace, страница ClassView


    В приложение Dater входят следующие классы.

    Класс Базовый класс Назначение
    CAboutDlg CDialog Управляет информационной диалоговой панелью About
    CDaterApp CWinApp Главный класс приложения
    CDaterDoc CDocument Представлляет документ приложения
    CDaterSet CRecordset Представлляет запись таблицы базы данных
    CDaterView CRecordView Управляет окном просмотра приложения. В этом окне отображаются записи таблицы базы данных
    CMainFrame CFrameWnd Главное окно приложения
    Главный класс приложения – CDaterApp

    Класс CDaterApp приложения Dater не содержит в себе ничего особенного и практически не отличается от соответствующего класса однооконного приложения Single, созданного MFC AppWizard и не работающего с базами данных:

    //////////////////////////////////////////////////////////////

    // Класс CDaterApp

    //

    class CDaterApp : public CWinApp {

    public:

    CDaterApp();


    // Overrides

     //{{AFX_VIRTUAL(CDaterApp)

    public:

     virtual BOOL InitInstance();

     //}}AFX_VIRTUAL


    // Implementation

     //{{AFX_MSG(CDaterApp)

     afx_msg void OnAppAbout();

     //}}AFX_MSG

     DECLARE_MESSAGE_MAP()

    };

    Класс CDaterApp содержит конструктор, а также методы InitInstance и OnAppAbout.

    Конструктор класса CDaterApp

    Конструктор класса CSingleApp не выполняет никаких действий и состоит из пустого блока:

    CDaterApp::CDaterApp() {

     // TODO:

    }

    Метод OnAppAbout класса CDaterApp

    Метод OnAppAbout класса CDaterApp вызывается для обработки командного сообщения с идентификатором ID_APP_ABOUT, которое посылается при выборе из меню Help строки About. Этот метод совместно с классом CAboutDlg предназначен для отображения информационной диалоговой панели About (в файле ресурсов она имеет идентификатор IDD_ABOUTBOX). Мы не будем рассматривать этот метод и класс CAboutDlg, так как они не используются для взаимодействия с базой данных.

    Метод InitInstance класса CDaterApp

    Наибольший интерес представляет метод InitInstance класса CDaterApp, который создает шаблон документа приложения и добавляет его к списку шаблонов приложения. Кроме того, метод InitInstance разбирает командную строку приложения, загружает поддержку трехмерных органов упрпавления и выполняет еще некоторые действия:

    BOOL CDaterApp::InitInstance() {

    #ifdef _AFXDLL

     Enable3dControls();

    #else

     Enable3dControlsStatic();

    #endif


     LoadStdProfileSettings();


     CSingleDocTemplate* pDocTemplate;

     pDocTemplate = new CSingleDocTemplate(IDR_MAINFRAME, RUNTIME_CLASS(CDaterDoc), RUNTIME_CLASS(CMainFrame), RUNTIME_CLASS(CDaterView));

     AddDocTemplate(pDocTemplate);


     CCommandLineInfo cmdInfo;

     ParseCommandLine(cmdInfo);


     if (!ProcessShellCommand(cmdInfo)) return FALSE;


     return TRUE;

    }

    При создании шаблона документа указывается идентификатор типа документа IDR_MAINFRAME, класс документа приложения CDaterDoc, класс главного окна приложения CMainFrame и класс окна просмотра CDaterView.

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

    Подробное описание метода InitInstance главного класса однооконного приложения можно получить в 24 томе серии “Библиотека системного программиста”.

    Класс главного окна приложения – CMainFrame

    Класс CMainFrame предназначен для управления главным окном приложения. Для этого класса определены конструктор, деструктор, методы PreCreateWindow, OnCreate, AssertValid и Dump. В него также входят два элемента данных m_wndToolBar и m_wndStatusBar, представляющие панель управления и панель состояния:

    class CMainFrame : public CFrameWnd {

    protected:

     CMainFrame();

     DECLARE_DYNCREATE(CMainFrame)


    // Attributes

    public:


    // Operations

    public:


    // Overrides

     //{{AFX_VIRTUAL(CMainFrame)

     virtual BOOL PreCreateWindow(CREATESTRUCT& cs);

     //}}AFX_VIRTUAL


    // Implementation

    public:

     virtual ~CMainFrame();

    #ifdef _DEBUG

     virtual void AssertValid() const;

     virtual void Dump(CDumpContext& dc) const;

    #endif


    protected: 

     CStatusBar m_wndStatusBar;

     CToolBar   m_wndToolBar;


    protected:

     //{{AFX_MSG(CMainFrame)

     afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);

     //}}AFX_MSG

     DECLARE_MESSAGE_MAP()

    };

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

    Конструктор и деструктор класса CMainFrame

    Конструктор и деструктор класса CMainFrame не содержат программного кода.

    Метод PreCreateWindow класса CMainFrame

    Метод PreCreateWindow вызывает метод PreCreateWindow базового класса CFrameWnd и выполняет обработку по умолчанию.

    Метод OnCreate класса CMainFrame

    Метод OnCreate класса CMainFrame создает главное окно приложения, и размещает в нем панель управления IDR_MAINFRAME и стандаартную панель состояния.

    Методы AssertValid и Dump класса CMainFrame

    Методы AssertValid и Dump класса CMainFrame могут использоваться при отладке приложения.

    Класс документа приложения – CDaterDoc

    Класс документа приложения CDaterDoc представляет документ, с которым работает приложение. В него входит элемент m_daterSet класса CDaterSet, также определенного в нашем приложении, который представляет запись базы данных.

    Кроме этого элемента в классе CDaterDoc определены конструктор, деструктор, метод OnNewDocument, а также методы AssertValid и Dump:

    class CDaterDoc : public CDocument {

    protected:

     CDaterDoc();

     DECLARE_DYNCREATE(CDaterDoc)


    // Attributes

    public:

     CDaterSet m_daterSet;


    // Operations

    public:


    // Overrides

     //{{AFX_VIRTUAL(CDaterDoc)

    public:

     virtual BOOL OnNewDocument();

     //}}AFX_VIRTUAL


    // Implementation

    public:

     virtual ~CDaterDoc();

    #ifdef _DEBUG

     virtual void AssertValid() const;

     virtual void Dump(CDumpContext& dc) const;

    #endif


    protected:

     //{{AFX_MSG(CDaterDoc)

     //}}AFX_MSG

     DECLARE_MESSAGE_MAP()

    };

    Конструктор и деструктор класса CDaterDoc

    Конструктор и деструктор класса CMainFrame не содержжат программного кода.

    Метод PreCreateWindow класса CDaterDoc

    Метод OnNewDocument вызывается, когда надо создать новый документ для приложения. Метод OnNewDocument приложения Dater вызывает метод OnNewDocument базового класса CDocument:

    BOOL CDaterDoc::OnNewDocument() {

     if (!CDocument::OnNewDocument()) return FALSE;

     // TODO:

     return TRUE;

    }

    Методы AssertValid и Dump класса CDaterDoc

    Методы AssertValid и Dump класса CMainFrame могут использоваться при отладке приложения.

    Класс окна просмотра приложения – CDaterView

    Большой интерес представляет класс окна просмотра приложения CDaterView. В нем содержится указатель m_pSet на объект класса CDaterSet, который представляет запись базы данных. Обратите внимание, что определение указателя находится внутри комментариев вида //{{AFX_DATA. Эти комментарии используются MFC ClassWizard:

    class CDaterView : public CRecordView {

    protected:

     CDaterView();

     DECLARE_DYNCREATE(CDaterView)


    public:

     //{{AFX_DATA(CDaterView)

     enum { IDD = IDD_DATER_FORM };

     CDaterSet* m_pSet;

     //}}AFX_DATA


    // Attributes

    public:

     CDaterDoc* GetDocument();


    // Operations

    public:


    // Overrides

     //{{AFX_VIRTUAL(CDaterView)

    public:

     virtual CRecordset* OnGetRecordset();

     virtual BOOL PreCreateWindow(CREATESTRUCT& cs);

    protected:

     virtual void DoDataExchange(CDataExchange* pDX);

     virtual void OnInitialUpdate();

     //}}AFX_VIRTUAL


    // Implementation

    public:

     virtual ~CDaterView();

    #ifdef _DEBUG

     virtual void AssertValid() const;

     virtual void Dump(CDumpContext& dc) const;

    #endif


    protected:

     //{{AFX_MSG(CDaterView)

     //}}AFX_MSG

     DECLARE_MESSAGE_MAP()

    };

    Помимо конструктора и деструктора в классе CDaterView определен целый ряд методов – PreCreateWindow, GetDocument, OnGetRecordset, DoDataExchange, OnInitialUpdate, а также AssertValid и Dump. Опишем наиболее важные из этих методов более подробно.

    Конструктор и деструктор класса CDaterView

    Конструктор класса CMainFrame вызывает конструктор базового класса CRecordView и передает ему в качестве параметра символ IDD, определенный как идентификатор шаблона диалоговой панели IDD_DATER_FORM, используемого окном просмотра.

    Конструктор CMainFrame также приваивает указателю m_pSet значение NULL:

    CDaterView::CDaterView() : CRecordView(CDaterView::IDD) {

     //{{AFX_DATA_INIT(CDaterView)

     m_pSet = NULL;

     //}}AFX_DATA_INIT

     // TODO:

    }

    Деструктор класса CMainFrame не содержит программного кода:

    CDaterView::~CDaterView() {}

    Метод PreCreateWindow класса CDaterView

    Метод PreCreateWindow вызывает метод PreCreateWindow базового класса CRecordView и выполняет обработку по умолчанию:

    BOOL CDaterView::PreCreateWindow(CREATESTRUCT& cs) {

     // TODO:

     return CRecordView::PreCreateWindow(cs);

    }

    Метод GetDocument класса CDaterView

    Метод GetDocument возвращает указатель на документ, связанный с данным окном просмотра. Если окно просмотра не связано ни с каким документом, метод возвращает значение NULL.

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

    Окончательная версия GetDocument определена непосредственно после самого класса окна просмотра CDaterView как встраиваемый (inline) метод. Когда вы используете страницу ClassView окна Project Workspace, чтобы просмотреть определение метода GetDocument, вы увидите именно этот код:

    // Окончательная версия приложения

    #ifndef _DEBUG 

    inline CDaterDoc* CDaterView::GetDocument() {

     return (CDaterDoc*)m_pDocument;

    }

    #endif

    Отладочная версия GetDocument расположена в файле реализации класса окна просмотра DaterView.cpp. Откройте этот файл вручную, выбрав его название из страницы FileView окна Project Workspace:

    // Отладочная версия приложения

    #ifdef _DEBUG

    CDaterDoc* CDaterView::GetDocument() {

     ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CDaterDoc)));

     return (CDaterDoc*)m_pDocument;

    }

    #endif //_DEBUG

    Макрокоманда RUNTIME_CLASS возвращает указатель на структуру CRuntimeClass, содержащую информацию о классе CDaterDoc. Метод IsKindOf, определенный в классе CObject, проверяет, принадлежит ли объект, на который указывает m_pDocument, к классу CDaterDoc или классу наследованному от CDaterDoc. Если в приложении есть ошибка и m_pDocument не указывает на документ приложения, макрокоманда ASSERT отображает соответствующее сообщение и прерывает работу приложения.

    Метод OnGetRecordset класса CDaterView

    Метод OnGetRecordset класса CDaterView возвращает указатель m_pSet на запись базы данных:

    //////////////////////////////////////////////////////////////

    // Метод OnGetRecordset класса CDaterView

    CRecordset* CDaterView::OnGetRecordset() {

     return m_pSet;

    }

    Метод OnInitialUpdate класса CDaterView

    Метод OnInitialUpdate класса окна просмотра CDaterView первоначально определен в базовом классе CView. Этот метод вызывается MFC перед отображением окна просмотра на экране:

    //////////////////////////////////////////////////////////////

    // Метод OnInitialUpdate класса CDaterView

    void CDaterView::OnInitialUpdate() {

     m_pSet = &GetDocument()->m_daterSet;

     CRecordView::OnInitialUpdate();

    }

    В момент вызова метода OnInitialUpdate окно просмотра уже связано с объектом документа приложения, поэтому можно использовать метод GetDocument.

    В нашем случае метод GetDocument используется, чтобы записать в переменную m_pSet (входящую в класс CDaterView) укзатель на объект m_daterSet класса CDaterSet, представляющий записи базы данных и входящий в класс документа приложения — класс CDaterDoc.

    Затем вызывается метод OnInitialUpdate базового класса CRecordView.

    Метод DoDataExchange класса CDaterView

    Виртуальный метод DoDataExchange класса CDaterView, первоначально определен в классе CWnd. Он служит для реализации механизмов автоматического обмена данными – Dialog Data Exchange (DDX) и автоматической проверки данных – Dialog Data Validation (DDV). Мы рассматривали этот механизм в 24 томе серии “Библиотека системного программиста”:

    //////////////////////////////////////////////////////////////

    // Метод DoDataExchange класса CDaterView

    void CDaterView::DoDataExchange(CDataExchange* pDX) {

    CRecordView::DoDataExchange(pDX);

     //{{AFX_DATA_MAP(CDaterView)

     DDX_FieldText(pDX,IDC_ADDRESS, m_pSet->m_ADDRESS, m_pSet);

     DDX_FieldText(pDX,IDC_NAME, m_pSet->m_NAME, m_pSet);

     DDX_FieldText(pDX,IDC_PHONE, m_pSet->m_PHONE, m_pSet);

     DDX_FieldText(pDX,IDC_PRIORITY, m_pSet->m_PRIORITY,m_pSet);

     //}}AFX_DATA_MAP

    }

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

    Обмен выполняется при помощи функций DDX_FieldText. Могут также использоваться и другие функции, например, DDX_FieldRadio, DDX_FieldCheck, DDX_FieldScroll. Практически каждый тип органов управления диалоговой панели имеет собственную функцию для выполнения процедуры обмена данными.

    Всем функциям DDX_FieldText, вызываевым в методе DoDataExchange класса CDaterView передаются четыре параметра.

    Первый параметр содержит указатель на объект класса CDataExchange. Этот объект определяет параметры обмена, в том числе направление, в котором надо выполнить обмен данными.

    Второй параметр определяет идентификатор органа управления окна просмотра, с которым выполняется обмен данными (окно просмотра доолжно быть представлено классом CRecordView). В нашем случае это идентификаторы полей IDC_ADDRESS, IDC_NAME, IDC_PHONE и IDC_PRIORITY, котоорые принадлежат шаблону диалоговой панели используемому окном просмотра.

    Третий параметр содержит ссылку на элемент данных класса CDaterSet, представляющий соответствующее поле базы данных. В нашем методе в качестве этого парамтера фигурируют m_pSet->m_ADDRESS, m_pSet->m_NAME, m_pSet->m_PHONE и m_pSet->m_PRIORITY.

    Четвертый параметр содержит указатель на объект класса CDaterSet, с которым выполняется обмен данными. В нашем случае для всех методов в качестве этого параметра используется указатель m_pSet.

    Методы AssertValid и Dump класса CDaterView

    Методы AssertValid и Dump класса CDaterView могут использоваться при отладке приложения.

    Класс записи базы данных – CDaterDoc

    Центральным классом приложений, которые взаимодействуют с базами данных через драйвера ODBC, является класс, наследованный от базового класса CRecordset. В нашем приложении в качестве этого класса выступает класс CDaterSet:

    class CDaterSet : public CRecordset {

    public:

     CDaterSet(CDatabase* pDatabase = NULL);

     DECLARE_DYNAMIC(CDaterSet)


    // Field/Param Data

     //{{AFX_FIELD(CDaterSet, CRecordset)

     CString m_NAME;

     CString m_ADDRESS;

     long m_PRIORITY;

     CString m_PHONE;

     //}}AFX_FIELD


    // Overrides

     //{{AFX_VIRTUAL(CDaterSet)

    public:

     virtual CString GetDefaultConnect();

     virtual CString GetDefaultSQL();

     virtual void DoFieldExchange(CFieldExchange* pFX);

     //}}AFX_VIRTUAL


    // Implementation

    #ifdef _DEBUG

     virtual void AssertValid() const;

     virtual void Dump(CDumpContext& dc) const;

    #endif


    };

    Класс CDaterSet содержит в себе переменные, представляющие поля записи базы данных. Эти переменные размещаются внутри комментариев вида //{{AFX_FIELD.

    В нашем случае эти переменные называются m_NAME, m_ADDRESS, m_PRIORITY и m_PHONE. Они представляют поля NAME, ADDRESS, PRIORITY и PHONE соответственно.

    В классе CDaterSet также определены конструктор класса и несколько методов – GetDefaultConnect, GetDefaultSQL, DoFieldExchange, а также AssertValid и Dump.

    Конструктор класса CDaterSet

    Конструктор класса CDaterSet вызывает конструктор базового класса CRecordset. В качестве параметра конструктору CDaterSet и конструктору базового класса передается указатель pdb на объект класса CDatabase, представляющий источник данных.

    В приложении Dater конструктору CDaterSet параметр pdb не передается (см. класс CDaterDoc). Посмотрите описание конструктора класса CRecordset в документации Microsoft Visual C++. Если он вызывается без параметра или с параметром NULL, то конструктор автоматически создает объект класса CDatabase. С Этим объектом связывается источник данных, определенный в методе GetDefaultConnect:

    CDaterSet::CDaterSet(CDatabase* pdb) : CRecordset(pdb) {

     DECLARE_DYNAMIC(CDaterSet)


    // Field/Param Data

     //{{AFX_FIELD(CDaterSet, CRecordset)

     CString m_NAME;

     CString m_ADDRESS;

     long m_PRIORITY;

     CString m_PHONE;

     //}}AFX_FIELD


    // Overrides

     //{{AFX_VIRTUAL(CDaterSet)

     public:

     virtual CString GetDefaultConnect();

     virtual CString GetDefaultSQL();

     virtual void DoFieldExchange(CFieldExchange* pFX);

     //}}AFX_VIRTUAL


    // Implementation

    #ifdef _DEBUG

     virtual void AssertValid() const;

     virtual void Dump(CDumpContext& dc) const;

    #endif


    };

    Класс CDaterSet содержит в себе переменные, представляющие поля записи базы данных. Эти переменные размещаются внутри комментариев вида //{{AFX_FIELD.

    В нашем случае эти переменные называются m_NAME, m_ADDRESS, m_PRIORITY и m_PHONE. Они представляют поля NAME, ADDRESS, PRIORITY и PHONE соответственно.

    Метод GetDefaultConnect класса CDaterSet

    Метод GetDefaultConnect возвращает текстовую строку, которая определяет источник данных, который будет связан с объектом CDaterSet. Эта строка формируется MFC AppWizard, при выборе вами источника данных:

    CString CDaterSet::GetDefaultConnect() {

     return _T("ODBC;DSN=Address Pad");

    }

    Метод GetDefaultSQL класса CDaterSet

    Метод GetDefaultSQL возвращает текстовую строку, которая должна содержать имя таблицы источника данных или выражение SELECT языка SQL. На основе этой таблицы или результата запроса SELECT будет сформирован набор записей для объекта CDaterSet:

    CString CDaterSet::GetDefaultSQL() {

     return _T("[TextBase.txt]");

    }

    Метод DoFieldExchange класса CDaterSet

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

    void CDaterSet::DoFieldExchange(CFieldExchange* pFX) {

     //{{AFX_FIELD_MAP(CDaterSet)

     pFX->SetFieldType(CFieldExchange::outputColumn);

     RFX_Text(pFX, _T("[NAME]"), m_NAME);

     RFX_Text(pFX, _T("[ADDRESS]"), m_ADDRESS);

     RFX_Long(pFX, _T("[PRIORITY]"), m_PRIORITY);

     RFX_Text(pFX, _T("[PHONE]"), m_PHONE);

     //}}AFX_FIELD_MAP

    }

    Метод DoFieldExchange содержит блок из комментариев //{{AFX_FIELD_MAP, в котором расположены несколько методов RFX_Text, которые выполняют обмен данными между полями источника данных (в нашем случае это поля NAME,  ADDRESS, PRIORITY, PHONE) и соответствующими элементами класса CDaterSet (m_NAME, m_ADDRESS, m_PRIORITY, m_PHONE).

    Вы не должны вручную исправлять программный код в блоке AFX_FIELD_MAP. Для этого надо использовать MFC ClassWizard (рис. 5.17).

    Рис. 5.17. Диалоговая панель MFC ClassWizard

    Методы AssertValid и Dump класса CDaterSet

    Методы AssertValid и Dump класса CDaterSet могут использоваться при отладке приложения.

    Ресурсы приложения Dater

    В файле ресурсов приложения Dater определены меню, панель управления и таблица клавиш акселераторов IDR_MAINFRAME, шаблон диалоговой панели IDD_DATER_FORM, который используется окном просмотра и шаблон информационной панели IDD_ABOUTBOX. В файле ресурсов также расположены строковые ресурсы, описывающие строки меню, кнопки панелей управления и индикаторы панели состояния. Мы привели исходный текст файла Dater.rc в листинге 5.3.

    Листинг 5.3. Файл Dater.rc

    //Microsoft Developer Studio generated resource script.

    //

    #include "resource.h"


    #define APSTUDIO_READONLY_SYMBOLS

    //////////////////////////////////////////////////////////////

    //

    // Generated from the TEXTINCLUDE 2 resource.

    //

    #include "afxres.h"


    //////////////////////////////////////////////////////////////

    #undef APSTUDIO_READONLY_SYMBOLS


    //////////////////////////////////////////////////////////////

    // English (U.S.) resources


    //#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)

    //#ifdef _WIN32

    //LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US

    //#pragma code_page(1252)

    //#endif //_WIN32


    #ifdef APSTUDIO_INVOKED

    //////////////////////////////////////////////////////////////

    //

    // TEXTINCLUDE

    //


    1 TEXTINCLUDE DISCARDABLE

    BEGIN

     "resource.h\0"

    END


    2 TEXTINCLUDE DISCARDABLE

    BEGIN

     "#include ""afxres.h""\r\n"

     "\0"

    END


    3 TEXTINCLUDE DISCARDABLE

    BEGIN

     "#define _AFX_NO_SPLITTER_RESOURCES\r\n"

     "#define _AFX_NO_OLE_RESOURCES\r\n"

     "#define _AFX_NO_TRACKER_RESOURCES\r\n"

     "#define _AFX_NO_PROPERTY_RESOURCES\r\n"

     "\r\n"

     "#if !defined(AFX_RESOURCE_DLL)||defined(AFX_TARG_ENU)\r\n"

     "#ifdef _WIN32\r\n"

     "LANGUAGE 9, 1\r\n"

     "#pragma code_page(1252)\r\n"

     "#endif\r\n"

     "#include ""res\\Dater.rc2""  // non-Microsoft Visual C++

                                   // edited resources\r\n"

     "#include ""afxres.rc""       // Standard components\r\n"

     "#include ""afxdb.rc""        // Database resources\r\n"

     "#endif\0"

    END


    #endif // APSTUDIO_INVOKED


    //////////////////////////////////////////////////////////////

    //

    // Icon

    //


    IDR_MAINFRAME ICON DISCARDABLE "res\\Dater.ico"

    IDR_DATERTYPE ICON DISCARDABLE "res\\DaterDoc.ico"


    //////////////////////////////////////////////////////////////

    //

    // Bitmap

    //


    IDR_MAINFRAME   BITMAP  MOVEABLE PURE   "res\\Toolbar.bmp"


    //////////////////////////////////////////////////////////////

    //

    // Toolbar

    //


    IDR_MAINFRAME TOOLBAR DISCARDABLE 16, 15

    BEGIN

     BUTTON ID_EDIT_CUT

     BUTTON ID_EDIT_COPY

     BUTTON ID_EDIT_PASTE

     SEPARATOR

     BUTTON ID_FILE_PRINT

     SEPARATOR

     BUTTON ID_RECORD_FIRST

     BUTTON ID_RECORD_PREV

     BUTTON ID_RECORD_NEXT

     BUTTON ID_RECORD_LAST

     SEPARATOR

     BUTTON ID_APP_ABOUT

    END


    //////////////////////////////////////////////////////////////

    //

    // Menu

    //


    IDR_MAINFRAME MENU PRELOAD DISCARDABLE

    BEGIN

     POPUP "&File"

     BEGIN

      MENUITEM "E&xit", ID_APP_EXIT

     END

     POPUP "&Edit"

     BEGIN

      MENUITEM "&Undo\tCtrl+Z", ID_EDIT_UNDO

      MENUITEM SEPARATOR

      MENUITEM "Cu&t\tCtrl+X", ID_EDIT_CUT

      MENUITEM "&Copy\tCtrl+C", ID_EDIT_COPY

      MENUITEM "&Paste\tCtrl+V", ID_EDIT_PASTE

     END

     POPUP "&Record"

     BEGIN

      MENUITEM "&First Record",    ID_RECORD_FIRST

      MENUITEM "&Previous Record", ID_RECORD_PREV

      MENUITEM "&Next Record",     ID_RECORD_NEXT

      MENUITEM "&Last Record",     ID_RECORD_LAST

     END

     POPUP "&View"

     BEGIN

      MENUITEM "&Toolbar",    ID_VIEW_TOOLBAR

      MENUITEM "&Status Bar", ID_VIEW_STATUS_BAR

     END

     POPUP "&Help"

     BEGIN

      MENUITEM "&About Dater...", ID_APP_ABOUT

     END

    END


    //////////////////////////////////////////////////////////////

    //

    // Accelerator

    //


    IDR_MAINFRAME ACCELERATORS PRELOAD MOVEABLE PURE

    BEGIN

     "Z",       ID_EDIT_UNDO,  VIRTKEY, CONTROL

     "X",       ID_EDIT_CUT,   VIRTKEY, CONTROL

     "C",       ID_EDIT_COPY,  VIRTKEY, CONTROL

     "V",       ID_EDIT_PASTE, VIRTKEY, CONTROL

     VK_BACK,   ID_EDIT_UNDO,  VIRTKEY, ALT

     VK_DELETE, ID_EDIT_CUT,   VIRTKEY, SHIFT

     VK_INSERT, ID_EDIT_COPY,  VIRTKEY, CONTROL

     VK_INSERT, ID_EDIT_PASTE, VIRTKEY, SHIFT

     VK_F6,     ID_NEXT_PANE,  VIRTKEY

     VK_F6,     ID_PREV_PANE,  VIRTKEY, SHIFT

    END


    //////////////////////////////////////////////////////////////

    //

    // Dialog

    //


    IDD_ABOUTBOX DIALOG DISCARDABLE  0, 0, 217, 55

    STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU

    CAPTION "About Dater"

    FONT 8, "MS Sans Serif"

    BEGIN

     ICON          IDR_MAINFRAME,IDC_STATIC,11,17,20,20

     LTEXT         "Dater Version 1.0", IDC_STATIC, 40, 10, 119, 8, SS_NOPREFIX

     LTEXT         "Copyright © 1996", IDC_STATIC, 40, 25, 119, 8

     DEFPUSHBUTTON "OK",IDOK,178,7,32,14,WS_GROUP

    END


    IDD_DATER_FORM DIALOG DISCARDABLE  0, 0, 201, 101

    STYLE WS_CHILD

    FONT 8, "MS Sans Serif"

    BEGIN

     LTEXT    "E-Mail",IDC_STATIC,5,35,20,8

     LTEXT    "Priority",IDC_STATIC,5,86,22,8

     EDITTEXT IDC_NAME,35,5,160,15,ES_AUTOHSCROLL

     LTEXT    "Name",IDC_STATIC,5,10,20,8

     EDITTEXT IDC_ADDRESS,35,30,160,15,ES_AUTOHSCROLL

     EDITTEXT IDC_PRIORITY,35,80,80,15,ES_AUTOHSCROLL

     LTEXT    "Phone",IDC_STATIC,5,60,22,8

     EDITTEXT IDC_PHONE,35,55,80,15,ES_AUTOHSCROLL

    END


    #ifndef _MAC

    //////////////////////////////////////////////////////////////

    //

    // Version

    //


    VS_VERSION_INFO VERSIONINFO

     FILEVERSION 1,0,0,1

     PRODUCTVERSION 1,0,0,1

     FILEFLAGSMASK 0x3fL

    #ifdef _DEBUG

     FILEFLAGS 0x1L

    #else

     FILEFLAGS 0x0L

    #endif

     FILEOS 0x4L

     FILETYPE 0x1L

     FILESUBTYPE 0x0L

    BEGIN

     BLOCK "StringFileInfo"

     BEGIN

      BLOCK "040904B0"

      BEGIN

       VALUE "CompanyName", "\0"

       VALUE "FileDescription", "DATER MFC Application\0"

       VALUE "FileVersion", "1, 0, 0, 1\0"

       VALUE "InternalName", "DATER\0"

       VALUE "LegalCopyright", "Copyright © 1996\0"

       VALUE "LegalTrademarks", "\0"

       VALUE "OriginalFilename", "DATER.EXE\0"

       VALUE "ProductName", "DATER Application\0"

       VALUE "ProductVersion", "1, 0, 0, 1\0"

      END

     END

     BLOCK "VarFileInfo"

     BEGIN

      VALUE "Translation", 0x409, 1200

     END

    END


    #endif // !_MAC


    //////////////////////////////////////////////////////////////

    //

    // DESIGNINFO

    //


    #ifdef APSTUDIO_INVOKED

    GUIDELINES DESIGNINFO DISCARDABLE

    BEGIN

     IDD_ABOUTBOX, DIALOG

     BEGIN

      LEFTMARGIN, 7

      RIGHTMARGIN, 210

      TOPMARGIN, 7

      BOTTOMMARGIN, 48

     END


     IDD_DATER_FORM, DIALOG

     BEGIN

      LEFTMARGIN, 7

      RIGHTMARGIN, 194

      TOPMARGIN, 7

      BOTTOMMARGIN, 94

     END

    END

    #endif // APSTUDIO_INVOKED


    //////////////////////////////////////////////////////////////

    //

    // String Table

    //


    STRINGTABLE DISCARDABLE

    BEGIN

     IDP_FAILED_OPEN_DATABASE "Cannot open database."

    END


    STRINGTABLE PRELOAD DISCARDABLE

    BEGIN

     IDR_MAINFRAME "Dater\n\nDater\n\n\nDater.Document\nDater Document"

    END


    STRINGTABLE PRELOAD DISCARDABLE

    BEGIN

     AFX_IDS_APP_TITLE   "Dater"

     AFX_IDS_IDLEMESSAGE "Ready"

    END


    STRINGTABLE DISCARDABLE

    BEGIN

     ID_INDICATOR_EXT  "EXT"

     ID_INDICATOR_CAPS "CAP"

     ID_INDICATOR_NUM  "NUM"

     ID_INDICATOR_SCRL "SCRL"

     ID_INDICATOR_OVR  "OVR"

     ID_INDICATOR_REC  "REC"

    END


    STRINGTABLE DISCARDABLE

    BEGIN

     ID_APP_ABOUT "Display program information, version number and copyright\nAbout"

     ID_APP_EXIT  "Quit the application; prompts to save documents\nExit"

    END


    STRINGTABLE DISCARDABLE

    BEGIN

     ID_FILE_MRU_FILE1  "Open this document"

     ID_FILE_MRU_FILE2  "Open this document"

     //...

     ID_FILE_MRU_FILE16 "Open this document"

    END


    STRINGTABLE DISCARDABLE

    BEGIN

     ID_NEXT_PANE "Switch to the next window pane\nNext Pane"

     ID_PREV_PANE "Switch back to the previous window pane\n Previous Pane"

    END


    STRINGTABLE DISCARDABLE

    BEGIN

     ID_WINDOW_SPLIT "Split the active window into panes\nSplit"

    END


    STRINGTABLE DISCARDABLE

    BEGIN

     ID_EDIT_CLEAR      "Erase the selection\nErase"

     ID_EDIT_CLEAR_ALL  "Erase everything\nErase All"

     ID_EDIT_COPY       "Copy the selection and put it on the Clipboard\nCopy"

     ID_EDIT_CUT        "Cut the selection and put it on the Clipboard\nCut"

     ID_EDIT_FIND       "Find the specified text\nFind"

     ID_EDIT_PASTE      "Insert Clipboard contents\nPaste"

     ID_EDIT_REPEAT     "Repeat the last action\nRepeat"

     ID_EDIT_REPLACE    "Replace specific text with different text\nReplace"

     ID_EDIT_SELECT_ALL "Select the entire document\nSelect All"

     ID_EDIT_UNDO      "Undo the last action\nUndo"

     ID_EDIT_REDO      "Redo the previously undone action\nRedo"

    END


    STRINGTABLE DISCARDABLE

    BEGIN

     ID_VIEW_TOOLBAR    "Show or hide the toolbar\nToggle ToolBar"

     ID_VIEW_STATUS_BAR "Show or hide the status bar\nToggle StatusBar"

    END


    STRINGTABLE DISCARDABLE

    BEGIN

     ID_RECORD_FIRST "Move to first record\nFirst Record"

     ID_RECORD_LAST  "Move to final record\nLast Record"

     ID_RECORD_NEXT  "Move to next record\nNext Record"

     ID_RECORD_PREV  "Move to previous record\nPrevious Record"

    END


    STRINGTABLE DISCARDABLE

    BEGIN

     AFX_IDS_SCSIZE       "Change the window size"

     AFX_IDS_SCMOVE       "Change the window position"

     AFX_IDS_SCMINIMIZE   "Reduce the window to an icon"

     AFX_IDS_SCMAXIMIZE   "Enlarge the window to full size"

     AFX_IDS_SCNEXTWINDOW "Switch to the next document window"

     AFX_IDS_SCPREVWINDOW "Switch to the previous document window"

     AFX_IDS_SCCLOSE      "Close the active window and prompts to save the documents"

    END


    STRINGTABLE DISCARDABLE

    BEGIN

     AFX_IDS_SCRESTORE  "Restore the window to normal size"

     AFX_IDS_SCTASKLIST "Activate Task List"

    END


    //#endif    // English (U.S.) resources

    //////////////////////////////////////////////////////////////


    #ifndef APSTUDIO_INVOKED

    //////////////////////////////////////////////////////////////

    //

    // Generated from the TEXTINCLUDE 3 resource.

    //

    #define _AFX_NO_SPLITTER_RESOURCES

    #define _AFX_NO_OLE_RESOURCES

    #define _AFX_NO_TRACKER_RESOURCES

    #define _AFX_NO_PROPERTY_RESOURCES


    #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)

    #ifdef _WIN32

    LANGUAGE 9, 1

    #pragma code_page(1252)

    #endif

    #include "res\Dater.rc2" // non-Microsoft Visual C++ edited resources

    #include "afxres.rc"     // Standard components

    #include "afxdb.rc"      // Database resources

    #endif

    //////////////////////////////////////////////////////////////

    #endif // not APSTUDIO_INVOKED

    Идентификаторы ресурсов приложения Dater определены в файле resource.h. Этот файл создается автоматически редактором ресурсов Microsoft Visual C++. Исходный текст файла resource.h представлен в листинге 3.15.

    Листинг 5.4. Файл resource.h

    //{{NO_DEPENDENCIES}}

    // Microsoft Developer Studio generated include file.

    // Used by Dater.rc

    //

    #define IDD_ABOUTBOX             100

    #define IDD_DATER_FORM           101

    #define IDP_FAILED_OPEN_DATABASE 103

    #define IDR_MAINFRAME            128

    #define IDR_DATERTYPE            129

    #define IDC_NAME                 1000

    #define IDC_ADDRESS              1001

    #define IDC_PRIORITY             1002

    #define IDC_PHONE                1003


    // Next default values for new objects

    //

    #ifdef APSTUDIO_INVOKED

    #ifndef APSTUDIO_READONLY_SYMBOLS

    #define _APS_3D_CONTROLS         1

    #define _APS_NEXT_RESOURCE_VALUE 130

    #define _APS_NEXT_COMMAND_VALUE  32771

    #define _APS_NEXT_CONTROL_VALUE  1004

    #define _APS_NEXT_SYMED_VALUE    101

    #endif

    #endif

    Наибольший интерес в файле ресурсов приложения Dater представляют строки меню Record и соответствующие им кнопки панели управления. Эти строки и кнопки позволяют просматривать в окне приложения все записи базы данных.

    Строка меню Record Идентификатор Описание
    First Record ID_RECORD_FIRST Перейти к первой записи
    Previous Record ID_RECORD_PREV Перейти к предыдущей записи
    Next Record ID_RECORD_NEXT Перейти к следующей записи
    Last Record ID_RECORD_LAST Перейти к последней записи 

    Командные сообщения с идентификаторами ID_RECORD_FIRST, ID_RECORD_PREV, ID_RECORD_NEXT и ID_RECORD_LAST обрабатываются виртуальным методом OnMove класса окна просмотра CRecordView.

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








    Главная | В избранное | Наш E-MAIL | Прислать материал | Нашёл ошибку | Наверх