2 * This file is part of the LibreOffice project.
4 * This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 * This file incorporates work covered by the following license notice:
10 * Licensed to the Apache Software Foundation (ASF) under one or more
11 * contributor license agreements. See the NOTICE file distributed
12 * with this work for additional information regarding copyright
13 * ownership. The ASF licenses this file to you under the Apache
14 * License, Version 2.0 (the "License"); you may not use this file
15 * except in compliance with the License. You may obtain a copy of
16 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
19 #include <sal/macros.h>
23 // necessary to include system headers without warnings
25 #pragma warning(disable:4668 4917)
28 #define USE_APP_SHORTCUTS
29 // the systray icon is only available on windows
31 #include <unotools/moduleoptions.hxx>
32 #include <unotools/dynamicmenuoptions.hxx>
37 #include "shutdownicon.hxx"
41 #include <osl/thread.h>
42 #include <systools/win32/qswin32.h>
43 #include <comphelper/sequenceashashmap.hxx>
47 using namespace ::osl
;
49 using ::com::sun::star::uno::Sequence
;
50 using ::com::sun::star::beans::PropertyValue
;
53 #define EXECUTER_WINDOWCLASS "SO Executer Class"
54 #define EXECUTER_WINDOWNAME "SO Executer Window"
57 #define ID_QUICKSTART 1
59 #if defined(USE_APP_SHORTCUTS)
63 # define IDM_IMPRESS 6
66 # define IDM_TEMPLATE 9
69 #define IDM_INSTALL 10
72 #define ICON_LO_DEFAULT 1
73 #define ICON_TEXT_DOCUMENT 2
74 #define ICON_SPREADSHEET_DOCUMENT 4
75 #define ICON_DRAWING_DOCUMENT 6
76 #define ICON_PRESENTATION_DOCUMENT 8
77 #define ICON_TEMPLATE 11
78 #define ICON_DATABASE_DOCUMENT 12
79 #define ICON_MATH_DOCUMENT 13
80 #define ICON_OPEN 5 // See index of open folder icon in shell32.dll
82 #define SFX_TASKBAR_NOTIFICATION WM_USER+1
84 static HWND aListenerWindow
= NULL
;
85 static HWND aExecuterWindow
= NULL
;
86 static HMENU popupMenu
= NULL
;
88 static void OnMeasureItem(HWND hwnd
, LPMEASUREITEMSTRUCT lpmis
);
89 static void OnDrawItem(HWND hwnd
, LPDRAWITEMSTRUCT lpdis
);
91 typedef struct tagMYITEM
100 static void addMenuItem( HMENU hMenu
, UINT id
, UINT iconId
, const OUString
& text
, int& pos
, int bOwnerdraw
, const OUString
& module
)
103 memset( &mi
, 0, sizeof( MENUITEMINFOW
) );
105 mi
.cbSize
= sizeof( MENUITEMINFOW
);
106 if( id
== static_cast<UINT
>( -1 ) )
109 mi
.fType
=MFT_SEPARATOR
;
115 mi
.fMask
=MIIM_TYPE
| MIIM_STATE
| MIIM_ID
| MIIM_DATA
;
116 mi
.fType
=MFT_OWNERDRAW
;
117 mi
.fState
=MFS_ENABLED
;
120 MYITEM
*pMyItem
= new MYITEM
;
121 pMyItem
->text
= text
;
122 pMyItem
->iconId
= iconId
;
123 pMyItem
->module
= module
;
124 mi
.dwItemData
= (DWORD_PTR
) pMyItem
;
128 mi
.fMask
=MIIM_TYPE
| MIIM_STATE
| MIIM_ID
| MIIM_DATA
;
130 mi
.fState
=MFS_ENABLED
;
132 mi
.dwTypeData
= (LPWSTR
) text
.getStr();
133 mi
.cch
= text
.getLength();
136 #if defined(USE_APP_SHORTCUTS)
137 if ( IDM_TEMPLATE
== id
)
138 mi
.fState
|= MFS_DEFAULT
;
142 InsertMenuItemW( hMenu
, pos
++, TRUE
, &mi
);
147 static HMENU
createSystrayMenu( )
149 SvtModuleOptions aModuleOptions
;
151 HMENU hMenu
= CreatePopupMenu();
154 ShutdownIcon
*pShutdownIcon
= ShutdownIcon::getInstance();
155 OSL_ENSURE( pShutdownIcon
, "ShutdownIcon instance empty!");
160 #if defined(USE_APP_SHORTCUTS)
161 // collect the URLs of the entries in the File/New menu
162 ::std::set
< OUString
> aFileNewAppsAvailable
;
163 SvtDynamicMenuOptions aOpt
;
164 Sequence
< Sequence
< PropertyValue
> > aNewMenu
= aOpt
.GetMenu( E_NEWMENU
);
165 const OUString
sURLKey( "URL" );
167 const Sequence
< PropertyValue
>* pNewMenu
= aNewMenu
.getConstArray();
168 const Sequence
< PropertyValue
>* pNewMenuEnd
= aNewMenu
.getConstArray() + aNewMenu
.getLength();
169 for ( ; pNewMenu
!= pNewMenuEnd
; ++pNewMenu
)
171 ::comphelper::SequenceAsHashMap
aEntryItems( *pNewMenu
);
172 OUString
sURL( aEntryItems
.getUnpackedValueOrDefault( sURLKey
, OUString() ) );
173 if ( sURL
.getLength() )
174 aFileNewAppsAvailable
.insert( sURL
);
177 // describe the menu entries for launching the applications
178 struct MenuEntryDescriptor
180 SvtModuleOptions::EModule eModuleIdentifier
;
183 const char* pAsciiURLDescription
;
186 { SvtModuleOptions::EModule::WRITER
, IDM_WRITER
, ICON_TEXT_DOCUMENT
, WRITER_URL
},
187 { SvtModuleOptions::EModule::CALC
, IDM_CALC
, ICON_SPREADSHEET_DOCUMENT
, CALC_URL
},
188 { SvtModuleOptions::EModule::IMPRESS
, IDM_IMPRESS
,ICON_PRESENTATION_DOCUMENT
, IMPRESS_WIZARD_URL
},
189 { SvtModuleOptions::EModule::DRAW
, IDM_DRAW
, ICON_DRAWING_DOCUMENT
, DRAW_URL
},
190 { SvtModuleOptions::EModule::DATABASE
, IDM_BASE
, ICON_DATABASE_DOCUMENT
, BASE_URL
},
191 { SvtModuleOptions::EModule::MATH
, IDM_MATH
, ICON_MATH_DOCUMENT
, MATH_URL
},
196 // insert the menu entries for launching the applications
197 for ( size_t i
= 0; i
< sizeof( aMenuItems
) / sizeof( aMenuItems
[0] ); ++i
)
199 if ( !aModuleOptions
.IsModuleInstalled( aMenuItems
[i
].eModuleIdentifier
) )
200 // the complete application is not even installed
203 OUString
sURL( OUString::createFromAscii( aMenuItems
[i
].pAsciiURLDescription
) );
205 if ( aFileNewAppsAvailable
.find( sURL
) == aFileNewAppsAvailable
.end() )
206 // the application is installed, but the entry has been configured to *not* appear in the File/New
207 // menu => also let not appear it in the quickstarter
210 addMenuItem( hMenu
, aMenuItems
[i
].nMenuItemID
, aMenuItems
[i
].nMenuIconID
,
211 pShutdownIcon
->GetUrlDescription( sURL
), pos
, true, aEmpty
);
216 // insert the remaining menu entries
217 addMenuItem( hMenu
, IDM_TEMPLATE
, ICON_TEMPLATE
,
218 pShutdownIcon
->GetResString( STR_QUICKSTART_FROMTEMPLATE
), pos
, true, aEmpty
);
219 addMenuItem( hMenu
, static_cast< UINT
>( -1 ), 0, OUString(), pos
, false, aEmpty
);
220 addMenuItem( hMenu
, IDM_OPEN
, ICON_OPEN
, pShutdownIcon
->GetResString( STR_QUICKSTART_FILEOPEN
), pos
, true, OUString("SHELL32"));
221 addMenuItem( hMenu
, static_cast< UINT
>( -1 ), 0, OUString(), pos
, false, aEmpty
);
223 addMenuItem( hMenu
, IDM_INSTALL
,0, pShutdownIcon
->GetResString( STR_QUICKSTART_PRELAUNCH
), pos
, false, aEmpty
);
224 addMenuItem( hMenu
, static_cast< UINT
>( -1 ), 0, OUString(), pos
, false, aEmpty
);
225 addMenuItem( hMenu
, IDM_EXIT
, 0, pShutdownIcon
->GetResString( STR_QUICKSTART_EXIT
), pos
, false, aEmpty
);
227 // indicate status of autostart folder
228 CheckMenuItem( hMenu
, IDM_INSTALL
, MF_BYCOMMAND
| (ShutdownIcon::GetAutostart() ? MF_CHECKED
: MF_UNCHECKED
) );
235 static void deleteSystrayMenu( HMENU hMenu
)
237 if( !hMenu
|| !IsMenu( hMenu
))
242 memset( &mi
, 0, sizeof( mi
) );
243 mi
.cbSize
= sizeof( mi
);
244 mi
.fMask
= MIIM_DATA
;
246 while( GetMenuItemInfoW( hMenu
, pos
++, true, &mi
) )
248 MYITEM
*pMyItem
= (MYITEM
*) mi
.dwItemData
;
251 (pMyItem
->text
).clear();
254 mi
.fMask
= MIIM_DATA
;
260 static void addTaskbarIcon( HWND hWnd
)
263 if( ShutdownIcon::getInstance() )
264 strTip
= ShutdownIcon::getInstance()->GetResString( STR_QUICKSTART_TIP
);
268 nid
.hIcon
= (HICON
)LoadImageA( GetModuleHandle( NULL
), MAKEINTRESOURCE( ICON_LO_DEFAULT
),
269 IMAGE_ICON
, GetSystemMetrics( SM_CXSMICON
), GetSystemMetrics( SM_CYSMICON
),
270 LR_DEFAULTCOLOR
| LR_SHARED
);
272 wcsncpy( nid
.szTip
, reinterpret_cast<LPCWSTR
>(strTip
.getStr()), 64 );
274 nid
.cbSize
= sizeof(nid
);
276 nid
.uID
= ID_QUICKSTART
;
277 nid
.uCallbackMessage
= SFX_TASKBAR_NOTIFICATION
;
278 nid
.uFlags
= NIF_MESSAGE
|NIF_TIP
|NIF_ICON
;
280 Shell_NotifyIconW(NIM_ADD
, &nid
);
285 LRESULT CALLBACK
listenerWndProc( HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
287 static UINT s_uTaskbarRestart
= 0;
288 static UINT s_uMsgKillTray
= 0;
296 // request notfication when taskbar is recreated
297 // we then have to add our icon again
298 s_uTaskbarRestart
= RegisterWindowMessage(TEXT("TaskbarCreated"));
299 s_uMsgKillTray
= RegisterWindowMessage( SHUTDOWN_QUICKSTART_MESSAGE
);
303 if( (popupMenu
= createSystrayMenu( )) == NULL
)
307 addTaskbarIcon( hWnd
);
310 ShutdownIcon::getInstance()->SetVeto( true );
311 ShutdownIcon::getInstance()->addTerminateListener();
316 OnMeasureItem(hWnd
, (LPMEASUREITEMSTRUCT
) lParam
);
320 OnDrawItem(hWnd
, (LPDRAWITEMSTRUCT
) lParam
);
323 case SFX_TASKBAR_NOTIFICATION
:
326 case WM_LBUTTONDBLCLK
:
327 #if defined(USE_APP_SHORTCUTS)
328 PostMessage( aExecuterWindow
, WM_COMMAND
, IDM_TEMPLATE
, (LPARAM
)hWnd
);
336 SetForegroundWindow( hWnd
);
338 // update status before showing menu, could have been changed from option page
339 CheckMenuItem( popupMenu
, IDM_INSTALL
, MF_BYCOMMAND
| (ShutdownIcon::GetAutostart() ? MF_CHECKED
: MF_UNCHECKED
) );
341 EnableMenuItem( popupMenu
, IDM_EXIT
, MF_BYCOMMAND
| (ShutdownIcon::bModalMode
? MF_GRAYED
: MF_ENABLED
) );
342 #if defined(USE_APP_SHORTCUTS)
343 EnableMenuItem( popupMenu
, IDM_OPEN
, MF_BYCOMMAND
| (ShutdownIcon::bModalMode
? MF_GRAYED
: MF_ENABLED
) );
344 EnableMenuItem( popupMenu
, IDM_TEMPLATE
, MF_BYCOMMAND
| (ShutdownIcon::bModalMode
? MF_GRAYED
: MF_ENABLED
) );
346 int m
= TrackPopupMenuEx( popupMenu
, TPM_RETURNCMD
|TPM_LEFTALIGN
|TPM_RIGHTBUTTON
,
347 pt
.x
, pt
.y
, hWnd
, NULL
);
348 PostMessage( hWnd
, 0, 0, 0 );
351 #if defined(USE_APP_SHORTCUTS)
363 CheckMenuItem( popupMenu
, IDM_INSTALL
, MF_BYCOMMAND
| (ShutdownIcon::GetAutostart() ? MF_CHECKED
: MF_UNCHECKED
) );
366 // delete taskbar icon
368 nid
.cbSize
=sizeof(NOTIFYICONDATA
);
370 nid
.uID
= ID_QUICKSTART
;
371 Shell_NotifyIconA(NIM_DELETE
, &nid
);
375 PostMessage( aExecuterWindow
, WM_COMMAND
, m
, (LPARAM
)hWnd
);
381 deleteSystrayMenu( popupMenu
);
382 // We don't need the Systray Thread anymore
383 PostQuitMessage( 0 );
384 return DefWindowProc(hWnd
, uMsg
, wParam
, lParam
);
386 if( uMsg
== s_uTaskbarRestart
)
388 // re-create taskbar icon
389 addTaskbarIcon( hWnd
);
391 else if ( uMsg
== s_uMsgKillTray
)
393 // delete taskbar icon
395 nid
.cbSize
=sizeof(NOTIFYICONDATA
);
397 nid
.uID
= ID_QUICKSTART
;
398 Shell_NotifyIconA(NIM_DELETE
, &nid
);
400 PostMessage( aExecuterWindow
, WM_COMMAND
, IDM_EXIT
, (LPARAM
)hWnd
);
403 return DefWindowProc(hWnd
, uMsg
, wParam
, lParam
);
410 LRESULT CALLBACK
executerWndProc( HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
420 switch( LOWORD(wParam
) )
422 #if defined(USE_APP_SHORTCUTS)
424 if ( !ShutdownIcon::bModalMode
)
425 ShutdownIcon::FileOpen();
428 ShutdownIcon::OpenURL( OUString( WRITER_URL
), OUString( "_default" ) );
431 ShutdownIcon::OpenURL( OUString( CALC_URL
), OUString( "_default" ) );
434 ShutdownIcon::OpenURL( OUString( IMPRESS_WIZARD_URL
), OUString( "_default" ) );
437 ShutdownIcon::OpenURL( OUString( DRAW_URL
), OUString( "_default" ) );
440 ShutdownIcon::OpenURL( OUString( BASE_URL
), OUString( "_default" ) );
443 ShutdownIcon::OpenURL( OUString( MATH_URL
), OUString( "_default" ) );
446 if ( !ShutdownIcon::bModalMode
)
447 ShutdownIcon::FromTemplate();
451 ShutdownIcon::SetAutostart( !ShutdownIcon::GetAutostart() );
454 // remove listener and
455 // terminate office if running in background
456 if ( !ShutdownIcon::bModalMode
)
457 ShutdownIcon::terminateDesktop();
463 return DefWindowProc(hWnd
, uMsg
, wParam
, lParam
);
471 DWORD WINAPI
SystrayThread( LPVOID
/*lpParam*/ )
473 osl_setThreadName("SystrayThread");
475 aListenerWindow
= CreateWindowExA(0,
476 QUICKSTART_CLASSNAME
, // registered class name
477 QUICKSTART_WINDOWNAME
, // window name
479 CW_USEDEFAULT
, // horizontal position of window
480 CW_USEDEFAULT
, // vertical position of window
481 CW_USEDEFAULT
, // window width
482 CW_USEDEFAULT
, // window height
483 (HWND
) NULL
, // handle to parent or owner window
484 NULL
, // menu handle or child identifier
485 (HINSTANCE
) GetModuleHandle( NULL
), // handle to application instance
486 NULL
// window-creation data
491 while ( GetMessage( &msg
, NULL
, 0, 0 ) )
493 TranslateMessage( &msg
);
494 DispatchMessage( &msg
);
497 return msg
.wParam
; // Exit code of WM_QUIT
502 void win32_init_sys_tray()
504 if ( ShutdownIcon::IsQuickstarterInstalled() )
506 WNDCLASSEXA listenerClass
;
507 listenerClass
.cbSize
= sizeof(WNDCLASSEX
);
508 listenerClass
.style
= 0;
509 listenerClass
.lpfnWndProc
= listenerWndProc
;
510 listenerClass
.cbClsExtra
= 0;
511 listenerClass
.cbWndExtra
= 0;
512 listenerClass
.hInstance
= (HINSTANCE
) GetModuleHandle( NULL
);
513 listenerClass
.hIcon
= NULL
;
514 listenerClass
.hCursor
= NULL
;
515 listenerClass
.hbrBackground
= NULL
;
516 listenerClass
.lpszMenuName
= NULL
;
517 listenerClass
.lpszClassName
= QUICKSTART_CLASSNAME
;
518 listenerClass
.hIconSm
= NULL
;
520 RegisterClassExA(&listenerClass
);
522 WNDCLASSEXA executerClass
;
523 executerClass
.cbSize
= sizeof(WNDCLASSEX
);
524 executerClass
.style
= 0;
525 executerClass
.lpfnWndProc
= executerWndProc
;
526 executerClass
.cbClsExtra
= 0;
527 executerClass
.cbWndExtra
= 0;
528 executerClass
.hInstance
= (HINSTANCE
) GetModuleHandle( NULL
);
529 executerClass
.hIcon
= NULL
;
530 executerClass
.hCursor
= NULL
;
531 executerClass
.hbrBackground
= NULL
;
532 executerClass
.lpszMenuName
= NULL
;
533 executerClass
.lpszClassName
= EXECUTER_WINDOWCLASS
;
534 executerClass
.hIconSm
= NULL
;
536 RegisterClassExA( &executerClass
);
538 aExecuterWindow
= CreateWindowExA(0,
539 EXECUTER_WINDOWCLASS
, // registered class name
540 EXECUTER_WINDOWNAME
, // window name
542 CW_USEDEFAULT
, // horizontal position of window
543 CW_USEDEFAULT
, // vertical position of window
544 CW_USEDEFAULT
, // window width
545 CW_USEDEFAULT
, // window height
546 (HWND
) NULL
, // handle to parent or owner window
547 NULL
, // menu handle or child identifier
548 (HINSTANCE
) GetModuleHandle( NULL
), // handle to application instance
549 NULL
// window-creation data
553 CreateThread( NULL
, 0, SystrayThread
, NULL
, 0, &dwThreadId
);
559 void win32_shutdown_sys_tray()
561 if ( ShutdownIcon::IsQuickstarterInstalled() )
563 if( IsWindow( aListenerWindow
) )
565 DestroyWindow( aListenerWindow
);
566 aListenerWindow
= NULL
;
567 DestroyWindow( aExecuterWindow
);
568 aExecuterWindow
= NULL
;
570 UnregisterClassA( QUICKSTART_CLASSNAME
, GetModuleHandle( NULL
) );
571 UnregisterClassA( EXECUTER_WINDOWCLASS
, GetModuleHandle( NULL
) );
579 void OnMeasureItem(HWND hwnd
, LPMEASUREITEMSTRUCT lpmis
)
581 MYITEM
*pMyItem
= (MYITEM
*) lpmis
->itemData
;
582 HDC hdc
= GetDC(hwnd
);
585 NONCLIENTMETRICS ncm
;
586 memset(&ncm
, 0, sizeof(ncm
));
587 ncm
.cbSize
= sizeof(ncm
);
589 SystemParametersInfo(SPI_GETNONCLIENTMETRICS
, 0, (PVOID
) &ncm
, 0);
591 // Assume every menu item can be default and printed bold
592 ncm
.lfMenuFont
.lfWeight
= FW_BOLD
;
594 HFONT hfntOld
= (HFONT
) SelectObject(hdc
, (HFONT
) CreateFontIndirect( &ncm
.lfMenuFont
));
596 GetTextExtentPoint32W(hdc
, reinterpret_cast<LPCWSTR
>(pMyItem
->text
.getStr()),
597 pMyItem
->text
.getLength(), &size
);
599 lpmis
->itemWidth
= size
.cx
+ 4 + GetSystemMetrics( SM_CXSMICON
);
600 lpmis
->itemHeight
= (size
.cy
> GetSystemMetrics( SM_CYSMICON
)) ? size
.cy
: GetSystemMetrics( SM_CYSMICON
);
601 lpmis
->itemHeight
+= 4;
603 DeleteObject( SelectObject(hdc
, hfntOld
) );
604 ReleaseDC(hwnd
, hdc
);
607 void OnDrawItem(HWND
/*hwnd*/, LPDRAWITEMSTRUCT lpdis
)
609 MYITEM
*pMyItem
= (MYITEM
*) lpdis
->itemData
;
610 COLORREF clrPrevText
, clrPrevBkgnd
;
614 BOOL fSelected
= lpdis
->itemState
& ODS_SELECTED
;
615 BOOL fDisabled
= lpdis
->itemState
& (ODS_DISABLED
| ODS_GRAYED
);
617 // Set the appropriate foreground and background colors.
619 RECT aRect
= lpdis
->rcItem
;
621 clrPrevBkgnd
= SetBkColor( lpdis
->hDC
, GetSysColor(COLOR_MENU
) );
624 clrPrevText
= SetTextColor( lpdis
->hDC
, GetSysColor( COLOR_GRAYTEXT
) );
626 clrPrevText
= SetTextColor( lpdis
->hDC
, GetSysColor( fSelected
? COLOR_HIGHLIGHTTEXT
: COLOR_MENUTEXT
) );
629 clrPrevBkgnd
= SetBkColor( lpdis
->hDC
, GetSysColor(COLOR_HIGHLIGHT
) );
631 clrPrevBkgnd
= SetBkColor( lpdis
->hDC
, GetSysColor(COLOR_MENU
) );
633 hbrOld
= (HBRUSH
)SelectObject( lpdis
->hDC
, CreateSolidBrush( GetBkColor( lpdis
->hDC
) ) );
636 PatBlt(lpdis
->hDC
, aRect
.left
, aRect
.top
, aRect
.right
-aRect
.left
, aRect
.bottom
-aRect
.top
, PATCOPY
);
638 int height
= aRect
.bottom
-aRect
.top
;
643 int cx
= GetSystemMetrics( SM_CXSMICON
);
644 int cy
= GetSystemMetrics( SM_CYSMICON
);
646 HMODULE
hModule( GetModuleHandle( NULL
) );
648 if ( pMyItem
->module
.getLength() > 0 )
650 LPCWSTR pModuleName
= reinterpret_cast<LPCWSTR
>( pMyItem
->module
.getStr() );
651 hModule
= GetModuleHandleW( pModuleName
);
652 if ( hModule
== NULL
)
654 LoadLibraryW( pModuleName
);
655 hModule
= GetModuleHandleW( pModuleName
);
659 hIcon
= (HICON
) LoadImageA( hModule
, MAKEINTRESOURCE( pMyItem
->iconId
),
661 LR_DEFAULTCOLOR
| LR_SHARED
);
664 HBRUSH hbrIcon
= CreateSolidBrush( GetSysColor( COLOR_GRAYTEXT
) );
666 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
) );
668 DeleteObject( hbrIcon
);
670 x
+= cx
+ 4; // space for icon
673 NONCLIENTMETRICS ncm
;
674 memset(&ncm
, 0, sizeof(ncm
));
675 ncm
.cbSize
= sizeof(ncm
);
677 SystemParametersInfo(SPI_GETNONCLIENTMETRICS
, 0, (PVOID
) &ncm
, 0);
679 // Print default menu entry with bold font
680 if ( lpdis
->itemState
& ODS_DEFAULT
)
681 ncm
.lfMenuFont
.lfWeight
= FW_BOLD
;
683 hfntOld
= (HFONT
) SelectObject(lpdis
->hDC
, (HFONT
) CreateFontIndirect( &ncm
.lfMenuFont
));
687 GetTextExtentPointW( lpdis
->hDC
, reinterpret_cast<LPCWSTR
>(pMyItem
->text
.getStr()), pMyItem
->text
.getLength(), &size
);
689 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
) );
691 // Restore the original font and colors.
692 DeleteObject( SelectObject( lpdis
->hDC
, hbrOld
) );
693 DeleteObject( SelectObject( lpdis
->hDC
, hfntOld
) );
694 SetTextColor(lpdis
->hDC
, clrPrevText
);
695 SetBkColor(lpdis
->hDC
, clrPrevBkgnd
);
699 // code from setup2 project
702 void _SHFree( void *pv
)
705 if( NOERROR
== SHGetMalloc(&pMalloc
) )
712 #define ALLOC(type, n) ((type *) HeapAlloc(GetProcessHeap(), 0, sizeof(type) * n ))
713 #define FREE(p) HeapFree(GetProcessHeap(), 0, p)
715 static OUString
_SHGetSpecialFolder( int nFolderID
)
719 HRESULT hHdl
= SHGetSpecialFolderLocation( NULL
, nFolderID
, &pidl
);
722 if( hHdl
== NOERROR
)
725 lpFolderA
= ALLOC( WCHAR
, 16000 );
727 SHGetPathFromIDListW( pidl
, lpFolderA
);
728 aFolder
= OUString( reinterpret_cast<const sal_Unicode
*>(lpFolderA
) );
736 OUString
ShutdownIcon::GetAutostartFolderNameW32()
738 return _SHGetSpecialFolder(CSIDL_STARTUP
);
741 static HRESULT WINAPI
SHCoCreateInstance( LPVOID lpszReserved
, REFCLSID clsid
, LPUNKNOWN pUnkUnknown
, REFIID iid
, LPVOID
*ppv
)
743 HRESULT hResult
= E_NOTIMPL
;
744 HMODULE hModShell
= GetModuleHandle( "SHELL32" );
746 if ( hModShell
!= NULL
)
748 typedef HRESULT (WINAPI
*SHCoCreateInstance_PROC
)( LPVOID lpszReserved
, REFCLSID clsid
, LPUNKNOWN pUnkUnknwon
, REFIID iid
, LPVOID
*ppv
);
750 SHCoCreateInstance_PROC lpfnSHCoCreateInstance
= (SHCoCreateInstance_PROC
)GetProcAddress( hModShell
, MAKEINTRESOURCE(102) );
752 if ( lpfnSHCoCreateInstance
)
753 hResult
= lpfnSHCoCreateInstance( lpszReserved
, clsid
, pUnkUnknown
, iid
, ppv
);
758 BOOL
CreateShortcut( const OUString
& rAbsObject
, const OUString
& rAbsObjectPath
,
759 const OUString
& rAbsShortcut
, const OUString
& rDescription
, const OUString
& rParameter
)
763 CLSID clsid_ShellLink
= CLSID_ShellLink
;
764 CLSID clsid_IShellLink
= IID_IShellLink
;
766 hres
= CoCreateInstance( clsid_ShellLink
, NULL
, CLSCTX_INPROC_SERVER
,
767 clsid_IShellLink
, (void**)&psl
);
769 hres
= SHCoCreateInstance( NULL
, clsid_ShellLink
, NULL
, clsid_IShellLink
, (void**)&psl
);
771 if( SUCCEEDED(hres
) )
774 psl
->SetPath( OUStringToOString(rAbsObject
, osl_getThreadTextEncoding()).getStr() );
775 psl
->SetWorkingDirectory( OUStringToOString(rAbsObjectPath
, osl_getThreadTextEncoding()).getStr() );
776 psl
->SetDescription( OUStringToOString(rDescription
, osl_getThreadTextEncoding()).getStr() );
777 if( rParameter
.getLength() )
778 psl
->SetArguments( OUStringToOString(rParameter
, osl_getThreadTextEncoding()).getStr() );
780 CLSID clsid_IPersistFile
= IID_IPersistFile
;
781 hres
= psl
->QueryInterface( clsid_IPersistFile
, (void**)&ppf
);
783 if( SUCCEEDED(hres
) )
785 hres
= ppf
->Save( reinterpret_cast<LPCOLESTR
>(rAbsShortcut
.getStr()), TRUE
);
796 static bool FileExistsW( LPCWSTR lpPath
)
798 bool bExists
= false;
799 WIN32_FIND_DATAW aFindData
;
801 HANDLE hFind
= FindFirstFileW( lpPath
, &aFindData
);
803 if ( INVALID_HANDLE_VALUE
!= hFind
)
812 bool ShutdownIcon::IsQuickstarterInstalled()
814 wchar_t aPath
[_MAX_PATH
];
815 GetModuleFileNameW( NULL
, aPath
, _MAX_PATH
-1);
817 OUString
aOfficepath( reinterpret_cast<const sal_Unicode
*>(aPath
) );
818 int i
= aOfficepath
.lastIndexOf((sal_Char
) '\\');
820 aOfficepath
= aOfficepath
.copy(0, i
);
822 OUString
quickstartExe(aOfficepath
);
823 quickstartExe
+= "\\quickstart.exe";
825 return FileExistsW( reinterpret_cast<LPCWSTR
>(quickstartExe
.getStr()) );
828 void ShutdownIcon::EnableAutostartW32( const OUString
&aShortcut
)
830 wchar_t aPath
[_MAX_PATH
];
831 GetModuleFileNameW( NULL
, aPath
, _MAX_PATH
-1);
833 OUString
aOfficepath( reinterpret_cast<const sal_Unicode
*>(aPath
) );
834 int i
= aOfficepath
.lastIndexOf((sal_Char
) '\\');
836 aOfficepath
= aOfficepath
.copy(0, i
);
838 OUString
quickstartExe(aOfficepath
);
839 quickstartExe
+= "\\quickstart.exe";
841 CreateShortcut( quickstartExe
, aOfficepath
, aShortcut
, OUString(), OUString() );
847 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */