在 Pocket PC 中以编程方式修改拨号参数/模式
了解如何使用非托管的 Windows CE DLL 作为 thunking 层来修改 RAS 连接的拨号参数。
引言
拨号参数/模式是信息字符串,用于控制在 Pocket PC 中建立 RAS 连接时如何拨打电话号码。例如
- 9,G 将拨打 9,然后拨打基本电话号码。
- 1FG 将拨打 1,区号,然后是电话号码。
本项目中的代码将解释如何解释上面屏幕截图中的每个字段。
使用代码
现在,修改设备注册表并不难,但是存储设置的类型/格式使得修改这些设置变得不那么明显。为了让您免于弄清这些问题的烦恼,我已经为您完成了这项脏活。请注意下面来自设备注册表的屏幕截图
HKEY_CURRENT_USER\ControlPanel\Dial\Locations
您可能会说,这很好,但是国家/地区代码、音调/脉冲拨号和禁用呼叫等待拨号字符串的设置在哪里呢?
在问了自己这个问题之后,我做了一些谷歌研究,发现注册表实际上以以下格式存储值
- Location
- 本地电话拨号字符串
- 长途电话拨号字符串
- 国际电话拨号字符串
- 区号拨号字符串
- 国家代码
- 禁用呼叫等待拨号字符串
- 音调或脉冲,其中音调 = 0,脉冲 = 1
REG_MULTI_SZ
类型的注册表项。根据 Pocket PC 2002 SDK 文档,REG_MULTI_SZ
是一个以空字符结尾的字符串数组,以两个空字符结尾。因此,注册表编辑器在显示这个字符串数组时会有点困惑,然后您就会被带到一个寻找剩余设置的疯狂追逐中,最终在几天后确定它们一直就在您眼前。现在我们知道了所有设置的真正存储位置,我们可以开始编码了。
// C++ Code BOOL WINAPI SetDialingParameters(WCHAR *KeyName, WCHAR *Location, WCHAR *LocalCalls, WCHAR *LongDistanceCalls, WCHAR *InternationalCalls, WCHAR *AreaCode, WCHAR *DisableCallWaitingSequence, WCHAR *CountryCode, WCHAR *ToneOrPulse ) { HKEY hKey; DWORD dataType = REG_MULTI_SZ; LONG retVal = 0; LONG ConfigurationStringSize = 512; WCHAR *ConfigurationString = new WCHAR[ConfigurationStringSize]; memset(ConfigurationString,'\0',512); // Build the configuration string. wcscat(ConfigurationString, Location); wcscat(ConfigurationString, TEXT("$")); wcscat(ConfigurationString, LocalCalls); wcscat(ConfigurationString, TEXT("$")); wcscat(ConfigurationString, LongDistanceCalls); wcscat(ConfigurationString, TEXT("$")); wcscat(ConfigurationString, InternationalCalls); wcscat(ConfigurationString, TEXT("$")); wcscat(ConfigurationString, AreaCode); wcscat(ConfigurationString, TEXT("$")); wcscat(ConfigurationString, DisableCallWaitingSequence); wcscat(ConfigurationString, TEXT("$")); wcscat(ConfigurationString, CountryCode); wcscat(ConfigurationString, TEXT("$")); wcscat(ConfigurationString, ToneOrPulse); wcscat(ConfigurationString, TEXT("$")); // Format the string correctly. int ConfigStringLen = wcslen(ConfigurationString); for(int x = 0; x < ConfigStringLen; ++x) { if(ConfigurationString[x] == '$') ConfigurationString[x] = '\0'; } // Open the registry key. retVal = RegOpenKeyEx(HKEY_CURRENT_USER , TEXT("ControlPanel\\Dial\\Locations"), 0, KEY_READ, &hKey); if(retVal != ERROR_SUCCESS) { delete [] ConfigurationString; return false; } // Set the value of the key. retVal = RegSetValueEx(hKey, KeyName, NULL, dataType, (PBYTE)ConfigurationString, ConfigurationStringSize); RegCloseKey(hKey); delete [] ConfigurationString; if(retVal != ERROR_SUCCESS) return false; else return true; }
这就是存储密钥所需的全部代码!当然,现在我们希望将它放入 DLL 中,以便我们可以从我们的应用程序中调用它。有关此方面的详细信息,请参阅本文顶部的源文件。
创建 DLL 后,您将需要充分利用它。现在,我们将演练从托管代码中 P/Invoking DLL,因为这可能是你们大多数人将要使用的。
启动 Visual Studio .NET 2003,并为 Pocket PC 创建一个新的 Smart Device 应用程序。
为您的 P/Invoke 方法创建一个新类,并将以下代码插入到您的类定义中
// C# Code [System.Runtime.InteropServices.DllImport("DialingParameters.dll")] public static extern int SetDialingParameters(string KeyName, string Location, string LocalCalls, string LongDistanceCalls, string InternationalCalls, string AreaCode, string DisableCallWaitingSequence, string CountryCode, string ToneOrPulse );就是这样!要从 EVB 调用此 DLL,您需要在表单顶部进行声明,就像以下内容一样
Declare Function RasDial Lib "DialingParameters.dll" Alias "SetDialingParameters" (ByVal KeyName As String, ByVal Location As String, ByVal LocalCalls As String, ByVal LongDistanceCalls As String, ByVal InternationalCalls As String, ByVal AreaCode As String, ByVal DisableCallWaitingSequence As String, ByVal CountryCode As String, ByVal ToneOrPulse As String ) As Long
关注点
请记住将您的 EVC DLL 保存在与您的使用应用程序相同的文件夹中,否则您的方法调用将失败。