diff --git a/reactos/subsys/system/explorer/Makefile b/reactos/subsys/system/explorer/Makefile index b63bfbbbcd1..da94f3ab375 100644 --- a/reactos/subsys/system/explorer/Makefile +++ b/reactos/subsys/system/explorer/Makefile @@ -128,12 +128,15 @@ ever: buildno.h: ../../../include/reactos/buildno.h $(CD_PREFIX)updatebuildno -$(TARGET): $(OBJECTS) $(PROGRAM)$(RES_SUFFIX) +$(TARGET): $(OBJECTS) $(PROGRAM)$(RES_SUFFIX) notifyhook.dll $(LINK) $(LFLAGS) -o $@ $^ $(addprefix -l,$(LIBS)) $(addprefix -l,$(DELAYIMPORTS)) explorer$(RES_SUFFIX): $(PROGRAM)_intres.rc res/*.bmp res/*.ico $(RC) $(RCFLAGS) -o $@ $(PROGRAM)_intres.rc +notifyhook.dll: notifyhook/notifyhook.c notifyhook/notifyhook.h + $(CC) -D_WIN32_IE=0x0600 -Wall -D_NOTIFYHOOK_IMPL -Os -s notifyhook/notifyhook.c -shared -o $@ + clean: $(TOOLS_PATH)/rdel $(TARGET) $(OBJECTS) $(PROGRAM)$(RES_SUFFIX) @@ -152,6 +155,7 @@ implib: install: -$(TOOLS_PATH)/rcopy $(TARGET) $(INSTALL_DIR)/$(TARGET) + -$(TOOLS_PATH)/rcopy notifyhook.dll $(INSTALL_DIR)/$(TARGET) bootcd: diff --git a/reactos/subsys/system/explorer/explorer.dsp b/reactos/subsys/system/explorer/explorer.dsp index 4d603e52c1b..35d182f529f 100644 --- a/reactos/subsys/system/explorer/explorer.dsp +++ b/reactos/subsys/system/explorer/explorer.dsp @@ -57,7 +57,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 shell32.lib comctl32.lib gdi32.lib user32.lib advapi32.lib ole32.lib delayimp.lib /nologo /subsystem:windows /machine:I386 /delayload:oleaut32.dll /delayload:wsock32.dll +# ADD LINK32 shell32.lib comctl32.lib gdi32.lib user32.lib advapi32.lib ole32.lib delayimp.lib /nologo /subsystem:windows /machine:I386 /libpath:"Release" /delayload:oleaut32.dll /delayload:wsock32.dll # SUBTRACT LINK32 /pdb:none !ELSEIF "$(CFG)" == "explorer - Win32 Debug" @@ -82,7 +82,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib shell32.lib comctl32.lib gdi32.lib user32.lib advapi32.lib ole32.lib delayimp.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept /delayload:oleaut32.dll /delayload:wsock32.dll +# ADD LINK32 kernel32.lib shell32.lib comctl32.lib gdi32.lib user32.lib advapi32.lib ole32.lib delayimp.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept /libpath:"Debug" /delayload:oleaut32.dll /delayload:wsock32.dll # SUBTRACT LINK32 /pdb:none !ELSEIF "$(CFG)" == "explorer - Win32 Debug Release" @@ -134,7 +134,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 user32.lib gdi32.lib advapi32.lib comctl32.lib shell32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 shell32.lib comctl32.lib gdi32.lib user32.lib advapi32.lib ole32.lib delayimp.lib /nologo /subsystem:windows /machine:I386 /delayload:oleaut32.dll /delayload:wsock32.dll +# ADD LINK32 shell32.lib comctl32.lib gdi32.lib user32.lib advapi32.lib ole32.lib delayimp.lib /nologo /subsystem:windows /machine:I386 /libpath:"Release" /delayload:oleaut32.dll /delayload:wsock32.dll # SUBTRACT LINK32 /pdb:none !ELSEIF "$(CFG)" == "explorer - Win32 Unicode Debug" @@ -160,7 +160,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 user32.lib gdi32.lib advapi32.lib comctl32.lib shell32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 shell32.lib comctl32.lib gdi32.lib user32.lib advapi32.lib ole32.lib delayimp.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept /delayload:oleaut32.dll /delayload:wsock32.dll +# ADD LINK32 shell32.lib comctl32.lib gdi32.lib user32.lib advapi32.lib ole32.lib delayimp.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept /libpath:"Debug" /delayload:oleaut32.dll /delayload:wsock32.dll # SUBTRACT LINK32 /pdb:none !ELSEIF "$(CFG)" == "explorer - Win32 _NO_COMUTIL" diff --git a/reactos/subsys/system/explorer/explorer.dsw b/reactos/subsys/system/explorer/explorer.dsw index 92fff86f51d..51e9b3bd73e 100644 --- a/reactos/subsys/system/explorer/explorer.dsw +++ b/reactos/subsys/system/explorer/explorer.dsw @@ -27,6 +27,18 @@ Package=<4> ############################################################################### +Project: "notifyhook"=.\notifyhook\notifyhook.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + Global: Package=<5> diff --git a/reactos/subsys/system/explorer/notifyhook/.cvsignore b/reactos/subsys/system/explorer/notifyhook/.cvsignore new file mode 100644 index 00000000000..0f3a6b1b966 --- /dev/null +++ b/reactos/subsys/system/explorer/notifyhook/.cvsignore @@ -0,0 +1,2 @@ +Debug +Release diff --git a/reactos/subsys/system/explorer/notifyhook/notifyhook.c b/reactos/subsys/system/explorer/notifyhook/notifyhook.c new file mode 100644 index 00000000000..41cd5de1610 --- /dev/null +++ b/reactos/subsys/system/explorer/notifyhook/notifyhook.c @@ -0,0 +1,116 @@ +/* + * Copyright 2004 Martin Fuchs + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + + // + // NotifyHook DLL for ROS Explorer + // + // notifyhook.cpp + // + // Martin Fuchs, 17.03.2004 + // + + +#include "../utility/utility.h" + +#include "notifyhook.h" + + +static HINSTANCE s_hInstance; +static UINT WM_GETMODULEPATH; +static HHOOK s_hNotifyHook; + + +BOOL APIENTRY DllMain(HINSTANCE hInst, DWORD dwReason, LPVOID param) +{ + switch(dwReason) { + case DLL_PROCESS_ATTACH: + s_hInstance = hInst; + DisableThreadLibraryCalls(hInst); + WM_GETMODULEPATH = RegisterWindowMessageA("WM_GETMODULEPATH"); + break; + } + + return TRUE; +} + + +struct COPYDATA_STRUCT { + HWND _hwnd; + int _len; + char _path[MAX_PATH]; +}; + +LRESULT CALLBACK NotifyHookProc(int code, WPARAM wparam, LPARAM lparam) +{ + MSG* pmsg = (MSG*)lparam; + + if (pmsg->message == WM_GETMODULEPATH) { + struct COPYDATA_STRUCT cds; + COPYDATASTRUCT data; + + cds._hwnd = pmsg->hwnd; + cds._len = GetWindowModuleFileNameA(pmsg->hwnd, cds._path, MAX_PATH); + + data.dwData = WM_GETMODULEPATH; + data.cbData = sizeof(cds); + data.lpData = &cds; + + SendMessage((HWND)pmsg->wParam, WM_COPYDATA, (WPARAM)pmsg->hwnd, (LPARAM)&data); + + return 0; + } + + return CallNextHookEx(s_hNotifyHook, code, wparam, lparam); +} + + +UINT InstallNotifyHook() +{ + s_hNotifyHook = SetWindowsHookEx(WH_GETMESSAGE, NotifyHookProc, s_hInstance, 0); + + return WM_GETMODULEPATH; +} + +void DeinstallNotifyHook() +{ + UnhookWindowsHookEx(s_hNotifyHook); + s_hNotifyHook = 0; +} + + +void GetWindowModulePath(HWND hwnd) +{ + SendMessage(hwnd, WM_GETMODULEPATH, 0, 0); +} + + // retrieve module path by receiving WM_COPYDATA message +DECL_NOTIFYHOOK int GetWindowModulePathCopyData(LPARAM lparam, HWND* phwnd, LPSTR buffer, int size) +{ + PCOPYDATASTRUCT data = (PCOPYDATASTRUCT) lparam; + + if (data->dwData == WM_GETMODULEPATH) { + struct COPYDATA_STRUCT* cds = (struct COPYDATA_STRUCT*) data->lpData; + + *phwnd = cds->_hwnd; + strncpy(buffer, cds->_path, size); + + return cds->_len; + } else + return 0; +} diff --git a/reactos/subsys/system/explorer/notifyhook/notifyhook.dsp b/reactos/subsys/system/explorer/notifyhook/notifyhook.dsp new file mode 100644 index 00000000000..2c1b2bf9938 --- /dev/null +++ b/reactos/subsys/system/explorer/notifyhook/notifyhook.dsp @@ -0,0 +1,101 @@ +# Microsoft Developer Studio Project File - Name="notifyhook" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=notifyhook - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "notifyhook.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "notifyhook.mak" CFG="notifyhook - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "notifyhook - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "notifyhook - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "notifyhook - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "shellhook___Win32_Release" +# PROP BASE Intermediate_Dir "shellhook___Win32_Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "..\Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_NOTIFYHOOK_IMPL" /FD /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x407 /d "NDEBUG" +# ADD RSC /l 0x407 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 +# ADD LINK32 user32.lib /nologo /subsystem:windows /dll /machine:I386 + +!ELSEIF "$(CFG)" == "notifyhook - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "shellhook___Win32_Debug" +# PROP BASE Intermediate_Dir "shellhook___Win32_Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "..\Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_NOTIFYHOOK_IMPL" /FR /FD /GZ /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x407 /d "_DEBUG" +# ADD RSC /l 0x407 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 user32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "notifyhook - Win32 Release" +# Name "notifyhook - Win32 Debug" +# Begin Source File + +SOURCE=.\notifyhook.c +# End Source File +# Begin Source File + +SOURCE=.\notifyhook.h +# End Source File +# End Target +# End Project diff --git a/reactos/subsys/system/explorer/notifyhook/notifyhook.h b/reactos/subsys/system/explorer/notifyhook/notifyhook.h new file mode 100644 index 00000000000..11ebd8c284f --- /dev/null +++ b/reactos/subsys/system/explorer/notifyhook/notifyhook.h @@ -0,0 +1,50 @@ +/* + * Copyright 2004 Martin Fuchs + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + + // + // NotifyHook DLL for ROS Explorer + // + // notifyhook.h + // + // Martin Fuchs, 17.03.2004 + // + + +#ifdef _NOTIFYHOOK_IMPL +#define DECL_NOTIFYHOOK __declspec(dllexport) +#else +#define DECL_NOTIFYHOOK __declspec(dllimport) +#ifdef _MSC_VER +#pragma comment(lib, "notifyhook") +#endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +DECL_NOTIFYHOOK UINT InstallNotifyHook(); +DECL_NOTIFYHOOK void DeinstallNotifyHook(); + +DECL_NOTIFYHOOK void GetWindowModulePath(HWND hwnd); +DECL_NOTIFYHOOK int GetWindowModulePathCopyData(LPARAM lparam, HWND* phwnd, LPSTR buffer, int size); + +#ifdef __cplusplus +}; +#endif diff --git a/reactos/subsys/system/explorer/taskbar/desktopbar.cpp b/reactos/subsys/system/explorer/taskbar/desktopbar.cpp index 3293a7674f9..8658393b09f 100644 --- a/reactos/subsys/system/explorer/taskbar/desktopbar.cpp +++ b/reactos/subsys/system/explorer/taskbar/desktopbar.cpp @@ -361,8 +361,6 @@ LRESULT DesktopBar::ProcessCopyData(COPYDATASTRUCT* pcd) if (pcd->dwData == 1) { TrayNotifyCDS* ptr = (TrayNotifyCDS*) pcd->lpData; - ///@todo process the differnt versions of the NOTIFYICONDATA structure (look at cbSize to decide which one) - NotifyArea* notify_area = GET_WINDOW(NotifyArea, _hwndNotify); if (notify_area) diff --git a/reactos/subsys/system/explorer/taskbar/traynotify.cpp b/reactos/subsys/system/explorer/taskbar/traynotify.cpp index 687fdaf9cec..71e86bb043c 100644 --- a/reactos/subsys/system/explorer/taskbar/traynotify.cpp +++ b/reactos/subsys/system/explorer/taskbar/traynotify.cpp @@ -34,6 +34,37 @@ #include "traynotify.h" +#include "../notifyhook/notifyhook.h" + +NotifyHook::NotifyHook() + : WM_GETMODULEPATH(InstallNotifyHook()) +{ +} + +NotifyHook::~NotifyHook() +{ + DeinstallNotifyHook(); +} + +void NotifyHook::GetModulePath(HWND hwnd, HWND hwndCallback) +{ + PostMessage(hwnd, WM_GETMODULEPATH, (WPARAM)hwndCallback, 0); +} + +bool NotifyHook::ModulePathCopyData(LPARAM lparam, HWND* phwnd, String& path) +{ + char buffer[MAX_PATH]; + + int l = GetWindowModulePathCopyData(lparam, phwnd, buffer, MAX_PATH); + + if (l) { + path.assign(buffer, l); + return true; + } else + return false; +} + + NotifyIconIndex::NotifyIconIndex(NOTIFYICONDATA* pnid) { _hWnd = pnid->hWnd; @@ -222,6 +253,17 @@ LRESULT NotifyArea::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) case WM_CONTEXTMENU: break; // don't let WM_CONTEXTMENU go through to the desktop bar + case WM_COPYDATA: { // receive NotifyHook answers + String path; + HWND hwnd; + + if (_hook.ModulePathCopyData(lparam, &hwnd, path)) { + _window_modules[hwnd] = path; + //@@ -> trigger DetermineHideState() + } + + break;} + default: if (nmsg>=WM_MOUSEFIRST && nmsg<=WM_MOUSELAST) { // close startup menu and other popup menus @@ -460,23 +502,14 @@ NotifyIconSet::iterator NotifyArea::IconHitTest(const POINT& pos) #if NOTIFYICON_VERSION>=3 // as of 21.08.2003 missing in MinGW headers bool NotifyArea::DetermineHideState(NotifyInfo& entry) { -/* - DWORD pid; - - if (GetWindowThreadProcessId(entry._hWnd, &pid)) { - - //@@ look for executable path - - } -*/ - TCHAR title[MAX_PATH]; - if (entry._tipText == TEXT("FRITZ!fon")) return true; if (entry._tipText == TEXT("FRITZ!fax")) return true; + TCHAR title[MAX_PATH]; + if (GetWindowText(entry._hWnd, title, MAX_PATH)) { if (_tcsstr(title, TEXT("Task Manager"))) return false; @@ -491,6 +524,17 @@ bool NotifyArea::DetermineHideState(NotifyInfo& entry) return true; } + const String& modulePath = _window_modules[entry._hWnd]; + + // request module path for new windows (We will get an asynchronous answer by a WM_COPYDATA message.) + if (modulePath.empty()) { + _hook.GetModulePath(entry._hWnd, _hwnd); + return false; + } + + if (modulePath == TEXT("xyz")) //@@ + return true; + return false; } #endif diff --git a/reactos/subsys/system/explorer/taskbar/traynotify.h b/reactos/subsys/system/explorer/taskbar/traynotify.h index d5f780b86c6..4f1e53a9108 100644 --- a/reactos/subsys/system/explorer/taskbar/traynotify.h +++ b/reactos/subsys/system/explorer/taskbar/traynotify.h @@ -35,6 +35,8 @@ #define NOTIFYICON_DIST 20 #define NOTIFYAREA_SPACE 10 +#define PM_GETMODULEPATH_CB (WM_APP+0x21) + /// NotifyIconIndex is used for maintaining the order of notification icons. struct NotifyIconIndex @@ -75,6 +77,19 @@ typedef map NotifyIconMap; typedef set NotifyIconSet; +struct NotifyHook +{ + NotifyHook(); + ~NotifyHook(); + + void GetModulePath(HWND hwnd, HWND hwndCallback); + bool ModulePathCopyData(LPARAM lparam, HWND* phwnd, String& path); + +protected: + const UINT WM_GETMODULEPATH; +}; + + /// tray notification area aka "tray" struct NotifyArea : public Window { @@ -111,6 +126,9 @@ protected: NotifyIconSet::iterator IconHitTest(const POINT& pos); bool DetermineHideState(NotifyInfo& entry); + + NotifyHook _hook; + map _window_modules; }; diff --git a/reactos/subsys/system/explorer/utility/window.h b/reactos/subsys/system/explorer/utility/window.h index 4aa7dcbf6f7..701d31ec766 100644 --- a/reactos/subsys/system/explorer/utility/window.h +++ b/reactos/subsys/system/explorer/utility/window.h @@ -315,7 +315,7 @@ protected: String _statusText; }; -#define PM_SETSTATUSTEXT (WM_APP+0x1D) +#define PM_SETSTATUSTEXT (WM_APP+0x1E) /** @@ -957,7 +957,7 @@ protected: enum {TRAYBUTTON_LEFT=0, TRAYBUTTON_RIGHT, TRAYBUTTON_MIDDLE}; -#define PM_TRAYICON (WM_APP+0x1E) +#define PM_TRAYICON (WM_APP+0x20) #define WINMSG_TASKBARCREATED TEXT("TaskbarCreated")