Листинг 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("UTF-8"), false);
txtEditor.Text = sr.ReadToEnd();
flag = false;
sr.Close();
Читать дальше