Опыт 1
Пара других пользователей также задавала на этой неделе аналогичный вопрос, но у меня не было доступа к машине, где установлена Delphi. К несчастью я затер их адреса, но надеюсь они увидят это сообщение. Нижеприведенный код является "экстрактом" моей технологии, которую я успешно применил для создания DDEPokes и DDEExecutes с WinWord в качестве сервера. Обратите внимание на то, что я использовал методы DDE, требующие PChar вместо строк, поскольку строки имеют дополнительные символы и при DDE-преобразованиях WinWord'у плохеет.
function TfrmLetter.CreateLetter: Boolean;varszCommand: Array[0..2048] of char;sCommand: String;BmkNames: array[0..3] of String;idx: ShortInt;DDEOK: Boolean;Buffer, ParMark: PChar;BufSize: Integer;hWord: hWnd;beginCreateLetter := 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 thensCommand := 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 doif CheckInclude[idx].Checked = True thenbeginBufSize := TextInclude[idx].GetTextLen;Inc(BufSize);GetMem(Buffer, BufSize);TextInclude[idx].GetTextBuf(Buffer,BufSize);DDEOK := DDEOK and DDEClient.PokeData(BmkNames[idx], Buffer);FreeMem(Buffer, BufSize);endelseDDEOK := DDEOK and DDEClient.PokeData(BmkNames[idx] + '2', ''); |
{------------------- полный исходный код --------------------------} 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' ) andDdeConv.OpenLink thenbeginShowMessage( 'Установлена связь с WinWord !' ) { убедимся в наличии соединения }DdeConv.PokeData( 'Bm1', 'Данные из Delphi !' ) { вставляем 'Данные из Delphi' в документ word }DdeConv.CloseLink ;end ;end; end. {------------------- конец исходного кода --------------------} |