Ich arbeite an einem kleinen Shell-Ersatz.
d.h. Explorer.exe wird gar nicht gestartet.
Ich erzeuge ein Fenster: 'Shell_TrayWnd' und seine 3 Childs TrayNotifyWnd, SysPager, ToolbarWindow32.
Habe gehört, dass manche Anwendungen danach suchen und abstürzen wenn die Childs nicht gefunden werden.
Nach dem Erzeugen sende ich noch die Message:
SendMessage(HWND_BROADCAST, RegisterWindowMessage('TaskbarCreated'), 0, 0);
Dann melden sich der Großteil der Anwendungen mit der WM_COPYDATA bei meinem 'Shell_TrayWnd' Fenster.
Alle Icons bekomme ich nur wenn ich einen Neustart mache. Das ist mit dem Explorer aber genau so - also OK.
Je nach NIM_ADD, NIM_MODIFY oder NIM_REMOVE Update/füge hinzu/entferne ich Icons.
Jedes Icon sendet mir seine TNotifyIconData und somit habe ich für jedes Icon dann die Callback & Hwnd & uID.
Weiterleiten tu ich z.b so:
Delphi-Quellcode:
Sendmessage(MyIcon[i].Wnd,
MyIcon[i].uCallbackMessage,
MyIcon[i].uID,
WM_LBUTTONDOWN);
Und das nimmt mir nicht jede Anwendung an!? Kaspersky z.B. geht linke & rechte Mouse super. Bei einer anderen Anwendung wie z.B. Windows Update Icon geht nichts!
EDIT: Habe mir nun etwas die
JEDI angesehen:
Die
Unit JvTrayIcon sucht nach der
TOOLBARCLASSNAME = 'ToolbarWindow32';
Davon will es sich ein TRect holen (Poistion der
TNA):
Delphi-Quellcode:
// Retrieve the button rectangle..
SendMessage(ToolbarHandle, TB_GETITEMRECT, Index, Longint(Data));
// ..and copy it to the current process. If it fails no need to continue
if not ReadProcessMemory(FData, SizeOf(IconRect), IconRect) then
Exit;
Da wird es schon mal aussteigen. Da muss ich anscheinend noch etwas nachbessern...
Auch das habe ich gefunden:
Delphi-Quellcode:
{ We get the following messages while clicking:
Shell version < 5.0 | Shell version >= 5.0
|
Single click Double click | Single click Double click
|
WM_BUTTONDOWN WM_BUTTONDOWN | WM_BUTTONDOWN WM_BUTTONDOWN
WM_BUTTONUP WM_BUTTONUP | WM_BUTTONUP WM_BUTTONUP
WM_BUTTONDBLCLK | WM_CONTEXTMENU (*) WM_CONTEXTMENU (*)
WM_BUTTONUP | WM_BUTTONDBLCLK
| WM_BUTTONUP
| WM_CONTEXTMENU (*)
(*) if clicked with the right mouse button.
o We use the tisClicked flag to indicate that we received a WM_BUTTONDOWN;
if we receive a WM_BUTTONUP we can then make a difference between button ups
from double click and from single clicks. DoClick is thus not called twice
for double clicks.
(similar to csClicked flag in TControl.ControlState)
o Normal behaviour for window controls is to call both DoClick and DoDoubleClick
when the user double clicks the control. For the tray icon we don't want that.
We use the tisWaitingForDoubleClick flag to indicate that we received a
WM_BUTTONDOWN and WM_BUTTONUP and thus want to call DoClick. But instead of
calling DoClick we start a timer; if we receive a WM_BUTTONDBLCLK before the
timer ends, the user double clicked the icon otherwise it was a single click.
o For Shell32.dll versions before 5.0 we call DoContextPopup in WM_BUTTONUP
to simulate WM_CONTEXTMENU messages.
Thus the result is:
Shell version < 5.0 | Shell version >= 5.0
|
Single click Double click | Single click Double click
|
WM_BUTTONDOWN WM_BUTTONDOWN | WM_BUTTONDOWN WM_BUTTONDOWN
OnMouseDown OnMouseDown | OnMouseDown OnMouseDown
WM_BUTTONUP WM_BUTTONUP | WM_BUTTONUP WM_BUTTONUP
Start Timer Start Timer | Start Timer Start Timer
OnMouseUp OnMouseUp | OnMouseUp OnMouseUp
OnContextPopup (*) OnContextPopup (*)| WM_CONTEXTMENU (*) WM_CONTEXTMENU (*)
WM_TIMER WM_BUTTONDBLCLK | OnContextPopup OnContextPopup
OnClick (**) Stop Timer | WM_TIMER WM_BUTTONDBLCLK
OnDoubleClick | OnClick (**) Stop Timer
WM_BUTTONUP | OnDoubleClick
OnMouseUp | WM_BUTTONUP
OnContextPopup | OnMouseUp
| WM_CONTEXTMENU (*)
| OnContextPopup
(*) if clicked with the right mouse button.
(**) OnClick comes after the OnMouseUp. Another design decision could
be to also delay OnMouseUp.
}