Solved

Screen position of Icon in SysTray

Posted on 2000-04-19
12
377 Views
Last Modified: 2010-04-04
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
Comment
Question by:petershaw9
[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
  • 5
  • 3
  • 2
  • +1
12 Comments
 
LVL 2

Expert Comment

by:PeterLarsen
ID: 2730140
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
 
LVL 1

Expert Comment

by:tomer_engel
ID: 2730141
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
 

Author Comment

by:petershaw9
ID: 2732611
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
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
LVL 4

Expert Comment

by:Radler
ID: 2732763
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
 

Author Comment

by:petershaw9
ID: 2732975
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
 
LVL 2

Expert Comment

by:PeterLarsen
ID: 2737546
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
 
LVL 4

Expert Comment

by:Radler
ID: 2743917
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
 

Author Comment

by:petershaw9
ID: 2749707
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
 
LVL 1

Expert Comment

by:tomer_engel
ID: 2750624
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
 
LVL 4

Accepted Solution

by:
Radler earned 50 total points
ID: 2753364
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
 

Author Comment

by:petershaw9
ID: 2842995
Comment accepted as answer
0
 

Author Comment

by:petershaw9
ID: 2842996
Comment accepted as answer
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

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

Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
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…
In this brief tutorial Pawel from AdRem Software explains how you can quickly find out which services are running on your network, or what are the IP addresses of servers responsible for each service. Software used is freeware NetCrunch Tools (https…
This is my first video review of Microsoft Bookings, I will be doing a part two with a bit more information, but wanted to get this out to you folks.
Suggested Courses
Course of the Month8 days, 21 hours left to enroll

617 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