Solved

Screen position of Icon in SysTray

Posted on 2000-04-19
12
368 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
  • 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
 
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
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
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

How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/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…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
Polish reports in Access so they look terrific. Take yourself to another level. Equations, Back Color, Alternate Back Color. Write easy VBA Code. Tighten space to use less pages. Launch report from a menu, considering criteria only when it is filled…
This video demonstrates how to create an example email signature rule for a department in a company using CodeTwo Exchange Rules. The signature will be inserted beneath users' latest emails in conversations and will be displayed in users' Sent Items…

747 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