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

📄 page1.cpp

📁 RAS高级编程实例
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	char  szMessage[256];
	m_Providers.ResetContent();
	//在程序上一次退出的时候,会记录下ComboBox中的当前选项(存到ini文件中的Main块中的
	//"LastEntry"条目中),然后,在下一次加载程序的时候,执行到这里,再把保存的信息读取出来,
	//放到sCurrentProvider串中。我估计,在后面的代码中,还会恢复ComboBox中的当前选项为上一次
	//退出时候的情况。
	sCurrentProvider = theApp.GetIniString(gchMain, "LastEntry", "");

	DWORD dwRet;
	LPBYTE lpBuffer;

	LPRASENTRYNAME lpRasEntry = new RASENTRYNAME;
	lpRasEntry->dwSize = sizeof(RASENTRYNAME);
	//获得所有连接
	dwRet = RasEnumEntries(NULL, NULL, lpRasEntry, &cbBuf, &cEntry);
	//delete lpRasEntry;

	//lpBuffer = new BYTE[cbBuf];
	//lpRasEntry = (LPRASENTRYNAME)lpBuffer;
	//lpRasEntry->dwSize = sizeof(RASENTRYNAME);
	dwRet = RasEnumEntries(NULL, NULL, lpRasEntry, &cbBuf, &cEntry);
	//delete[] lpBuffer;

	//下面是出错处理,If the function succeeds, the return value is zero.所以,所有不是0的
	//返回值,都表示有错误发生
	if (ERROR_BUFFER_TOO_SMALL == dwRet) //“输出缓冲区太小,装不下输出值”的错误
	{
		delete lpRasEntry;
		lpRasEntry = NULL;
		lpRasEntry = (LPRASENTRYNAME) new char[cbBuf];
		if (NULL != lpRasEntry)
		{
			ZeroMemory(lpRasEntry, cbBuf);
			lpRasEntry->dwSize = cbBuf;
			dwRet = RasEnumEntries(NULL, NULL, lpRasEntry, &cbBuf, &cEntry);
		}
		else
			dwRet = ERROR_NOT_ENOUGH_MEMORY;
	}
	if (0 != dwRet) // 其他错误
	{
		if (0 != RasGetErrorString((UINT)dwRet, szMessage, 256))
		{
			CString sss; sss.LoadString(IDS_RASCS_25);
			wsprintf((LPSTR)szMessage, sss);
		}
		m_StatusText = szMessage;
		UpdateData(FALSE);
	}
	//如果列举出来的电话簿条目数量是0,则
	if (0 == cEntry)
	{
		delete lpRasEntry ;
		return FALSE;
	}
	BOOL bSet = FALSE; //这个局部变量,是用来记录:是否在电话簿中发现了上一次退出时ComboBox中的当前被选中的条目。如果发现了,就把那个条目设置为ComboBox的当前被选中的条目。
	if (0 == dwRet)  // 没有错误
	{
		for (ndx = 0; ndx < cEntry; ndx++)
		{
			m_Providers.InsertString(ndx, lpRasEntry[ndx].szEntryName);
			if (lpRasEntry[ndx].szEntryName == sCurrentProvider)
			{
				m_Providers.SetCurSel(ndx);
				bSet = TRUE;//表示已经设置好了“ComboBox中的当前被选中的条目”
			}
		}
		//如果没设置好,就把第一个条目设置为当前条目
		if (!bSet)
		{
			m_Providers.SetCurSel(0);
			sCurrentProvider = lpRasEntry[0].szEntryName;//将第一个条目的内容记录到sCurrentProvider变量中
		}
	}
	delete lpRasEntry ;
	return TRUE;
}

//获得以前所拨过的电话号码,从应用程序的ini文件中读出,显示到List控件中
BOOL CPage1::QueryPhones(CString sEntryName)
{
	//清空List Control控件
	m_PhoneList.DeleteAllItems();
	//获取ini文件中保存的Phones条目的值,如果没有,就返回缺省值0
	UINT pn = atoi(theApp.GetIniString(sEntryName, "Phones", "0"));
	//如果"Phones"条目的值是0,表示电话簿中没有号码,则
	if (1 == pn)
	{
		//NT或Win2000的电话簿放在:系统根目录\system32\Ras\RasPhone.pbk
		//从系统的电话簿中读取当前使用的连接(例如ADSL)的属性,然后将其写入到ini文件中
		//当前使用的连接为ADSL的时候,向ini文件中写入的信息是:
		//[ADSL]块中的Phones条目的值是1;
		//[ADSL]块中的Phone1条目的值是空串;
		bPhone = LoadDefautPhoneNumber(sEntryName);
		pn = 1;//因为加载了一个缺省号码,所以,需要修改pn变量的值了
	}
	else
		bPhone = FALSE;
	if (!bPhone) return FALSE;
	CString sss;
	//这个变量用来记载跳过的循环次数,目的是为了使List控件中的item的下标值正确。
	//用一个循环,将ini文件中,ADSL块中,的所有的电话号码,都添加到List控件中。
	for (UINT i = 0; i < pn; i++)
	{
		sss = theApp.GetIniString(sEntryName, "Phone" + L2S(i + 1), "-");
		if (sss.IsEmpty()) continue;//如果电话号码是空串,就不添加了
		m_PhoneList.InsertItem(i, sss);//将取出来的电话号码,插入到List控件中
		sss = theApp.GetIniString(sEntryName, "Comment" + L2S(i + 1), "");
		if (!sss.IsEmpty())
		{
			LV_ITEM lvi;
			lvi.mask = LVIF_TEXT;
			lvi.iItem = i;
			lvi.iSubItem = 1;
			lvi.pszText = sss.GetBuffer(512);
			m_PhoneList.SetItem(&lvi);//将注释内容写入刚插入的电话号码条目中(的第二栏中)
			sss.ReleaseBuffer();
		}
	}
	//从ini文件中,取出“LastPhone”条目的内容(就是拨的上一个电话)
	UINT lpn = atoi(theApp.GetIniString(sEntryName, "LastPhone", "1"));
	if (lpn > pn) lpn = pn;
	SelectLVItem(m_PhoneList, lpn - 1);//选中List控件中的第lpn - 1项
	SetButtonsState();
	return TRUE;
}


BOOL CPage1::ParseArgs(CString sss)
{
	int i;
	CString aaa;
	BOOL bNeedReload = FALSE;
	aaa = sss;
	aaa.MakeUpper();
	i = aaa.Find("/?");
	if (i != -1)
	{
		AfxMessageBox(IDS_ARG_HELP);
	}
	aaa.MakeUpper();
	i = aaa.Find("/C\"");
	if (i != -1)
	{
		aaa = sss.Mid(i + 3, sss.GetLength());
		i = aaa.Find("\"");
		if (i > 0)
		{
			aaa = aaa.Mid(0, i);
			theApp.SetIniString(gchMain,"LastEntry", aaa);
			bNeedReload = TRUE;
		}
	}
	aaa = sss;
	aaa.MakeUpper();
	i = aaa.Find("/P");
	if (i != -1)
	{
		aaa = sss.Mid(i + 2, sss.GetLength());
		i = atol(aaa);
		if (i != 0)
		{
			theApp.SetIniString(
			sCurrentProvider, "LastPhone", L2S(i));
			bNeedReload = TRUE;
		}
	}
	if (bNeedReload)
	{
		QueryConnections();
		QueryPhones(sCurrentProvider);
	}
	CString s1, s2;
	aaa = sss;
	aaa.MakeUpper();
	i = aaa.Find("/D");
	if (i != -1) OnDial();
	return TRUE;
}

//set 属性页中的各个控件的状态
void CPage1::SetButtonsState()
{
	CString sss;
	GetDlgItem(IDC_BUTTON_TEL_ADD)->EnableWindow(!sCurrentProvider.IsEmpty());
	GetDlgItem(IDC_BUTTON_TEL_EDIT)->EnableWindow(bPhone);
	GetDlgItem(IDC_BUTTON_TEL_DEL)->EnableWindow(!bDialing && bPhone);
	GetDlgItem(IDC_BUTTON_PROV_DEL)->EnableWindow(!bDialing);
	UINT pn = atoi(theApp.GetIniString(sCurrentProvider, "Phones", "0"));

	//如果电话号码数少于2,则 禁用 那个“删除”按钮
	if (pn <= 1) GetDlgItem(IDC_BUTTON_TEL_DEL)->EnableWindow(FALSE);
	//判断现在是否有上网,如果有上网,则锁定下拉框
	GetDlgItem(IDC_COMBO_PROVIDER)->EnableWindow(!bDialing);

	//如果当前不是正在上网,并且加载电话号码成功,则
	if (!bDialing && bPhone)
	sss.LoadString(IDS_DIAL);//加载"Dial"串,表示那个两用的大按钮当前功能是“拨号”
	else
	sss.LoadString(IDS_HANGUP);//加载"Hang Up"串,表示大按钮当前功能是“挂断”
	GetDlgItem(IDC_DIAL)->SetWindowText(sss);
	m_ProgressTimeout.ShowWindow(SW_HIDE);//隐藏进度条控件
	//从ini文件中读取:是否需要Enable拨号超时值
	BOOL m_bMaxWaitTime = atol(theApp.GetIniString(gchMain, gchEnableTimeout, "0"));
	//如果Enable了拨号超时值,并且正在拨号,并且尚没拨通,则
	if (m_bMaxWaitTime && bDialing && !bConnected)
	{
		m_ProgressTimeout.ShowWindow(SW_SHOW);//显示进度条
	}
	m_ProgressTimeout.SetPos(0);//设置进度条控件的位置为0
}

//载入默认的电话号码。我家的电脑的ADSL设置之中,并没有缺省的号码,所以,
//最后向ini文件中写入的信息是:
//[ADSL]块中的Phones条目的值是1;
//[ADSL]块中的Phone1条目的值是空串;
//返回值:true表示成功;
BOOL CPage1::LoadDefautPhoneNumber(CString sEntryName)
{
//定义一个函数指针类型
typedef DWORD (WINAPI* RGEPA)
(LPCTSTR lpszPhonebook,		// pointer to full path and filename of 
							// phone-book file
  LPCTSTR lpszEntry,		// pointer to an entry name
  LPRASENTRY lpRasEntry,	// buffer that receives entry information
  LPDWORD lpdwEntryInfoSize,	// size, in bytes, of the lpRasEntry 
								// buffer
  LPBYTE lpbDeviceInfo,			// buffer that receives device-specific 
								// configuration information
  LPDWORD lpdwDeviceInfoSize	// size, in bytes, of the 
								// lpbDeviceInfo buffer
);
// 动态 load a library
	HINSTANCE hLib = LoadLibrary(_T("RASAPI32.DLL"));
	if (NULL == hLib) return FALSE;
	//获得RasGetEntryProperties函数的入口点
	RGEPA rgepa = (RGEPA) GetProcAddress(hLib, "RasGetEntryPropertiesA");
	if (NULL == rgepa)//防错处理
	{
		::FreeLibrary(hLib);
		return FALSE;
	}
	RASENTRY RasEntry;
	DWORD dw = sizeof(RASENTRY);
	ZeroMemory(&RasEntry, dw);//初始化结构体变量RasEntry的数据为全0
	RasEntry.dwSize = dw;
	//调用RasGetEntryProperties函数,获取“ADSL”条目的属性值。
	//The RasGetEntryProperties function retrieves the properties of a phone-book entry.
	DWORD ret = rgepa(NULL, sEntryName, &RasEntry, &dw, NULL, NULL);
	::FreeLibrary(hLib);//释放动态加载的DLL
	if (ret != 0) return FALSE;//又是防错处理

	CString phone;
	//如果要使用国家和地区号,则
	if (RasEntry.dwfOptions & RASEO_UseCountryAndAreaCodes)
	{
		phone = "8w";
		phone += RasEntry.szAreaCode;//区号
		phone += RasEntry.szLocalPhoneNumber;//电话号码
	}
	else
	phone = RasEntry.szLocalPhoneNumber;//RasEntry.szLocalPhoneNumber是空串。
	//当此函数的参数sEntryName是“ADSL”,流程执行到这里,phone的内容是空串。
	UINT pn = 1;
	//向ini文件中写入两条信息
	theApp.SetIniString(sEntryName, "Phones", L2S(pn));
	theApp.SetIniString(sEntryName,"Phone" + L2S(pn), phone);
	return TRUE;
}

//挂断拨号
BOOL CPage1::HangUp(BOOL bExitApp)
{
	DWORD dwRet;
	RASCONNSTATUS rStatus;
	ZeroMemory(&rStatus, sizeof(RASCONNSTATUS));
	rStatus.dwSize = sizeof(RASCONNSTATUS);
	dwRet = RasGetConnectStatus(hRasConn, &rStatus);
	if ((dwRet != ERROR_INVALID_HANDLE) || (bDialNow))
	{
		bDialNow = FALSE;
		theApp.FinishSession();
		//挂断连接
		RasHangUp(hRasConn);
		dwRet = RasGetConnectStatus(hRasConn, &rStatus);
		m_StatusText.LoadString(IDS_TERMINATING_CONN);
		UpdateData(FALSE);
		//获得当前时间
		CTime t1 = CTime::GetCurrentTime();
		CTimeSpan ts;
		MSG msg;
		while (dwRet != ERROR_INVALID_HANDLE)
		{
			while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
			{
				TranslateMessage(&msg);
				DispatchMessage(&msg);
			}
			dwRet = RasGetConnectStatus(hRasConn, &rStatus);
			ts = CTime::GetCurrentTime() - t1;
			if (!bExitApp)
			if (ts.GetTotalSeconds() > 3) break;
		}
		//设定日志
		theApp.LOG("HangUp.");
		m_StatusText.LoadString(IDS_PAUSE);
		UpdateData(FALSE);
		if (bConnected) theApp.RunProgramsOnEvent(RUN_HANGUP);
	}
	Sleep(500);
	m_StatusText.Empty();
	UpdateData(FALSE);
	bConnected = FALSE;
	return TRUE;
}

BOOL CPage1::PublicOnDial()
{
	OnDial();
	return TRUE;
}


LRESULT CPage1::OnDialFunc(WPARAM w, LPARAM l)
{

	char szMessage[256];
   
	//将回调函数返回回来的状态信息,翻译成用户可以理解的同等内容。
	m_StatusText = GetRasConnState((RASCONNSTATE) w);
	UpdateData(FALSE);
	if (l)  // 错误产生
	{
		if (RasGetErrorString((UINT) l, szMessage, 256) != 0)
		{
			CString sss; sss.LoadString(IDS_RASCS_25);
			wsprintf((LPSTR)szMessage, sss);
		}
		m_LastCallText = szMessage;
		TRACE(CString("External error ") + CString(szMessage) + "\n");

⌨️ 快捷键说明

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