📄 page1.cpp
字号:
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 + -