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>
20 #include <sal/log.hxx>
22 #include <unotools/moduleoptions.hxx>
23 #include <unotools/dynamicmenuoptions.hxx>
28 #include "shutdownicon.hxx"
29 #include <sfx2/sfxresid.hxx>
30 #include <sfx2/strings.hrc>
33 #include <osl/thread.h>
34 #include <systools/win32/qswin32.h>
35 #include <comphelper/sequenceashashmap.hxx>
36 #include <o3tl/char16_t2wchar_t.hxx>
40 using namespace ::osl
;
42 using ::com::sun::star::uno::Sequence
;
43 using ::com::sun::star::beans::PropertyValue
;
46 #define EXECUTER_WINDOWCLASS L"SO Executer Class"
47 #define EXECUTER_WINDOWNAME L"SO Executer Window"
50 #define ID_QUICKSTART 1
58 #define IDM_TEMPLATE 9
60 #define IDM_INSTALL 10
61 #define IDM_STARTCENTER 14
64 #define ICON_LO_DEFAULT 1
65 #define ICON_TEXT_DOCUMENT 2
66 #define ICON_SPREADSHEET_DOCUMENT 4
67 #define ICON_DRAWING_DOCUMENT 6
68 #define ICON_PRESENTATION_DOCUMENT 8
69 #define ICON_TEMPLATE 11
70 #define ICON_DATABASE_DOCUMENT 12
71 #define ICON_MATH_DOCUMENT 13
72 #define ICON_OPEN 5 // See index of open folder icon in shell32.dll
74 #define SFX_TASKBAR_NOTIFICATION WM_USER+1
76 static HWND aListenerWindow
= nullptr;
77 static HWND aExecuterWindow
= nullptr;
78 static HMENU popupMenu
= nullptr;
80 static void OnMeasureItem(HWND hwnd
, LPMEASUREITEMSTRUCT lpmis
);
81 static void OnDrawItem(HWND hwnd
, LPDRAWITEMSTRUCT lpdis
);
85 typedef struct tagMYITEM
94 static void addMenuItem( HMENU hMenu
, UINT id
, UINT iconId
, const OUString
& text
, int& pos
, bool bOwnerdraw
, const OUString
& module
)
96 MENUITEMINFOW mi
= {};
98 mi
.cbSize
= sizeof( mi
);
99 if( id
== static_cast<UINT
>( -1 ) )
102 mi
.fType
=MFT_SEPARATOR
;
108 mi
.fMask
=MIIM_TYPE
| MIIM_STATE
| MIIM_ID
| MIIM_DATA
;
109 mi
.fType
=MFT_OWNERDRAW
;
110 mi
.fState
=MFS_ENABLED
;
113 MYITEM
*pMyItem
= new MYITEM
;
114 pMyItem
->text
= text
;
115 pMyItem
->iconId
= iconId
;
116 pMyItem
->module
= module
;
117 mi
.dwItemData
= reinterpret_cast<DWORD_PTR
>(pMyItem
);
121 mi
.fMask
=MIIM_TYPE
| MIIM_STATE
| MIIM_ID
| MIIM_DATA
;
123 mi
.fState
=MFS_ENABLED
;
125 mi
.dwTypeData
= o3tl::toW(
126 const_cast<sal_Unicode
*>(text
.getStr()));
127 mi
.cch
= text
.getLength();
130 if ( IDM_TEMPLATE
== id
)
131 mi
.fState
|= MFS_DEFAULT
;
134 InsertMenuItemW( hMenu
, pos
++, TRUE
, &mi
);
138 static HMENU
createSystrayMenu( )
140 SvtModuleOptions aModuleOptions
;
142 HMENU hMenu
= CreatePopupMenu();
145 ShutdownIcon
*pShutdownIcon
= ShutdownIcon::getInstance();
146 OSL_ENSURE( pShutdownIcon
, "ShutdownIcon instance empty!");
151 // collect the URLs of the entries in the File/New menu
152 ::std::set
< OUString
> aFileNewAppsAvailable
;
153 SvtDynamicMenuOptions aOpt
;
154 Sequence
< Sequence
< PropertyValue
> > const aNewMenu
= aOpt
.GetMenu( EDynamicMenuType::NewMenu
);
155 const OUString
sURLKey( "URL" );
157 for ( auto const & newMenuProp
: aNewMenu
)
159 ::comphelper::SequenceAsHashMap
aEntryItems( newMenuProp
);
160 OUString
sURL( aEntryItems
.getUnpackedValueOrDefault( sURLKey
, OUString() ) );
161 if ( sURL
.getLength() )
162 aFileNewAppsAvailable
.insert( sURL
);
165 // describe the menu entries for launching the applications
166 struct MenuEntryDescriptor
168 SvtModuleOptions::EModule eModuleIdentifier
;
171 const char* pAsciiURLDescription
;
174 { SvtModuleOptions::EModule::WRITER
, IDM_WRITER
, ICON_TEXT_DOCUMENT
, WRITER_URL
},
175 { SvtModuleOptions::EModule::CALC
, IDM_CALC
, ICON_SPREADSHEET_DOCUMENT
, CALC_URL
},
176 { SvtModuleOptions::EModule::IMPRESS
, IDM_IMPRESS
,ICON_PRESENTATION_DOCUMENT
, IMPRESS_WIZARD_URL
},
177 { SvtModuleOptions::EModule::DRAW
, IDM_DRAW
, ICON_DRAWING_DOCUMENT
, DRAW_URL
},
178 { SvtModuleOptions::EModule::DATABASE
, IDM_BASE
, ICON_DATABASE_DOCUMENT
, BASE_URL
},
179 { SvtModuleOptions::EModule::MATH
, IDM_MATH
, ICON_MATH_DOCUMENT
, MATH_URL
},
182 // insert the menu entries for launching the applications
183 for ( size_t i
= 0; i
< SAL_N_ELEMENTS(aMenuItems
); ++i
)
185 if ( !aModuleOptions
.IsModuleInstalled( aMenuItems
[i
].eModuleIdentifier
) )
186 // the complete application is not even installed
189 OUString
sURL( OUString::createFromAscii( aMenuItems
[i
].pAsciiURLDescription
) );
191 if ( aFileNewAppsAvailable
.find( sURL
) == aFileNewAppsAvailable
.end() )
192 // the application is installed, but the entry has been configured to *not* appear in the File/New
193 // menu => also let not appear it in the quickstarter
196 addMenuItem( hMenu
, aMenuItems
[i
].nMenuItemID
, aMenuItems
[i
].nMenuIconID
,
197 ShutdownIcon::GetUrlDescription( sURL
), pos
, true, "" );
201 // insert the remaining menu entries
202 addMenuItem( hMenu
, IDM_TEMPLATE
, ICON_TEMPLATE
,
203 SfxResId( STR_QUICKSTART_FROMTEMPLATE
), pos
, true, "");
204 addMenuItem( hMenu
, static_cast< UINT
>( -1 ), 0, OUString(), pos
, false, "" );
205 addMenuItem( hMenu
, IDM_OPEN
, ICON_OPEN
, SfxResId(STR_QUICKSTART_FILEOPEN
), pos
, true, "SHELL32");
206 addMenuItem( hMenu
, static_cast< UINT
>( -1 ), 0, OUString(), pos
, false, "" );
207 addMenuItem( hMenu
, IDM_INSTALL
,0, SfxResId(STR_QUICKSTART_PRELAUNCH
), pos
, false, "" );
208 addMenuItem( hMenu
, static_cast< UINT
>( -1 ), 0, OUString(), pos
, false, "" );
209 addMenuItem( hMenu
, IDM_EXIT
, 0, SfxResId(STR_QUICKSTART_EXIT
), pos
, false, "" );
211 // indicate status of autostart folder
212 CheckMenuItem( hMenu
, IDM_INSTALL
, MF_BYCOMMAND
| (ShutdownIcon::GetAutostart() ? MF_CHECKED
: MF_UNCHECKED
) );
218 static void deleteSystrayMenu( HMENU hMenu
)
220 if( !hMenu
|| !IsMenu( hMenu
))
223 MENUITEMINFOW mi
= {};
225 mi
.cbSize
= sizeof( mi
);
226 mi
.fMask
= MIIM_DATA
;
228 while( GetMenuItemInfoW( hMenu
, pos
++, true, &mi
) )
230 MYITEM
*pMyItem
= reinterpret_cast<MYITEM
*>(mi
.dwItemData
);
233 pMyItem
->text
.clear();
236 mi
.fMask
= MIIM_DATA
;
241 static void addTaskbarIcon( HWND hWnd
)
243 OUString strTip
= SfxResId(STR_QUICKSTART_TIP
);
247 nid
.hIcon
= static_cast<HICON
>(LoadImageW( GetModuleHandleW( nullptr ), MAKEINTRESOURCEW( ICON_LO_DEFAULT
),
248 IMAGE_ICON
, GetSystemMetrics( SM_CXSMICON
), GetSystemMetrics( SM_CYSMICON
),
249 LR_DEFAULTCOLOR
| LR_SHARED
));
251 wcsncpy( nid
.szTip
, o3tl::toW(strTip
.getStr()), 64 );
253 nid
.cbSize
= sizeof(nid
);
255 nid
.uID
= ID_QUICKSTART
;
256 nid
.uCallbackMessage
= SFX_TASKBAR_NOTIFICATION
;
257 nid
.uFlags
= NIF_MESSAGE
|NIF_TIP
|NIF_ICON
;
259 Shell_NotifyIconW(NIM_ADD
, &nid
);
263 static LRESULT CALLBACK
listenerWndProc( HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
265 static UINT s_uTaskbarRestart
= 0;
266 static UINT s_uMsgKillTray
= 0;
274 // request notification when taskbar is recreated
275 // we then have to add our icon again
276 s_uTaskbarRestart
= RegisterWindowMessageW(L
"TaskbarCreated");
277 s_uMsgKillTray
= RegisterWindowMessageW( SHUTDOWN_QUICKSTART_MESSAGE
);
281 if( (popupMenu
= createSystrayMenu( )) == nullptr )
285 addTaskbarIcon( hWnd
);
288 ShutdownIcon::getInstance()->SetVeto( true );
289 ShutdownIcon::addTerminateListener();
294 OnMeasureItem(hWnd
, reinterpret_cast<LPMEASUREITEMSTRUCT
>(lParam
));
298 OnDrawItem(hWnd
, reinterpret_cast<LPDRAWITEMSTRUCT
>(lParam
));
301 case SFX_TASKBAR_NOTIFICATION
:
306 bool const ret
= PostMessageW(aExecuterWindow
, WM_COMMAND
, IDM_STARTCENTER
, reinterpret_cast<LPARAM
>(hWnd
));
307 SAL_WARN_IF(!ret
, "sfx.appl", "ERROR: PostMessage() failed!");
315 SetForegroundWindow( hWnd
);
317 // update status before showing menu, could have been changed from option page
318 CheckMenuItem( popupMenu
, IDM_INSTALL
, MF_BYCOMMAND
| (ShutdownIcon::GetAutostart() ? MF_CHECKED
: MF_UNCHECKED
) );
320 EnableMenuItem( popupMenu
, IDM_EXIT
, MF_BYCOMMAND
| (ShutdownIcon::bModalMode
? MF_GRAYED
: MF_ENABLED
) );
321 EnableMenuItem( popupMenu
, IDM_OPEN
, MF_BYCOMMAND
| (ShutdownIcon::bModalMode
? MF_GRAYED
: MF_ENABLED
) );
322 EnableMenuItem( popupMenu
, IDM_TEMPLATE
, MF_BYCOMMAND
| (ShutdownIcon::bModalMode
? MF_GRAYED
: MF_ENABLED
) );
323 int m
= TrackPopupMenuEx( popupMenu
, TPM_RETURNCMD
|TPM_LEFTALIGN
|TPM_RIGHTBUTTON
,
324 pt
.x
, pt
.y
, hWnd
, nullptr );
325 bool const ret
= PostMessageW( hWnd
, 0, 0, 0 );
326 SAL_WARN_IF(!ret
, "sfx.appl", "ERROR: PostMessage() failed!");
339 CheckMenuItem( popupMenu
, IDM_INSTALL
, MF_BYCOMMAND
| (ShutdownIcon::GetAutostart() ? MF_CHECKED
: MF_UNCHECKED
) );
342 // delete taskbar icon
344 nid
.cbSize
=sizeof(nid
);
346 nid
.uID
= ID_QUICKSTART
;
347 Shell_NotifyIconW(NIM_DELETE
, &nid
);
351 bool const ret2
= PostMessageW(aExecuterWindow
, WM_COMMAND
, m
, reinterpret_cast<LPARAM
>(hWnd
));
352 SAL_WARN_IF(!ret2
, "sfx.appl", "ERROR: PostMessage() failed!");
358 deleteSystrayMenu( popupMenu
);
359 // We don't need the Systray Thread anymore
360 PostQuitMessage( 0 );
361 return DefWindowProcW(hWnd
, uMsg
, wParam
, lParam
);
363 if( uMsg
== s_uTaskbarRestart
)
365 // re-create taskbar icon
366 addTaskbarIcon( hWnd
);
368 else if ( uMsg
== s_uMsgKillTray
)
370 // delete taskbar icon
372 nid
.cbSize
=sizeof(nid
);
374 nid
.uID
= ID_QUICKSTART
;
375 Shell_NotifyIconW(NIM_DELETE
, &nid
);
377 bool const ret
= PostMessageW(aExecuterWindow
, WM_COMMAND
, IDM_EXIT
, reinterpret_cast<LPARAM
>(hWnd
));
378 SAL_WARN_IF(!ret
, "sfx.appl", "ERROR: PostMessage() failed!");
381 return DefWindowProcW(hWnd
, uMsg
, wParam
, lParam
);
387 static LRESULT CALLBACK
executerWndProc( HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
397 switch( LOWORD(wParam
) )
400 if ( !ShutdownIcon::bModalMode
)
401 ShutdownIcon::FileOpen();
404 ShutdownIcon::OpenURL( WRITER_URL
, "_default" );
407 ShutdownIcon::OpenURL( CALC_URL
, "_default" );
410 ShutdownIcon::OpenURL( IMPRESS_WIZARD_URL
, "_default" );
413 ShutdownIcon::OpenURL( DRAW_URL
, "_default" );
416 ShutdownIcon::OpenURL( BASE_URL
, "_default" );
419 ShutdownIcon::OpenURL( MATH_URL
, "_default" );
421 case IDM_STARTCENTER
:
422 ShutdownIcon::OpenURL( STARTMODULE_URL
, "_default" );
425 if ( !ShutdownIcon::bModalMode
)
426 ShutdownIcon::FromTemplate();
429 ShutdownIcon::SetAutostart( !ShutdownIcon::GetAutostart() );
432 // remove listener and
433 // terminate office if running in background
434 if ( !ShutdownIcon::bModalMode
)
435 ShutdownIcon::terminateDesktop();
441 return DefWindowProcW(hWnd
, uMsg
, wParam
, lParam
);
447 static DWORD WINAPI
SystrayThread( LPVOID
/*lpParam*/ )
449 osl_setThreadName("SystrayThread");
451 aListenerWindow
= CreateWindowExW(0,
452 QUICKSTART_CLASSNAME
, // registered class name
453 QUICKSTART_WINDOWNAME
, // window name
455 CW_USEDEFAULT
, // horizontal position of window
456 CW_USEDEFAULT
, // vertical position of window
457 CW_USEDEFAULT
, // window width
458 CW_USEDEFAULT
, // window height
459 nullptr, // handle to parent or owner window
460 nullptr, // menu handle or child identifier
461 GetModuleHandleW( nullptr ), // handle to application instance
462 nullptr // window-creation data
467 while ( GetMessageW( &msg
, nullptr, 0, 0 ) )
469 TranslateMessage( &msg
);
470 DispatchMessageW( &msg
);
473 return msg
.wParam
; // Exit code of WM_QUIT
477 void win32_init_sys_tray()
479 if ( ShutdownIcon::IsQuickstarterInstalled() )
481 WNDCLASSEXW listenerClass
;
482 listenerClass
.cbSize
= sizeof(listenerClass
);
483 listenerClass
.style
= 0;
484 listenerClass
.lpfnWndProc
= listenerWndProc
;
485 listenerClass
.cbClsExtra
= 0;
486 listenerClass
.cbWndExtra
= 0;
487 listenerClass
.hInstance
= GetModuleHandleW( nullptr );
488 listenerClass
.hIcon
= nullptr;
489 listenerClass
.hCursor
= nullptr;
490 listenerClass
.hbrBackground
= nullptr;
491 listenerClass
.lpszMenuName
= nullptr;
492 listenerClass
.lpszClassName
= QUICKSTART_CLASSNAME
;
493 listenerClass
.hIconSm
= nullptr;
495 RegisterClassExW(&listenerClass
);
497 WNDCLASSEXW executerClass
;
498 executerClass
.cbSize
= sizeof(executerClass
);
499 executerClass
.style
= 0;
500 executerClass
.lpfnWndProc
= executerWndProc
;
501 executerClass
.cbClsExtra
= 0;
502 executerClass
.cbWndExtra
= 0;
503 executerClass
.hInstance
= GetModuleHandleW( nullptr );
504 executerClass
.hIcon
= nullptr;
505 executerClass
.hCursor
= nullptr;
506 executerClass
.hbrBackground
= nullptr;
507 executerClass
.lpszMenuName
= nullptr;
508 executerClass
.lpszClassName
= EXECUTER_WINDOWCLASS
;
509 executerClass
.hIconSm
= nullptr;
511 RegisterClassExW( &executerClass
);
513 aExecuterWindow
= CreateWindowExW(0,
514 EXECUTER_WINDOWCLASS
, // registered class name
515 EXECUTER_WINDOWNAME
, // window name
517 CW_USEDEFAULT
, // horizontal position of window
518 CW_USEDEFAULT
, // vertical position of window
519 CW_USEDEFAULT
, // window width
520 CW_USEDEFAULT
, // window height
521 nullptr, // handle to parent or owner window
522 nullptr, // menu handle or child identifier
523 GetModuleHandleW( nullptr ), // handle to application instance
524 nullptr // window-creation data
528 CloseHandle(CreateThread(nullptr, 0, SystrayThread
, nullptr, 0, &dwThreadId
));
533 void win32_shutdown_sys_tray()
535 if ( ShutdownIcon::IsQuickstarterInstalled() )
537 if( IsWindow( aListenerWindow
) )
539 DestroyWindow( aListenerWindow
);
540 aListenerWindow
= nullptr;
541 DestroyWindow( aExecuterWindow
);
542 aExecuterWindow
= nullptr;
544 UnregisterClassW( QUICKSTART_CLASSNAME
, GetModuleHandleW( nullptr ) );
545 UnregisterClassW( EXECUTER_WINDOWCLASS
, GetModuleHandleW( nullptr ) );
550 void OnMeasureItem(HWND hwnd
, LPMEASUREITEMSTRUCT lpmis
)
552 MYITEM
*pMyItem
= reinterpret_cast<MYITEM
*>(lpmis
->itemData
);
553 HDC hdc
= GetDC(hwnd
);
556 NONCLIENTMETRICSW ncm
= {};
557 ncm
.cbSize
= sizeof(ncm
);
559 SystemParametersInfoW(SPI_GETNONCLIENTMETRICS
, 0, &ncm
, 0);
561 // Assume every menu item can be default and printed bold
562 ncm
.lfMenuFont
.lfWeight
= FW_BOLD
;
564 HFONT hfntOld
= static_cast<HFONT
>(SelectObject(hdc
, CreateFontIndirectW( &ncm
.lfMenuFont
)));
566 GetTextExtentPoint32W(hdc
, o3tl::toW(pMyItem
->text
.getStr()),
567 pMyItem
->text
.getLength(), &size
);
569 lpmis
->itemWidth
= size
.cx
+ 4 + GetSystemMetrics( SM_CXSMICON
);
570 lpmis
->itemHeight
= std::max
<int>(size
.cy
, GetSystemMetrics( SM_CYSMICON
));
571 lpmis
->itemHeight
+= 4;
573 DeleteObject( SelectObject(hdc
, hfntOld
) );
574 ReleaseDC(hwnd
, hdc
);
577 void OnDrawItem(HWND
/*hwnd*/, LPDRAWITEMSTRUCT lpdis
)
579 MYITEM
*pMyItem
= reinterpret_cast<MYITEM
*>(lpdis
->itemData
);
580 COLORREF clrPrevText
, clrPrevBkgnd
;
584 bool fSelected
= lpdis
->itemState
& ODS_SELECTED
;
585 bool fDisabled
= lpdis
->itemState
& (ODS_DISABLED
| ODS_GRAYED
);
587 // Set the appropriate foreground and background colors.
589 RECT aRect
= lpdis
->rcItem
;
591 clrPrevBkgnd
= SetBkColor( lpdis
->hDC
, GetSysColor(COLOR_MENU
) );
594 clrPrevText
= SetTextColor( lpdis
->hDC
, GetSysColor( COLOR_GRAYTEXT
) );
596 clrPrevText
= SetTextColor( lpdis
->hDC
, GetSysColor( fSelected
? COLOR_HIGHLIGHTTEXT
: COLOR_MENUTEXT
) );
599 clrPrevBkgnd
= SetBkColor( lpdis
->hDC
, GetSysColor(COLOR_HIGHLIGHT
) );
601 clrPrevBkgnd
= SetBkColor( lpdis
->hDC
, GetSysColor(COLOR_MENU
) );
603 hbrOld
= static_cast<HBRUSH
>(SelectObject( lpdis
->hDC
, CreateSolidBrush( GetBkColor( lpdis
->hDC
) ) ));
606 PatBlt(lpdis
->hDC
, aRect
.left
, aRect
.top
, aRect
.right
-aRect
.left
, aRect
.bottom
-aRect
.top
, PATCOPY
);
608 int height
= aRect
.bottom
-aRect
.top
;
613 int cx
= GetSystemMetrics( SM_CXSMICON
);
614 int cy
= GetSystemMetrics( SM_CYSMICON
);
615 HICON
hIcon( nullptr );
616 HMODULE
hModule( GetModuleHandleW( nullptr ) );
618 if ( pMyItem
->module
.getLength() > 0 )
620 LPCWSTR pModuleName
= o3tl::toW( pMyItem
->module
.getStr() );
621 hModule
= GetModuleHandleW( pModuleName
);
622 if ( hModule
== nullptr )
624 hModule
= LoadLibraryW(pModuleName
);
628 hIcon
= static_cast<HICON
>(LoadImageW( hModule
, MAKEINTRESOURCEW( pMyItem
->iconId
),
630 LR_DEFAULTCOLOR
| LR_SHARED
));
633 HBRUSH hbrIcon
= CreateSolidBrush( GetSysColor( COLOR_GRAYTEXT
) );
635 DrawStateW( lpdis
->hDC
, hbrIcon
, nullptr, reinterpret_cast<LPARAM
>(hIcon
), WPARAM(0), x
, y
+(height
-cy
)/2, 0, 0, DST_ICON
| (fDisabled
? (fSelected
? DSS_MONO
: DSS_DISABLED
) : DSS_NORMAL
) );
637 DeleteObject( hbrIcon
);
639 x
+= cx
+ 4; // space for icon
642 NONCLIENTMETRICSW ncm
= {};
643 ncm
.cbSize
= sizeof(ncm
);
645 SystemParametersInfoW(SPI_GETNONCLIENTMETRICS
, 0, &ncm
, 0);
647 // Print default menu entry with bold font
648 if ( lpdis
->itemState
& ODS_DEFAULT
)
649 ncm
.lfMenuFont
.lfWeight
= FW_BOLD
;
651 hfntOld
= static_cast<HFONT
>(SelectObject(lpdis
->hDC
, CreateFontIndirectW( &ncm
.lfMenuFont
)));
655 GetTextExtentPointW( lpdis
->hDC
, o3tl::toW(pMyItem
->text
.getStr()), pMyItem
->text
.getLength(), &size
);
657 DrawStateW( lpdis
->hDC
, nullptr, nullptr, reinterpret_cast<LPARAM
>(pMyItem
->text
.getStr()), WPARAM(0), aRect
.left
, aRect
.top
+ (height
- size
.cy
)/2, 0, 0, DST_TEXT
| (fDisabled
&& !fSelected
? DSS_DISABLED
: DSS_NORMAL
) );
659 // Restore the original font and colors.
660 DeleteObject( SelectObject( lpdis
->hDC
, hbrOld
) );
661 DeleteObject( SelectObject( lpdis
->hDC
, hfntOld
) );
662 SetTextColor(lpdis
->hDC
, clrPrevText
);
663 SetBkColor(lpdis
->hDC
, clrPrevBkgnd
);
667 // code from setup2 project
670 static void SHFree_( void *pv
)
673 if( NOERROR
== SHGetMalloc(&pMalloc
) )
680 #define ALLOC(type, n) static_cast<type *>(HeapAlloc(GetProcessHeap(), 0, sizeof(type) * n ))
681 #define FREE(p) HeapFree(GetProcessHeap(), 0, p)
683 static OUString
SHGetSpecialFolder( int nFolderID
)
687 HRESULT hHdl
= SHGetSpecialFolderLocation( nullptr, nFolderID
, &pidl
);
690 if( hHdl
== NOERROR
)
693 lpFolderA
= ALLOC( WCHAR
, 16000 );
695 SHGetPathFromIDListW( pidl
, lpFolderA
);
696 aFolder
= o3tl::toU( lpFolderA
);
704 OUString
ShutdownIcon::GetAutostartFolderNameW32()
706 return SHGetSpecialFolder(CSIDL_STARTUP
);
709 static HRESULT WINAPI
SHCoCreateInstance( LPVOID lpszReserved
, REFCLSID clsid
, LPUNKNOWN pUnkUnknown
, REFIID iid
, LPVOID
*ppv
)
711 HRESULT hResult
= E_NOTIMPL
;
712 HMODULE hModShell
= GetModuleHandleW( L
"SHELL32" );
714 if ( hModShell
!= nullptr )
716 typedef HRESULT (WINAPI
*SHCoCreateInstance_PROC
)( LPVOID lpszReserved
, REFCLSID clsid
, LPUNKNOWN pUnkUnknown
, REFIID iid
, LPVOID
*ppv
);
718 SHCoCreateInstance_PROC lpfnSHCoCreateInstance
= reinterpret_cast<SHCoCreateInstance_PROC
>(GetProcAddress( hModShell
, MAKEINTRESOURCEA(102) ));
720 if ( lpfnSHCoCreateInstance
)
721 hResult
= lpfnSHCoCreateInstance( lpszReserved
, clsid
, pUnkUnknown
, iid
, ppv
);
726 static bool CreateShortcut( const OUString
& rAbsObject
, const OUString
& rAbsObjectPath
,
727 const OUString
& rAbsShortcut
, const OUString
& rDescription
, const OUString
& rParameter
)
731 CLSID clsid_ShellLink
= CLSID_ShellLink
;
732 CLSID clsid_IShellLink
= IID_IShellLinkW
;
734 hres
= CoCreateInstance( clsid_ShellLink
, nullptr, CLSCTX_INPROC_SERVER
,
735 clsid_IShellLink
, reinterpret_cast<void**>(&psl
) );
737 hres
= SHCoCreateInstance( nullptr, clsid_ShellLink
, nullptr, clsid_IShellLink
, reinterpret_cast<void**>(&psl
) );
739 if( SUCCEEDED(hres
) )
742 psl
->SetPath( o3tl::toW(rAbsObject
.getStr()) );
743 psl
->SetWorkingDirectory( o3tl::toW(rAbsObjectPath
.getStr()) );
744 psl
->SetDescription( o3tl::toW(rDescription
.getStr()) );
745 if( rParameter
.getLength() )
746 psl
->SetArguments( o3tl::toW(rParameter
.getStr()) );
748 CLSID clsid_IPersistFile
= IID_IPersistFile
;
749 hres
= psl
->QueryInterface( clsid_IPersistFile
, reinterpret_cast<void**>(&ppf
) );
751 if( SUCCEEDED(hres
) )
753 hres
= ppf
->Save( o3tl::toW(rAbsShortcut
.getStr()), TRUE
);
764 static bool FileExistsW( LPCWSTR lpPath
)
766 bool bExists
= false;
767 WIN32_FIND_DATAW aFindData
;
769 HANDLE hFind
= FindFirstFileW( lpPath
, &aFindData
);
771 if ( INVALID_HANDLE_VALUE
!= hFind
)
780 bool ShutdownIcon::IsQuickstarterInstalled()
782 wchar_t aPath
[_MAX_PATH
];
783 GetModuleFileNameW( nullptr, aPath
, _MAX_PATH
-1);
785 OUString
aOfficepath( o3tl::toU(aPath
) );
786 int i
= aOfficepath
.lastIndexOf('\\');
788 aOfficepath
= aOfficepath
.copy(0, i
);
790 OUString
quickstartExe(aOfficepath
+ "\\quickstart.exe");
792 return FileExistsW( o3tl::toW(quickstartExe
.getStr()) );
795 void ShutdownIcon::EnableAutostartW32( const OUString
&aShortcut
)
797 wchar_t aPath
[_MAX_PATH
];
798 GetModuleFileNameW( nullptr, aPath
, _MAX_PATH
-1);
800 OUString
aOfficepath( o3tl::toU(aPath
) );
801 int i
= aOfficepath
.lastIndexOf('\\');
803 aOfficepath
= aOfficepath
.copy(0, i
);
805 OUString
quickstartExe(aOfficepath
+ "\\quickstart.exe");
807 CreateShortcut( quickstartExe
, aOfficepath
, aShortcut
, OUString(), OUString() );
811 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */