LibreOffice Module sfx2 (master) 1
shutdowniconw32.cxx
Go to the documentation of this file.
1/*
2 * This file is part of the LibreOffice project.
3 *
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/.
7 *
8 * This file incorporates work covered by the following license notice:
9 *
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 .
17 */
18
19#include <sal/macros.h>
20#include <sal/log.hxx>
21
24
25#undef WB_LEFT
26#undef WB_RIGHT
27
28#include "shutdownicon.hxx"
29#include <sfx2/sfxresid.hxx>
30#include <sfx2/strings.hrc>
31#include <shlobj.h>
32#include <objidl.h>
33#include <osl/diagnose.h>
34#include <osl/thread.h>
35#include <systools/win32/qswin32.h>
39
40#include <set>
41
42
43#define EXECUTER_WINDOWCLASS L"SO Executer Class"
44#define EXECUTER_WINDOWNAME L"SO Executer Window"
45
46
47#define ID_QUICKSTART 1
48#define IDM_EXIT 2
49#define IDM_OPEN 3
50#define IDM_WRITER 4
51#define IDM_CALC 5
52#define IDM_IMPRESS 6
53#define IDM_DRAW 7
54#define IDM_BASE 8
55#define IDM_TEMPLATE 9
56#define IDM_MATH 12
57#define IDM_INSTALL 10
58#define IDM_STARTCENTER 14
59
60
61#define ICON_LO_DEFAULT 1
62#define ICON_TEXT_DOCUMENT 2
63#define ICON_SPREADSHEET_DOCUMENT 4
64#define ICON_DRAWING_DOCUMENT 6
65#define ICON_PRESENTATION_DOCUMENT 8
66#define ICON_TEMPLATE 11
67#define ICON_DATABASE_DOCUMENT 12
68#define ICON_MATH_DOCUMENT 13
69#define ICON_OPEN 5 // See index of open folder icon in shell32.dll
70
71#define SFX_TASKBAR_NOTIFICATION WM_USER+1
72
73static HWND aListenerWindow = nullptr;
74static HWND aExecuterWindow = nullptr;
75static HMENU popupMenu = nullptr;
76
77static void OnMeasureItem(HWND hwnd, LPMEASUREITEMSTRUCT lpmis);
78static void OnDrawItem(HWND hwnd, LPDRAWITEMSTRUCT lpdis);
79
80namespace {
81
82struct MYITEM
83{
84 OUString text;
85 OUString module;
86 UINT iconId;
87};
88
89}
90
91static void addMenuItem( HMENU hMenu, UINT id, UINT iconId, const OUString& text, int& pos, bool bOwnerdraw, const OUString& module )
92{
93 MENUITEMINFOW mi = {};
94
95 mi.cbSize = sizeof( mi );
96 if( id == static_cast<UINT>( -1 ) )
97 {
98 mi.fMask=MIIM_FTYPE;
99 mi.fType=MFT_SEPARATOR;
100 }
101 else
102 {
103 if( bOwnerdraw )
104 {
105 mi.fMask=MIIM_FTYPE | MIIM_STATE | MIIM_ID | MIIM_DATA;
106 mi.fType=MFT_OWNERDRAW;
107
108 MYITEM *pMyItem = new MYITEM;
109 pMyItem->text = text;
110 pMyItem->iconId = iconId;
111 pMyItem->module = module;
112 mi.dwItemData = reinterpret_cast<ULONG_PTR>(pMyItem);
113 }
114 else
115 {
116 mi.fMask=MIIM_STRING | MIIM_STATE | MIIM_ID;
117 mi.dwTypeData = o3tl::toW(
118 const_cast<sal_Unicode *>(text.getStr()));
119 mi.cch = text.getLength();
120 }
121
122 mi.fState = MFS_ENABLED;
123 mi.wID = id;
124 if ( IDM_TEMPLATE == id )
125 mi.fState |= MFS_DEFAULT;
126 }
127
128 InsertMenuItemW( hMenu, pos++, TRUE, &mi );
129}
130
131
132static HMENU createSystrayMenu( )
133{
134 SvtModuleOptions aModuleOptions;
135
136 HMENU hMenu = CreatePopupMenu();
137 int pos=0;
138
139 ShutdownIcon *pShutdownIcon = ShutdownIcon::getInstance();
140 OSL_ENSURE( pShutdownIcon, "ShutdownIcon instance empty!");
141
142 if( !pShutdownIcon )
143 return nullptr;
144
145 // collect the URLs of the entries in the File/New menu
146 ::std::set< OUString > aFileNewAppsAvailable;
147 std::vector< SvtDynMenuEntry > const aNewMenu = SvtDynamicMenuOptions::GetMenu( EDynamicMenuType::NewMenu );
148 for ( SvtDynMenuEntry const & newMenuProp : aNewMenu )
149 {
150 if ( !newMenuProp.sURL.isEmpty() )
151 aFileNewAppsAvailable.insert( newMenuProp.sURL );
152 }
153
154 // describe the menu entries for launching the applications
155 struct MenuEntryDescriptor
156 {
157 SvtModuleOptions::EModule eModuleIdentifier;
158 UINT nMenuItemID;
159 UINT nMenuIconID;
160 rtl::OUStringConstExpr sURLDescription;
161 } static const aMenuItems[] =
162 {
169 };
170
171 // insert the menu entries for launching the applications
172 for (const auto& [eModuleIdentifier, nMenuItemID, nMenuIconID, sURL] : aMenuItems)
173 {
174 if ( !aModuleOptions.IsModuleInstalled( eModuleIdentifier ) )
175 // the complete application is not even installed
176 continue;
177
178 if ( aFileNewAppsAvailable.find( sURL ) == aFileNewAppsAvailable.end() )
179 // the application is installed, but the entry has been configured to *not* appear in the File/New
180 // menu => also let not appear it in the quickstarter
181 continue;
182
183 addMenuItem( hMenu, nMenuItemID, nMenuIconID,
184 ShutdownIcon::GetUrlDescription( sURL.asView() ), pos, true, "" );
185 }
186
187
188 // insert the remaining menu entries
190 SfxResId( STR_QUICKSTART_FROMTEMPLATE ), pos, true, "");
191 addMenuItem( hMenu, static_cast< UINT >( -1 ), 0, OUString(), pos, false, "" );
192 addMenuItem( hMenu, IDM_OPEN, ICON_OPEN, SfxResId(STR_QUICKSTART_FILEOPEN), pos, true, "SHELL32");
193 addMenuItem( hMenu, static_cast< UINT >( -1 ), 0, OUString(), pos, false, "" );
194 addMenuItem( hMenu, IDM_INSTALL,0, SfxResId(STR_QUICKSTART_PRELAUNCH), pos, false, "" );
195 addMenuItem( hMenu, static_cast< UINT >( -1 ), 0, OUString(), pos, false, "" );
196 addMenuItem( hMenu, IDM_EXIT, 0, SfxResId(STR_QUICKSTART_EXIT), pos, false, "" );
197
198 // indicate status of autostart folder
199 CheckMenuItem( hMenu, IDM_INSTALL, MF_BYCOMMAND | (ShutdownIcon::GetAutostart() ? MF_CHECKED : MF_UNCHECKED) );
200
201 return hMenu;
202}
203
204
205static void deleteSystrayMenu( HMENU hMenu )
206{
207 if( !hMenu || !IsMenu( hMenu ))
208 return;
209
210 MENUITEMINFOW mi = {};
211 mi.cbSize = sizeof( mi );
212 mi.fMask = MIIM_DATA;
213
214 for (UINT pos = 0; GetMenuItemInfoW(hMenu, pos, true, &mi); ++pos)
215 {
216 if (MYITEM* pMyItem = reinterpret_cast<MYITEM*>(mi.dwItemData))
217 delete pMyItem;
218 mi.fMask = MIIM_DATA;
219 }
220}
221
222
223static void addTaskbarIcon( HWND hWnd )
224{
225 OUString strTip = SfxResId(STR_QUICKSTART_TIP);
226
227 // add taskbar icon
228 NOTIFYICONDATAW nid;
229 nid.hIcon = static_cast<HICON>(LoadImageW( GetModuleHandleW( nullptr ), MAKEINTRESOURCEW( ICON_LO_DEFAULT ),
230 IMAGE_ICON, GetSystemMetrics( SM_CXSMICON ), GetSystemMetrics( SM_CYSMICON ),
231 LR_DEFAULTCOLOR | LR_SHARED ));
232
233 wcsncpy( nid.szTip, o3tl::toW(strTip.getStr()), 64 );
234
235 nid.cbSize = sizeof(nid);
236 nid.hWnd = hWnd;
237 nid.uID = ID_QUICKSTART;
238 nid.uCallbackMessage = SFX_TASKBAR_NOTIFICATION;
239 nid.uFlags = NIF_MESSAGE|NIF_TIP|NIF_ICON;
240
241 Shell_NotifyIconW(NIM_ADD, &nid);
242}
243
244
245static LRESULT CALLBACK listenerWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
246{
247 static UINT s_uTaskbarRestart = 0;
248 static UINT s_uMsgKillTray = 0;
249
250 switch (uMsg)
251 {
252 case WM_NCCREATE:
253 return TRUE;
254 case WM_CREATE:
255 {
256 // request notification when taskbar is recreated
257 // we then have to add our icon again
258 s_uTaskbarRestart = RegisterWindowMessageW(L"TaskbarCreated");
259 s_uMsgKillTray = RegisterWindowMessageW( SHUTDOWN_QUICKSTART_MESSAGE );
260
261 // create the menu
262 if( !popupMenu )
263 if( (popupMenu = createSystrayMenu( )) == nullptr )
264 return -1;
265
266 // and the icon
267 addTaskbarIcon( hWnd );
268
269 // disable shutdown
272 }
273 return 0;
274
275 case WM_MEASUREITEM:
276 OnMeasureItem(hWnd, reinterpret_cast<LPMEASUREITEMSTRUCT>(lParam));
277 return TRUE;
278
279 case WM_DRAWITEM:
280 OnDrawItem(hWnd, reinterpret_cast<LPDRAWITEMSTRUCT>(lParam));
281 return TRUE;
282
284 switch( lParam )
285 {
286 case WM_LBUTTONDOWN:
287 {
288 bool const ret = PostMessageW(aExecuterWindow, WM_COMMAND, IDM_STARTCENTER, reinterpret_cast<LPARAM>(hWnd));
289 SAL_WARN_IF(!ret, "sfx.appl", "ERROR: PostMessage() failed!");
290 break;
291 }
292
293 case WM_RBUTTONDOWN:
294 {
295 POINT pt;
296 GetCursorPos(&pt);
297 SetForegroundWindow( hWnd );
298
299 // update status before showing menu, could have been changed from option page
300 CheckMenuItem( popupMenu, IDM_INSTALL, MF_BYCOMMAND| (ShutdownIcon::GetAutostart() ? MF_CHECKED : MF_UNCHECKED) );
301
302 EnableMenuItem( popupMenu, IDM_EXIT, MF_BYCOMMAND | (ShutdownIcon::bModalMode ? MF_GRAYED : MF_ENABLED) );
303 EnableMenuItem( popupMenu, IDM_OPEN, MF_BYCOMMAND | (ShutdownIcon::bModalMode ? MF_GRAYED : MF_ENABLED) );
304 EnableMenuItem( popupMenu, IDM_TEMPLATE, MF_BYCOMMAND | (ShutdownIcon::bModalMode ? MF_GRAYED : MF_ENABLED) );
305 int m = TrackPopupMenuEx( popupMenu, TPM_RETURNCMD|TPM_LEFTALIGN|TPM_RIGHTBUTTON,
306 pt.x, pt.y, hWnd, nullptr );
307 bool const ret = PostMessageW( hWnd, 0, 0, 0 );
308 SAL_WARN_IF(!ret, "sfx.appl", "ERROR: PostMessage() failed!");
309 switch( m )
310 {
311 case IDM_OPEN:
312 case IDM_WRITER:
313 case IDM_CALC:
314 case IDM_IMPRESS:
315 case IDM_DRAW:
316 case IDM_TEMPLATE:
317 case IDM_BASE:
318 case IDM_MATH:
319 break;
320 case IDM_INSTALL:
321 CheckMenuItem( popupMenu, IDM_INSTALL, MF_BYCOMMAND| (ShutdownIcon::GetAutostart() ? MF_CHECKED : MF_UNCHECKED) );
322 break;
323 case IDM_EXIT:
324 // delete taskbar icon
325 NOTIFYICONDATAW nid;
326 nid.cbSize=sizeof(nid);
327 nid.hWnd = hWnd;
328 nid.uID = ID_QUICKSTART;
329 Shell_NotifyIconW(NIM_DELETE, &nid);
330 break;
331 }
332
333 bool const ret2 = PostMessageW(aExecuterWindow, WM_COMMAND, m, reinterpret_cast<LPARAM>(hWnd));
334 SAL_WARN_IF(!ret2, "sfx.appl", "ERROR: PostMessage() failed!");
335 }
336 break;
337 }
338 break;
339 case WM_DESTROY:
341 // We don't need the Systray Thread anymore
342 PostQuitMessage( 0 );
343 return DefWindowProcW(hWnd, uMsg, wParam, lParam);
344 default:
345 if( uMsg == s_uTaskbarRestart )
346 {
347 // re-create taskbar icon
348 addTaskbarIcon( hWnd );
349 }
350 else if ( uMsg == s_uMsgKillTray )
351 {
352 // delete taskbar icon
353 NOTIFYICONDATAW nid;
354 nid.cbSize=sizeof(nid);
355 nid.hWnd = hWnd;
356 nid.uID = ID_QUICKSTART;
357 Shell_NotifyIconW(NIM_DELETE, &nid);
358
359 bool const ret = PostMessageW(aExecuterWindow, WM_COMMAND, IDM_EXIT, reinterpret_cast<LPARAM>(hWnd));
360 SAL_WARN_IF(!ret, "sfx.appl", "ERROR: PostMessage() failed!");
361 }
362 else
363 return DefWindowProcW(hWnd, uMsg, wParam, lParam);
364 }
365 return 0;
366}
367
368
369static LRESULT CALLBACK executerWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
370{
371 switch (uMsg)
372 {
373 case WM_NCCREATE:
374 return TRUE;
375 case WM_CREATE:
376 return 0;
377
378 case WM_COMMAND:
379 switch( LOWORD(wParam) )
380 {
381 case IDM_OPEN:
384 break;
385 case IDM_WRITER:
386 ShutdownIcon::OpenURL( WRITER_URL, "_default" );
387 break;
388 case IDM_CALC:
389 ShutdownIcon::OpenURL( CALC_URL, "_default" );
390 break;
391 case IDM_IMPRESS:
393 break;
394 case IDM_DRAW:
395 ShutdownIcon::OpenURL( DRAW_URL, "_default" );
396 break;
397 case IDM_BASE:
398 ShutdownIcon::OpenURL( BASE_URL, "_default" );
399 break;
400 case IDM_MATH:
401 ShutdownIcon::OpenURL( MATH_URL, "_default" );
402 break;
403 case IDM_STARTCENTER:
405 break;
406 case IDM_TEMPLATE:
409 break;
410 case IDM_INSTALL:
412 break;
413 case IDM_EXIT:
414 // remove listener and
415 // terminate office if running in background
418 break;
419 }
420 break;
421 case WM_DESTROY:
422 default:
423 return DefWindowProcW(hWnd, uMsg, wParam, lParam);
424 }
425 return 0;
426}
427
428
429static DWORD WINAPI SystrayThread( LPVOID /*lpParam*/ )
430{
431 osl_setThreadName("SystrayThread");
432
433 aListenerWindow = CreateWindowExW(0,
434 QUICKSTART_CLASSNAME, // registered class name
435 QUICKSTART_WINDOWNAME, // window name
436 0, // window style
437 CW_USEDEFAULT, // horizontal position of window
438 CW_USEDEFAULT, // vertical position of window
439 CW_USEDEFAULT, // window width
440 CW_USEDEFAULT, // window height
441 nullptr, // handle to parent or owner window
442 nullptr, // menu handle or child identifier
443 GetModuleHandleW( nullptr ), // handle to application instance
444 nullptr // window-creation data
445 );
446
447 MSG msg;
448
449 for (;;)
450 {
451 int const bRet = GetMessageW(&msg, nullptr, 0, 0);
452 if (bRet == 0)
453 {
454 break;
455 }
456 if (-1 == bRet)
457 {
458 SAL_WARN("sfx.appl", "GetMessageW failed: " << WindowsErrorString(GetLastError()));
459 return 1;
460 }
461 TranslateMessage( &msg );
462 DispatchMessageW( &msg );
463 }
464
465 return msg.wParam; // Exit code of WM_QUIT
466}
467
468
470{
472 {
473 WNDCLASSEXW listenerClass;
474 listenerClass.cbSize = sizeof(listenerClass);
475 listenerClass.style = 0;
476 listenerClass.lpfnWndProc = listenerWndProc;
477 listenerClass.cbClsExtra = 0;
478 listenerClass.cbWndExtra = 0;
479 listenerClass.hInstance = GetModuleHandleW( nullptr );
480 listenerClass.hIcon = nullptr;
481 listenerClass.hCursor = nullptr;
482 listenerClass.hbrBackground = nullptr;
483 listenerClass.lpszMenuName = nullptr;
484 listenerClass.lpszClassName = QUICKSTART_CLASSNAME;
485 listenerClass.hIconSm = nullptr;
486
487 RegisterClassExW(&listenerClass);
488
489 WNDCLASSEXW executerClass;
490 executerClass.cbSize = sizeof(executerClass);
491 executerClass.style = 0;
492 executerClass.lpfnWndProc = executerWndProc;
493 executerClass.cbClsExtra = 0;
494 executerClass.cbWndExtra = 0;
495 executerClass.hInstance = GetModuleHandleW( nullptr );
496 executerClass.hIcon = nullptr;
497 executerClass.hCursor = nullptr;
498 executerClass.hbrBackground = nullptr;
499 executerClass.lpszMenuName = nullptr;
500 executerClass.lpszClassName = EXECUTER_WINDOWCLASS;
501 executerClass.hIconSm = nullptr;
502
503 RegisterClassExW( &executerClass );
504
505 aExecuterWindow = CreateWindowExW(0,
506 EXECUTER_WINDOWCLASS, // registered class name
507 EXECUTER_WINDOWNAME, // window name
508 0, // window style
509 CW_USEDEFAULT, // horizontal position of window
510 CW_USEDEFAULT, // vertical position of window
511 CW_USEDEFAULT, // window width
512 CW_USEDEFAULT, // window height
513 nullptr, // handle to parent or owner window
514 nullptr, // menu handle or child identifier
515 GetModuleHandleW( nullptr ), // handle to application instance
516 nullptr // window-creation data
517 );
518
519 DWORD dwThreadId;
520 CloseHandle(CreateThread(nullptr, 0, SystrayThread, nullptr, 0, &dwThreadId));
521 }
522}
523
524
526{
528 {
529 if( IsWindow( aListenerWindow ) )
530 {
531 DestroyWindow( aListenerWindow );
532 aListenerWindow = nullptr;
533 DestroyWindow( aExecuterWindow );
534 aExecuterWindow = nullptr;
535 }
536 UnregisterClassW( QUICKSTART_CLASSNAME, GetModuleHandleW( nullptr ) );
537 UnregisterClassW( EXECUTER_WINDOWCLASS, GetModuleHandleW( nullptr ) );
538 }
539}
540
541
542void OnMeasureItem(HWND hwnd, LPMEASUREITEMSTRUCT lpmis)
543{
544 MYITEM *pMyItem = reinterpret_cast<MYITEM *>(lpmis->itemData);
545 HDC hdc = GetDC(hwnd);
546 SIZE size;
547
548 NONCLIENTMETRICSW ncm = {};
549 ncm.cbSize = sizeof(ncm);
550
551 SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
552
553 // Assume every menu item can be default and printed bold
554 ncm.lfMenuFont.lfWeight = FW_BOLD;
555
556 HFONT hfntOld = static_cast<HFONT>(SelectObject(hdc, CreateFontIndirectW( &ncm.lfMenuFont )));
557
558 GetTextExtentPoint32W(hdc, o3tl::toW(pMyItem->text.getStr()),
559 pMyItem->text.getLength(), &size);
560
561 lpmis->itemWidth = size.cx + 4 + GetSystemMetrics( SM_CXSMICON );
562 lpmis->itemHeight = std::max<int>(size.cy, GetSystemMetrics( SM_CYSMICON ));
563 lpmis->itemHeight += 4;
564
565 DeleteObject( SelectObject(hdc, hfntOld) );
566 ReleaseDC(hwnd, hdc);
567}
568
569void OnDrawItem(HWND /*hwnd*/, LPDRAWITEMSTRUCT lpdis)
570{
571 MYITEM *pMyItem = reinterpret_cast<MYITEM *>(lpdis->itemData);
572 COLORREF clrPrevText, clrPrevBkgnd;
573 HFONT hfntOld;
574 HBRUSH hbrOld;
575 int x, y;
576 bool fSelected = lpdis->itemState & ODS_SELECTED;
577 bool fDisabled = lpdis->itemState & (ODS_DISABLED | ODS_GRAYED);
578
579 // Set the appropriate foreground and background colors.
580
581 RECT aRect = lpdis->rcItem;
582
583 clrPrevBkgnd = SetBkColor( lpdis->hDC, GetSysColor(COLOR_MENU) );
584
585 if ( fDisabled )
586 clrPrevText = SetTextColor( lpdis->hDC, GetSysColor( COLOR_GRAYTEXT ) );
587 else
588 clrPrevText = SetTextColor( lpdis->hDC, GetSysColor( fSelected ? COLOR_HIGHLIGHTTEXT : COLOR_MENUTEXT ) );
589
590 if ( fSelected )
591 clrPrevBkgnd = SetBkColor( lpdis->hDC, GetSysColor(COLOR_HIGHLIGHT) );
592 else
593 clrPrevBkgnd = SetBkColor( lpdis->hDC, GetSysColor(COLOR_MENU) );
594
595 hbrOld = static_cast<HBRUSH>(SelectObject( lpdis->hDC, CreateSolidBrush( GetBkColor( lpdis->hDC ) ) ));
596
597 // Fill background
598 PatBlt(lpdis->hDC, aRect.left, aRect.top, aRect.right-aRect.left, aRect.bottom-aRect.top, PATCOPY);
599
600 int height = aRect.bottom-aRect.top;
601
602 x = aRect.left;
603 y = aRect.top;
604
605 int cx = GetSystemMetrics( SM_CXSMICON );
606 int cy = GetSystemMetrics( SM_CYSMICON );
607 HICON hIcon( nullptr );
608 HMODULE hModule( GetModuleHandleW( nullptr ) );
609
610 if ( pMyItem->module.getLength() > 0 )
611 {
612 LPCWSTR pModuleName = o3tl::toW( pMyItem->module.getStr() );
613 hModule = GetModuleHandleW( pModuleName );
614 if ( hModule == nullptr )
615 {
616 hModule = LoadLibraryW(pModuleName);
617 }
618 }
619
620 hIcon = static_cast<HICON>(LoadImageW( hModule, MAKEINTRESOURCEW( pMyItem->iconId ),
621 IMAGE_ICON, cx, cy,
622 LR_DEFAULTCOLOR | LR_SHARED ));
623
624
625 HBRUSH hbrIcon = CreateSolidBrush( GetSysColor( COLOR_GRAYTEXT ) );
626
627 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) );
628
629 DeleteObject( hbrIcon );
630
631 x += cx + 4; // space for icon
632 aRect.left = x;
633
634 NONCLIENTMETRICSW ncm = {};
635 ncm.cbSize = sizeof(ncm);
636
637 SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
638
639 // Print default menu entry with bold font
640 if ( lpdis->itemState & ODS_DEFAULT )
641 ncm.lfMenuFont.lfWeight = FW_BOLD;
642
643 hfntOld = static_cast<HFONT>(SelectObject(lpdis->hDC, CreateFontIndirectW( &ncm.lfMenuFont )));
644
645
646 SIZE size;
647 GetTextExtentPointW( lpdis->hDC, o3tl::toW(pMyItem->text.getStr()), pMyItem->text.getLength(), &size );
648
649 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) );
650
651 // Restore the original font and colors.
652 DeleteObject( SelectObject( lpdis->hDC, hbrOld ) );
653 DeleteObject( SelectObject( lpdis->hDC, hfntOld) );
654 SetTextColor(lpdis->hDC, clrPrevText);
655 SetBkColor(lpdis->hDC, clrPrevBkgnd);
656}
657
658
659// code from setup2 project
660
661
662static void SHFree_( void *pv )
663{
664 IMalloc *pMalloc;
665 if( NOERROR == SHGetMalloc(&pMalloc) )
666 {
667 pMalloc->Free( pv );
668 pMalloc->Release();
669 }
670}
671
672#define ALLOC(type, n) static_cast<type *>(HeapAlloc(GetProcessHeap(), 0, sizeof(type) * n ))
673#define FREE(p) HeapFree(GetProcessHeap(), 0, p)
674
675static OUString SHGetSpecialFolder( int nFolderID )
676{
677
678 LPITEMIDLIST pidl;
679 HRESULT hHdl = SHGetSpecialFolderLocation( nullptr, nFolderID, &pidl );
680 OUString aFolder;
681
682 if( hHdl == NOERROR )
683 {
684 WCHAR *lpFolderA;
685 lpFolderA = ALLOC( WCHAR, 16000 );
686
687 SHGetPathFromIDListW( pidl, lpFolderA );
688 aFolder = o3tl::toU( lpFolderA );
689
690 FREE( lpFolderA );
691 SHFree_( pidl );
692 }
693 return aFolder;
694}
695
696OUString ShutdownIcon::GetAutostartFolderNameW32()
697{
698 return SHGetSpecialFolder(CSIDL_STARTUP);
699}
700
701static HRESULT WINAPI SHCoCreateInstance( LPVOID lpszReserved, REFCLSID clsid, LPUNKNOWN pUnkUnknown, REFIID iid, LPVOID *ppv )
702{
703 HRESULT hResult = E_NOTIMPL;
704 HMODULE hModShell = GetModuleHandleW( L"SHELL32" );
705
706 if ( hModShell != nullptr )
707 {
708 typedef HRESULT (WINAPI *SHCoCreateInstance_PROC)( LPVOID lpszReserved, REFCLSID clsid, LPUNKNOWN pUnkUnknown, REFIID iid, LPVOID *ppv );
709
710 SHCoCreateInstance_PROC lpfnSHCoCreateInstance = reinterpret_cast<SHCoCreateInstance_PROC>(GetProcAddress( hModShell, MAKEINTRESOURCEA(102) ));
711
712 if ( lpfnSHCoCreateInstance )
713 hResult = lpfnSHCoCreateInstance( lpszReserved, clsid, pUnkUnknown, iid, ppv );
714 }
715 return hResult;
716}
717
718static bool CreateShortcut( const OUString& rAbsObject, const OUString& rAbsObjectPath,
719 const OUString& rAbsShortcut, const OUString& rDescription, const OUString& rParameter )
720{
721 HRESULT hres;
722 IShellLinkW* psl;
723 CLSID clsid_ShellLink = CLSID_ShellLink;
724 CLSID clsid_IShellLink = IID_IShellLinkW;
725
726 hres = CoCreateInstance( clsid_ShellLink, nullptr, CLSCTX_INPROC_SERVER,
727 clsid_IShellLink, reinterpret_cast<void**>(&psl) );
728 if( FAILED(hres) )
729 hres = SHCoCreateInstance( nullptr, clsid_ShellLink, nullptr, clsid_IShellLink, reinterpret_cast<void**>(&psl) );
730
731 if( SUCCEEDED(hres) )
732 {
733 IPersistFile* ppf;
734 psl->SetPath( o3tl::toW(rAbsObject.getStr()) );
735 psl->SetWorkingDirectory( o3tl::toW(rAbsObjectPath.getStr()) );
736 psl->SetDescription( o3tl::toW(rDescription.getStr()) );
737 if( rParameter.getLength() )
738 psl->SetArguments( o3tl::toW(rParameter.getStr()) );
739
740 CLSID clsid_IPersistFile = IID_IPersistFile;
741 hres = psl->QueryInterface( clsid_IPersistFile, reinterpret_cast<void**>(&ppf) );
742
743 if( SUCCEEDED(hres) )
744 {
745 hres = ppf->Save( o3tl::toW(rAbsShortcut.getStr()), TRUE );
746 ppf->Release();
747 } else return false;
748 psl->Release();
749 } else return false;
750 return true;
751}
752
753
754// install/uninstall
755
756static bool FileExistsW( LPCWSTR lpPath )
757{
758 bool bExists = false;
759 WIN32_FIND_DATAW aFindData;
760
761 HANDLE hFind = FindFirstFileW( lpPath, &aFindData );
762
763 if ( INVALID_HANDLE_VALUE != hFind )
764 {
765 bExists = true;
766 FindClose( hFind );
767 }
768
769 return bExists;
770}
771
773{
774 wchar_t aPath[_MAX_PATH];
775 GetModuleFileNameW( nullptr, aPath, _MAX_PATH-1);
776
777 OUString aOfficepath( o3tl::toU(aPath) );
778 int i = aOfficepath.lastIndexOf('\\');
779 if( i != -1 )
780 aOfficepath = aOfficepath.copy(0, i);
781
782 OUString quickstartExe(aOfficepath + "\\quickstart.exe");
783
784 return FileExistsW( o3tl::toW(quickstartExe.getStr()) );
785}
786
787void ShutdownIcon::EnableAutostartW32( const OUString &aShortcut )
788{
789 wchar_t aPath[_MAX_PATH];
790 GetModuleFileNameW( nullptr, aPath, _MAX_PATH-1);
791
792 OUString aOfficepath( o3tl::toU(aPath) );
793 int i = aOfficepath.lastIndexOf('\\');
794 if( i != -1 )
795 aOfficepath = aOfficepath.copy(0, i);
796
797 OUString quickstartExe(aOfficepath + "\\quickstart.exe");
798
799 CreateShortcut( quickstartExe, aOfficepath, aShortcut, OUString(), OUString() );
800}
801
802
803/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static bool IsQuickstarterInstalled()
static ShutdownIcon * getInstance()
static void terminateDesktop()
static void FromTemplate()
static void addTerminateListener()
static void FileOpen()
static OUString GetUrlDescription(std::u16string_view aUrl)
static bool bModalMode
static bool GetAutostart()
static void SetAutostart(bool bActivate)
static void OpenURL(const OUString &aURL, const OUString &rTarget, const css::uno::Sequence< css::beans::PropertyValue > &=css::uno::Sequence< css::beans::PropertyValue >(0))
void SetVeto(bool bVeto)
bool IsModuleInstalled(EModule eModule) const
float y
float x
#define TRUE
#define SAL_WARN_IF(condition, area, stream)
#define SAL_WARN(area, stream)
#define _MAX_PATH
def text(shape, orig_st)
std::vector< SvtDynMenuEntry > GetMenu(EDynamicMenuType eMenu)
size
PATCOPY
int i
m
module
constexpr tools::Long SIZE
FW_BOLD
#define CALLBACK
OUString SfxResId(TranslateId aId)
Definition: sfxresid.cxx:22
constexpr OUStringLiteral DRAW_URL
constexpr OUStringLiteral MATH_URL
constexpr OUStringLiteral STARTMODULE_URL
constexpr OUStringLiteral CALC_URL
constexpr OUStringLiteral BASE_URL
constexpr OUStringLiteral WRITER_URL
constexpr OUStringLiteral IMPRESS_WIZARD_URL
#define FREE(p)
#define IDM_DRAW
#define IDM_TEMPLATE
#define IDM_CALC
#define ICON_DRAWING_DOCUMENT
static void OnMeasureItem(HWND hwnd, LPMEASUREITEMSTRUCT lpmis)
static void SHFree_(void *pv)
static DWORD WINAPI SystrayThread(LPVOID)
static LRESULT CALLBACK listenerWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
static OUString SHGetSpecialFolder(int nFolderID)
static HRESULT WINAPI SHCoCreateInstance(LPVOID lpszReserved, REFCLSID clsid, LPUNKNOWN pUnkUnknown, REFIID iid, LPVOID *ppv)
void win32_init_sys_tray()
#define IDM_WRITER
static bool CreateShortcut(const OUString &rAbsObject, const OUString &rAbsObjectPath, const OUString &rAbsShortcut, const OUString &rDescription, const OUString &rParameter)
#define IDM_BASE
#define EXECUTER_WINDOWNAME
#define IDM_STARTCENTER
static LRESULT CALLBACK executerWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
static void OnDrawItem(HWND hwnd, LPDRAWITEMSTRUCT lpdis)
static void addTaskbarIcon(HWND hWnd)
#define ICON_TEMPLATE
#define ICON_MATH_DOCUMENT
static void addMenuItem(HMENU hMenu, UINT id, UINT iconId, const OUString &text, int &pos, bool bOwnerdraw, const OUString &module)
static HMENU createSystrayMenu()
#define IDM_EXIT
#define SFX_TASKBAR_NOTIFICATION
#define ICON_OPEN
#define ICON_TEXT_DOCUMENT
static void deleteSystrayMenu(HMENU hMenu)
#define ALLOC(type, n)
#define EXECUTER_WINDOWCLASS
static HWND aExecuterWindow
static bool FileExistsW(LPCWSTR lpPath)
#define ICON_SPREADSHEET_DOCUMENT
#define IDM_MATH
#define ID_QUICKSTART
#define IDM_IMPRESS
static HMENU popupMenu
static HWND aListenerWindow
#define IDM_INSTALL
#define ICON_PRESENTATION_DOCUMENT
#define ICON_LO_DEFAULT
#define IDM_OPEN
void win32_shutdown_sys_tray()
#define ICON_DATABASE_DOCUMENT
sal_uInt16 sal_Unicode
size_t pos