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.
 
 
 
 
 
 

707 lines
18 KiB

//+----------------------------------------------------------------------------
//
// File: StatusDlg.cpp
//
// Module: CMMON32.EXE
//
// Synopsis: Implement status/count-down dialog class CStatusDlg
//
// Copyright (c) 1998-1999 Microsoft Corporation
//
// Author: ????? Created 02/20/98
//
//+----------------------------------------------------------------------------
#include "cmmaster.h"
#include "StatusDlg.h"
#include "Connection.h"
#include "resource.h"
#include "Monitor.h"
#include "cmmgr32.h" // help IDs
#include "cm_misc.h"
#include "resource.h"
//
// Map of control id to help id
//
const DWORD CStatusDlg::m_dwHelp[] = {IDOK, IDH_OK_CONNECTED,
IDC_DISCONNECT, IDH_STATUS_DISCONNECT,
IDC_DETAILS, IDH_DETAILS,
0,0};
//+----------------------------------------------------------------------------
//
// Function: CStatusDlg::CStatusDlg
//
// Synopsis: Constructor
//
// Arguments: CCmConnection* pConnection - The connection to notify event
//
// Returns: Nothing
//
// History: Created Header 2/20/98
//
//+----------------------------------------------------------------------------
CStatusDlg::CStatusDlg(CCmConnection* pConnection):CModelessDlg(m_dwHelp)
{
m_pConnection = pConnection;
m_fDisplayStatus = FALSE;
m_fStatusWindowVisible = FALSE;
}
//+----------------------------------------------------------------------------
//
// Function: CStatusDlg::Create
//
// Synopsis: Create a modeless status dialog
//
// Arguments: HINSTANCE hInstance - Instance of the resource
// HWND hWndParent - Parent window
// LPCTSTR lpszTitle - Dialog window title
// HICON hIcon - Dialog icon
//
// Returns: HWND - The dialog window handle
//
// History: Created Header 2/20/98
//
//+----------------------------------------------------------------------------
HWND CStatusDlg::Create(HINSTANCE hInstance, HWND hWndParent,
LPCTSTR lpszTitle, HICON hIcon)
{
MYDBGASSERT(lpszTitle);
MYDBGASSERT(hIcon);
DWORD dwStatusDlgId = OS_NT4 ? IDD_CONNSTATNT4 : IDD_CONNSTAT;
if (!CModelessDlg::Create(hInstance, dwStatusDlgId, hWndParent))
{
MYDBGASSERT(FALSE);
return NULL;
}
EnableWindow(m_hWnd, FALSE);
UpdateFont(m_hWnd);
SetWindowTextU(m_hWnd,lpszTitle);
SendDlgItemMessageA(m_hWnd,IDC_CONNSTAT_ICON,STM_SETIMAGE,
IMAGE_ICON,(LPARAM) hIcon);
MakeBold(GetDlgItem(m_hWnd,IDC_CONNSTAT_DISCONNECT_DISPLAY), FALSE);
m_uiHwndMsgTaskBar = RegisterWindowMessageA("TaskbarCreated");
return m_hWnd;
}
//+----------------------------------------------------------------------------
//
// Function: CStatusDlg::OnInitDialog
//
// Synopsis: Called when dialog is intialized and WM_INITDIALOG is received.
//
// Arguments: None
//
// Returns: BOOL - FALSE is focus was assigned to a control.
//
// History: nickball 03/22/00 Created
//
//+----------------------------------------------------------------------------
BOOL CStatusDlg::OnInitDialog()
{
SetForegroundWindow(m_hWnd);
return FALSE;
}
//+----------------------------------------------------------------------------
//
// Function: CStatusDlg::OnOtherCommand
//
// Synopsis: Process WM_COMMAND other than IDOK and IDCANCEL
//
// Arguments: WPARAM wParam - wParam of the message
// LPARAM -
//
// Returns: DWORD - Return value of the message
//
// History: fengsun Created Header 2/20/98
//
//+----------------------------------------------------------------------------
DWORD CStatusDlg::OnOtherCommand(WPARAM wParam, LPARAM)
{
switch (LOWORD(wParam))
{
case IDC_DISCONNECT:
KillRasMonitorWindow();
//
// The thread message loop will handle thread message
//
PostThreadMessageU(GetCurrentThreadId(), CCmConnection::WM_CONN_EVENT,
CCmConnection::EVENT_USER_DISCONNECT, 0);
break;
case IDC_DETAILS:
m_pConnection->OnStatusDetails();
break;
case IDMC_TRAY_STATUS:
//
// Don't show the UI if we are at Winlogon unless we are on NT4
//
if (!IsLogonAsSystem() || OS_NT4)
{
BringToTop();
}
break;
case WM_DESTROY:
ReleaseBold(GetDlgItem(m_hWnd, IDC_CONNSTAT_DISCONNECT_DISPLAY));
break;
default:
//
// Should be message comes from additional tray icon menu item
//
if (LOWORD(wParam) >= CCmConnection::IDM_TRAYMENU &&
LOWORD(wParam) <= (CCmConnection::IDM_TRAYMENU + 100))
{
m_pConnection->OnAdditionalTrayMenu(LOWORD(wParam));
}
break;
}
return FALSE;
}
//+----------------------------------------------------------------------------
//
// Function: CStatusDlg::OnOtherMessage
//
// Synopsis: Process message other than WM_COMMAND and WM_INITDIALOG
//
// Arguments: UINT uMsg - the message
// WPARAM wParam - wParam of the message
// LPARAM lParam - lParam of the message
//
// Returns: DWORD - return value of the message
//
// History: Created Header 2/20/98
//
//+----------------------------------------------------------------------------
DWORD CStatusDlg::OnOtherMessage(UINT uMsg, WPARAM wParam, LPARAM lParam )
{
switch (uMsg)
{
case CCmConnection::WM_TRAYICON:
return m_pConnection->OnTrayIcon(wParam, lParam);
case WM_TIMER:
// CMMON does not use WM_TIMER
MYDBGASSERT(0);
return 0;
case WM_SHOWWINDOW:
if (wParam) //fShow == TRUE
{
//
// Statistics is not updated if window is invisible.
// Force a update of statistics now.
//
m_pConnection->StateConnectedOnTimer();
}
break;
default:
if (uMsg == m_uiHwndMsgTaskBar && !m_pConnection->IsTrayIconHidden())
{
//
// we need to re-add the trayicon
//
m_pConnection->ReInstateTrayIcon();
}
break;
}
return FALSE;
}
//+----------------------------------------------------------------------------
//
// Function: CStatusDlg::OnCancel
//
// Synopsis: Virtual function. Process WM_COMMAND IDCANCEL
//
// Arguments: None
//
// Returns: Nothing
//
// History: fengsun Created Header 2/20/98
//
//+----------------------------------------------------------------------------
void CStatusDlg::OnCancel()
{
//
// Even through, the status dialog does not have a cancel button, this message
// is send when user click Esc, or close from system menu
//
//
// As if OK/StayOnLine is clicked
//
OnOK();
}
//+----------------------------------------------------------------------------
//
// Function: CStatusDlg::OnOK
//
// Synopsis: Virtual function. Process WM_COMMAND IDOK
//
// Arguments: None
//
// Returns: Nothing
//
// History: fengsun Created Header 2/20/98
//
//+----------------------------------------------------------------------------
void CStatusDlg::OnOK()
{
if (m_fDisplayStatus)
{
ShowWindow(m_hWnd, SW_HIDE);
EnableWindow(m_hWnd, FALSE);
}
else // in count-down state
{
m_pConnection->OnStayOnLine();
//
// If window is was up previously and a countdown is being
// terminated leave the window active. Otherwise restore
// window to previous hidden state.
//
if (!m_fStatusWindowVisible)
{
ShowWindow(m_hWnd,SW_HIDE);
EnableWindow(m_hWnd, FALSE);
}
}
if (!IsWindowVisible(m_hWnd))
{
//
// Minimize the working set after hide the window.
//
CMonitor::MinimizeWorkingSet();
}
}
//+----------------------------------------------------------------------------
//
// Function: CStatusDlg::ChangeToCountDown
//
// Synopsis: Change the status dialog to count-down dialog
//
// Arguments: None
//
// Returns: Nothing
//
// History: fengsun Created Header 2/20/98
//
//+----------------------------------------------------------------------------
void CStatusDlg::ChangeToCountDown()
{
MYDBGASSERT(m_fDisplayStatus); // is status;
m_fDisplayStatus = FALSE;
//
// After user clicked "Stay Online", we need to restore the visible state
// Convert is to real boolean
//
m_fStatusWindowVisible = IsWindowVisible(m_hWnd) != FALSE;
KillRasMonitorWindow();
//
// Change OK to Stay Online
//
LPTSTR pszTmp = CmLoadString(CMonitor::GetInstance(),IDMSG_CONNDISC_STAYONLINE);
SetDlgItemTextU(m_hWnd,IDOK,pszTmp);
CmFree(pszTmp);
//
// Change Disconnect to Disconnect Now
//
pszTmp = CmLoadString(CMonitor::GetInstance(),IDMSG_CONNDISC_DISCNOW);
SetDlgItemTextU(m_hWnd,IDC_DISCONNECT,pszTmp);
CmFree(pszTmp);
// Hide/Show the windows for countdown mode
if (!OS_NT4)
{
//
// Hide 9X statistics control
//
ShowWindow(GetDlgItem(m_hWnd,IDC_CONNSTAT_SPEED_DISPLAY),SW_HIDE);
ShowWindow(GetDlgItem(m_hWnd,IDC_CONNSTAT_RECEIVED_DISPLAY),SW_HIDE);
ShowWindow(GetDlgItem(m_hWnd,IDC_CONNSTAT_SENT_DISPLAY),SW_HIDE);
}
ShowWindow(GetDlgItem(m_hWnd,IDC_AUTODISC),SW_SHOW);
SetForegroundWindow(m_hWnd);
//
// Make sure we're flashing and topmost for countdown
//
SetWindowPos(m_hWnd, HWND_TOPMOST, 0,0,0,0, SWP_NOMOVE | SWP_NOSIZE);
Flash();
}
//+----------------------------------------------------------------------------
//
// Function: CStatusDlg::ChangeToStatus
//
// Synopsis: Change the count-down dialog to status dialog
//
// Arguments: None
//
// Returns: Nothing
//
// History: fengsun Created Header 2/20/98
//
//+----------------------------------------------------------------------------
void CStatusDlg::ChangeToStatus()
{
MYDBGASSERT(!m_fDisplayStatus); // is count down
m_fDisplayStatus = TRUE;
// Set text for buttons and static to standard mode
SetDlgItemTextU(m_hWnd,IDC_CONNSTAT_DISCONNECT_DISPLAY,TEXT(""));
//
// Change back to OK
//
LPTSTR pszTmp = CmLoadString(CMonitor::GetInstance(),IDMSG_CONNDISC_OK);
SetDlgItemTextU(m_hWnd,IDOK,pszTmp);
CmFree(pszTmp);
//
// Change back to Disconnect
//
pszTmp = CmLoadString(CMonitor::GetInstance(),IDMSG_CONNDISC_DISCONNECT);
SetDlgItemTextU(m_hWnd,IDC_DISCONNECT,pszTmp);
CmFree(pszTmp);
// Hide/Show the windows for standard mode
ShowWindow(GetDlgItem(m_hWnd,IDC_AUTODISC),SW_HIDE);
if (!OS_NT4)
{
ShowWindow(GetDlgItem(m_hWnd,IDC_CONNSTAT_SPEED_DISPLAY),SW_SHOW);
ShowWindow(GetDlgItem(m_hWnd,IDC_CONNSTAT_RECEIVED_DISPLAY),SW_SHOW);
ShowWindow(GetDlgItem(m_hWnd,IDC_CONNSTAT_SENT_DISPLAY),SW_SHOW);
}
//
// Make sure we're not top-most, just on top, when we switch to status
//
SetWindowPos(m_hWnd, HWND_TOP, 0,0,0,0, SWP_NOMOVE | SWP_NOSIZE);
}
//+----------------------------------------------------------------------------
//
// Function: CStatusDlg::UpdateCountDown
//
// Synopsis: Update the "xx seconds until disconnect" of the count-down dialog
//
// Arguments: DWORD dwDuration: connection duration
// DWORD dwSeconds - seconds remain to disconnect
//
// Returns: Nothing
//
// History: fengsun Created Header 2/20/98
//
//+----------------------------------------------------------------------------
void CStatusDlg::UpdateCountDown(DWORD dwDuration, DWORD dwSeconds)
{
MYDBGASSERT(!m_fDisplayStatus);
MYDBGASSERT(dwSeconds < 0xFFFF);
UpdateDuration(dwDuration);
LPTSTR pszTmp = CmFmtMsg(CMonitor::GetInstance(), IDMSG_CONNDISCONNECT, dwSeconds);
SetDlgItemTextU(m_hWnd,IDC_CONNSTAT_DISCONNECT_DISPLAY,pszTmp);
CmFree(pszTmp);
}
//+----------------------------------------------------------------------------
//
// Function: CStatusDlg::UpdateDuration
//
// Synopsis: Update the connection duration
//
// Arguments: DWORD dwSeconds - connected duration
//
// Returns: Nothing
//
// History: fengsun Created Header 2/20/98
//
//+----------------------------------------------------------------------------
void CStatusDlg::UpdateDuration(DWORD dwSeconds)
{
if (!IsWindowVisible(m_hWnd))
{
return;
}
LPTSTR pszMsg;
// Connect Duration
pszMsg = CmFmtMsg(CMonitor::GetInstance(),
IDMSG_CONNDUR,
(WORD)((dwSeconds/60)/60),
(WORD)((dwSeconds/60)%60),
(WORD)(dwSeconds%60));
SetDlgItemTextU(m_hWnd,IDC_CONNSTAT_DURATION_DISPLAY,pszMsg);
CmFree(pszMsg);
}
//+----------------------------------------------------------------------------
//
// Function: CStatusDlg::UpdateStats
//
// Synopsis: Update the status dialog for Win9X
//
// Arguments: DWORD dwBaudRate - Baud rate
// DWORD dwBytesRead - Total Bytes read
// DWORD dwBytesWrite - Total bytes written
// DWORD dwBytesReadPerSec - Byte read last second
// DWORD dwBytesWritePerSec - Byte written last second
//
// Returns: Nothing
//
// History: fengsun Created Header 2/20/98
//
//+----------------------------------------------------------------------------
void CStatusDlg::UpdateStats(DWORD dwBaudRate, DWORD dwBytesRead, DWORD dwBytesWrite,
DWORD dwBytesReadPerSec, DWORD dwBytesWritePerSec)
{
//
// Received
//
CHAR szFmtNum1[MAX_PATH];
CHAR szFmtNum2[MAX_PATH];
LPSTR pszMsg;
FmtNum(dwBytesRead, szFmtNum1, sizeof(szFmtNum1));
if (dwBytesReadPerSec)
{
FmtNum(dwBytesReadPerSec, szFmtNum2, sizeof(szFmtNum2));
pszMsg = CmFmtMsgA(CMonitor::GetInstance(), IDMSG_CONNCNTRATE, szFmtNum1, szFmtNum2);
}
else
{
pszMsg = CmFmtMsgA(CMonitor::GetInstance(), IDMSG_CONNCNT, szFmtNum1);
}
SetDlgItemTextA(m_hWnd, IDC_CONNSTAT_RECEIVED_DISPLAY, pszMsg);
CmFree(pszMsg);
//
// Sent
//
FmtNum(dwBytesWrite, szFmtNum1, sizeof(szFmtNum1));
if (dwBytesWritePerSec)
{
FmtNum(dwBytesWritePerSec, szFmtNum2, sizeof(szFmtNum2));
pszMsg = CmFmtMsgA(CMonitor::GetInstance(), IDMSG_CONNCNTRATE, szFmtNum1, szFmtNum2);
}
else
{
pszMsg = CmFmtMsgA(CMonitor::GetInstance(), IDMSG_CONNCNT, szFmtNum1);
}
SetDlgItemTextA(m_hWnd, IDC_CONNSTAT_SENT_DISPLAY, pszMsg);
CmFree(pszMsg);
if (dwBaudRate)
{
FmtNum(dwBaudRate, szFmtNum1, sizeof(szFmtNum1));
pszMsg = CmFmtMsgA(CMonitor::GetInstance(), IDMSG_CONNSPEED, szFmtNum1);
SetDlgItemTextA(m_hWnd, IDC_CONNSTAT_SPEED_DISPLAY, pszMsg);
CmFree(pszMsg);
}
}
//+----------------------------------------------------------------------------
//
// Function: CStatusDlg::GetRasMonitorWindow
//
// Synopsis: Find the RasMonitor window on NT, if present
// The Status window is the owner of the RasMonitor
//
// Arguments: none
//
// Returns: HWND - The RasMonitor window handle or NULL
//
// History: fengsun Created Header 2/12/98
//
//+----------------------------------------------------------------------------
HWND CStatusDlg::GetRasMonitorWindow()
{
//
// RasMonitor window only exists on NT
//
if (!OS_NT4)
{
return NULL;
}
//
// The RasMonitor window is the child window of desktop
// however, the owner window is the status window
//
HWND hwnd = NULL;
while (hwnd = FindWindowExU(NULL, hwnd, WC_DIALOG, NULL))
{
if (GetParent(hwnd) == m_hWnd)
{
return hwnd;
}
}
return NULL;
}
//+----------------------------------------------------------------------------
//
// Function: CStatusDlg::KillRasMonitorWindow
//
// Synopsis: Close the RasMonitorDlg and any child dialog it might have
//
// Arguments: None
//
// Returns: Nothing
//
// History: fengsun Created Header 4/28/98
//
//+----------------------------------------------------------------------------
void CStatusDlg::KillRasMonitorWindow()
{
HWND hwndRasMonitor = GetRasMonitorWindow();
if (hwndRasMonitor)
{
//
// The current thread is the connection thread
//
MYDBGASSERT(GetWindowThreadProcessId(m_hWnd, NULL) == GetCurrentThreadId());
//
// The RasMonitorDlg can pop up aother dialog, such as details.
// Kill all the dialog in the RasMonitor thread
//
DWORD dwRasMonitorThread = GetWindowThreadProcessId(hwndRasMonitor, NULL);
MYDBGASSERT(dwRasMonitorThread);
MYDBGASSERT(dwRasMonitorThread != GetCurrentThreadId());
EnumThreadWindows(dwRasMonitorThread, KillRasMonitorWndProc, (LPARAM)this);
}
}
//+----------------------------------------------------------------------------
//
// Function: CStatusDlg::KillRasMonitorWndProc
//
// Synopsis: Kill all the window in the RasMonitorThread
//
// Arguments: HWND hwnd - Window handle belong to the RasMonitorThread
// LPARAM lParam - pointer to CStatusDlg
//
// Returns: BOOL - TRUE to continue enumeration
//
// History: fengsun Created Header 4/28/98
//
//+----------------------------------------------------------------------------
BOOL CALLBACK CStatusDlg::KillRasMonitorWndProc(HWND hwnd, LPARAM lParam)
{
//
// SendMessage will block until the message returns, because we do not
// want to exit the connection thread before RasMinotor thread ended.
// CM sends a message from Connection thread to RasMonitor thread.
// Be careful about possible deadlock situation
// Cause Bug 166787
//
SendMessageA(hwnd, WM_CLOSE, (WPARAM)0, (LPARAM)0);
return TRUE;
}
//+----------------------------------------------------------------------------
//
// Function: CStatusDlg::DismissStatusDlg
//
// Synopsis: Dismisses the status dialog.
//
// Arguments: None
//
// Returns: Nothing
//
// History: quintinb Created Header 4/28/98
//
//+----------------------------------------------------------------------------
void CStatusDlg::DismissStatusDlg()
{
//
// Since OnOK is protected and virtual we will just add a member function
// to call it. We really just want to dismiss the dialog so it will be
// hidden again.
//
OnOK();
}
#ifdef DEBUG
//+----------------------------------------------------------------------------
//
// Function: CStatusDlg::AssertValid
//
// Synopsis: For debug purpose only, assert the object is valid
//
// Arguments: None
//
// Returns: Nothing
//
// History: Created Header 2/12/98
//
//+----------------------------------------------------------------------------
void CStatusDlg::AssertValid() const
{
MYDBGASSERT(m_fDisplayStatus == TRUE || m_fDisplayStatus == FALSE);
MYDBGASSERT(m_fStatusWindowVisible == TRUE || m_fStatusWindowVisible == FALSE);
MYDBGASSERT(m_pConnection != NULL);
}
#endif