Solved

Screen position of Icon in SysTray

Posted on 2000-04-19
12
369 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
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Delphi OLE Error 8 95
delphi prevent click fast 2 191
tvirtualstringtree freeze when load too manny images 10 52
Dynamically Created Query 3 50
A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
This Micro Tutorial hows how you can integrate  Mac OSX to a Windows Active Directory Domain. Apple has made it easy to allow users to bind their macs to a windows domain with relative ease. The following video show how to bind OSX Mavericks to …
This is used to tweak the memory usage for your computer, it is used for servers more so than workstations but just be careful editing registry settings as it may cause irreversible results. I hold no responsibility for anything you do to the regist…

867 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

21 Experts available now in Live!

Get 1:1 Help Now