Adding / Deleting Menu Items in OLE-Bound Applications (Views: 300)
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; |