Here's some code for you to use. I only coded in a simulated left doubleclick. You can easily add support for single left or right clicks as needed.
Code: Select all
;/============================================================
;/ Code : Simulate Doubleclick on Notification Area icon
;/ Author : Sparkie
;/ Date : 03/16/2008
;/ PB Support : PB 4.00 or later
;/ OS Support : Windows XP or later
;/ License : Free to use with no restrictions
;/============================================================
If OSVersion() < #PB_OS_Windows_XP
MessageRequester("Sorry", "WinXP or later is required", #PB_MessageRequester_Ok | #MB_ICONEXCLAMATION)
End
EndIf
;/ Constants ========================================================
#ICON_SMALL = 0
;/ Enumerations =====================================================
Enumeration
#WindowMain
EndEnumeration
Enumeration
#TextInfo
#ListIcons
#ButtonRefresh
EndEnumeration
;/ Macros ===========================================================
Macro MakeLong(low, high)
low | high <<16
EndMacro
;/ ========================= Structures ==========================
Structure EXTRAINFO
hwnd.l
dummy0.l
dummy1.l
dummy2.l
dummy3.l
exePath.l
dummy5.l
EndStructure
;/ ========================= Procedures ==========================
;- Find Taskbar and enumerate buttons
Procedure.l TaskBarList(clickit.l, iCmd.l)
cf.CHARFORMAT
cf\cbSize = SizeOf(CHARFORMAT)
cf\dwMask = #CFM_COLOR
Protected hIcons.l = 0
Protected hTray.l = 0
Protected hNotify.l = 0
Protected hPager.l = 0
result.l = 0
;- Find the Notification Area Toolbar that holds the icons
hTray = FindWindow_("Shell_TrayWnd", 0)
If hTray
result + 1
hNotify = FindWindowEx_(hTray, 0, "TrayNotifyWnd", 0)
If hNotify
result + 1
hPager = FindWindowEx_(hNotify, 0, "SysPager", 0)
If hPager
result + 1
hIcons = FindWindowEx_(hPager, 0, "ToolbarWindow32", 0)
If hIcons
result + 1
EndIf
EndIf
EndIf
EndIf
If result < 4
MessageRequester("Error Code " + Str(result), "Unable to locate Taskbar", #MB_OK | #MB_ICONERROR)
End
EndIf
result=0
;- Get the Notification icon (button) count
buttonCount.l = SendMessage_(hIcons, #TB_BUTTONCOUNT, 0, 0)
;- Open taskbar process
pid.l = 0
GetWindowThreadProcessId_(hIcons, @pid)
If pid
result + 1
Protected trayProc.l = 0
trayProc.l = OpenProcess_(#PROCESS_VM_OPERATION | #PROCESS_VM_READ | #PROCESS_VM_WRITE, #False, pid)
If trayProc
result + 1
;- Create buffer to hold result for reading taskbar info
*Buff1 = VirtualAllocEx_(trayProc, 0, 2048, #MEM_COMMIT, #PAGE_READWRITE)
If *Buff1
result + 1
EndIf
EndIf
EndIf
If result < 3
MessageRequester("Error Code " + Str(result), "Unable to init Taskbar", #MB_OK | #MB_ICONERROR)
End
EndIf
;- Write TBBUTTONINFO from tray icons
tbi.TBBUTTONINFO
tbi\cbSize = SizeOf(TBBUTTONINFO)
tbi\dwMask = #TBIF_BYINDEX | #TBIF_LPARAM | #TBIF_SIZE | #TBIF_STATE | #TBIF_STYLE | #TBIF_COMMAND
If *Buff1
WriteProcessMemory_(trayProc, *Buff1, @tbi, SizeOf(TBBUTTONINFO), @result)
Else
MessageRequester("Error", "unable to write to Buffer", #MB_OK | #MB_ICONERROR)
End
EndIf
result = 0
;- Loop through all taskbar buttons
For i = 0 To buttonCount - 1
;--- Read the TBBUTTONINFO
SendMessage_(hIcons, #TB_GETBUTTONINFO, i, *Buff1)
If *Buff1
ReadProcessMemory_(trayProc, *Buff1, @tbi, SizeOf(TBBUTTONINFO), @result)
Else
MessageRequester("Error", "unable to write to buffer", #MB_OK | #MB_ICONERROR)
End
EndIf
result = 0
;- Get the extra button info found within lparam (hwnd, exepath)
eInfo.EXTRAINFO
If tbi\lParam
ReadProcessMemory_(trayProc, tbi\lParam, @eInfo, SizeOf(EXTRAINFO), @result)
Else
MessageRequester("Error", "unable to read memory", #MB_OK | #MB_ICONERROR)
End
EndIf
result = 0
;- Get the Notification icon tooltip text
bLen = SendMessage_(hIcons, #TB_GETBUTTONTEXT, tbi\idCommand, 0)
If bLen > 0
button$ = Space(bLen)
SendMessage_(hIcons, #TB_GETBUTTONTEXT, tbi\idCommand, *Buff1 + SizeOf(TBBUTTONINFO))
If *Buff1
ReadProcessMemory_(trayProc, *Buff1 + SizeOf(TBBUTTONINFO), @button$, bLen, @result)
Else
MessageRequester("Error", "unable to read memory", #MB_OK | #MB_ICONERROR)
End
EndIf
Else
button$ = "hidden"
EndIf
;- Get the icon
If button$ <> "hidden"
hIconSmall.l = 0
;- First try to get icon
hIconSmall = SendMessage_(eInfo\hwnd, #WM_GETICON, #ICON_SMALL, 0)
If hIconSmall = 0
;- Second try to get icon
hIconSmall = GetClassLong_(eInfo\hwnd, #GCL_HICONSM)
If hIconSmall = 0
;- Third try to get icon
GetWindowThreadProcessId_(eInfo\hwnd, @ctpid.l)
hProcess = OpenProcess_(#PROCESS_QUERY_INFORMATION | #PROCESS_VM_READ, #False, ctpid)
If OpenLibrary(0, "psapi.dll")
exepath$ = Space(#MAX_PATH)
CallFunction(0, "GetModuleFileNameExA", hProcess, 0, @exepath$, #MAX_PATH)
CloseLibrary(0)
EndIf
CloseHandle_(hProcess)
ExtractIconEx_(@exepath$, 0, 0, @hIconSmall, 1)
di = 1
If hIconSmall = 0
;- When all else fails
hIconSmall = LoadIcon_(0, #IDI_WINLOGO)
EndIf
EndIf
EndIf
EndIf
;- Fill our ListIconGadget with visible Notification icons
If tbi\fsState & #TBSTATE_ENABLED And Not tbi\fsState & #TBSTATE_HIDDEN And clickit = -2
;- Some text may contain Chr(10) so we will remove it
tt$ = ReplaceString(button$, Chr(10), " ")
AddGadgetItem(#ListIcons, -1, tt$, hIconSmall)
;- Store the command id for our icon
SetGadgetItemData(#ListIcons, CountGadgetItems(#ListIcons) - 1, tbi\idCommand)
EndIf
;- Destroy Icon if we extracted it from exepath
If di
DestroyIcon_(hIconSmall)
di = 0
EndIf
;- If we detect a click on our ListIconGadget
If clickit > -1
;- Get the Notification icon position/coordinates
index = SendMessage_(hIcons, #TB_COMMANDTOINDEX, iCmd, 0)
SendMessage_(hIcons, #TB_GETITEMRECT, index, *Buff1)
ReadProcessMemory_(trayProc, *Buff1, @rc.RECT, SizeOf(RECT), @result)
;- Convert the ListIconGadget click to a doubleclick on Notification icon
Select clickit
Case #PB_EventType_LeftClick
SetForegroundWindow_(hIcons)
PostMessage_(hIcons, #WM_LBUTTONDOWN, 0, MakeLong(rc\left, rc\top))
PostMessage_(hIcons, #WM_LBUTTONUP, 0, MakeLong(rc\left, rc\top))
PostMessage_(hIcons, #WM_LBUTTONDOWN, 0, MakeLong(rc\left, rc\top))
PostMessage_(hIcons, #WM_LBUTTONUP, 0, MakeLong(rc\left, rc\top))
PostMessage_(hIcons, #WM_LBUTTONDBLCLK, 0, MakeLong(rc\left, rc\top))
clickit = -1
EndSelect
EndIf
ct + 1
Next
;- Clean up
If *Buff1
VirtualFreeEx_(trayProc, *Buff1, 0, #MEM_RELEASE)
EndIf
If trayProc
CloseHandle_(trayProc)
EndIf
EndProcedure
;/ Main Window ======================================================
If OpenWindow(#WindowMain, 0, 0, 400, 500, "Tray Icon Test by Sparkie", #PB_Window_SizeGadget | #PB_Window_ScreenCentered | #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_TitleBar) And CreateGadgetList(WindowID(#WindowMain))
info$ = "Click on any item to simulate a doubleclick on the tray icon."
TextGadget(#TextInfo, 10, 10, 380, 50, info$, #PB_Text_Center)
ButtonGadget(#ButtonRefresh, 10, 60, 72, 25, "Refresh list")
ListIconGadget(#ListIcons, 10, 90, 380, 400, "Tray Icon ToolTip Text", 375, #PB_ListIcon_FullRowSelect | #PB_ListIcon_GridLines)
;- Get Notification Area icons and fill our ListIcon
TaskBarList(-2, -1)
;/ Main Event Loop ==================================================
Repeat
event = WaitWindowEvent()
eType = EventType()
Select event
Case #PB_Event_Gadget
Select EventGadget()
Case #ListIcons
;- Get the Notification icon command id
iCmd = GetGadgetItemData(#ListIcons, GetGadgetState(#ListIcons))
Select eType
Case #PB_EventType_LeftClick
TaskBarList(EventType(), iCmd)
EndSelect
Case #ButtonRefresh
ClearGadgetItemList(#ListIcons)
TaskBarList(-2, -1)
EndSelect
EndSelect
Until event = #PB_Event_CloseWindow
EndIf
End