- •Часть 2 (продолжение): Прикладное программирование в Windows
- •Глава 8. Виртуальное окно: работа с текстом
- •8.1. Оконные координаты, цвета, отображение строк
- •Кодировка rgb-значений
- •Размеры системных метрик
- •8.2. Виртуальное окно
- •Способы заполнения прямоугольной области
- •8.3. Изменение шрифтов
- •Макроимена распространенных шрифтов
- •8.4. Создание собственных шрифтов
- •Глава 9. Программирование графики
- •9.1. Логическая система координат
- •Рекомендуемый самый яркий состав цветов
- •9.2. Пиксели, линии, дуги, прямоугольники, эллипсы и секторы
- •9.3. Работа с перьями и кистями
- •Типы линий, создаваемых пером
- •9.4. Технология виртуального окна
- •9.5. Режимы отображения и области вывода
- •Текущий режим отображения (mappind mode)
- •Глава 10. Работа с панелями инструментов
- •10.1. Общие элементы управления
- •Общие элементы управления
- •10.2. Подключение и инициализация общих элементов управления
- •10.3. Работа с панелью инструментов
- •Начальные состояния кнопок панели инструментов
- •Стиль кнопки определяется (значения поля fsStyle)
- •Сообщения к панели инструментов
- •10.4. Создание растрового изображения для панели инструментов
- •10.5. Включение подсказок
- •Глава 11. Спины, ползунки и индикаторы процессов
- •11.1. Работа со спином
- •Стили «up-down control»
- •Сообщения, которые можно посылать спину
- •11.2. Создание спина с «приятельским» окном
- •11.3. Работа с ползунком
- •Значения стилей для ползунка
- •Перечень сообщений, которые можно посылать ползунку
- •Перечень нотификационных сообщения ползунка
- •11.4. Индикатор процесса
- •Управляющие сообщения индикатору
- •Глава 12. Многозадачность: процессы и потоки
- •12.1. Создание нового процесса (отдельной задачи)
- •Разрешенные значения поля dwFlags
- •12.2. Многопотоковые программы
- •12.3. Работа с несколькими потоками
- •12.4. Синхронизация процессов и потоков: семафоры
- •12.5. Обработка событий
- •Глава 13. Приемы программного управления вычислительным процессом
- •13.1. Использование функций Проводника Explorer для работы в файловой системе
- •Управляющая информация Проводника
- •Режимы обработки файлов
- •13.2. Создание собственных динамических библиотек (dll-файлов)
- •13.3. Работа с буфером обмена Clipboard
- •Функции подсистемы Clipboard
- •Свойства выделяемого блока памяти
- •Форматы и типы данных
- •Литература
Режимы обработки файлов
№ |
Параметр mode |
Режим |
1 |
"r" |
Открыть файл для чтения |
2 |
"w" |
Открыть файл для записи |
3 |
"a" |
Открыть файл для записи в конец файла (новая информация дописывается перед признаком EOF)
|
4 |
"r+" |
Открыть файл как для чтения, так и для записи (к этому моменту файл должен существовать) |
5 |
"w+" |
Открыть файл как для чтения, так и для записи (если к этому моменту файл уже существует, то его содержимое будет утеряно) |
6 |
"a+" |
Открыть файл как для чтения, так и для записи в конец файла (новая информация дописывается перед признаком EOF) |
Пример 13-1. Программа работы с Проводником
В следующем примере в качестве каркаса используется программа, рассмотренная в примере 8-2. К ней дописаны описанные выше средства, демонстрирующие возможность работы с проводником.
Файл ресурсов Mydialog.rc после включения кнопки Найти файл теперь выглядит следующим образом:
#include <Windows.h>
#include "Text.h"
MYMENU MENU
{
MENUITEM "&Текст", ID_SHOW
MENUITEM "&Сначала", ID_RESET
MENUITEM "&Найти файл", ID_FOPEN
MENUITEM "Помощь", ID_HELP
}
MYMENU ACCELERATORS
{
VK_F2, ID_SHOW, VIRTKEY
VK_F3, ID_RESET, VIRTKEY
VK_F4, ID_FOPEN, VIRTKEY
VK_F1, ID_HELP, VIRTKEY
}
STRINGTABLE
{
ID_FILTERS "Word-файлы(*.DOC)|*.doc|
Текстовые файлы(*.TXT)|*.txt|
Все файлы (*.*)|*.*|"
}
Секция STRINGTABLE файла ресурсов может обслуживать несколько модулей (и несколько диалогов). Кроме строки IDS_FILTERS могут быть заданы и другие строки. Дело в том, что в разных модулях можно получать конкретную строку. Ее идентификатор – средство связи с программой.
Соответственно, изменится и вспомогательный файл Text.h:
#define ID_SHOW 100
#define ID_RESET 101
#define ID_FOPEN 102
#define ID_HELP 103
#define ID_FILTERS 104
Далее создаем структуру OPENFILENAME и опишем другие глобальные рабочие переменные:
OPENFILENAME ofn;
char filename[256]; // Полное имя файла (путь)
char szFile[256];
char szFilter[256];
UINT cbString;
char chReplace; // Разделитель строк для szFilter
char szFileTitle[256];
char szDirName[256];
FILE *stream; // Дескриптор файла
HINSTANCE hInst; // Дескриптор текущего приложения
Распишем команду Найти файл:
case ID_FOPEN:
GetCurrentDirectory(sizeof(szDirName), szDirName);
szFile[0]= '\0';
cbString = LoadString(hInst, ID_FILTERS, szFilter,
sizeof(szFilter));
chReplace= szFilter[cbString - 1];
for(i=0; szFilter[i] != '\0'; i++)
if (szFilter[i] == chReplace)
szFilter[i] = '\0'; // Расст. разделителей
memset(&ofn, 0, sizeof(OPENFILENAME));
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = hwnd;
ofn.lpstrFilter = szFilter;
ofn.nFilterIndex = 1;
ofn.lpstrFile = szFile;
ofn.nMaxFile = sizeof(szFile);
ofn.lpstrFileTitle = szFileTitle;
ofn.nMaxFileTitle = sizeof(szFileTitle);
ofn.lpstrTitle = "Найти файл";
ofn.lpstrInitialDir = szDirName;
ofn.Flags = OFN_SHOWHELP | OFN_PATHMUSTEXIST |
OFN_FILEMUSTEXIST;
if(GetOpenFileName(&ofn))
{
sprintf(filename,"%s", ofn.lpstrFile);
if((stream = fopen(filename,"r")) == NULL )
MessageBox(hwnd, "К Файлу нет доступа",
"Предупреждение:", MB_OK);
else
MessageBox(hwnd, "Файл найден(открыт)",
"Уведомление:", MB_OK);
}
InvalidateRect(hwnd,NULL,1); //Сообщить
break;
Полный текст примера программы, взаимодействующей с Проводником, представлен ниже. На рисунке 13.1 показаны результаты работы программы.
// Демонстрация работы с проводником,
// с использованием виртуального окна
#include <Windows.h>
#include <String.h>
#include <Stdio.h>
#include "Text.h"
LRESULT CALLBACK WindowFunc(HWND,UINT,WPARAM,LPARAM);
char szWinName[] = "МоеОкно"; // Имя класса окна
char str[255]; // Буфер строки вывода
int X=0, Y=0; // Текущие координаты строки
int maxX, maxY; // Размеры экрана
HDC memdc; // DC виртуального окна
HBITMAP hbit; // Растр - это виртуальное окно
HBRUSH hbrush; // Дескриптор кисти
OPENFILENAME ofn;
char filename[256]; // Полное имя файла (путь)
char szDirName[256];
char szFile[256];
char szFilter[256];
UINT cbString;
char chReplace; // Разделитель строк для szFilter
char szFileTitle[256];
char szDirName[256];
FILE *stream; // Дескриптор файла
HINSTANCE hInst; // Дескриптор текущего приложения
int WINAPI WinMain (HINSTANCE hThisInst,
HINSTANCE hPrevInst,
LPSTR lpszArgs,
int nWinMode)
{
HWND hwnd;
MSG msg;
WNDCLASS wcl;
HACCEL hAccel;
// Определить класс окна
wcl.hInstance=hThisInst; // Дескриптор приложения
wcl.lpszClassName=szWinName; // Имя класса окна
wcl.lpfnWndProc=WindowFunc; // Функция окна
wcl.style=0; // Стиль по умолчанию
wcl.hIcon=LoadIcon(NULL,IDI_APPLICATION); // Иконка
wcl.hCursor=LoadCursor(NULL,IDC_ARROW) ; // Курсор
wcl.lpszMenuName="MYMENU"; // Меню
wcl.cbClsExtra=0; // Без дополнительной
wcl.cbWndExtra=0; // информации
// Определить заполнение окна белым цветом
wcl.hbrBackground=
(HBRUSH)GetStockObject(WHITE_BRUSH);
if(!RegisterClass(&wcl)) // Зарегистр. класс окна
return 0;
// Создать окно
hwnd=CreateWindow(szWinName, // Имя класса
"Демонстрация работы с проводником",
WS_OVERLAPPEDWINDOW,// Стиль окна
CW_USEDEFAULT, // Х-координата
CW_USEDEFAULT, // Y-координата
CW_USEDEFAULT, // Ширина окна
CW_USEDEFAULT, // Высота окна
HWND_DESKTOP, // Нет родит. окна
NULL, // Нет меню
hThisInst, // Дескрип. приложения
NULL); // Без дополит. аргументов
hInst = hThisInst; // Сохр. дескриптор приложения
// Загрузить акселераторы
hAccel=LoadAccelerators(hThisInst,"MYMENU");
ShowWindow(hwnd,nWinMode) ; // Показать окно и
UpdateWindow(hwnd); // перерисовать содержимое
// Запустить цикл обработки сообщений
while(GetMessage (&msg,NULL,0,0))
if(!TranslateAccelerator(hwnd,hAccel,&msg))
{
TranslateMessage(&msg); // Использ.Клавиатуры
DispatchMessage (&msg); // Возврат к Windows
}
return msg. wParam;
}
// Следующая функция вызывается операционной системой
// Windows и получает в качестве параметров сообщения
// из очереди сообщений данного приложения
LRESULT CALLBACK WindowFunc(HWND hwnd,
UINT message,
WPARAM wParam,
LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT paintstruct;
TEXTMETRIC tm;
SIZE size;
int i;
switch(message)
{
case WM_CREATE: // Получаем размеры экрана
maxX=GetSystemMetrics(SM_CXSCREEN);
maxY=GetSystemMetrics(SM_CYSCREEN);
hdc=GetDC(hwnd); // Совмест. с окном растр
memdc=CreateCompatibleDC(hdc);
hbit=CreateCompatibleBitmap(hdc,maxX,maxY);
SelectObject(memdc,hbit);
hbrush=(HBRUSH)GetStockObject(WHITE_BRUSH);
SelectObject(memdc,hbrush);
PatBlt(memdc,0,0,maxX,maxY,PATCOPY);
ReleaseDC(hwnd,hdc);
break;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case ID_SHOW:
SetTextColor(memdc,RGB(0,0,0)); // Черн
SetBkColor(memdc,RGB(0,255,255)); //Син
GetTextMetrics(memdc,&tm); // Метрики
sprintf(str,
"Высота шрифта %ld пикселей",
tm.tmHeight);
TextOut(memdc,X,Y,str,strlen(str));
Y=Y+tm.tmHeight // Следующая
+tm.tmExternalLeading; // строка
strcpy(str,"Это следующая строка.");
TextOut(memdc,X,Y,str,strlen(str));
GetTextExtentPoint32(memdc,str, //Длина
strlen(str),
&size);
sprintf(str,
"Длина предыдущей строки %ld",
size.cx);
X=size.cx; // В конец предыдущей строки
TextOut(memdc,X,Y,str,strlen(str));
Y=Y+tm.tmHeight // Следующая
+tm.tmExternalLeading; // строка
X=0; // X опять в начало
sprintf(str,"Размеры экрана %d x %d",
maxX,maxY);
TextOut(memdc,X,Y,str,strlen(str));
Y=Y+tm.tmHeight // Следующая
+tm.tmExternalLeading; // строка
InvalidateRect(hwnd,NULL,1); //Сообщить
break;
case ID_RESET:
X=Y=0; // Стереть перерисовкой фона
PatBlt(memdc,0,0,maxX,maxY,PATCOPY);
InvalidateRect(hwnd,NULL,1); //Сообщить
break;
case IDM_FOPEN:
GetCurrentDirectory(sizeof(szDirName),
szDirName);
szFile[0]= '\0';
cbString =LoadString(hInst,ID_FILTERS,
szFilter,
sizeof(szFilter));
chReplace=szFilter[cbString-1];
for(i=0; szFilter[i] != '\0'; i++)
if(szFilter[i]==chReplace)
szFilter[i]='\0'; // Разделители
memset(&ofn, 0, sizeof(OPENFILENAME));
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = hwnd;
ofn.lpstrFilter = szFilter;
ofn.nFilterIndex= 1;
ofn.lpstrFile = szFile;
ofn.nMaxFile = sizeof(szFile);
ofn.lpstrFileTitle = szFileTitle;
ofn.nMaxFileTitle =sizeof(szFileTitle);
ofn.lpstrTitle = "Найти файл";
ofn.lpstrInitialDir = szDirName;
ofn.Flags = OFN_SHOWHELP |
OFN_PATHMUSTEXIST |
OFN_FILEMUSTEXIST;
if(GetOpenFileName(&ofn))
{
sprintf(filename,"%s",
ofn.lpstrFile);
if((stream=fopen(filename,"r"))
==NULL)
MessageBox(hwnd,
"К Файлу нет доступа",
"Предупреждение:",
MB_OK);
else
MessageBox(hwnd,
"Файл найден(открыт)",
"Уведомление:",
MB_OK);
}
InvalidateRect(hwnd,NULL,1); //Сообщить
break;
case ID_HELP:
MessageBox(hwnd,"F2: Вывести текст\n"
"F3: В начала экрана\n"
"F4: Найти файл",
"Помощь",MB_OK);
InvalidateRect(hwnd,NULL,1); //Сообщить
break;
}
break;
case WM_PAINT: // Перерисовка окна
hdc=BeginPaint(hwnd,&paintstruct); // Пол. DC
// Теперь копируем растр из памяти на экран
BitBlt(hdc,0,0,maxX,maxY,memdc,0,0,SRCCOPY);
EndPaint(hwnd,&paintstruct); // Освободить DC
break;
case WM_DESTROY: // Завершение программы
DeleteDC(memdc); // Удалить виртуальное окно
PostQuitMessage(0);
break;
default:
// Все сообщения, не обрабатываемые в данной
// функции, направляются на обработку по
// умолчанию
return DefWindowProc(hwnd,message,
wParam,lParam);
}
return 0;
}
