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.
1508 lines
37 KiB
1508 lines
37 KiB
/**
|
|
|
|
Copyright (c) Microsoft Corporation 1999-2000
|
|
|
|
Module Name:
|
|
|
|
monitor.cpp
|
|
|
|
Abstract:
|
|
|
|
This module implements the fax monitor dialog.
|
|
|
|
**/
|
|
|
|
|
|
#include <windows.h>
|
|
#include <faxreg.h>
|
|
#include <faxutil.h>
|
|
#include <fxsapip.h>
|
|
#include <commctrl.h>
|
|
#include <tchar.h>
|
|
#include <DebugEx.h>
|
|
|
|
#include <list>
|
|
using namespace std;
|
|
|
|
#include "monitor.h"
|
|
#include "resource.h"
|
|
|
|
#define DURATION_TIMER_RESOLUTION 500 // Resolution (millisecs) of duration text update timer
|
|
|
|
//////////////////////////////////////////////////////////////
|
|
// Global data
|
|
//
|
|
|
|
extern HINSTANCE g_hModule; // DLL Global instance
|
|
extern HINSTANCE g_hResource; // Resource DLL handle
|
|
extern HANDLE g_hFaxSvcHandle;
|
|
extern DWORD g_dwCurrentJobID;
|
|
extern CONFIG_OPTIONS g_ConfigOptions;
|
|
extern TCHAR g_szRemoteId[MAX_PATH]; // Sender ID or Recipient ID
|
|
extern HCALL g_hCall; // Handle to call (from FAX_EVENT_TYPE_NEW_CALL)
|
|
//
|
|
// Events log
|
|
//
|
|
|
|
struct EVENT_ENTRY
|
|
{
|
|
eIconType eIcon; // Event icon
|
|
TCHAR tszTime[30]; // Event time string
|
|
TCHAR tszEvent[MAX_PATH]; // Event string
|
|
};
|
|
|
|
typedef EVENT_ENTRY *PEVENT_ENTRY;
|
|
|
|
typedef list<EVENT_ENTRY> EVENTS_LIST, *PEVENTS_LIST;
|
|
|
|
EVENTS_LIST g_lstEvents; // Global list of events
|
|
|
|
#define MAX_EVENT_LIST_SIZE 50 // Maximal number of events in log
|
|
|
|
//
|
|
// Monitor dialog
|
|
//
|
|
HWND g_hMonitorDlg = NULL;
|
|
|
|
//
|
|
// Controls
|
|
//
|
|
HWND g_hStatus = NULL; // Status line (static text)
|
|
HWND g_hElapsedTime = NULL; // Elapsed time line (static text)
|
|
HWND g_hToFrom = NULL; // To/From line (static text)
|
|
HWND g_hListDetails = NULL; // Details list control
|
|
HWND g_hAnimation = NULL; // Animation control
|
|
HWND g_hDisconnect = NULL; // Disconnect button
|
|
|
|
HICON g_hDlgIcon = NULL; // Dialog main icon
|
|
HIMAGELIST g_hDlgImageList = NULL; // Dialog's image list
|
|
|
|
//
|
|
// Data
|
|
//
|
|
BOOL g_bAnswerNow = FALSE; // TRUE if the dialog button shows 'Answer Now'. FALSE if it shows 'Disconnect'.
|
|
DWORD g_dwHeightDelta = 0; // Used when pressing "More >>>" / "Less <<<" to resize the dialog
|
|
DWORD g_dwDlgHeight = 0; // The dialog height
|
|
BOOL g_bDetails = FALSE; // Is the "More >>>" button pressed?
|
|
DeviceState g_devState = FAX_IDLE; // Current fax state (animation)
|
|
DWORD g_dwStartTime = 0; // Activity start time (tick counts)
|
|
UINT_PTR g_nElapsedTimerId = 0; // Timer id for elapsed time (ticks every 1 second)
|
|
TCHAR g_tszTimeSeparator[5] = {0};
|
|
DWORD g_dwCurrentAnimationId = 0; // Current animation resource ID
|
|
TCHAR g_tszLastEvent[MAX_PATH] = {0}; // The last event string
|
|
POINT g_ptPosition = {-1, -1}; // Dialog position
|
|
BOOL g_bTopMost = FALSE; // Is the monitor dialog always visible?
|
|
|
|
#define DETAILS_TIME_COLUMN_WIDTH 90
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// Function prototypes
|
|
//
|
|
|
|
// public
|
|
BOOL IsUserGrantedAccess(DWORD);
|
|
DWORD OpenFaxMonitor(VOID);
|
|
void SetStatusMonitorDeviceState(DeviceState devState);
|
|
void OnDisconnect();
|
|
void FreeMonitorDialogData (BOOL bShutdown);
|
|
|
|
// Private
|
|
INT_PTR CALLBACK FaxMonitorDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
|
VOID CALLBACK ElapsedTimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime);
|
|
|
|
void InitMonitorDlg(HWND hDlg);
|
|
DWORD UpdateMonitorData(HWND hDlg);
|
|
void AddEventToView(PEVENT_ENTRY pEvent);
|
|
void OnAlwaysOnTop(HWND hDlg);
|
|
void OnDetailsButton(HWND hDlg, BOOL bDetails);
|
|
void OnClearLog();
|
|
int FaxMessageBox(HWND hWnd, DWORD dwTextID, UINT uType);
|
|
DWORD RefreshImageList ();
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// Implementation
|
|
//
|
|
|
|
void
|
|
FreeMonitorDialogData (
|
|
BOOL bShutdown /* = FALSE */
|
|
)
|
|
/*++
|
|
|
|
Routine name : FreeMonitorDialogData
|
|
|
|
Routine description:
|
|
|
|
Frees up all the data allocated by the monitor module
|
|
|
|
Author:
|
|
|
|
Eran Yariv (EranY), Mar, 2001
|
|
|
|
Arguments:
|
|
|
|
bShutdown - [in] TRUE only is the module is shutting down.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
{
|
|
DWORD dwRes = ERROR_SUCCESS;
|
|
DBG_ENTER(TEXT("FreeMonitorDialogData"), dwRes);
|
|
|
|
RECT rc = {0};
|
|
if(GetWindowRect(g_hMonitorDlg, &rc))
|
|
{
|
|
g_ptPosition.x = rc.left;
|
|
g_ptPosition.y = rc.top;
|
|
}
|
|
|
|
|
|
g_hMonitorDlg = NULL;
|
|
|
|
g_hStatus = NULL;
|
|
g_hElapsedTime = NULL;
|
|
g_hToFrom = NULL;
|
|
g_hListDetails = NULL;
|
|
g_hDisconnect = NULL;
|
|
g_hAnimation = NULL;
|
|
g_dwCurrentAnimationId = 0;
|
|
|
|
if (g_hDlgImageList)
|
|
{
|
|
ImageList_Destroy (g_hDlgImageList);
|
|
g_hDlgImageList = NULL;
|
|
}
|
|
if (bShutdown)
|
|
{
|
|
//
|
|
// DLL is shutting down.
|
|
//
|
|
|
|
//
|
|
// The icon is cached in memory even when the dialog is closed.
|
|
// This is a good time to free it.
|
|
//
|
|
if(g_nElapsedTimerId)
|
|
{
|
|
if (!KillTimer(NULL, g_nElapsedTimerId))
|
|
{
|
|
CALL_FAIL (GENERAL_ERR, TEXT("KillTimer"), GetLastError ());
|
|
}
|
|
g_nElapsedTimerId = NULL;
|
|
}
|
|
|
|
if (g_hDlgIcon)
|
|
{
|
|
if (!DestroyIcon (g_hDlgIcon))
|
|
{
|
|
CALL_FAIL (WINDOW_ERR, TEXT("DestroyIcon"), GetLastError ());
|
|
}
|
|
g_hDlgIcon = NULL;
|
|
}
|
|
//
|
|
// Also delete all the events from the list
|
|
//
|
|
try
|
|
{
|
|
g_lstEvents.clear();
|
|
}
|
|
catch (exception &ex)
|
|
{
|
|
VERBOSE (MEM_ERR,
|
|
TEXT("Got an STL exception while clearing the events list (%S)"),
|
|
ex.what());
|
|
}
|
|
|
|
g_ptPosition.x = -1;
|
|
g_ptPosition.y = -1;
|
|
}
|
|
} // FreeMonitorDialogData
|
|
|
|
|
|
INT_PTR
|
|
CALLBACK
|
|
FaxMonitorDlgProc(
|
|
HWND hwndDlg, // handle to dialog box
|
|
UINT uMsg, // message
|
|
WPARAM wParam, // first message parameter
|
|
LPARAM lParam // second message parameter
|
|
)
|
|
/*++
|
|
|
|
Routine description:
|
|
|
|
fax monitor dialog procedure
|
|
|
|
Arguments:
|
|
|
|
HWND hwndDlg, // handle to dialog box
|
|
UINT uMsg, // message
|
|
WPARAM wParam, // first message parameter
|
|
LPARAM lParam // second message parameter
|
|
|
|
Return Value:
|
|
|
|
return TRUE if it processed the message
|
|
|
|
--*/
|
|
|
|
{
|
|
switch ( uMsg )
|
|
{
|
|
case WM_INITDIALOG:
|
|
InitMonitorDlg(hwndDlg);
|
|
return TRUE;
|
|
|
|
case WM_DESTROY:
|
|
FreeMonitorDialogData ();
|
|
return TRUE;
|
|
|
|
case WM_COMMAND:
|
|
switch(LOWORD(wParam))
|
|
{
|
|
case IDC_DETAILS:
|
|
g_bDetails = !g_bDetails;
|
|
OnDetailsButton(hwndDlg, g_bDetails);
|
|
return TRUE;
|
|
|
|
case IDC_ALWAYS_ON_TOP:
|
|
OnAlwaysOnTop(hwndDlg);
|
|
return TRUE;
|
|
|
|
case IDC_CLEAR_LOG:
|
|
OnClearLog();
|
|
return TRUE;
|
|
|
|
case IDC_DISCONNECT:
|
|
OnDisconnect();
|
|
return TRUE;
|
|
|
|
case IDCANCEL:
|
|
DestroyWindow( hwndDlg );
|
|
return TRUE;
|
|
|
|
} // switch(LOWORD(wParam))
|
|
|
|
break;
|
|
|
|
case WM_HELP:
|
|
WinHelpContextPopup(((LPHELPINFO)lParam)->dwContextId, hwndDlg);
|
|
return TRUE;
|
|
|
|
case WM_CONTEXTMENU:
|
|
WinHelpContextPopup(GetWindowContextHelpId((HWND)wParam), hwndDlg);
|
|
return TRUE;
|
|
|
|
case WM_SYSCOLORCHANGE:
|
|
RefreshImageList ();
|
|
return TRUE;
|
|
|
|
} // switch ( uMsg )
|
|
return FALSE;
|
|
} // FaxMonitorDlgProc
|
|
|
|
DWORD
|
|
RefreshImageList ()
|
|
/*++
|
|
|
|
Routine name : RefreshImageList
|
|
|
|
Routine description:
|
|
|
|
Refreshes the image list and list view background color
|
|
|
|
Author:
|
|
|
|
Eran Yariv (EranY), May, 2001
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
Standard Win32 error code
|
|
|
|
--*/
|
|
{
|
|
DWORD dwRes = ERROR_SUCCESS;
|
|
DBG_ENTER(TEXT("RefreshImageList"), dwRes);
|
|
ListView_SetExtendedListViewStyle(g_hListDetails,
|
|
LVS_EX_FULLROWSELECT | LVS_EX_INFOTIP | LVS_EX_ONECLICKACTIVATE);
|
|
|
|
if (NULL != g_hDlgImageList)
|
|
{
|
|
ImageList_Destroy (g_hDlgImageList);
|
|
g_hDlgImageList = NULL;
|
|
}
|
|
g_hDlgImageList = ImageList_Create (16, 16, ILC_COLOR8, 4, 0);
|
|
if(!g_hDlgImageList)
|
|
{
|
|
dwRes = GetLastError();
|
|
CALL_FAIL (WINDOW_ERR, TEXT("ImageList_Create"), dwRes);
|
|
return dwRes;
|
|
}
|
|
HBITMAP hBmp = (HBITMAP) LoadImage (
|
|
g_hModule,
|
|
MAKEINTRESOURCE(IDB_LIST_IMAGES),
|
|
IMAGE_BITMAP,
|
|
0,
|
|
0,
|
|
LR_DEFAULTSIZE | LR_LOADTRANSPARENT);
|
|
if (!hBmp)
|
|
{
|
|
dwRes = GetLastError();
|
|
CALL_FAIL (WINDOW_ERR, TEXT("LoadBitmap"), dwRes);
|
|
ImageList_Destroy (g_hDlgImageList);
|
|
g_hDlgImageList = NULL;
|
|
return dwRes;
|
|
}
|
|
ImageList_Add (g_hDlgImageList, hBmp, NULL);
|
|
//
|
|
// ImageList_Add creates a copy of the bitmap - it's now safe to delete it
|
|
//
|
|
::DeleteObject ((HGDIOBJ)hBmp);
|
|
ListView_SetImageList(g_hListDetails, g_hDlgImageList, LVSIL_SMALL);
|
|
ListView_SetBkColor (g_hListDetails, ::GetSysColor(COLOR_WINDOW));
|
|
return dwRes;
|
|
} // RefreshImageList
|
|
|
|
void
|
|
InitMonitorDlg(
|
|
HWND hDlg
|
|
)
|
|
/*++
|
|
|
|
Routine description:
|
|
|
|
Initialize fax monitor dialog
|
|
|
|
Arguments:
|
|
|
|
hDlg [in] - fax monitor dialog handle
|
|
|
|
Return Value:
|
|
|
|
none
|
|
|
|
--*/
|
|
{
|
|
DWORD dwRes = ERROR_SUCCESS;
|
|
DBG_ENTER(TEXT("InitMonitorDlg"), dwRes);
|
|
|
|
//
|
|
// Set the dialog icon
|
|
//
|
|
if (NULL == g_hDlgIcon)
|
|
{
|
|
//
|
|
// 1st time the dialog is opened - load the icons
|
|
//
|
|
g_hDlgIcon = LoadIcon(g_hModule, MAKEINTRESOURCE(IDI_FAX_MONITOR));
|
|
if(!g_hDlgIcon)
|
|
{
|
|
dwRes = GetLastError();
|
|
CALL_FAIL (WINDOW_ERR, TEXT ("LoadIcon"), dwRes);
|
|
return;
|
|
}
|
|
}
|
|
SendMessage(hDlg, WM_SETICON, ICON_BIG, (LPARAM)g_hDlgIcon);
|
|
SendMessage(hDlg, WM_SETICON, ICON_SMALL, (LPARAM)g_hDlgIcon);
|
|
//
|
|
// Calculate the height of the details part
|
|
//
|
|
RECT rcList, rcDialog;
|
|
if(!GetWindowRect(hDlg, &rcDialog))
|
|
{
|
|
dwRes = GetLastError();
|
|
CALL_FAIL (WINDOW_ERR, TEXT ("GetWindowRect"), dwRes);
|
|
return;
|
|
}
|
|
g_dwDlgHeight = rcDialog.bottom - rcDialog.top;
|
|
|
|
g_hListDetails = GetDlgItem(hDlg, IDC_LIST_DETAILS);
|
|
ASSERTION (g_hListDetails);
|
|
|
|
if(!GetWindowRect(g_hListDetails, &rcList))
|
|
{
|
|
dwRes = GetLastError();
|
|
CALL_FAIL (WINDOW_ERR, TEXT ("GetWindowRect"), dwRes);
|
|
return;
|
|
}
|
|
|
|
g_dwHeightDelta = rcDialog.bottom - rcList.top;
|
|
|
|
//
|
|
// Shrink down to small size (initially)
|
|
//
|
|
OnDetailsButton(hDlg, g_bDetails);
|
|
|
|
//
|
|
// Init the list view
|
|
//
|
|
RefreshImageList ();
|
|
//
|
|
// Add time column
|
|
//
|
|
TCHAR tszHeader[MAX_PATH];
|
|
|
|
LVCOLUMN lvColumn = {0};
|
|
lvColumn.mask = LVCF_TEXT | LVCF_WIDTH;
|
|
lvColumn.cx = DETAILS_TIME_COLUMN_WIDTH;
|
|
lvColumn.pszText = tszHeader;
|
|
|
|
if (ERROR_SUCCESS != (dwRes = LoadAndFormatString (IDS_DETAIL_TIME_HEADER, tszHeader, ARR_SIZE(tszHeader))))
|
|
{
|
|
return;
|
|
}
|
|
|
|
ListView_InsertColumn(g_hListDetails, 0, &lvColumn);
|
|
|
|
//
|
|
// add event column
|
|
//
|
|
if (ERROR_SUCCESS != (dwRes = LoadAndFormatString (IDS_DETAIL_EVENT_HEADER, tszHeader, ARR_SIZE(tszHeader))))
|
|
{
|
|
return;
|
|
}
|
|
ListView_InsertColumn(g_hListDetails, 1, &lvColumn);
|
|
|
|
//
|
|
// Autosize the last column width
|
|
//
|
|
ListView_SetColumnWidth(g_hListDetails, 1, LVSCW_AUTOSIZE_USEHEADER);
|
|
|
|
//
|
|
// Animation control
|
|
//
|
|
g_hAnimation = GetDlgItem(hDlg, IDC_ANIMATE);
|
|
ASSERTION (g_hAnimation);
|
|
//
|
|
// Get static text controls
|
|
//
|
|
g_hStatus = GetDlgItem(hDlg, IDC_STATUS);
|
|
ASSERTION (g_hStatus);
|
|
g_hElapsedTime = GetDlgItem(hDlg, IDC_ELAPSED_TIME);
|
|
ASSERTION (g_hElapsedTime);
|
|
g_hToFrom = GetDlgItem(hDlg, IDC_MON_TITLE);
|
|
ASSERTION (g_hToFrom);
|
|
//
|
|
// Disconnect button
|
|
//
|
|
g_hDisconnect = GetDlgItem(hDlg, IDC_DISCONNECT);
|
|
ASSERTION (g_hDisconnect);
|
|
//
|
|
// Get the time separator string
|
|
//
|
|
if(!GetLocaleInfo(LOCALE_USER_DEFAULT,
|
|
LOCALE_STIME,
|
|
g_tszTimeSeparator,
|
|
ARR_SIZE(g_tszTimeSeparator) - 1))
|
|
{
|
|
dwRes = GetLastError();
|
|
CALL_FAIL (WINDOW_ERR, TEXT ("GetLocaleInfo(LOCALE_STIME)"), dwRes);
|
|
}
|
|
|
|
if(g_ptPosition.x != -1 && g_ptPosition.y != -1)
|
|
{
|
|
SetWindowPos(hDlg, 0, g_ptPosition.x, g_ptPosition.y, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
|
|
}
|
|
|
|
UpdateMonitorData(hDlg);
|
|
|
|
} // InitMonitorDlg
|
|
|
|
|
|
DWORD
|
|
UpdateMonitorData(
|
|
HWND hDlg
|
|
)
|
|
/*++
|
|
|
|
Routine description:
|
|
|
|
Update monitor data and controls
|
|
|
|
Arguments:
|
|
|
|
hDlg [in] - fax monitor dialog handle
|
|
|
|
Return Value:
|
|
|
|
standard error code
|
|
|
|
--*/
|
|
{
|
|
DWORD dwRes = ERROR_SUCCESS;
|
|
DBG_ENTER(TEXT("UpdateMonitorData"), dwRes);
|
|
|
|
if(!hDlg || !g_hStatus || !g_hElapsedTime || !g_hToFrom || !g_hListDetails || !g_hDisconnect)
|
|
{
|
|
return dwRes;
|
|
}
|
|
//
|
|
// elapsed time
|
|
//
|
|
if(FAX_IDLE == g_devState)
|
|
{
|
|
if(!SetWindowText(g_hElapsedTime, TEXT("")))
|
|
{
|
|
dwRes = GetLastError();
|
|
CALL_FAIL (WINDOW_ERR, TEXT ("SetWindowText"), dwRes);
|
|
}
|
|
}
|
|
//
|
|
// Disconnect/Answer button
|
|
//
|
|
BOOL bButtonEnable = FALSE;
|
|
DWORD dwButtonTitleID = IDS_BUTTON_DISCONNECT;
|
|
TCHAR tszButtonTitle[MAX_PATH] = {0};
|
|
g_bAnswerNow = FALSE;
|
|
if (ERROR_SUCCESS == CheckAnswerNowCapability (FALSE, // Don't force service to be up
|
|
NULL)) // Don't care about device id
|
|
{
|
|
//
|
|
// Answer Now option is valid
|
|
//
|
|
g_bAnswerNow = TRUE;
|
|
bButtonEnable = TRUE;
|
|
dwButtonTitleID = IDS_BUTTON_ANSWER;
|
|
}
|
|
else if((FAX_SENDING == g_devState ||
|
|
FAX_RECEIVING == g_devState)
|
|
&&
|
|
(IsUserGrantedAccess(FAX_ACCESS_SUBMIT) ||
|
|
IsUserGrantedAccess(FAX_ACCESS_SUBMIT_NORMAL) ||
|
|
IsUserGrantedAccess(FAX_ACCESS_SUBMIT_HIGH) ||
|
|
IsUserGrantedAccess(FAX_ACCESS_MANAGE_JOBS)))
|
|
{
|
|
//
|
|
// Fax in progress
|
|
//
|
|
bButtonEnable = TRUE;
|
|
dwButtonTitleID = IDS_BUTTON_DISCONNECT;
|
|
}
|
|
|
|
EnableWindow(g_hDisconnect, bButtonEnable);
|
|
|
|
if (ERROR_SUCCESS == LoadAndFormatString (dwButtonTitleID, tszButtonTitle, ARR_SIZE(tszButtonTitle)))
|
|
{
|
|
SetWindowText(g_hDisconnect, tszButtonTitle);
|
|
}
|
|
else
|
|
{
|
|
ASSERTION_FAILURE;
|
|
}
|
|
//
|
|
// Animation
|
|
//
|
|
DWORD dwAnimationId = IDR_FAX_IDLE;
|
|
switch(g_devState)
|
|
{
|
|
case FAX_IDLE:
|
|
dwAnimationId = IDR_FAX_IDLE;
|
|
break;
|
|
case FAX_RINGING:
|
|
dwAnimationId = IDR_FAX_RINGING;
|
|
break;
|
|
case FAX_SENDING:
|
|
dwAnimationId = IDR_FAX_SEND;
|
|
break;
|
|
case FAX_RECEIVING:
|
|
dwAnimationId = IDR_FAX_RECEIVE;
|
|
break;
|
|
}
|
|
|
|
if(g_dwCurrentAnimationId != dwAnimationId)
|
|
{
|
|
if(!Animate_OpenEx(g_hAnimation, g_hModule, MAKEINTRESOURCE(dwAnimationId)))
|
|
{
|
|
CALL_FAIL (WINDOW_ERR, TEXT ("Animate_Open"), 0);
|
|
}
|
|
else
|
|
{
|
|
if(!Animate_Play(g_hAnimation, 0, -1, -1))
|
|
{
|
|
CALL_FAIL (WINDOW_ERR, TEXT ("Animate_Play"), 0);
|
|
}
|
|
else
|
|
{
|
|
g_dwCurrentAnimationId = dwAnimationId;
|
|
}
|
|
}
|
|
}
|
|
//
|
|
// Status
|
|
//
|
|
if(FAX_IDLE != g_devState) // Non-idle state and
|
|
{
|
|
if(!SetWindowText(g_hStatus, g_tszLastEvent))
|
|
{
|
|
dwRes = GetLastError();
|
|
CALL_FAIL (WINDOW_ERR, TEXT ("SetWindowText"), dwRes);
|
|
}
|
|
}
|
|
else // idle
|
|
{
|
|
DWORD dwStrId = IDS_FAX_READY;
|
|
TCHAR tszReady[MAX_PATH];
|
|
|
|
if(g_ConfigOptions.bSend &&
|
|
(g_ConfigOptions.bReceive || g_ConfigOptions.dwManualAnswerDeviceId == g_ConfigOptions.dwMonitorDeviceId))
|
|
{
|
|
dwStrId = IDS_READY_TO_SND_AND_RCV;
|
|
}
|
|
else if(g_ConfigOptions.bSend)
|
|
{
|
|
dwStrId = IDS_READY_TO_SND;
|
|
}
|
|
else if(g_ConfigOptions.bReceive || g_ConfigOptions.dwManualAnswerDeviceId == g_ConfigOptions.dwMonitorDeviceId)
|
|
{
|
|
dwStrId = IDS_READY_TO_RCV;
|
|
}
|
|
|
|
if (ERROR_SUCCESS != (dwRes = LoadAndFormatString (dwStrId, tszReady, ARR_SIZE(tszReady))))
|
|
{
|
|
return dwRes;
|
|
}
|
|
if(!SetWindowText(g_hStatus, tszReady))
|
|
{
|
|
dwRes = GetLastError();
|
|
CALL_FAIL (WINDOW_ERR, TEXT ("SetWindowText"), dwRes);
|
|
}
|
|
}
|
|
//
|
|
// to/from
|
|
//
|
|
TCHAR tszToFrom[MAX_PATH] = {0};
|
|
if(FAX_SENDING == g_devState || FAX_RECEIVING == g_devState)
|
|
{
|
|
LPCTSTR lpctstrAddressParam = NULL;
|
|
DWORD dwStringResId = (FAX_SENDING == g_devState) ? IDS_SENDING : IDS_RECEIVING;
|
|
if(_tcslen(g_szRemoteId))
|
|
{
|
|
//
|
|
// Remote ID is known
|
|
//
|
|
lpctstrAddressParam = g_szRemoteId;
|
|
dwStringResId = (FAX_SENDING == g_devState) ? IDS_SENDING_TO : IDS_RECEIVING_FROM;
|
|
}
|
|
if (ERROR_SUCCESS != (dwRes = LoadAndFormatString (dwStringResId,
|
|
tszToFrom,
|
|
ARR_SIZE(tszToFrom),
|
|
lpctstrAddressParam)))
|
|
{
|
|
return dwRes;
|
|
}
|
|
}
|
|
if(!SetWindowText(g_hToFrom, tszToFrom))
|
|
{
|
|
dwRes = GetLastError();
|
|
CALL_FAIL (WINDOW_ERR, TEXT ("SetWindowText"), dwRes);
|
|
}
|
|
//
|
|
// Details log list
|
|
//
|
|
if(ListView_GetItemCount(g_hListDetails) == 0)
|
|
{
|
|
//
|
|
// Log is empty - fill it with list data
|
|
//
|
|
ASSERTION (g_lstEvents.size() <= MAX_EVENT_LIST_SIZE);
|
|
for (EVENTS_LIST::iterator it = g_lstEvents.begin(); it != g_lstEvents.end(); ++it)
|
|
{
|
|
EVENT_ENTRY &Event = *it;
|
|
AddEventToView(&Event);
|
|
}
|
|
}
|
|
|
|
if(!CheckDlgButton(hDlg, IDC_ALWAYS_ON_TOP, g_bTopMost ? BST_CHECKED : BST_UNCHECKED))
|
|
{
|
|
dwRes = GetLastError();
|
|
CALL_FAIL (WINDOW_ERR, TEXT ("CheckDlgButton(IDC_ALWAYS_ON_TOP)"), dwRes);
|
|
}
|
|
|
|
OnAlwaysOnTop(hDlg);
|
|
|
|
return dwRes;
|
|
} // UpdateMonitorData
|
|
|
|
|
|
void
|
|
OnDetailsButton(
|
|
HWND hDlg,
|
|
BOOL bDetails
|
|
)
|
|
/*++
|
|
|
|
Routine description:
|
|
|
|
Show/Hide event log and change the details button text
|
|
according to bDetails value
|
|
|
|
Arguments:
|
|
|
|
hDlg [in] - fax monitor dialog handle
|
|
bDetails [in] - new details state
|
|
|
|
Return Value:
|
|
|
|
none
|
|
|
|
--*/
|
|
{
|
|
DBG_ENTER(TEXT("OnDetailsButton"));
|
|
|
|
if(!hDlg)
|
|
{
|
|
ASSERTION (FALSE);
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Show/Hide the event log
|
|
//
|
|
RECT rc;
|
|
GetWindowRect(hDlg, &rc);
|
|
|
|
BOOL bLogOpened = (rc.bottom - rc.top > g_dwDlgHeight - g_dwHeightDelta/2);
|
|
//
|
|
// If the current dialog heigh more then
|
|
// dlialog heigh with open log minus half log heigh
|
|
// we suppose that the log is opened.
|
|
// This done due to different dialog size in the high contrast mode.
|
|
//
|
|
if(bLogOpened != bDetails)
|
|
{
|
|
//
|
|
// Current log state does not fit the new state
|
|
//
|
|
rc.bottom += g_dwHeightDelta * (bDetails ? 1 : -1);
|
|
MoveWindow(hDlg, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, TRUE);
|
|
}
|
|
|
|
//
|
|
// Set More/Less button text
|
|
//
|
|
TCHAR tszButtonText[MAX_PATH];
|
|
if (ERROR_SUCCESS != LoadAndFormatString (bDetails ? IDS_BUTTON_LESS : IDS_BUTTON_MORE,
|
|
tszButtonText,
|
|
ARR_SIZE(tszButtonText)))
|
|
{
|
|
return;
|
|
}
|
|
|
|
if(!SetDlgItemText(hDlg, IDC_DETAILS, tszButtonText))
|
|
{
|
|
CALL_FAIL (WINDOW_ERR, TEXT ("SetDlgItemText"), GetLastError());
|
|
}
|
|
|
|
} // OnDetailsButton
|
|
|
|
void
|
|
OnAlwaysOnTop(
|
|
HWND hDlg
|
|
)
|
|
/*++
|
|
|
|
Routine description:
|
|
|
|
Change monitor "on top" state and save it to the registry
|
|
|
|
Arguments:
|
|
|
|
hDlg [in] - fax monitor dialog handle
|
|
|
|
Return Value:
|
|
|
|
none
|
|
|
|
--*/
|
|
{
|
|
DBG_ENTER(TEXT("OnAlwaysOnTop"));
|
|
|
|
if(!hDlg)
|
|
{
|
|
ASSERTION (FALSE);
|
|
return;
|
|
}
|
|
|
|
g_bTopMost = (IsDlgButtonChecked(hDlg, IDC_ALWAYS_ON_TOP) == BST_CHECKED) ? 1:0;
|
|
DWORD dwRes;
|
|
|
|
if(!SetWindowPos(hDlg,
|
|
g_bTopMost ? HWND_TOPMOST : HWND_NOTOPMOST,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE))
|
|
{
|
|
dwRes = GetLastError();
|
|
CALL_FAIL (WINDOW_ERR, TEXT ("SetWindowPos"), dwRes);
|
|
}
|
|
|
|
HKEY hKey;
|
|
dwRes = RegOpenKeyEx(HKEY_CURRENT_USER, REGKEY_FAX_USERINFO, 0, KEY_WRITE, &hKey);
|
|
if (ERROR_SUCCESS == dwRes)
|
|
{
|
|
dwRes = RegSetValueEx(hKey, REGVAL_ALWAYS_ON_TOP, 0, REG_DWORD, (CONST BYTE*)&g_bTopMost, sizeof(g_bTopMost));
|
|
if(ERROR_SUCCESS != dwRes)
|
|
{
|
|
CALL_FAIL (WINDOW_ERR, TEXT ("RegSetValueEx(REGVAL_ALWAYS_ON_TOP)"), dwRes);
|
|
}
|
|
|
|
RegCloseKey( hKey );
|
|
}
|
|
else
|
|
{
|
|
CALL_FAIL (WINDOW_ERR, TEXT ("RegOpenKeyEx"), dwRes);
|
|
}
|
|
} // OnAlwaysOnTop
|
|
|
|
void
|
|
SetStatusMonitorDeviceState(
|
|
DeviceState devState
|
|
)
|
|
/*++
|
|
|
|
Routine description:
|
|
|
|
Change device state
|
|
Start/stop elapsed timer
|
|
|
|
Arguments:
|
|
|
|
devState - [in] device state
|
|
|
|
Return Value:
|
|
|
|
none
|
|
|
|
--*/
|
|
{
|
|
DWORD dwRes = ERROR_SUCCESS;
|
|
DBG_ENTER(TEXT("SetStatusMonitorDeviceState"), dwRes);
|
|
|
|
if(g_devState != devState)
|
|
{
|
|
//
|
|
// State has changed
|
|
//
|
|
if(g_nElapsedTimerId)
|
|
{
|
|
//
|
|
// Old timer exists
|
|
//
|
|
if(!KillTimer(NULL, g_nElapsedTimerId))
|
|
{
|
|
dwRes = GetLastError();
|
|
CALL_FAIL (WINDOW_ERR, TEXT ("KillTimer"), dwRes);
|
|
}
|
|
g_nElapsedTimerId = 0;
|
|
}
|
|
}
|
|
|
|
if(!g_nElapsedTimerId && (devState == FAX_SENDING || devState == FAX_RECEIVING))
|
|
{
|
|
//
|
|
// We need to count elapsed time for send / receive states.
|
|
//
|
|
g_dwStartTime = GetTickCount();
|
|
|
|
g_nElapsedTimerId = SetTimer(NULL, 0, DURATION_TIMER_RESOLUTION, ElapsedTimerProc);
|
|
if(!g_nElapsedTimerId)
|
|
{
|
|
dwRes = GetLastError();
|
|
CALL_FAIL (WINDOW_ERR, TEXT ("SetTimer"), dwRes);
|
|
}
|
|
}
|
|
|
|
g_devState = devState;
|
|
|
|
UpdateMonitorData(g_hMonitorDlg);
|
|
} // SetStatusMonitorDeviceState
|
|
|
|
|
|
VOID
|
|
CALLBACK
|
|
ElapsedTimerProc(
|
|
HWND hwnd, // handle to window
|
|
UINT uMsg, // WM_TIMER message
|
|
UINT_PTR idEvent, // timer identifier
|
|
DWORD dwTime // current system time
|
|
)
|
|
/*++
|
|
|
|
Routine description:
|
|
|
|
Timer precedure to update elapsed time value
|
|
|
|
Arguments:
|
|
|
|
HWND hwnd, // handle to window
|
|
UINT uMsg, // WM_TIMER message
|
|
UINT_PTR idEvent, // timer identifier
|
|
DWORD dwTime // current system time
|
|
|
|
Return Value:
|
|
|
|
none
|
|
|
|
--*/
|
|
{
|
|
DBG_ENTER(TEXT("ElapsedTimerProc"));
|
|
|
|
if(!g_hElapsedTime)
|
|
{
|
|
return;
|
|
}
|
|
|
|
TCHAR tszTime[MAX_PATH] = {0};
|
|
TCHAR tszTimeFormat[MAX_PATH] = {0};
|
|
|
|
DWORD dwRes;
|
|
|
|
if (ERROR_SUCCESS != (dwRes = LoadAndFormatString (IDS_ELAPSED_TIME, tszTimeFormat, ARR_SIZE(tszTimeFormat))))
|
|
{
|
|
return;
|
|
}
|
|
|
|
DWORD dwElapsedTime = (GetTickCount() - g_dwStartTime)/1000;
|
|
|
|
_sntprintf(tszTime,
|
|
ARR_SIZE(tszTime) - 1,
|
|
tszTimeFormat,
|
|
dwElapsedTime/60,
|
|
g_tszTimeSeparator,
|
|
dwElapsedTime%60);
|
|
|
|
if(!SetWindowText(g_hElapsedTime, tszTime))
|
|
{
|
|
dwRes = GetLastError();
|
|
CALL_FAIL (WINDOW_ERR, TEXT ("SetWindowText"), dwRes);
|
|
}
|
|
} // ElapsedTimerProc
|
|
|
|
|
|
DWORD
|
|
LoadAndFormatString (
|
|
IN DWORD dwStringResourceId,
|
|
OUT LPTSTR lptstrFormattedString,
|
|
IN DWORD dwOutStrSize,
|
|
IN LPCTSTR lpctstrAdditionalParam /* = NULL */
|
|
)
|
|
/*++
|
|
|
|
Routine name : LoadAndFormatString
|
|
|
|
Routine description:
|
|
|
|
Loads a string from the resource and optionally formats it with another string
|
|
|
|
Author:
|
|
|
|
Eran Yariv (EranY), Dec, 2000
|
|
|
|
Arguments:
|
|
|
|
dwStringResourceId [in] - String resource id
|
|
lptstrFormattedString [out] - Result buffer. Must be at least MAX_PATH charactes long.
|
|
dwOutStrSize [in] - size of lptstrFormattedString in TCHARs
|
|
lpctstrAdditionalParam [in] - Optional string paramter.
|
|
If non-NULL, this loaded strings is used as a format specifier (sprintf-like) to
|
|
format this additional string.
|
|
|
|
Return Value:
|
|
|
|
Standard Win32 error code
|
|
|
|
--*/
|
|
{
|
|
DWORD dwRes = ERROR_SUCCESS;
|
|
DBG_ENTER(TEXT("LoadAndFormatString"),
|
|
dwRes,
|
|
TEXT("ResourceId=%d, Param=%s"),
|
|
dwStringResourceId,
|
|
lpctstrAdditionalParam);
|
|
|
|
ASSERTION (lptstrFormattedString && dwStringResourceId);
|
|
|
|
TCHAR tszString[MAX_PATH] = {0};
|
|
|
|
if (!LoadString(g_hResource, dwStringResourceId, tszString, ARR_SIZE(tszString)-1))
|
|
{
|
|
dwRes = GetLastError();
|
|
CALL_FAIL (RESOURCE_ERR, TEXT("LoadString"), dwRes);
|
|
return dwRes;
|
|
}
|
|
if (lpctstrAdditionalParam)
|
|
{
|
|
_sntprintf(lptstrFormattedString,
|
|
dwOutStrSize - 1,
|
|
tszString,
|
|
lpctstrAdditionalParam);
|
|
lptstrFormattedString[dwOutStrSize -1] = _T('\0');
|
|
|
|
}
|
|
else
|
|
{
|
|
lstrcpyn (lptstrFormattedString, tszString, dwOutStrSize - 1);
|
|
}
|
|
return dwRes;
|
|
} // LoadAndFormatString
|
|
|
|
DWORD
|
|
AddStatusMonitorLogEvent (
|
|
IN eIconType eIcon,
|
|
IN DWORD dwStringResourceId,
|
|
IN LPCTSTR lpctstrAdditionalParam /* = NULL */,
|
|
OUT LPTSTR lptstrFormattedEvent /* = NULL */,
|
|
IN DWORD dwOutStrSize /* = 0 */
|
|
)
|
|
/*++
|
|
|
|
Routine name : AddStatusMonitorLogEvent
|
|
|
|
Routine description:
|
|
|
|
Adds a status monitor event log line
|
|
|
|
Author:
|
|
|
|
Eran Yariv (EranY), Dec, 2000
|
|
|
|
Arguments:
|
|
|
|
eIcon [in] - Icon to display in log entry
|
|
dwStringResourceId [in] - String resource id to use
|
|
lpctstrAdditionalParam [in] - Optional string. If non-NULL, the string loaded from dwStringResourceId
|
|
is used to format the additional parameter.
|
|
lptstrFormattedEvent [out] - Optional, if non-NULL, points to a buffer to receive the final status string.
|
|
Buffer must be at least MAX_PATH characters long.
|
|
dwOutStrSize [in] - Optional size of lptstrFormattedEvent in TCHARs
|
|
|
|
Return Value:
|
|
|
|
Standard Win32 error code
|
|
|
|
--*/
|
|
{
|
|
DWORD dwRes = ERROR_SUCCESS;
|
|
DBG_ENTER(TEXT("AddStatusMonitorLogEvent"),
|
|
dwRes,
|
|
TEXT("Icon=%d, ResourceId=%d, Param=%s"),
|
|
eIcon,
|
|
dwStringResourceId,
|
|
lpctstrAdditionalParam);
|
|
|
|
TCHAR tszStatus[MAX_PATH * 2] = {0};
|
|
dwRes = LoadAndFormatString (dwStringResourceId, tszStatus, ARR_SIZE(tszStatus), lpctstrAdditionalParam);
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
return dwRes;
|
|
}
|
|
if (lptstrFormattedEvent)
|
|
{
|
|
lstrcpyn (lptstrFormattedEvent, tszStatus, dwOutStrSize - 1);
|
|
}
|
|
dwRes = AddStatusMonitorLogEvent (eIcon, tszStatus);
|
|
return dwRes;
|
|
} // AddStatusMonitorLogEvent
|
|
|
|
|
|
DWORD
|
|
AddStatusMonitorLogEvent (
|
|
eIconType eIcon,
|
|
LPCTSTR lpctstrString
|
|
)
|
|
/*++
|
|
|
|
Routine description:
|
|
|
|
Add new event to the event list
|
|
|
|
Arguments:
|
|
|
|
eIcon - [in] icon index
|
|
lpctstrString - [in] event description
|
|
|
|
Return Value:
|
|
|
|
standard error code
|
|
|
|
--*/
|
|
{
|
|
DWORD dwRes = ERROR_SUCCESS;
|
|
DBG_ENTER(TEXT("AddStatusMonitorLogEvent"),
|
|
dwRes,
|
|
TEXT("Icon=%d, Status=%s"),
|
|
eIcon,
|
|
lpctstrString);
|
|
|
|
TCHAR tszTime [MAX_PATH] = {0};
|
|
|
|
ASSERTION (lpctstrString);
|
|
|
|
static TCHAR tszRinging[MAX_PATH] = {0};
|
|
|
|
if(_tcslen(tszRinging) == 0)
|
|
{
|
|
if (ERROR_SUCCESS != (dwRes = LoadAndFormatString (IDS_RINGING, tszRinging, ARR_SIZE(tszRinging))))
|
|
{
|
|
ASSERTION_FAILURE;
|
|
return dwRes;
|
|
}
|
|
}
|
|
|
|
if(_tcscmp(lpctstrString, g_tszLastEvent) == 0 &&
|
|
_tcscmp(lpctstrString, tszRinging) != 0)
|
|
{
|
|
//
|
|
// Do not display the same string twice
|
|
// except "Ringing"
|
|
//
|
|
return dwRes;
|
|
}
|
|
|
|
EVENT_ENTRY Event;
|
|
Event.eIcon = eIcon;
|
|
|
|
SYSTEMTIME sysTime;
|
|
GetLocalTime(&sysTime);
|
|
if(!FaxTimeFormat(LOCALE_USER_DEFAULT, 0, &sysTime, NULL, Event.tszTime, ARR_SIZE(Event.tszTime) - 1))
|
|
{
|
|
dwRes = GetLastError();
|
|
CALL_FAIL (WINDOW_ERR, TEXT ("FaxTimeFormat"), dwRes);
|
|
return dwRes;
|
|
}
|
|
|
|
lstrcpyn (Event.tszEvent, lpctstrString, ARR_SIZE(Event.tszEvent) - 1);
|
|
lstrcpyn (g_tszLastEvent, lpctstrString, ARR_SIZE(g_tszLastEvent) - 1);
|
|
|
|
try
|
|
{
|
|
g_lstEvents.push_back (Event);
|
|
if (g_lstEvents.size() > MAX_EVENT_LIST_SIZE)
|
|
{
|
|
//
|
|
// We exceeded the maximal size we permit - remove the most ancient entry
|
|
//
|
|
g_lstEvents.pop_front ();
|
|
}
|
|
}
|
|
catch (exception &ex)
|
|
{
|
|
VERBOSE (MEM_ERR,
|
|
TEXT("Got an STL exception while handling with event list (%S)"),
|
|
ex.what());
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
|
|
AddEventToView(&Event);
|
|
dwRes = UpdateMonitorData(g_hMonitorDlg);
|
|
return dwRes;
|
|
} // AddStatusMonitorLogEvent
|
|
|
|
void
|
|
AddEventToView(
|
|
PEVENT_ENTRY pEvent
|
|
)
|
|
/*++
|
|
|
|
Routine description:
|
|
|
|
Add event to the list view
|
|
|
|
Arguments:
|
|
|
|
pEvent - event data
|
|
|
|
Return Value:
|
|
|
|
none
|
|
|
|
--*/
|
|
{
|
|
DBG_ENTER(TEXT("AddEventToView"));
|
|
ASSERTION (pEvent);
|
|
|
|
if(!g_hListDetails)
|
|
{
|
|
return;
|
|
}
|
|
|
|
LV_ITEM lvi = {0};
|
|
DWORD dwItem;
|
|
|
|
lvi.pszText = pEvent->tszTime ? pEvent->tszTime : TEXT("");
|
|
lvi.iItem = ListView_GetItemCount( g_hListDetails );
|
|
lvi.iSubItem = 0;
|
|
lvi.mask = LVIF_TEXT | LVIF_IMAGE;
|
|
lvi.iImage = pEvent->eIcon;
|
|
|
|
dwItem = ListView_InsertItem( g_hListDetails, &lvi );
|
|
|
|
lvi.pszText = pEvent->tszEvent ? pEvent->tszEvent : TEXT("");
|
|
lvi.iItem = dwItem;
|
|
lvi.iSubItem = 1;
|
|
lvi.mask = LVIF_TEXT;
|
|
ListView_SetItem( g_hListDetails, &lvi );
|
|
|
|
ListView_EnsureVisible(g_hListDetails, dwItem, FALSE);
|
|
|
|
if(ListView_GetItemCount(g_hListDetails) > MAX_EVENT_LIST_SIZE)
|
|
{
|
|
ListView_DeleteItem(g_hListDetails, 0);
|
|
}
|
|
|
|
//
|
|
// Autosize the last column to get rid of unnecessary horizontal scroll bar
|
|
//
|
|
ListView_SetColumnWidth(g_hListDetails, 1, LVSCW_AUTOSIZE_USEHEADER);
|
|
|
|
} // AddEventToView
|
|
|
|
|
|
DWORD
|
|
OpenFaxMonitor(VOID)
|
|
/*++
|
|
|
|
Routine description:
|
|
|
|
Opens fax monitor dialog
|
|
|
|
Arguments:
|
|
|
|
none
|
|
|
|
Return Value:
|
|
|
|
Standard error code.
|
|
|
|
--*/
|
|
{
|
|
DWORD dwRes = ERROR_SUCCESS;
|
|
DBG_ENTER(TEXT("OpenFaxMonitor"), dwRes);
|
|
|
|
if(!g_hMonitorDlg)
|
|
{
|
|
//
|
|
// Read 'top most' value
|
|
//
|
|
HKEY hKey;
|
|
|
|
dwRes = RegOpenKeyEx(HKEY_CURRENT_USER, REGKEY_FAX_USERINFO, 0, KEY_READ, &hKey);
|
|
if (ERROR_SUCCESS == dwRes)
|
|
{
|
|
g_bTopMost = GetRegistryDword(hKey, REGVAL_ALWAYS_ON_TOP);
|
|
RegCloseKey( hKey );
|
|
}
|
|
else
|
|
{
|
|
CALL_FAIL (WINDOW_ERR, TEXT ("RegOpenKeyEx"), dwRes);
|
|
}
|
|
//
|
|
// Create the dialog
|
|
//
|
|
g_hMonitorDlg = CreateDialogParam(g_hResource,
|
|
MAKEINTRESOURCE(IDD_MONITOR),
|
|
NULL,
|
|
FaxMonitorDlgProc,
|
|
NULL);
|
|
if(!g_hMonitorDlg)
|
|
{
|
|
dwRes = GetLastError();
|
|
CALL_FAIL (WINDOW_ERR, TEXT ("CreateDialogParam"), dwRes);
|
|
return dwRes;
|
|
}
|
|
}
|
|
//
|
|
// Set the focus on the dialog and make it the top window
|
|
//
|
|
SetFocus(g_hMonitorDlg);
|
|
SetActiveWindow(g_hMonitorDlg);
|
|
SetWindowPos(g_hMonitorDlg,
|
|
HWND_TOPMOST,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE);
|
|
if (!g_bTopMost)
|
|
{
|
|
SetWindowPos(g_hMonitorDlg,
|
|
HWND_NOTOPMOST,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE);
|
|
}
|
|
return dwRes;
|
|
} // OpenFaxMonitor
|
|
|
|
void
|
|
OnDisconnect()
|
|
/*++
|
|
|
|
Routine description:
|
|
|
|
Abort current transmission
|
|
OR
|
|
Answer a call
|
|
|
|
Return Value:
|
|
|
|
none
|
|
|
|
--*/
|
|
{
|
|
DWORD dwRes = ERROR_SUCCESS;
|
|
DBG_ENTER(TEXT("OnDisconnect"), dwRes);
|
|
|
|
if(g_bAnswerNow)
|
|
{
|
|
//
|
|
// The button shows 'Answer Now'
|
|
//
|
|
AnswerTheCall();
|
|
return;
|
|
}
|
|
//
|
|
// Else, the button shows 'Disconnect'
|
|
//
|
|
if(!g_dwCurrentJobID)
|
|
{
|
|
//
|
|
// No job - nothing to disconnect
|
|
//
|
|
SetStatusMonitorDeviceState(FAX_IDLE);
|
|
return;
|
|
}
|
|
|
|
DWORD dwMsgId = (FAX_SENDING == g_devState) ? IDS_ABORT_SEND_CONFIRM : IDS_ABORT_RECEIVE_CONFIRM;
|
|
|
|
if(IDYES != FaxMessageBox(g_hMonitorDlg, dwMsgId, MB_YESNO | MB_DEFBUTTON2 | MB_ICONQUESTION))
|
|
{
|
|
return;
|
|
}
|
|
|
|
if(!Connect())
|
|
{
|
|
dwRes = GetLastError();
|
|
CALL_FAIL (RPC_ERR, TEXT ("Connect"), dwRes);
|
|
return;
|
|
}
|
|
|
|
FAX_JOB_ENTRY fje = {0};
|
|
fje.SizeOfStruct = sizeof(FAX_JOB_ENTRY);
|
|
|
|
if(g_hDisconnect)
|
|
{
|
|
EnableWindow(g_hDisconnect, FALSE);
|
|
}
|
|
|
|
if (!FaxSetJob (g_hFaxSvcHandle, g_dwCurrentJobID, JC_DELETE, &fje))
|
|
{
|
|
dwRes = GetLastError();
|
|
CALL_FAIL (RPC_ERR, TEXT ("FaxSetJob"), dwRes);
|
|
|
|
if(g_hDisconnect)
|
|
{
|
|
EnableWindow(g_hDisconnect, TRUE);
|
|
}
|
|
|
|
if(ERROR_ACCESS_DENIED == dwRes)
|
|
{
|
|
FaxMessageBox(g_hMonitorDlg, IDS_DELETE_ACCESS_DENIED, MB_OK | MB_ICONSTOP);
|
|
}
|
|
}
|
|
|
|
} // OnDisconnect
|
|
|
|
|
|
void
|
|
OnClearLog()
|
|
/*++
|
|
|
|
Routine description:
|
|
|
|
Clear the monitor event log
|
|
|
|
Return Value:
|
|
|
|
none
|
|
|
|
--*/
|
|
{
|
|
DBG_ENTER(TEXT("OnClearLog"));
|
|
ASSERTION (g_hListDetails);
|
|
try
|
|
{
|
|
g_lstEvents.clear();
|
|
}
|
|
catch (exception &ex)
|
|
{
|
|
VERBOSE (MEM_ERR,
|
|
TEXT("Got an STL exception while clearing the events list (%S)"),
|
|
ex.what());
|
|
}
|
|
if(!ListView_DeleteAllItems(g_hListDetails))
|
|
{
|
|
CALL_FAIL (WINDOW_ERR, TEXT ("ListView_DeleteAllItems"), 0);
|
|
}
|
|
} // OnClearLog
|
|
|
|
|
|
int
|
|
FaxMessageBox(
|
|
HWND hWnd,
|
|
DWORD dwTextID,
|
|
UINT uType
|
|
)
|
|
/*++
|
|
|
|
Routine description:
|
|
|
|
Open standard message box
|
|
|
|
Arguments:
|
|
|
|
hWnd - handle to owner window
|
|
dwTextID - text resource ID in message box
|
|
uType - message box style
|
|
|
|
Return Value:
|
|
|
|
MessageBox() return value
|
|
|
|
--*/
|
|
{
|
|
int iRes;
|
|
DBG_ENTER(TEXT("FaxMessageBox"), iRes);
|
|
|
|
TCHAR tsCaption[MAX_PATH];
|
|
TCHAR tsText[MAX_PATH];
|
|
|
|
DWORD dwRes;
|
|
if (ERROR_SUCCESS != (dwRes = LoadAndFormatString (IDS_MESSAGE_BOX_CAPTION, tsCaption, ARR_SIZE(tsCaption))))
|
|
{
|
|
SetLastError (dwRes);
|
|
iRes = 0;
|
|
return iRes;
|
|
}
|
|
|
|
if (ERROR_SUCCESS != (dwRes = LoadAndFormatString (dwTextID, tsText, ARR_SIZE(tsText))))
|
|
{
|
|
SetLastError (dwRes);
|
|
iRes = 0;
|
|
return iRes;
|
|
}
|
|
iRes = AlignedMessageBox(hWnd, tsText, tsCaption, uType);
|
|
return iRes;
|
|
} // FaxMessageBox
|
|
|