xref: /AOO41X/main/desktop/win32/source/QuickStart/QuickStart.cpp (revision 13ac66067bb747a4eb70bcaea767c3d0442347d5)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 // QuickStart.cpp : Defines the entry point for the application.
23 //
24 
25 #include "stdafx.h"
26 #include "resource.h"
27 #include <systools/win32/uwinapi.h>
28 #include <stdio.h>
29 
30 #define MY_TASKBAR_NOTIFICATION         WM_USER+1
31 
32 #define MAX_LOADSTRING 100
33 
34 // message used to communicate with soffice
35 #define TERMINATIONVETO_MESSAGE "SO TerminationVeto"
36 #define TERMINATE_MESSAGE       "SO Terminate"
37 #define LISTENER_WINDOWCLASS    "SO Listener Class"
38 #define KILLTRAY_MESSAGE        "SO KillTray"
39 
40 static  UINT aTerminationVetoMessage = 0x7FFF;
41 static  UINT aTerminateMessage = 0x7FFF;
42 static  HMENU popupMenu = NULL;
43 static  bool bTerminateVeto = true;
44 
45 #define UPDATE_TIMER   1
46 
47 // Global Variables:
48 HINSTANCE hInst;                                // current instance
49 TCHAR szTitle[MAX_LOADSTRING];                  // The title bar text
50 TCHAR szWindowClass[MAX_LOADSTRING];            // The title bar text
51 
52 TCHAR szExitString[MAX_LOADSTRING];
53 TCHAR szTooltipString[MAX_LOADSTRING];
54 
55 // Foward declarations of functions included in this code module:
56 ATOM                MyRegisterClass(HINSTANCE hInstance);
57 BOOL                InitInstance(HINSTANCE, int);
58 LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
59 LRESULT CALLBACK    About(HWND, UINT, WPARAM, LPARAM);
60 
SofficeRuns()61 bool SofficeRuns()
62 {
63     // check for soffice by searching the communication window
64     return ( FindWindowEx( NULL, NULL, LISTENER_WINDOWCLASS, NULL ) == NULL ) ? false : true;
65 }
66 
launchSoffice()67 bool launchSoffice( )
68 {
69     if ( !SofficeRuns() )
70     {
71         // UINT ret = WinExec( "h:\\office60.630b\\program\\swriter.exe -bean", SW_SHOW );
72         char filename[_MAX_PATH + 1];
73 
74         filename[_MAX_PATH] = 0;
75         GetModuleFileName( NULL, filename, _MAX_PATH ); // soffice resides in the same dir
76         char *p = strrchr( filename, '\\' );
77         if ( !p )
78             return false;
79 
80         strncpy( p+1, "soffice.exe", _MAX_PATH - (p+1 - filename) );
81 
82         char imagename[_MAX_PATH + 1];
83 
84         imagename[_MAX_PATH] = 0;
85         _snprintf(imagename, _MAX_PATH, "\"%s\" -quickstart", filename );
86 
87         UINT ret = WinExec( imagename, SW_SHOW );
88         if ( ret < 32 )
89             return false;
90 /*
91         // wait until we can communicate
92         int retry = 30;
93         while (retry-- && !SofficeRuns() )
94             Sleep(1000);
95 
96         return SofficeRuns();
97         */
98         return true;
99     }
100     else
101         return true;
102 }
103 
NotifyListener(HWND hWnd)104 void NotifyListener( HWND hWnd )
105 {
106     static HICON hIconActive=NULL;
107     //static HICON hIconInActive=NULL;
108 
109     if( !hIconActive )
110     {
111         hIconActive = (HICON)LoadImage( GetModuleHandle( NULL ), MAKEINTRESOURCE( ICON_ACTIVE ),
112             IMAGE_ICON, GetSystemMetrics( SM_CXSMICON ), GetSystemMetrics( SM_CYSMICON ),
113             LR_DEFAULTCOLOR | LR_SHARED );
114 
115 /*        hIconInActive = (HICON)LoadImage( GetModuleHandle( NULL ), MAKEINTRESOURCE( ICON_INACTIVE ),
116             IMAGE_ICON, GetSystemMetrics( SM_CXSMICON ), GetSystemMetrics( SM_CYSMICON ),
117             LR_DEFAULTCOLOR | LR_SHARED );
118             */
119     }
120 
121     NOTIFYICONDATA nid;
122     nid.cbSize = sizeof(NOTIFYICONDATA);
123     nid.hWnd   = hWnd;
124     nid.uID    = IDM_QUICKSTART;
125     nid.szTip[elementsof(nid.szTip) - 1] = 0;
126 //    nid.hIcon = bTerminateVeto ? hIconActive : hIconInActive;
127 //    strncpy(nid.szTip, bTerminateVeto ? STRING_QUICKSTARTACTIVE : STRING_QUICKSTARTINACTIVE, elementsof(nid.szTip) - 1 );
128     nid.hIcon = hIconActive;
129     strncpy(nid.szTip, szTooltipString, elementsof(nid.szTip) - 1);
130     nid.uFlags = NIF_TIP|NIF_ICON;
131 
132     // update systray
133     Shell_NotifyIcon( NIM_MODIFY, &nid );
134     //CheckMenuItem( popupMenu, IDM_QUICKSTART, bTerminateVeto ? MF_CHECKED : MF_UNCHECKED );
135 
136     // notify listener
137     SendMessage( HWND_BROADCAST, aTerminationVetoMessage, (WORD) bTerminateVeto, 0L );
138 }
139 
140 
141 
WinMain(HINSTANCE hInstance,HINSTANCE,LPSTR,int nCmdShow)142 int APIENTRY WinMain(HINSTANCE hInstance,
143                      HINSTANCE /*hPrevInstance*/,
144                      LPSTR     /*lpCmdLine*/,
145                      int       nCmdShow)
146 {
147     // Look for -killtray argument
148 
149     for ( int i = 1; i < __argc; i++ )
150     {
151         if ( 0 == strcmp( __argv[i], "-killtray" ) )
152         {
153             HWND    hwndTray = FindWindow( LISTENER_WINDOWCLASS, NULL );
154 
155             if ( hwndTray )
156             {
157                 UINT    uMsgKillTray = RegisterWindowMessage( KILLTRAY_MESSAGE );
158                 SendMessage( hwndTray, uMsgKillTray, 0, 0 );
159             }
160 
161             return 0;
162         }
163     }
164 
165     launchSoffice();
166     return 0;
167 
168     // TODO: Place code here.
169     MSG msg;
170     HACCEL hAccelTable;
171     aTerminationVetoMessage = RegisterWindowMessage( TERMINATIONVETO_MESSAGE );
172     aTerminateMessage       = RegisterWindowMessage( TERMINATE_MESSAGE );
173 
174     // Initialize global strings
175     LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
176     LoadString(hInstance, IDC_QUICKSTART, szWindowClass, MAX_LOADSTRING);
177 
178     LoadString(hInstance, IDS_EXIT,    szExitString, MAX_LOADSTRING);
179     LoadString(hInstance, IDS_TOOLTIP, szTooltipString, MAX_LOADSTRING);
180 
181     MyRegisterClass(hInstance);
182 
183     // Perform application initialization:
184     if (!InitInstance (hInstance, nCmdShow))
185     {
186         return FALSE;
187     }
188 
189     hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_QUICKSTART);
190 
191     // Main message loop:
192     while (GetMessage(&msg, NULL, 0, 0))
193     {
194         if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
195         {
196             TranslateMessage(&msg);
197             DispatchMessage(&msg);
198         }
199     }
200 
201     return msg.wParam;
202 }
203 
204 
205 
206 //
207 //  FUNCTION: MyRegisterClass()
208 //
209 //  PURPOSE: Registers the window class.
210 //
211 //  COMMENTS:
212 //
213 //    This function and its usage is only necessary if you want this code
214 //    to be compatible with Win32 systems prior to the 'RegisterClassEx'
215 //    function that was added to Windows 95. It is important to call this function
216 //    so that the application will get 'well formed' small icons associated
217 //    with it.
218 //
MyRegisterClass(HINSTANCE hInstance)219 ATOM MyRegisterClass(HINSTANCE hInstance)
220 {
221     WNDCLASSEX wcex;
222 
223     wcex.cbSize = sizeof(WNDCLASSEX);
224 
225     wcex.style          = CS_HREDRAW | CS_VREDRAW;
226     wcex.lpfnWndProc    = (WNDPROC)WndProc;
227     wcex.cbClsExtra     = 0;
228     wcex.cbWndExtra     = 0;
229     wcex.hInstance      = hInstance;
230     wcex.hIcon          = LoadIcon(hInstance, (LPCTSTR)IDI_QUICKSTART);
231     wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
232     wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
233     wcex.lpszMenuName   = NULL;
234     wcex.lpszClassName  = szWindowClass;
235     wcex.hIconSm        = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
236 
237     return RegisterClassEx(&wcex);
238 }
239 
240 //
241 //   FUNCTION: InitInstance(HANDLE, int)
242 //
243 //   PURPOSE: Saves instance handle and creates main window
244 //
245 //   COMMENTS:
246 //
247 //        In this function, we save the instance handle in a global variable and
248 //        create and display the main program window.
249 //
InitInstance(HINSTANCE hInstance,int nCmdShow)250 BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
251 {
252    HWND hWnd;
253 
254    hInst = hInstance; // Store instance handle in our global variable
255 
256    hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
257       CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
258 
259    if (!hWnd)
260    {
261       return FALSE;
262    }
263 
264    nCmdShow = SW_HIDE;   // hide main window, we only need the taskbar icon
265    ShowWindow(hWnd, nCmdShow);
266    UpdateWindow(hWnd);
267 
268    return TRUE;
269 }
270 
271 //
272 //  FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
273 //
274 //  PURPOSE:  Processes messages for the main window.
275 //
276 //  WM_COMMAND  - process the application menu
277 //  WM_PAINT    - Paint the main window
278 //  WM_DESTROY  - post a quit message and return
279 //
280 //
WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)281 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
282 {
283     switch (message)
284     {
285         case WM_CREATE:
286         {
287             // make sure soffice runs
288             if( !launchSoffice() )
289                 return -1;
290 
291             // create popup menu
292             popupMenu = CreatePopupMenu();
293             static int count=0;
294 
295             // Add my items
296             MENUITEMINFO mi;
297             mi.cbSize = sizeof(MENUITEMINFO);
298             mi.fMask=MIIM_TYPE|MIIM_STATE|MIIM_ID;
299             mi.fType=MFT_STRING;
300             mi.fState=MFS_ENABLED|MFS_DEFAULT;
301             mi.wID = IDM_QUICKSTART;
302             mi.hSubMenu=NULL;
303             mi.hbmpChecked=NULL;
304             mi.hbmpUnchecked=NULL;
305             mi.dwItemData=NULL;
306             mi.dwTypeData = "QuickStart";
307             mi.cch = strlen(mi.dwTypeData);
308 //            InsertMenuItem(popupMenu, count++, TRUE, &mi);
309 
310             mi.cbSize = sizeof(MENUITEMINFO);
311             mi.fMask=MIIM_TYPE|MIIM_STATE|MIIM_ID;
312             mi.fType=MFT_STRING;
313             mi.fState=MFS_ENABLED;
314             mi.wID = IDM_ABOUT;
315             mi.hSubMenu=NULL;
316             mi.hbmpChecked=NULL;
317             mi.hbmpUnchecked=NULL;
318             mi.dwItemData=NULL;
319             mi.dwTypeData = "Info...";
320             mi.cch = strlen(mi.dwTypeData);
321 //            InsertMenuItem(popupMenu, count++, TRUE, &mi);
322 
323             mi.cbSize = sizeof(MENUITEMINFO);
324             mi.fMask=MIIM_TYPE;
325             mi.fType=MFT_SEPARATOR;
326             mi.hSubMenu=NULL;
327             mi.hbmpChecked=NULL;
328             mi.hbmpUnchecked=NULL;
329             mi.dwItemData=NULL;
330 //            InsertMenuItem(popupMenu, count++, TRUE, &mi);
331 
332             mi.cbSize = sizeof(MENUITEMINFO);
333             mi.fMask=MIIM_TYPE|MIIM_STATE|MIIM_ID;
334             mi.fType=MFT_STRING;
335             mi.fState=MFS_ENABLED;
336             mi.wID = IDM_EXIT;
337             mi.hSubMenu=NULL;
338             mi.hbmpChecked=NULL;
339             mi.hbmpUnchecked=NULL;
340             mi.dwItemData=NULL;
341             mi.dwTypeData = szExitString;
342             mi.cch = strlen(mi.dwTypeData);
343             InsertMenuItem(popupMenu, count++, TRUE, &mi);
344 
345             // add taskbar icon
346             NOTIFYICONDATA nid;
347             nid.cbSize = sizeof(NOTIFYICONDATA);
348             nid.hWnd   = hWnd;
349             nid.uID    = IDM_QUICKSTART;
350             nid.uFlags = NIF_MESSAGE;
351             nid.uCallbackMessage=MY_TASKBAR_NOTIFICATION;
352             Shell_NotifyIcon(NIM_ADD, &nid);
353 
354             // and update state
355             NotifyListener( hWnd );
356 
357             // check for soffice
358             SetTimer(hWnd, UPDATE_TIMER, 3000, NULL);
359         }
360         break;
361 
362         case MY_TASKBAR_NOTIFICATION: // message from taskbar
363             switch(lParam)
364             {
365 /*
366                 case WM_LBUTTONDBLCLK:
367                     bTerminateVeto = bTerminateVeto ? false : true;
368                     NotifyListener( hWnd );
369                     break;
370                     */
371 
372                 case WM_LBUTTONDOWN:
373                 case WM_RBUTTONDOWN:
374                 {
375                     POINT pt;
376                     GetCursorPos(&pt);
377                     SetForegroundWindow( hWnd );
378                     int m = TrackPopupMenuEx(popupMenu, TPM_RETURNCMD|TPM_LEFTALIGN|TPM_RIGHTBUTTON,
379                         pt.x, pt.y, hWnd, NULL);
380                     // BUGFIX: See Q135788 (PRB: Menus for Notification Icons Don't Work Correctly)
381                     PostMessage(hWnd, NULL, 0, 0);
382                     switch(m)
383                     {
384                     case IDM_QUICKSTART:
385                         bTerminateVeto = bTerminateVeto ? false : true;
386                         NotifyListener( hWnd );
387                         break;
388                     case IDM_ABOUT:
389                         DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
390                         break;
391                     case IDM_EXIT:
392                         DestroyWindow(hWnd);
393                         break;
394                     }
395                 }
396                 break;
397             }
398             break;
399 
400         case WM_TIMER:
401             if( wParam == UPDATE_TIMER )
402             {
403                 // update state
404                 NotifyListener( hWnd );
405             }
406             break;
407 
408         case WM_DESTROY:
409             // try to terminate office
410             SendMessage( HWND_BROADCAST, aTerminateMessage, 0, 0L );
411 
412             // delete taskbar icon
413             NOTIFYICONDATA nid;
414             nid.cbSize=sizeof(NOTIFYICONDATA);
415             nid.hWnd = hWnd;
416             nid.uID = IDM_QUICKSTART;
417             Shell_NotifyIcon(NIM_DELETE, &nid);
418 
419             PostQuitMessage(0);
420             break;
421         default:
422             return DefWindowProc(hWnd, message, wParam, lParam);
423    }
424    return 0;
425 }
426 
427 // Mesage handler for about box.
About(HWND hDlg,UINT message,WPARAM wParam,LPARAM)428 LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM)
429 {
430     switch (message)
431     {
432         case WM_INITDIALOG:
433                 return TRUE;
434 
435         case WM_COMMAND:
436             if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
437             {
438                 EndDialog(hDlg, LOWORD(wParam));
439                 return TRUE;
440             }
441             break;
442     }
443     return FALSE;
444 }
445