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