Электронная библиотека книг Александра Фролова и Григория Фролова.
Shop2You.ru Создайте свой интернет-магазин
Библиотека
Братьев
Фроловых

Разработка приложений для Internet

© Александр Фролов, Григорий Фролов
Том 31, М.: Диалог-МИФИ, 1997, 286 стр.

[Назад] [Содеожание] [Дальше]

Функции WinInet

Кроме классов WinInet в состав библиотеки MFC входят три глобальные функции - AfxParseURL, AfxGetInternetHandleType и AfxThrowInternetException. Они не принадлежат классам MFC и могут вызываться из любого места приложения.

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

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

Функция AfxGetInternetHandleType позволяет определить тип идентификатора Internet. Для определения типа идентификатора Internet глобальная функция InternetQueryOption вызывает функцию InternetQueryOption библиотеки WinInet.

Также как и классы WinInet все глобальные функции описаны в файле AFXINET.H. Если вы желаете изучить их более подробно, то можете найти исходные тексты в файле INET.CPP.

Адреса URL

Ресурсы, доступные через сеть Internet, определяются посредством универсальных адресов ресурсов или просто адресов (URL - Universal Resource Locators или Uniform Resource Locators). Адрес URL определяет имя сервера на котором расположен ресурс, имя объекта и каталог где этот ресурс находится, протокол для взаимодействия с сервером и номер порта TCP/IP на котором происходит соединение.

Общий формат адресов URL представлен ниже:


service://server:port/dir/dir/object.ext

Поле service определяет протокол для работы с сервером. Сразу после названия протокола следует символ двоеточия и два обратных слеша.

Затем идет поле server. Оно содержит название сервера, соответствующего данному адресу.

После имени сервера может располагаться номер порта TCP/IP. Это числовое значение перед которым надо указать символ двоеточия. Данное поле необязательное. Если вы не укажете номер порта TCP/IP, то будет использоваться порт принятый по умолчанию для данного протокола.

Непосредственно за номером порта TCP/IP или сразу после имени сервера (если номер порта TCP/IP не задан) следует путь каталога и имя объекта на который ссылается адрес. В качестве имени объекта может фигурировать имя файла, имя расширения CGI или ISAPI.

Функция AfxParseURL

Функция AfxParseURL разбирает текстовую строку, содержащую универсальный указатель ресурсов URL и выделяет из него тип сервиса, объект и номер порта TCP/IP. Приведем прототип функции AfxParseURL:


BOOL AFXAPI 
AfxParseURL( 
   LPCTSTR pstrURL, 
   DWORD& dwServiceType, 
   CString& strServer, 
   CString& strObject, 
   INTERNET_PORT& nPort 
);

Указатель на строку, содержащую URL, передается функции AfxParseURL через параметр pstrURL. Функция AfxParseURL разбирает данную строку и возвращает результат через параметры dwServiceType, strServer, strObject и nPort.

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

Константа

Тип сервиса

AFX_INET_SERVICE_FILE

Имя файла на локальном диске компьютера

AFX_INET_SERVICE_FTP

Протокол передачи файлов FTP

AFX_INET_SERVICE_GOPHER

Протокол Gopher

AFX_INET_SERVICE_HTTP

Протокол передачи гипертекста

AFX_INET_SERVICE_MAILTO

Адрес электронной почты (e-Mail)

AFX_INET_SERVICE_NEWS

Новости

AFX_INET_SERVICE_NNTP

Новости с использованием протокола NNTP

AFX_INET_SERVICE_TELNET

Протокол Telnet

AFX_INET_SERVICE_WAIS

Протокол Wais

В строку strServer записывается первое поле URL, определяющее тип сервиса (тип протокола). Объект на который ссылается URL записывается в строку strObject. И, наконец, номер порта TCP/IP записывается в переменную nPort.

Функция AfxParseURL возвращает ненулевое значение в случае успешного завершения и нуль в случае ошибки.

Приложение Parse

В этом разделе мы представим вашему вниманию приложение Parse. Оно использует функцию AfxParseURL для разбора на составные части адресов URL, которые пользователь может вводить в диалоговой панели приложения (рис. 1.3).

Приложение Parse не выполняет соединение с Internet и вы можете его запустить на компьютере, не имеющем ни модема, ни сетевой карты, и не подключенном к сетям Internet и Intranet. Конечно, пользы от такого приложения не много, но мы предлагаем вам с ним поработать, чтобы лучше разобраться со структурой адресов URL.

Рис. 1.3. Приложение ParseURL

Чтобы упростить приложение, мы выбрали для него интерфейс на основе диалоговой панели. Запустите MFC AppWizard, выбрав из меню File строку New. На экране появится одноименная диалоговая панель. Выберите в ней из списка New строку Project Workspace и нажмите кнопку OK. Откроется диалоговая панель New Project Workspace. В качестве типа создаваемого приложения укажите MFC AppWizard (exe) и введите в поле Name имя проекта - Parse. Затем нажмите кнопку Create.

На экране появится первая диалоговая панель MFC AppWizard - MFC AppWizard - Step 1. В ней вы должны выбрать тип пользовательского интерфейса приложения - Dialog based, то есть приложение с главной диалоговой панелью. В принципе, теперь вы можете нажать кнопку Finish и оставить все остальные характеристики приложения по умолчанию. Но чтобы упростить приложение и сделать его исходный текст более доступным для понимания, мы предлагаем вам сначала перейти к следующей панели MFC AppWizard Step 2 of 4 и отключить в ней переключатель About box. При этом MFC AppWizard не будет подключать к приложению информационную диалоговую панель About. За счет этого можно несколько упростить исходные тексты приложения.

После этого, нажмите кнопку Finish, просмотрите информацию о приложении, которая появится в диалоговой панели New Project Information, и нажмите на кнопку OK. MFC AppWizard создаст проект.

Мы уже детально рассматривали шаблон приложения с пользовательским интерфейсом на основе диалоговой панели в 28 томе серии “Библиотека системного программиста”. Поэтому мы сразу приступим к доработке шаблона приложения и не будем останавливаться на исходных текстах, созданных MFC AppWizard.

Сначала загрузите в редактор ресурсов шаблон главной диалоговой панели IDD_PARSEURL_DIALOG приложения Parse. Разместите на этой диалоговой панели пять полей редактирования IDC_EDIT_URL_ADDRESS, IDC_EDIT_SERVICE_TYPE, IDC_EDIT_SERVER_NAME, IDC_EDIT_OBJECT_NAME и IDC_EDIT_PORT_NUMBER. Все поля редактирования кроме IDC_EDIT_URL_ADDRESS сделайте доступными только для чтения. Для этого в панели свойств этих полей Edit Propeties на странице Styles установите переключатель Read-only. Около каждого поля редактирования сделайте соответствующие текстовые подписи URL Address, Service type, Server name, Object name и Port number.

По умолчанию MFC AppWizard создает в диалоговой панели IDD_PARSEURL_DIALOG две кнопки - кнопку OK с идентификатором IDOK и кнопку Cancel с идентификатором IDCANCEL. Кнопка Cancel нам не понадобится вы можете ее удалить. Вместо нее добавьте кнопку Convert, присвоив ей идентификатор IDC_BUTTON_CONVERT.

В листинге 1.1 мы привели фрагмент файла ресурсов приложения Parse, в котором определяется шаблон диалоговой панели IDD_PARSEURL_DIALOG. Ориентируйтесь на него, когда будете создавать эту диалоговую панель.

Листинг 1.1. Фрагмент файла Parse.rc, шаблон диалоговой панели IDD_PARSEURL_DIALOG


//////////////////////////////////////////////////////////////
//
// Dialog
//

IDD_PARSEURL_DIALOG DIALOGEX 0, 0, 241, 210
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | 
                      WS_SYSMENU
EXSTYLE WS_EX_APPWINDOW
CAPTION "ParseURL"
FONT 8, "MS Sans Serif"
BEGIN
  DEFPUSHBUTTON   "OK",IDOK,184,183,50,14

  EDITTEXT  IDC_EDIT_URL_ADDRESS,7,27,227,15, ES_AUTOHSCROLL
  LTEXT     "URL Address",IDC_STATIC,7,15,43,8
  EDITTEXT  IDC_EDIT_SERVICE_TYPE,7,73,227,15,ES_AUTOHSCROLL | 
                                              ES_READONLY
  LTEXT     "Service type",IDC_STATIC,7,61,40,8
  EDITTEXT  IDC_EDIT_SERVER_NAME,7,110,227,15,ES_AUTOHSCROLL | 
                                              ES_READONLY
  LTEXT     "Server name",IDC_STATIC,7,97,41,8
  EDITTEXT  IDC_EDIT_OBJECT_NAME,7,147,227,15,ES_AUTOHSCROLL | 
                                              ES_READONLY
  LTEXT     "Object name",IDC_STATIC,7,135,41,8
  EDITTEXT  IDC_EDIT_PORT_NUMBER,7,182,52,15, ES_AUTOHSCROLL | 
                                              ES_READONLY
  LTEXT     "Port number",IDC_STATIC,7,170,39,8

  PUSHBUTTON      "Convert",IDC_BUTTON_CONVERT,115,183,50,14
END

Все идентификаторы, которые создаются автоматически во время редактирования ресурсов приложения, в том числе диалоговой панели IDD_PARSEURL_DIALOG, записываются в файле resource.h. Исходный текст этого файла мы привели в листинге 1.2.

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


//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by ParseURL.rc
//
#define IDM_ABOUTBOX                    0x0010
#define IDD_ABOUTBOX                    100
#define IDS_ABOUTBOX                    101
#define IDD_PARSEURL_DIALOG             102
#define IDR_MAINFRAME                   128
#define IDC_EDIT_URL_ADDRESS            1000
#define IDC_EDIT_SERVICE_TYPE           1001
#define IDC_EDIT_SERVER_NAME            1002
#define IDC_EDIT_OBJECT_NAME            1003
#define IDC_EDIT_PORT_NUMBER            1004
#define IDC_BUTTON_CONVERT              1005

// Next default values for new objects
// 
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE        129
#define _APS_NEXT_COMMAND_VALUE         32771
#define _APS_NEXT_CONTROL_VALUE         1006
#define _APS_NEXT_SYMED_VALUE           101
#endif
#endif

После того, как вы завершите подготовку диалоговой панели IDD_PARSEURL_DIALOG, запустите MFC ClassWizard. С его помощью мы привяжем к полям редактирования диалоговой панели новые элементы данных класса CParseURLDlg.

В диалоговой панели MFC ClassWizard перейдите на страницу Member Variables. Выберите в поле Class name имя класса CParseURLDlg и добавьте к нему с помощью кнопки Add Variable пять переменных, привязав их к полям ввода. К полю IDC_EDIT_URL_ADDRESS привяжите переменную m_UrlAddress, к IDC_EDIT_SERVICE_TYPE - m_ServiceType, IDC_EDIT_SERVER_NAME - m_ServerName и к IDC_EDIT_PORT_NUMBER - m_PortNumber. В качестве типа переменных выберите для всех них класс CString. Тогда используя механизм DDX вы легко сможете обмениваться данными между полями редактирования и соответствующими строками.

В исходных текстах приложения MFC ClassWizard модифицирует конструктор и метод DoDataExchange класса CParseURLDlg. В конструкторе класса CParseURLDlg добавляется программный код, выполняющий инициализацию строк, привязанных к полям редактирования диалоговой панели. Как видно из листинга 1.3, соответствующие команды добавляются внутри блока AFX_DATA_INIT.

Листинг 1.3. Фрагмент файла Parse.cpp, конструктор класса CParseURLDlg


CParseURLDlg::CParseURLDlg(CWnd* pParent /*=NULL*/)
   : CDialog(CParseURLDlg::IDD, pParent)
{
   //{{AFX_DATA_INIT(CParseURLDlg)
   m_ObjectName = _T("");
   m_PortNumber = _T("");
   m_ServerName = _T("");
   m_ServiceType = _T("");
   m_UrlAddress = _T("");
   //}}AFX_DATA_INIT

   m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

К методу DoDataExchange класса CParseURLDlg MFC ClassWizard добавляет методы DDX_Text, фактически осуществляющие обмен данными между полями редактирования диалоговой панели и соответствующими текстовыми строками. Мы привели фрагмент файла Parse.cpp с определением метода DoDataExchange в листинге 1.4.

Листинг 1.4. Фрагмент файла Parse.cpp, метод DoDataExchange класса CParseURLDlg

void CParseURLDlg::DoDataExchange(CDataExchange* pDX)


void CParseURLDlg::DoDataExchange(CDataExchange* pDX)
{
   CDialog::DoDataExchange(pDX);
   //{{AFX_DATA_MAP(CParseURLDlg)
   DDX_Text(pDX, IDC_EDIT_OBJECT_NAME, m_ObjectName);
   DDX_Text(pDX, IDC_EDIT_PORT_NUMBER, m_PortNumber);
   DDX_Text(pDX, IDC_EDIT_SERVER_NAME, m_ServerName);
   DDX_Text(pDX, IDC_EDIT_SERVICE_TYPE, m_ServiceType);
   DDX_Text(pDX, IDC_EDIT_URL_ADDRESS, m_UrlAddress);
   //}}AFX_DATA_MAP
}

Мы разместили на диалоговой панели IDD_PARSEURL_DIALOG кнопку Convert. Еще раз воспользуйтесь MFC ClassWizard и добавьте к классу CParseURLDlg обработчик сообщений от этой кнопки. Он будет вызываться когда пользователь будет нажимать на кнопку. MFC ClassWizard предложит вам назвать соответствующий метод именем OnButtonConvert. Согласитесь с этим предложением и в таблице сообщений класса CParseURLDlg появится новая макрокоманда:


BEGIN_MESSAGE_MAP(CParseURLDlg, CDialog)
   //{{AFX_MSG_MAP(CParseURLDlg)
   . . .
   ON_BN_CLICKED(IDC_BUTTON_CONVERT, OnButtonConvert)
   //}}AFX_MSG_MAP
END_MESSAGE_MAP()

Кроме того, в определении класса CParseURLDlg будет добавлено описание метода OnButtonConvert. Мы привели определение класса CParseURLDlg в листинге 1.5.

Листинг 1.5. Фрагмент файла Parse.h, определение класса CParseURLDlg


class CParseURLDlg : public CDialog
{
// Construction
public:
   CParseURLDlg(CWnd* pParent = NULL);   

// Dialog Data
   //{{AFX_DATA(CParseURLDlg)
   enum { IDD = IDD_PARSEURL_DIALOG };
   CString   m_ObjectName;
   CString   m_PortNumber;
   CString   m_ServerName;
   CString   m_ServiceType;
   CString   m_UrlAddress;
   //}}AFX_DATA

   // ClassWizard generated virtual function overrides
   //{{AFX_VIRTUAL(CParseURLDlg)
   protected:
   virtual void DoDataExchange(CDataExchange* pDX);   
   //}}AFX_VIRTUAL

// Implementation
protected:
   HICON m_hIcon;

   // Generated message map functions
   //{{AFX_MSG(CParseURLDlg)
   virtual BOOL OnInitDialog();
   afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
   afx_msg void OnPaint();
   afx_msg HCURSOR OnQueryDragIcon();
   afx_msg void OnButtonConvert();
   //}}AFX_MSG
   DECLARE_MESSAGE_MAP()
};

Определение метода OnButtonConvert размещается в файле Parse.cpp вместе с остальными методами класса CParseURLDlg. MFC ClassWizard создает только шаблон метода, который не выполняет никаких действий. Вы должны самостоятельно доработать метод OnButtonConvert, загрузив его в текстовый редактор Microsoft Visual C++. В листинге 1.6 мы привели фрагменты файла Parse.cpp с определением метода OnButtonConvert класса CParseURLDlg.

Листинг 1.6. Фрагмент файла Parse.cpp, метод OnButtonConvert класса CParseURLDlg


void CParseURLDlg::OnButtonConvert() 
{
   // Получаем адрес, введенный в диалоговой панели
   UpdateData(TRUE);

   CString sServer;     // Имя сервера
   CString sObject;     // Имя объекта (с каталогами)
   INTERNET_PORT nPort; // Номер порта TCP/IP
   DWORD dwServiceType; // Тип сервиса или протокола

   // Разбираем адрес URL, записанный в строке m_UrlAddress
   if (!AfxParseURL(m_UrlAddress, dwServiceType, m_ServerName, 
                    m_ObjectName, nPort))
   {
      AfxMessageBox("AfxParseURL Error");

      m_ObjectName = "";
      m_PortNumber = "";
      m_ServerName = "";
      m_ServiceType = "";
   }
   else
   {
      switch(dwServiceType)
      {
         case AFX_INET_SERVICE_FTP:
            m_ServiceType = "AFX_INET_SERVICE_FTP";
            break;

         case AFX_INET_SERVICE_HTTP:
            m_ServiceType = "AFX_INET_SERVICE_HTTP";
            break;

         case AFX_INET_SERVICE_GOPHER:
            m_ServiceType = "AFX_INET_SERVICE_GOPHER";
            break;
            
         case AFX_INET_SERVICE_FILE:
            m_ServiceType = "AFX_INET_SERVICE_FILE";
            break;         

         default:
            m_ServiceType.Format("%d", dwServiceType);
      }
         
      m_PortNumber.Format("%d", nPort);
   }
   // Выводим полученные значения в диалоговой панелли
   UpdateData(FALSE);
}

Для наглядности во время запуска приложения мы выполняем инициализацию поля ввода адреса URL, записывая в него строку http://host:80/bin/programm/main.htm. Этот адрес содержит все возможные элементы - тип протокола http, имя сервера host, номер порта 80, а также путь и имя объекта /bin/programm/main.htm, на который и указывает данный адрес URL.

Соответствующий программный код, инициализирующий строку адреса надо добавить к методу OnInitDialog класса CParseURLDlg. Мы привели исходный текст этого метода в листинге 1.7.

Листинг 1.7. Фрагмент файла Parse.cpp, метод OnInitDialog класса CParseURLDlg


BOOL CParseURLDlg::OnInitDialog()
{
   CDialog::OnInitDialog();

   // . . .

   SetIcon(m_hIcon, TRUE);         // Set big icon
   SetIcon(m_hIcon, FALSE);      // Set small icon
   
   // Инициализируем поле адреса URL 
   m_UrlAddress = "http://host:80/bin/programm/main.htm";
   // Отображаем строку m_UrlAddress в диалоговой панели
   UpdateData(FALSE);
   
   return TRUE;
}

Теперь в исходный текст приложения внесены все необходимые изменения. Вы можете построить проект и запустить приложение. На экране появится диалоговая панель ParseURL, внешний вид которой мы уже приводили ранее на рисунке 4.4.

Изначально в поле URL Address отображается адрес http://host:80/bin/programm/main.htm, который мы взяли в качестве примера. Вы можете изменить его по своему усмотрению - поменять тип протокола обмена, имя сервера, путь и имя объекта и номер порта. Вы даже можете попытаться ввести неправильный адрес, не соответствующий формату адресов URL.

Нажмите кнопку Convert. Приложение разберет введенный вами адрес URL на составные части и выведет их в других полях диалоговой панели. Так в поле Service type будет показан тип сервиса (протокола обмена). Это может быть либо текстовая строка, либо число. В поле Server name вы увидите имя сервера, а в поле Object name - имя объекта, включая путь. Если в адрес URL включен номер порта, то он будет показан в поле Port number.

Если вы введете в поле адреса URL неправильную строку, то на экране появится сообщение об ошибке, а поля Service type, Server name, Object name и Port number будут очищены.

Когда вы закончите экспериментировать с разбором различных адресов URL завершите приложение. Для этого достаточно нажать кнопку OK.

Как работает приложение ParseURL

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

Сразу после запуска, приложение ParseURL создает диалоговую панель IDD_PARSEURL_DIALOG и отображает ее на экране. Управление этой диалоговой панелью осуществляет класс CParseURLDlg, определенный в нашем приложении.

Конструктор класса CParseURLDlg инициализирует строки m_ObjectName, m_PortNumber, m_ServiceType, m_UrlAddress. Несколько позже, когда будет вызван метод OnInitDialog, мы запишем в строку m_UrlAddress пример адреса URL. Чтобы вывести этот адрес на экран, метод OnInitDialog вызывает метод UpdateData с параметром FALSE:


UpdateData(FALSE);

Когда пользователь нажимает кнопку Convert, командное сообщение от нее попадает в таблицу сообщений класса CParseURLDlg и для его обработки вызывается метод OnButtonConvert:


ON_BN_CLICKED(IDC_BUTTON_CONVERT, OnButtonConvert)

Метод OnButtonConvert опять вызывает метод UpdateData, но на этот раз в качестве параметра ему передается значение TRUE. Этот метод считывает данные из органов управления диалоговой панели и записывает их в соответствующие переменные. Вызов этого метода необходим, так как пользователь мог изменить адрес URL в поле URL Address диалоговой панели приложения:


UpdateData(TRUE);

Теперь в строке m_UrlAddress записан адрес URL, который необходимо разобрать на составные части. Для этого вызываем глобальную функцию AfxParseURL, передавая ей строку m_UrlAddress для разбора и переменные dwServiceType, m_ServerName, m_ObjectName, nPort. В них будет записан результат разбора адреса:


if (!AfxParseURL(m_UrlAddress, dwServiceType, m_ServerName, 
                    m_ObjectName, nPort))
{
}

Обратите внимание, что имя сервера и имя объекта записываются непосредственно в переменные m_ServerName и m_ObjectName, привязанные к полям диалоговой панели. А вот тип сервиса (тип протокола) и номер порта записываются во временные переменные nPort и dwServiceType, так как их тип не соответствует строковому:


INTERNET_PORT nPort;
DWORD dwServiceType;

Если в строке m_UrlAddress записан неправильный адрес, то функция AfxParseURL возвращает нулевое значение. В этом случае мы выводим сообщение об ошибке и сбрасываем строки m_ObjectName, m_PortNumber, m_ServerName, m_ServiceType:


AfxMessageBox("AfxParseURL Error");

m_ObjectName = "";
m_PortNumber = "";
m_ServerName = "";
m_ServiceType = "";

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


switch(dwServiceType)
{
   case AFX_INET_SERVICE_FTP:
      m_ServiceType = "AFX_INET_SERVICE_FTP";
      break;

   case AFX_INET_SERVICE_HTTP:
      m_ServiceType = "AFX_INET_SERVICE_HTTP";
      break;

   case AFX_INET_SERVICE_GOPHER:
      m_ServiceType = "AFX_INET_SERVICE_GOPHER";
      break;
            
   case AFX_INET_SERVICE_FILE:
      m_ServiceType = "AFX_INET_SERVICE_FILE";
      break;         

   default:
      // Формируем строку из значения переменной dwServiceType
      m_ServiceType.Format("%d", dwServiceType);
}

Если вы указали другой тип сервиса мы записываем в строку m_PortNumber соответствующее числовое значение. Для этого мы используем метод Format класса CString:


m_PortNumber.Format("%d", nPort);

¨     Метод Format класса CString очень удобен для записи в строку форматированных значений каких-либо переменных. По своему назначению и формату вызова данный метод напоминает хорошо известную вам функцию sprintf. Только в функции sprintf строка, в которую записываются форматированные данные, определяется первым параметром, а метод Format вызывается для объекта представляющего эту строку.

После того, как все переменные, привязанные к полям редактирования диалоговой панели, заполнены, вызываем метод UpdateData с параметром FALSE. Он отображает их содержимое в диалоговой панели:


UpdateData(FALSE);
[Назад] [Содеожание] [Дальше]