mirror of
https://github.com/reactos/reactos.git
synced 2025-04-19 12:08:55 +00:00
launch all registered Shell Service Objects (Systray, network icons, ...)
svn path=/trunk/; revision=14361
This commit is contained in:
parent
f9a85ac5fb
commit
9b8f8ea446
20 changed files with 332 additions and 68 deletions
|
@ -45,10 +45,11 @@ TARGET_OBJECTS := \
|
|||
shell/pane.o \
|
||||
shell/regfs.o \
|
||||
shell/shellbrowser.o \
|
||||
shell/startup.o \
|
||||
shell/unixfs.o \
|
||||
shell/webchild.o \
|
||||
shell/winfs.o \
|
||||
services/startup.o \
|
||||
services/shellservices.o \
|
||||
taskbar/desktopbar.o \
|
||||
taskbar/taskbar.o \
|
||||
taskbar/startmenu.o \
|
||||
|
|
|
@ -38,7 +38,7 @@ CXXFLAGS = $(CFLAGS)
|
|||
EXEC_SUFFIX = .exe
|
||||
RES_SUFFIX = .coff
|
||||
|
||||
VPATH = shell utility taskbar desktop dialogs
|
||||
VPATH = shell utility taskbar desktop dialogs services
|
||||
|
||||
PROGRAM = explorer
|
||||
|
||||
|
@ -51,6 +51,7 @@ OBJECTS = \
|
|||
window.o \
|
||||
dragdropimpl.o \
|
||||
shellbrowserimpl.o \
|
||||
shellservices.o \
|
||||
explorer.o \
|
||||
entries.o \
|
||||
winfs.o \
|
||||
|
|
|
@ -39,7 +39,7 @@ CXXFLAGS = $(CFLAGS)
|
|||
EXEC_SUFFIX = .exe
|
||||
RES_SUFFIX = .coff
|
||||
|
||||
VPATH = shell utility taskbar desktop dialogs
|
||||
VPATH = shell utility taskbar desktop dialogs services
|
||||
|
||||
PROGRAM = explorer
|
||||
|
||||
|
@ -69,6 +69,7 @@ OBJECTS = \
|
|||
desktopbar.o \
|
||||
taskbar.o \
|
||||
startmenu.o \
|
||||
shellservices.o \
|
||||
traynotify.o \
|
||||
quicklaunch.o \
|
||||
favorites.o \
|
||||
|
|
|
@ -10,7 +10,7 @@ EXTRA_OBJS = notifyhook.dll libexpat.dll
|
|||
EXTRALIBS = $(LIBUUID)
|
||||
|
||||
C_SRCS = \
|
||||
shell/startup.c \
|
||||
services/startup.c \
|
||||
utility/splitpath.c
|
||||
|
||||
CPP_SRCS = \
|
||||
|
@ -34,6 +34,7 @@ CPP_SRCS = \
|
|||
shell/regfs.cpp \
|
||||
shell/fatfs.cpp \
|
||||
shell/webchild.cpp \
|
||||
services/shellservices.cpp \
|
||||
taskbar/desktopbar.cpp \
|
||||
taskbar/taskbar.cpp \
|
||||
taskbar/startmenu.cpp \
|
||||
|
|
|
@ -41,6 +41,8 @@
|
|||
|
||||
#include "dialogs/settings.h" // for MdiSdiDlg
|
||||
|
||||
#include "services/shellservices.h"
|
||||
|
||||
|
||||
extern "C" int initialize_gdb_stub(); // start up GDB stub
|
||||
|
||||
|
@ -829,7 +831,9 @@ int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdL
|
|||
// another undocumented event: "Global\\msgina: ReturnToWelcome"
|
||||
if (!SetShellReadyEvent(TEXT("msgina: ShellReadyEvent")))
|
||||
SetShellReadyEvent(TEXT("Global\\msgina: ShellReadyEvent"));
|
||||
}
|
||||
|
||||
if (!any_desktop_running) {
|
||||
// launch the shell DDE server
|
||||
if (g_SHDOCVW_ShellDDEInit)
|
||||
(*g_SHDOCVW_ShellDDEInit)(TRUE);
|
||||
|
@ -868,19 +872,32 @@ int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdL
|
|||
g_Globals.read_persistent();
|
||||
|
||||
if (startup_desktop) {
|
||||
WaitCursor wait;
|
||||
|
||||
g_Globals._desktops.init();
|
||||
|
||||
g_Globals._hwndDesktop = DesktopWindow::Create();
|
||||
#ifdef _USE_HDESK
|
||||
g_Globals._desktops.get_current_Desktop()->_hwndDesktop = g_Globals._hwndDesktop;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (g_Globals._hwndDesktop)
|
||||
g_Globals._desktop_mode = true;
|
||||
|
||||
Thread* pSSOThread = NULL;
|
||||
|
||||
if (startup_desktop) {
|
||||
// launch SSO thread to allow message processing independent from the explorer main thread
|
||||
pSSOThread = new SSOThread;
|
||||
pSSOThread->Start();
|
||||
}
|
||||
|
||||
/**TODO launching autostart programs can be moved into a background thread. */
|
||||
if (autostart) {
|
||||
char* argv[] = {"", "s"}; // call startup routine in SESSION_START mode
|
||||
startup(2, argv);
|
||||
}
|
||||
}
|
||||
|
||||
/**TODO fix command line handling */
|
||||
if (*lpCmdLine=='"' && lpCmdLine[_tcslen(lpCmdLine)-1]=='"') {
|
||||
|
@ -888,17 +905,21 @@ int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdL
|
|||
lpCmdLine[_tcslen(lpCmdLine)-1] = '\0';
|
||||
}
|
||||
|
||||
if (g_Globals._hwndDesktop)
|
||||
g_Globals._desktop_mode = true;
|
||||
|
||||
int ret = explorer_main(hInstance, lpCmdLine, nShowCmd);
|
||||
|
||||
// write configuration file
|
||||
g_Globals.write_persistent();
|
||||
|
||||
if (pSSOThread) {
|
||||
pSSOThread->Stop();
|
||||
delete pSSOThread;
|
||||
}
|
||||
|
||||
if (!any_desktop_running) {
|
||||
// shutdown the shell DDE server
|
||||
if (g_SHDOCVW_ShellDDEInit)
|
||||
(*g_SHDOCVW_ShellDDEInit)(FALSE);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -702,11 +702,6 @@ SOURCE=.\shell\shellfs.h
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\shell\startup.c
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\shell\unixfs.cpp
|
||||
# PROP Exclude_From_Build 1
|
||||
# End Source File
|
||||
|
@ -785,5 +780,22 @@ SOURCE=.\precomp.cpp
|
|||
SOURCE=.\precomp.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "services"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\services\shellservices.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\services\shellservices.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\services\startup.c
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
||||
|
|
|
@ -31,9 +31,6 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
|
||||
// launch start programs
|
||||
extern int startup(int argc, char *argv[]);
|
||||
|
||||
// explorer main routine
|
||||
extern int explorer_main(HINSTANCE hinstance, LPTSTR lpCmdLine, int cmdshow);
|
||||
|
||||
|
|
95
reactos/subsys/system/explorer/services/shellservices.cpp
Normal file
95
reactos/subsys/system/explorer/services/shellservices.cpp
Normal file
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* Copyright 2005 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
|
||||
*/
|
||||
|
||||
|
||||
//
|
||||
// Explorer clone
|
||||
//
|
||||
// shellservices.cpp
|
||||
//
|
||||
// Martin Fuchs, 28.03.2005
|
||||
//
|
||||
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
#include "shellservices.h"
|
||||
|
||||
|
||||
int SSOThread::Run()
|
||||
{
|
||||
ComInit usingCOM(COINIT_APARTMENTTHREADED|COINIT_DISABLE_OLE1DDE|COINIT_SPEED_OVER_MEMORY);
|
||||
|
||||
HKEY hkey;
|
||||
CLSID clsid;
|
||||
WCHAR name[MAX_PATH], value[MAX_PATH];
|
||||
|
||||
typedef vector<SIfacePtr<IOleCommandTarget>*> SSOVector;
|
||||
SSOVector sso_ptrs;
|
||||
|
||||
if (!RegOpenKey(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\ShellServiceObjectDelayLoad"), &hkey)) {
|
||||
for(int idx=0; ; ++idx) {
|
||||
DWORD name_len = MAX_PATH;
|
||||
DWORD value_len = sizeof(value);
|
||||
|
||||
if (RegEnumValueW(hkey, idx, name, &name_len, 0, NULL, (LPBYTE)&value, &value_len))
|
||||
break;
|
||||
|
||||
if (!_alive)
|
||||
break;
|
||||
|
||||
SIfacePtr<IOleCommandTarget>* sso_ptr = new SIfacePtr<IOleCommandTarget>;
|
||||
|
||||
if (CLSIDFromString(value, &clsid) == NOERROR) {
|
||||
if (SUCCEEDED(sso_ptr->CreateInstance(clsid, IID_IOleCommandTarget))) {
|
||||
if (SUCCEEDED((*sso_ptr)->Exec(&CGID_ShellServiceObject, OLECMDID_NEW, OLECMDEXECOPT_DODEFAULT, NULL, NULL)))
|
||||
sso_ptrs.push_back(sso_ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RegCloseKey(hkey);
|
||||
}
|
||||
|
||||
MSG msg;
|
||||
|
||||
while(_alive) {
|
||||
if (MsgWaitForMultipleObjects(1, &_evtFinish, FALSE, INFINITE, QS_ALLINPUT) == WAIT_OBJECT_0+0)
|
||||
break; // _evtFinish has been set.
|
||||
|
||||
while(_alive) {
|
||||
if (!PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
|
||||
break;
|
||||
|
||||
if (msg.message == WM_QUIT)
|
||||
break;
|
||||
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
}
|
||||
|
||||
// shutdown all running Shell Service Objects
|
||||
for(SSOVector::iterator it=sso_ptrs.begin(); it!=sso_ptrs.end(); ++it) {
|
||||
SIfacePtr<IOleCommandTarget>* sso_ptr = *it;
|
||||
(*sso_ptr)->Exec(&CGID_ShellServiceObject, OLECMDID_SAVE, OLECMDEXECOPT_DODEFAULT, NULL, NULL);
|
||||
delete sso_ptr;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
36
reactos/subsys/system/explorer/services/shellservices.h
Normal file
36
reactos/subsys/system/explorer/services/shellservices.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright 2005 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
|
||||
*/
|
||||
|
||||
|
||||
//
|
||||
// Explorer clone
|
||||
//
|
||||
// shellservices.h
|
||||
//
|
||||
// Martin Fuchs, 28.03.2005
|
||||
//
|
||||
|
||||
|
||||
// launch start programs
|
||||
extern "C" int startup(int argc, char *argv[]);
|
||||
|
||||
// load Shell Service Objects (volume control, printer/network icons, ...)
|
||||
struct SSOThread : public Thread
|
||||
{
|
||||
int Run();
|
||||
};
|
|
@ -163,7 +163,7 @@ void Pane::init()
|
|||
HKEY hkeyExplorer = 0;
|
||||
DWORD len = sizeof(_clrCompressed);
|
||||
|
||||
if (RegOpenKey(HKEY_CURRENT_USER, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer"), &hkeyExplorer) ||
|
||||
if (RegOpenKey(HKEY_CURRENT_USER, TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer"), &hkeyExplorer) ||
|
||||
RegQueryValueEx(hkeyExplorer, TEXT("AltColor"), 0, NULL, (LPBYTE)&_clrCompressed, &len) || len!=sizeof(_clrCompressed))
|
||||
_clrCompressed = RGB(0,0,255);
|
||||
|
||||
|
|
|
@ -43,9 +43,9 @@ void RegDirectory::read_directory(int scan_flags)
|
|||
_tcscpy(buffer, (LPCTSTR)_path);
|
||||
LPTSTR pname = buffer + _tcslen(buffer);
|
||||
|
||||
HKEY hKey;
|
||||
HKEY hkey;
|
||||
|
||||
if (!RegOpenKeyEx(_hKeyRoot, *buffer=='\\'?buffer+1:buffer, 0, STANDARD_RIGHTS_READ|KEY_QUERY_VALUE|KEY_ENUMERATE_SUB_KEYS, &hKey)) {
|
||||
if (!RegOpenKeyEx(_hKeyRoot, *buffer=='\\'?buffer+1:buffer, 0, STANDARD_RIGHTS_READ|KEY_QUERY_VALUE|KEY_ENUMERATE_SUB_KEYS, &hkey)) {
|
||||
if (pname[-1] != '\\')
|
||||
*pname++ = '\\';
|
||||
|
||||
|
@ -60,7 +60,7 @@ void RegDirectory::read_directory(int scan_flags)
|
|||
DWORD name_len = MAX_PATH;
|
||||
DWORD class_len = MAX_PATH;
|
||||
|
||||
if (RegEnumKeyEx(hKey, idx, name, &name_len, 0, class_name, &class_len, &w32fd.ftLastWriteTime))
|
||||
if (RegEnumKeyEx(hkey, idx, name, &name_len, 0, class_name, &class_len, &w32fd.ftLastWriteTime))
|
||||
break;
|
||||
|
||||
w32fd.dwFileAttributes |= FILE_ATTRIBUTE_DIRECTORY;
|
||||
|
@ -88,7 +88,7 @@ void RegDirectory::read_directory(int scan_flags)
|
|||
TCHAR value[MAX_PATH];
|
||||
LONG value_len = sizeof(value);
|
||||
|
||||
if (!RegQueryValue(hKey, NULL, value, &value_len) && value_len>1) {
|
||||
if (!RegQueryValue(hkey, NULL, value, &value_len) && value_len>1) {
|
||||
memset(&w32fd, 0, sizeof(WIN32_FIND_DATA));
|
||||
|
||||
lstrcpy(w32fd.cFileName, TEXT("(Default)"));
|
||||
|
@ -114,7 +114,7 @@ void RegDirectory::read_directory(int scan_flags)
|
|||
for(int idx=0; ; ++idx) {
|
||||
DWORD name_len = MAX_PATH;
|
||||
|
||||
if (RegEnumValue(hKey, idx, name, &name_len, 0, &type, NULL, NULL))
|
||||
if (RegEnumValue(hkey, idx, name, &name_len, 0, &type, NULL, NULL))
|
||||
break;
|
||||
|
||||
memset(&w32fd, 0, sizeof(WIN32_FIND_DATA));
|
||||
|
@ -147,7 +147,7 @@ void RegDirectory::read_directory(int scan_flags)
|
|||
TCHAR value[MAX_PATH];
|
||||
DWORD value_len = sizeof(value);
|
||||
|
||||
if (!RegQueryValueEx(hKey, name, NULL, NULL, (LPBYTE)value, &value_len)) {
|
||||
if (!RegQueryValueEx(hkey, name, NULL, NULL, (LPBYTE)value, &value_len)) {
|
||||
if (type==REG_SZ || type==REG_EXPAND_SZ || type==REG_LINK)
|
||||
entry->_content = _tcsdup(value);
|
||||
else if (type == REG_DWORD) {
|
||||
|
@ -171,7 +171,7 @@ void RegDirectory::read_directory(int scan_flags)
|
|||
if (last)
|
||||
last->_next = NULL;
|
||||
|
||||
RegCloseKey(hKey);
|
||||
RegCloseKey(hkey);
|
||||
}
|
||||
|
||||
_down = first_entry;
|
||||
|
|
|
@ -41,7 +41,11 @@
|
|||
|
||||
DesktopBar::DesktopBar(HWND hwnd)
|
||||
: super(hwnd),
|
||||
#ifdef _ROS_
|
||||
_trayIcon(hwnd, ID_TRAY_VOLUME)
|
||||
#else
|
||||
WM_TASKBARCREATED(RegisterWindowMessage(WINMSG_TASKBARCREATED))
|
||||
#endif
|
||||
{
|
||||
SetWindowIcon(hwnd, IDI_REACTOS/*IDI_SEARCH*/); // icon in for TrayNotifyDlg
|
||||
|
||||
|
@ -107,6 +111,12 @@ LRESULT DesktopBar::Init(LPCREATESTRUCT pcs)
|
|||
// create tray notification area
|
||||
_hwndNotify = NotifyArea::Create(_hwnd);
|
||||
|
||||
|
||||
// notify all top level windows about the successfully created desktop bar
|
||||
//@@ Use SendMessage() instead of PostMessage() to avoid problems with delayed created shell service objects?
|
||||
PostMessage(HWND_BROADCAST, WM_TASKBARCREATED, 0, 0);
|
||||
|
||||
|
||||
_hwndQuickLaunch = QuickLaunchBar::Create(_hwnd);
|
||||
|
||||
// create rebar window to manage task and quick launch bar
|
||||
|
@ -147,10 +157,8 @@ LRESULT DesktopBar::Init(LPCREATESTRUCT pcs)
|
|||
SendMessage(_hwndrebar, RB_INSERTBAND, (WPARAM)-1, (LPARAM)&rbBand);
|
||||
#endif
|
||||
|
||||
RegisterHotkeys();
|
||||
|
||||
// notify all top level windows about the successfully created desktop bar
|
||||
PostMessage(HWND_BROADCAST, WM_TASKBARCREATED, 0, 0);
|
||||
RegisterHotkeys();
|
||||
|
||||
// prepare Startmenu, but hide it for now
|
||||
_startMenuRoot = GET_WINDOW(StartMenuRoot, StartMenuRoot::Create(_hwnd));
|
||||
|
@ -332,6 +340,7 @@ int DesktopBar::Command(int id, int code)
|
|||
PostMessage(_hwndQuickLaunch, PM_UPDATE_DESKTOP, desktop_idx, 0);
|
||||
break;}
|
||||
|
||||
#ifdef _ROS_
|
||||
case ID_TRAY_VOLUME:
|
||||
launch_file(_hwnd, TEXT("sndvol32.exe"), SW_SHOWNORMAL); // launch volume control application
|
||||
break;
|
||||
|
@ -339,6 +348,7 @@ int DesktopBar::Command(int id, int code)
|
|||
case ID_VOLUME_PROPERTIES:
|
||||
launch_cpanel(_hwnd, TEXT("mmsys.cpl"));
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
if (_hwndQuickLaunch)
|
||||
|
@ -381,6 +391,8 @@ LRESULT DesktopBar::ProcessCopyData(COPYDATASTRUCT* pcd)
|
|||
}
|
||||
|
||||
|
||||
#ifdef _ROS_
|
||||
|
||||
void DesktopBar::AddTrayIcons()
|
||||
{
|
||||
_trayIcon.Add(SmallIcon(IDI_SPEAKER), ResString(IDS_VOLUME));
|
||||
|
@ -410,3 +422,5 @@ void DesktopBar::TrayDblClick(UINT id, int btn)
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -61,11 +61,20 @@
|
|||
|
||||
|
||||
/// desktop bar window, also known as "system tray"
|
||||
struct DesktopBar : public TrayIconControllerTemplate<
|
||||
struct DesktopBar : public
|
||||
#ifdef _ROS_
|
||||
TrayIconControllerTemplate<
|
||||
OwnerDrawParent<Window> >
|
||||
#else
|
||||
OwnerDrawParent<Window>
|
||||
#endif
|
||||
{
|
||||
#ifdef _ROS_
|
||||
typedef TrayIconControllerTemplate<
|
||||
OwnerDrawParent<Window> > super;
|
||||
#else
|
||||
typedef OwnerDrawParent<Window> super;
|
||||
#endif
|
||||
|
||||
DesktopBar(HWND hwnd);
|
||||
~DesktopBar();
|
||||
|
@ -93,9 +102,13 @@ protected:
|
|||
|
||||
struct StartMenuRoot* _startMenuRoot;
|
||||
|
||||
#ifdef _ROS_
|
||||
TrayIcon _trayIcon;
|
||||
|
||||
void AddTrayIcons();
|
||||
virtual void TrayClick(UINT id, int btn);
|
||||
virtual void TrayDblClick(UINT id, int btn);
|
||||
#else
|
||||
const UINT WM_TASKBARCREATED;
|
||||
#endif
|
||||
};
|
||||
|
|
|
@ -144,6 +144,7 @@ LRESULT TaskBar::Init(LPCREATESTRUCT pcs)
|
|||
(*g_RegisterShellHookWindow)(_hwnd);
|
||||
} else {
|
||||
LOG(TEXT("Shell hooks not available."));
|
||||
|
||||
SetTimer(_hwnd, 0, 200, NULL);
|
||||
}
|
||||
|
||||
|
@ -188,8 +189,6 @@ LRESULT TaskBar::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
|
|||
|
||||
default: def:
|
||||
if (nmsg == WM_SHELLHOOK) {
|
||||
LOG(FmtString(TEXT("SHELLHOOK %x"), wparam));
|
||||
|
||||
switch(wparam) {
|
||||
case HSHELL_WINDOWCREATED:
|
||||
case HSHELL_WINDOWDESTROYED:
|
||||
|
|
|
@ -104,13 +104,23 @@ NotifyInfo::NotifyInfo()
|
|||
#define NID_SIZE_A5 (sizeof(NOTIFYICONDATAA)-sizeof(GUID))
|
||||
#define NID_SIZE_A3 (sizeof(NOTIFYICONDATAA)-sizeof(GUID)-(128-64)*sizeof(CHAR))
|
||||
|
||||
NotifyInfo& NotifyInfo::operator=(NOTIFYICONDATA* pnid)
|
||||
bool NotifyInfo::modify(NOTIFYICONDATA* pnid)
|
||||
{
|
||||
bool changes = false;
|
||||
|
||||
if (_hWnd!=pnid->hWnd || _uID!=pnid->uID) {
|
||||
_hWnd = pnid->hWnd;
|
||||
_uID = pnid->uID;
|
||||
|
||||
if (pnid->uFlags & NIF_MESSAGE)
|
||||
changes = true;
|
||||
}
|
||||
|
||||
if (pnid->uFlags & NIF_MESSAGE) {
|
||||
if (_uCallbackMessage != pnid->uCallbackMessage) {
|
||||
_uCallbackMessage = pnid->uCallbackMessage;
|
||||
changes = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (pnid->uFlags & NIF_ICON) {
|
||||
// Some applications destroy the icon immediatelly after completing the
|
||||
|
@ -119,15 +129,25 @@ NotifyInfo& NotifyInfo::operator=(NOTIFYICONDATA* pnid)
|
|||
DestroyIcon(_hIcon);
|
||||
|
||||
_hIcon = (HICON) CopyImage(pnid->hIcon, IMAGE_ICON, NOTIFYICON_SIZE, NOTIFYICON_SIZE, 0);
|
||||
|
||||
changes = true; ///@todo compare icon
|
||||
}
|
||||
|
||||
#ifdef NIF_STATE // as of 21.08.2003 missing in MinGW headers
|
||||
if (pnid->uFlags & NIF_STATE)
|
||||
_dwState = (_dwState&~pnid->dwStateMask) | (pnid->dwState&pnid->dwStateMask);
|
||||
if (pnid->uFlags & NIF_STATE) {
|
||||
DWORD new_state = (_dwState&~pnid->dwStateMask) | (pnid->dwState&pnid->dwStateMask);
|
||||
|
||||
if (_dwState != new_state) {
|
||||
_dwState = new_state;
|
||||
changes = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// store tool tip text
|
||||
if (pnid->uFlags & NIF_TIP)
|
||||
if (pnid->uFlags & NIF_TIP) {
|
||||
String new_text;
|
||||
|
||||
if (pnid->cbSize==NID_SIZE_W6 || pnid->cbSize==NID_SIZE_W5 || pnid->cbSize==NID_SIZE_W3) {
|
||||
// UNICODE version of NOTIFYICONDATA structure
|
||||
LPCWSTR txt = (LPCWSTR)pnid->szTip;
|
||||
|
@ -139,7 +159,12 @@ NotifyInfo& NotifyInfo::operator=(NOTIFYICONDATA* pnid)
|
|||
if (!txt[l])
|
||||
break;
|
||||
|
||||
_tipText.assign(txt, l);
|
||||
new_text.assign(txt, l);
|
||||
|
||||
if (new_text != _tipText) {
|
||||
_tipText = new_text;
|
||||
changes = true;
|
||||
}
|
||||
} else if (pnid->cbSize==NID_SIZE_A6 || pnid->cbSize==NID_SIZE_A5 || pnid->cbSize==NID_SIZE_A3) {
|
||||
LPCSTR txt = (LPCSTR)pnid->szTip;
|
||||
int max_len = pnid->cbSize==NID_SIZE_A3? 64: 128;
|
||||
|
@ -149,20 +174,35 @@ NotifyInfo& NotifyInfo::operator=(NOTIFYICONDATA* pnid)
|
|||
if (!txt[l])
|
||||
break;
|
||||
|
||||
_tipText.assign(txt, l);
|
||||
new_text.assign(txt, l);
|
||||
|
||||
if (new_text != _tipText) {
|
||||
_tipText = new_text;
|
||||
changes = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TCHAR title[MAX_PATH];
|
||||
|
||||
if (GetWindowText(_hWnd, title, MAX_PATH))
|
||||
DWORD pid;
|
||||
GetWindowThreadProcessId(_hWnd, &pid);
|
||||
|
||||
// avoid to send WM_GETTEXT messages to the own process
|
||||
if (pid != GetCurrentProcessId())
|
||||
if (GetWindowText(_hWnd, title, MAX_PATH)) {
|
||||
if (_windowTitle != title) {
|
||||
_windowTitle = title;
|
||||
changes = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (changes) {
|
||||
create_name();
|
||||
|
||||
///@todo test for real changes
|
||||
_lastChange = GetTickCount();
|
||||
}
|
||||
|
||||
return *this;
|
||||
return changes;
|
||||
}
|
||||
|
||||
|
||||
|
@ -194,7 +234,7 @@ static bool get_hide_clock_from_registry()
|
|||
bool hide_clock = false;
|
||||
|
||||
// check if the clock should be hidden
|
||||
if (!RegOpenKey(HKEY_CURRENT_USER, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\StuckRects2"), &hkeyStuckRects) &&
|
||||
if (!RegOpenKey(HKEY_CURRENT_USER, TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\StuckRects2"), &hkeyStuckRects) &&
|
||||
!RegQueryValueEx(hkeyStuckRects, TEXT("Settings"), 0, NULL, (LPBYTE)buffer, &len) &&
|
||||
len==sizeof(buffer) && buffer[0]==sizeof(buffer))
|
||||
hide_clock = buffer[2] & 0x08? true: false;
|
||||
|
@ -338,7 +378,7 @@ HWND NotifyArea::Create(HWND hwndParent)
|
|||
ClientRect clnt(hwndParent);
|
||||
|
||||
return Window::Create(WINDOW_CREATOR(NotifyArea), WS_EX_STATICEDGE,
|
||||
wcTrayNotify, TITLE_TRAYNOTIFY, WS_CHILD|WS_VISIBLE,
|
||||
wcTrayNotify, TITLE_TRAYNOTIFY, WS_CHILD|WS_VISIBLE|WS_CLIPCHILDREN,
|
||||
clnt.right-(NOTIFYAREA_WIDTH_DEF+1), 1, NOTIFYAREA_WIDTH_DEF, clnt.bottom-2, hwndParent);
|
||||
}
|
||||
|
||||
|
@ -448,6 +488,10 @@ LRESULT NotifyArea::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
|
|||
(*AllowSetForegroundWindow)(pid);
|
||||
}
|
||||
|
||||
// use PostMessage() for notifcation icons of Shell Service Objects in the own process
|
||||
if (pid == GetCurrentProcessId())
|
||||
PostMessage(entry._hWnd, entry._uCallbackMessage, entry._uID, nmsg);
|
||||
else
|
||||
SendMessage(entry._hWnd, entry._uCallbackMessage, entry._uID, nmsg);
|
||||
}
|
||||
}
|
||||
|
@ -540,17 +584,34 @@ LRESULT NotifyArea::ProcessTrayNotification(int notify_code, NOTIFYICONDATA* pni
|
|||
case NIM_ADD:
|
||||
case NIM_MODIFY:
|
||||
if ((int)pnid->uID >= 0) { ///@todo This is a fix for Windows Task Manager.
|
||||
NotifyInfo& entry = _icon_map[pnid] = pnid;
|
||||
NotifyInfo& entry = _icon_map[pnid];
|
||||
|
||||
// a new entry?
|
||||
if (entry._idx == -1)
|
||||
entry._idx = ++_next_idx;
|
||||
/*
|
||||
NotifyIconMap::iterator found = _icon_map.find(pnid);
|
||||
NotifyInfo* pentry;
|
||||
// a new entry?
|
||||
if (found == _icon_map.end()) {
|
||||
pentry = &_icon_map[pnid];
|
||||
pentry->_idx = ++_next_idx;
|
||||
} else {
|
||||
pentry = &found->second;
|
||||
*pentry = pnid;
|
||||
}
|
||||
NotifyInfo& entry = *pentry;
|
||||
*/
|
||||
bool changes = entry.modify(pnid);
|
||||
|
||||
#if NOTIFYICON_VERSION>=3 // as of 21.08.2003 missing in MinGW headers
|
||||
if (DetermineHideState(entry) && entry._mode==NIM_HIDE)
|
||||
if (DetermineHideState(entry) && entry._mode==NIM_HIDE) {
|
||||
entry._dwState |= NIS_HIDDEN;
|
||||
changes = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (changes)
|
||||
UpdateIcons(); ///@todo call only if really changes occurred
|
||||
|
||||
return TRUE;
|
||||
|
@ -1290,6 +1351,8 @@ void ClockWindow::Paint()
|
|||
{
|
||||
PaintCanvas canvas(_hwnd);
|
||||
|
||||
FillRect(canvas, &canvas.rcPaint, GetSysColorBrush(COLOR_BTNFACE));
|
||||
|
||||
BkMode bkmode(canvas, TRANSPARENT);
|
||||
FontSelection font(canvas, GetStockFont(ANSI_VAR_FONT));
|
||||
|
||||
|
|
|
@ -98,7 +98,7 @@ struct NotifyInfo : public NotifyIconIndex, public NotifyIconConfig
|
|||
friend bool operator<(const NotifyInfo& a, const NotifyInfo& b)
|
||||
{return a._idx < b._idx;}
|
||||
|
||||
NotifyInfo& operator=(NOTIFYICONDATA* pnid);
|
||||
bool modify(NOTIFYICONDATA* pnid);
|
||||
|
||||
int _idx; // display index
|
||||
HICON _hIcon;
|
||||
|
|
|
@ -281,11 +281,11 @@ String get_windows_version_str()
|
|||
} else {
|
||||
TCHAR type[80];
|
||||
DWORD dwBufLen;
|
||||
HKEY hKey;
|
||||
HKEY hkey;
|
||||
|
||||
if (!RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\CurrentControlSet\\Control\\ProductOptions"), 0, KEY_QUERY_VALUE, &hKey)) {
|
||||
RegQueryValueEx(hKey, TEXT("ProductType"), NULL, NULL, (LPBYTE)type, &dwBufLen);
|
||||
RegCloseKey(hKey);
|
||||
if (!RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\CurrentControlSet\\Control\\ProductOptions"), 0, KEY_QUERY_VALUE, &hkey)) {
|
||||
RegQueryValueEx(hkey, TEXT("ProductType"), NULL, NULL, (LPBYTE)type, &dwBufLen);
|
||||
RegCloseKey(hkey);
|
||||
|
||||
if (!_tcsicmp(TEXT("WINNT"), type))
|
||||
str += TEXT(" Workstation");
|
||||
|
|
|
@ -317,16 +317,22 @@ protected:
|
|||
struct Thread
|
||||
{
|
||||
Thread()
|
||||
: _alive(false)
|
||||
: _alive(false),
|
||||
_destroy(false)
|
||||
{
|
||||
_hThread = INVALID_HANDLE_VALUE;
|
||||
_evtFinish = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
}
|
||||
|
||||
virtual ~Thread()
|
||||
{
|
||||
Stop();
|
||||
|
||||
CloseHandle(_evtFinish);
|
||||
CloseHandle(_hThread);
|
||||
|
||||
if (_destroy)
|
||||
delete this;
|
||||
}
|
||||
|
||||
void Start()
|
||||
|
@ -339,6 +345,8 @@ struct Thread
|
|||
|
||||
void Stop()
|
||||
{
|
||||
SetEvent(_evtFinish);
|
||||
|
||||
if (_alive) {
|
||||
{
|
||||
Lock lock(_crit_sect);
|
||||
|
@ -360,7 +368,9 @@ protected:
|
|||
static DWORD WINAPI ThreadProc(void* para);
|
||||
|
||||
HANDLE _hThread;
|
||||
HANDLE _evtFinish;
|
||||
bool _alive;
|
||||
bool _destroy;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -277,7 +277,7 @@ LRESULT CALLBACK Window::WindowWndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPAR
|
|||
|
||||
LRESULT Window::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
|
||||
{
|
||||
/*@@TODO: replaced by StartMenu::TrackStartmenu()
|
||||
/**@todo: replaced by StartMenu::TrackStartmenu()
|
||||
HWND hwnd = _hwnd;
|
||||
|
||||
// close startup menu and other popup menus
|
||||
|
@ -352,7 +352,7 @@ LRESULT CALLBACK SubclassedWindow::SubclassedWndProc(HWND hwnd, UINT nmsg, WPARA
|
|||
|
||||
LRESULT SubclassedWindow::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
|
||||
{
|
||||
/*@@TODO: replaced by StartMenu::TrackStartmenu()
|
||||
/**@todo: replaced by StartMenu::TrackStartmenu()
|
||||
// close startup menu and other popup menus
|
||||
// This functionality is for tray notification icons missing in MS Windows.
|
||||
if (nmsg == WM_SETFOCUS)
|
||||
|
|
Loading…
Reference in a new issue