| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| // QuickStart.cpp : Defines the entry point for the application. |
| // |
| |
| #include "stdafx.h" |
| #include "resource.h" |
| #include <systools/win32/uwinapi.h> |
| #include <stdio.h> |
| |
| #define MY_TASKBAR_NOTIFICATION WM_USER+1 |
| |
| #define MAX_LOADSTRING 100 |
| |
| // message used to communicate with soffice |
| #define TERMINATIONVETO_MESSAGE "SO TerminationVeto" |
| #define TERMINATE_MESSAGE "SO Terminate" |
| #define LISTENER_WINDOWCLASS "SO Listener Class" |
| #define KILLTRAY_MESSAGE "SO KillTray" |
| |
| static UINT aTerminationVetoMessage = 0x7FFF; |
| static UINT aTerminateMessage = 0x7FFF; |
| static HMENU popupMenu = NULL; |
| static bool bTerminateVeto = true; |
| |
| #define UPDATE_TIMER 1 |
| |
| // Global Variables: |
| HINSTANCE hInst; // current instance |
| TCHAR szTitle[MAX_LOADSTRING]; // The title bar text |
| TCHAR szWindowClass[MAX_LOADSTRING]; // The title bar text |
| |
| TCHAR szExitString[MAX_LOADSTRING]; |
| TCHAR szTooltipString[MAX_LOADSTRING]; |
| |
| // Foward declarations of functions included in this code module: |
| ATOM MyRegisterClass(HINSTANCE hInstance); |
| BOOL InitInstance(HINSTANCE, int); |
| LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); |
| LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM); |
| |
| bool SofficeRuns() |
| { |
| // check for soffice by searching the communication window |
| return ( FindWindowEx( NULL, NULL, LISTENER_WINDOWCLASS, NULL ) == NULL ) ? false : true; |
| } |
| |
| bool launchSoffice( ) |
| { |
| if ( !SofficeRuns() ) |
| { |
| // UINT ret = WinExec( "h:\\office60.630b\\program\\swriter.exe -bean", SW_SHOW ); |
| char filename[_MAX_PATH + 1]; |
| |
| filename[_MAX_PATH] = 0; |
| GetModuleFileName( NULL, filename, _MAX_PATH ); // soffice resides in the same dir |
| char *p = strrchr( filename, '\\' ); |
| if ( !p ) |
| return false; |
| |
| strncpy( p+1, "soffice.exe", _MAX_PATH - (p+1 - filename) ); |
| |
| char imagename[_MAX_PATH + 1]; |
| |
| imagename[_MAX_PATH] = 0; |
| _snprintf(imagename, _MAX_PATH, "\"%s\" -quickstart", filename ); |
| |
| UINT ret = WinExec( imagename, SW_SHOW ); |
| if ( ret < 32 ) |
| return false; |
| /* |
| // wait until we can communicate |
| int retry = 30; |
| while (retry-- && !SofficeRuns() ) |
| Sleep(1000); |
| |
| return SofficeRuns(); |
| */ |
| return true; |
| } |
| else |
| return true; |
| } |
| |
| void NotifyListener( HWND hWnd ) |
| { |
| static HICON hIconActive=NULL; |
| //static HICON hIconInActive=NULL; |
| |
| if( !hIconActive ) |
| { |
| hIconActive = (HICON)LoadImage( GetModuleHandle( NULL ), MAKEINTRESOURCE( ICON_ACTIVE ), |
| IMAGE_ICON, GetSystemMetrics( SM_CXSMICON ), GetSystemMetrics( SM_CYSMICON ), |
| LR_DEFAULTCOLOR | LR_SHARED ); |
| |
| /* hIconInActive = (HICON)LoadImage( GetModuleHandle( NULL ), MAKEINTRESOURCE( ICON_INACTIVE ), |
| IMAGE_ICON, GetSystemMetrics( SM_CXSMICON ), GetSystemMetrics( SM_CYSMICON ), |
| LR_DEFAULTCOLOR | LR_SHARED ); |
| */ |
| } |
| |
| NOTIFYICONDATA nid; |
| nid.cbSize = sizeof(NOTIFYICONDATA); |
| nid.hWnd = hWnd; |
| nid.uID = IDM_QUICKSTART; |
| nid.szTip[elementsof(nid.szTip) - 1] = 0; |
| // nid.hIcon = bTerminateVeto ? hIconActive : hIconInActive; |
| // strncpy(nid.szTip, bTerminateVeto ? STRING_QUICKSTARTACTIVE : STRING_QUICKSTARTINACTIVE, elementsof(nid.szTip) - 1 ); |
| nid.hIcon = hIconActive; |
| strncpy(nid.szTip, szTooltipString, elementsof(nid.szTip) - 1); |
| nid.uFlags = NIF_TIP|NIF_ICON; |
| |
| // update systray |
| Shell_NotifyIcon( NIM_MODIFY, &nid ); |
| //CheckMenuItem( popupMenu, IDM_QUICKSTART, bTerminateVeto ? MF_CHECKED : MF_UNCHECKED ); |
| |
| // notify listener |
| SendMessage( HWND_BROADCAST, aTerminationVetoMessage, (WORD) bTerminateVeto, 0L ); |
| } |
| |
| |
| |
| int APIENTRY WinMain(HINSTANCE hInstance, |
| HINSTANCE /*hPrevInstance*/, |
| LPSTR /*lpCmdLine*/, |
| int nCmdShow) |
| { |
| // Look for -killtray argument |
| |
| for ( int i = 1; i < __argc; i++ ) |
| { |
| if ( 0 == strcmp( __argv[i], "-killtray" ) ) |
| { |
| HWND hwndTray = FindWindow( LISTENER_WINDOWCLASS, NULL ); |
| |
| if ( hwndTray ) |
| { |
| UINT uMsgKillTray = RegisterWindowMessage( KILLTRAY_MESSAGE ); |
| SendMessage( hwndTray, uMsgKillTray, 0, 0 ); |
| } |
| |
| return 0; |
| } |
| } |
| |
| launchSoffice(); |
| return 0; |
| |
| // TODO: Place code here. |
| MSG msg; |
| HACCEL hAccelTable; |
| aTerminationVetoMessage = RegisterWindowMessage( TERMINATIONVETO_MESSAGE ); |
| aTerminateMessage = RegisterWindowMessage( TERMINATE_MESSAGE ); |
| |
| // Initialize global strings |
| LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); |
| LoadString(hInstance, IDC_QUICKSTART, szWindowClass, MAX_LOADSTRING); |
| |
| LoadString(hInstance, IDS_EXIT, szExitString, MAX_LOADSTRING); |
| LoadString(hInstance, IDS_TOOLTIP, szTooltipString, MAX_LOADSTRING); |
| |
| MyRegisterClass(hInstance); |
| |
| // Perform application initialization: |
| if (!InitInstance (hInstance, nCmdShow)) |
| { |
| return FALSE; |
| } |
| |
| hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_QUICKSTART); |
| |
| // Main message loop: |
| while (GetMessage(&msg, NULL, 0, 0)) |
| { |
| if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) |
| { |
| TranslateMessage(&msg); |
| DispatchMessage(&msg); |
| } |
| } |
| |
| return msg.wParam; |
| } |
| |
| |
| |
| // |
| // FUNCTION: MyRegisterClass() |
| // |
| // PURPOSE: Registers the window class. |
| // |
| // COMMENTS: |
| // |
| // This function and its usage is only necessary if you want this code |
| // to be compatible with Win32 systems prior to the 'RegisterClassEx' |
| // function that was added to Windows 95. It is important to call this function |
| // so that the application will get 'well formed' small icons associated |
| // with it. |
| // |
| ATOM MyRegisterClass(HINSTANCE hInstance) |
| { |
| WNDCLASSEX wcex; |
| |
| wcex.cbSize = sizeof(WNDCLASSEX); |
| |
| wcex.style = CS_HREDRAW | CS_VREDRAW; |
| wcex.lpfnWndProc = (WNDPROC)WndProc; |
| wcex.cbClsExtra = 0; |
| wcex.cbWndExtra = 0; |
| wcex.hInstance = hInstance; |
| wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_QUICKSTART); |
| wcex.hCursor = LoadCursor(NULL, IDC_ARROW); |
| wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); |
| wcex.lpszMenuName = NULL; |
| wcex.lpszClassName = szWindowClass; |
| wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL); |
| |
| return RegisterClassEx(&wcex); |
| } |
| |
| // |
| // FUNCTION: InitInstance(HANDLE, int) |
| // |
| // PURPOSE: Saves instance handle and creates main window |
| // |
| // COMMENTS: |
| // |
| // In this function, we save the instance handle in a global variable and |
| // create and display the main program window. |
| // |
| BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) |
| { |
| HWND hWnd; |
| |
| hInst = hInstance; // Store instance handle in our global variable |
| |
| hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, |
| CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); |
| |
| if (!hWnd) |
| { |
| return FALSE; |
| } |
| |
| nCmdShow = SW_HIDE; // hide main window, we only need the taskbar icon |
| ShowWindow(hWnd, nCmdShow); |
| UpdateWindow(hWnd); |
| |
| return TRUE; |
| } |
| |
| // |
| // FUNCTION: WndProc(HWND, unsigned, WORD, LONG) |
| // |
| // PURPOSE: Processes messages for the main window. |
| // |
| // WM_COMMAND - process the application menu |
| // WM_PAINT - Paint the main window |
| // WM_DESTROY - post a quit message and return |
| // |
| // |
| LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) |
| { |
| switch (message) |
| { |
| case WM_CREATE: |
| { |
| // make sure soffice runs |
| if( !launchSoffice() ) |
| return -1; |
| |
| // create popup menu |
| popupMenu = CreatePopupMenu(); |
| static int count=0; |
| |
| // Add my items |
| MENUITEMINFO mi; |
| mi.cbSize = sizeof(MENUITEMINFO); |
| mi.fMask=MIIM_TYPE|MIIM_STATE|MIIM_ID; |
| mi.fType=MFT_STRING; |
| mi.fState=MFS_ENABLED|MFS_DEFAULT; |
| mi.wID = IDM_QUICKSTART; |
| mi.hSubMenu=NULL; |
| mi.hbmpChecked=NULL; |
| mi.hbmpUnchecked=NULL; |
| mi.dwItemData=NULL; |
| mi.dwTypeData = "QuickStart"; |
| mi.cch = strlen(mi.dwTypeData); |
| // InsertMenuItem(popupMenu, count++, TRUE, &mi); |
| |
| mi.cbSize = sizeof(MENUITEMINFO); |
| mi.fMask=MIIM_TYPE|MIIM_STATE|MIIM_ID; |
| mi.fType=MFT_STRING; |
| mi.fState=MFS_ENABLED; |
| mi.wID = IDM_ABOUT; |
| mi.hSubMenu=NULL; |
| mi.hbmpChecked=NULL; |
| mi.hbmpUnchecked=NULL; |
| mi.dwItemData=NULL; |
| mi.dwTypeData = "Info..."; |
| mi.cch = strlen(mi.dwTypeData); |
| // InsertMenuItem(popupMenu, count++, TRUE, &mi); |
| |
| mi.cbSize = sizeof(MENUITEMINFO); |
| mi.fMask=MIIM_TYPE; |
| mi.fType=MFT_SEPARATOR; |
| mi.hSubMenu=NULL; |
| mi.hbmpChecked=NULL; |
| mi.hbmpUnchecked=NULL; |
| mi.dwItemData=NULL; |
| // InsertMenuItem(popupMenu, count++, TRUE, &mi); |
| |
| mi.cbSize = sizeof(MENUITEMINFO); |
| mi.fMask=MIIM_TYPE|MIIM_STATE|MIIM_ID; |
| mi.fType=MFT_STRING; |
| mi.fState=MFS_ENABLED; |
| mi.wID = IDM_EXIT; |
| mi.hSubMenu=NULL; |
| mi.hbmpChecked=NULL; |
| mi.hbmpUnchecked=NULL; |
| mi.dwItemData=NULL; |
| mi.dwTypeData = szExitString; |
| mi.cch = strlen(mi.dwTypeData); |
| InsertMenuItem(popupMenu, count++, TRUE, &mi); |
| |
| // add taskbar icon |
| NOTIFYICONDATA nid; |
| nid.cbSize = sizeof(NOTIFYICONDATA); |
| nid.hWnd = hWnd; |
| nid.uID = IDM_QUICKSTART; |
| nid.uFlags = NIF_MESSAGE; |
| nid.uCallbackMessage=MY_TASKBAR_NOTIFICATION; |
| Shell_NotifyIcon(NIM_ADD, &nid); |
| |
| // and update state |
| NotifyListener( hWnd ); |
| |
| // check for soffice |
| SetTimer(hWnd, UPDATE_TIMER, 3000, NULL); |
| } |
| break; |
| |
| case MY_TASKBAR_NOTIFICATION: // message from taskbar |
| switch(lParam) |
| { |
| /* |
| case WM_LBUTTONDBLCLK: |
| bTerminateVeto = bTerminateVeto ? false : true; |
| NotifyListener( hWnd ); |
| break; |
| */ |
| |
| case WM_LBUTTONDOWN: |
| case WM_RBUTTONDOWN: |
| { |
| POINT pt; |
| GetCursorPos(&pt); |
| SetForegroundWindow( hWnd ); |
| int m = TrackPopupMenuEx(popupMenu, TPM_RETURNCMD|TPM_LEFTALIGN|TPM_RIGHTBUTTON, |
| pt.x, pt.y, hWnd, NULL); |
| // BUGFIX: See Q135788 (PRB: Menus for Notification Icons Don't Work Correctly) |
| PostMessage(hWnd, NULL, 0, 0); |
| switch(m) |
| { |
| case IDM_QUICKSTART: |
| bTerminateVeto = bTerminateVeto ? false : true; |
| NotifyListener( hWnd ); |
| break; |
| case IDM_ABOUT: |
| DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About); |
| break; |
| case IDM_EXIT: |
| DestroyWindow(hWnd); |
| break; |
| } |
| } |
| break; |
| } |
| break; |
| |
| case WM_TIMER: |
| if( wParam == UPDATE_TIMER ) |
| { |
| // update state |
| NotifyListener( hWnd ); |
| } |
| break; |
| |
| case WM_DESTROY: |
| // try to terminate office |
| SendMessage( HWND_BROADCAST, aTerminateMessage, 0, 0L ); |
| |
| // delete taskbar icon |
| NOTIFYICONDATA nid; |
| nid.cbSize=sizeof(NOTIFYICONDATA); |
| nid.hWnd = hWnd; |
| nid.uID = IDM_QUICKSTART; |
| Shell_NotifyIcon(NIM_DELETE, &nid); |
| |
| PostQuitMessage(0); |
| break; |
| default: |
| return DefWindowProc(hWnd, message, wParam, lParam); |
| } |
| return 0; |
| } |
| |
| // Mesage handler for about box. |
| LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM) |
| { |
| switch (message) |
| { |
| case WM_INITDIALOG: |
| return TRUE; |
| |
| case WM_COMMAND: |
| if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) |
| { |
| EndDialog(hDlg, LOWORD(wParam)); |
| return TRUE; |
| } |
| break; |
| } |
| return FALSE; |
| } |