xref: /AOO41X/main/sfx2/source/appl/shutdowniconw32.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_sfx2.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir #ifdef WNT
32*cdf0e10cSrcweir 
33*cdf0e10cSrcweir // necessary to include system headers without warnings
34*cdf0e10cSrcweir #ifdef _MSC_VER
35*cdf0e10cSrcweir #pragma warning(disable:4668 4917)
36*cdf0e10cSrcweir #endif
37*cdf0e10cSrcweir 
38*cdf0e10cSrcweir // Support Windows 95 too
39*cdf0e10cSrcweir #undef WINVER
40*cdf0e10cSrcweir #define WINVER 0x0400
41*cdf0e10cSrcweir #define USE_APP_SHORTCUTS
42*cdf0e10cSrcweir //
43*cdf0e10cSrcweir // the systray icon is only available on windows
44*cdf0e10cSrcweir //
45*cdf0e10cSrcweir 
46*cdf0e10cSrcweir #include <unotools/moduleoptions.hxx>
47*cdf0e10cSrcweir #include <unotools/dynamicmenuoptions.hxx>
48*cdf0e10cSrcweir 
49*cdf0e10cSrcweir #include "shutdownicon.hxx"
50*cdf0e10cSrcweir #include "app.hrc"
51*cdf0e10cSrcweir #include <shlobj.h>
52*cdf0e10cSrcweir #include <objidl.h>
53*cdf0e10cSrcweir #include <stdio.h>
54*cdf0e10cSrcweir #include <io.h>
55*cdf0e10cSrcweir #include <osl/thread.h>
56*cdf0e10cSrcweir #include <setup_native/qswin32.h>
57*cdf0e10cSrcweir #include <comphelper/sequenceashashmap.hxx>
58*cdf0e10cSrcweir #include <comphelper/processfactory.hxx>
59*cdf0e10cSrcweir #include <com/sun/star/uno/Reference.h>
60*cdf0e10cSrcweir #include <com/sun/star/lang/XMultiServiceFactory.hpp>
61*cdf0e10cSrcweir #include <com/sun/star/task/XJob.hpp>
62*cdf0e10cSrcweir #include <com/sun/star/beans/NamedValue.hpp>
63*cdf0e10cSrcweir 
64*cdf0e10cSrcweir #include <set>
65*cdf0e10cSrcweir 
66*cdf0e10cSrcweir using namespace ::rtl;
67*cdf0e10cSrcweir using namespace ::com::sun::star::uno;
68*cdf0e10cSrcweir using namespace ::com::sun::star::task;
69*cdf0e10cSrcweir using namespace ::com::sun::star::lang;
70*cdf0e10cSrcweir using namespace ::com::sun::star::beans;
71*cdf0e10cSrcweir using namespace ::osl;
72*cdf0e10cSrcweir 
73*cdf0e10cSrcweir 
74*cdf0e10cSrcweir #define EXECUTER_WINDOWCLASS    "SO Executer Class"
75*cdf0e10cSrcweir #define EXECUTER_WINDOWNAME     "SO Executer Window"
76*cdf0e10cSrcweir 
77*cdf0e10cSrcweir 
78*cdf0e10cSrcweir #define ID_QUICKSTART               1
79*cdf0e10cSrcweir #define IDM_EXIT                    2
80*cdf0e10cSrcweir #if defined(USE_APP_SHORTCUTS)
81*cdf0e10cSrcweir #	define IDM_OPEN                    3
82*cdf0e10cSrcweir #	define IDM_WRITER                  4
83*cdf0e10cSrcweir #	define IDM_CALC                    5
84*cdf0e10cSrcweir #	define IDM_IMPRESS                 6
85*cdf0e10cSrcweir #	define IDM_DRAW                    7
86*cdf0e10cSrcweir #   define IDM_BASE                    8
87*cdf0e10cSrcweir #   define IDM_TEMPLATE                9
88*cdf0e10cSrcweir #	define IDM_MATH					  12
89*cdf0e10cSrcweir #endif
90*cdf0e10cSrcweir #define IDM_INSTALL                 10
91*cdf0e10cSrcweir #define IDM_UNINSTALL               11
92*cdf0e10cSrcweir 
93*cdf0e10cSrcweir 
94*cdf0e10cSrcweir #define ICON_SO_DEFAULT 				1
95*cdf0e10cSrcweir #define ICON_TEXT_DOCUMENT				2
96*cdf0e10cSrcweir #define ICON_TEXT_TEMPLATE				3
97*cdf0e10cSrcweir #define ICON_SPREADSHEET_DOCUMENT		4
98*cdf0e10cSrcweir #define ICON_SPREADSHEET_TEMPLATE		5
99*cdf0e10cSrcweir #define ICON_DRAWING_DOCUMENT			6
100*cdf0e10cSrcweir #define ICON_DRAWING_TEMPLATE			7
101*cdf0e10cSrcweir #define ICON_PRESENTATION_DOCUMENT		8
102*cdf0e10cSrcweir #define ICON_PRESENTATION_TEMPLATE		9
103*cdf0e10cSrcweir #define ICON_PRESENTATION_COMPRESSED	10
104*cdf0e10cSrcweir #define ICON_GLOBAL_DOCUMENT			11
105*cdf0e10cSrcweir #define ICON_HTML_DOCUMENT				12
106*cdf0e10cSrcweir #define ICON_CHART_DOCUMENT				13
107*cdf0e10cSrcweir #define ICON_DATABASE_DOCUMENT			14
108*cdf0e10cSrcweir #define ICON_MATH_DOCUMENT				15
109*cdf0e10cSrcweir #define ICON_TEMPLATE					16
110*cdf0e10cSrcweir #define ICON_MACROLIBRARY				17
111*cdf0e10cSrcweir #define ICON_CONFIGURATION				18
112*cdf0e10cSrcweir #define ICON_OPEN						5   // See index of open folder icon in shell32.dll
113*cdf0e10cSrcweir #define ICON_SETUP						500
114*cdf0e10cSrcweir 
115*cdf0e10cSrcweir #define SFX_TASKBAR_NOTIFICATION    WM_USER+1
116*cdf0e10cSrcweir 
117*cdf0e10cSrcweir static HWND  aListenerWindow = NULL;
118*cdf0e10cSrcweir static HWND  aExecuterWindow = NULL;
119*cdf0e10cSrcweir static HMENU popupMenu = NULL;
120*cdf0e10cSrcweir 
121*cdf0e10cSrcweir static void OnMeasureItem(HWND hwnd, LPMEASUREITEMSTRUCT lpmis);
122*cdf0e10cSrcweir static void OnDrawItem(HWND hwnd, LPDRAWITEMSTRUCT lpdis);
123*cdf0e10cSrcweir 
124*cdf0e10cSrcweir typedef struct tagMYITEM
125*cdf0e10cSrcweir {
126*cdf0e10cSrcweir     OUString text;
127*cdf0e10cSrcweir     OUString module;
128*cdf0e10cSrcweir     UINT iconId;
129*cdf0e10cSrcweir } MYITEM;
130*cdf0e10cSrcweir 
131*cdf0e10cSrcweir // -------------------------------
132*cdf0e10cSrcweir 
133*cdf0e10cSrcweir static bool isNT()
134*cdf0e10cSrcweir {
135*cdf0e10cSrcweir     static bool bInitialized    = false;
136*cdf0e10cSrcweir     static bool bWnt            = false;
137*cdf0e10cSrcweir 
138*cdf0e10cSrcweir     if( !bInitialized )
139*cdf0e10cSrcweir     {
140*cdf0e10cSrcweir         bInitialized = true;
141*cdf0e10cSrcweir 
142*cdf0e10cSrcweir 	    OSVERSIONINFO   aVerInfo;
143*cdf0e10cSrcweir 	    aVerInfo.dwOSVersionInfoSize = sizeof( aVerInfo );
144*cdf0e10cSrcweir 	    if ( GetVersionEx( &aVerInfo ) )
145*cdf0e10cSrcweir 	    {
146*cdf0e10cSrcweir 		    if ( aVerInfo.dwPlatformId == VER_PLATFORM_WIN32_NT )
147*cdf0e10cSrcweir 			    bWnt = true;
148*cdf0e10cSrcweir 	    }
149*cdf0e10cSrcweir     }
150*cdf0e10cSrcweir     return bWnt;
151*cdf0e10cSrcweir }
152*cdf0e10cSrcweir 
153*cdf0e10cSrcweir 
154*cdf0e10cSrcweir // -------------------------------
155*cdf0e10cSrcweir 
156*cdf0e10cSrcweir static void addMenuItem( HMENU hMenu, UINT id, UINT iconId, const OUString& text, int& pos, int bOwnerdraw, const OUString& module )
157*cdf0e10cSrcweir {
158*cdf0e10cSrcweir     MENUITEMINFOW mi;
159*cdf0e10cSrcweir     memset( &mi, 0, sizeof( MENUITEMINFOW ) );
160*cdf0e10cSrcweir 
161*cdf0e10cSrcweir     mi.cbSize = sizeof( MENUITEMINFOW );
162*cdf0e10cSrcweir     if( id == -1 )
163*cdf0e10cSrcweir     {
164*cdf0e10cSrcweir         mi.fMask=MIIM_TYPE;
165*cdf0e10cSrcweir         mi.fType=MFT_SEPARATOR;
166*cdf0e10cSrcweir     }
167*cdf0e10cSrcweir     else
168*cdf0e10cSrcweir     {
169*cdf0e10cSrcweir         if( bOwnerdraw )
170*cdf0e10cSrcweir         {
171*cdf0e10cSrcweir             mi.fMask=MIIM_TYPE | MIIM_STATE | MIIM_ID | MIIM_DATA;
172*cdf0e10cSrcweir             mi.fType=MFT_OWNERDRAW;
173*cdf0e10cSrcweir             mi.fState=MFS_ENABLED;
174*cdf0e10cSrcweir             mi.wID = id;
175*cdf0e10cSrcweir 
176*cdf0e10cSrcweir             MYITEM *pMyItem = new MYITEM;
177*cdf0e10cSrcweir             pMyItem->text = text;
178*cdf0e10cSrcweir             pMyItem->iconId = iconId;
179*cdf0e10cSrcweir             pMyItem->module = module;
180*cdf0e10cSrcweir             mi.dwItemData = (DWORD) pMyItem;
181*cdf0e10cSrcweir         }
182*cdf0e10cSrcweir         else
183*cdf0e10cSrcweir         {
184*cdf0e10cSrcweir             mi.fMask=MIIM_TYPE | MIIM_STATE | MIIM_ID | MIIM_DATA;
185*cdf0e10cSrcweir             mi.fType=MFT_STRING;
186*cdf0e10cSrcweir             mi.fState=MFS_ENABLED;
187*cdf0e10cSrcweir             mi.wID = id;
188*cdf0e10cSrcweir             mi.dwTypeData = (LPWSTR) text.getStr();
189*cdf0e10cSrcweir             mi.cch = text.getLength();
190*cdf0e10cSrcweir         }
191*cdf0e10cSrcweir 
192*cdf0e10cSrcweir #if defined(USE_APP_SHORTCUTS)
193*cdf0e10cSrcweir 		if ( IDM_TEMPLATE == id )
194*cdf0e10cSrcweir 			mi.fState |= MFS_DEFAULT;
195*cdf0e10cSrcweir #endif
196*cdf0e10cSrcweir 	}
197*cdf0e10cSrcweir 
198*cdf0e10cSrcweir     InsertMenuItemW( hMenu, pos++, TRUE, &mi );
199*cdf0e10cSrcweir }
200*cdf0e10cSrcweir 
201*cdf0e10cSrcweir // -------------------------------
202*cdf0e10cSrcweir 
203*cdf0e10cSrcweir static HMENU createSystrayMenu( )
204*cdf0e10cSrcweir {
205*cdf0e10cSrcweir 	SvtModuleOptions	aModuleOptions;
206*cdf0e10cSrcweir 
207*cdf0e10cSrcweir     HMENU hMenu = CreatePopupMenu();
208*cdf0e10cSrcweir     int pos=0;
209*cdf0e10cSrcweir 
210*cdf0e10cSrcweir     ShutdownIcon *pShutdownIcon = ShutdownIcon::getInstance();
211*cdf0e10cSrcweir     OSL_ENSURE( pShutdownIcon, "ShutdownIcon instance empty!");
212*cdf0e10cSrcweir 
213*cdf0e10cSrcweir     if( !pShutdownIcon )
214*cdf0e10cSrcweir         return NULL;
215*cdf0e10cSrcweir 
216*cdf0e10cSrcweir #if defined(USE_APP_SHORTCUTS)
217*cdf0e10cSrcweir     // collect the URLs of the entries in the File/New menu
218*cdf0e10cSrcweir     ::std::set< ::rtl::OUString > aFileNewAppsAvailable;
219*cdf0e10cSrcweir     SvtDynamicMenuOptions aOpt;
220*cdf0e10cSrcweir     Sequence < Sequence < PropertyValue > > aNewMenu = aOpt.GetMenu( E_NEWMENU );
221*cdf0e10cSrcweir     const ::rtl::OUString sURLKey( RTL_CONSTASCII_USTRINGPARAM( "URL" ) );
222*cdf0e10cSrcweir 
223*cdf0e10cSrcweir     const Sequence< PropertyValue >* pNewMenu = aNewMenu.getConstArray();
224*cdf0e10cSrcweir     const Sequence< PropertyValue >* pNewMenuEnd = aNewMenu.getConstArray() + aNewMenu.getLength();
225*cdf0e10cSrcweir     for ( ; pNewMenu != pNewMenuEnd; ++pNewMenu )
226*cdf0e10cSrcweir     {
227*cdf0e10cSrcweir         ::comphelper::SequenceAsHashMap aEntryItems( *pNewMenu );
228*cdf0e10cSrcweir         ::rtl::OUString sURL( aEntryItems.getUnpackedValueOrDefault( sURLKey, ::rtl::OUString() ) );
229*cdf0e10cSrcweir         if ( sURL.getLength() )
230*cdf0e10cSrcweir             aFileNewAppsAvailable.insert( sURL );
231*cdf0e10cSrcweir     }
232*cdf0e10cSrcweir 
233*cdf0e10cSrcweir     // describe the menu entries for launching the applications
234*cdf0e10cSrcweir     struct MenuEntryDescriptor
235*cdf0e10cSrcweir     {
236*cdf0e10cSrcweir         SvtModuleOptions::EModule   eModuleIdentifier;
237*cdf0e10cSrcweir         UINT                        nMenuItemID;
238*cdf0e10cSrcweir         UINT                        nMenuIconID;
239*cdf0e10cSrcweir         const char*                 pAsciiURLDescription;
240*cdf0e10cSrcweir     }   aMenuItems[] =
241*cdf0e10cSrcweir     {
242*cdf0e10cSrcweir         { SvtModuleOptions::E_SWRITER,    IDM_WRITER, ICON_TEXT_DOCUMENT,         WRITER_URL },
243*cdf0e10cSrcweir         { SvtModuleOptions::E_SCALC,      IDM_CALC,   ICON_SPREADSHEET_DOCUMENT,  CALC_URL },
244*cdf0e10cSrcweir         { SvtModuleOptions::E_SIMPRESS,   IDM_IMPRESS,ICON_PRESENTATION_DOCUMENT, IMPRESS_WIZARD_URL },
245*cdf0e10cSrcweir         { SvtModuleOptions::E_SDRAW,      IDM_DRAW,   ICON_DRAWING_DOCUMENT,      DRAW_URL },
246*cdf0e10cSrcweir         { SvtModuleOptions::E_SDATABASE,  IDM_BASE,   ICON_DATABASE_DOCUMENT,     BASE_URL },
247*cdf0e10cSrcweir         { SvtModuleOptions::E_SMATH,      IDM_MATH,   ICON_MATH_DOCUMENT,	      MATH_URL },
248*cdf0e10cSrcweir     };
249*cdf0e10cSrcweir 
250*cdf0e10cSrcweir     OUString aEmpty;
251*cdf0e10cSrcweir 
252*cdf0e10cSrcweir     // insert the menu entries for launching the applications
253*cdf0e10cSrcweir     for ( size_t i = 0; i < sizeof( aMenuItems ) / sizeof( aMenuItems[0] ); ++i )
254*cdf0e10cSrcweir     {
255*cdf0e10cSrcweir         if ( !aModuleOptions.IsModuleInstalled( aMenuItems[i].eModuleIdentifier ) )
256*cdf0e10cSrcweir             // the complete application is not even installed
257*cdf0e10cSrcweir             continue;
258*cdf0e10cSrcweir 
259*cdf0e10cSrcweir         ::rtl::OUString sURL( ::rtl::OUString::createFromAscii( aMenuItems[i].pAsciiURLDescription ) );
260*cdf0e10cSrcweir 
261*cdf0e10cSrcweir         if ( aFileNewAppsAvailable.find( sURL ) == aFileNewAppsAvailable.end() )
262*cdf0e10cSrcweir             // the application is installed, but the entry has been configured to *not* appear in the File/New
263*cdf0e10cSrcweir             // menu => also let not appear it in the quickstarter
264*cdf0e10cSrcweir             continue;
265*cdf0e10cSrcweir 
266*cdf0e10cSrcweir 		addMenuItem( hMenu, aMenuItems[i].nMenuItemID, aMenuItems[i].nMenuIconID,
267*cdf0e10cSrcweir 			pShutdownIcon->GetUrlDescription( sURL ), pos, true, aEmpty );
268*cdf0e10cSrcweir     }
269*cdf0e10cSrcweir 
270*cdf0e10cSrcweir 
271*cdf0e10cSrcweir 
272*cdf0e10cSrcweir     // insert the remaining menu entries
273*cdf0e10cSrcweir     addMenuItem( hMenu, IDM_TEMPLATE, ICON_TEMPLATE,
274*cdf0e10cSrcweir         pShutdownIcon->GetResString( STR_QUICKSTART_FROMTEMPLATE ), pos, true, aEmpty);
275*cdf0e10cSrcweir     addMenuItem( hMenu, static_cast< UINT >( -1 ), 0, OUString(), pos, false, aEmpty );
276*cdf0e10cSrcweir     addMenuItem( hMenu, IDM_OPEN,   ICON_OPEN, pShutdownIcon->GetResString( STR_QUICKSTART_FILEOPEN ), pos, true, OUString::createFromAscii( "SHELL32" ));
277*cdf0e10cSrcweir     addMenuItem( hMenu, static_cast< UINT >( -1 ), 0, OUString(), pos, false, aEmpty );
278*cdf0e10cSrcweir #endif
279*cdf0e10cSrcweir     addMenuItem( hMenu, IDM_INSTALL,0, pShutdownIcon->GetResString( STR_QUICKSTART_PRELAUNCH ), pos, false, aEmpty );
280*cdf0e10cSrcweir     addMenuItem( hMenu, static_cast< UINT >( -1 ), 0, OUString(), pos, false, aEmpty );
281*cdf0e10cSrcweir     addMenuItem( hMenu, IDM_EXIT,   0, pShutdownIcon->GetResString( STR_QUICKSTART_EXIT ), pos, false, aEmpty );
282*cdf0e10cSrcweir 
283*cdf0e10cSrcweir     // indicate status of autostart folder
284*cdf0e10cSrcweir     CheckMenuItem( hMenu, IDM_INSTALL, MF_BYCOMMAND | (ShutdownIcon::GetAutostart() ? MF_CHECKED : MF_UNCHECKED) );
285*cdf0e10cSrcweir 
286*cdf0e10cSrcweir     return hMenu;
287*cdf0e10cSrcweir }
288*cdf0e10cSrcweir 
289*cdf0e10cSrcweir // -------------------------------
290*cdf0e10cSrcweir 
291*cdf0e10cSrcweir static void deleteSystrayMenu( HMENU hMenu )
292*cdf0e10cSrcweir {
293*cdf0e10cSrcweir     if( !hMenu || !IsMenu( hMenu ))
294*cdf0e10cSrcweir         return;
295*cdf0e10cSrcweir 
296*cdf0e10cSrcweir     MENUITEMINFOW mi;
297*cdf0e10cSrcweir     MYITEM *pMyItem;
298*cdf0e10cSrcweir     int pos=0;
299*cdf0e10cSrcweir     memset( &mi, 0, sizeof( mi ) );
300*cdf0e10cSrcweir     mi.cbSize = sizeof( mi );
301*cdf0e10cSrcweir     mi.fMask = MIIM_DATA;
302*cdf0e10cSrcweir 
303*cdf0e10cSrcweir     while( GetMenuItemInfoW( hMenu, pos++, true, &mi ) )
304*cdf0e10cSrcweir     {
305*cdf0e10cSrcweir         pMyItem = (MYITEM*) mi.dwItemData;
306*cdf0e10cSrcweir         if( pMyItem )
307*cdf0e10cSrcweir         {
308*cdf0e10cSrcweir             pMyItem->text = OUString();
309*cdf0e10cSrcweir             delete pMyItem;
310*cdf0e10cSrcweir         }
311*cdf0e10cSrcweir         mi.fMask = MIIM_DATA;
312*cdf0e10cSrcweir     }
313*cdf0e10cSrcweir }
314*cdf0e10cSrcweir 
315*cdf0e10cSrcweir // -------------------------------
316*cdf0e10cSrcweir 
317*cdf0e10cSrcweir static void addTaskbarIcon( HWND hWnd )
318*cdf0e10cSrcweir {
319*cdf0e10cSrcweir     OUString strTip;
320*cdf0e10cSrcweir     if( ShutdownIcon::getInstance() )
321*cdf0e10cSrcweir         strTip = ShutdownIcon::getInstance()->GetResString( STR_QUICKSTART_TIP );
322*cdf0e10cSrcweir 
323*cdf0e10cSrcweir     // add taskbar icon
324*cdf0e10cSrcweir     NOTIFYICONDATAA nid;
325*cdf0e10cSrcweir     nid.hIcon = (HICON)LoadImageA( GetModuleHandle( NULL ), MAKEINTRESOURCE( ICON_SO_DEFAULT ),
326*cdf0e10cSrcweir         IMAGE_ICON, GetSystemMetrics( SM_CXSMICON ), GetSystemMetrics( SM_CYSMICON ),
327*cdf0e10cSrcweir         LR_DEFAULTCOLOR | LR_SHARED );
328*cdf0e10cSrcweir 
329*cdf0e10cSrcweir     // better use unicode wrapper here ?
330*cdf0e10cSrcweir     strncpy( nid.szTip, ( OUStringToOString(strTip, osl_getThreadTextEncoding()).getStr() ), 64 );
331*cdf0e10cSrcweir 
332*cdf0e10cSrcweir     nid.cbSize              = sizeof(nid);
333*cdf0e10cSrcweir     nid.hWnd                = hWnd;
334*cdf0e10cSrcweir     nid.uID                 = ID_QUICKSTART;
335*cdf0e10cSrcweir     nid.uCallbackMessage    = SFX_TASKBAR_NOTIFICATION;
336*cdf0e10cSrcweir     nid.uFlags              = NIF_MESSAGE|NIF_TIP|NIF_ICON;
337*cdf0e10cSrcweir 
338*cdf0e10cSrcweir     Shell_NotifyIconA(NIM_ADD, &nid);
339*cdf0e10cSrcweir }
340*cdf0e10cSrcweir 
341*cdf0e10cSrcweir // -------------------------------
342*cdf0e10cSrcweir 
343*cdf0e10cSrcweir /*
344*cdf0e10cSrcweir static void removeTaskbarIcon()
345*cdf0e10cSrcweir {
346*cdf0e10cSrcweir     ShutdownIcon *pShutdownIcon = ShutdownIcon::getInstance();
347*cdf0e10cSrcweir     OSL_ENSURE( pShutdownIcon, "ShutdownIcon instance empty!");
348*cdf0e10cSrcweir 
349*cdf0e10cSrcweir     if( !pShutdownIcon )
350*cdf0e10cSrcweir         return;
351*cdf0e10cSrcweir 
352*cdf0e10cSrcweir     if ( IsWindow( aListenerWindow ))
353*cdf0e10cSrcweir     {
354*cdf0e10cSrcweir         deleteSystrayMenu( popupMenu );
355*cdf0e10cSrcweir 
356*cdf0e10cSrcweir         NOTIFYICONDATAA nid;
357*cdf0e10cSrcweir         nid.cbSize=sizeof(NOTIFYICONDATA);
358*cdf0e10cSrcweir         nid.hWnd = aListenerWindow;
359*cdf0e10cSrcweir         nid.uID = ID_QUICKSTART;
360*cdf0e10cSrcweir         Shell_NotifyIconA(NIM_DELETE, &nid);
361*cdf0e10cSrcweir     }
362*cdf0e10cSrcweir }
363*cdf0e10cSrcweir */
364*cdf0e10cSrcweir 
365*cdf0e10cSrcweir // -------------------------------
366*cdf0e10cSrcweir 
367*cdf0e10cSrcweir LRESULT CALLBACK listenerWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
368*cdf0e10cSrcweir {
369*cdf0e10cSrcweir     static UINT s_uTaskbarRestart = 0;
370*cdf0e10cSrcweir     static UINT s_uMsgKillTray = 0;
371*cdf0e10cSrcweir 
372*cdf0e10cSrcweir     switch (uMsg)
373*cdf0e10cSrcweir     {
374*cdf0e10cSrcweir         case WM_NCCREATE:
375*cdf0e10cSrcweir             return TRUE;
376*cdf0e10cSrcweir         case WM_CREATE:
377*cdf0e10cSrcweir             {
378*cdf0e10cSrcweir                 // request notfication when taskbar is recreated
379*cdf0e10cSrcweir                 // we then have to add our icon again
380*cdf0e10cSrcweir                 s_uTaskbarRestart = RegisterWindowMessage(TEXT("TaskbarCreated"));
381*cdf0e10cSrcweir                 s_uMsgKillTray = RegisterWindowMessage( SHUTDOWN_QUICKSTART_MESSAGE );
382*cdf0e10cSrcweir 
383*cdf0e10cSrcweir                 // create the menu
384*cdf0e10cSrcweir                 if( !popupMenu )
385*cdf0e10cSrcweir                     if( (popupMenu = createSystrayMenu( )) == NULL )
386*cdf0e10cSrcweir                         return -1;
387*cdf0e10cSrcweir 
388*cdf0e10cSrcweir                 // and the icon
389*cdf0e10cSrcweir                 addTaskbarIcon( hWnd );
390*cdf0e10cSrcweir 
391*cdf0e10cSrcweir                 // disable shutdown
392*cdf0e10cSrcweir                 ShutdownIcon::getInstance()->SetVeto( true );
393*cdf0e10cSrcweir 				ShutdownIcon::getInstance()->addTerminateListener();
394*cdf0e10cSrcweir             }
395*cdf0e10cSrcweir             return 0;
396*cdf0e10cSrcweir 
397*cdf0e10cSrcweir         case WM_MEASUREITEM:
398*cdf0e10cSrcweir             OnMeasureItem(hWnd, (LPMEASUREITEMSTRUCT) lParam);
399*cdf0e10cSrcweir             return TRUE;
400*cdf0e10cSrcweir 
401*cdf0e10cSrcweir         case WM_DRAWITEM:
402*cdf0e10cSrcweir             OnDrawItem(hWnd, (LPDRAWITEMSTRUCT) lParam);
403*cdf0e10cSrcweir             return TRUE;
404*cdf0e10cSrcweir 
405*cdf0e10cSrcweir         case SFX_TASKBAR_NOTIFICATION:
406*cdf0e10cSrcweir             switch( lParam )
407*cdf0e10cSrcweir             {
408*cdf0e10cSrcweir                 case WM_LBUTTONDBLCLK:
409*cdf0e10cSrcweir #if defined(USE_APP_SHORTCUTS)
410*cdf0e10cSrcweir 					PostMessage( aExecuterWindow, WM_COMMAND, IDM_TEMPLATE, (LPARAM)hWnd );
411*cdf0e10cSrcweir #endif
412*cdf0e10cSrcweir                     break;
413*cdf0e10cSrcweir 
414*cdf0e10cSrcweir                 case WM_RBUTTONDOWN:
415*cdf0e10cSrcweir                 {
416*cdf0e10cSrcweir                     POINT pt;
417*cdf0e10cSrcweir                     GetCursorPos(&pt);
418*cdf0e10cSrcweir                     SetForegroundWindow( hWnd );
419*cdf0e10cSrcweir 
420*cdf0e10cSrcweir                     // update status before showing menu, could have been changed from option page
421*cdf0e10cSrcweir                     CheckMenuItem( popupMenu, IDM_INSTALL, MF_BYCOMMAND| (ShutdownIcon::GetAutostart() ? MF_CHECKED : MF_UNCHECKED) );
422*cdf0e10cSrcweir 
423*cdf0e10cSrcweir 					EnableMenuItem( popupMenu, IDM_EXIT, MF_BYCOMMAND | (ShutdownIcon::bModalMode ? MF_GRAYED : MF_ENABLED) );
424*cdf0e10cSrcweir #if defined(USE_APP_SHORTCUTS)
425*cdf0e10cSrcweir 					EnableMenuItem( popupMenu, IDM_OPEN, MF_BYCOMMAND | (ShutdownIcon::bModalMode ? MF_GRAYED : MF_ENABLED) );
426*cdf0e10cSrcweir 					EnableMenuItem( popupMenu, IDM_TEMPLATE, MF_BYCOMMAND | (ShutdownIcon::bModalMode ? MF_GRAYED : MF_ENABLED) );
427*cdf0e10cSrcweir #endif
428*cdf0e10cSrcweir                     int m = TrackPopupMenuEx( popupMenu, TPM_RETURNCMD|TPM_LEFTALIGN|TPM_RIGHTBUTTON,
429*cdf0e10cSrcweir                                               pt.x, pt.y, hWnd, NULL );
430*cdf0e10cSrcweir                     // BUGFIX: See Q135788 (PRB: Menus for Notification Icons Don't Work Correctly)
431*cdf0e10cSrcweir                     PostMessage( hWnd, NULL, 0, 0 );
432*cdf0e10cSrcweir                     switch( m )
433*cdf0e10cSrcweir                     {
434*cdf0e10cSrcweir #if defined(USE_APP_SHORTCUTS)
435*cdf0e10cSrcweir                         case IDM_OPEN:
436*cdf0e10cSrcweir                         case IDM_WRITER:
437*cdf0e10cSrcweir                         case IDM_CALC:
438*cdf0e10cSrcweir                         case IDM_IMPRESS:
439*cdf0e10cSrcweir                         case IDM_DRAW:
440*cdf0e10cSrcweir                         case IDM_TEMPLATE:
441*cdf0e10cSrcweir                         case IDM_BASE:
442*cdf0e10cSrcweir 						case IDM_MATH:
443*cdf0e10cSrcweir 							break;
444*cdf0e10cSrcweir #endif
445*cdf0e10cSrcweir                         case IDM_INSTALL:
446*cdf0e10cSrcweir                             CheckMenuItem( popupMenu, IDM_INSTALL, MF_BYCOMMAND| (ShutdownIcon::GetAutostart() ? MF_CHECKED : MF_UNCHECKED) );
447*cdf0e10cSrcweir                             break;
448*cdf0e10cSrcweir                         case IDM_EXIT:
449*cdf0e10cSrcweir                             // delete taskbar icon
450*cdf0e10cSrcweir                             NOTIFYICONDATAA nid;
451*cdf0e10cSrcweir                             nid.cbSize=sizeof(NOTIFYICONDATA);
452*cdf0e10cSrcweir                             nid.hWnd = hWnd;
453*cdf0e10cSrcweir                             nid.uID = ID_QUICKSTART;
454*cdf0e10cSrcweir                             Shell_NotifyIconA(NIM_DELETE, &nid);
455*cdf0e10cSrcweir                             break;
456*cdf0e10cSrcweir                     }
457*cdf0e10cSrcweir 
458*cdf0e10cSrcweir 					PostMessage( aExecuterWindow, WM_COMMAND, m, (LPARAM)hWnd );
459*cdf0e10cSrcweir                 }
460*cdf0e10cSrcweir                 break;
461*cdf0e10cSrcweir             }
462*cdf0e10cSrcweir             break;
463*cdf0e10cSrcweir         case WM_DESTROY:
464*cdf0e10cSrcweir             deleteSystrayMenu( popupMenu );
465*cdf0e10cSrcweir 			// We don't need the Systray Thread anymore
466*cdf0e10cSrcweir 			PostQuitMessage( 0 );
467*cdf0e10cSrcweir             return DefWindowProc(hWnd, uMsg, wParam, lParam);
468*cdf0e10cSrcweir         default:
469*cdf0e10cSrcweir             if( uMsg == s_uTaskbarRestart )
470*cdf0e10cSrcweir             {
471*cdf0e10cSrcweir                 // re-create taskbar icon
472*cdf0e10cSrcweir                 addTaskbarIcon( hWnd );
473*cdf0e10cSrcweir             }
474*cdf0e10cSrcweir 			else if ( uMsg == s_uMsgKillTray )
475*cdf0e10cSrcweir 			{
476*cdf0e10cSrcweir                 // delete taskbar icon
477*cdf0e10cSrcweir                 NOTIFYICONDATAA nid;
478*cdf0e10cSrcweir                 nid.cbSize=sizeof(NOTIFYICONDATA);
479*cdf0e10cSrcweir                 nid.hWnd = hWnd;
480*cdf0e10cSrcweir                 nid.uID = ID_QUICKSTART;
481*cdf0e10cSrcweir                 Shell_NotifyIconA(NIM_DELETE, &nid);
482*cdf0e10cSrcweir 
483*cdf0e10cSrcweir 				PostMessage( aExecuterWindow, WM_COMMAND, IDM_EXIT, (LPARAM)hWnd );
484*cdf0e10cSrcweir 			}
485*cdf0e10cSrcweir 			else
486*cdf0e10cSrcweir 				return DefWindowProc(hWnd, uMsg, wParam, lParam);
487*cdf0e10cSrcweir     }
488*cdf0e10cSrcweir     return 0;
489*cdf0e10cSrcweir }
490*cdf0e10cSrcweir 
491*cdf0e10cSrcweir // -------------------------------
492*cdf0e10cSrcweir 
493*cdf0e10cSrcweir static sal_Bool checkOEM() {
494*cdf0e10cSrcweir     Reference<XMultiServiceFactory> rFactory = ::comphelper::getProcessServiceFactory();
495*cdf0e10cSrcweir     Reference<XJob> rOemJob(rFactory->createInstance(
496*cdf0e10cSrcweir         OUString::createFromAscii("com.sun.star.office.OEMPreloadJob")),
497*cdf0e10cSrcweir         UNO_QUERY );
498*cdf0e10cSrcweir     Sequence<NamedValue> args;
499*cdf0e10cSrcweir     sal_Bool bResult = sal_False;
500*cdf0e10cSrcweir     if (rOemJob.is())
501*cdf0e10cSrcweir     {
502*cdf0e10cSrcweir         Any aResult = rOemJob->execute(args);
503*cdf0e10cSrcweir         aResult >>= bResult;
504*cdf0e10cSrcweir     } else bResult = sal_True;
505*cdf0e10cSrcweir     return bResult;
506*cdf0e10cSrcweir }
507*cdf0e10cSrcweir 
508*cdf0e10cSrcweir LRESULT CALLBACK executerWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
509*cdf0e10cSrcweir {
510*cdf0e10cSrcweir     switch (uMsg)
511*cdf0e10cSrcweir     {
512*cdf0e10cSrcweir         case WM_NCCREATE:
513*cdf0e10cSrcweir             return TRUE;
514*cdf0e10cSrcweir         case WM_CREATE:
515*cdf0e10cSrcweir             return 0;
516*cdf0e10cSrcweir 
517*cdf0e10cSrcweir         case WM_COMMAND:
518*cdf0e10cSrcweir             switch( LOWORD(wParam) )
519*cdf0e10cSrcweir             {
520*cdf0e10cSrcweir #if defined(USE_APP_SHORTCUTS)
521*cdf0e10cSrcweir                 case IDM_OPEN:
522*cdf0e10cSrcweir 					if ( !ShutdownIcon::bModalMode && checkOEM() )
523*cdf0e10cSrcweir 						ShutdownIcon::FileOpen();
524*cdf0e10cSrcweir                 break;
525*cdf0e10cSrcweir                 case IDM_WRITER:
526*cdf0e10cSrcweir                     if (checkOEM())
527*cdf0e10cSrcweir                     ShutdownIcon::OpenURL( OUString( RTL_CONSTASCII_USTRINGPARAM( WRITER_URL ) ), OUString( RTL_CONSTASCII_USTRINGPARAM( "_default" ) ) );
528*cdf0e10cSrcweir                 break;
529*cdf0e10cSrcweir                 case IDM_CALC:
530*cdf0e10cSrcweir                     if (checkOEM())
531*cdf0e10cSrcweir                     ShutdownIcon::OpenURL( OUString( RTL_CONSTASCII_USTRINGPARAM( CALC_URL ) ), OUString( RTL_CONSTASCII_USTRINGPARAM( "_default" ) ) );
532*cdf0e10cSrcweir                 break;
533*cdf0e10cSrcweir                 case IDM_IMPRESS:
534*cdf0e10cSrcweir                     if (checkOEM())
535*cdf0e10cSrcweir                     ShutdownIcon::OpenURL( OUString( RTL_CONSTASCII_USTRINGPARAM( IMPRESS_WIZARD_URL ) ), OUString( RTL_CONSTASCII_USTRINGPARAM( "_default" ) ) );
536*cdf0e10cSrcweir                 break;
537*cdf0e10cSrcweir                 case IDM_DRAW:
538*cdf0e10cSrcweir                     if (checkOEM())
539*cdf0e10cSrcweir                     ShutdownIcon::OpenURL( OUString( RTL_CONSTASCII_USTRINGPARAM( DRAW_URL ) ), OUString( RTL_CONSTASCII_USTRINGPARAM( "_default" ) ) );
540*cdf0e10cSrcweir                 break;
541*cdf0e10cSrcweir                 case IDM_BASE:
542*cdf0e10cSrcweir                     if (checkOEM())
543*cdf0e10cSrcweir                     ShutdownIcon::OpenURL( OUString( RTL_CONSTASCII_USTRINGPARAM( BASE_URL ) ), OUString( RTL_CONSTASCII_USTRINGPARAM( "_default" ) ) );
544*cdf0e10cSrcweir                 break;
545*cdf0e10cSrcweir                 case IDM_MATH:
546*cdf0e10cSrcweir                     if (checkOEM())
547*cdf0e10cSrcweir                     ShutdownIcon::OpenURL( OUString( RTL_CONSTASCII_USTRINGPARAM( MATH_URL ) ), OUString( RTL_CONSTASCII_USTRINGPARAM( "_default" ) ) );
548*cdf0e10cSrcweir                 break;
549*cdf0e10cSrcweir                 case IDM_TEMPLATE:
550*cdf0e10cSrcweir 					if ( !ShutdownIcon::bModalMode && checkOEM())
551*cdf0e10cSrcweir 						ShutdownIcon::FromTemplate();
552*cdf0e10cSrcweir                 break;
553*cdf0e10cSrcweir #endif
554*cdf0e10cSrcweir                 case IDM_INSTALL:
555*cdf0e10cSrcweir                     ShutdownIcon::SetAutostart( !ShutdownIcon::GetAutostart() );
556*cdf0e10cSrcweir                     break;
557*cdf0e10cSrcweir                 case IDM_EXIT:
558*cdf0e10cSrcweir                     // remove listener and
559*cdf0e10cSrcweir                     //  terminate office if running in background
560*cdf0e10cSrcweir 					if ( !ShutdownIcon::bModalMode )
561*cdf0e10cSrcweir 						ShutdownIcon::terminateDesktop();
562*cdf0e10cSrcweir                     break;
563*cdf0e10cSrcweir             }
564*cdf0e10cSrcweir 			break;
565*cdf0e10cSrcweir         case WM_DESTROY:
566*cdf0e10cSrcweir         default:
567*cdf0e10cSrcweir             return DefWindowProc(hWnd, uMsg, wParam, lParam);
568*cdf0e10cSrcweir     }
569*cdf0e10cSrcweir     return 0;
570*cdf0e10cSrcweir }
571*cdf0e10cSrcweir 
572*cdf0e10cSrcweir // -------------------------------
573*cdf0e10cSrcweir 
574*cdf0e10cSrcweir 
575*cdf0e10cSrcweir DWORD WINAPI SystrayThread( LPVOID /*lpParam*/ )
576*cdf0e10cSrcweir {
577*cdf0e10cSrcweir 	aListenerWindow = CreateWindowExA(0,
578*cdf0e10cSrcweir         QUICKSTART_CLASSNAME,	    // registered class name
579*cdf0e10cSrcweir         QUICKSTART_WINDOWNAME,        // window name
580*cdf0e10cSrcweir         0,          				// window style
581*cdf0e10cSrcweir         CW_USEDEFAULT,			    // horizontal position of window
582*cdf0e10cSrcweir         CW_USEDEFAULT,			    // vertical position of window
583*cdf0e10cSrcweir         CW_USEDEFAULT,			    // window width
584*cdf0e10cSrcweir         CW_USEDEFAULT,			    // window height
585*cdf0e10cSrcweir         (HWND) NULL,	            // handle to parent or owner window
586*cdf0e10cSrcweir         NULL,						// menu handle or child identifier
587*cdf0e10cSrcweir         (HINSTANCE) GetModuleHandle( NULL ),    // handle to application instance
588*cdf0e10cSrcweir         NULL						// window-creation data
589*cdf0e10cSrcweir         );
590*cdf0e10cSrcweir 
591*cdf0e10cSrcweir 	MSG	msg;
592*cdf0e10cSrcweir 
593*cdf0e10cSrcweir 	while ( GetMessage( &msg, NULL, 0, 0 ) )
594*cdf0e10cSrcweir 	{
595*cdf0e10cSrcweir 		TranslateMessage( &msg );
596*cdf0e10cSrcweir 		DispatchMessage( &msg );
597*cdf0e10cSrcweir 	}
598*cdf0e10cSrcweir 
599*cdf0e10cSrcweir 	return msg.wParam; // Exit code of WM_QUIT
600*cdf0e10cSrcweir }
601*cdf0e10cSrcweir 
602*cdf0e10cSrcweir // -------------------------------
603*cdf0e10cSrcweir 
604*cdf0e10cSrcweir void win32_init_sys_tray()
605*cdf0e10cSrcweir {
606*cdf0e10cSrcweir 	if ( ShutdownIcon::IsQuickstarterInstalled() )
607*cdf0e10cSrcweir 	{
608*cdf0e10cSrcweir 		WNDCLASSEXA listenerClass;
609*cdf0e10cSrcweir 		listenerClass.cbSize		= sizeof(WNDCLASSEX);
610*cdf0e10cSrcweir 		listenerClass.style			= 0;
611*cdf0e10cSrcweir 		listenerClass.lpfnWndProc	= listenerWndProc;
612*cdf0e10cSrcweir 		listenerClass.cbClsExtra	= 0;
613*cdf0e10cSrcweir 		listenerClass.cbWndExtra	= 0;
614*cdf0e10cSrcweir 		listenerClass.hInstance		= (HINSTANCE) GetModuleHandle( NULL );
615*cdf0e10cSrcweir 		listenerClass.hIcon			= NULL;
616*cdf0e10cSrcweir 		listenerClass.hCursor		= NULL;
617*cdf0e10cSrcweir 		listenerClass.hbrBackground	= NULL;
618*cdf0e10cSrcweir 		listenerClass.lpszMenuName	= NULL;
619*cdf0e10cSrcweir 		listenerClass.lpszClassName	= QUICKSTART_CLASSNAME;
620*cdf0e10cSrcweir 		listenerClass.hIconSm	    = NULL;
621*cdf0e10cSrcweir 
622*cdf0e10cSrcweir 		RegisterClassExA(&listenerClass);
623*cdf0e10cSrcweir 
624*cdf0e10cSrcweir 		WNDCLASSEXA executerClass;
625*cdf0e10cSrcweir 		executerClass.cbSize		= sizeof(WNDCLASSEX);
626*cdf0e10cSrcweir 		executerClass.style			= 0;
627*cdf0e10cSrcweir 		executerClass.lpfnWndProc	= executerWndProc;
628*cdf0e10cSrcweir 		executerClass.cbClsExtra	= 0;
629*cdf0e10cSrcweir 		executerClass.cbWndExtra	= 0;
630*cdf0e10cSrcweir 		executerClass.hInstance		= (HINSTANCE) GetModuleHandle( NULL );
631*cdf0e10cSrcweir 		executerClass.hIcon			= NULL;
632*cdf0e10cSrcweir 		executerClass.hCursor		= NULL;
633*cdf0e10cSrcweir 		executerClass.hbrBackground	= NULL;
634*cdf0e10cSrcweir 		executerClass.lpszMenuName	= NULL;
635*cdf0e10cSrcweir 		executerClass.lpszClassName	= EXECUTER_WINDOWCLASS;
636*cdf0e10cSrcweir 		executerClass.hIconSm	    = NULL;
637*cdf0e10cSrcweir 
638*cdf0e10cSrcweir 		RegisterClassExA( &executerClass );
639*cdf0e10cSrcweir 
640*cdf0e10cSrcweir 		aExecuterWindow = CreateWindowExA(0,
641*cdf0e10cSrcweir 			EXECUTER_WINDOWCLASS,	    // registered class name
642*cdf0e10cSrcweir 			EXECUTER_WINDOWNAME,        // window name
643*cdf0e10cSrcweir 			0,          				// window style
644*cdf0e10cSrcweir 			CW_USEDEFAULT,			    // horizontal position of window
645*cdf0e10cSrcweir 			CW_USEDEFAULT,			    // vertical position of window
646*cdf0e10cSrcweir 			CW_USEDEFAULT,			    // window width
647*cdf0e10cSrcweir 			CW_USEDEFAULT,			    // window height
648*cdf0e10cSrcweir 			(HWND) NULL,	            // handle to parent or owner window
649*cdf0e10cSrcweir 			NULL,						// menu handle or child identifier
650*cdf0e10cSrcweir 			(HINSTANCE) GetModuleHandle( NULL ),    // handle to application instance
651*cdf0e10cSrcweir 			NULL						// window-creation data
652*cdf0e10cSrcweir 			);
653*cdf0e10cSrcweir 
654*cdf0e10cSrcweir 		DWORD	dwThreadId;
655*cdf0e10cSrcweir 		CreateThread( NULL, 0, SystrayThread, NULL, 0, &dwThreadId );
656*cdf0e10cSrcweir 	}
657*cdf0e10cSrcweir }
658*cdf0e10cSrcweir 
659*cdf0e10cSrcweir // -------------------------------
660*cdf0e10cSrcweir 
661*cdf0e10cSrcweir void win32_shutdown_sys_tray()
662*cdf0e10cSrcweir {
663*cdf0e10cSrcweir 	if ( ShutdownIcon::IsQuickstarterInstalled() )
664*cdf0e10cSrcweir 	{
665*cdf0e10cSrcweir 		if( IsWindow( aListenerWindow ) )
666*cdf0e10cSrcweir 		{
667*cdf0e10cSrcweir 			DestroyWindow( aListenerWindow );
668*cdf0e10cSrcweir 			aListenerWindow = NULL;
669*cdf0e10cSrcweir 			DestroyWindow( aExecuterWindow );
670*cdf0e10cSrcweir 			aExecuterWindow = NULL;
671*cdf0e10cSrcweir 		}
672*cdf0e10cSrcweir 		UnregisterClassA( QUICKSTART_CLASSNAME, GetModuleHandle( NULL ) );
673*cdf0e10cSrcweir 		UnregisterClassA( EXECUTER_WINDOWCLASS, GetModuleHandle( NULL ) );
674*cdf0e10cSrcweir 	}
675*cdf0e10cSrcweir }
676*cdf0e10cSrcweir 
677*cdf0e10cSrcweir 
678*cdf0e10cSrcweir 
679*cdf0e10cSrcweir // -------------------------------
680*cdf0e10cSrcweir 
681*cdf0e10cSrcweir void OnMeasureItem(HWND hwnd, LPMEASUREITEMSTRUCT lpmis)
682*cdf0e10cSrcweir {
683*cdf0e10cSrcweir     MYITEM *pMyItem = (MYITEM *) lpmis->itemData;
684*cdf0e10cSrcweir     HDC hdc = GetDC(hwnd);
685*cdf0e10cSrcweir     SIZE size;
686*cdf0e10cSrcweir 
687*cdf0e10cSrcweir 	NONCLIENTMETRICS ncm;
688*cdf0e10cSrcweir 	memset(&ncm, 0, sizeof(ncm));
689*cdf0e10cSrcweir 	ncm.cbSize = sizeof(ncm);
690*cdf0e10cSrcweir 
691*cdf0e10cSrcweir 	SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, (PVOID) &ncm, 0);
692*cdf0e10cSrcweir 
693*cdf0e10cSrcweir 	// Assume every menu item can be default and printed bold
694*cdf0e10cSrcweir 	ncm.lfMenuFont.lfWeight = FW_BOLD;
695*cdf0e10cSrcweir 
696*cdf0e10cSrcweir     HFONT hfntOld = (HFONT) SelectObject(hdc, (HFONT) CreateFontIndirect( &ncm.lfMenuFont ));
697*cdf0e10cSrcweir 
698*cdf0e10cSrcweir     GetTextExtentPoint32W(hdc, reinterpret_cast<LPCWSTR>(pMyItem->text.getStr()),
699*cdf0e10cSrcweir             pMyItem->text.getLength(), &size);
700*cdf0e10cSrcweir 
701*cdf0e10cSrcweir     lpmis->itemWidth = size.cx + 4 + GetSystemMetrics( SM_CXSMICON );
702*cdf0e10cSrcweir     lpmis->itemHeight = (size.cy > GetSystemMetrics( SM_CYSMICON )) ? size.cy : GetSystemMetrics( SM_CYSMICON );
703*cdf0e10cSrcweir     lpmis->itemHeight += 4;
704*cdf0e10cSrcweir 
705*cdf0e10cSrcweir     DeleteObject( SelectObject(hdc, hfntOld) );
706*cdf0e10cSrcweir     ReleaseDC(hwnd, hdc);
707*cdf0e10cSrcweir }
708*cdf0e10cSrcweir 
709*cdf0e10cSrcweir void OnDrawItem(HWND /*hwnd*/, LPDRAWITEMSTRUCT lpdis)
710*cdf0e10cSrcweir {
711*cdf0e10cSrcweir     MYITEM *pMyItem = (MYITEM *) lpdis->itemData;
712*cdf0e10cSrcweir     COLORREF clrPrevText, clrPrevBkgnd;
713*cdf0e10cSrcweir     HFONT hfntOld;
714*cdf0e10cSrcweir     HBRUSH hbrOld;
715*cdf0e10cSrcweir     int x, y;
716*cdf0e10cSrcweir 	BOOL	fSelected = lpdis->itemState & ODS_SELECTED;
717*cdf0e10cSrcweir 	BOOL	fDisabled = lpdis->itemState & (ODS_DISABLED | ODS_GRAYED);
718*cdf0e10cSrcweir 
719*cdf0e10cSrcweir     // Set the appropriate foreground and background colors.
720*cdf0e10cSrcweir 
721*cdf0e10cSrcweir     RECT aRect = lpdis->rcItem;
722*cdf0e10cSrcweir 
723*cdf0e10cSrcweir     clrPrevBkgnd = SetBkColor( lpdis->hDC, GetSysColor(COLOR_MENU) );
724*cdf0e10cSrcweir 
725*cdf0e10cSrcweir 	if ( fDisabled )
726*cdf0e10cSrcweir         clrPrevText = SetTextColor( lpdis->hDC, GetSysColor( COLOR_GRAYTEXT ) );
727*cdf0e10cSrcweir 	else
728*cdf0e10cSrcweir         clrPrevText = SetTextColor( lpdis->hDC, GetSysColor( fSelected ? COLOR_HIGHLIGHTTEXT : COLOR_MENUTEXT ) );
729*cdf0e10cSrcweir 
730*cdf0e10cSrcweir 	if ( fSelected )
731*cdf0e10cSrcweir 		clrPrevBkgnd = SetBkColor( lpdis->hDC, GetSysColor(COLOR_HIGHLIGHT) );
732*cdf0e10cSrcweir 	else
733*cdf0e10cSrcweir 		clrPrevBkgnd = SetBkColor( lpdis->hDC, GetSysColor(COLOR_MENU) );
734*cdf0e10cSrcweir 
735*cdf0e10cSrcweir 	hbrOld = (HBRUSH)SelectObject( lpdis->hDC, CreateSolidBrush( GetBkColor( lpdis->hDC ) ) );
736*cdf0e10cSrcweir 
737*cdf0e10cSrcweir     // Fill background
738*cdf0e10cSrcweir     PatBlt(lpdis->hDC, aRect.left, aRect.top, aRect.right-aRect.left, aRect.bottom-aRect.top, PATCOPY);
739*cdf0e10cSrcweir 
740*cdf0e10cSrcweir     int height = aRect.bottom-aRect.top;
741*cdf0e10cSrcweir 
742*cdf0e10cSrcweir     x = aRect.left;
743*cdf0e10cSrcweir     y = aRect.top;
744*cdf0e10cSrcweir 
745*cdf0e10cSrcweir     int     cx = GetSystemMetrics( SM_CXSMICON );
746*cdf0e10cSrcweir     int     cy = GetSystemMetrics( SM_CYSMICON );
747*cdf0e10cSrcweir     HICON   hIcon( 0 );
748*cdf0e10cSrcweir     HMODULE hModule( GetModuleHandle( NULL ) );
749*cdf0e10cSrcweir 
750*cdf0e10cSrcweir     if ( pMyItem->module.getLength() > 0 )
751*cdf0e10cSrcweir     {
752*cdf0e10cSrcweir         LPCWSTR pModuleName = reinterpret_cast<LPCWSTR>( pMyItem->module.getStr() );
753*cdf0e10cSrcweir         hModule = GetModuleHandleW( pModuleName );
754*cdf0e10cSrcweir         if ( hModule == NULL )
755*cdf0e10cSrcweir         {
756*cdf0e10cSrcweir             LoadLibraryW( pModuleName );
757*cdf0e10cSrcweir             hModule = GetModuleHandleW( pModuleName );
758*cdf0e10cSrcweir         }
759*cdf0e10cSrcweir     }
760*cdf0e10cSrcweir 
761*cdf0e10cSrcweir     hIcon = (HICON) LoadImageA( hModule, MAKEINTRESOURCE( pMyItem->iconId ),
762*cdf0e10cSrcweir                                 IMAGE_ICON, cx, cy,
763*cdf0e10cSrcweir                                 LR_DEFAULTCOLOR | LR_SHARED );
764*cdf0e10cSrcweir 
765*cdf0e10cSrcweir     // DrawIconEx( lpdis->hDC, x, y+(height-cy)/2, hIcon, cx, cy, 0, NULL, DI_NORMAL );
766*cdf0e10cSrcweir 
767*cdf0e10cSrcweir 	HBRUSH hbrIcon = CreateSolidBrush( GetSysColor( COLOR_GRAYTEXT ) );
768*cdf0e10cSrcweir 
769*cdf0e10cSrcweir 	DrawStateW( lpdis->hDC, (HBRUSH)hbrIcon, (DRAWSTATEPROC)NULL, (LPARAM)hIcon, (WPARAM)0, x, y+(height-cy)/2, 0, 0, DST_ICON | (fDisabled ? (fSelected ? DSS_MONO : DSS_DISABLED) : DSS_NORMAL) );
770*cdf0e10cSrcweir 
771*cdf0e10cSrcweir 	DeleteObject( hbrIcon );
772*cdf0e10cSrcweir 
773*cdf0e10cSrcweir     x += cx + 4;    // space for icon
774*cdf0e10cSrcweir     aRect.left = x;
775*cdf0e10cSrcweir 
776*cdf0e10cSrcweir 	NONCLIENTMETRICS ncm;
777*cdf0e10cSrcweir 	memset(&ncm, 0, sizeof(ncm));
778*cdf0e10cSrcweir 	ncm.cbSize = sizeof(ncm);
779*cdf0e10cSrcweir 
780*cdf0e10cSrcweir 	SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, (PVOID) &ncm, 0);
781*cdf0e10cSrcweir 
782*cdf0e10cSrcweir 	// Print default menu entry with bold font
783*cdf0e10cSrcweir 	if ( lpdis->itemState & ODS_DEFAULT )
784*cdf0e10cSrcweir 		ncm.lfMenuFont.lfWeight = FW_BOLD;
785*cdf0e10cSrcweir 
786*cdf0e10cSrcweir     hfntOld = (HFONT) SelectObject(lpdis->hDC, (HFONT) CreateFontIndirect( &ncm.lfMenuFont ));
787*cdf0e10cSrcweir 
788*cdf0e10cSrcweir 
789*cdf0e10cSrcweir 	SIZE	size;
790*cdf0e10cSrcweir 	GetTextExtentPointW( lpdis->hDC, reinterpret_cast<LPCWSTR>(pMyItem->text.getStr()), pMyItem->text.getLength(), &size );
791*cdf0e10cSrcweir 
792*cdf0e10cSrcweir 	DrawStateW( lpdis->hDC, (HBRUSH)NULL, (DRAWSTATEPROC)NULL, (LPARAM)pMyItem->text.getStr(), (WPARAM)0, aRect.left, aRect.top + (height - size.cy)/2, 0, 0, DST_TEXT | (fDisabled && !fSelected ? DSS_DISABLED : DSS_NORMAL) );
793*cdf0e10cSrcweir 
794*cdf0e10cSrcweir     // Restore the original font and colors.
795*cdf0e10cSrcweir     DeleteObject( SelectObject( lpdis->hDC, hbrOld ) );
796*cdf0e10cSrcweir     DeleteObject( SelectObject( lpdis->hDC, hfntOld) );
797*cdf0e10cSrcweir     SetTextColor(lpdis->hDC, clrPrevText);
798*cdf0e10cSrcweir     SetBkColor(lpdis->hDC, clrPrevBkgnd);
799*cdf0e10cSrcweir }
800*cdf0e10cSrcweir 
801*cdf0e10cSrcweir // -------------------------------
802*cdf0e10cSrcweir // code from setup2 project
803*cdf0e10cSrcweir // -------------------------------
804*cdf0e10cSrcweir 
805*cdf0e10cSrcweir void _SHFree( void *pv )
806*cdf0e10cSrcweir {
807*cdf0e10cSrcweir 	IMalloc	*pMalloc;
808*cdf0e10cSrcweir 	if( NOERROR == SHGetMalloc(&pMalloc) )
809*cdf0e10cSrcweir 	{
810*cdf0e10cSrcweir 		pMalloc->Free( pv );
811*cdf0e10cSrcweir 		pMalloc->Release();
812*cdf0e10cSrcweir 	}
813*cdf0e10cSrcweir }
814*cdf0e10cSrcweir 
815*cdf0e10cSrcweir #define ALLOC(type, n) ((type *) HeapAlloc(GetProcessHeap(), 0, sizeof(type) * n ))
816*cdf0e10cSrcweir #define FREE(p) HeapFree(GetProcessHeap(), 0, p)
817*cdf0e10cSrcweir 
818*cdf0e10cSrcweir static OUString _SHGetSpecialFolder( int nFolderID )
819*cdf0e10cSrcweir {
820*cdf0e10cSrcweir 
821*cdf0e10cSrcweir 	LPITEMIDLIST	pidl;
822*cdf0e10cSrcweir 	HRESULT			hHdl = SHGetSpecialFolderLocation( NULL, nFolderID, &pidl );
823*cdf0e10cSrcweir 	OUString		aFolder;
824*cdf0e10cSrcweir 
825*cdf0e10cSrcweir 	if( hHdl == NOERROR )
826*cdf0e10cSrcweir 	{
827*cdf0e10cSrcweir 		WCHAR *lpFolderA;
828*cdf0e10cSrcweir 		lpFolderA = ALLOC( WCHAR, 16000 );
829*cdf0e10cSrcweir 
830*cdf0e10cSrcweir 		SHGetPathFromIDListW( pidl, lpFolderA );
831*cdf0e10cSrcweir 		aFolder = OUString( reinterpret_cast<const sal_Unicode*>(lpFolderA) );
832*cdf0e10cSrcweir 
833*cdf0e10cSrcweir 		FREE( lpFolderA );
834*cdf0e10cSrcweir 		_SHFree( pidl );
835*cdf0e10cSrcweir 	}
836*cdf0e10cSrcweir 	return aFolder;
837*cdf0e10cSrcweir }
838*cdf0e10cSrcweir 
839*cdf0e10cSrcweir OUString ShutdownIcon::GetAutostartFolderNameW32()
840*cdf0e10cSrcweir {
841*cdf0e10cSrcweir 	return _SHGetSpecialFolder(CSIDL_STARTUP);
842*cdf0e10cSrcweir }
843*cdf0e10cSrcweir 
844*cdf0e10cSrcweir static HRESULT WINAPI SHCoCreateInstance( LPVOID lpszReserved, REFCLSID clsid, LPUNKNOWN pUnkUnknown, REFIID iid, LPVOID *ppv )
845*cdf0e10cSrcweir {
846*cdf0e10cSrcweir 	HRESULT	hResult = E_NOTIMPL;
847*cdf0e10cSrcweir 	HMODULE	hModShell = GetModuleHandle( "SHELL32" );
848*cdf0e10cSrcweir 
849*cdf0e10cSrcweir 	if ( hModShell != NULL )
850*cdf0e10cSrcweir 	{
851*cdf0e10cSrcweir 		typedef	HRESULT (WINAPI *SHCoCreateInstance_PROC)( LPVOID lpszReserved, REFCLSID clsid, LPUNKNOWN pUnkUnknwon, REFIID iid, LPVOID *ppv );
852*cdf0e10cSrcweir 
853*cdf0e10cSrcweir 		SHCoCreateInstance_PROC	lpfnSHCoCreateInstance = (SHCoCreateInstance_PROC)GetProcAddress( hModShell, MAKEINTRESOURCE(102) );
854*cdf0e10cSrcweir 
855*cdf0e10cSrcweir 		if ( lpfnSHCoCreateInstance )
856*cdf0e10cSrcweir 			hResult = lpfnSHCoCreateInstance( lpszReserved, clsid, pUnkUnknown, iid, ppv );
857*cdf0e10cSrcweir 	}
858*cdf0e10cSrcweir 	return hResult;
859*cdf0e10cSrcweir }
860*cdf0e10cSrcweir 
861*cdf0e10cSrcweir BOOL CreateShortcut( const OUString& rAbsObject, const OUString& rAbsObjectPath,
862*cdf0e10cSrcweir 	const OUString& rAbsShortcut, const OUString& rDescription, const OUString& rParameter )
863*cdf0e10cSrcweir {
864*cdf0e10cSrcweir 	HRESULT hres;
865*cdf0e10cSrcweir 	IShellLink* psl;
866*cdf0e10cSrcweir 	CLSID clsid_ShellLink = CLSID_ShellLink;
867*cdf0e10cSrcweir 	CLSID clsid_IShellLink = IID_IShellLink;
868*cdf0e10cSrcweir 
869*cdf0e10cSrcweir 	hres = CoCreateInstance( clsid_ShellLink, NULL, CLSCTX_INPROC_SERVER,
870*cdf0e10cSrcweir 							 clsid_IShellLink, (void**)&psl );
871*cdf0e10cSrcweir 	if( FAILED(hres) )
872*cdf0e10cSrcweir 		hres = SHCoCreateInstance( NULL, clsid_ShellLink, NULL, clsid_IShellLink, (void**)&psl );
873*cdf0e10cSrcweir 
874*cdf0e10cSrcweir 	if( SUCCEEDED(hres) )
875*cdf0e10cSrcweir 	{
876*cdf0e10cSrcweir 		IPersistFile* ppf;
877*cdf0e10cSrcweir 		psl->SetPath( OUStringToOString(rAbsObject, osl_getThreadTextEncoding()).getStr() );
878*cdf0e10cSrcweir 		psl->SetWorkingDirectory( OUStringToOString(rAbsObjectPath, osl_getThreadTextEncoding()).getStr() );
879*cdf0e10cSrcweir 		psl->SetDescription( OUStringToOString(rDescription, osl_getThreadTextEncoding()).getStr() );
880*cdf0e10cSrcweir 		if( rParameter.getLength() )
881*cdf0e10cSrcweir 			psl->SetArguments( OUStringToOString(rParameter, osl_getThreadTextEncoding()).getStr() );
882*cdf0e10cSrcweir 
883*cdf0e10cSrcweir 		CLSID clsid_IPersistFile = IID_IPersistFile;
884*cdf0e10cSrcweir 		hres = psl->QueryInterface( clsid_IPersistFile, (void**)&ppf );
885*cdf0e10cSrcweir 
886*cdf0e10cSrcweir 		if( SUCCEEDED(hres) )
887*cdf0e10cSrcweir 		{
888*cdf0e10cSrcweir 			hres = ppf->Save( reinterpret_cast<LPCOLESTR>(rAbsShortcut.getStr()), TRUE );
889*cdf0e10cSrcweir 			ppf->Release();
890*cdf0e10cSrcweir 		} else return FALSE;
891*cdf0e10cSrcweir 		psl->Release();
892*cdf0e10cSrcweir 	} else return FALSE;
893*cdf0e10cSrcweir 	return TRUE;
894*cdf0e10cSrcweir }
895*cdf0e10cSrcweir 
896*cdf0e10cSrcweir // ------------------
897*cdf0e10cSrcweir // install/uninstall
898*cdf0e10cSrcweir 
899*cdf0e10cSrcweir static bool FileExistsW( LPCWSTR lpPath )
900*cdf0e10cSrcweir {
901*cdf0e10cSrcweir 	bool	bExists = false;
902*cdf0e10cSrcweir 	WIN32_FIND_DATAW	aFindData;
903*cdf0e10cSrcweir 
904*cdf0e10cSrcweir 	HANDLE	hFind = FindFirstFileW( lpPath, &aFindData );
905*cdf0e10cSrcweir 
906*cdf0e10cSrcweir 	if ( INVALID_HANDLE_VALUE != hFind )
907*cdf0e10cSrcweir 	{
908*cdf0e10cSrcweir 		bExists = true;
909*cdf0e10cSrcweir 		FindClose( hFind );
910*cdf0e10cSrcweir 	}
911*cdf0e10cSrcweir 
912*cdf0e10cSrcweir 	return bExists;
913*cdf0e10cSrcweir }
914*cdf0e10cSrcweir 
915*cdf0e10cSrcweir bool ShutdownIcon::IsQuickstarterInstalled()
916*cdf0e10cSrcweir {
917*cdf0e10cSrcweir     wchar_t aPath[_MAX_PATH];
918*cdf0e10cSrcweir     if( isNT() )
919*cdf0e10cSrcweir     {
920*cdf0e10cSrcweir         GetModuleFileNameW( NULL, aPath, _MAX_PATH-1);
921*cdf0e10cSrcweir     }
922*cdf0e10cSrcweir     else
923*cdf0e10cSrcweir     {
924*cdf0e10cSrcweir         char szPathA[_MAX_PATH];
925*cdf0e10cSrcweir         GetModuleFileNameA( NULL, szPathA, _MAX_PATH-1);
926*cdf0e10cSrcweir 
927*cdf0e10cSrcweir 		// calc the string wcstr len
928*cdf0e10cSrcweir 		int nNeededWStrBuffSize = MultiByteToWideChar( CP_ACP, 0, szPathA, -1, NULL, 0 );
929*cdf0e10cSrcweir 
930*cdf0e10cSrcweir 		// copy the string if necessary
931*cdf0e10cSrcweir 		if ( nNeededWStrBuffSize > 0 )
932*cdf0e10cSrcweir 			MultiByteToWideChar( CP_ACP, 0, szPathA, -1, aPath, nNeededWStrBuffSize );
933*cdf0e10cSrcweir 	}
934*cdf0e10cSrcweir 
935*cdf0e10cSrcweir     OUString aOfficepath( reinterpret_cast<const sal_Unicode*>(aPath) );
936*cdf0e10cSrcweir     int i = aOfficepath.lastIndexOf((sal_Char) '\\');
937*cdf0e10cSrcweir     if( i != -1 )
938*cdf0e10cSrcweir         aOfficepath = aOfficepath.copy(0, i);
939*cdf0e10cSrcweir 
940*cdf0e10cSrcweir     OUString quickstartExe(aOfficepath);
941*cdf0e10cSrcweir     quickstartExe += OUString( RTL_CONSTASCII_USTRINGPARAM( "\\quickstart.exe" ) );
942*cdf0e10cSrcweir 
943*cdf0e10cSrcweir 	return FileExistsW( reinterpret_cast<LPCWSTR>(quickstartExe.getStr()) );
944*cdf0e10cSrcweir }
945*cdf0e10cSrcweir 
946*cdf0e10cSrcweir void ShutdownIcon::EnableAutostartW32( const rtl::OUString &aShortcut )
947*cdf0e10cSrcweir {
948*cdf0e10cSrcweir 	wchar_t aPath[_MAX_PATH];
949*cdf0e10cSrcweir 	if( isNT() )
950*cdf0e10cSrcweir 		GetModuleFileNameW( NULL, aPath, _MAX_PATH-1);
951*cdf0e10cSrcweir 	else
952*cdf0e10cSrcweir 	{
953*cdf0e10cSrcweir 		char szPathA[_MAX_PATH];
954*cdf0e10cSrcweir 		GetModuleFileNameA( NULL, szPathA, _MAX_PATH-1);
955*cdf0e10cSrcweir 
956*cdf0e10cSrcweir 		// calc the string wcstr len
957*cdf0e10cSrcweir 		int nNeededWStrBuffSize = MultiByteToWideChar( CP_ACP, 0, szPathA, -1, NULL, 0 );
958*cdf0e10cSrcweir 
959*cdf0e10cSrcweir 		// copy the string if necessary
960*cdf0e10cSrcweir 		if ( nNeededWStrBuffSize > 0 )
961*cdf0e10cSrcweir 			MultiByteToWideChar( CP_ACP, 0, szPathA, -1, aPath, nNeededWStrBuffSize );
962*cdf0e10cSrcweir 	}
963*cdf0e10cSrcweir 
964*cdf0e10cSrcweir 	OUString aOfficepath( reinterpret_cast<const sal_Unicode*>(aPath) );
965*cdf0e10cSrcweir 	int i = aOfficepath.lastIndexOf((sal_Char) '\\');
966*cdf0e10cSrcweir 	if( i != -1 )
967*cdf0e10cSrcweir 		aOfficepath = aOfficepath.copy(0, i);
968*cdf0e10cSrcweir 
969*cdf0e10cSrcweir 	OUString quickstartExe(aOfficepath);
970*cdf0e10cSrcweir 	quickstartExe += OUString( RTL_CONSTASCII_USTRINGPARAM( "\\quickstart.exe" ) );
971*cdf0e10cSrcweir 
972*cdf0e10cSrcweir 	CreateShortcut( quickstartExe, aOfficepath, aShortcut, OUString(), OUString() );
973*cdf0e10cSrcweir }
974*cdf0e10cSrcweir 
975*cdf0e10cSrcweir #endif // WNT
976*cdf0e10cSrcweir 
977*cdf0e10cSrcweir 
978