Sources
Delphi Russian Knowledge Base
DRKB - это самая большая и удобная в использовании база знаний по Дельфи в рунете, составленная Виталием Невзоровым

WinWord через DDE

01.01.2007
Кто-нибудь пробовал использовать WinWord в качестве DDE-сервера? Поделитесь результатами, если они, конечно, успешны.

Опыт 1

Пара других пользователей также задавала на этой неделе аналогичный вопрос, но у меня не было доступа к машине, где установлена Delphi. К несчастью я затер их адреса, но надеюсь они увидят это сообщение. Нижеприведенный код является "экстрактом" моей технологии, которую я успешно применил для создания DDEPokes и DDEExecutes с WinWord в качестве сервера. Обратите внимание на то, что я использовал методы DDE, требующие PChar вместо строк, поскольку строки имеют дополнительные символы и при DDE-преобразованиях WinWord'у плохеет.

function TfrmLetter.CreateLetter: Boolean;
var
  szCommand
: array[0..2048] of char;
  sCommand
: string;
 
BmkNames: array[0..3] of string;
  idx
: ShortInt;
  DDEOK
: Boolean;
 
Buffer, ParMark: PChar;
 
BufSize: Integer;
  hWord
: hWnd;
begin
 
CreateLetter := False;
  DDEOK
:= True; {Флаг проверки результатов DDE-операций}
 
DDEClient.SetLink('winword', WordDoc);
   
{WordDoc содержит имя документа winword, необходимого для связи}
 
{DDEClient - элемент управления DDE client}
 
if DDEClient.OpenLink = False then
   
Exit;
 
  hWord
:= FindWindow('OpusApp', nil);
 
LockWindowUpdate(hWord); {Блокируем обновление экрана winword}
 
 
{Убедитесь, что нужный документ является активным окном Word}
  sCommand
:= '[If FileName$() <> "' + WordDoc + '" Then]';
  sCommand
:= sCommand + '[While (idx < CountWindows()) and (FileName$() <> "';
  sCommand
:= sCommand + WordDoc + '")][NextWindow][idx = idx + 1]';
  sCommand
:= sCommand + '[Wend][Activate WindowName$()][End If]';
 
StrPLCopy(szCommand, sCommand, SizeOf(szCommand) - 1);
  DDEOK
:= DDEOK and DDEClient.ExecuteMacro(szCommand, False);
 
 
{Сбрасываем баннер}
  sCommand
:= '[EditGoto "Banner"]';
 
if GetWinwordVersion = 2 then
   
{GetWinword - простая функция пользователя, использующая GetModuleHandle
   
для определения номера версии запущенного Word: Word 2 или Word 6}
    sCommand
:= sCommand + '[EditGlossary "Banner"]'
 
else if GetWinwordVersion = 6 then
    sCommand
:= sCommand + '[EditAutoText "Banner"]';
  sCommand
:= sCommand + '[EditGoto "Date"][UpdateFields][LockFields]';
 
StrPLCopy(szCommand, sCommand, SizeOf(szCommand) - 1);
  DDEOK
:= DDEOK and DDEClient.ExecuteMacro(szCommand, False);
 
Application.ProcessMessages;
 
 
{Вставляем Имя отправителя, Прямой номер абонента и пр.}
 
BmkNames[0] := 'DirectDialNumber';
 
BmkNames[1] := 'EMailAddress';
 
BmkNames[2] := 'AuthorName';
 
BmkNames[3] := 'Personal';
 
for idx := 0 to 3 do
   
if CheckInclude[idx].Checked = True then
   
begin
     
BufSize := TextInclude[idx].GetTextLen;
     
Inc(BufSize);
     
GetMem(Buffer, BufSize);
     
TextInclude[idx].GetTextBuf(Buffer, BufSize);
      DDEOK
:= DDEOK and DDEClient.PokeData(BmkNames[idx], Buffer);
     
FreeMem(Buffer, BufSize);
   
end
   
else
      DDEOK
:= DDEOK and DDEClient.PokeData(BmkNames[idx] + '2', '');

и так далее.

Опыт 2

Автор: Jean Yves

Вот еще очень простой пример DDE-связи с WinWord 6. Это работает.

В Word вы должны иметь заранее созданный файл (в нашем примере DDETEST.DOC) и закладку с именем "Bm1".

unit Unit1;
 
interface
 
uses
 
 
SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
 
Forms, Dialogs, StdCtrls, DdeMan;
 
type
 
  TForm1
= class(TForm)
   
DdeConv: TDdeClientConv;
   
Word: TButton;
    procedure
WordClick(Sender: TObject);
 
private
   
{ Private-declarations }
 
public
   
{ Public-declarations }
 
end;
 
 
{  Свойства DdeConv:       }
 
{  ConnectMode : ddeManual }
 
{  DdeService : [None]     }
 
{  DdeTopic    : [None]    }
 
{  FormatChars : False     }
 
{  Name        : DdeConv   }
 
var
 
  Form1
: TForm1;
 
implementation
 
{$R *.DFM}
 
procedure TForm1
.WordClick(Sender: TObject);
begin
 
 
if DdeConv.SetLink('WINWORD', 'D:\WINWORD\DDETEST') and
   
DdeConv.OpenLink then
 
begin
   
ShowMessage('Установлена связь с WinWord !')
     
{ убедимся в наличии соединения }
   
DdeConv.PokeData('Bm1', 'Данные из Delphi !')
     
{ вставляем 'Данные из Delphi' в документ word }
   
DdeConv.CloseLink;
 
end;
end;
 
end.

Но только сделав это хотя бы раз своими руками, вы сможете разобраться в этой технологии

https://delphiworld.narod.ru/

DelphiWorld 6.0