⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 page1.cpp

📁 RAS高级编程实例
💻 CPP
📖 第 1 页 / 共 3 页
字号:
///////////////////////////////////////////////////////////////////////
// If this program works, it was written by Alexander Fedorov.
// If not, I don't know who wrote it.
// mailto:lamer2000@hotmail.com
// Home Page: http://members.xoom.com/lamer2000/
// This file is part of Alexf Dialer.
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
///////////////////////////////////////////////////////////////////////

// Page1.cpp : implementation file
//

#include "stdafx.h"
#include "Afd.h"
#include "Page1.h"
#include "PhoneNumberDlg.h"
#include "RunProgDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

extern CAfdApp theApp;

static HRASCONN hRasConn = NULL;

//回调函数,用来获得系统反馈回来的“连接状态信息”
VOID WINAPI RasDialFunc(UINT unMsg, RASCONNSTATE rasconnstate, DWORD dwError)
{
	TRACE("RasDialFunc\n");
	if (unMsg != WM_RASDIALEVENT) TRACE("Strange event!\n");
	//通过此函数来发送消息,传递当前的状态,给属性页1。
	//之所以这么设计,是因为这个函数不是CPage1类的成员函数,所以,为了把消息传递给类,就采用
	//发送消息的方法。其实,这只是一种方法,还有其他的方法可以实现回调函数跟类的成员函数通信,
	//例如:通过文件级的 类对象的指针。
	theApp.PostDialMessage(WM_DIAL_FUNC, rasconnstate, dwError);
	TRACE("RasDialFunc - exit\n");
}

//选中List控件中的第item(第二个输入参数)项
BOOL SelectLVItem(CListCtrl & list, int item)
{
	LV_ITEM lvi;
	ZeroMemory(&lvi, sizeof(lvi));
	lvi.iItem = item;
	lvi.mask = LVIF_STATE;
	if (!list.GetItem(&lvi)) return FALSE;
	lvi.state |= LVIS_FOCUSED | LVIS_SELECTED;
	lvi.stateMask |= LVIS_FOCUSED | LVIS_SELECTED;
	if (!list.SetItem(&lvi)) return FALSE;
	return list.EnsureVisible(item, FALSE);
}


/////////////////////////////////////////////////////////////////////////////
// CPage1 property page

IMPLEMENT_DYNCREATE(CPage1, CPropertyPage)

CPage1::CPage1() : CPropertyPage(CPage1::IDD)
{
	//{{AFX_DATA_INIT(CPage1)
	m_StatusText = _T("");
	m_LastCallText = _T("");
	//}}AFX_DATA_INIT
}

CPage1::~CPage1()
{
}

void CPage1::DoDataExchange(CDataExchange* pDX)
{
	CPropertyPage::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CPage1)
	DDX_Control(pDX, IDC_LIST_PHONES, m_PhoneList);
	DDX_Control(pDX, IDC_PROGRESS_TIMEOUT, m_ProgressTimeout);
	DDX_Control(pDX, IDC_COMBO_PROVIDER, m_Providers);
	DDX_Text(pDX, IDC_STATUS, m_StatusText);
	DDX_Text(pDX, IDC_LAST_CALL, m_LastCallText);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CPage1, CPropertyPage)
	//{{AFX_MSG_MAP(CPage1)
	ON_WM_DESTROY()
	ON_WM_TIMER()
	ON_BN_CLICKED(IDC_BUTTON_PROV_ADD, OnButtonProvAdd)
	ON_BN_CLICKED(IDC_BUTTON_PROV_EDIT, OnButtonProvEdit)
	ON_BN_CLICKED(IDC_BUTTON_PROV_DEL, OnButtonProvDel)
	ON_BN_CLICKED(IDC_BUTTON_TEL_ADD, OnButtonTelAdd)
	ON_BN_CLICKED(IDC_BUTTON_TEL_EDIT, OnButtonTelEdit)
	ON_BN_CLICKED(IDC_BUTTON_TEL_DEL, OnButtonTelDel)
	ON_BN_CLICKED(IDC_DIAL, OnDial)
	ON_CBN_SELCHANGE(IDC_COMBO_PROVIDER, OnSelchangeComboProvider)
	ON_NOTIFY(NM_CLICK, IDC_LIST_PHONES, OnClickListPhones)
//	ON_MESSAGE(WM_DIAL_NEXT_PHONE, OnDialNextPhone)
	ON_MESSAGE(WM_DIAL_FUNC, OnDialFunc)
//	ON_BN_CLICKED(IDC_BUTTON_DIAL, OnButtonDial)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CPage1 message handlers
//初始化属性一
BOOL CPage1::InitPropertyPage()
{
	CString sss;
	sss.LoadString(IDS_LIST1_COL1);
	m_PhoneList.InsertColumn(0, sss, LVCFMT_LEFT, 100);
	sss.LoadString(IDS_LIST1_COL2);
	//向电话号码列表框插入初始化电话号码
	m_PhoneList.InsertColumn(1, sss, LVCFMT_LEFT, 180);
	DWORD dwStyle = m_PhoneList.SendMessage(LVM_GETEXTENDEDLISTVIEWSTYLE);
	dwStyle |= LVS_EX_FULLROWSELECT;
	m_PhoneList.SendMessage(LVM_SETEXTENDEDLISTVIEWSTYLE, 0, (LPARAM)dwStyle);
	m_ProgressTimeout.SetRange32(0, 100);
	m_ProgressTimeout.ShowWindow(SW_HIDE);
	//初始化一些变量
	bPhone = FALSE;
	bDialNow = FALSE;
	bInOnTimer = FALSE;//初始化为false,表示:当前流程还没有进入OnTimer函数
	bConnected = FALSE;
	bDialing = FALSE;
	bAuthenticationBegin = FALSE;
	bSpeedChecked = FALSE;
	//查询电话簿,获得所有的计算机创建的连接,加入到组合框中。还要设置好组合框的当前(连接)项。
	QueryConnections();
	//查询目前的拨号情况
	QueryPhones(sCurrentProvider);
	//设定按钮状态
   	SetButtonsState();
	UpdateData(FALSE);
	//设定定时器
	uTimer = SetTimer(1, 1000, NULL);
	CheckExternalConnect();
	//需要注意的是,返回的是串在内存中的地址,而并不是串的内容。
	//CWinApp::m_lpCmdLine  Corresponds to the lpCmdLine parameter passed by Windows to WinMain. 
	//Points to a null-terminated string that specifies the command line for the application. 
	//Use m_lpCmdLine to access any command-line arguments the user entered when the application was started. m_lpCmdLine is a public variable of type LPTSTR.
	//经过调试发现,m_lpCmdLine的值是Afd
	return ParseArgs(theApp.m_lpCmdLine);
}

BOOL CPage1::OnInitDialog() 
{
	CPropertyPage::OnInitDialog();
	return TRUE;
}

void CPage1::OnDestroy() 
{
	KillTimer(uTimer);
	BOOL bTerminateWhenExit = atol(theApp.GetIniString(gchMain, gchEnableTerminateWhenExit, "1"));
	if (bTerminateWhenExit) HangUp(TRUE);
	CPropertyPage::OnDestroy();
}

void CPage1::OnTimer(UINT nIDEvent) 
{
	CPropertyPage::OnTimer(nIDEvent);
	// 如果流程还没有退出OnTimer函数,则返回,目的是为了防止重复进入OnTimer函数	if (bInOnTimer) return;
	// 设定为TRUE,这样就能防止重复进入此函数
	bInOnTimer = TRUE;
	// 如果当前不需要拨号,则
	if (!bDialing)
	{
		//如果当前不是正在拨号,也不是已经连通了,则
		if ((!bDialNow) && (!bConnected)) CheckExternalConnect();
		bInOnTimer = FALSE;
		return;
	}
	//如果当前已经拨号连通了,则	if (bConnected)
	{
		CheckingConnected();
		bInOnTimer = FALSE;
		return;
	}
	if (bDialNow) CheckingDialing();
	else
	// 开始拨号
	StartDial();
	//定时器变量改为FALSE
	bInOnTimer = FALSE;
}

BOOL CPage1::OnSetActive() 
{
	return CPropertyPage::OnSetActive();
}

//增加新的连接
void CPage1::OnButtonProvAdd() 
{
	RasCreatePhonebookEntry(GetSafeHwnd(), sCurrentProvider);
	QueryConnections();
}

//编辑已有连接
void CPage1::OnButtonProvEdit() 
{
	RasEditPhonebookEntry(GetSafeHwnd(), NULL, sCurrentProvider);
	QueryConnections();
}

//删除连接
void CPage1::OnButtonProvDel() 
{
	int i = AfxMessageBox(IDS_DELETE_CONNECTION, MB_YESNO | MB_ICONQUESTION);
	if (i != IDYES) return;
	//结构体
	typedef DWORD (WINAPI* RDE)
	(
		LPCTSTR lpszPhonebook,  // pointer to full path and filename of 
		LPCTSTR lpszEntry	   // pointer to an entry name to delete
	);
	// 载入动态库
	HINSTANCE hLib = LoadLibrary(_T("RASAPI32.DLL"));
	if (NULL == hLib) return;
	RDE rde = (RDE) GetProcAddress(hLib, "RasDeleteEntryA");
	if (rde != NULL)
	{
		rde(NULL, sCurrentProvider);
		QueryConnections();
		QueryPhones(sCurrentProvider);
	}
	::FreeLibrary(hLib);
}

//增加拨号的号码
void CPage1::OnButtonTelAdd() 
{
	CPhoneNumberDlg dlg;
	int nResponse = dlg.DoModal();
	if (nResponse != IDOK) return;
	UINT pn = atoi(theApp.GetIniString(sCurrentProvider, "Phones", "0"));
	pn++;
	theApp.SetIniString(sCurrentProvider, "Phones", L2S(pn));
	theApp.SetIniString(sCurrentProvider,"Phone" + L2S(pn), dlg.m_sNumber);
	theApp.SetIniString(sCurrentProvider,"Comment" + L2S(pn), dlg.m_sComments);
	theApp.SetIniString(sCurrentProvider,"LastPhone", L2S(pn));
	QueryPhones(sCurrentProvider);
}

void CPage1::OnButtonTelEdit() 
{
	CPhoneNumberDlg dlg;
	dlg.m_sNumber = GetPhoneListSelection();
	UINT lph = atoi(theApp.GetIniString(sCurrentProvider, "LastPhone", "1"));
	dlg.m_sComments = theApp.GetIniString(sCurrentProvider, "Comment" + L2S(lph), "");
	int nResponse = dlg.DoModal();
	if (nResponse != IDOK) return;
	UINT pn = atoi(theApp.GetIniString(sCurrentProvider, "Phones", "0"));
	CString sss;
	for (UINT i = 0; i < pn; i++)
	{
		sss = theApp.GetIniString(sCurrentProvider, "Phone" + L2S(i + 1), "-");
		if (sss != GetPhoneListSelection()) continue;
		sss = dlg.m_sNumber;
		theApp.SetIniString(sCurrentProvider, "Phone" + L2S(i + 1), sss);
		sss = dlg.m_sComments;
		theApp.SetIniString(sCurrentProvider, "Comment" + L2S(i + 1), sss);
		break;
	}
	QueryPhones(sCurrentProvider);
}

void CPage1::OnButtonTelDel() 
{
	int j = AfxMessageBox(IDS_DELETE_PHONE, MB_YESNO | MB_ICONQUESTION);
	if (j != IDYES) return;
	UINT pn = atoi(theApp.GetIniString(sCurrentProvider, "Phones", "0"));
	UINT lph = atoi(theApp.GetIniString(sCurrentProvider, "LastPhone", "1"));
	CString sss;
	for (UINT i = 0; i < pn; i++)
	{
		sss = theApp.GetIniString(sCurrentProvider, "Phone" + L2S(i + 1), "-");
		if (sss != GetPhoneListSelection()) continue;
		sss = theApp.GetIniString(sCurrentProvider, "Phone" + L2S(pn), "-");
		theApp.SetIniString(sCurrentProvider,"Phone" + L2S(i + 1), sss);
		pn--;
		if (lph > pn) lph = pn;
		theApp.SetIniString(sCurrentProvider, "Phones", L2S(pn));
		theApp.SetIniString(sCurrentProvider, "LastPhone", L2S(lph));
		break;
	}
	QueryPhones(sCurrentProvider);
}

//“Dial”按钮的消息处理函数,需要注意的是:这个函数并不是真正执行拨号操作的函数,真正的
//执行拨号操作的函数(StartDial())是在定时器的处理函数中被调用的。
//那么,真正的拨号函数是如何被调用的呢?
//答案是:将变量bDialing置为true,然后,在定时器处理函数中,根据这些变量来决定,是否应该拨号。
void CPage1::OnDial() 
{
	if (!bDialing)
	{
		bDialing = TRUE;
		theApp.LOG(CString("Dial:<" + sCurrentProvider) +
		CString("> using phone:<" + GetPhoneListSelection()) + ">.");
	}
	else
	{
		TRACE("OnHangup()\n");
		theApp.LOG("Hang Up button pressed.");
		bDialing = FALSE;
		HangUp(FALSE);
	}
   	SetButtonsState();
}

void CPage1::OnSelchangeComboProvider() 
{
	m_Providers.GetLBText(m_Providers.GetCurSel(), sCurrentProvider);
	m_StatusText = sCurrentProvider;
	theApp.SetIniString(gchMain, "LastEntry", sCurrentProvider);
	QueryPhones(sCurrentProvider);
	UpdateData(FALSE);
	theApp.NotifyProviderChanged();
}

void CPage1::OnClickListPhones(NMHDR* pNMHDR, LRESULT* pResult) 
{
	GetPhoneListSelection();
	*pResult = 0;
}

//查询电话簿,获得所有的计算机创建的连接,加入到组合框中。还要设置好当前连接项
BOOL CPage1::QueryConnections()
{
	DWORD cbBuf;
	DWORD cEntry;
	UINT  ndx;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -