2010. november 3., szerda

Adding / Deleting Menu Items in OLE-Bound Applications


Problem/Question/Abstract:

How can I Delete Menu Items in Applications other than my own?

Answer:

Solve 1:

When You want to control an external Application via OLE, you sometimes have to remove some Menue-Points.

Generally, this is possible by putting the OLE-Application into a OLE-Container instead of opening it off-site. In an OLE-Container, the application tries to open its own Menu. When You now put a menu onto Your own application, OLE mixes the menues. Every second main menu-point from the external application is visible, the first, third, fifth ... menu-point is replaced by the menu You have written. In this way, You can write for example Your own FILE-menu for WORD. Now you just have to align the OLE-Container to Your form and make the form resizable, then You have Word customized as You wanted it.


Solve 2:

To Create a WORD-Like Look-and-feel in Your application, You have to follow these steps:

Create a new Form
insert an OLE-Container (NOT the WORD OLE-Object You have shipped with Delphi!!!)and  Set following properties: Align: alClient, AutoActivate: aaManual, AllowInPlace : TRUE, AllowActiveDoc: True.
Insert a Menu and fill the first menu point with 'file' and the sub-menue with the approptiate Items. Now You will have a Listing like that:

type
  TOLE_Testform = class(TForm)
    OleContainer1: TOleContainer;
    MainMenu1: TMainMenu;
                DocOpenDialog: TOpenDialog;
    File1: TMenuItem;
    New1: TMenuItem;
    Open1: TMenuItem;
    Save1: TMenuItem;
    Exit1: TMenuItem;
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

When You now run the program, You will just see Your 'File'-Menu.

Now add OnClick-Events for each menu item.

For Open, it will go like this:

procedure TOLE_Testform.Open1Click(Sender: TObject);
var
  continue: boolean;
  filename: string;
begin
  continue := DocOpenDialog.Execute();
  if continue = TRUE then
  begin
    filename := DocOpenDialog.Filename;
    //      OleContainer1.DoVerb(ovShow);
    OleContainer1.DestroyObject;
    OleContainer1.CreateObjectFromFile(filename, FALSE);
    OleContainer1.DoVerb(ovShow);
  end;
end;

CreateObjectFromFile will create the appropriate OLE-Object for the given file extension, e.g. WORD for *.DOC.

A new document You will get from this statement:

procedure TOLE_Testform.New1Click(Sender: TObject);
begin
  OleContainer1.DestroyObject;
  OleContainer1.CreateObject('WORD.Document', FALSE);
  OleContainer1.DoVerb(ovShow);
end;

When you opened an existing or created a new document, You will see that the default WORD file menu has been replaced by Your own. And now You can go on experimenting... ;-))


Solve 3:

I've been playing around. Trying to make a menu/menuitem in notepad. And I've succeded. But sadly I can not work out how to tell when the menu/menuitem is clicked. The two methods I've used to add the menuitem are listed now

var
  mnuItem: TMenuItem;
  mnuItemHandle: hmenu;
  notepad: hwnd;
  notepadmenu: hmenu;
  menucount: integer;
  MenuItemInfo: TMenuItemInfo;

{Method 1}

procedure TForm1.AddMenu1;
notepad := findwindow('Notepad', 'Untitled - Notepad');
notepadmnu := getmenu(notepad);
mnuItem := TMenuItem.Create(self);
mnuitem.Caption := 'Test';
mnuItemHandle := mnuitem.handle;
appendmenu(notepadmenu, 0, mnuitemhandle, pchar(mnuitem.caption));
end;

{Method 2}

procedure TForm1.AddMenu2;
notepad := findwindow('Notepad', 'Untitled - Notepad');
notepadmnu := getmenu(notepad);
menucount := getmenuitemcount(notepadmnu);
MenuItemInfo.fMask := MIIM_DATA + MIIM_TYPE + MIIM_STATE + MIIM_ID;
MenuItemInfo.fType := MFT_STRING;
MenuItemInfo.fState := MFS_ENABLED;
MenuItemInfo.wID := 2000;
MenuItemInfo.dwTypeData := '!CLICK ME!';
MenuItemInfo.cch := 10;
MenuItemInfo.cbSize := sizeof(MenuItemInfo);
insertmenuitem(notepadmnu, c + 1, true, MenuItemInfo);
end;

Nincsenek megjegyzések:

Megjegyzés küldése