?
Solved

Add Menuitem.

Posted on 2000-02-18
16
Medium Priority
?
322 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 8
  • 7
16 Comments
 
LVL 8

Accepted Solution

by:
ZifNab earned 600 total points
ID: 2534623
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
ID: 2537500
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
ID: 2537545
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
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 8

Expert Comment

by:ZifNab
ID: 2538343
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
ID: 2538372
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
ID: 2540230
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
ID: 2542543
listening...
0
 

Author Comment

by:yingkit
ID: 2545269
Adjusted points to 200
0
 

Author Comment

by:yingkit
ID: 2545270
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
ID: 2546880
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
ID: 2557303
Actually, is it impossible to interfere other programs' menus, just like my question?  Very difficult??
0
 
LVL 8

Expert Comment

by:ZifNab
ID: 2557340
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
ID: 2557347
mmm, perhaps a global messages hook can work...

Zif.
0
 

Author Comment

by:yingkit
ID: 2557362
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
ID: 2562325
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
ID: 2564120
yingkit, I'll certainly do!
0

Featured Post

On Demand Webinar: Networking for the Cloud Era

Ready to improve network connectivity? Watch this webinar to learn how SD-WANs and a one-click instant connect tool can boost provisions, deployment, and management of your cloud connection.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
Michael from AdRem Software outlines event notifications and Automatic Corrective Actions in network monitoring. Automatic Corrective Actions are scripts, which can automatically run upon discovery of a certain undesirable condition in your network.…
Michael from AdRem Software explains how to view the most utilized and worst performing nodes in your network, by accessing the Top Charts view in NetCrunch network monitor (https://www.adremsoft.com/). Top Charts is a view in which you can set seve…
Suggested Courses

764 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