• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 384
  • Last Modified:

Screen position of Icon in SysTray

I create a icon in the windows systray. When I right click the icon, it pops up a menu. Now I try to use short cut (like pressing Ctrl + c)to actvate the menu, But Menu's popup method requires the position point(x, y), How can I get the icon position?

Best regards

Peter Shaw
0
petershaw9
Asked:
petershaw9
  • 5
  • 3
  • 2
  • +1
1 Solution
 
PeterLarsenCommented:
Hi Peter.
I have created a similar program, but i'm not satisfied with the result. My problem is, that the popupmenu only receive keyboard focus if the application have a visible form.
Would it be possible to see how you solved that problem ??

Regarding your question. I don't know how to get the position if a particular trayicon. But i can show you how to get the position of the taskbar :

procedure .....
var
 AP : PAppBarData;
begin
 new(ap);
 ap^.cbSize:=Sizeof(ap^);
 SHAppBarMessage(ABM_GETTASKBARPOS, AP^);
 showmessage(inttostr(ap^.rc.Left)+' - '+inttostr(ap^.rc.Top));
 Dispose(ap);
end;

Please let me know if you find a way to get the position of a trayicon.

Good luck
Peter
0
 
tomer_engelCommented:
ok,,you don't need the icon's poition,you need the cursor's position

procedure TMyForm.TryIconIconCallback(var Msg:TMessage);
var
  Windows_Cursor_Pos : TPoint;
begin
  case Msg.lParam of
  WM_LBUTTONDOWN :
    begin
     //mouse cur. position
        GetCursorPos(CursorPos);
    //do your stuuf now like popups..
        mypopup.Popup(Windows_Cursor_Pos .X,Windows_Cursor_Pos.Y);
      end;
  end;
end;
0
 
petershaw9Author Commented:
Hi!
I show my client the program. They said they don't want use the mouse to operate, because keyboard is fast. The getcursor position is the current method that I use, but they don't like it.

PeterLarsen
I set main KeyPreview = true, and on the Keydown event I write the code,
  SysTrayform.PopupMenu1.Popup(p.x,p.y);
The problem is I don't know the icon's p.x, p.y.


Thanks

Peter  
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
RadlerCommented:
The complete code my time avoid give you, the hints are:
FindWindow to  'TrayNotifyWnd' to get the handle
ClientToScreen with the tray handle and a tpoint = (0,0) or a calculated value ( using GetViewportExtEx with GetDC( trayhandle ) ).
If used GetDc, call ReleaseDc after,OK ?

T++, Radler.
0
 
petershaw9Author Commented:
I tried:
var hdl : HWND;
begin
  hdl := FindWindow('TForm2', 'Form2');
  Showmessage(inttostr(hdl));
end;

It will show me a number.

But if I wrote
  P.x := form2.Left;
  P.Top := fvorm2.top;  
  P := hdl.ClienttoScreen(P);
Compiler gives me error on P := hdl.ClienttoScreen(P);

So, for systray icon, what is the icon class -- TIcon?, What is the Icon name, the icon file name? When I created the systray, this is a Icon handle: IconData.hIcon := frmSysTray.Icon.Handle; Can I use frmSysTray.Icon.Handle instead of FindWindow ?

  How to use ClientToScreen with the Icon handle?

Thanks

PeterShaw
0
 
PeterLarsenCommented:
Radler, i don't get it.
I have tried the following, but i think i'm using the wrong handle because GetViewportExtEx(d, TG) gives the position 1,1 and Windows.ClientToScreen(IconData.Wnd, TPO) gives the position 287, 182 !?!
How do i get the "tray-handle" ??

IconData : TNotifyIconData;
....
procedure TForm1.Button3Click(Sender: TObject);
var
 h : HWND;
 d : HDC;
 TG : tagsize;
 TPO : tagpoint;
begin
 d:=getdc(IconData.Wnd);
 GetViewportExtEx(d, TG);
 ReleaseDC(IconData.Wnd, d);
 showmessage(inttostr(tg.cx)+' - '+inttostr(tg.cy));
 Windows.ClientToScreen(IconData.Wnd, TPO);
 showmessage(inttostr(tpo.x)+' - '+inttostr(tpo.y));
end;

Regards
Peter
0
 
RadlerCommented:
Sorry peter,

I should provide more details really
Well, a better way maybe
procedure TForm1.FormDblClick(Sender: TObject);
var
      Pos : TPoint;
      Rec : TRect;
      Win : THandle;
begin
      Win:=FindWindow('Shell_TrayWnd', nil );
      Win:=FindWindowEx( Win, 0, 'TrayNotifyWnd', nil );
      if IsWindowVisible( Win ) then begin
            Windows.GetClientRect( Win, Rec );
            Pos.x:=Rec.Left + (Rec.Right - Rec.Left) div 2;
            Pos.y:=Rec.Bottom - (Rec.Bottom - Rec.Top) div 2;
            Windows.ClientToScreen( Win, Pos );
            Self.TrayIcon1.PopupMenu.Popup( Pos.x + 2, Pos.y -2 );
            //MessageDlg( IntToStr( Pos.x + 1), mtInformation, [mbOK], 0);
      end else begin
            MessageDlg( IntToStr( Win ), mtInformation, [mbOK], 0);
      end;
end;


NOTE : TrayIcon1 is my component to lead with tray( you have one I imagine ).

Good luck, Radler.
0
 
petershaw9Author Commented:
Hi, Radler,
Thank you for your help. I tried your code, it works well.
In my application, it generates two tray icons. How can I differentiate these two icons?

best regardds

Peter Shaw
0
 
tomer_engelCommented:
if you create the icons using the NOTIFYICONDATA structure then there's a field in that stucture that named uID, that holds the icon id-- meaning if you have two icons put the id of the first to 1,and the second to two,, now when you get the callback function,the icon id is in the wParam field of the function ( just make a case statement):

 Procedure  On_MYWM_NOTIFYICON( wParam:WPARAM; lParam:LPARAM )  
 Var
    uID : UINT;  
    uMouseMsg : UINT;
  Begin
       
   
      uID = UINT (wParam);  
      uMouseMsg = UINT (lParam);  
   
      if (uMouseMsg = WM_LBUTTONDOWN) then
      begin
          case (uID)  of
           IDI_MYBATTERYICON:  
   
                  // The user clicked the battery icon. Display the  
                 // battery status.  
                  ShowBatteryStatus();  
           IDI_MYPRINTERICON:  
   
                  // The user clicked the printer icon. Display the  
                  // status of the print job.  
                  ShowJobStatus();  
          end;//the case statment
       end;//the if  uMouseMsg = WM_LBUTTONDOWN
     
   End;//the procedure  
0
 
RadlerCommented:
Hi peter,

More details about this you can take at
http://skyscraper.fortunecity.com/gigo/311/winprog.html
I know this link ( thanks nick ) a long time but being C/C++ I omitted it.

T++, Radler.
0
 
petershaw9Author Commented:
Comment accepted as answer
0
 
petershaw9Author Commented:
Comment accepted as answer
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

  • 5
  • 3
  • 2
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now