faqs.org.ru

 Главная > Программирование > Языки Pascal/Delphi >

Delphi MultiTier FAQ


--- added in v6.0
Q>:
После того, как я использовал правый щелчок мыши для создания
функции-провайдера, как мне снова выполнить команду контекстного меню
"Export from Table"?
A>:
Как только Вы экспортировали интерфейс провайдера, эта команда контекстного
меню перестает быть видимой. Чтобы снова включить ее, Вы должны удалить
ассоциированное свойство в Редакторе Библиотеки Типов, и затем нажать кнопку
обновления информации в Редакторе Библиотеки Типов (Type Library Editors
Refresh button). Вы могли бы также удалить точку вхождения "Get_XXX" в
исходном тексте RemoteDataModule.

(Inprise (ex-Borland) FAQ N584, переведен Акжаном Абдулиным)
.

Q>:
Как я могу избавиться от "зарегистрированного" имени сервера, если я не
хочу использовать его далее?
A>:
Запустите исполняемый файл сервера с ключом /UNREGSERVER:

MYSERVER.EXE /UNREGSERVER

Это обычный путь разрегистрации саморегистрирующего сервера автоматизации OLE.

(Inprise (ex-Borland) FAQ N594, переведен Акжаном Абдулиным)
.

Q>:
Как осуществить минимальный тест на корректность глобального идентификатора
(GUID), и интерфейсы, унаследованные от IDispatch (и, следовательно,
поддерживающих методы автоматизации)?
A>:
Вызовите CreateRemoteComObject, передав GUID интерфейса и имя компьютера, к
которому Вы пытаетесь подключиться. Если функция вернет ошибку, то наличествует
проблема сервера, иначе возможная проблема относится к клиенту.

const
  MyGUID = '{444...111}';  //Whatever the guid is...

var
  Unk: IUnknown;
  Disp: IDispatch;

begin

  { Make sure this line works correctly }
  Unk := CreateRemoteComObject('server1',
    StringToGUID(MyGUID));

  { If it does, then cast it to a IDispatch }
  Disp := Unk as IDispatch;

end;

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

(Inprise (ex-Borland) FAQ N681, переведен Акжаном Абдулиным)
.

--- added in v5.1
Q>:
Почему мои ISAPI-ориентированные библиотеки, созданные в Delphi 3, не могут
обрабатывать несколько соединений?
A>:
Волшебник по созданию ISAPI DLL в Delphi 3 создает полностью безопасную
многопоточную библиотеку, но не выставляет флаг, говорящий приложению,
что эта библиотека в этом отношении безопасна.
Это легко исправить, просто добавив строчку:

 IsMultiThread := TRUE;

первой строкой в Вашем блоке begin-end файла проекта (DPR).

(Borland FAQ N715, переведен Акжаном Абдулиным)
.

Q>:
Как я могу выбрать на клиента только часть данных с определенной позиции
из набора данных на сервере?
A>:
Наиболее приемлемым является использование TQuery
и Provider.SetParams.
Но также Вы можете сделать это иначе:

Сперва на клиенте Вам нужно считать с сервера только метаданные для
набора данных. Это можно сделать, установив PacketRecords в 0, и затем вызвав Open.
Затем Вы должны вызвать метод сервера (Вы должны определить этот метод на сервере),
который спозиционирует курсор на первую нужную запись.
И, наконец, установите PacketRecords в нужное значение, большее нуля,
и вызовите GetNextPacket.

(Borland FAQ N657, переведен Акжаном Абдулиным)
.

Q>:
Когда я применяю ApplyApdates на ClientDataSet, на серверной стороне не
срабатывает событие OnNewRecord для оригинального набора данных.
Как это исправить?
A>:
Никак. Эти обновления идут прямо через BDE, а не через компонент набора данных.

(Borland FAQ N599, переведен Акжаном Абдулиным)

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

Q>:
В чем разница между сокетами, DCOM и ELE Enterprise при использовании их
в качестве транспорта?
A>:
Sockets (TCP/IP):
 - на клиентах и сервере требуется наличие стека TCP/IP;
 - не требуется дополнительной настройки клиентов;
DCOM:
 - на клиентах и серверах требуется наличие DCOM
(входит в состав Windows NT 4.0, для Windows'95 доступен как опция)
 - требуется настройка клиентов (DCOM Configuration Utility - DCOMCNFG.EXE);
 - встроенная поддержка модели безопасности Windows NT;
 - поддержка обратных вызовов (методов).
OLE Enterprise:
 - на клиентах и серверах требуется наличие OLE Enterprise;
 - требуется настройка клиентов;
 - поддержка обратных вызовов (методов).

(Borland FAQ N596, переведен и видоизменен Акжаном Абдулиным)
.

Q>:
Предположим, что пользователь изменил строковое поле в Null.
Как тогда я в обработчике OnUpdateData смогу определить,
изменилось ли это поле на строку Null, или поле просто не было изменено?
A>:
Используйте свойство NewValue класса TField при чтении второй записи
(той, которая содержит изменения). Если возвращаемое значение (variant)
пуст или неназначен, тогда поле не было модифицировано.
Здесь немного иллюстрирующего кода:

var
  NewVal: Variant;

begin
  NewVal := DataSet.FieldByName('MyStrField').NewValue;
  if VarIsEmpty(NewVal) then
    ShowMessage('Field was not edited')
  else if VarIsNull(NewVal) then
    ShowMessage('Field was blanked out')
  else
    ShowMessage('New Field Value: ' + String(NewVal));
end;

Если Вы взглянете на исходники формы RecError (в репозитории), то Вы увидите,
как она использует эту информацию для вывода строки '<Unchanged>' при показе
ошибок reconcile.

На сервере Вы добавляете ограничения уровня записи, используя
свойство Constraints Вашего TQuery/TTable или ограничения уровня поля,
используя постоянные обьекты TField (с помощью FieldsEditor либо на
CustomConstraint, либо ImportedConstraint).

Если Вы используете ограничения уровня поля, они вступают в силу, когда данные
отправляются в поле (например, когда Вы уходите из органа управления, связанного
с этим полем (типа TDBEdit)).

(Borland FAQ N654, переведен Акжаном Абдулиным)
.

Q>:
Что я получаю от наличия ConstraintBroker (брокера ограничений)?
A>:
ConstraintBroker позволяет Вам включать проверки на ограничения
в данные. Это означает, что когда Вы запрашиваете данные,
Вы получаете правила. Эти правила автоматически без дополнительного кода входят в силу
Поскольку это происходит без единой строчки кода, то Вам не требуется переписывать или обновлять приложение
каждый раз при изменении правил.
Фактически это простое решение задачи обновления клиентского приложения
без выхода из него.
Каждое приложение, использующее ConstraintBroker, автоматически получает
это качество.

(Borland FAQ N655, переведен Акжаном Абдулиным)
.

Q>:
Нужны ли мне формы в сервере приложений?
A>:
Да. Необязательно, чтобы они были видимы, но должна присутствовать хотя бы одна.
Чтобы сделать главную форму невидимой, установите

Application.ShowMainForm := False

в файле проекта.
Пример:

begin
  Application.ShowMainForm := False;
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.

(Borland FAQ N583, переведен Акжаном Абдулиным)
.

Q>:
Как достучаться до методов сервера приложений из TClientDataSet?
A>:
Вот так:
RemoteServer.AppServer.MyMethod.

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

(Borland FAQ N598, переведен Акжаном Абдулиным)
.

Q>:
Я включил dbclient.dll в секцию "additional files" опций распространения по web,
но этот файл никогда не загружается на клиент. Как это исправить?
A>:
Ваш INF-файл должен включать в себя строки наподобие:

============
[Add.Code]

dbclient.dll=dbclient.dll

[dbclient.dll]

file=http://yoursite.com/dbclient.cab

clsid={9E8D2F81-591C-11D0-BF52-0020AF32BD64}

RegisterServer=yes

FileVersion=4,0,0,36
============

Замените "yoursite" Вашим HTTP-адресом, где находится cab-файл.
FileVersion - это версия ффайла в Вашем cab-файле
your CAB file (check the version information of DBCLIENT
FileVersion - это версия файла в Вашем cab-файле
(проверьте информацию о версии DBCLIENT, чтобы быть уверенным в
соответствии).

Убедитесь, что FileVersion относится к версии Вашего DBCLIENT.DLL.

Вы можете положить dbclient.dll в cab-файл, используя утилиту CABARC,
которую Вы найдете в папке delphi\bin.

Примерная команда вызова CABARC может выглядеть примерно так:

CABARC N DBCLIENT.CAB DBCLIENT.DLL

(Borland FAQ N685, переведен Акжаном Абдулиным)
.

--- added in v5.0
Q>:
Как я могу определить доступные сервера приложений на этой машине
через Registry?
A>:
Прочитайте ключ под HKEY_CLASSES_ROOT\CLSID\*, просматривая его насчет
ключей, которые имеют подключ "Borland DataBroker".
Эти вхождения и являются серверами приложений.

Ниже пример, который загружает имена доступных серверов приложений в Listbox:

procedure TForm1.FormCreate(Sender: TObject);
var

uses Registry;
  I: integer;
  TempList: TStringList;
begin
  TempList := TStringList.Create;
  try
    with TRegistry.Create do
    try
      RootKey := HKEY_CLASSES_ROOT;
      if OpenKey('CLSID', False) then
        GetKeyNames(TempList);
      CloseKey;
      for I := 1 to TempList.Count - 1 do
        if KeyExists('CLSID\' + TempList[I]
          + '\Borland DataBroker') then
        begin
          if OpenKey('CLSID\' + TempList[I] + '\ProgID', False)
            then begin
              Listbox1.Items.Add(ReadString(''));
              CloseKey;
            end;
        end;
    finally
      Free;
    end;
  finally
    TempList.Free;
  end;
end;

(Borland FAQ N587, переведен Акжаном Абдулиным)
.

Q>:
Как передать UserName и Password в удаленный модуль данных (remote datamodule)?
A>:
В Удаленный Модуль Данных бросьте компонент TDatabase, затем добавьте процедуру
автоматизации (пункт главного меню Edit | Add To Interface) для Login.
Убедитесь, что свойство HandleShared компонента TDatabase установлено в True.

procedure Login(UserName, Password: WideString);
begin
  { DB = TDatabase }

  { Something unique between clients }
  DB.DatabaseName := UserName + 'DB';
  DB.Params.Values['USER NAME'] := UserName;
  DB.Params.Values['PASSWORD'] := Password;
  DB.Open;
end;

После того, как Вы создали этот метод автоматизации, Вы можете
вызывать его с помощью:

  RemoteServer1.AppServer.Login('USERNAME','PASSWORD');

(Borland FAQ N588, переведен Акжаном Абдулиным)
.

Q>:
Как можно использовать TClientDataSet в локальном приложении с таблицами
Paradox, без использования компонент TProvider и TRemoteServer?
A>:
Вы не сможете отделаться от Провайдера (хотя бросать его на форму/модуль
данных не придется), но Вы сможете использовать TClientDataSet
в одно-точечном (single-tier) приложении. Для того, чтобы открыть
Client DataSet, Вы должны назначить Провайдера Данных вручную.

{ CDS = TClientDataSet }
{ Table1 = TTable }
CDS.Provider := Table1.Provider;
CDS.Open;

Также Вы должны включить модуль BDEProv в предложение Uses.

(Borland FAQ N885, переведен Акжаном Абдулиным)
.

Q>:
Как работать с новыми, своими интерфейсами в RemoteDateModule?
A>:
В редакторе библиотеки типов (typelib) Вы можете добавить свои
интерфейсы и сделать их членами оригинального coClass.
После этого Вы можете обращаться к этим интерфейсам,
используя следующий синтаксис:

(IDispatch(RemoteServer.AppServer) as IAnother)

Необходимо заметить, что это будет работать только, если Вы используете
DCOM как транспорт.

(Borland FAQ N886, переведен Акжаном Абдулиным)
.

Вернуться в раздел "Языки Pascal/Delphi" - Обсудить эту статью на Форуме
Главная - Поиск по сайту - О проекте - Форум - Обратная связь

© faqs.org.ru