Книга: Программирование КПК и смартфонов на .NET Compact Framework

Стандартные операции с текстом

Стандартные операции с текстом

На данной стадии уже создан первый прототип приложения. После запуска программы пользователь может вводить и удалять текст с помощью SIP. Но этого недостаточно для комфортной работы с текстом.

Пользователь должен иметь возможность манипулировать текстом, то есть копировать часть текста, вырезать его, удалять и вставлять в нужную позицию. Для этого надо создать меню при помощи элемента mainMenu. В подменю Правка надо добавить стандартные команды редактирования текста — Отменить, Вырезать, Копировать, Вставить. Если бы приложение создавалось для среды исполнения .NET Compact Framework 2.0, то можно было бы использовать класс Clipboard. Но так как используется .NET Compact Framework 1.0, то придется обратиться к функциям Windows API и использовать неуправляемый код, что иллюстрирует листинг 7.32.

Листинг 7.32

// сообщения буфера обмена
public const int WM_CUT = 0x0300;
public const int WM_COPY = 0x0301;
public const int WM_PASTE = 0x0302;
public const int WM_CLEAR = 0x0303;
public const int WM_UNDO = 0x0304;
// функции API
[DllImport("coredll.dll", CharSet = CharSet.Unicode)]
public static extern IntPtr GetFocus();
[DllImport("coredll.dll")]
public static extern int SendMessage(IntPtr hWnd, uint Message,
 uint wParam, uint lParam);
private void mnuCut_Click(object sender, EventArgs e) {
 // Вырезаем текст
 SendMessage(hwndEditor, WM_CUT, 0, 0);
}
private void mnuUndo_Click(object sender, EventArgs e) {
 // Отменяем последнее действие
 SendMessage(hwndEditor, WM_UNDO, 0, 0);
}
private void mnuCopy_Click(object sender, EventArgs e) {
 // Копируем выделенный текст
 SendMessage(hwndEditor, WM_COPY, 0, 0);
}
private void mnuPaste_Click(object sender, EventArgs e) {
 // Вставляем текст из буфера обмена
 SendMessage(hwndEditor, WM_PASTE, 0, 0);
}
private void mnuDelete_Click(object sender, EventArgs e) {
 // Удаляем выделенный текст
 SendMessage(hwndEditor, WM_CLEAR, 0, 0);
}

Теперь необходимо добавить в создаваемое приложение поддержку контекстного меню. Использование контекстного меню избавит пользователя от необходимости постоянно переводить стилус в нижнюю часть экрана для доступа к командам меню. В программу нужно добавить элемент управления ContextMenu и сделать список команд меню, который будет дублировать подпункт основного меню Правка. Созданное контекстное меню надо связать с текстовым полем при помощи свойства ContextMenu. Осталось только скопировать код из команд основного меню в соответствующие места для команд контекстного меню. Например, для команды контекстного меню Копировать надо использовать код, приведенный в листинге 7.33.

Листинг 7.33

private void cmenuCopy_Click(object sender, EventArgs e) {
 // Копируем выделенный текст
 SendMessage(hwndEditor, WM_COPY, 0, 0);
}

Мы сделали еще один шаг вперед. Теперь наш маленький блокнот умеет работать с текстом. Но приложение нужно еще немного доработать. Например, пользователь может во время работы с блокнотом переключиться на другую программу и скопировать в буфер обмена картинку, а затем вернуться обратно к текстовому редактору. Конечно, картинку нельзя вставить в текстовое поле. Поэтому надо проверить тип содержимого в буфере обмена, и если там содержатся не текстовые данные, то нужно заблокировать пункт меню Вставить. Для этого можно использовать функцию IsClipboardFormatAvailable, а проверку данных в буфере обмена выполнять в событии Popup, как показано в листинге 7.34.

Листинг 7.34

[DllImport("Coredll.dll")]
private static extern bool IsClipboardFormatAvailable(uint uFormat);
// константа для буфера обмена
private const uint CF_UNICODETEXT = 13;
public static bool IsText() {
 try {
  return IsClipboardFormatAvailable(CF_UNICODETEXT);
 } catch (Exception ex) {
  MessageBox.Show("He могу понять, что содержится в буфере обмена!");
  return false;
 }
}
private void mnuEdit_Popup(object sender, EventArgs e) {
 if (IsText())
  mnuPaste.Enabled = true;
 else
  mnuPaste.Enabled = false;
}

Подобные изменения надо сделать и для пунктов меню. Если пользователь не выделил часть текста, то пункты Вырезать, Копировать и Удалить также должны быть заблокированы. Код, реализующий эту функциональность, приведен в листинге 7.35.

Листинг 7.35

//Если текст выделен
if (txtEditor.SelectionLength > 0) {
 mnuCut.Enabled = true;
 mnuCopy.Enabled = true;
 mnuDelete.Enabled = true;
} else {
 mnuCut.Enabled = false;
 mnuCopy.Enabled = false;
 mnuDelete.Enabled = false;
}

Следующим шагом в развитии программы будет добавление файловых операций. Работа с текстовым редактором предполагает не только правку текста, но и сохранение текста в файле, а также чтение данных из файла. Для этого в меню создаются соответствующие команды Создать, Открыть, Сохранить и Сохранить как. Код, связанный с этими командами, приведен в листинге 7.36.

Листинг 7.36

private void mnuOpen_Click(object sender, EventArgs e) {
 dlgOpenFile.Filter = "Текстовые документы (*.txt)|*.txt|Все файлы |*.*";
 dlgOpenFile.ShowDialog();
 if (File.Exists(dlgOpenFile.FileName)) {
  fname = dlgOpenFile.FileName;
  StreamReader sr =
   new StreamReader(fname, System.Text.Encoding.GetEncoding("Windows-1251"), false);
  txtEditor.Text = sr.ReadToEnd();
  flag = false;
  sr.Close();
 }
}
private void mnuSaveAs_Click(object sender, EventArgs e) {
 SaveFileDialog dlgSaveFile = new SaveFileDialog();
 dlgSaveFile.Filter = "Текстовые документы (*.txt)|*.txt|Все файлы |*.*";
 dlgSaveFile.ShowDialog(); fname = dlgSaveFile.FileName;
 savedata();
}
private void savedata() {
 if (fname == "") {
  SaveFileDialog dlgSaveFile = new SaveFileDialog();
  dlgSaveFile.Filter = "Текстовые документы (*.txt)|*.txt|Все файлы|*.*";
  DialogResult res = dlgSaveFile.ShowDialog();
  if (res == DialogResult.Cancel) {
   return;
  }
  fname = dlgSaveFile.FileName;
  MessageBox.Show(fname);
 }
 StreamWriter sw =
  new StreamWriter(fname, false, System.Text.Encoding.GetEncoding("Windows-1251"));
 sw.WriteLine(txtEditor.Text);
 sw.Flush();
 sw.Close();
 flag = false;
}
private void mnuSave_Click(object sender, EventArgs e) {
 savedata();
}
private void txtEditor_TextChanged(object sender, EventArgs e) {
 flag = true;
}

Работа с файлами в .NET Compact Framework не отличается от методов работы с файлами в полной версии .NET Framework, поэтому заострять внимание на этом коде не нужно. Осталось только добавить в программу некоторые детали, которые придают программе профессиональный вид. Нужно присоединить собственную пиктограмму приложения, а также добавить диалоговое окно О программе с упоминанием автора программы и логотипом фирмы. Безусловно, вы можете наделить текстовый редактор новыми возможностями или расширить его функциональность. Например, для сохранения и открытия файлов я использовал стандартные диалоговые окна, которые работают с файлами в пределах папки Мои документы. Но используя код ранее созданного файлового менеджера, можно научить приложение сохранять и открывать файлы в любом месте файловой системы. Также можно доработать меню Формат, позволяющее работать с различными кодировками текста.

Оглавление книги


Генерация: 1.100. Запросов К БД/Cache: 3 / 1
поделиться
Вверх Вниз