//txtEditor.Height = this.Height;
SetTextBoxHeight();
}
// устанавливаем размеры текстового поля в зависимости от
// активности SIP
private void SetTextBoxHeight() {
if (SIP.Enabled)
txtEditor.Height = SIP.VisibleDesktop.Height + 2;
else
txtEditor.Height = this.Height;
}
private void SIP_EnabledChanged(object sender, EventArgs e) {
SetTextBoxHeight();
}
Стандартные операции с текстом
На данной стадии уже создан первый прототип приложения. После запуска программы пользователь может вводить и удалять текст с помощью SIP. Но этого недостаточно для комфортной работы с текстом.
Пользователь должен иметь возможность манипулировать текстом, то есть копировать часть текста, вырезать его, удалять и вставлять в нужную позицию. Для этого надо создать меню при помощи элемента mainMenu
. В подменю Правка
надо добавить стандартные команды редактирования текста — Отменить
, Вырезать
, Копировать
, Вставить
. Если бы приложение создавалось для среды исполнения .NET Compact Framework 2.0, то можно было бы использовать класс Clipboard
. Но так как используется .NET Compact Framework 1.0, то придется обратиться к функциям Windows API и использовать неуправляемый код, что иллюстрирует листинг 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.
private void cmenuCopy_Click(object sender, EventArgs e) {
// Копируем выделенный текст
SendMessage(hwndEditor, WM_COPY, 0, 0);
}
Мы сделали еще один шаг вперед. Теперь наш маленький блокнот умеет работать с текстом. Но приложение нужно еще немного доработать. Например, пользователь может во время работы с блокнотом переключиться на другую программу и скопировать в буфер обмена картинку, а затем вернуться обратно к текстовому редактору. Конечно, картинку нельзя вставить в текстовое поле. Поэтому надо проверить тип содержимого в буфере обмена, и если там содержатся не текстовые данные, то нужно заблокировать пункт меню Вставить
. Для этого можно использовать функцию IsClipboardFormatAvailable
, а проверку данных в буфере обмена выполнять в событии Popup
, как показано в листинге 7.34.
[DllImport('Coredll.dll')]
private static extern bool IsClipboardFormatAvailable(uint uFormat);
// константа для буфера обмена
private const uint CF_UNICODETEXT = 13;