WM_CLEAR
Удаление выделенного текста с записью его в Clipboard. Удаленный текст можно восстановить, если послать в редактор сообщение EM_UNDO.
WM_CUT
Вставка текста из буфера обмена Clipboard в текущую позицию редактируемого текста.
WM_PASTE
Копирование выделенного фрагмента текста в универсальный буфер обмена Clipboard.
WM_COPY
Помимо описанных выше, текстовому редактору можно посылать некоторые сообщения, символические имена которых начинаются с префикса WM_. Это сообщения WM_COPY, WM_PASTE, WM_CUT, WM_CLEAR.
CCMax - размер текста.
Определение максимального количества символов, которое можно ввести в окно редактирования.
EM_LIMITTEXT
Отмена последней операции редактирования текста.
EM_UNDO
EM_SETTABSTOPS
EM_SETSEL
Выделение заданных символов в окне редактирования.
Параметры:
wParam = (WPARAM)(UINT)fScroll;
|
|
lParam = MAKELPARAM(ichStart, ichEnd);
fScroll - если этот параметр равен 1, текстовый курсор сворачивается, если 0 - нет.
ichStart - начальная позиция.
ichEnd - конечная позиция. Если начальная позиция равна 0, а конечная -1, выбирается весь текст. Если начальная позиция равна -1, выделение фрагмента (если оно было) исчезает.
Возвращаемое значение: TRUE, если сообщение посылается редактору, созданному как орган управления
Установка позиций табуляции.
Параметры:
wParam = (WPARAM)cTabs;
lParam = (LPARAM)(const int FAR *) lpTabs;
cTabs - расстояние для табуляции. Если этот параметр указан как 0, используется значение по умолчанию - 32.
lpTabs - массив беззнаковых целых чисел, определяющих расположение позиций табуляции в единицах, используемых для диалоговых панелей. Эти единицы будут описаны в следующей главе.
Возвращаемое значение:
TRUE, если позиции табуляции были установлены ил FALSE при ошибке
Параметры:
wParam = 0;
lParam = 0;
Возвращаемое значение: не используется
Параметры:
wParam = (WPARAM)cCmax;
lParam = 0;
Возвращаемое значение: не используется
// Устанавливаем максимальную длину// редактируемого текста, равную 32000 байт SendMessage(hEdit, EM_LIMITTEXT, 32000, 0L);Параметры: wParam = 0; lParam = 0;
Возвращаемое значение: не используется
Параметры: wParam = 0; lParam = 0;
Возвращаемое значение: не используется
Параметры: wParam = 0; lParam = 0;
Возвращаемое значение: не используется
Параметры: wParam = 0; lParam = 0;
Возвращаемое значение: не используется
// Реализуем стандартные функции меню Edit case ID_EDIT_UNDO: SendMessage(hwndEdit, EM_UNDO, 0, 0L); return 0; break; case ID_EDIT_CUT: SendMessage(hwndEdit, WM_CUT, 0, 0L); return 0; break; case ID_EDIT_COPY: SendMessage(hwndEdit, WM_COPY, 0, 0L); return 0; break; case ID_EDIT_PASTE: SendMessage(hwndEdit, WM_PASTE, 0, 0L); return 0; break; case ID_EDIT_DELETE: SendMessage(hwndEdit, WM_CLEAR, 0, 0L); return 0; break;
Пример 3: Приложение TEDIT
|
|
Приложение TEDIT представляет собой текстовый редактор, аналогичный редактору Notepad только без меню. Он способен создавать новые файлы, загружать и редактировать имеющиеся, сохранять текст в старом или новом файле.
#define STRICT 1
#include <windows.h>
#include <stdio.h>
#include <string>
#include <tchar.h>
//using namespace std;
// Идентификатор редактора текста
#define ID_EDIT 1
// Идентификаторы кнопок
#define ID_NEW 2
#define ID_OPEN 3
#define ID_SAVE 4
#define ID_EXIT 5
using namespace std;
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
HFILE OpenFile(void);
HFILE OpenSaveFile(void);
TCHAR const szClassName[] = _T("ButtonAppClass");
// Заголовок окна
TCHAR const szWindowTitle[] = _T("Button Demo");
// Идентификатор копии приложения
HINSTANCE hInst;
// Флаг изменений в тексте
BOOL bUpdate;
//================================================
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
HWND hWnd;
MSG msg;
WNDCLASS wc;
wc.style=CS_HREDRAW|CS_VREDRAW;
wc.cbClsExtra=wc.cbWndExtra=0;
wc.lpfnWndProc=WndProc;
wc.hInstance=hInstance;
wc.hIcon=LoadIcon(NULL,IDI_APPLICATION);
wc.hCursor=LoadCursor(NULL,IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.lpszMenuName=(LPCTSTR)NULL;
wc.lpszClassName=szClassName;
if (!RegisterClass(&wc))
{
MessageBox(NULL,_T("Не могу зарегестрировать класс"),_T("Error"),MB_OK);
return 0;
}
hInst = hInstance;
hWnd=CreateWindow(szClassName,szWindowTitle,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,CW_USEDEFAULT,
CW_USEDEFAULT,CW_USEDEFAULT,
NULL,NULL,
hInstance,NULL);
if (!hWnd)
{
MessageBox(NULL,_T("Не могу создать окно"),_T("Error"),MB_OK);
return FALSE;
}
ShowWindow(hWnd,nCmdShow);
UpdateWindow(hWnd);
while (GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
//=================================================
LRESULT CALLBACK WndProc(HWND hWnd,UINT uMsg, WPARAM wParam, LPARAM lParam)
{
// Идентификатор редактора текста
static HWND hEdit;
// Идентификаторы кнопок
static HWND hButtNew;
static HWND hButtOpen;
static HWND hButtSave;
static HWND hButtExit;
// Идентификаторы файлов
static HFILE hfSrcFile, hfDstFile;
switch (uMsg)
{
case WM_CREATE:
{
// Создаем редактор текста
hEdit = CreateWindow(_T("edit"), NULL,
WS_CHILD | WS_VISIBLE | WS_BORDER |
WS_HSCROLL | WS_VSCROLL |
ES_LEFT | ES_AUTOHSCROLL | ES_AUTOVSCROLL |
ES_MULTILINE,
0, 0, 0, 0,
hWnd, (HMENU) ID_EDIT, hInst, NULL);
SendMessage(hEdit, EM_LIMITTEXT, 32000, 0L);
// Сбрасываем флаг обновления текста
bUpdate = FALSE;
// Создаем кнопки
hButtNew = CreateWindow(_T("button"), _T("New"),
WS_CHILD | WS_VISIBLE |
BS_PUSHBUTTON,
0, 0, 50, 20,
hWnd, (HMENU) ID_NEW, hInst, NULL);
hButtOpen = CreateWindow(_T("button"), _T("Open"),
WS_CHILD | WS_VISIBLE |
BS_PUSHBUTTON,
50, 0, 50, 20,
hWnd, (HMENU) ID_OPEN, hInst, NULL);
hButtSave = CreateWindow(_T("button"), _T("Save"),
WS_CHILD | WS_VISIBLE |
BS_PUSHBUTTON,
100, 0, 50, 20,
hWnd, (HMENU) ID_SAVE, hInst, NULL);
hButtExit = CreateWindow(_T("button"), _T("Exit"),
WS_CHILD | WS_VISIBLE |
BS_PUSHBUTTON,
150, 0, 50, 20,
hWnd, (HMENU) ID_EXIT, hInst, NULL);
return 0;
}
case WM_SIZE:
{
// Устанавливаем размер органа управления (текстового
// редактора) в соответствии с размерами главного окна приложения
MoveWindow(hEdit, 0, 20, LOWORD(lParam),
HIWORD(lParam) - 20, TRUE);
return 0;
}
// Когда главное окно приложения получает
// фокус ввода, отдаем фокус редактору текста
case WM_SETFOCUS:
{
SetFocus(hEdit);
return 0;
}
case WM_COMMAND:
{
// Обработка извещений текстового редактора
if(wParam == ID_EDIT)
{
// Ошибка
if(HIWORD(lParam) == EN_ERRSPACE)
{
MessageBox(hWnd, _T("Мало памяти"),
szWindowTitle, MB_OK);
}
// Произошло изменение в редактируемом тексте
else if(HIWORD(lParam) == EN_UPDATE)
{
// Устанавливаем флаг обновления текста
bUpdate = TRUE;
}
return 0;
}
// Нажата кнопка сохранения текста
else if(wParam == ID_SAVE)
{
WORD wSize;
HANDLE hTxtBuf;
NPSTR npTextBuffer;
// Открываем выходной файл
hfDstFile = OpenSaveFile();
if(!hfDstFile) return 0;
// Определяем размер текста
wSize = GetWindowTextLength(hEdit);
// Получаем идентификатор блока памяти,
// в котором находится редактируемый текст
hTxtBuf = (HANDLE) SendMessage(hEdit, EM_GETHANDLE,
0, 0L);
// Фиксируем блок памяти и получаем указатель на него
npTextBuffer = (NPSTR)LocalLock(hTxtBuf);
// Записываем содержимое блока памяти в файл
if(wSize!= _lwrite(hfDstFile, npTextBuffer, wSize))
{
// При ошибке закрываем файл и выдаем сообщение
_lclose(hfDstFile);
MessageBox(hWnd, _T("Ошибка при записи файла"),
szWindowTitle, MB_OK);
return 0;
}
// Закрываем файл
_lclose(hfDstFile);
// Расфиксируем блок памяти
LocalUnlock(hTxtBuf);
// Так как файл был только что сохранен,
// сбрасываем флаг обновления
bUpdate = FALSE;
return 0;
|
|
}
// Создание нового файла
else if(wParam == ID_NEW)
{
// Проверяем флаг обновления
if(bUpdate)
{
if(IDYES == MessageBox(hWnd,
_T("Файл был изменен. Желаете сохранить?"),
szWindowTitle, MB_YESNO | MB_ICONQUESTION))
return 0;
}
// Сбрасываем содержимое текстового редактора
SetWindowText(hEdit, _T("\0"));
return 0;
}
// Загрузка файла для редактирования
else if(wParam == ID_OPEN)
{
LPSTR lpTextBuffer;
DWORD dwFileSize, dwCurrentPos;
// Проверяем флаг обновления
if(bUpdate)
{
if(IDYES == MessageBox(hWnd,
_T("Файл был изменен. Желаете сохранить?"),
szWindowTitle, MB_YESNO | MB_ICONQUESTION))
return 0;
}
// Открываем входной файл.
hfSrcFile = OpenFile();
if(!hfSrcFile) return 0;
// Определяем размер файла
dwCurrentPos = _llseek(hfSrcFile, 0L, 1);
dwFileSize = _llseek(hfSrcFile, 0L, 2);
_llseek(hfSrcFile, dwCurrentPos, 0);
// Размер файла не должен превосходить 32000 байт
if(dwFileSize >= 32000)
{
_lclose(hfSrcFile);
MessageBox(hWnd, _T("Размер файла больше 32000 байт"),
szWindowTitle, MB_OK);
return 0;
}
// Заказываем память для загрузки файла
lpTextBuffer = (LPSTR)malloc(32000);
if(lpTextBuffer == NULL)
return 0;
// Загружаем текст из файла в буфер
_lread(hfSrcFile, lpTextBuffer, dwFileSize);
// Закрываем буфер двоичным нулем
lpTextBuffer[(WORD)dwFileSize] = '\0';
// Закрываем файл
_lclose(hfSrcFile);
// Переносим содержимое буфера в текстовый редактор
SetWindowText(hEdit, lpTextBuffer);
// Освобождаем буфер
free((void *)lpTextBuffer);
// сбрасываем флаг обновления
bUpdate = FALSE;
}
else if(wParam == ID_EXIT)
{
// Проверяем флаг обновления
if(bUpdate)
{
if(IDYES == MessageBox(hWnd,
_T("Файл был изменен. Желаете сохранить?"),
szWindowTitle, MB_YESNO | MB_ICONQUESTION))
return 0;
}
// Посылаем в функцию главного окна
// сообщение WM_CLOSE
SendMessage(hWnd, WM_CLOSE, 0, 0L);
return 0;
}
return 0;
}
case WM_DESTROY:
{
PostQuitMessage(0);
return 0;
}
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
HFILE OpenFile(void)
{
// Структура для выбора файла
OPENFILENAME ofn;
// Буфер для записи пути к выбранному файлу
TCHAR szFile[256];
// Буфер для записи имени выбранного файла
TCHAR szFileTitle[256];
// Фильтр расширений имени файлов
TCHAR szFilter[256] =
_T("Text Files\0*.txt;*.doc\0Any Files\0*.*\0");
// Идентификатор открываемого файла
HFILE hf;
// Инициализация имени выбираемого файла
// не нужна, поэтому создаем пустую строку
szFile[0] = _T('\0');
// Записываем нулевые значения во все поля
// структуры, которая будет использована для
|
|
// выбора файла
memset(&ofn, 0, sizeof(OPENFILENAME));
// Инициализируем нужные нам поля
// Размер структуры
ofn.lStructSize = sizeof(OPENFILENAME);
// Идентификатор окна
ofn.hwndOwner = NULL;
// Адрес строки фильтра
ofn.lpstrFilter = szFilter;
// Номер позиции выбора
ofn.nFilterIndex = 1;
// Адрес буфера для записи пути выбранного файла
ofn.lpstrFile = szFile;
// Размер буфера для записи пути выбранного файла
ofn.nMaxFile = sizeof(szFile);
// Адрес буфера для записи имени выбранного файла
ofn.lpstrFileTitle = szFileTitle;
// Размер буфера для записи имени выбранного файла
ofn.nMaxFileTitle = sizeof(szFileTitle);
// В качестве начального каталога для
// поиска выбираем текущий каталог
ofn.lpstrInitialDir = NULL;
// Определяем режимы выбора файла
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST
| OFN_HIDEREADONLY;
// Выбираем входной файл
if (GetOpenFileName(&ofn)) {
// Открываем выбранный файл
hf = _lopen((LPCSTR)ofn.lpstrFile, OF_READ);
// Возвращаем идентификатор файла
return hf;
}
// При отказе от выбора возвращаем нулевое значение
else return 0;
}
// -------------------------------
// Функция OpenSaveFile
// Выбор файла для редактирования
// -------------------------------
HFILE OpenSaveFile(void)
{
OPENFILENAME ofn;
TCHAR szFile[256];
TCHAR szFileTitle[256];
TCHAR szFilter[256] = _T("Text Files\0*.txt\0Any Files\0*.*\0");
HFILE hf;
szFile[0] = _T('\0');
memset(&ofn, 0, sizeof(OPENFILENAME));
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = NULL;
ofn.lpstrFilter = szFilter;
ofn.nFilterIndex = 1;
ofn.lpstrFile = szFile;
ofn.nMaxFile = sizeof(szFile);
ofn.lpstrFileTitle = szFileTitle;
ofn.nMaxFileTitle = sizeof(szFileTitle);
ofn.lpstrInitialDir = NULL;
ofn.Flags = OFN_HIDEREADONLY;
// Выбираем выходной файл
if (GetSaveFileName(&ofn)) {
// При необходимости создаем файл
hf = _lcreat(ofn.lpstrFile, 0);
return hf;
}
else return 0;
}
Функция GetOpenFileName создает стандартное диалоговое окно Открыть (Open), которое дает возможность пользователю определить диск, каталог и имя файла или ряд файлов, чтобы открыть.
Синтаксис