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 // Forward 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