blob: 6dfac4b467dd4f39090f4fa62497eba7f43639f6 [file] [log] [blame]
/**************************************************************
*
* 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;
}