I recently wanted to add something like a button like Jinshan's words.
I have found it for a while, there is no example of Delphi, there is no way to get it,
1. Create a new Active Library
2. Create a new COM Object, fill in the class name, such as TEST.
Click the List button behind the Implement interface. Let's click the Add library button in the dialog.
Select the msaddndr.dll file under the "Program Files / Common Files / Designer" directory.
Then find the _idTextensibility2 interface inside MsadDndr.dll in the list. OK.
3. Now the com address section has been completed, now add a CommandBar and a button in Word, and let the button respond to the event.
4. Create a TCommandbarbutton's Oleserver class to connect to CommandButton and respond to the event. code show as below
Define some
Tcommandbarbuttonclick = procedure (const ctrl: olevariant; var caledefault: olevariant) of object;
TcommandbarButton = Class (TOLESERVER)
Private
FINTF: CommandbarButton;
FONCLICK: TCOMMAVAndbarButtonClick;
Function getDefaultInterface: commandbarbutton;
Procedure setonclick (const value: tcommandbarbutton);
protected
Procedure INITSERVERDATA; OVERRIDE;
Procedure InvokeEvent (Dispid: Tdispid; Var params: tvariantaray); OVERRIDE;
public
Constructor Create (Aowner: Tcomponent); OVERRIDE;
DESTRUCTOR DESTROY; OVERRIDE;
Override;
Procedure ConnectTo (SVRINTF: Commandbarbutton);
Procedure disconnect; Override DISCONNECT;
Property DefaultInterface: CommandBarbutton Read GetDefaultInterface;
Published
Property Onclick: TcommandbarbuttonClick Read Fonclick Write setonclick
END;
Implementation part
{Tcommandbarbutton}
Procedure tcommandbarbutton.connect;
VAR
Punk: IUNKNOWN;
Begin
IF FINTF = NIL THEN
Begin
Punk: = Get Server;
ConnecTevents (PUNK);
FINTF: = punk as commandbutton;
END;
END;
Procedure TcommandbarButton.ConnectTo (SVRINTF: CommandBarbutton);
Begin
Disconnect;
FINTF: = SVRINTF;
ConnecTevents (FINTF);
END;
Constructor TcommandbarButton.create (Aowner: Tcomponent);
Begininherited;
END;
Destructor TcommandbarButton.Destroy;
Begin
inherited;
END;
Procedure tcommandbarbutton.disconnect;
Begin
IF FINTF <> nil dam
Begin
DisconnecTevents (FINTF);
FINTF: = NIL;
END;
END;
Function Tcommandbarbutton.getDefaultinterface: CommandbarButton;
Begin
IF FINTF = NIL THEN
CONNECT;
Assert (FINTF <> NIL, 'Defaultinterface is Null. Component is not connection to server. You must call' 'connect' 'or' 'connection' 'before this operation');
Result: = FINTF;
END;
Procedure TcommandbarButton.initServerData;
Const
CSERVERDATA: TSERVERDATA = (
ClassID: '{55F88891-7708-11D1-ACEB-006008961DA5}'
Intfiid: '{000c030E-0000-0000-C000-000000000046}';
Eventiid: '{000c0351-0000-0000-c000-000000000046}';
LicenseKey: NIL;
Version: 500);
Begin
ServerData: = @cserverdata;
END;
Procedure Tcommandbarbutton.InvokeEvent (Dispid); DISPID: TDISPID;
Var params: tvariantaray;
Begin
Case Dispid of
-1: EXIT; / / DISPID_UNKNOWN
1: if Assigned (fonclick) THEN
FONCLICK (params [0], params [1]);
End; {copy dispid}
END;
Procedure TcommandbarButton.setonclick
Const value: tcommandbarbuttonclick;
Begin
FONCLICK: = Value;
END;
5. Continue to complete the TTEST class
Add two items in the class definition
Private
FCommandbarbutton: tcommandbarbutton;
Procedure Fclick (Const Ctrl: Olevariant; Var Canceldefault: Olevariant);
Write the following code on ONCONNECTION
Procedure TTest.onConnection (Const Application: iDispatch);
ConnectMode: EXT_CONNECTMODE; Const address: idispatch;
VAR CUSTOM: PSAFEARRAY
// This is to read a bitmap from the resource and copy it to the paste board.
Procedure CopyBitmaptoclipboard;
VAR
ASTREAM: TSTREAM;
Abitmap: graphics.tbitmap;
Begin
With tclipboard.create do
Begin
Try
ASTREAM: = TRESOURSTREAM.CREATEFROMID (Hinstance, 1, RT_RCDATA); ABITMAP: = graphics.tbitmap.create;
Abitmap.LoadFromstream (astream);
Assign (ABITMAP);
Finally
ASTREAM.FREE;
Abitmap.free;
FREE;
END;
END;
END;
VAR
App: WordApplication;
Acommandbar: commandbar;
Abutton: _CommandbarButton;
Begin
App: = WordApplication (Application);
Acommandbar: = App.comMandbars.Add ('Test', Msobartop, False, True);
Abutton: = Acommandbar.controls.add (MsoControlbutton, EmptyParam, EmptyParam, EmptyParam, True) AS _CommandbarButton
Abutton.Set_Style (MsobuttonIndCaption);
Abutton.SET_CAPTION ('Test');
// copybitmaptoclipboard; // These two sentences are to set an external icon for the button,
//abutton.pasteface; // You have to add a RCDATA's BitMap resource Bitmap size 16 * 16, how to do, please refer to other documents
Abutton.Set_Tag ('Test111');
FCommandbarButton: = tcommandbarbutton.create (nil);
FCommandbarButton.ConnectTo (Abutton);
FCommandbarButton.onClick: = fclick;
Acommandbar.set_visible (true);
END;
Write the following code on OnDisConnection
Procedure TTest.ondisconnection (RemoveMode: ext_disconnectmode;
VAR CUSTOM: PSAFEARRAY
Begin
FCommandbarButton.disconnect;
FCommandbarButton.Free;
END;
Write Click events (inserting the current time in the Word document)
Procedure TTest.fclick (const ctrl: olevariant;
Var Canceldefault: olevariant);
Begin
Ctrl.Application.selection.typetext (dateteStr (now) # 10);
END;
6. Last use of menus -> RUN-> Register Active Server registration COM object
7. Add com address to Word to open regedit, add an item "HKEY_CURRENT_USER / SOFTWARE / Microsoft / Office / Word / Addins / Addinterest.test"
In this item, add a string value "FriendlyName" to give a value, such as "Test"
Add another double-byte value "loadbehavior" set the value to 3
carry out! Open Word now You can see that a button above is added to the current document to output a current time.