Solved

Add Menuitem.

Posted on 2000-02-18
16
312 Views
Last Modified: 2010-04-04
Hi,
How can I add a custom menuitem to OTHER program's menu, such as Notepad's FileMenu?  Examples expected.
(D2)
0
Comment
Question by:yingkit
  • 8
  • 7
16 Comments
 
LVL 8

Accepted Solution

by:
ZifNab earned 200 total points
Comment Utility
Hi yingkit,

here is an example for Eudora Light (but can be any window)

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  DBTables, Grids, DBGrids, Db, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

type
  PFindWindowStruct = ^TFindWindowStruct;
  TFindWindowStruct = record
    Caption : string;
    ClassName : string;
    WindowHandle : THandle;
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}


function EnumWindowsProc(hWindow : hWnd;
                         lParam  : LongInt) : Bool
{$IFDEF Win32} stdcall; {$ELSE} ; export; {$ENDIF}
var
  lpBuffer : PChar;
  WindowCaptionFound : bool;
  ClassNameFound : bool;

begin
  GetMem(lpBuffer, 255);
  Result := True;
  WindowCaptionFound := False;
  ClassNameFound := False;

  try
    if GetWindowText(hWindow, lpBuffer, 255) > 0 then
      if Pos(PFindWindowStruct(lParam).Caption, StrPas(lpBuffer)) > 0
       then WindowCaptionFound := true;
    if PFindWindowStruct(lParam).ClassName = '' then
      ClassNameFound := True else
        if GetClassName(hWindow, lpBuffer, 255) > 0 then
          if Pos(PFindWindowStruct(lParam).ClassName, StrPas(lpBuffer))
           > 0 then ClassNameFound := True;

    if (WindowCaptionFound and ClassNameFound) then begin
      PFindWindowStruct(lParam).WindowHandle := hWindow;
      Result := False;
    end;

  finally
    FreeMem(lpBuffer, sizeof(lpBuffer^));
  end;
end;

function FindAWindow(ACaption : string;
                     AClassName : string) : THandle;
var
  WindowInfo : TFindWindowStruct;

begin
  with WindowInfo do begin
    Caption := ACaption;
    ClassName := AClassName;
    WindowHandle := 0;
    EnumWindows(@EnumWindowsProc, LongInt(@WindowInfo));
    FindAWindow := WindowHandle;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  TheWindowHandle : THandle;
begin
  TheWindowHandle := FindAWindow('Eudora Light', '');
  if TheWindowHandle = 0 then
    ShowMessage('Window Not Found!') else
  begin
    AppendMenu(GetMenu(TheWindowHandle),
      MF_STRING,
      $EFF0,
      'Your menu text');
  end;
end;

end.

Regards, Zif.
0
 

Author Comment

by:yingkit
Comment Utility
Hello Zif,
The code worked quite well.  But if I don't want to create a new menu, but just want to add a menuitem under the "File" menu, how should I modify the code?
Thanks in advance.
0
 

Author Comment

by:yingkit
Comment Utility
I've tried the function insertmenu, but I can't control the position where the menuitem appears.
If possible, could you please also tell me how can I execute an EXE file with some parameters when the added menuitem is clicked by the user?  Of course, I will offer more points for the answers.
Thanks!
0
 
LVL 8

Expert Comment

by:ZifNab
Comment Utility
Hi


InsertMenu works like this :

procedure TForm1.Button1Click(Sender: TObject);
var
  TheWindowHandle, MenuHandle : THandle;
begin
  TheWindowHandle := FindAWindow('Untitled - Notepad', '');
  if TheWindowHandle = 0 then
    ShowMessage('Window Not Found!') else
  begin
    MenuHandle := GetMenu(TheWindowHandle);
    MenuHandle := GetSubMenu(MenuHandle, 0);
    InsertMenu(MenuHandle,
      3,
      MF_STRING + MF_BYPOSITION,
      $EFF0,
      'Menu at place 4');
  end;
end;

I don't know directly how to intercept the click of the menu. I'll look into it.

Zif.
0
 
LVL 8

Expert Comment

by:ZifNab
Comment Utility
yuck, it's not so easy as I thought... here is what I have so far... perhaps it should work when using dll. But I don't have time to test it in a dll.

const
  WM_NotePad = WM_USER + 100;


procedure MenuIsClicked;
begin
 showmessage('hello');
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  TheWindowHandle, MenuHandle : THandle;
  POldWndProc : Pointer;
begin
  TheWindowHandle := FindAWindow('Untitled - Notepad', '');
  if TheWindowHandle = 0 then
    ShowMessage('Window Not Found!') else
  begin
    MenuHandle := GetMenu(TheWindowHandle);
    MenuHandle := GetSubMenu(MenuHandle, 0);
    InsertMenu(MenuHandle,
      3,
      MF_STRING + MF_BYPOSITION,
      WM_NotePad,
      'Menu at place 4');
    POldWndProc := Pointer(SetWindowLong(MenuHandle, GWL_WNDPROC, LongInt(@MenuIsClicked)));
  end;
end;

Regards, zif

0
 
LVL 8

Expert Comment

by:ZifNab
Comment Utility
Hi,

Reading this :

Processes run in different memory spaces on Win32 and you cannot directly call a function in another memory space.

and we know that we've to create a dll if we want to get it to work :-(

0
 
LVL 3

Expert Comment

by:gandalf_the_white
Comment Utility
listening...
0
 

Author Comment

by:yingkit
Comment Utility
Adjusted points to 200
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 

Author Comment

by:yingkit
Comment Utility
Is it possible to test it in a DLL for me and show me how I can make the DLL and get everything worked??
0
 
LVL 8

Expert Comment

by:ZifNab
Comment Utility
yuck, tried it with DLL and I get an error about not a correct window handler, when using the menu handle :-(
0
 

Author Comment

by:yingkit
Comment Utility
Actually, is it impossible to interfere other programs' menus, just like my question?  Very difficult??
0
 
LVL 8

Expert Comment

by:ZifNab
Comment Utility
Hi, I don't know, it should be possible, because we can add a menu to it... only problem is that we don't find a way to attach a function/procedure to this menu :-(. Nevertheless, it looks like it is really hard.

Zif.
0
 
LVL 8

Expert Comment

by:ZifNab
Comment Utility
mmm, perhaps a global messages hook can work...

Zif.
0
 

Author Comment

by:yingkit
Comment Utility
Hook?  Can you give me some examples?  I don't really care what method is used.  I just want to have a new menuitem appeared in other program with my own procedures.
0
 

Author Comment

by:yingkit
Comment Utility
Thanks ZifNab.
If you find a way to attach a procedure to a menuitem in the future, please post it here.  Thank you very much!
0
 
LVL 8

Expert Comment

by:ZifNab
Comment Utility
yingkit, I'll certainly do!
0

Featured Post

Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

Join & Write a Comment

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
Get a first impression of how PRTG looks and learn how it works.   This video is a short introduction to PRTG, as an initial overview or as a quick start for new PRTG users.
This video gives you a great overview about bandwidth monitoring with SNMP and WMI with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're looking for how to monitor bandwidth using netflow or packet s…

772 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now