Solved

Pretty damn hard...

Posted on 2002-06-11
16
197 Views
Last Modified: 2010-04-04
How can i handle other applications SystemMenu's ?

I'm writing a Taskbar replacement application to be run in a Citrix Environment...but that's not really the point.

I know how to get the SystemMenu's...but i can't seem to get those SystemMenu's to Work with TrackPopupMenu...what can i do ?

Does the process need to have any special priveleges to handle other applications systemmenu's ?

Will Inc(Points, ManyMore); for a nice answer. =)

Regards
//raidos

0
Comment
Question by:raidos
  • 8
  • 7
16 Comments
 
LVL 12

Expert Comment

by:Lee_Nover
ID: 7071166
also interested ;)
0
 
LVL 14

Expert Comment

by:DragonSlayer
ID: 7071765
If you want to modify/access other applications system menu, you would need to create a DLL to do so and then inject that DLL into the application.

Madshi should be the right person to point you to the right direction in this :)
0
 
LVL 14

Expert Comment

by:DragonSlayer
ID: 7071770
Or you could just use his (Madshi's) components to do so... check out his page at http://www.madshi.net, click on Delphi, then click on madCodeHook.

Docs are available here as well: http://help.madshi.net/Data/madCodeHook.htm


HTH
DragonSlayer
0
 
LVL 3

Author Comment

by:raidos
ID: 7072182
ohh...well....
i've got to disagree that injecting is necessary....
i can remove/disable any menuitem on any process SystemMenu straight from my application.

I don't see why i shouldn't be able to use TrackPopupMenu directly from my application with the SystemMenu that it uses...

Hoping for a different solution...

Regards
//raidos
0
 
LVL 14

Expert Comment

by:DragonSlayer
ID: 7072199
Yes you can add/remove menuitems... that's because you can get the handle to the system menus. But if you want to do other things (such as adding a new menuitem and executing a command when user clicks on the menuitem), then you need to inject your DLL into the process.
0
 
LVL 3

Author Comment

by:raidos
ID: 7072204
I don't want to add new menuitems i just want to handle the menuitems that are already inside the SystemMenu...

just the way the "Explorer" taskbar does it.

And adding new menuitems is possible without injecting a dll, a SystemHook would be possible to use too...unless i'm missing something...

Regards
//raidos
0
 
LVL 3

Author Comment

by:raidos
ID: 7072408
I've managed to move on a bit...

but with applications that are not created with borland tools it seems i get an error, 1401 := "Invalid menu" don't know why...the Var I use contains the "Correct SystemMenu"

This is the code i use:
  Window := FindWindow(Nil, 'Delphi 5'); //Change 'Delphi 5' to whatever application..
  SysMenu := GetSystemMenu(Window, FALSE);

  DrawMenuBar(Window);

  I := LongInt(TrackPopupMenu(SysMenu, TPM_CENTERALIGN OR TPM_LEFTBUTTON OR TPM_RETURNCMD, Mouse.CursorPos.X, Mouse.CursorPos.y, 0, Form1.Handle, Nil));
  If I <> 0 Then
    PostMessage(Window, WM_SYSCOMMAND, I,0)
  Else begin
    I := GetLastError;
    ShowMessage(IntToStr(I));
  End;

Regards
//raidos
0
 
LVL 14

Expert Comment

by:DragonSlayer
ID: 7072442
Here's mine:

unit uMain;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ExtCtrls, Menus;

type
  TForm1 = class(TForm)
    ListBox1: TListBox;
    Panel1: TPanel;
    Panel2: TPanel;
    Button1: TButton;
    Label1: TLabel;
    Label2: TLabel;
    procedure Button1Click(Sender: TObject);
    procedure ListBox1Click(Sender: TObject);
    procedure Panel1MouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

function EnumWindowsProc(AHandle: HWND; Param: LPARAM): BOOL; export; stdcall;
var
  WinText: array [0 .. 4096] of Char;
  ACap: string;
begin
  Result := True;
  GetWindowText(AHandle, @WinText[0], 4096);
  ACap := WinText;
  SetLength(ACap, StrLen(WinText));
  if (ACap <> '') and (IsWindowVisible(AHandle)) then
    Form1.ListBox1.Items.AddObject(WinText, TObject(AHandle));
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  ListBox1.Clear;
  EnumWindows(@EnumWindowsProc, 0);
end;

procedure TForm1.ListBox1Click(Sender: TObject);
var
  SysMenuHandle: THandle;
  AppHandle: THandle;
  PopupMenu: TPopupMenu;
begin
  if ListBox1.ItemIndex > -1 then
  begin
    AppHandle := Integer(ListBox1.Items.Objects[ListBox1.ItemIndex]);
    Label1.Caption := ListBox1.Items[ListBox1.ItemIndex] +
      ' @ $' + IntToHex(AppHandle, 8);
  end else Label1.Caption := 'Nothing Selected';
end;

procedure TForm1.Panel1MouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
  ScreenPoint: TPoint;
  SysMenuHandle: THandle;
  AppHandle: THandle;
begin
  if not (Button = mbRight) then
    Exit;
  if ListBox1.ItemIndex = -1 then
    Exit;

  AppHandle := Integer(ListBox1.Items.Objects[ListBox1.ItemIndex]);
  ScreenPoint := Panel1.ClientToScreen(Point(X, Y));
  SysMenuHandle := GetSystemMenu(AppHandle, False);
  TrackPopupMenu(SysMenuHandle,
    TPM_CENTERALIGN or TPM_LEFTBUTTON or TPM_RETURNCMD,
    ScreenPoint.x, ScreenPoint.y, 0, Handle, nil);
  PostMessage(AppHandle, WM_SYSCOMMAND, 1, 0);
end;

end.
0
Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

 
LVL 14

Expert Comment

by:DragonSlayer
ID: 7072444
And the form:


object Form1: TForm1
  Left = 192
  Top = 106
  Width = 518
  Height = 443
  Caption = 'Form1'
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
  object ListBox1: TListBox
    Left = 0
    Top = 41
    Width = 510
    Height = 334
    Align = alClient
    ItemHeight = 13
    TabOrder = 0
    OnClick = ListBox1Click
  end
  object Panel1: TPanel
    Left = 0
    Top = 375
    Width = 510
    Height = 41
    Align = alBottom
    Caption = 'Click Area'
    TabOrder = 1
    OnMouseUp = Panel1MouseUp
    object Label2: TLabel
      Left = 8
      Top = 16
      Width = 32
      Height = 13
      Caption = 'Label2'
    end
  end
  object Panel2: TPanel
    Left = 0
    Top = 0
    Width = 510
    Height = 41
    Align = alTop
    TabOrder = 2
    object Label1: TLabel
      Left = 90
      Top = 13
      Width = 82
      Height = 13
      Caption = 'Nothing Selected'
    end
    object Button1: TButton
      Left = 5
      Top = 8
      Width = 75
      Height = 25
      Caption = 'Refresh'
      TabOrder = 0
      OnClick = Button1Click
    end
  end
end




The menus came out, but they are not functional. Also, for Delphi apps, you will find two windows for each app, because of the use of TApplication (check out the programme and you will see)


HTH
DragonSlayer
0
 
LVL 3

Author Comment

by:raidos
ID: 7072497
Nice little Application, but it doesn't do anything i haven't already tried, sadly...

and the popupmenus seem to only work with Applications written with Delphi/C++ Builder/* Borland * ?

Will work on my function a bit more, perhaps i need to get the MainFormHandle for the window or something...

Regards
//raidos
0
 
LVL 3

Author Comment

by:raidos
ID: 7074182
I've gotten it to work now, it's wierd though it only works if the applications are started after the my little "Taskbar" replacement...

so if i start IE before it is unable to Handle IE's SystemMenu, but if IE is started after my little proggy it works like a charm...seriously wierd...

any ideas on that ?

Points will to be delivered to you soon DragonSlayer

Regards
//raidos
0
 
LVL 14

Expert Comment

by:DragonSlayer
ID: 7074422
> it's wierd though it only works if the applications are started after the my little "Taskbar" replacement...

What works? You mean you will only be able to get the menu if the applications are started after yours? Or did you mean that the menu becomes functional if the apps are started after yours?



DragonSlayer
0
 
LVL 3

Author Comment

by:raidos
ID: 7074773
Dragonslayer, I only get the menu for the application if it was started after mine...

//raidos
0
 
LVL 14

Accepted Solution

by:
DragonSlayer earned 100 total points
ID: 7074783
Hmm... the sample I posted above works all the time. Tested in Win2K and Win98SE
0
 
LVL 3

Author Comment

by:raidos
ID: 7074881
Your sample doesn't work "all the time" for me....sadly...but it doesn't matter anyhow, im going to start my "taskbar" replacement before any other apps anyway...

Regards
//raidos
0
 
LVL 14

Expert Comment

by:DragonSlayer
ID: 7074946
please feel free to ask... I might not have all the answers, but we can surely discuss and explore ;)
0

Featured Post

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

Join & Write a Comment

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
Access reports are powerful and flexible. Learn how to create a query and then a grouped report using the wizard. Modify the report design after the wizard is done to make it look better. There will be another video to explain how to put the final p…
Here's a very brief overview of the methods PRTG Network Monitor (https://www.paessler.com/prtg) offers for monitoring bandwidth, to help you decide which methods you´d like to investigate in more detail.  The methods are covered in more detail in o…

760 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

20 Experts available now in Live!

Get 1:1 Help Now