⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ahword97.pas

📁 一个好的word的控件
💻 PAS
📖 第 1 页 / 共 4 页
字号:
unit AHWord97;

interface
                              
{
   These objects are based on the TWordObject demo in the directory
   C:\Program Files\Borland\Delphi4\Demos\Activex\Oleauto\Word8

   This is the Delphi 4 version

	 Feel free to add to this unit. My only condition is that you e-mail me your additions
  and put in small comments indicating updates/changes (eg '<- added by JB 1/3/99')
  and large comments where things are not obvious.

	 You are free to use this unit in any program, even commercial (although I'd like to know
  about where it is being used). You are not allowed to sell this, or a variation on it, as
  that would be dishonest. If you give away your source code in a program and use this unit,
  please keep this header so bugs/bug-fixes come to me.

  Dr Allan Harkness
  e-mail A.Harkness@bio.gla.ac.uk
  Scotland

  History: see Word97 Hx.txt
  Version 1.7
}

uses
  {$IFDEF VER130} Word97, {$ELSE} Word_TLB, {$ENDIF}
  Windows, Classes, SysUtils, ActiveX, OleCtrls, Forms;


const
  wdTrue : Integer = -1;
  wdFalse : Integer = 0;

type
  TWordDoc = class;
  TWordApp = class;

  TWordDocEvent = procedure (WordApp: TWordApp; WordDoc : TWordDoc) of object;

  TWordEventSink = class(TInterfacedObject, IUnknown, IDispatch)
  private
    FWordApp : TWordApp;
    FAppDispatch: IDispatch;
    FDocDispatch: IDispatch;
    FAppDispIntfIID: TGUID;
    FDocDispIntfIID: TGUID;
    FAppConnection: Integer;
    FDocConnection: Integer;
  protected
    { IUnknown }
    function QueryInterface(const IID: TGUID; out Obj): HRESULT; stdcall;
    function _AddRef: Integer; stdcall;
    function _Release: Integer; stdcall;
    { IDispatch }
    function GetTypeInfoCount(out Count: Integer): HRESULT; stdcall;
    function GetTypeInfo(Index, LocaleID: Integer; out TypeInfo): HRESULT; stdcall;
    function GetIDsOfNames(const IID: TGUID; Names: Pointer;
      NameCount, LocaleID: Integer; DispIDs: Pointer): HRESULT; stdcall;
    function Invoke(DispID: Integer; const IID: TGUID; LocaleID: Integer;
      Flags: Word; var Params; VarResult, ExcepInfo, ArgErr: Pointer): HRESULT; stdcall;
  public
    constructor Create(WordApp : TWordApp; AnAppDispatch: IDispatch; const AnAppDispIntfIID, ADocDispIntfIID: TGUID);
    destructor Destroy; override;
  end;

  TWordApp = class
  private
    FComApp : _Application;
    FComGlobal : _Global;
    FUsedExisting : Boolean;
    FEventSink : TWordEventSink;
    FOnQuit : TNotifyEvent;
    FOnChangeDocument : TWordDocEvent;
    FOnOpenDocument : TWordDocEvent;
    FOnPreCloseDocument : TNotifyEvent;
    FOnCloseDocument : TWordDocEvent;
    function GetCaption : String;
    procedure SetCaption(Value : String);
    function GetVisible : Boolean;
    procedure SetVisible(Value : Boolean);
    function GetScreenUpdating : Boolean;
    procedure SetScreenUpdating (Value : Boolean);
    function GetWindowState : TOleEnum;
    procedure SetWindowState (Value : TOleEnum);
    function GetDocument(Index : Integer) : TWordDoc;
    function GetNoOfDocuments : Integer;
    function GetOnQuit : TNotifyEvent;
    procedure SetOnQuit(Value : TNotifyEvent);
    function GetOnChangeDocument : TWordDocEvent;
    procedure SetOnChangeDocument(Value : TWordDocEvent);
    function GetOnOpenDocument: TWordDocEvent;
    procedure SetOnOpenDocument(Value : TWordDocEvent);
    function GetOnPreCloseDocument: TNotifyEvent;
    procedure SetOnPreCloseDocument(Value : TNotifyEvent);
    function GetOnCloseDocument: TWordDocEvent;
    procedure SetOnCloseDocument(Value : TWordDocEvent);
    procedure FreeDocumentsAndSink;
  protected
    FDocuments : TList;
    procedure RemoveDoc(Index : Integer);
    procedure QuitAppEvent;
    procedure PreCloseDocEvent;
    procedure SyncWithWord;
    procedure ChangeDocEvent;
  public
    constructor Create(UseExisting : Boolean = True; Sink : Boolean = True);
    constructor CreateFromOleObject(OleObject : OleVariant; Sink : Boolean = True);
    destructor Destroy; override;
    destructor CloseApp(oeSaveChanges: TOleEnum);

    function AddNewDoc(Template : String) : TWordDoc;
    function AddOpenDoc(DocName : String) : TWordDoc;
    function AddActiveDoc : TWordDoc;
    procedure CloseActiveDoc(oeSaveChanges: TOleEnum);
    procedure Move(oeUnit : TOleEnum = wdCharacter; Count : Integer = 1);
    procedure MoveEnd(oeUnit : TOleEnum = wdCharacter; Count : Integer = 1);
    procedure MoveStart(oeUnit : TOleEnum = wdCharacter; Count : Integer = 1);
    procedure MoveRight(oeUnit : TOleEnum = wdCharacter; Count : Integer = 1; Extend : TOleEnum = wdMove);
    procedure MoveLeft(oeUnit : TOleEnum = wdCharacter; Count : Integer = 1; Extend : TOleEnum = wdMove);
    procedure MoveUp(oeUnit : TOleEnum = wdLine; Count : Integer = 1; Extend : TOleEnum = wdMove);
    procedure MoveDown(oeUnit : TOleEnum = wdLine; Count : Integer = 1; Extend : TOleEnum = wdMove);
    procedure GotoBookmark(Bookmark : String);
    procedure GoTo_(oeWhat, oeWhich : TOleEnum; oeCount: Integer = 1; oeName: String = '');
    procedure GoToNext(oeWhat : TOleEnum);
    procedure GoToPrevious(oeWhat : TOleEnum);
    procedure UpdateActiveDocFields;
    Procedure RunMacro(MacroName : string);
    procedure ScreenRefresh;
    procedure Cut;
    procedure Copy;
    procedure Paste;
    procedure Activate;
    procedure InsertText(Text : String);
    procedure PrintActiveDoc;
    procedure SaveActiveDocAs(Filename : String);
    property Global : _Global read FComGlobal;
    property Application : _Application read FComApp;
    property UsedExisting : Boolean read FUsedExisting;
    property Caption : String read GetCaption write SetCaption;
    property Visible : Boolean read GetVisible write SetVisible;
    property ScreenUpdating : Boolean read GetScreenUpdating write SetScreenUpdating;
    property WindowState : TOleEnum read GetWindowState write SetWindowState;
    property Document [Index: Integer] : TWordDoc read GetDocument;
    property NoOfDocuments : Integer read GetNoOfDocuments;
    property OnQuit : TNotifyEvent read GetOnQuit write SetOnQuit;
    property OnChangeDocument : TWordDocEvent read GetOnChangeDocument write SetOnChangeDocument;
    property OnOpenDocument : TWordDocEvent read GetOnOpenDocument write SetOnOpenDocument;
    property OnPreCloseDocument : TNotifyEvent read GetOnPreCloseDocument write SetOnPreCloseDocument;
    property OnCloseDocument : TWordDocEvent read GetOnCloseDocument write SetOnCloseDocument;
  end;

  TWordRange = class;

  TWordDocMode = (wdmCreating, wdmExisting, wdmDestroying);

  TWordDoc = class
  private
    FComDoc : _Document;
    FWordApp : TWordApp;
    FFullname : String;
    FItemIndex : Integer;
    function GetActive : Boolean;
    procedure SetActive(Value : Boolean);
    function GetRange(Index : Integer) : TWordRange;
    function GetNoOfRanges : Integer;
    function GetNoOfBookMarks : Integer;
    function GetBookmarkByName (BookmarkName: String) : {$IFDEF VER130}Word97.Bookmark{$ELSE}Word_TLB.Bookmark{$ENDIF};
    function GetBookmarkByIndex(Index: Integer) : {$IFDEF VER130}Word97.Bookmark{$ELSE}Word_TLB.Bookmark{$ENDIF};
    procedure SetBuiltInProperty(Index : String; Const Value: Variant);
    function GetBuiltInProperty(Index : String) : Variant;
    procedure SetCustomProperty(Index : String; Const Value : Variant);
    function GetCustomProperty(Index : String) : Variant;
    procedure FreeRangesAndRemoveDoc;
    function GetAutoTextEntries : OleVariant;
  protected
    FMode : TWordDocMode;
    FRanges : TList;
    procedure RemoveRange(Index : Integer);
  public
    constructor CreateNewDoc(WordApp : TWordApp; Template : String);
    constructor CreateOpenDoc(WordApp : TWordApp; FileName : String);
    constructor CreateFromComDoc(WordApp : TWordApp; ComDoc : _Document);
    constructor CreateFromActiveDoc(WordApp : TWordApp);
    destructor Destroy; override;
    destructor CloseDoc(oeSaveChanges: TOleEnum);
    procedure Print;
    function AddRangeFromBookMark(BookmarkName : String) : TWordRange;
    function AddRangeFromSelection : TWordRange;
    function AddRangeFromDoc(iStart : Integer = 1; iEnd : Integer = 1) : TWordRange;
    function AddRangeFromRange(ComRange : Range) : TWordRange;
    function GoTo_(oeWhat, oeWhich : TOleEnum; oeCount: Integer = 1; oeName: String = '') : {$IFDEF VER130}Word97.Range{$ELSE}Word_TLB.Range{$ENDIF};
    function GoToNext(oeWhat : TOleEnum) : {$IFDEF VER130}Word97.Range{$ELSE}Word_TLB.Range{$ENDIF};
    function GoToPrevious(oeWhat : TOleEnum) : {$IFDEF VER130}Word97.Range{$ELSE}Word_TLB.Range{$ENDIF};
    function NoOfPages (IncludeFootnotesAndEndnotes : Boolean = False) : Integer;
    function NoOfWords (IncludeFootnotesAndEndnotes : Boolean = False) : Integer;
    procedure ReplaceBookmark (BookmarkName, ReplaceText : String; ReassignBookmark : Boolean = True);
    procedure DeleteRange(Index : Integer);
    function DocStillInWord : Boolean;
    procedure UpdateFields;
    procedure UpdateFullname;
    procedure SaveAs(Filename : String);
    property WordApp : TWordApp read FWordApp;
    property Document : _Document read FComDoc write FComDoc;
    property Fullname : String read FFullname;
    property Active : Boolean read GetActive write SetActive;
    property AutoTextEntries : OleVariant read GetAutoTextEntries;
    property Range [Index: Integer] : TWordRange read GetRange;
    property NoOfRanges : Integer read GetNoOfRanges;
    property BookmarkByIndex [Index: Integer] : Bookmark read GetBookmarkByIndex;
    property Bookmark [BookmarkName: String] : Bookmark read GetBookmarkByName;
    property NoOfBookmarks : Integer read GetNoOfBookmarks;
    property BuiltInProperty [Index : String] : Variant read GetBuiltInProperty write SetBuiltInProperty;
    property CustomProperty [Index : String] : Variant read GetCustomProperty write SetCustomProperty;
    property ItemIndex : Integer read FItemIndex;
    property Mode : TWordDocMode read FMode;
  end;

  TWordRange = class
  private
    FComRange : {$IFDEF VER130}Word97.Range{$ELSE}Word_TLB.Range{$ENDIF};
    FWordDoc : TWordDoc;
    FItemIndex : Integer;
    procedure SetStart(Value : Integer);
    function GetStart : Integer;
    procedure SetEnd(Value : Integer);
    function GetEnd : Integer;
    procedure SetText(Value : String);
    function GetText : String;
    procedure SetBold(Value : Boolean);
    function GetBold : Boolean;
    procedure SetItalic(Value : Boolean);
    function GetItalic : Boolean;
    procedure SetUnderline(Value : Boolean);
    function GetUnderline : Boolean;
    procedure SetCase(oeValue : TOleEnum);
    function GetCase :TOleEnum;
    procedure SetFont(fFont : _Font);
    function GetFont : _Font;
    procedure SetStyle(Style : String);
    function GetStyle : String;
  protected
  public
    constructor CreateFromBookMark(WordDoc : TWordDoc; BookmarkName : String);
    constructor CreateFromSelection(WordDoc : TWordDoc);
    constructor CreateFromDoc(WordDoc : TWordDoc; iStart : Integer = 1; iEnd : Integer = 1);
    constructor CreateFromRange(WordDoc : TWordDoc; ComRange : {$IFDEF VER130}Word97.Range{$ELSE}Word_TLB.Range{$ENDIF});
    destructor Destroy; override;
    procedure Collapse(oeDirection : TOleEnum = wdCollapseStart);
    function EndOf(oeUnit : TOleEnum = wdWord; oeExtend : TOleEnum = wdMove) : Integer;
    function Expand(oeUnit : TOleEnum = wdWord) : Integer;
    function GoTo_(oeWhat, oeWhich : TOleEnum; oeCount: Integer = 1; oeName: String = '') : {$IFDEF VER130}Word97.Range{$ELSE}Word_TLB.Range{$ENDIF};
    function GotoBookmark(BookmarkName : string) : {$IFDEF VER130}Word97.Range{$ELSE}Word_TLB.Range{$ENDIF};
    function GoToNext(oeWhat : TOleEnum) : {$IFDEF VER130}Word97.Range{$ELSE}Word_TLB.Range{$ENDIF};
    function GoToPrevious(oeWhat : TOleEnum) : {$IFDEF VER130}Word97.Range{$ELSE}Word_TLB.Range{$ENDIF};
    function NoOfWords : Integer;
    procedure InsertAfter(Text : String);
    procedure InsertAutoText;
    procedure InsertGivenAutoText (AutoText : String; UseRichText : Boolean = True);
    procedure InsertBefore(Text : String);
    procedure InsertBreak(oeType : TOleEnum = wdPageBreak);
    procedure InsertParagraph;
    procedure InsertParagraphAfter;
    procedure InsertParagraphBefore;
    procedure InsertSymbol(CharacterNumber: Integer; Font: String;
                            Unicode: Boolean = False; oeBias : TOleEnum = wdFontBiasDefault);
    function Move(oeUnit : TOleEnum = wdCharacter; oeCount : Integer = 1) : Integer;
    function MoveWhile(Cset : String; Count : Integer = wdForward) : Integer;
    function MoveUntil(Cset : String; Count : Integer = wdForward) : Integer;
    function MoveStart(oeUnit : TOleEnum = wdCharacter; oeCount : Integer = 1) : Integer;
    function MoveStartWhile(Cset : String; Count : Integer = wdForward) : Integer;
    function MoveStartUntil(Cset : String; Count : Integer = wdForward) : Integer;
    function MoveEnd(oeUnit : TOleEnum = wdCharacter; oeCount : Integer = 1) : Integer;
    function MoveEndUntil(Cset : String; Count : Integer = wdForward) : Integer;
    function MoveEndWhile(Cset : String; Count : Integer = wdForward) : Integer;
    function Next(oeUnit : TOleEnum = wdCharacter; oeCount : Integer = 1) : {$IFDEF VER130}Word97.Range{$ELSE}Word_TLB.Range{$ENDIF};
    function Previous(oeUnit : TOleEnum = wdCharacter; oeCount : Integer = 1) : {$IFDEF VER130}Word97.Range{$ELSE}Word_TLB.Range{$ENDIF};
    function GetNextRange(oeUnit : TOleEnum = wdCharacter; oeCount : Integer = 1) : {$IFDEF VER130}Word97.Range{$ELSE}Word_TLB.Range{$ENDIF};
    function GetPreviousRange(oeUnit : TOleEnum = wdCharacter; oeCount : Integer = 1) : {$IFDEF VER130}Word97.Range{$ELSE}Word_TLB.Range{$ENDIF};
    procedure SetRange(iStart, iEnd : Integer);
    function StartOf(oeUnit : TOleEnum = wdWord; oeExtend : TOleEnum = wdMove) : Integer;
    procedure CreateBookMark(BookmarkName : String);
    procedure Select;
    procedure Cut;
    procedure Copy;
    procedure Paste;

    property Range : {$IFDEF VER130}Word97.Range{$ELSE}Word_TLB.Range{$ENDIF} read FComRange write FComRange;
    property WordDoc : TWordDoc read FWordDoc;
    property Start : Integer read GetStart write SetStart;
    property End_ : Integer read GetEnd write SetEnd;
    property Text : String read GetText write SetText;
    property Bold : Boolean read GetBold write SetBold;
    property Italic : Boolean read GetItalic write SetItalic;
    property Underline : Boolean read GetUnderline write SetUnderline;
    property Case_ : TOleEnum read GetCase write SetCase;
    property Font : _Font read GetFont write SetFont;
    property Style : String read GetStyle write SetStyle;
    property ItemIndex : Integer read FItemIndex;
  end;

implementation

uses
  ComObj;

{ TWordEventSink implementation }

constructor TWordEventSink.Create(WordApp : TWordApp; AnAppDispatch: IDispatch; const AnAppDispIntfIID, ADocDispIntfIID: TGUID);
begin
  inherited Create;

  FWordApp := WordApp;
  FAppDispIntfIID := AnAppDispIntfIID;
  FDocDispIntfIID := ADocDispIntfIID;
  FAppDispatch := AnAppDispatch;

  // Hook the sink up to the automation server (Word97)
  InterfaceConnect(FAppDispatch,FAppDispIntfIID,Self,FAppConnection);
end;

destructor TWordEventSink.Destroy;
begin
  // Unhook the sink from the automation server (Word97)
  InterfaceDisconnect(FAppDispatch,FAppDispIntfIID,FAppConnection);

  inherited Destroy;
end;

function TWordEventSink.QueryInterface(const IID: TGUID; out Obj): HRESULT;
begin
  // We need to return the two event interfaces when they're asked for
  Result := E_NOINTERFACE;
  if GetInterface(IID,Obj) then
    Result := S_OK;
  if IsEqualGUID(IID,FAppDispIntfIID) and GetInterface(IDispatch,Obj) then
    Result := S_OK;
  if IsEqualGUID(IID,FDocDispIntfIID) and GetInterface(IDispatch,Obj) then
    Result := S_OK;
end;

function TWordEventSink._AddRef: Integer;
begin
// Skeleton implementation
  Result := 2;
end;

function TWordEventSink._Release: Integer;
begin
// Skeleton implementation
  Result := 1;
end;

function TWordEventSink.GetTypeInfoCount(out Count: Integer): HRESULT;
begin
// Skeleton implementation
  Count  := 0;
  Result := S_OK;
end;

function TWordEventSink.GetTypeInfo(Index, LocaleID: Integer; out TypeInfo): HRESULT;
begin
// Skeleton implementation
  Result := E_NOTIMPL;
end;

function TWordEventSink.GetIDsOfNames(const IID: TGUID; Names: Pointer;
  NameCount, LocaleID: Integer; DispIDs: Pointer): HRESULT;
begin
// Skeleton implementation
  Result := E_NOTIMPL;
end;

function TWordEventSink.Invoke(DispID: Integer; const IID: TGUID; LocaleID: Integer;
  Flags: Word; var Params; VarResult, ExcepInfo, ArgErr: Pointer): HRESULT;
begin
  // Fire the different event handlers when the different event methods are invoked
  // Only do this if FDocuments has not been destroyed.
  // Usually the "closing events" occur before FreeDocumentsAndSink when TWordApp is
  // destroyed. This results in a clean clear-up. However occasionally the "closing events"
  // occurs after FreeDocumentsAndSink where any reference to FDocuments will cause an
  // exception. I cannot seem to predict/prevent this and may be due to message queues.
  // Therefor in this situation, the event sink will not fire closing/quiting events.
  if FWordApp.FDocuments <> nil then
    case DispID of
      2 : FWordApp.QuitAppEvent;
      3 : begin
            FWordApp.ChangeDocEvent;
            // When we see a document change, we also need to disconnect the
            // sink from the old document, and hook it up to the new document
            InterfaceDisconnect(FDocDispatch,FDocDispIntfIID,FDocConnection);
            try
              // Added check for *any* document before trying to connect to it
              // Otherwise closing the last document causes an exception here
              // Note Word events are unreliable - in my demo:-
              // Closing a document -> DispID 6 and then 3 !!!
              // Opening a document -> DispID 3 but not 5 !!!
              if _Application(FAppDispatch).Documents.Count > 0 then
              begin
                FDocDispatch := _Application(FAppDispatch).ActiveDocument;
                InterfaceConnect(FDocDispatch,FDocDispIntfIID,Self,FDocConnection);
              end;
            except;
            end;
          end;
      {4 : if Assigned(FWordApp.OnNewDocument) then  // never seems to be called
            FWordApp.OnNewDocument(FWordApp, nil);}
      {5 : if Assigned(FWordApp.OnOpenDocument) then // never seems to be called
            FWordApp.OnOpenDocument(FWordApp, nil);}
      6 : FWordApp.PreCloseDocEvent;
    end;
  Result := S_OK;
end;

{ TWordApp implementation }

constructor TWordApp.Create(UseExisting : Boolean = True; Sink : Boolean = True);
var
  TempIUnknown : IUnknown;
  Result: HResult;
begin
  inherited Create;
  FUsedExisting := False;
  if UseExisting then
  begin
    {$IFDEF VER130}
    Result := GetActiveObject(CLASS_WordApplication, nil, TempIUnknown);
    {$ELSE}
    Result := GetActiveObject(CLASS_Application_, nil, TempIUnknown);
    {$ENDIF}
    if Result = MK_E_UNAVAILABLE then // Word application does not exist
      {$IFDEF VER130}
        FComApp := CoWordApplication.Create
      {$ELSE}
        FComApp := CoApplication_.Create
      {$ENDIF}
    else
    begin                             // Word application exists
      // make sure no other error occured while trying to get global class
      OleCheck(Result);
      // convert late bound IUnknown to early bound _Global
      OleCheck(TempIUnknown.QueryInterface(_Application, FComApp));
      FUsedExisting := True; // actually got an existing instance
    end;
  end
  else
    {$IFDEF VER130}
      FComApp := CoWordApplication.Create;
    {$ELSE}
      FComApp := CoApplication_.Create;
    {$ENDIF}
  FComGlobal := CoGlobal.Create;

  if Sink then // Create the event sink if required
    FEventSink := TWordEventSink.Create(Self,FComApp,ApplicationEvents,DocumentEvents)
  else
    FEventSink := nil;
  FDocuments := TList.Create;
  if FUsedExisting then SyncWithWord;
end;

constructor TWordApp.CreateFromOleObject(OleObject : OleVariant; Sink : Boolean = True);
begin
  inherited Create;
  FUsedExisting := False;
  try
    {$IFDEF VER130}
      FComApp := IDISPATCH (OleObject.Application) as WordApplication;
    {$ELSE}
      FComApp := IDISPATCH (OleObject.Application) as _Application;
    {$ENDIF}
    FComGlobal := CoGlobal.Create;
    FUsedExisting := True; // actually got an existing instance

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -