Александр Климов - Программирование КПК и смартфонов на .NET Compact Framework
using System.Reflection;
namespace PlaySound_CS {
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
InitializeComponent();
#if DEBUG
MinimizeBox = false;
#else
MinimizeBox = true;
#endif
}
private void butResource_Click(object sender, EventArgs e) {
Sound sound =
new Sound(Assembly.GetExecutingAssembly().GetManifestResourceStream(
"PlaySound_CS.chimes.wav"));
sound.Play();
}
private void butFile_Click(object sender, EventArgs e) {
Sound sound = new Sound("Windows\alarm3.wav");
sound.Play();
}
}
}
Системные звуки
Также разработчик может использовать функцию MessageBeep, позволяющую проигрывать системные звуки. Код, использующий эту функцию, приведен в листинге 13.13.
Листинг 13.13[DllImport("coredll.dll")]
extern static void MessageBeep(uint BeepType);
private void butBeep_Click(object sender, EventArgs e) {
MessageBeep(0);
}
Системное время
Чтобы получить или установить системное время на устройстве, нужно использовать функции GetSystemTime и SetSystemTime. Следует учитывать, что функция GetSystemTime возвращает время по Гринвичу, а не местное время. Код, иллюстрирующий применение этих функций, приведен в листинге 13.14.
Листинг 13.14using System.Runtime.InteropServices;
[DllImport("coredll.dll")]
private extern static void GetSystemTime(ref SYSTEMTIME lpSystemTime);
[DllImport("coredll.dll")]
private extern static uint SetSystemTime(ref SYSTEMTIME lpSystemTime);
private struct SYSTEMTIME {
public ushort wYear;
public ushort wMonth;
public ushort wDayOfWeek;
public ushort wDay;
public ushort wHour;
public ushort wMinute;
public ushort wSecond;
public ushort wMilliseconds;
}
private void GetTime() {
// Получим системное время
SYSTEMTIME st = new SYSTEMTIME();
GetSystemTime(ref st);
DateTime dt = DateTime.UtcNow.ToLocalTime();
// Выводим сообщение
MessageBox.Show("Текущее время: " + st.wHour.ToString() + ":" +
st.wMinute.ToString());
}
private void SetTime() {
// Сначала получим системное время
SYSTEMTIME st = new SYSTEMTIME();
GetSystemTime(ref st);
// А теперь прибавим один час
st.wHour = (ushort)(st.wHour + 1 % 24);
SetSystemTime(ref st);
MessageBox.Show("Новое время: " + st.wHour.ToString() + ":" +
st.wMinute.ToString());
}
private void butGetTime_Click(object sender, EventArgs e) {
GetTime();
}
private void butSetTime_Click(object sender, EventArgs e) {
SetTime();
}
Создание ярлыка
В некоторых случаях программисту необходимо создать ярлык к какой-либо программе. В этом случае можно воспользоваться специальной функцией SHCreateShortcut, применение которой демонстрируется в листинге 13.15.
Листинг 13.15/// <summary>
/// Функция для создания ярлыка
/// </summary>
/// <param name="szShortcut">Строка, содержащая
/// путь и имя создаваемого ярлыка.
///</param>
/// <param name="szTarget">Строка, содержащая
/// путь и аргументы для ярлыка.
/// Размер строки ограничен 256 символами.
/// </param>
/// <returns>B успешном случае возвращается TRUE,
/// в случае ошибки возвращается FALSE
/// </returns>
[DllImport("coredll.dll", EntryPoint = "SHCreateShortcut")]
private static extern bool SHCreateShortcut(string szShortcut,
string szTarget);
private void butCreateShortcut_Click(object sender, EventArgs e) {
// Создадим ярлык к калькулятору
bool success = SHCreateShortcut("\My Documents\Shortcut.lnk",
"\Windows\calс.exe"");
}
В этом примере создается ярлык Shortcut.lnk для стандартного калькулятора, чей исполняемый файл носит имя windowscalc.exe.
Количество строк в текстовом поле
Если у текстового поля свойство Multiline имеет значение True, то свойство Lines возвращает массив строк в текстовом поле. Но у данного свойства есть два недостатка. Во-первых, свойство Lines не поддерживается библиотекой .NET Compact Framework, а во-вторых, это свойство не учитывает перенос слов. Для подсчета количества строк в многострочном текстовом поле можно использовать сообщение EM_GETLINECOUNT. Соответствующий код приведен в листинге 13.16.
Листинг 13.16[DllImport("coredll.dll")]
static extern int SendMessage(IntPtr hwnd, int msg, int wParam, int lParam);
const int EM_GETLINECOUNT = 0x00BA;
private void butGetNumber_Click(object sender, EventArgs e) {
// Узнаем число строк в текстовом поле
int numberOfLines = SendMessage(textBox1.Handle, EM_GETLINECOUNT, 0, 0);
sbInfo.Text = "Число строк: " + numberOfLines.ToString();
}
Реестр
Реестр является важной частью любой операционной системы семейства Windows. Не является исключением и система Windows Mobile, в которой тоже имеется собственный реестр. Однако разработчики компании Microsoft не стали включать редактор реестра в состав Windows Mobile. Поэтому для доступа к разделам реестра приходится устанавливать программы от сторонних производителей.
Однако любой программист может написать свой редактор реестра, используя возможности .NET Compact Framework. При этом следует учитывать, что в библиотеке .NET Compact Framework 2.0 появились классы для работы с разделами реестра. Если же вы продолжаете писать программы с использованием .NET Compact Framework 1.0, то придется вызывать функции Windows API.
В листинге 13.17 приведен код, который будет работать в любой версии .NET Compact Framework.
Листинг 13.17using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace Registry_CS {
class Registry {
/// <summary>
/// Создает ключ
/// </summary>
/// <param name="keyName">Имя создаваемого ключа</param>
/// <returns>B успешном случае возвращается
/// ERROR_SUCCESS</ returns>
public static int CreateKey(UIntPtr root, string keyName) {
UIntPtr hkey = UintPtr.Zero;
uint disposition = 0;
try {
return
RegCreateKeyEx(root, keyName, 0, null, 0, KeyAccess.None, IntPtr.Zero,
ref hkey, ref disposition);
} finally {
if (UIntPtr.Zero != hkey) {
RegCloseKey(hkey);
}
}
}
/// <summary>
/// Удаляет ключ
/// </summary>
/// <param name="keyName">Имя ключа</param>
/// <returns>B успешном случае возвращается
/// ERROR_SUCCESS</returns>
public static int DeleteKey(UIntPtr root, string keyName) {
return RegDeleteKey(root, keyName);
}
/// <summary>
/// Создает строковой параметр в заданном ключе
/// </summary>
/// <param name="keyName">Имя ключа</param>
/// <param name="valueName">Имя параметра</param>
/// <param name="stringData">Значение параметра</param>
/// <returns>В успешном случае возвращается
/// ERROR_SUCCESS</returns>
public static int CreateValueString(string keyName, string valueName,
string stringData) {
UIntPtr hkey = UintPtr.Zero;
try {
int result = RegOpenKeyEx(root, keyName, 0, KeyAccess.None, ref hkey);
if (ERROR_SUCCESS != result) return result;
byte[] bytes = Encoding.Unicode.GetBytes(stringData);
return RegSetValueEx(hkey, valueName, 0, KeyType.String, bytes,
(uint)bytes.Length);
} finally {
if (UIntPtr.Zero != hkey) {
RegCloseKey(hkey);
}
}
}
/// <summary>
/// Создает параметр типа DWORD в заданном ключе
/// </summary>
/// <param name="keyName">Имя ключа</param>
/// <param name="valueName">Имя параметра</param>
/// <param name="dwordData">Значение параметра</param>
/// <returns>В успешном случае возвращается
/// ERROR_SUCCESS</returns>
public static int CreateValueDWORD(UIntPtr root, string keyName,
string valueName, uint dwordData) {
UIntPtr hkey = UintPtr.Zero;
try {
int result = RegOpenKeyEx(root, keyName, 0, KeyAccess.None, ref hkey);
if (ERROR_SUCCESS != result) return result;
byte[] bytes = BitConverter.GetBytes(dwordData);
return RegSetValueEx(hkey, valueName, 0, KeyType.Dword, bytes,
(uint)bytes.Length);
} finally {
if (UIntPtr.Zero != hkey) {
RegCloseKey(hkey);
}
}