Build any systray application with APIs.

Published on by Yousfi Benameur


In my previous post  http://yousfi.over-blog.com/2018/03/put-any-application-on-systray-knwing-its-hwnd.html
the code  *3* built an icon on systray to hide/show any window given by its handle (as _vfp.hwnd).there was no contextuel  menu attached to this icon.

here we build an icon on systray but with an attached contextuel  menu as vfp9 systray class can provides.
all this is built with APIs ( createpopupmenu and appendMenu).
of course this is the windows standard  technic with APIs to build systray balloons and notifications with shell_notifyIcon API.

this code dont use at all the vfp9 systray class but use very similar tools to do the same goal.
if the vfp9 systray class uses a top level form to hold the contextuel menu, here i used an olecontrol (a treeview)also top level and works as well.
All the job is to build the structure passed as a string (lcNotifyString).see the procedure ybuild_structure in code.This structure is driven by the shell_notifyIcon API with messages alias NIM_*.
the balloon depends on windows Shell version installed : if version <5 no balloon can shown,vrsion 6 and version >6.in windows 10 there is a 'version 10').
a balloon (style depends also on shell version.in windows 10 i have a colored rectangle with icon,title and text animated from the right to left and having
a timeout to disappear).by default the notification sound is on (can also disable it by code).

Shell_NotifyIcon API parameters : dwMessage As Long, pnid As NOTIFYICONDATA structure)
dwMessage
    One of the following flags specifying the action to take:
  NIM_ADD       Add the icon described by pnid to the system tray.
  NIM_DELETE    Remove the icon described by pnid from the system tray.
  NIM_MODIFY    Modify the icon described by pnid.
  NIM_SETFOCUS  Windows 2000: Return the focus to the system tray. This should be done after completing the user interface operations associated with the icon.
  NIM_SETVERSION Windows 2000: Use the uVersion member of the structure passed as pnid to determine which taskbar behavior to use. The two options are the Windows 2000-specific behavior and the behavior found on other Windows platforms. Note that this guide does not explain how to use the behavior introduced by Windows 2000.

 pnid    Provides identifying information and settings for the tray icon, as needed by the value passed as dwMessage.
-click on menu to exit or rightclick to fire the menu.
in the menu can change the used  window icon programmatly and by API.
*the notepad sample window caption must be localized in code (here in french)
[Post 267]


Click on code to select [then copy] -click outside to deselect

*1* created on Monday 11 of march 2018
*update NIIF_SOUND on 14 march 2018

Clea All
Local m.x
m.x=Inputbox("VFP (0) or notepad (1) to traybar","","0")
If Empty(m.x)
  Return .F.
Endi
Do Case
  Case m.x=="0"
    = ytray(_vfp.HWnd,Home(1)+"graphics\icons\misc\face03.ico")
  Case m.x="1"
    _Screen.WindowState=1
    Run/N notepad
    Inke(2)
    Declare Integer FindWindow In user32 String,String
    HWnd=FindWindow(Null,"Sans titre - Bloc-notes")  &&localized here French and exact caption.
    Wait Window HWnd  Timeout 0.5
    If HWnd=0
    messagebox("handle not found..cancelling.",16+4096)
      Return.F.
    Endi
   = ytray(HWnd,Home(1)+"graphics\icons\misc\face03.ico")

  Otherwise
    Return .F.
Endcase

Function ytray()
  Parameters  HWnd, lcIconNameFile   && public
  If Pcount()<2 Or !Vartype(HWnd)=="N"  Or !Lower(Justext(lcIconNameFile))=="ico"
    Messagebox("Error on parameters",16+4096,'Error',1300)
    Return .F.
  Endi

  Local Retry_yes
  Retry_yes=.T.
  _Screen.AddProperty("OLD_ICON",_Screen.Icon)
  _screen.addProperty("ysound",.t.)  && .t. for sound associated with notification .f. no sound.
  If Vartype(lcIconNameFile)="C" And !Empty(lcIconNameFile)
    If Atc(".ico",lcIconNameFile)=0
      lcIconNameFile = lcIconNameFile + ".ico"
    Endif
    _Screen.Icon = lcIconNameFile
  Else
    If Empty(_Screen.Icon)
      Messagebox ("Icon file not defined.", 48, "Erreur")
      Retry_yes=.F.
    Else
      lcIconNameFile = _Screen.Icon
    Endif
  Endif
  If !File(_Screen.Icon)
    Messagebox ("Icon file not found", 48, "Erreur")
    Retry_yes=.F.
  Endif
  If !File(lcIconNameFile)
    Messagebox ("Icon file not found" + lcIconNameFile + ".", 48, "Erreur")
    Retry_yes=.F.
  Endif
  If !Retry_yes
    _Screen.Icon=OLD_ICON
    Return .F.
  Endif
  * API declarations
  Declare Integer FindWindow In win32api Integer,String
  Declare Integer ShowWindow In win32api Integer,Integer
  Declare Integer SetForegroundWindow In user32 Integer
  Declare Integer Shell_NotifyIcon In shell32 Long, String
  Declare Long ExtractIconEx In shell32 String lpszFile, Long nIconIndex,long @phiconLarge, Long @phiconSmall, Long nIcons
  Declare Long DestroyIcon In user32 Long hIcon
  Declare Integer CreatePopupMenu In USER32
  Declare Integer DestroyMenu In USER32 Integer
  Declare Integer GetCursorPos In user32 String@
  Declare Integer AppendMenu In user32 Integer,Integer,Integer,String
  Declare Integer TrackPopupMenu In user32 Integer,Integer,Integer,Integer,Integer,Integer,Integer
  * some windows contstants relative to shell_notifyIcon used in code
  #Define TPM_CENTERALIGN 0x4
  #Define TPM_LEFTALIGN 0x0
  #Define TPM_RIGHTALIGN 0x8
  #Define TPM_BOTTOMALIGN 0x20
  #Define TPM_TOPALIGN 0x0
  #Define TPM_VCENTERALIGN 0x10
  #Define TPM_RETURNCMD 0x100
  #Define TPM_LEFTBUTTON 0x0
  #Define TPM_RIGHTBUTTON 0x2
  #Define TPM_LEFTALIGN 0x0
  #Define TPM_TOPALIGN 0x0
  #Define TPM_NONOTIFY 0x80
  #Define TPM_LEFTBUTTON 0x0
  #Define TPM_HORIZONTAL 0x0
  #Define TPM_VERTICAL 0x40
  #Define SW_HIDE 0
  #Define SW_SHOW 5
  #Define SW_MINIMIZE 6
  #Define SW_RESTORE 9
  #Define VK_LBUTTON 1
  #Define VK_RBUTTON 2
  #Define NIM_ADD 0x0
  #Define NIM_MODIFY 0x1
  #Define NIM_DELETE 0x2
  #Define NIF_MESSAGE 1
  #Define NIF_ICON 2
  #Define NIF_TIP 4

  #Define   NIF_SHOWTIP 0x00000080
  #Define NIF_INFO   0x00000010
  #define NIIF_NOSOUND 0x00000010   && no sound 
  #define messTip "Main text of balloon <=127chars depending on shell version used.Text is troncated to fill the balloon as well."+Ttoc(Date())
  #define messTitle "This is the balloon title"

  *some tests validation
  *  variables
  Local phiconLarge, phiconSmall, lcTip, lcNotifyString
  If Empty(HWnd)
    Messagebox ("Window not found...cancel", 48, "Erreur")
  Else
    * Variables for icons
    phiconLarge=0
    phiconSmall=0
    * get icons by API result
    ExtractIconEx(lcIconNameFile,0,@phiconLarge,@phiconSmall,1)
    If Empty(phiconSmall)
      Messagebox ("phiconSmall not found", 48, "Erreur")
    Else
      _Screen.AddProperty("phIconSmall",phiconSmall)
      Local oForm1
      oForm1=Newobject("FORM")
      oForm1.AddObject('ytree',"OLECONTROL1","MSComctlLib.TreeCtrl.2")  &&invisible treeview  here to hold the contextuel menu.
      _Screen.AddProperty("yhwnd",oForm1.ytree.HWnd)  &&public

      local m.lcBalloonText,m.lcBalloontitle,m.lnIcon,m.lnTimeout,m.lctip,lcNotifyString
      m.lcBalloonText =messTip       &&"this is main text of balloon <=127chars depending on shell version used.Text is troncated to fill the balloon as well."+Ttoc(Date())
      m.lcBalloonTitle=messTitle
      m.lnIcon=1
      m.lnTimeout=5
      m.lcTip =_Screen.Caption
      m.lcNotifyString=ybuild_structure(m.lcBalloonText,m.lcBalloonTitle,m.lnIcon,m.lnTimeout,_Screen.phiconSmall,m.lcTip)

      If Shell_NotifyIcon(NIM_ADD, m.lcNotifyString)<>0 && add icon to the system windows traybar if valid structure
        =Shell_NotifyIcon( NIM_MODIFY, @lcNotifyString)
        ShowWindow(HWnd, SW_MINIMIZE)
        ShowWindow(HWnd, SW_HIDE)
        Read Events    &&process events until clea events is encountered
 */////////////////////////////////////////////////////
        * put the window hwnd in foreground
        SetForegroundWindow(HWnd)
        * delete traybar icon
        Shell_NotifyIcon(NIM_DELETE, lcNotifyString)
        DestroyIcon(phiconLarge)
        DestroyIcon(phiconSmall)
        DoEvent
        * show window on screen
        ShowWindow(HWnd, SW_SHOW)
        ShowWindow(HWnd, SW_RESTORE)
      Else
        Messagebox ("Error with icon creation", 48, "Erreur")
      Endif
      oForm1.Release()
    Endif
  Endif
  *clean and exit
  HWnd=Null
  Release HWnd
  lcIconNameFile=Null
  _Screen.yhwnd=Null
  Release lcIconNameFile

  Return
Endfunc
*
Function  buf2dword (lcBuffer)
  Return Asc(Substr(lcBuffer, 1,1)) + ;
    BitLShift(Asc(Substr(lcBuffer, 2,1)),  8) +;
    BitLShift(Asc(Substr(lcBuffer, 3,1)), 16) +;
    BitLShift(Asc(Substr(lcBuffer, 4,1)), 24)
Endfunc

*convert numeric INTEGER to DWORD
Procedure DoubleWord
  Parameters Integer_word_size
  Private I,Double_word_size
  Double_word_size = ''
  For I = 1 To 4
    Double_word_size = Double_word_size + Chr(Integer_word_size % 256)
    Integer_word_size = Int(Integer_word_size / 256)
  Endfor
  Return Double_word_size
  *

  *convert a numeric DWORD to  INTEGER
 Procedure IntegerWord
  Parameters Double_word_size
  Private I,Integer_word_size
  Integer_word_size = 0
  For I = 1 To 4
    Integer_word_size= Integer_word_size+256**(I-1)*Asc(Substr(Double_word_size,I,1))
  Endfor
  Return Integer_word_size
  *

Define Class OLECONTROL1 As OleControl  &&just to hold the menu because always on top  (can be a top level form as used in vfp9 systray class)
  Procedure MouseDown
    Lparameters Button, Shift, x, Y
    Do Case
      Case x=0x201 && left mouse
        If Messagebox("Want to Exit ?",4+64+4096)=6
          Clea Events
        Endi

      Case x=0x204 && Rightclick
        ymenu=CreatePopupMenu() && create menu by CreatePopupMenu API

        If ymenu<>0
          * Add items to ymenu by API AppendMenu
          AppendMenu(ymenu,0,1,'& Hide window')
          AppendMenu(ymenu,0,2,'& Show window')
          AppendMenu(ymenu,0,3,'& set window icon')
          AppendMenu(ymenu,0,4,"& Shell Version")
          AppendMenu(ymenu,0x0800,0,'') &&  Séparator
          AppendMenu(ymenu,0,5,"& ShowBalloon-0")  && no balloon icon
          AppendMenu(ymenu,0,6,"& ShowBalloon-1")  &&Info. A lowercase "i" in a small balloon
          AppendMenu(ymenu,0,7,"& ShowBalloon-2")  &&Warning. An exclamation point (!) in a triangle.
          AppendMenu(ymenu,0,8,"& ShowBalloon-3")  &&Error. A red disk with an X through it.
          *Add 16 (0x10) to the value to mute the sound that is played when the balloon is displayed (Windows XP and later).
          AppendMenu(ymenu,0x0800,0,'') &&  Séparator
          AppendMenu(ymenu,0,9,"& Help notifyIcon structure")
          AppendMenu(ymenu,0,10,"& Summary Help")
          AppendMenu(ymenu,0,11,"& notification sound (off/on)")
          AppendMenu(ymenu,0x0800,0,'') &&  Séparator
          AppendMenu(ymenu,0,12,'& Exit')
          * mouse cursor coordinates
          Curpos=DoubleWord(0)+DoubleWord(0)
          GetCursorPos(@Curpos)

          * show menu ymenu
          Local m.myvar
          m.myvar=TrackPopupMenu(ymenu,Bitor(TPM_VERTICAL,Bitor(TPM_NONOTIFY,TPM_RETURNCMD)),IntegerWord(Left(Curpos,4)),IntegerWord(Right(Curpos,4)),0,_vfp.HWnd,0)
          Do Case
            Case m.myvar=1
              * hide window hwnd
              ShowWindow(HWnd, SW_MINIMIZE)
              ShowWindow(HWnd, SW_HIDE)

            Case m.myvar=2
              *show/restore window hwnd
              ShowWindow(HWnd, SW_SHOW)
              ShowWindow(HWnd, SW_RESTORE)

            Case m.myvar=3  &&set/reset window icon from any exe
              Declare Integer ExtractIcon In shell32 Integer hInst, String  lpszExeFileName, Integer lpiIcon
              Declare Integer SendMessage In user32 Integer HWnd, Integer Msg, Integer wParam, Integer Lparam
              #Define WM_GETICON 0x7F
              #Define WM_SETICON 0x80
              #Define ICON_SMALL 0
              #Define ICON_BIG 1
              Local lnIcon
              Try
                m.xapp=Home(1)+"vfp9.exe"   &&"c:\windows\system32\notepad.exe"      &&"c:\windows\system32\mspaint.exe" any exe having icon in zero index to extract programmatly
                lnIcon = ExtractIcon (0,m.xapp,0)
                SendMessage(HWnd, WM_SETICON, ICON_SMALL, lnIcon)
              Catch
              Endtry

            Case m.myvar=4  &&shell version  from new2news
              Declare Integer DllGetVersion In shell32 String @pdvi
              *|typedef struct _DllVersionInfo {
              *|    DWORD  cbSize;            0:4
              *|    DWORD  dwMajorVersion;    4:4
              *|    DWORD  dwMinorVersion;    8:4
              *|    DWORD  dwBuildNumber;    12:4
              *|    DWORD  dwPlatformID;     16:4
              *|} DLLVERSIONINFO; total bytes = 20

              #Define NOERROR  0
              #Define DLLVER_PLATFORM_WINDOWS  1
              #Define DLLVER_PLATFORM_NT       2

              Local lcBuffer
              lcBuffer = Chr(20) + Repli(Chr(0), 19)

              If DllGetVersion (@lcBuffer) = NOERROR
                Local m.myt
                TEXT to m.myt textmerge pretext 7 noshow
    *** Shell32.dll"
    Major version:<< buf2dword(SUBSTR(lcBuffer, 5,4))>>
    Minor version:<< buf2dword(SUBSTR(lcBuffer, 9,4))>>
    Build number: << buf2dword(SUBSTR(lcBuffer, 13,4))>>
    Platform:     << Iif(buf2dword(SUBSTR(lcBuffer, 17,4))=1, "Windows", "WinNT")>>
*
*shell version / NOTIFIYICONDATA struct size constants
*Public Const NOTIFYICONDATA_V1_SIZE As Long = 88  'pre-5.0 structure size
*Public Const NOTIFYICONDATA_V2_SIZE As Long = 488 'pre-6.0 structure size
*Public Const NOTIFYICONDATA_V3_SIZE As Long = 504 '6.0+ structure size
*Public NOTIFYICONDATA_SIZE As Long

*Link: https://msdn.microsoft.com/en-us/library/windows/desktop/bb773352(v=vs.85).aspx
*
*typedef struct _NOTIFYICONDATA {
  DWORD cbSize;
  HWND  hWnd;
  UINT  uID;
  UINT  uFlags;
  UINT  uCallbackMessage;
  HICON hIcon;
  TCHAR szTip[64];
  DWORD dwState;
  DWORD dwStateMask;
  TCHAR szInfo[256];
  union {
    UINT uTimeout;
    UINT uVersion;
  };
  TCHAR szInfoTitle[64];
  DWORD dwInfoFlags;
  GUID  guidItem;
  HICON hBalloonIcon;
} NOTIFYICONDATA, *PNOTIFYICONDATA;
                ENDTEXT

                Local oshell
                oshell = Createobject('WScript.Shell')
                oshell.Popup(m.myt,0, 'Shell version & structure', 0+32+4096)  &&4,16,48,64...
                oshell=Null
              Endif

            Case m.myvar=5  &&showBalloon    
              Local m.lcBalloonText,m.lcBalloonTitle,m.lnIcon,m.lnTimeout
              m.lcBalloonText=messTip
              m.lcBalloonTitle=messTitle
              m.lnIcon=0  &&0,1,2,3
              m.lcTip =Allt(_Screen.Caption)
              lcNotifyString=ybuild_structure(m.lcBalloonText,m.lcBalloonTitle,m.lnIcon,m.lnTimeout,_Screen.phiconSmall,m.lcTip)

            Case m.myvar=6  &&showBalloon
              Local m.lcBalloonText,m.lcBalloonTitle,m.lnIcon,m.lnTimeout
              m.lcBalloonText=messTip
              m.lcBalloonTitle=messTitle
              m.lnIcon=1   &&0,1,2,3
              m.lnTimeout=5  && seconds
              m.lcTip =Allt(_Screen.Caption)
              lcNotifyString=ybuild_structure(m.lcBalloonText,m.lcBalloonTitle,m.lnIcon,m.lnTimeout,_Screen.phiconSmall,m.lcTip)

            Case m.myvar=7 &&showBalloon
              Local m.lcBalloonText,m.lcBalloonTitle,m.lnIcon,m.lnTimeout
              m.lcBalloonText=messTip
              m.lcBalloonTitle=messTitle
              m.lnIcon=2   &&0,1,2,3
              m.lnTimeout=5  && seconds
              m.lcTip =Allt(_Screen.Caption)
              lcNotifyString=ybuild_structure(m.lcBalloonText,m.lcBalloonTitle,m.lnIcon,m.lnTimeout,_Screen.phiconSmall,m.lcTip)

            Case m.myvar=8  &&showBalloon
              Local m.lcBalloonText,m.lcBalloonTitle,m.lnIcon,m.lnTimeout
              m.lcBalloonText=messTip
              m.lcBalloonTitle=messTitle
              m.lnIcon=3   &&0,1,2,3
              m.lnTimeout=5  && seconds
              m.lcTip =Allt(_Screen.Caption)
              lcNotifyString=ybuild_structure(m.lcBalloonText,m.lcBalloonTitle,m.lnIcon,m.lnTimeout,_Screen.phiconSmall,m.lcTip)

            Case m.myvar=9  &&link msdn help
              Local m.o
              m.o=Newobject("hyperlink")
              m.o.NavigateTo("https://msdn.microsoft.com/en-us/library/windows/desktop/bb773352(v=vs.85).aspx")
              m.o=Null

          case m.myvar=10
            =yhelp()
            
            case m.myvar=11
            _screen.ysound=iif(_screen.ysound=.t.,.f.,.t.)

            Case m.myvar=12  &&clean+exit application (jump after read events in code)
              DestroyMenu(ymenu)
              _Screen.Icon=_Screen.OLD_ICON
              Clear Events
          Endcase
        Endif
    Endcase
  Endproc

Enddefine

Procedure ybuild_structure
  Lparameters cBalloonText,cBalloonTitle,lnIcon,lnTimeout,phiconSmall,lcTip
  If Pcount() < 1
    *  Must at least include the balloon Text.
    Return -1
  Endif

  If Type("cBalloonText") <> "C"
    Return -1
  Endif

  If Type("cBalloonTitle") <> "C"
    lcBalloonTitle = ""
  Endif

  If Type("lnIcon") <> "N"
    lnIcon = 0
  Endif

  If Type("lnTimeout") <> "N"
    lnTimeout = 0
  Else
    lnTimeout = m.lnTimeout * 1000	&& Convert seconds to Milliseconds.
  Endif

  Local lcNotifyString
  lcNotifyString = ;
    + DoubleWord(504) ;
    + DoubleWord(_Screen.yhwnd) ;
    + DoubleWord(0) ;
    + DoubleWord( Bitor(NIF_ICON,NIF_TIP,NIF_MESSAGE,NIF_INFO)) ;
    + DoubleWord(0x201);
    + DoubleWord(phiconSmall) ;
    + Padr(Left(lcTip+Chr(0), 127), 128, Chr(0));
    + DoubleWord(0);
    + DoubleWord(0);
    + Padr(Left(Transform(cBalloonText), 255),256, Chr(0));
    + DoubleWord(m.lnTimeout) ;
    + Padr(Left(Transform(cBalloonTitle), 63),64, Chr(0))	;
    + iif(_screen.ysound=.t.,"",DoubleWord(NIIF_NOSOUND));
    + DoubleWord(Bitand(lnIcon, 0x1F))

  *  Send request to display balloon.  This is asynchronous, so
  *  balloon may not be displayed immediately.
  lnReturn =Shell_NotifyIcon( NIM_MODIFY,@lcNotifyString)  &&return 1 if successful

  Return lcNotifyString
Endproc

Procedure yhelp
local m.yh
text to m.yh pretext 7 textmerge noshow
In my previous post  http://yousfi.over-blog.com/2018/03/put-any-application-on-systray-knwing-its-hwnd.html
the code  *3* built an icon on systray to hide/show any window given by its handle (as _vfp.hwnd).there was no contextuel  menu attached to this icon.

here we build an icon on systray but with an attached contextuel  menu as vfp9 systray class can provides.
all this is built with APIs ( createpopupmenu and appendMenu).
of course this is the windows standard  technic with APIs to build systray balloons and notifications with shell_notifyIcon API.
this code dont use at all the vfp9 systray class but use very similar tools to do the same goal.
if the vfp9 systray class uses a top level form to hold the contextuel menu, here i used an olecontrol (a treeview)  also top level and works as well even invisible.
All the job is to build the structure passed as a string (lcNotifyString).see the procedure ybuild_structure in code.This structure is driven by the
shell_notifyIcon API with messages alias NIM_*.
the balloon depends on windows Shell version installed : if version <5 no balloon can shown,version 6 and version >6.in windows 10 there is a 'shell version 10').
a balloon (style depends also on shell version.in windows 10 i ave a colored rectangle with icon,title and text animated from the right to left and having
a timeout to disappear).by default the notification sound is on (can also disable/enable it by code-see contextuel menu).

Shell_NotifyIcon API parameters : dwMessage As Long, pnid As NOTIFYICONDATA)
dwMessage
    One of the following flags specifying the action to take:
  NIM_ADD       Add the icon described by pnid to the system tray.
  NIM_DELETE    Remove the icon described by pnid from the system tray.
  NIM_MODIFY    Modify the icon described by pnid.
  NIM_SETFOCUS  Windows 2000: Return the focus to the system tray. This should be done after completing the user interface operations associated with the icon.
  NIM_SETVERSION Windows 2000: Use the uVersion member of the structure passed as pnid to determine which taskbar behavior to use. The two options are the
  Windows 2000-specific behavior and the behavior found on other Windows platforms. Note that this guide does not explain how to use the behavior
  introduced by Windows 2000.

 pnid    Provides identifying information and settings for the tray icon, as needed by the value passed as dwMessage.
 -click on menu to exit or rightclick to fire the menu.
* in the menu can change the used  window icon programmatly and by API.
endtext
_cliptext=m.yh
local oshell
    oshell = Createobject('WScript.Shell')
    oshell.Popup(m.yh,0, 'Summary help(in clipboard)', 0+32+4096)  &&4,16,48,64...
    oshell=Null
 endproc


note : can create shell_notifyIcon structure as empty object and populate it with all components: o = createobject('Empty')
note : can create shell_notifyIcon structure as empty object and populate it with all components: o = createobject('Empty')
note : can create shell_notifyIcon structure as empty object and populate it with all components: o = createobject('Empty')
note : can create shell_notifyIcon structure as empty object and populate it with all components: o = createobject('Empty')
note : can create shell_notifyIcon structure as empty object and populate it with all components: o = createobject('Empty')

note : can create shell_notifyIcon structure as empty object and populate it with all components: o = createobject('Empty')

Click on code to select [then copy] -click outside to deselect


*2* created on tuesday 13 of march 2018
*this set any icon extracted from an executable (here vfp9) on the window titlebar wanted(running notepad here).
*this code runs notepad and set dynamically  vfp9 fox icon ont it.

run/n notepad
inke(1)
declare integer FindWindow in user32 string,string
local hwnd
 hwnd=findwindow(null,"Sans titre - Bloc-notes")  && must be exact caption and localized( here in french)
if hwnd=0
messagebox("Fail to find window...cancel",16+4096)
endi

 Declare Integer ExtractIcon In shell32 Integer hInst, String  lpszExeFileName, Integer lpiIcon
 Declare Integer SendMessage In user32 Integer HWnd, Integer Msg, Integer wParam, Integer Lparam
              #Define WM_GETICON 0x7F
              #Define WM_SETICON 0x80
              #Define ICON_SMALL 0
              #Define ICON_BIG 1
              Local lnIcon
              Try
                m.xapp=Home(1)+"vfp9.exe"   &&"c:\windows\system32\notepad.exe"      &&"c:\windows\system32\mspaint.exe" any exe having icon in zero index

                lnIcon = ExtractIcon (0,m.xapp,0)
                SendMessage(HWnd, WM_SETICON, ICON_SMALL, lnIcon)
              Catch
              Endtry



                     

Yousfi Benameur


Build any systray application with APIs.

Important:All Codes above are tested on VFP9SP2 & windows 10 pro 64 bits version 1709(fall creator) & IE11 emulation. Navigator: firefox - screen:32 pouces.

To be informed of the latest articles, subscribe:
Comment on this post