Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1745 lines
45 KiB

/****************************************************************************
PROGRAM: Telephony Location Manager
PURPOSE:
FUNCTIONS:
****************************************************************************/
#define STRICT
#include "windows.h"
#include "windowsx.h"
#include "shellapi.h"
#include "prsht.h"
#include "dbt.h"
//#include "stdio.h"
#if WINNT
#else
#include "pbt.h"
#endif
#include "tapi.h"
#include "tapitna.h"
#include "clientr.h"
#include "general.h"
#if DBG
#define DBGOUT(arg) DbgPrt arg
VOID
DbgPrt(
IN DWORD dwDbgLevel,
IN PTCHAR DbgMessage,
IN ...
);
#define DOFUNC(arg1,arg2) DoFunc(arg1,arg2)
#else
#define DBGOUT(arg)
#define DOFUNC(arg1,arg2) DoFunc(arg1)
#endif
int WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int );
LRESULT CALLBACK MainWndProc(HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam);
static BOOL InitApplication( void );
static BOOL InitInstance( void );
static HINSTANCE ghInst;
static HWND ghWnd; /* handle to main window */
static const TCHAR gszConfigMe[] = TEXT("ConfigMe");
LPDWORD lpdwLocationIDs = NULL;
TCHAR buf[356];
TCHAR buf2[356];
int i;
//***************************************************************************
//***************************************************************************
//***************************************************************************
//#define TAPI_API_VERSION 0x00020000
#define TAPI_API_VERSION 0x00010004
//***************************************************************************
extern TCHAR gszCurrentProfileKey[];
extern TCHAR gszStaticProfileKey[];
extern TCHAR gszAutoLaunchKey[];
extern TCHAR gszAutoLaunchValue[];
extern TCHAR gszAutoLocationID[];
extern BOOL GetTranslateCaps( LPLINETRANSLATECAPS FAR * pptc);
//***************************************************************************
// Need to keep tapi initialized so that we can get
// location id changes from Xlate dialog (or lineSetCurrentLocation()...)
HLINEAPP ghLineApp = 0;
//DWORD gdwTapiAPIVersion = 0;
//***************************************************************************
//***************************************************************************
//***************************************************************************
//***************************************************************************
BOOL MachineHasMultipleHWProfiles()
{
DWORD dwDataSize;
DWORD dwDataType;
HKEY hKey;
LONG lResult;
//
// Try to get the friendly name for profile #2. If
// this fails, that means we only have one config,
// so there's no point in confusing the user with
// hotdocking options they can't use...
//
lResult = RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
TEXT("System\\CurrentControlSet\\Control\\IDConfigDB"),
0,
KEY_READ,
&hKey
);
if (ERROR_SUCCESS == lResult)
{
dwDataSize = sizeof(buf);
lResult = RegQueryValueEx(
hKey,
TEXT("FriendlyName0002"),
0,
&dwDataType,
(LPBYTE)buf,
&dwDataSize
);
RegCloseKey( hKey );
}
return ( ERROR_SUCCESS == lResult);
}
//***************************************************************************
//***************************************************************************
//***************************************************************************
LONG SaveNewLocation( DWORD dwNewLocation )
{
HKEY hKey;
DWORD dwTemp;
LONG lResult;
//
// Ok, the user wants to change the location
//
DBGOUT((0, TEXT("SaveNewLocation...")));
{
//
// Update the AutoLocationID entry in the current
// profile config
//
lResult = RegCreateKeyEx(
HKEY_CURRENT_CONFIG,
gszCurrentProfileKey,
0,
TEXT(""),
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
NULL,
&hKey,
&dwTemp
);
if ( 0 == lResult )
{
lResult = RegSetValueEx(
hKey,
gszAutoLocationID,
0,
REG_DWORD,
(LPBYTE)&dwNewLocation,
sizeof(DWORD)
);
RegCloseKey( hKey );
}
}
return lResult;
}
//***************************************************************************
//***************************************************************************
//***************************************************************************
VOID PASCAL TapiCallbackProc( DWORD hDevice, DWORD dwMsg, DWORD dwCallbackInstance,
DWORD dwParam1, DWORD dwParam2, DWORD dwParam3 )
{
TCHAR buf[256];
//{
//char buf[100];
//wsprintf(buf, "dwMsg=0x%08lx dwParam1=0x%08lx dwParam2=0x%08lx dwParam3=0x%08lx",
// dwMsg, dwParam1, dwParam2, dwParam3 );
//MessageBox(GetFocus(), buf, "LINEDEVSTATE", MB_OK);
//}
//
// Since we don't bother doing a negotiate (like, cause if there are no
// devices, we _can't_, so why bother at all?), we use the 1.4 cheat of
// looking at dwParam2 and dwParam3 on a REINIT for the real dwMsg and
// dwParam1
//
if (
(dwMsg == LINE_LINEDEVSTATE)
&&
(dwParam1 == LINEDEVSTATE_REINIT)
)
{
if (
(dwParam2 == LINE_LINEDEVSTATE)
&&
(dwParam3 == LINEDEVSTATE_TRANSLATECHANGE)
)
{
LPLINETRANSLATECAPS ptc;
DBGOUT((0,TEXT("XlateChange!!")));
if ( GetTranslateCaps(&ptc) )
{
SaveNewLocation( ptc->dwCurrentLocationID );
GlobalFreePtr(ptc);
}
}
else
if (
(dwParam2 == 0)
&&
(dwParam3 == 0)
)
{
LONG lResult=1;
UINT nTooManyTries;
DWORD dwNumDevs;
DBGOUT((0,TEXT("Reinit!!")));
lineShutdown( ghLineApp );
LoadString( ghInst,
IDS_CAPTION,
buf,
sizeof(buf) );
for ( nTooManyTries=0;
(nTooManyTries<500) && (lResult != 0);
nTooManyTries++)
{
Sleep(1000);
lResult = lineInitialize( &ghLineApp,
ghInst,
// use the MainWndProc as the callback
// cause we're gonna ignore all of the
// messages anyway...
(LINECALLBACK) TapiCallbackProc,
(LPCSTR) buf,
&dwNumDevs
);
}
}
}
}
//***************************************************************************
//***************************************************************************
//***************************************************************************
void ChangeTapiLocation( UINT nCallersFlag )
{
HKEY hKey;
DWORD dwNewLocationID;
DWORD dwSize = sizeof(dwNewLocationID);
DWORD dwType;
DWORD dwMyFlags = 0;
LONG lResult;
//
// read our flags
//
lResult = RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
gszAutoLaunchKey,
0,
KEY_ALL_ACCESS,
&hKey
);
if (ERROR_SUCCESS == lResult)
{
RegQueryValueEx(
hKey,
TEXT("AutoLaunchFlags"),
0,
&dwType,
(LPBYTE)&dwMyFlags,
&dwSize
);
RegCloseKey( hKey );
}
//
// If the user doesn't want to get involved,
// let's get out now.
//
if ( 0 == (dwMyFlags & nCallersFlag) )
{
return;
}
lResult = RegOpenKeyEx(
HKEY_CURRENT_CONFIG,
gszCurrentProfileKey,
0,
KEY_ALL_ACCESS,
&hKey
);
if ( ERROR_SUCCESS == lResult )
{
dwSize = sizeof(dwNewLocationID);
lResult = RegQueryValueEx(
hKey,
gszAutoLocationID,
0,
&dwType,
(LPBYTE)&dwNewLocationID,
&dwSize
);
}
#if DBG
else
{
MessageBox( GetFocus(), TEXT("...and there's no key"), TEXT("Config changed"), MB_OK);
}
#endif
//
// Did we find the key\value?
//
if ( ERROR_SUCCESS == lResult )
{
LONG lTranslateCapsResult;
LPLINETRANSLATECAPS ptc;
//
// Ok, the user wants to change the location
//
lTranslateCapsResult = GetTranslateCaps(&ptc);
//
// If the location to be set to is the same as the
// current, do nothing.
//
if ( ptc &&
ptc->dwCurrentLocationID != dwNewLocationID )
{
//
// Check flag - should we confirm with user?
//
if ( dwMyFlags & FLAG_PROMPTAUTOLOCATIONID )
{
}
DBGOUT((0, TEXT("ChangeLocation...")));
lineSetCurrentLocation( ghLineApp, dwNewLocationID );
DBGOUT((0,TEXT("Done.")));
//
// Should we tell the user what we've done?
//
if ( dwMyFlags & FLAG_ANNOUNCEAUTOLOCATIONID )
{
LPTSTR pstrOldLocation = NULL;
LPTSTR pstrNewLocation = NULL;
//FEATUREFEATURE Tell the user from what location and to what location
if ( lTranslateCapsResult )
{
DWORD i;
LPLINELOCATIONENTRY ple;
DWORD dwCurLocID = ptc->dwCurrentLocationID;
DWORD dwNumLocations = ptc->dwNumLocations;
//
// Allocate an array of DWORDs. This will allow us
// to map the menuID to the TAPI perm provider ID.
//
lpdwLocationIDs = GlobalAllocPtr( GMEM_FIXED, sizeof(DWORD)*dwNumLocations );
//
// Put each location in the menu. When we hit the
// "current" location, put a check next to it.
//
ple = (LPLINELOCATIONENTRY)((LPBYTE)ptc + ptc->dwLocationListOffset);
for (i = 0; i < dwNumLocations; i++, ple++)
{
if (ptc->dwCurrentLocationID ==
ple->dwPermanentLocationID)
{
pstrOldLocation = (LPTSTR)((LPBYTE)ptc +
ple->dwLocationNameOffset);
}
if (dwNewLocationID ==
ple->dwPermanentLocationID)
{
pstrNewLocation = (LPTSTR)((LPBYTE)ptc +
ple->dwLocationNameOffset);
}
}
}
//
// If the location has since been deleted, we should
// say something about it.
//
if (
(NULL == pstrOldLocation)
||
(NULL == pstrNewLocation)
)
{
LoadString( ghInst,
IDS_CANTFINDLOCATIONID,
buf2,
sizeof(buf2) );
wsprintf( buf,
buf2,
dwNewLocationID
);
}
else
{
LoadString( ghInst,
IDS_LOCATIONCHANGED,
buf2,
sizeof(buf2) );
wsprintf( buf,
buf2,
pstrOldLocation,
pstrNewLocation );
}
// We're done using buf2, so reuse it.
LoadString( ghInst,
IDS_CAPTION,
buf2,
sizeof(buf2) );
MessageBox(
NULL, //GetFocus(),
buf,
buf2, // caption
MB_OK
);
}
GlobalFreePtr(ptc);
}
}
else
{
#if DBG
MessageBox( GetFocus(), TEXT("...and there's no key (or value)"), TEXT("Config changed"), MB_OK);
#endif
}
}
//***************************************************************************
//***************************************************************************
//***************************************************************************
PTSTR SkipSpaces( PTSTR const ptStr )
{
PTSTR pStr = ptStr;
while ( *pStr && (*pStr == ' ' ) )
{
pStr++;
}
return pStr;
}
//***************************************************************************
//***************************************************************************
//***************************************************************************
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
// int nResult = 1;
// UINT nSwitchLen;
TCHAR *pCommandLine;
TCHAR *pCommandLineSave;
// TCHAR *pLastStart;
DWORD dwParmLocationID;
LONG lResult;
BOOL fDieNow = FALSE;
DWORD dwCommandLineLength;
TCHAR buf[256];
DBGOUT((0, TEXT("Main...")));
ghInst = GetModuleHandle(0);
if (InitApplication() == 0)
{
return (FALSE);
}
if (InitInstance() == 0)
{
return (FALSE);
}
{
DWORD dwNumDevs;
LoadString( ghInst,
IDS_CAPTION,
buf,
sizeof(buf) );
//
// We initialize TAPI and we never shutdown (except to reinit) so
// we get notifications if someone changes the location from
// the Dialing Properties dialog.
//
lineInitialize( &ghLineApp,
ghInst,
// use the MainWndProc as the callback
// cause we're gonna ignore all of the
// messages anyway...
(LINECALLBACK) TapiCallbackProc,
(LPCSTR) buf,
&dwNumDevs
);
}
//----------------------
// //
// // If the user wants it, startup in the config dialog
// // But we'll only do this if there is more than one HW config...
// //
// if ( MachineHasMultipleHWProfiles() )
// {
// //
// // (We do a bunch of stuff "manually" here so we don't have to
// // drag in the entire MSVCRT20 for this one function...)
// //
// nSwitchLen = lstrlen(gszConfigMe);
//
// //
// // 'pLastStart' is the last possible char the string could start on
// //
// pLastStart = pCommandLine + 1 + (lstrlen(pCommandLine) - nSwitchLen);
//
// for ( ; pCommandLine < pLastStart; pCommandLine++)
// {
// //
// // Do a hack so we can use lstrcmpi
// //
// TCHAR c;
//
// c = pCommandLine[nSwitchLen];
// pCommandLine[nSwitchLen] = '\0';
//
// nResult = lstrcmpi( (LPSTR)pCommandLine, gszConfigMe );
//
// pCommandLine[nSwitchLen] = c;
//
// if (0 == nResult)
// {
// break;
// }
// }
//
// //
// // Did we find our string?
// //
// if ( 0 == nResult )
// {
// PostMessage(ghWnd, WM_COMMAND, IDM_PROPERTIES, 0);
// }
// }
//----------------------
dwCommandLineLength = (lstrlen( GetCommandLine() ) + 1) * sizeof(TCHAR);
pCommandLine = LocalAlloc( LPTR, dwCommandLineLength );
pCommandLineSave = pCommandLine; // We'll need this later to free it...
lstrcpy( pCommandLine, GetCommandLine() );
while ( *pCommandLine )
{
//
// Is this an arg?
//
if (
('-' == *pCommandLine)
||
('/' == *pCommandLine)
)
{
TCHAR c;
//
// Figger out what the arg is
//
pCommandLine = SkipSpaces( pCommandLine + 1 );
//
// Just looking?
//
if (
('?' == *pCommandLine)
||
('H' == *pCommandLine)
||
('h' == *pCommandLine)
)
{
LoadString( ghInst,
IDS_HELP,
buf,
sizeof(buf) );
LoadString( ghInst,
IDS_CAPTION,
buf2,
sizeof(buf2) );
MessageBox(GetFocus(), buf, buf2, MB_OK);
// MessageBox(NULL, buf, buf2, MB_OK);
//
// Ok, now that we're leaving, we can shut this down...
//
fDieNow = TRUE;
}
//
// Is this a location die-now request?
//
if (
('X' == *pCommandLine)
||
('x' == *pCommandLine)
)
{
fDieNow = TRUE;
}
//
// Is this a location ID?
//
if (
('I' == *pCommandLine)
||
('i' == *pCommandLine)
)
{
pCommandLine = SkipSpaces( pCommandLine + 1 );
dwParmLocationID = 0;
//
// get digits
//
while (
(*pCommandLine >= '0')
&&
(*pCommandLine <= '9')
)
{
dwParmLocationID = ( dwParmLocationID * 10 ) +
(*pCommandLine - '0');
pCommandLine++;
}
//
// Now set the current location to the ID we just gathered
//
lResult = lineSetCurrentLocation( ghLineApp, dwParmLocationID );
if ( 0 == lResult )
lResult = SaveNewLocation( dwParmLocationID );
if ( 0 != lResult )
{
LoadString( ghInst,
IDS_CANTFINDLOCATIONID,
buf2,
sizeof(buf2) );
wsprintf( buf, buf2, dwParmLocationID);
LoadString( ghInst,
IDS_CAPTION,
buf2,
sizeof(buf2) );
//
// Messagebox to tell the user what happened
//
MessageBox(
NULL,
buf,
buf2,
MB_OK | MB_ICONERROR
);
}
}
//
// Is this a location name?
//
if (
('N' == *pCommandLine)
||
('n' == *pCommandLine)
)
{
LPLINETRANSLATECAPS ptc;
PTSTR pszMyString;
PTSTR pszMyStringPointer;
pCommandLine = SkipSpaces( pCommandLine + 1 );
//
// We'll never need more than the entire command line's len...
// (and that's better than some arbitraty large number)
//
pszMyString = LocalAlloc( LPTR, dwCommandLineLength );
if (pszMyString == NULL)
{
return (FALSE);
}
pszMyStringPointer = pszMyString;
pCommandLine = SkipSpaces( pCommandLine );
while (
(*pCommandLine != '\0')
&&
(*pCommandLine != '/')
&&
(*pCommandLine != '-')
)
{
//
// add this char to the string
//
*pszMyStringPointer = *pCommandLine;
pszMyStringPointer++;
pCommandLine++;
}
//
// First, get back to the last char
//
pszMyStringPointer--;
//
// Now chop off any trailing spaces
//
while (
(' ' == *pszMyStringPointer)
&&
(pszMyStringPointer > pszMyString )
)
{
pszMyStringPointer--;
}
//
// Set the end of the string to be the last non-space in the name
//
*(pszMyStringPointer + 1) = '\0';
if (GetTranslateCaps(&ptc))
{
DWORD i;
LPLINELOCATIONENTRY ple;
DWORD dwCurLocID = ptc->dwCurrentLocationID;
DWORD dwNumLocations = ptc->dwNumLocations;
DBGOUT((0, TEXT("There seem to be %ld locations - ptc=0x%08lx"), dwNumLocations,
ptc));
//
// See if we can find the string...
//
ple = (LPLINELOCATIONENTRY)((LPBYTE)ptc + ptc->dwLocationListOffset);
for (i = 0; i < dwNumLocations; i++, ple++)
{
DBGOUT((0, TEXT("Location #%ld is [%s] at 0x%08lx"),
i,
(LPTSTR)((LPBYTE)ptc + ple->dwLocationNameOffset),
(LPTSTR)((LPBYTE)ptc + ple->dwLocationNameOffset) ));
if ( 0 == lstrcmpi( (LPTSTR)((LPBYTE)ptc + ple->dwLocationNameOffset),
pszMyString
)
)
{
dwParmLocationID = ple->dwPermanentLocationID;
break;
}
}
//
// Did we run the list without finding a match?
//
if ( i == dwNumLocations )
{
LoadString( ghInst,
IDS_CANTFINDLOCATIONNAME,
buf2,
sizeof(buf2) );
wsprintf( buf, buf2, pszMyString );
LoadString( ghInst,
IDS_CAPTION,
buf2,
sizeof(buf2) );
//
// Messagebox to tell the user what happened
//
MessageBox(
NULL,
buf,
buf2,
MB_OK | MB_ICONERROR
);
lResult = LINEERR_INVALLOCATION;
}
else
{
lResult = lineSetCurrentLocation( ghLineApp, dwParmLocationID );
if ( 0 == lResult )
lResult = SaveNewLocation( dwParmLocationID );
}
GlobalFreePtr(ptc);
LocalFree( pszMyString );
}
}
//
// Is this parm "ConfigMe" ?
//
c = pCommandLine[ lstrlen( gszConfigMe ) ];
if ( 0 == lstrcmpi( pCommandLine, gszConfigMe ) )
{
//
// Found this arg.
//
//
// If the user wants it, startup in the config dialog
// But we'll only do this if there is more than one HW config...
//
if ( MachineHasMultipleHWProfiles() )
{
PostMessage( ghWnd, WM_COMMAND, IDM_PROPERTIES, 0 );
}
//
// In either case, get past this arg
//
pCommandLine[ lstrlen( gszConfigMe ) ] = c;
pCommandLine += lstrlen( gszConfigMe );
}
}
else
{
pCommandLine++;
}
}
LocalFree( pCommandLineSave );
//
// Go see if we should auto-update the TAPI location on startup
//
ChangeTapiLocation( FLAG_UPDATEONSTARTUP );
//
// Should we quit before we start?
//
if ( fDieNow )
{
DestroyWindow( ghWnd );
}
while (GetMessage(&msg, 0, 0, 0) != 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
//
// Ok, now that we're leaving, we can shut this down...
lineShutdown( ghLineApp );
return ((int) msg.wParam);
}
/****************************************************************************
FUNCTION: InitApplication(HANDLE)
PURPOSE: Initializes window data and registers window class
****************************************************************************/
static BOOL InitApplication( void )
{
WNDCLASS wc;
wc.style = 0;
wc.lpfnWndProc = MainWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = ghInst;
wc.hIcon = NULL;
wc.hCursor = NULL;
wc.hbrBackground = NULL;
wc.lpszMenuName = NULL;
wc.lpszClassName = TEXT("TLOCMGR_WINCLSS");
return (RegisterClass(&wc));
}
//***************************************************************************
//***************************************************************************
//***************************************************************************
static BOOL InitInstance( void )
{
ghWnd = CreateWindow(
TEXT("TLOCMGR_WINCLSS"),
NULL,
WS_OVERLAPPED | WS_MINIMIZE,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
0,
0,
ghInst,
0 );
if (ghWnd == 0 )
{
return ( FALSE );
}
ShowWindow(ghWnd, SW_HIDE);
#if WINNT
#else
RegisterServiceProcess( 0, RSP_SIMPLE_SERVICE);
#endif
return (TRUE);
}
//***************************************************************************
//***************************************************************************
//***************************************************************************
LRESULT CALLBACK MainWndProc(HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam)
{
HICON hIcon;
static DWORD dwCurrentChoice = 0;
DWORD i;
static NOTIFYICONDATA nid = {
sizeof(NOTIFYICONDATA),
0, //hWnd,
IDI_TAPITNAICON,
NIF_ICON | NIF_MESSAGE | NIF_TIP,
WM_USER+0x42,
0, //hIcon,
0 //pCaption
};
switch ( message )
{
#if WINNT
case WM_POWER:
{
if (
(PWR_SUSPENDRESUME == LOWORD(wParam))
||
(PWR_CRITICALRESUME == LOWORD(wParam))
)
{
DBGOUT((0, TEXT("Power resume(normal or critical)")));
ChangeTapiLocation( FLAG_UPDATEONSTARTUP );
}
}
break;
#else
case WM_POWERBROADCAST:
{
if (
(PBT_APMRESUMESUSPEND == wParam)
||
(PBT_APMRESUMESTANDBY == wParam)
||
(PBT_APMRESUMECRITICAL == wParam)
)
{
DBGOUT((0, TEXT("Power resume(normal or critical)")));
ChangeTapiLocation( FLAG_UPDATEONSTARTUP );
}
}
break;
#endif
case WM_DEVICECHANGE:
{
switch (wParam)
{
// case DBT_DEVICEARRIVAL:
//MessageBox( GetFocus(), "DBT_DEVICEARRIVAL", "WM_DEVICECHANGE", MB_OK);
// break;
//
// case DBT_DEVICEREMOVECOMPLETE:
//MessageBox( GetFocus(), "DBT_DEVICEREMOVECOMPLETE", "WM_DEVICECHANGE", MB_OK);
// break;
//
// case DBT_MONITORCHANGE:
//MessageBox( GetFocus(), "DBT_MONITORCHANGE", "WM_DEVICECHANGE", MB_OK);
//// lParam = new resolution LOWORD=x HIWORD=y
// break;
case DBT_CONFIGCHANGED:
{
DBGOUT((0, TEXT("DBG_CONFIGCHANGED")));
ChangeTapiLocation( FLAG_AUTOLOCATIONID );
}
break;
}
}
break;
case WM_SETTINGCHANGE:
{
//
// Is it something we're interested in?
//
// if ( SPI_SETICONMETRICS == wParam )
{
// hIcon = LoadImage(ghInst,
// MAKEINTRESOURCE(IDI_TAPITNAICON),
// IMAGE_ICON,
// GetSystemMetrics(SM_CXSMICON),
// GetSystemMetrics(SM_CYSMICON),
// 0);
hIcon = LoadImage(ghInst,
MAKEINTRESOURCE(IDI_TAPITNAICON),
IMAGE_ICON,
0,
0,
0);
Shell_NotifyIcon( NIM_MODIFY, &nid );
return 0;
}
// else
// {
// return (DefWindowProc(hWnd, message, wParam, lParam));
// }
}
// break;
case WM_CREATE:
{
//
// Well, we're not gonna create a window, but we can do other
// stuff...
//
LoadString (ghInst, IDS_CAPTION, nid.szTip, sizeof (nid.szTip));
// hIcon = LoadIcon(ghInst, MAKEINTRESOURCE(IDI_TAPITNAICON) );
hIcon = LoadImage(ghInst,
MAKEINTRESOURCE(IDI_TAPITNAICON),
IMAGE_ICON,
0,
0,
// GetSystemMetrics(SM_CXSMICON),
// GetSystemMetrics(SM_CYSMICON),
0);
// IMAGE_ICON, 32, 32, 0);
// IMAGE_ICON, 16, 16, 0);
nid.hWnd = hWnd;
nid.hIcon = hIcon;
// fResult =
Shell_NotifyIcon( NIM_ADD, &nid );
}
break;
case WM_USER+0x42:
{
switch ( lParam )
{
case WM_LBUTTONDOWN:
{
switch ( wParam )
{
case IDI_TAPITNAICON:
{
//
// User is left clicking on our icon.
//
PostMessage(hWnd, WM_COMMAND, IDM_LOCATIONMENU, 0L);
}
break;
default:
break;
}
}
break;
case WM_LBUTTONDBLCLK:
{
PostMessage(hWnd, WM_COMMAND, IDM_DIALINGPROPERTIES, 0L);
}
break;
case WM_RBUTTONDOWN:
{
switch ( wParam )
{
case IDI_TAPITNAICON:
{
//
// User is right clicking on our icon. Now what?
//
//MessageBox(GetFocus(), "RCLICK", "RCLICK", MB_OK);
PostMessage(hWnd, WM_COMMAND, IDM_CONTEXTMENU, 0L);
}
break;
default:
break;
}
}
break;
default:
break;
}
}
break;
case WM_COMMAND:
switch ( wParam )
{
case IDM_ABOUT:
{
LoadString(ghInst, IDS_CAPTION, buf, sizeof(buf));
LoadString(ghInst, IDS_ABOUTTEXT, buf2, sizeof(buf2));
hIcon = LoadIcon(ghInst, MAKEINTRESOURCE(IDI_TAPITNAICON) );
return ShellAbout(hWnd, buf, buf2, hIcon);
}
break;
case IDM_CONTEXTMENU:
{
HMENU popup;
HMENU subpopup;
POINT mousepos;
popup = LoadMenu(ghInst,MAKEINTRESOURCE(IDR_RBUTTONMENU));
if(popup)
{
//
// So? Is there more than one config?
//
if ( !MachineHasMultipleHWProfiles() )
{
//
// Nope, remove the hotdock options. :-(
//
RemoveMenu( popup,
IDM_PROPERTIES,
MF_BYCOMMAND
);
}
subpopup = GetSubMenu(popup, 0);
if (subpopup)
{
SetMenuDefaultItem(subpopup,IDM_DIALINGPROPERTIES,FALSE);
if(GetCursorPos(&mousepos))
{
SetForegroundWindow(ghWnd);
ShowWindow(ghWnd, SW_HIDE);
TrackPopupMenuEx( subpopup,
TPM_LEFTALIGN |
TPM_LEFTBUTTON |
TPM_RIGHTBUTTON,
mousepos.x,
mousepos.y,
ghWnd,
NULL
);
}
RemoveMenu(popup, 0, MF_BYPOSITION);
DestroyMenu(subpopup);
}
DestroyMenu(popup);
}
}
break;
case IDM_LOCATIONMENU:
{
HMENU fakepopup = NULL;
POINT mousepos;
LPLINETRANSLATECAPS ptc;
UINT nPrefixSize;
fakepopup = CreatePopupMenu();
nPrefixSize = LoadString( ghInst,
IDS_SELECTNEWLOCATION,
buf,
sizeof(buf) );
// AppendMenu( fakepopup,
// MF_BYPOSITION | MF_STRING | MF_DISABLED, // | MF_GRAYED,
// 0,
// buf
// );
//
// AppendMenu( fakepopup,
// MF_BYPOSITION | MF_STRING | MF_SEPARATOR,
// 0,
// 0
// );
if (GetTranslateCaps(&ptc))
{
LPLINELOCATIONENTRY ple;
DWORD dwCurLocID = ptc->dwCurrentLocationID;
DWORD dwNumLocations = ptc->dwNumLocations;
DBGOUT((0, TEXT("There seem to be %ld locations - ptc=0x%08lx"), dwNumLocations,
ptc));
//
// Allocate an array of DWORDs. This will allow us
// to map the menuID to the TAPI perm provider ID.
//
lpdwLocationIDs = GlobalAllocPtr( GMEM_FIXED, sizeof(DWORD)*dwNumLocations );
//
// Put each location in the menu. When we hit the
// "current" location, put a check next to it.
//
ple = (LPLINELOCATIONENTRY)((LPBYTE)ptc + ptc->dwLocationListOffset);
for (i = 0; i < dwNumLocations; i++, ple++)
{
lpdwLocationIDs[i] = ple->dwPermanentLocationID;
//
// Now make a proper displayable string
lstrcpy( &buf[nPrefixSize],
(LPTSTR)((LPBYTE)ptc + ple->dwLocationNameOffset)
);
AppendMenu( fakepopup,
MF_BYPOSITION |
MF_STRING |
MF_ENABLED |
((dwCurLocID == ple->dwPermanentLocationID) ?
MF_CHECKED : 0),
IDM_LOCATION0+i,
buf
);
DBGOUT((0, TEXT("Location #%ld is [%s] at 0x%08lx"),
i,
(LPTSTR)((LPBYTE)ptc + ple->dwLocationNameOffset),
(LPTSTR)((LPBYTE)ptc + ple->dwLocationNameOffset) ));
if (dwCurLocID == ple->dwPermanentLocationID)
{
dwCurrentChoice = IDM_LOCATION0+i;
}
}
GlobalFreePtr(ptc);
}
else
{
DBGOUT((0, TEXT("Gettranscaps failed")));
}
if (fakepopup)
{
// SetMenuDefaultItem(fakepopup,0,MF_BYPOSITION);
GetCursorPos(&mousepos);
SetForegroundWindow(ghWnd);
ShowWindow(ghWnd, SW_HIDE);
TrackPopupMenu(fakepopup, TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON , mousepos.x, mousepos.y-20, 0, ghWnd, NULL);
DestroyMenu(fakepopup);
}
// {
// subpopup = GetSubMenu(fakepopup, 0);
//
// //put a check next to the current location
//
// SetMenuDefaultItem(subpopup,0,MF_BYPOSITION);
// if(GetCursorPos(&mousepos))
// {
// SetForegroundWindow(ghWnd);
// TrackPopupMenuEx(subpopup, TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON ,mousepos.x,mousepos.y,ghWnd,NULL);
// }
// RemoveMenu(popup, 0, MF_BYPOSITION);
// DestroyMenu(fakepopup);
// DestroyMenu(popup);
// DestroyMenu(subpopup);
// }
}
break;
case IDM_DIALINGPROPERTIES:
{
{
lineTranslateDialog(ghLineApp, 0, TAPI_API_VERSION, ghWnd, NULL);
ShowWindow( ghWnd, SW_HIDE );
// lineTranslateDialog(ghLineApp, 0, TAPI_API_VERSION, GetFocus(), NULL);
}
}
break;
case IDM_PROPERTIES:
{
#ifdef NASHVILLE_BUILD_FLAG
// Should we just hack into the TAPI dialing properties?
#else
HPROPSHEETPAGE rPages[1];
PROPSHEETPAGE psp;
PROPSHEETHEADER psh;
//
// Let's configure TAPITNA
//
psh.dwSize = sizeof(psh);
psh.dwFlags = PSH_DEFAULT; //PSH_NOAPPLYNOW;
psh.hwndParent = GetFocus(); //NULL; //hwnd;
psh.hInstance = ghInst;
LoadString(ghInst, IDS_CAPTION, buf, sizeof(buf)/sizeof(TCHAR));
psh.pszCaption = buf;
psh.nPages = 0;
psh.nStartPage = 0;
psh.phpage = rPages;
psp.dwSize = sizeof(psp);
psp.dwFlags = PSP_DEFAULT;
psp.hInstance = ghInst;
psp.pszTemplate = MAKEINTRESOURCE(IDD_GENERAL);
psp.pfnDlgProc = (DLGPROC) GeneralDlgProc;
psp.lParam = 0;
psh.phpage[psh.nPages] = CreatePropertySheetPage (&psp);
if (psh.phpage[psh.nPages])
{
psh.nPages++;
}
PropertySheet (&psh);
#endif
}
break;
// case IDM_OTHERMENUITEM:
// {
// }
// break;
case IDM_LAUNCHDIALER:
{
ShellExecute( ghWnd,
NULL,
TEXT("Dialer.exe"),
NULL,
NULL,
SW_SHOWDEFAULT);
}
break;
case IDM_CLOSEIT:
{
DestroyWindow(ghWnd);
}
break;
default:
{
//
// Ok, we actually have to do work in this default.
// If the user has the location menu open and selects one,
// we deal with it here (instead of having 100 case
// statements). This is the limitation: 100 locations is
// the max we put up with (would that many even display?).
//
if (
(wParam >= IDM_LOCATION0)
&&
(wParam <= IDM_LOCATION0 + 100)
)
{
//
// Ok, set this to be the new current location
//
// there's a bug in TAPI - either the docs or the code, but the following
// _should_ work but doesn't...
// lineSetCurrentLocation(NULL, currentlocation);
//
// If the user is selecting the same location,
// do nothing.
//
if ( dwCurrentChoice == wParam )
{
}
else
{
i = lineSetCurrentLocation( ghLineApp,
lpdwLocationIDs[wParam-IDM_LOCATION0] );
if ( 0 == i )
SaveNewLocation( lpdwLocationIDs[wParam-IDM_LOCATION0] );
}
GlobalFreePtr( lpdwLocationIDs );
return( TRUE );
}
else
{
return (DefWindowProc(hWnd, message, wParam, lParam));
}
}
break;
}
break;
case WM_DESTROY:
Shell_NotifyIcon( NIM_DELETE, &nid );
PostQuitMessage(0);
break;
#if WINNT
#else
case WM_ENDSESSION:
if (wParam) {
RegisterServiceProcess( 0, RSP_UNREGISTER_SERVICE);
DestroyWindow(hWnd);
}
#endif
default:
return (DefWindowProc(hWnd, message, wParam, lParam));
}
return (FALSE);
}
//{
//char buf[100];
//wsprintf(buf, "GetActiveWindwow() = 0x%08lx", (DWORD) GetActiveWindow());
//OutputDebugString(buf);
//}
//{
//char buf[60];
//wsprintf (buf, "fResult = 0x%08lx",
// fResult);
//MessageBox(GetFocus(), buf, "", MB_OK);
//}
#if DBG
#include "stdarg.h"
#include "stdio.h"
VOID
DbgPrt(
IN DWORD dwDbgLevel,
IN PTCHAR lpszFormat,
IN ...
)
/*++
Routine Description:
Formats the incoming debug message & calls DbgPrint
Arguments:
DbgLevel - level of message verboseness
DbgMessage - printf-style format string, followed by appropriate
list of arguments
Return Value:
--*/
{
static DWORD gdwDebugLevel = 0; //HACKHACK
if (dwDbgLevel <= gdwDebugLevel)
{
TCHAR buf[256] = TEXT("TLOCMGR: ");
va_list ap;
va_start(ap, lpszFormat);
wvsprintf (&buf[8],
lpszFormat,
ap
);
lstrcat(buf, TEXT("\n"));
OutputDebugString(buf);
va_end(ap);
}
}
#endif