1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
29 #include <sal/macros.h>
33 // necessary to include system headers without warnings
35 #pragma warning(disable:4668 4917)
38 // Support Windows 95 too
41 #define USE_APP_SHORTCUTS
42 // the systray icon is only available on windows
44 #include <unotools/moduleoptions.hxx>
45 #include <unotools/dynamicmenuoptions.hxx>
47 #include "shutdownicon.hxx"
51 #include <osl/thread.h>
52 #include <systools/win32/qswin32.h>
53 #include <comphelper/sequenceashashmap.hxx>
57 using namespace ::rtl
;
58 using namespace ::osl
;
60 using ::com::sun::star::uno::Sequence
;
61 using ::com::sun::star::beans::PropertyValue
;
64 #define EXECUTER_WINDOWCLASS "SO Executer Class"
65 #define EXECUTER_WINDOWNAME "SO Executer Window"
68 #define ID_QUICKSTART 1
70 #if defined(USE_APP_SHORTCUTS)
74 # define IDM_IMPRESS 6
77 # define IDM_TEMPLATE 9
80 #define IDM_INSTALL 10
81 #define IDM_UNINSTALL 11
84 #define ICON_LO_DEFAULT 1
85 #define ICON_TEXT_DOCUMENT 2
86 #define ICON_TEXT_TEMPLATE 3
87 #define ICON_SPREADSHEET_DOCUMENT 4
88 #define ICON_SPREADSHEET_TEMPLATE 5
89 #define ICON_DRAWING_DOCUMENT 6
90 #define ICON_DRAWING_TEMPLATE 7
91 #define ICON_PRESENTATION_DOCUMENT 8
92 #define ICON_PRESENTATION_TEMPLATE 9
93 #define ICON_MASTER_DOCUMENT 10
94 #define ICON_TEMPLATE 11
95 #define ICON_DATABASE_DOCUMENT 12
96 #define ICON_MATH_DOCUMENT 13
97 #define ICON_MACROLIBRARY 1
98 #define ICON_OPEN 5 // See index of open folder icon in shell32.dll
99 #define ICON_SETUP 500
101 #define SFX_TASKBAR_NOTIFICATION WM_USER+1
103 static HWND aListenerWindow
= NULL
;
104 static HWND aExecuterWindow
= NULL
;
105 static HMENU popupMenu
= NULL
;
107 static void OnMeasureItem(HWND hwnd
, LPMEASUREITEMSTRUCT lpmis
);
108 static void OnDrawItem(HWND hwnd
, LPDRAWITEMSTRUCT lpdis
);
110 typedef struct tagMYITEM
117 // -------------------------------
119 static void addMenuItem( HMENU hMenu
, UINT id
, UINT iconId
, const OUString
& text
, int& pos
, int bOwnerdraw
, const OUString
& module
)
122 memset( &mi
, 0, sizeof( MENUITEMINFOW
) );
124 mi
.cbSize
= sizeof( MENUITEMINFOW
);
125 if( id
== static_cast<UINT
>( -1 ) )
128 mi
.fType
=MFT_SEPARATOR
;
134 mi
.fMask
=MIIM_TYPE
| MIIM_STATE
| MIIM_ID
| MIIM_DATA
;
135 mi
.fType
=MFT_OWNERDRAW
;
136 mi
.fState
=MFS_ENABLED
;
139 MYITEM
*pMyItem
= new MYITEM
;
140 pMyItem
->text
= text
;
141 pMyItem
->iconId
= iconId
;
142 pMyItem
->module
= module
;
143 mi
.dwItemData
= (DWORD
) pMyItem
;
147 mi
.fMask
=MIIM_TYPE
| MIIM_STATE
| MIIM_ID
| MIIM_DATA
;
149 mi
.fState
=MFS_ENABLED
;
151 mi
.dwTypeData
= (LPWSTR
) text
.getStr();
152 mi
.cch
= text
.getLength();
155 #if defined(USE_APP_SHORTCUTS)
156 if ( IDM_TEMPLATE
== id
)
157 mi
.fState
|= MFS_DEFAULT
;
161 InsertMenuItemW( hMenu
, pos
++, TRUE
, &mi
);
164 // -------------------------------
166 static HMENU
createSystrayMenu( )
168 SvtModuleOptions aModuleOptions
;
170 HMENU hMenu
= CreatePopupMenu();
173 ShutdownIcon
*pShutdownIcon
= ShutdownIcon::getInstance();
174 OSL_ENSURE( pShutdownIcon
, "ShutdownIcon instance empty!");
179 #if defined(USE_APP_SHORTCUTS)
180 // collect the URLs of the entries in the File/New menu
181 ::std::set
< ::rtl::OUString
> aFileNewAppsAvailable
;
182 SvtDynamicMenuOptions aOpt
;
183 Sequence
< Sequence
< PropertyValue
> > aNewMenu
= aOpt
.GetMenu( E_NEWMENU
);
184 const ::rtl::OUString
sURLKey( "URL" );
186 const Sequence
< PropertyValue
>* pNewMenu
= aNewMenu
.getConstArray();
187 const Sequence
< PropertyValue
>* pNewMenuEnd
= aNewMenu
.getConstArray() + aNewMenu
.getLength();
188 for ( ; pNewMenu
!= pNewMenuEnd
; ++pNewMenu
)
190 ::comphelper::SequenceAsHashMap
aEntryItems( *pNewMenu
);
191 ::rtl::OUString
sURL( aEntryItems
.getUnpackedValueOrDefault( sURLKey
, ::rtl::OUString() ) );
192 if ( sURL
.getLength() )
193 aFileNewAppsAvailable
.insert( sURL
);
196 // describe the menu entries for launching the applications
197 struct MenuEntryDescriptor
199 SvtModuleOptions::EModule eModuleIdentifier
;
202 const char* pAsciiURLDescription
;
205 { SvtModuleOptions::E_SWRITER
, IDM_WRITER
, ICON_TEXT_DOCUMENT
, WRITER_URL
},
206 { SvtModuleOptions::E_SCALC
, IDM_CALC
, ICON_SPREADSHEET_DOCUMENT
, CALC_URL
},
207 { SvtModuleOptions::E_SIMPRESS
, IDM_IMPRESS
,ICON_PRESENTATION_DOCUMENT
, IMPRESS_WIZARD_URL
},
208 { SvtModuleOptions::E_SDRAW
, IDM_DRAW
, ICON_DRAWING_DOCUMENT
, DRAW_URL
},
209 { SvtModuleOptions::E_SDATABASE
, IDM_BASE
, ICON_DATABASE_DOCUMENT
, BASE_URL
},
210 { SvtModuleOptions::E_SMATH
, IDM_MATH
, ICON_MATH_DOCUMENT
, MATH_URL
},
215 // insert the menu entries for launching the applications
216 for ( size_t i
= 0; i
< sizeof( aMenuItems
) / sizeof( aMenuItems
[0] ); ++i
)
218 if ( !aModuleOptions
.IsModuleInstalled( aMenuItems
[i
].eModuleIdentifier
) )
219 // the complete application is not even installed
222 ::rtl::OUString
sURL( ::rtl::OUString::createFromAscii( aMenuItems
[i
].pAsciiURLDescription
) );
224 if ( aFileNewAppsAvailable
.find( sURL
) == aFileNewAppsAvailable
.end() )
225 // the application is installed, but the entry has been configured to *not* appear in the File/New
226 // menu => also let not appear it in the quickstarter
229 addMenuItem( hMenu
, aMenuItems
[i
].nMenuItemID
, aMenuItems
[i
].nMenuIconID
,
230 pShutdownIcon
->GetUrlDescription( sURL
), pos
, true, aEmpty
);
235 // insert the remaining menu entries
236 addMenuItem( hMenu
, IDM_TEMPLATE
, ICON_TEMPLATE
,
237 pShutdownIcon
->GetResString( STR_QUICKSTART_FROMTEMPLATE
), pos
, true, aEmpty
);
238 addMenuItem( hMenu
, static_cast< UINT
>( -1 ), 0, OUString(), pos
, false, aEmpty
);
239 addMenuItem( hMenu
, IDM_OPEN
, ICON_OPEN
, pShutdownIcon
->GetResString( STR_QUICKSTART_FILEOPEN
), pos
, true, OUString("SHELL32"));
240 addMenuItem( hMenu
, static_cast< UINT
>( -1 ), 0, OUString(), pos
, false, aEmpty
);
242 addMenuItem( hMenu
, IDM_INSTALL
,0, pShutdownIcon
->GetResString( STR_QUICKSTART_PRELAUNCH
), pos
, false, aEmpty
);
243 addMenuItem( hMenu
, static_cast< UINT
>( -1 ), 0, OUString(), pos
, false, aEmpty
);
244 addMenuItem( hMenu
, IDM_EXIT
, 0, pShutdownIcon
->GetResString( STR_QUICKSTART_EXIT
), pos
, false, aEmpty
);
246 // indicate status of autostart folder
247 CheckMenuItem( hMenu
, IDM_INSTALL
, MF_BYCOMMAND
| (ShutdownIcon::GetAutostart() ? MF_CHECKED
: MF_UNCHECKED
) );
252 // -------------------------------
254 static void deleteSystrayMenu( HMENU hMenu
)
256 if( !hMenu
|| !IsMenu( hMenu
))
262 memset( &mi
, 0, sizeof( mi
) );
263 mi
.cbSize
= sizeof( mi
);
264 mi
.fMask
= MIIM_DATA
;
266 while( GetMenuItemInfoW( hMenu
, pos
++, true, &mi
) )
268 pMyItem
= (MYITEM
*) mi
.dwItemData
;
271 pMyItem
->text
= OUString();
274 mi
.fMask
= MIIM_DATA
;
278 // -------------------------------
280 static void addTaskbarIcon( HWND hWnd
)
283 if( ShutdownIcon::getInstance() )
284 strTip
= ShutdownIcon::getInstance()->GetResString( STR_QUICKSTART_TIP
);
288 nid
.hIcon
= (HICON
)LoadImageA( GetModuleHandle( NULL
), MAKEINTRESOURCE( ICON_LO_DEFAULT
),
289 IMAGE_ICON
, GetSystemMetrics( SM_CXSMICON
), GetSystemMetrics( SM_CYSMICON
),
290 LR_DEFAULTCOLOR
| LR_SHARED
);
292 wcsncpy( nid
.szTip
, strTip
.getStr(), 64 );
294 nid
.cbSize
= sizeof(nid
);
296 nid
.uID
= ID_QUICKSTART
;
297 nid
.uCallbackMessage
= SFX_TASKBAR_NOTIFICATION
;
298 nid
.uFlags
= NIF_MESSAGE
|NIF_TIP
|NIF_ICON
;
300 Shell_NotifyIconW(NIM_ADD
, &nid
);
303 // -------------------------------
305 LRESULT CALLBACK
listenerWndProc( HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
307 static UINT s_uTaskbarRestart
= 0;
308 static UINT s_uMsgKillTray
= 0;
316 // request notfication when taskbar is recreated
317 // we then have to add our icon again
318 s_uTaskbarRestart
= RegisterWindowMessage(TEXT("TaskbarCreated"));
319 s_uMsgKillTray
= RegisterWindowMessage( SHUTDOWN_QUICKSTART_MESSAGE
);
323 if( (popupMenu
= createSystrayMenu( )) == NULL
)
327 addTaskbarIcon( hWnd
);
330 ShutdownIcon::getInstance()->SetVeto( true );
331 ShutdownIcon::getInstance()->addTerminateListener();
336 OnMeasureItem(hWnd
, (LPMEASUREITEMSTRUCT
) lParam
);
340 OnDrawItem(hWnd
, (LPDRAWITEMSTRUCT
) lParam
);
343 case SFX_TASKBAR_NOTIFICATION
:
346 case WM_LBUTTONDBLCLK
:
347 #if defined(USE_APP_SHORTCUTS)
348 PostMessage( aExecuterWindow
, WM_COMMAND
, IDM_TEMPLATE
, (LPARAM
)hWnd
);
356 SetForegroundWindow( hWnd
);
358 // update status before showing menu, could have been changed from option page
359 CheckMenuItem( popupMenu
, IDM_INSTALL
, MF_BYCOMMAND
| (ShutdownIcon::GetAutostart() ? MF_CHECKED
: MF_UNCHECKED
) );
361 EnableMenuItem( popupMenu
, IDM_EXIT
, MF_BYCOMMAND
| (ShutdownIcon::bModalMode
? MF_GRAYED
: MF_ENABLED
) );
362 #if defined(USE_APP_SHORTCUTS)
363 EnableMenuItem( popupMenu
, IDM_OPEN
, MF_BYCOMMAND
| (ShutdownIcon::bModalMode
? MF_GRAYED
: MF_ENABLED
) );
364 EnableMenuItem( popupMenu
, IDM_TEMPLATE
, MF_BYCOMMAND
| (ShutdownIcon::bModalMode
? MF_GRAYED
: MF_ENABLED
) );
366 int m
= TrackPopupMenuEx( popupMenu
, TPM_RETURNCMD
|TPM_LEFTALIGN
|TPM_RIGHTBUTTON
,
367 pt
.x
, pt
.y
, hWnd
, NULL
);
368 PostMessage( hWnd
, 0, 0, 0 );
371 #if defined(USE_APP_SHORTCUTS)
383 CheckMenuItem( popupMenu
, IDM_INSTALL
, MF_BYCOMMAND
| (ShutdownIcon::GetAutostart() ? MF_CHECKED
: MF_UNCHECKED
) );
386 // delete taskbar icon
388 nid
.cbSize
=sizeof(NOTIFYICONDATA
);
390 nid
.uID
= ID_QUICKSTART
;
391 Shell_NotifyIconA(NIM_DELETE
, &nid
);
395 PostMessage( aExecuterWindow
, WM_COMMAND
, m
, (LPARAM
)hWnd
);
401 deleteSystrayMenu( popupMenu
);
402 // We don't need the Systray Thread anymore
403 PostQuitMessage( 0 );
404 return DefWindowProc(hWnd
, uMsg
, wParam
, lParam
);
406 if( uMsg
== s_uTaskbarRestart
)
408 // re-create taskbar icon
409 addTaskbarIcon( hWnd
);
411 else if ( uMsg
== s_uMsgKillTray
)
413 // delete taskbar icon
415 nid
.cbSize
=sizeof(NOTIFYICONDATA
);
417 nid
.uID
= ID_QUICKSTART
;
418 Shell_NotifyIconA(NIM_DELETE
, &nid
);
420 PostMessage( aExecuterWindow
, WM_COMMAND
, IDM_EXIT
, (LPARAM
)hWnd
);
423 return DefWindowProc(hWnd
, uMsg
, wParam
, lParam
);
428 // -------------------------------
430 LRESULT CALLBACK
executerWndProc( HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
440 switch( LOWORD(wParam
) )
442 #if defined(USE_APP_SHORTCUTS)
444 if ( !ShutdownIcon::bModalMode
)
445 ShutdownIcon::FileOpen();
448 ShutdownIcon::OpenURL( OUString( WRITER_URL
), OUString( "_default" ) );
451 ShutdownIcon::OpenURL( OUString( CALC_URL
), OUString( "_default" ) );
454 ShutdownIcon::OpenURL( OUString( IMPRESS_WIZARD_URL
), OUString( "_default" ) );
457 ShutdownIcon::OpenURL( OUString( DRAW_URL
), OUString( "_default" ) );
460 ShutdownIcon::OpenURL( OUString( BASE_URL
), OUString( "_default" ) );
463 ShutdownIcon::OpenURL( OUString( MATH_URL
), OUString( "_default" ) );
466 if ( !ShutdownIcon::bModalMode
)
467 ShutdownIcon::FromTemplate();
471 ShutdownIcon::SetAutostart( !ShutdownIcon::GetAutostart() );
474 // remove listener and
475 // terminate office if running in background
476 if ( !ShutdownIcon::bModalMode
)
477 ShutdownIcon::terminateDesktop();
483 return DefWindowProc(hWnd
, uMsg
, wParam
, lParam
);
488 // -------------------------------
491 DWORD WINAPI
SystrayThread( LPVOID
/*lpParam*/ )
493 aListenerWindow
= CreateWindowExA(0,
494 QUICKSTART_CLASSNAME
, // registered class name
495 QUICKSTART_WINDOWNAME
, // window name
497 CW_USEDEFAULT
, // horizontal position of window
498 CW_USEDEFAULT
, // vertical position of window
499 CW_USEDEFAULT
, // window width
500 CW_USEDEFAULT
, // window height
501 (HWND
) NULL
, // handle to parent or owner window
502 NULL
, // menu handle or child identifier
503 (HINSTANCE
) GetModuleHandle( NULL
), // handle to application instance
504 NULL
// window-creation data
509 while ( GetMessage( &msg
, NULL
, 0, 0 ) )
511 TranslateMessage( &msg
);
512 DispatchMessage( &msg
);
515 return msg
.wParam
; // Exit code of WM_QUIT
518 // -------------------------------
520 void win32_init_sys_tray()
522 if ( ShutdownIcon::IsQuickstarterInstalled() )
524 WNDCLASSEXA listenerClass
;
525 listenerClass
.cbSize
= sizeof(WNDCLASSEX
);
526 listenerClass
.style
= 0;
527 listenerClass
.lpfnWndProc
= listenerWndProc
;
528 listenerClass
.cbClsExtra
= 0;
529 listenerClass
.cbWndExtra
= 0;
530 listenerClass
.hInstance
= (HINSTANCE
) GetModuleHandle( NULL
);
531 listenerClass
.hIcon
= NULL
;
532 listenerClass
.hCursor
= NULL
;
533 listenerClass
.hbrBackground
= NULL
;
534 listenerClass
.lpszMenuName
= NULL
;
535 listenerClass
.lpszClassName
= QUICKSTART_CLASSNAME
;
536 listenerClass
.hIconSm
= NULL
;
538 RegisterClassExA(&listenerClass
);
540 WNDCLASSEXA executerClass
;
541 executerClass
.cbSize
= sizeof(WNDCLASSEX
);
542 executerClass
.style
= 0;
543 executerClass
.lpfnWndProc
= executerWndProc
;
544 executerClass
.cbClsExtra
= 0;
545 executerClass
.cbWndExtra
= 0;
546 executerClass
.hInstance
= (HINSTANCE
) GetModuleHandle( NULL
);
547 executerClass
.hIcon
= NULL
;
548 executerClass
.hCursor
= NULL
;
549 executerClass
.hbrBackground
= NULL
;
550 executerClass
.lpszMenuName
= NULL
;
551 executerClass
.lpszClassName
= EXECUTER_WINDOWCLASS
;
552 executerClass
.hIconSm
= NULL
;
554 RegisterClassExA( &executerClass
);
556 aExecuterWindow
= CreateWindowExA(0,
557 EXECUTER_WINDOWCLASS
, // registered class name
558 EXECUTER_WINDOWNAME
, // window name
560 CW_USEDEFAULT
, // horizontal position of window
561 CW_USEDEFAULT
, // vertical position of window
562 CW_USEDEFAULT
, // window width
563 CW_USEDEFAULT
, // window height
564 (HWND
) NULL
, // handle to parent or owner window
565 NULL
, // menu handle or child identifier
566 (HINSTANCE
) GetModuleHandle( NULL
), // handle to application instance
567 NULL
// window-creation data
571 CreateThread( NULL
, 0, SystrayThread
, NULL
, 0, &dwThreadId
);
575 // -------------------------------
577 void win32_shutdown_sys_tray()
579 if ( ShutdownIcon::IsQuickstarterInstalled() )
581 if( IsWindow( aListenerWindow
) )
583 DestroyWindow( aListenerWindow
);
584 aListenerWindow
= NULL
;
585 DestroyWindow( aExecuterWindow
);
586 aExecuterWindow
= NULL
;
588 UnregisterClassA( QUICKSTART_CLASSNAME
, GetModuleHandle( NULL
) );
589 UnregisterClassA( EXECUTER_WINDOWCLASS
, GetModuleHandle( NULL
) );
595 // -------------------------------
597 void OnMeasureItem(HWND hwnd
, LPMEASUREITEMSTRUCT lpmis
)
599 MYITEM
*pMyItem
= (MYITEM
*) lpmis
->itemData
;
600 HDC hdc
= GetDC(hwnd
);
603 NONCLIENTMETRICS ncm
;
604 memset(&ncm
, 0, sizeof(ncm
));
605 ncm
.cbSize
= sizeof(ncm
);
607 SystemParametersInfo(SPI_GETNONCLIENTMETRICS
, 0, (PVOID
) &ncm
, 0);
609 // Assume every menu item can be default and printed bold
610 ncm
.lfMenuFont
.lfWeight
= FW_BOLD
;
612 HFONT hfntOld
= (HFONT
) SelectObject(hdc
, (HFONT
) CreateFontIndirect( &ncm
.lfMenuFont
));
614 GetTextExtentPoint32W(hdc
, reinterpret_cast<LPCWSTR
>(pMyItem
->text
.getStr()),
615 pMyItem
->text
.getLength(), &size
);
617 lpmis
->itemWidth
= size
.cx
+ 4 + GetSystemMetrics( SM_CXSMICON
);
618 lpmis
->itemHeight
= (size
.cy
> GetSystemMetrics( SM_CYSMICON
)) ? size
.cy
: GetSystemMetrics( SM_CYSMICON
);
619 lpmis
->itemHeight
+= 4;
621 DeleteObject( SelectObject(hdc
, hfntOld
) );
622 ReleaseDC(hwnd
, hdc
);
625 void OnDrawItem(HWND
/*hwnd*/, LPDRAWITEMSTRUCT lpdis
)
627 MYITEM
*pMyItem
= (MYITEM
*) lpdis
->itemData
;
628 COLORREF clrPrevText
, clrPrevBkgnd
;
632 BOOL fSelected
= lpdis
->itemState
& ODS_SELECTED
;
633 BOOL fDisabled
= lpdis
->itemState
& (ODS_DISABLED
| ODS_GRAYED
);
635 // Set the appropriate foreground and background colors.
637 RECT aRect
= lpdis
->rcItem
;
639 clrPrevBkgnd
= SetBkColor( lpdis
->hDC
, GetSysColor(COLOR_MENU
) );
642 clrPrevText
= SetTextColor( lpdis
->hDC
, GetSysColor( COLOR_GRAYTEXT
) );
644 clrPrevText
= SetTextColor( lpdis
->hDC
, GetSysColor( fSelected
? COLOR_HIGHLIGHTTEXT
: COLOR_MENUTEXT
) );
647 clrPrevBkgnd
= SetBkColor( lpdis
->hDC
, GetSysColor(COLOR_HIGHLIGHT
) );
649 clrPrevBkgnd
= SetBkColor( lpdis
->hDC
, GetSysColor(COLOR_MENU
) );
651 hbrOld
= (HBRUSH
)SelectObject( lpdis
->hDC
, CreateSolidBrush( GetBkColor( lpdis
->hDC
) ) );
654 PatBlt(lpdis
->hDC
, aRect
.left
, aRect
.top
, aRect
.right
-aRect
.left
, aRect
.bottom
-aRect
.top
, PATCOPY
);
656 int height
= aRect
.bottom
-aRect
.top
;
661 int cx
= GetSystemMetrics( SM_CXSMICON
);
662 int cy
= GetSystemMetrics( SM_CYSMICON
);
664 HMODULE
hModule( GetModuleHandle( NULL
) );
666 if ( pMyItem
->module
.getLength() > 0 )
668 LPCWSTR pModuleName
= reinterpret_cast<LPCWSTR
>( pMyItem
->module
.getStr() );
669 hModule
= GetModuleHandleW( pModuleName
);
670 if ( hModule
== NULL
)
672 LoadLibraryW( pModuleName
);
673 hModule
= GetModuleHandleW( pModuleName
);
677 hIcon
= (HICON
) LoadImageA( hModule
, MAKEINTRESOURCE( pMyItem
->iconId
),
679 LR_DEFAULTCOLOR
| LR_SHARED
);
682 HBRUSH hbrIcon
= CreateSolidBrush( GetSysColor( COLOR_GRAYTEXT
) );
684 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
) );
686 DeleteObject( hbrIcon
);
688 x
+= cx
+ 4; // space for icon
691 NONCLIENTMETRICS ncm
;
692 memset(&ncm
, 0, sizeof(ncm
));
693 ncm
.cbSize
= sizeof(ncm
);
695 SystemParametersInfo(SPI_GETNONCLIENTMETRICS
, 0, (PVOID
) &ncm
, 0);
697 // Print default menu entry with bold font
698 if ( lpdis
->itemState
& ODS_DEFAULT
)
699 ncm
.lfMenuFont
.lfWeight
= FW_BOLD
;
701 hfntOld
= (HFONT
) SelectObject(lpdis
->hDC
, (HFONT
) CreateFontIndirect( &ncm
.lfMenuFont
));
705 GetTextExtentPointW( lpdis
->hDC
, reinterpret_cast<LPCWSTR
>(pMyItem
->text
.getStr()), pMyItem
->text
.getLength(), &size
);
707 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
) );
709 // Restore the original font and colors.
710 DeleteObject( SelectObject( lpdis
->hDC
, hbrOld
) );
711 DeleteObject( SelectObject( lpdis
->hDC
, hfntOld
) );
712 SetTextColor(lpdis
->hDC
, clrPrevText
);
713 SetBkColor(lpdis
->hDC
, clrPrevBkgnd
);
716 // -------------------------------
717 // code from setup2 project
718 // -------------------------------
720 void _SHFree( void *pv
)
723 if( NOERROR
== SHGetMalloc(&pMalloc
) )
730 #define ALLOC(type, n) ((type *) HeapAlloc(GetProcessHeap(), 0, sizeof(type) * n ))
731 #define FREE(p) HeapFree(GetProcessHeap(), 0, p)
733 static OUString
_SHGetSpecialFolder( int nFolderID
)
737 HRESULT hHdl
= SHGetSpecialFolderLocation( NULL
, nFolderID
, &pidl
);
740 if( hHdl
== NOERROR
)
743 lpFolderA
= ALLOC( WCHAR
, 16000 );
745 SHGetPathFromIDListW( pidl
, lpFolderA
);
746 aFolder
= OUString( reinterpret_cast<const sal_Unicode
*>(lpFolderA
) );
754 OUString
ShutdownIcon::GetAutostartFolderNameW32()
756 return _SHGetSpecialFolder(CSIDL_STARTUP
);
759 static HRESULT WINAPI
SHCoCreateInstance( LPVOID lpszReserved
, REFCLSID clsid
, LPUNKNOWN pUnkUnknown
, REFIID iid
, LPVOID
*ppv
)
761 HRESULT hResult
= E_NOTIMPL
;
762 HMODULE hModShell
= GetModuleHandle( "SHELL32" );
764 if ( hModShell
!= NULL
)
766 typedef HRESULT (WINAPI
*SHCoCreateInstance_PROC
)( LPVOID lpszReserved
, REFCLSID clsid
, LPUNKNOWN pUnkUnknwon
, REFIID iid
, LPVOID
*ppv
);
768 SHCoCreateInstance_PROC lpfnSHCoCreateInstance
= (SHCoCreateInstance_PROC
)GetProcAddress( hModShell
, MAKEINTRESOURCE(102) );
770 if ( lpfnSHCoCreateInstance
)
771 hResult
= lpfnSHCoCreateInstance( lpszReserved
, clsid
, pUnkUnknown
, iid
, ppv
);
776 BOOL
CreateShortcut( const OUString
& rAbsObject
, const OUString
& rAbsObjectPath
,
777 const OUString
& rAbsShortcut
, const OUString
& rDescription
, const OUString
& rParameter
)
781 CLSID clsid_ShellLink
= CLSID_ShellLink
;
782 CLSID clsid_IShellLink
= IID_IShellLink
;
784 hres
= CoCreateInstance( clsid_ShellLink
, NULL
, CLSCTX_INPROC_SERVER
,
785 clsid_IShellLink
, (void**)&psl
);
787 hres
= SHCoCreateInstance( NULL
, clsid_ShellLink
, NULL
, clsid_IShellLink
, (void**)&psl
);
789 if( SUCCEEDED(hres
) )
792 psl
->SetPath( OUStringToOString(rAbsObject
, osl_getThreadTextEncoding()).getStr() );
793 psl
->SetWorkingDirectory( OUStringToOString(rAbsObjectPath
, osl_getThreadTextEncoding()).getStr() );
794 psl
->SetDescription( OUStringToOString(rDescription
, osl_getThreadTextEncoding()).getStr() );
795 if( rParameter
.getLength() )
796 psl
->SetArguments( OUStringToOString(rParameter
, osl_getThreadTextEncoding()).getStr() );
798 CLSID clsid_IPersistFile
= IID_IPersistFile
;
799 hres
= psl
->QueryInterface( clsid_IPersistFile
, (void**)&ppf
);
801 if( SUCCEEDED(hres
) )
803 hres
= ppf
->Save( reinterpret_cast<LPCOLESTR
>(rAbsShortcut
.getStr()), TRUE
);
811 // ------------------
814 static bool FileExistsW( LPCWSTR lpPath
)
816 bool bExists
= false;
817 WIN32_FIND_DATAW aFindData
;
819 HANDLE hFind
= FindFirstFileW( lpPath
, &aFindData
);
821 if ( INVALID_HANDLE_VALUE
!= hFind
)
830 bool ShutdownIcon::IsQuickstarterInstalled()
832 wchar_t aPath
[_MAX_PATH
];
833 GetModuleFileNameW( NULL
, aPath
, _MAX_PATH
-1);
835 OUString
aOfficepath( reinterpret_cast<const sal_Unicode
*>(aPath
) );
836 int i
= aOfficepath
.lastIndexOf((sal_Char
) '\\');
838 aOfficepath
= aOfficepath
.copy(0, i
);
840 OUString
quickstartExe(aOfficepath
);
841 quickstartExe
+= OUString( "\\quickstart.exe" );
843 return FileExistsW( reinterpret_cast<LPCWSTR
>(quickstartExe
.getStr()) );
846 void ShutdownIcon::EnableAutostartW32( const rtl::OUString
&aShortcut
)
848 wchar_t aPath
[_MAX_PATH
];
849 GetModuleFileNameW( NULL
, aPath
, _MAX_PATH
-1);
851 OUString
aOfficepath( reinterpret_cast<const sal_Unicode
*>(aPath
) );
852 int i
= aOfficepath
.lastIndexOf((sal_Char
) '\\');
854 aOfficepath
= aOfficepath
.copy(0, i
);
856 OUString
quickstartExe(aOfficepath
);
857 quickstartExe
+= OUString( "\\quickstart.exe" );
859 CreateShortcut( quickstartExe
, aOfficepath
, aShortcut
, OUString(), OUString() );
865 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */