В структуре работы Windows программа не может работать непосредственно с устройством. В системе предусматривается полный уровень абстрагирования от аппаратуры. Программа работает с логической моделью устройства – контекстом устройства, причем одновременно может быть открыто несколько контекстов, и они могут представлять собой не только окна экрана, но и принтер метафайл.
Программа
Контекст устройства Драйвер устройства Уст¬ройство вывода
Обязательным является закрытие контекста устройства. Иначе при каждой перерисовке изображения или его части, будет открываться новый контекст графического устройства, что довольно быстро исчерпает все ресурсы компьютера.
Программирование на Си под Windows.doc
1.1. Организация программы под DOS
Программа под MS DOS
Дисплей, клавиатура,
СОМ порты, LPT порты,
таймер, принтер, мышь,
динамик.
Диски
Аппаратура
Подсистемы
MS DOS
1. Файловая система
2. Система управления памятью
3. Система управления программами
4. Система ввода вывода
BIOS
Драйверы
1.2. Организация программы под Windows
Аппаратура
Драйверы устройств
Windows
Дисплей
Принтер
RS232
Звуковой
генератор
display.drv
printer.drv
comm.drv
sound.drv
gdi.exe
user.exe
Клавиатура
keyboard.drv
Мышь
ОЗУ
Диски
mouse.drv
Kоernel.exe
А.В. Красов «Программирование под MsWindows на Borland C»
1 1.3.
Обмен сообщениями между приложением и Windows
Приложение Windows
Приложение
Windows
Windows
Системная
очередь События
RegisterClass()
CreateWindow()
ShowWindow()
WinMain()
Цикл
обработки
сообщений
Оконная
функция
WndProc()
Очередь
приложений
Окно
приложения
А.В. Красов «Программирование под MsWindows на Borland C»
2 2.1. Блоксхема функции WinMain()
А.В. Красов «Программирование под MsWindows на Borland C»
3 2.2. Блоксхема оконной функции
2.3. Соответствие типов данных
Типы данных
Соответствие в Си
BYTE
WORD
LONG
DWORD
LPSTR
BOOL
unsigned char
unsihned short
long
unsigned long
char far *
int
А.В. Красов «Программирование под MsWindows на Borland C»
4 2.4. Новые типы данных Windows
Соответствие
unsigned int
unsigned int
far *
Тип
HANDLE
HWND
FARPROC
MSG
WNDCLASS
PAINTSTRUCT
RECT
Описание
Идентификатор объекта Windows
Идентификатор окна
Указатель на функцию
Структура параметров сообщения
Windows
Структура, описывающая окно
Структура для рисования в окне
Координаты прямоугольника
2.4. Общие правила разработки программ на Си под Ms Windows
Особенность построения ОС Windows требует соблюдение следующих правил при
программировании:
1. Нельзя использовать стандартные функции языка Си для работы с консолью,
памятью, устройствами (клавиатурой, мышью, дисплеем). Это такие функции как
scanf, printf, getch, line, initgraph, callcoc и др. При попытке работать с этими
устройствами напрямую, нарушаются механизмы работы ОС Windows, что может
привести к непредсказуемым последствиям. Работа со всей аппаратурой
возможна только через ресурсы, предоставляемые Windows.
2. Если Ваша оконная функция не будет постоянно возвращать управление ОС, то
вся многозадачность Windows исчезнет, как мыльный пузырь.
Листинг исходного текста первого примера:
#include
long FAR PASCAL WndProc(HWND hwnd,WORD message,WORD wParam,
LONG lParam)
{
hdc ;
HDC
PAINTSTRUCT ps ;
switch(mesage)
{
А.В. Красов «Программирование под MsWindows на Borland C»
5 case WM_PAINT :
;
hdc=BeginPaint(hwnd,&ps)
TextOut(hdc,10,10,"Hello !!!",9) ;
EndPaint(hwnd,&ps) ;
return(0) ;
case WM_DESTROY : PostQuitMessage(0) ;
return(0) ;
}
/*
Кон.
switch()
*/
return(DefWindowProc(hwnd,message,wParam,lParam)) ;
} /* Кон. WndProc() */
int InitWin(HANDLE hInstance)
WNDCLASS wndclass ;
{
// тип класса
wndclass.style
= CS_HREDRAW|CS_VREDRAW ;
// указатель на оконную функцию
wndclass.lpfnWndProc = WndProc
// дополнительная память для класса
wndclass.cbClsExtra = 0
// дополнительная память для каждого окна
wndclass.cbWndExtra
// идентификатор программы регистрирующий класс
wndclass.hInstance = hInstance
;
;
= 0 ;
;
// пиктограмма
// курсор
wndclass.hIcon
= LoadIcon(NULL,IDI_APPLICATION);
wndclass.hCursor
= LoadCursor(NULL,IDC_ARROW)
;
// цвет и стиль закраски фона окна
wndclass.hbrBackground = GetStockObject(WHITE_BRUSH) ;
// указатель на меню
// имя класса
wndclass.lpszMenuName = NULL
wndclass.lpszClassName = "Hello"
/**/
RegisterClass(&wndclass) ;
;
;
return(1) ;
} /* Кон. InitWin() */
А.В. Красов «Программирование под MsWindows на Borland C»
6 int PASCAL WinMain(
HANDLE hInstance, /* дескриптор текущего экземпляра программы */
HANDLE hPrevInstance, /* // предыдущего */
LPSTR lpszCmdParam, /* командная строка аргументов,
передаваемая из Windows */
int nCmdShow /* первоначальный вид окна */
)
{
HWND hwnd ;
MSG msg ;
/* если запускается вторая копия программы, то повторно регистрировать класс не
требуется */
if( ! hPrevInstance ) InitWin(hInstance) ;
hwnd=CreateWindow("Hello","Заголовок окна",
WS_OVERLAPPEDWINDOW,
//
тип
окна
CW_USEDEFAULT,CW_USEDEFAULT,
//
размеры
CW_USEDEFAULT,CW_USEDEFAULT, NULL, //
идентификатор родительского окна NULL, // указатель
на меню
hInstance, // идентификатор программы
NULL) ; // указатель на параметры
ShowWindow(hwnd,nCmdSow) ;
UpdateWindow(hwnd) ;
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg) ;
DispatchMessage(&msg) ;
} /* Кон. while() */
return(msg.wParam) ;
} /* Кон. WinMain() */
А.В. Красов «Программирование под MsWindows на Borland C»
7 Файл HELLO.DEF
Hello
NAME
DESCRIPTION "Hello World"
EXETYPE WINDOWS
STUB
CODE
DATA
HEAPSIZE 1024
STACKSIZE 8192
EXPORTS WndProc
"Winstub.exe"
PRELOAD MOVEABLE DISCARDABLE
PRELOAD MOVEABLE MULTIPLE
Данный файл включается в проект:
[hello.rc]
helo.c
hello.def
Файл проекта, приведенный выше, содержит: файл с описанием ресурсов, для
первого примера его пока нет, исходный текст программы и описание задачи.
Файл *.rc содержит описание ресурсов, используемых программой, такие как меню,
диалоговые окна, пиктограммы и т.п.
3. Рисование в окне
3.1. Сообщение WM_PAINT
В структуре работы Windows программа не может работать непосредственно с
устройством. В системе предусматривается полный уровень абстрагирования от
аппаратуры. Программа работает с логической моделью устройства – контекстом
устройства, причем одновременно может быть открыто несколько контекстов, и они
могут представлять собой не только окна экрана, но и принтер метафайл.
Программа
Контекст
устройства
Драйвер
устройства
Устройство
вывода
Обязательным является закрытие контекста устройства. Иначе при каждой
перерисовке изображения или его части, будет открываться новый контекст
графического устройства, что довольно быстро исчерпает все ресурсы компьютера.
А.В. Красов «Программирование под MsWindows на Borland C»
8 PAINTSTRUCT ps ;
HDC
. . . .
case WM_PAINT: hdc=BeginPaint(hwnd,&ps) ; // Получить контекст
hdc ;
// устройства отображения
< Команды рисования >
EndPaint(hwnd,&ps) ; // Освободить контекст
break ;
3.2. Функции рисования
SetPixel(hdc,X,Y,Color) Поставить точку указанного цвета
Color=GetPixel(hdc,X,Y Узнать цвет точки
LineTo(hdc,X,Y)
Провести линию из текущей точки в
указанную (X,Y)
Для рисования линии между двумя указанными точками рекомендуется ввести
собственную функцию. Подобная стандартная функция отсутствует.
int Line(HDC hdc,int X1,int Y1,int X2,int Y2)
{
POINT pt ;
MoveToEx(hdc,X1,Y1,&pt) ;
LineTo(hdc,X2,Y2) ; return(1) ;
} /* Кон. Line() */
PolyLine(hdc, pt[n],n)
массиве
Polygon(hdc, pt[n],n )
pt массив точек (X,Y), n колво точек в
Х2, Y2
Xb, Yb
Arc(hdc,X1,Y1,X2,Y2,Xb,Yb,Xe,Ye)
X1, Y1
Pie(hdc,X1,Y1,X2,Y2,Xb,Yb,Xe,Ye) Xe, Ye
А.В. Красов «Программирование под MsWindows на Borland C»
9 X1, Y1
Rectangle(hdc,X1,Y1,X2,Y2)
X2, Y2
X1, Y1 ry
RoundRect(hdc,X1,Y1,X2,Y1,rx,ry) rx
X2, X2
X1, Y1
Ellipse(hdc,X1,Y1,X2,Y2)
3.3. Цвета
X2, Y2
RGB(<красный>,<зеленый>,<синий>)
Значение каждого цвета от 0 до 255. Если установленный видео режим не
поддерживает такой цвет, отображается ближайшим цветом.
3.4. Выбор пера
hPen=CreatePen(<Стиль>,<Ширина>,<Цвет>) Создать перо.
Выбрать перо.
hOldPen=SelectPen(hdc,hPen)
DeleteObject(hdc,hPen)
Удалить перо.
!!! Внимание !!!
Активное перо удалить нельзя.
3.5. Стили перьев
PS_SOLID
PS_DASH
. . . . . . . . . .
PS_DOT
PS_DASHDOT
_ . _ . _ . _ . _ .
PS_DASHDOTDOT _ . . _ . . _ . . _
А.В. Красов «Программирование под MsWindows на Borland C»
10 PS_NULL
PS_INSIDEFRAME
Не видимая
Линия для обводки замкнутых
фигур
3.6. Режим рисования
SetROP2(hdc,<Режим>)
Режимы рисования
R2_COPYPEN Указанный цвет
R2_NOT
. . . . .
Инверсия
3.7. Выбор кисти
hBrush=CreateSolidBrush(<Цвет>)
Создание собственной кисти
hNulBrush=(HBRUSH)
GetStockObject(NULL_BRUSH) Получить встроенную кисть
SelectObject(hdc,hBrush)
DeleteObject(hBrush)
Выбрать кисть
Удалить кисть
3.8. Работа с метафайлами
Метафайлы представляют собой удобный способ запоминания векторных команд.
Метафайл может сформировать как сама программа, так и есть ряд векторных
редакторов, которые позволяют создавать метафайлы. Для разработки учебных
программ в первую очередь представляет интерес нарисовать в них элемент программы
и проиграть его в рабочем окне программы.
Для работы с метафайлами предусматриваются следующие функции:
CreateMetaFile() и CloseMetaFile(). Пример работы с этими функциями.
HdcMeta=CreateMetaFile(<Имя метафайла>)
Rectangle(hdcMeta,0,0,100,100) ;
А.В. Красов «Программирование под MsWindows на Borland C»
11 Hmf=CloseMetaFile(hdcMeta) ;
Если вместо имени метафайла указать NULL, то метафайл на диске не будет
сохранен, а останется только в памяти. С помощью этих двух функций возможно
создавать
выполнения
Hmf=CloseMetaFile(hdcMeta), Hmf равен 0, то метафайл не был сформирован.
метафайлы из
Если после
программы.
Содержимое метафайла воспроизводится функцией PlayMetaFile(hdc,
Hmf).
PlayMetafile(HDC hdc, HANDLE hmf), где hdc – дескриптор графического устройства,
hmf идентификатор метафайла.
Загрузить метафайл с диска возможно функцией Hmf=GetMetaFile(<Имя
метафайла>). В зависимости от задачи, загрузку метафайла можно вынести в обработку
сообщения WM_CREATE, а удаление в WM_DESTROY.
Если метафайл в памяти больше не нужен, то он удаляется с помощью функции
DeleteMetaFile(Hmf). Метафайл удаляется только из памяти, на диске его можно
удалить как обычный файл.
4. Окна со скроллингом
4.1. Размеры окна
Для определения размеров удобнее всего воспользоваться сообщением
WM_SIZE. Это сообщение посылается окну при создании и при всех изменениях
размера окна.
static int SizeWindowX,SizeWindowY ;
. . . . . . . . .
case WM_SIZE : SizeWindowX=LOWORD(lParam) ;
SizeWindowY=HIWORD(lParam) ;
break ;
Размеры окна удобнее всего объявить статическими переменными, возможно
использование глобальных переменных. Проблемы появляются, если в программе
будет несколько окон.
4.2. Скроллинг
Для создания окна со скроллингом в функции CreateWindow используются флаги
WS_HSCROLL и WS_VSCROLL.
hwnd=CreateWindow("Hello","Заголовок окна",
А.В. Красов «Программирование под MsWindows на Borland C»
12 WS_OVERLAPPEDWINDOW|
WS_HSCROLL|WS_VSCROLL, // тип окна
CW_USEDEFAULT,CW_USEDEFAULT, //размеры
CW_USEDEFAULT,CW_USEDEFAULT,
NULL, // идентификатор родительского окна
NULL, // указатель на меню
hInstance, // идентификатор программы
NULL) ;
// указатель на параметры
Окно со скролингом посылает оконной функции сообщения: WM_HSCROLL и
WM_VSCROLL. Дальнейшая обработка происходит по дополнительным параметрам
wParam и lParam.
Используются следующие переменные:
static int SizeX,SizeY,
/* Размер поля вывода */
SizeWindowX,SizeWindowY, /* Размеры окна */
BeginX,BeginY ;
/* Начало видимого участка */
Переменные charDX,charDY размер на сколько сдвигать изображение при
нажатии кнопки на полосе прокрутки. Рекомендуется использовать размеры
системного шрифта.
case WM_HSCROLL:switch(wParam)
{
А.В. Красов «Программирование под MsWindows на Borland C»
13 : i=0 ; break ;
case SB_TOP
case SB_BOTTOM : i=SizeX ; break ;
case SB_LINEUP : i=max(0,BeginXcharDX) ;
break ;
case SB_LINEDOWN:i=min(SizeX,BeginX+charDX) ;
break ;
case SB_PAGEUP : i=max(0,BeginXSizeWindowX) ;
break ;
case SB_PAGEDOWN:i=min(SizeX,
BeginX+SizeWindow_X);
break ;
case SB_THUMBPOSITION:
i=LOWORD(lParam) ;
break ;
default : i=BeginX ;
} /* Кон. Switch() */
if(i!=BeginX)
{
ScrollWindow(hwnd,BeginXi,0,NULL,NULL) ;
BeginX=i ;
SetScrollPos(hwnd,SB_HORZ,BeginX,TRUE) ;
UpdateWindow(hwnd)
;
message=WM_PAINT ;
} /* Кон. if() */
return(0) ;
case WM_VSCROLL:switch(wParam)
{
case SB_TOP
: i= 0 ; break ;
case SB_BOTTOM : i=SizeY ; break ;
case SB_LINEUP : i=max(0,BeginYcharDY) ; break ;
case SB_LINEDOWN: i=min(SizeY,BeginY+charDY) ;
break ;
case SB_PAGEUP : i=max(0,BeginYSizeWindowY) ;
break ;
case SB_PAGEDOWN:i=min(SizeY,BeginY+SizeWindowY);
break ;
case SB_THUMBPOSITION:
А.В. Красов «Программирование под MsWindows на Borland C»
14 i=LOWORD(lParam) ;
break ;
:i=BeginY ;
default
}
if(i!=BeginY)
{
ScrollWindow(hwnd,0,BeginYi,NULL,NULL) ;
BeginY=i ;
SetScrollPos(hwnd,SB_VERT,BeginY,TRUE) ;
UpdateWindow(hwnd) ;
}
return(0) ;
Кроме того, требуется доработать сообщение WM_SIZE, для изменения размеров
полосы прокрутки и положений указателей позиции.
case WM_SIZE : SizeWindowX=LOWORD(lParam) ;
SizeWindowY=HIWORD(lParam) ;
SetScrollRange(hwnd,SB_HORZ,0,SizeX,TRUE)
SetScrollRange(hwnd,SB_VERT,0,SizeY,TRUE)
SetScrollPos(hwnd,SB_HORZ,BeginX,TRUE)
SetScrollPos(hwnd,SB_VERT,BeginY,TRUE) ; return(0) ;
;
;
;
4.3. Рисование с учетом скроллинга
При перерисовке изображений окна положение скроллинга необходимо учитывать
вручную. За (0,0) считается левый верхний угол окна. Автоматический сдвиг
происходит только для неперерисовываемой части окна.
case WM_PAINT:hdc=BeginPaint(hwnd,&ps) ; // Получить контекст
// устройства отображения
Line(hdc,100BeginX,100BeginY,
200BeginX,200BeginY) ;
EndPaint(hwnd,&ps) ; // Освободить контекст break
;
А.В. Красов «Программирование под MsWindows на Borland C»
15 5. Органы управления
5.1. Диалоговая функция MessageBox()
Функция MessageBox() служит для создания простого диалогового сообщения, с
возможным вопросом.
i=MessageBox(hwnd,"Сообщение","Заголовок окна",<Тип диалога>)
Типы диалога (кнопки вопросов)
MB_OK
MB_YESNO
Диалоговое окно с копкой «Ok». При ее нажатии
возвращается значение IDOK
Диалоговое окно с кнопками «Yes» и «No». При нажатии
кнопки с надписью «Yes» возвращается значение IDYES, при
нажатии кнопки с надписью «No» возвращается значение
IDNO.
MB_OKCANCEL Диалоговое окно с кнопками «Ok» и «Cancel». При нажатии
кнопки надписью «Ok» возвращается значение IDOK, при
нажатии кнопки надписью «Cancel» возвращается значение
IDCANCEL.
Пиктограммы диалога
Константа
Изображение иконки
MB_ICONINFORMATION
MB_ICONSTOP
MB_ICONQUESTION
Функция возвращает код, соответствующий одной из констант IDOK,
IDCANCEL, IDYES, IDNO. Выполнение программы до ответа пользователя
прекращается, переключение на другие окна приложения невозможны.
А.В. Красов «Программирование под MsWindows на Borland C»
16 5.2. Меню, сообщение от меню
При инициализации класса окна можно указать, что окно имеет меню:
// указатель на меню
wndclass.lpszMenuName = "MENU_TEST"
;
Содержание меню указывается в файле ресурсов *.rc. Данный файл может
редактироваться редактором ресурсов или как текстовый файл.
В рассмотренном ниже примере создается меню следующего типа:
File
Run
Make
New
Open
Save as
Exit
About
Help
Resourses
Help
MENU_TEST MENU
BEGIN
POPUP "&File"
BEGIN
MENUITEM "&New" 101
MENUITEM "&Open" 102
MENUITEM "&Save" 103
MENUITEM "Save&As"
MENUITEM SEPARATOR
MENUITEM "E&xit" 105
MENUITEM SEPARATOR
MENUITEM "About" 106
END
MENUITEM "Run"
MENUITEM "Make"
POPUP "&Help"
BEGIN
121
122
MENUITEM "Resourses"
MENUITEM "Help"
108
END
104
107
А.В. Красов «Программирование под MsWindows на Borland C»
17 END
Выбор пункта меню генерирует сообщение WM_COMMAND с идентификатором
выбранного элемента в дополнительном параметре wParam.
case WM_COMMAND:switch(wParam)
{
case 106:MessageBox(hwnd,"Выбран пункт About",
"Сообщение от меню",
MB_OK|MB_ICONINFORMATION) ;
break ;
} /* Кон. switch(wParam) */
6. Работа с мышью
6.1. Сообщения от мыши
Сообщения от мыши генерируются, если мышь находится над окном.
WM_LBUTTONDOWN
WM_RBUTTONDOWN
WM_LBUTTONUP
WM_RBUTTONUP
WM_LBUTTONDBLCLK
WM_RBUTTONDBLCLK
WM_MOUSEMOVE
нажата левая клавиша
нажата правая клавиша
отпущена левая клавиша
отпущена правая клавиша
двойной щелочек левой клавиши
двойной щелочек правой клавиши
перемещение мыши
Двойные щелчки мыши отрабатываются, только если в типе окна, при
инициализации, указан тип CS_DBLCKS.
Сообщение о перемещении мыши поступают через определенные интервалы
времени, резкие изменения туда обратно могут быть не отслежены.
case WM_MOUSEMOVE:MsX=LOWORD(lParam) ;
MsY=HIWORD(lParam) ; return(0) ;
А.В. Красов «Программирование под MsWindows на Borland C»
18 6.2. Рисование вне сообщения WM_PAINT
Для рисования вне сообщения WM_PAINT используются функции GetDC() и
ReleaseDC(), работа функций в целом аналогична функциям BeginPaint() и EndPaint().
HDC hdc ;
. . . .
hdc=GetDC(hwnd);
... Рисование ...
ReleaseDC(hwnd, hdc);
6.3. Вывод координат мыши
HDC hdc ;
char MouseSt[20] ;
. . . . . .
case WM_MOUSEMOVE:MsX=LOWORD(lParam) ;
MsY=HIWORD(lParam) ;
hdc=GetDC(hwnd);
SelectObject(hdc,hBrush[15]) ; sprintf(MouseSt,"x=%3d
y=%3d",MsX,MsY) ; Rectangle(hdc,200,10,400,30) ;
TextOut(hdc,202,12,MouseSt,lstrlen(MouseSt));
ReleaseDC(hwnd,hdc);
break ;
7. Диалоговые окна
7.1. Простейшие диалоговые окна
Windows позволяет создать управляющие подокна с более сложной организацией,
чем MessageBox(). Такие окна проще всего создать с помощью редактора ресурсов rc.
Редактирование описание окна можно производить, загрузив в редактор файл ресурсов
*.rc.
DIOLOG_TEST DIALOG 70, 36, 170, 100
STYLE DS_MODALFRAME |WS_POPUP |WS_CAPTION |WS_SYSMENU
А.В. Красов «Программирование под MsWindows на Borland C»
19 CAPTION "Заголовок"
BEGIN
DEFPUSHBUTTON "OK", IDOK, 14, 79, 57, 14, WS_CHILD |
WS_VISIBLE
|WS_TABSTOP
PUSHBUTTON "Cancel", IDCANCEL, 112, 78, 46, 14, WS_CHILD |
WS_VISIBLE | WS_TABSTOP
END
Вызов из основной программы выглядит следующим образом:
static DLGPROC lpfnDlgProc; /* Адрес функции обработки сообщений
. . . .
диалогового окна */
lpfnDlgProc=(DLGPROC)
MakeProcInstance((FARPROC)DlgProc,MainhInstance);
DialogBox(MainhInstance,"DIALOG_TEST",hwnd,lpfnDlgProc);
break;
Глобальная переменная MainhInstance типа HANDLE, в WinMain(), ей
присваивается значение параметра hInstance.
Функция диалогового окна описывается следующим образом:
#pragma argsused // Игнорировать предупреждения об неиспользованных
// параметрах функции диалогового окна.
BOOL CALLBACK _export
DlgProc(HWND hdlg,UINT msg,WPARAM wParam,LPARAM lParam)
{
switch(msg)
{
case WM_INITDIALOG: return(1) ;
case WM_COMMAND:switch(wParam)
{
case IDOK:
case IDCANCEL:
EndDialog(hdlg,0);
return(TRUE) ;
} /* Кон. switch(wPara) */
} /* Кон. switch(msg) */
return(FALSE) ;
А.В. Красов «Программирование под MsWindows на Borland C»
20 } /* Кон. DlgProc() */
7.2. Работа с элементами диалогового окна
Передача сообщений (информации) элементам диалогового окна чаще всего
производится при инициализации диалога, в сообщении WM_INITDIALOG.
Элементы диалога могут посылать функции диалогового окна сообщения
WM_COMMAND с wParam равным значению своего идентификатора, см. пред.
пример.
Получение информации введенной в элементах редактирования или выбранной в
списках и перечисляемых элементах, чаще всего производится при завершении
обработки диалога перед командой EndDialog().
Если ввод пользователя оказался некорректным вызов команды на завершение
диалога ( EndDialog() ) можно не производить.
7.3. Текстовая информация
Посылка текстовой строки в элемент диалога с идентификатором 700.
SetDlgItemText(hdlg,700,st1) ;
Получение текстовой строки из элемента редактора строки диалога с
идентификатором 701.
GetDlgItemText(hdlg,701,st2,11) ; // 11 максимальная длина строки.
7.4. Числовые значения
Если в редактор необходимо передать на редактирование число, то его сначала
необходимо записать в строку, функцией sprintf().
sprintf(st,"%f",Hmax) ;
SetDlgItemText(hdlg,710,st) ;
Если в редакторе редактировалось число, то из полученной строки его можно
получить функций sscanf():
А.В. Красов «Программирование под MsWindows на Borland C»
21 GetDlgItemText(hdlg,706,st,12) ; sscanf(st,"%f",&T0) ;
7.5. Выбор из списка
Если в диалоге содержится элемент, типа списка, то управлять им можно с
помощью сообщений
LB_ADDSTRING добавить в список строку,
LB_SETCURSEL установить позицию в вписке.
for(i=0;i<10;i++)
{
}
sprintf(st,"Type %d",i+1) ;
SendDlgItemMessage(hdlg,712,LB_ADDSTRING,0,(LONG)(LPSTR)st) ;
SendDlgItemMessage(hdlg,712,LB_SETCURSEL,TypeIntegr,0L) ;
Для получения номера выбранного пункта необходимо воспользоваться
сообщением LB_GETCURSEL.
TypeIntegr=SendDlgItemMessage(hdlg,702,LB_GETCURSEL,0,0L)+1 ;
7.5. Отмечаемые кнопки
Для работы с отмечаемыми кнопками можно воспользоваться сообщениями:
BM_SETCHECK
BM_GETCHECK
установить значение кнопки ( 0 | 1 ),
получить значение кнопки ( 0 | 1 ).
Приведенный ниже пример иллюстрирует работу с нажимными кнопками.
Выбирается СОМ порт для работы с аппаратурой. При выборе СОМ1, СОМ2
сбрасывается и наоборот. Аналогичные действия можно получить, используя
специальный класс групповых элементов.
#pragma argsused BOOL CALLBACK _export
Opt_Dlg(HWND hdlg,UINT msg,WPARAM wParam,LPARAM lParam)
{
int i ;
switch(msg)
А.В. Красов «Программирование под MsWindows на Borland C»
22 {
case WM_INITDIALOG:
for(i=0;i<2;i++)
SendDlgItemMessage(hdlg,903+i,BM_SETCHECK,0,NULL)
SendDlgItemMessage(hdlg,903+PORT,BM_SETCHECK,1,NULL);
return TRUE;
case WM_COMMAND:
switch(wParam)
{
case 903:SendDlgItemMessage(hdlg,904,BM_SETCHECK,
SendDlgItemMessage(hdlg,903,BM_SETCHECK,
case 904:SendDlgItemMessage(hdlg,903,BM_SETCHECK,
SendDlgItemMessage(hdlg,904,BM_SETCHECK,
0,NULL)
1,NULL) ;
0,NULL)
1,NULL) ;
;
;
break ;
break ;
case IDOK:PORT=SendDlgItemMessage(hdlg,904,
BM_GETCHECK,0,NULL)+1 ;
case IDCANCEL: EndDialog(hdlg,0);
return TRUE;
} /* конец switc(wParam) */
} /* конец. switch(msg) */
return FALSE;
} /* конец GetCOM() */
Особое внимание в приведенном примере следует обратить на команду return. Если
она возвращает TRUE, как в конце приведенной выше функции, то диалоговое окно
не прорисовывается. Если диалоговая функция возвращает значение FALSE, то все
элементы диалогового окна будут при необходимости прорисовываться (фон, рамка).
Значение TRUE встречается в данном примере один раз, при уничтожении
диалогового окна. В остальных случаях используется значение FALSE.
А.В. Красов «Программирование под MsWindows на Borland C»
23 7.6. Команда на перерисовку окна
Выполнение команд меню или ввод информации в диалоге может потребовать
перерисовки изображения в основном окне. Сделать это можно вызовом двух
функций:
InvalidateRect(hwnd,NULL,TRUE) ;
UpdateWindow(hwnd) ;
Если требуется перерисовать только часть окна, то вместо NULL необходимо
подставить адрес структуры RECT, ограничивающий данную область.
7.7. Рисование в диалоге
Редактор ресурсов позволяет разместить в диалоговом окне только определенные
элементы, без возможности рисования в окне. Для создания в диалоге рисунка
необходимо наложить на диалог дочернее окно.
В описании диалога необходимо указать имя класса окна.
GET_ADD DIALOG 96, 29, 142, 99
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Add bloc data"
BEGIN
PUSHBUTTON "Ok",IDOK,40,83,29,11,WS_CHILD|WS_VISIBLE|WS_TABSTOP
PUSHBUTTON
"Can",IDCANCEL,74,82,28,11,WS_CHILD|WS_VISIBLE|
WS_TABSTOP
CONTROL "OK" IDOK,"DRAW_L",(WS_TABSTOP|WS_GROUP),61,35,20,20
END
В функции инициализации окон необходимо зарегистрировать класс окна и
указать функцию, которая будет выполнять графические команды в окне, наложенном
на диалог.
wndclass.style=CS_HREDRAW|CS_VREDRAW;
wndclass.lpfnWndProc=(WNDPROC)DrawL;
wndclass.cbClsExtra=0;
wndclass.cbWndExtra=0;
wndclass.hInstance=hInstance;
wndclass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
wndclass.hCursor=LoadCursor(NULL,IDC_ARROW);
wndclass.hbrBackground=GetStockObject(WHITE_BRUSH);
А.В. Красов «Программирование под MsWindows на Borland C»
24 wndclass.lpszMenuName=NULL ;
wndclass.lpszClassName="DRAW_L";
RegisterClass(&wndclass);
Функция окна, кроме сообщения WM_PAINT может обрабатывать и другие
сообщения, например, перемещение мышки.
long FAR PASCAL DrawL(HWND hwnd,WORD message, WORD wParam,LONG
lParam)
{
HDC hdc ;
PAINTSTRUCT ps ;
TEXTMETRIC tm ;
RECT rect ;
switch(message)
{
case WM_PAINT:
hdc=BeginPaint(hwnd,&ps) ;
Line(hdc,10,10,100,100) ;
EndPaint(hwnd,&ps)
return(0) ;
;
}/*Конец. switch() */ return(DefWindowProc(hwnd,message,wParam,lParam)) ;
} /*Конец DrawADD() */
8. Многооконный интерфейс
В Windows существует всего три типа окон.
WS_OVERLAPPED Перекрывающиеся окна. Это основной, универсальный тип
WS_POPUP
WS_CHILD
окна в Windows.
Всплывающие окна. Окна этого типа всегда оказываются
поверх всех окон на экране, даже если оно неактивное.
Данный тип окон не имеет заголовка.
Дочерние окна. Всегда имеет родительское окно. Всегда
отображаются внутри родительского окна.
Кроме этого, есть еще дополнительные типы, комбинация которых с выше
перечисленными типами описывает любое окно Windows.
WS_MAXIMIZEBOX Окно имеет кнопку максимизации.
А.В. Красов «Программирование под MsWindows на Borland C»
25 WS_MINIMIZEBOX Окно имеет кнопку минимизации.
WS_THICKFRAME
WS_SYSMENU
WS_HSCROLL
WS_VSCROLL
WS_DLGFRAME
WS_BORDER
WS_CAPTION
WS_MAXIMIZE
WS_DISABLED
WS_VISIBLE
WS_MINIMIZE
Для дочерних окон
WS_TABSTOP
WS_GROUP
WS_CLIPSIBLINGS
Окно имеет рамку. Без этого флага изменять размер окна
будет невозможно.
Окно имеет системное меню.
Окно имеет горизонтальный скроллинг.
Окно имеет вертикальный скроллинг.
Окно имеет тонкую рамку без заголовка.
Окно имеет широкую рамку без заголовка.
Окно имеет рамку и заголовок. Такие окна можно
перемещать мышкой за заголовок.
Создаваемое окно с таким флагом будет отражено в
максимальном размере.
Создается неактивное окно.
Окно оказывается видимым сразу после создания.
Создаваемое окно будет свернуто в пиктограмму.
Разрешение перехода по клавише табуляция на
ближайшее окно или орган управления.
Орган управления, помеченный этим флагом, отмечает
начало группы управляющих элементов, по которым
можно перемещаться, используя клавиши управления
курсом. Группа оканчивается там, где начинается
следующая группа.
Этот флаг позволяет избежать конфликтов при
измерении размеров дочернего окна и наложении его на
другие дочерние окна.
А.В. Красов «Программирование под MsWindows на Borland C»
26 Перечисленные выше флаги являются битовыми масками, которые можно
складывать друг с другом с помощью арифметической операции ИЛИ обозначаемой «|».
Но при этом необходимо учитывать, что не все флаги совместимы между собой.
Наиболее распространенные комбинации флагов для описания окон уже описаны:
WS_OVERLPPEDWINDOW WS_OWERLAPPED
|
|
|
|
WS_TICKFRAME
WS_CAPTION
WS_SYSMENU
WS_MINIMIZEBOX | WS_MAXIMIZEBOX
WS_POPUP | WS_BORDER | WS_SYSMENU
WS_POPUPWINDOW
WS_WS_CHILDWINDOW WS_CHILD
Указание типа окна осуществляется в третьем аргументе функции CreateWindow().
Пример:
hwnd=CreateWindow("Hello","Заголовок окна",
WS_OVERLAPPEDWINDOW,
//
тип окна
CW_USEDEFAULT,CW_USEDEFAULT,
СW_USEDEFAULT,CW_USEDEFAULT,
NULL, hInstance, NULL).
NULL,
Отдельным сложным моментом при создании многооконного интерфейса
является то, что при создании несколько окон одного класса, оконная функция у
них будет одна и та же.
А.В. Красов «Программирование под MsWindows на Borland C»
27 9. Создание справочной системы
Программа, а тем более, учебная программа, на разработку которой ориентированно
данное пособие, немыслима без системы помощи. Операционная система Windows
имеет в своем составе утилиту WinHelp.exe, которая быстро и просто позволяет
сложные и разветвленные системы помощи. Исходный файл для системы помощи
создается с редактором Ms Word, расставляя управляющие символы можно
организовывать меню и переходы между страницами. Для трансляции документа Ms
Word необходимо сохранить его в формате RTF файла, и откомпилировать
специальным компилятором. В составе Borland Cи имеется компилятор hlp файлов, но у
него есть некоторые проблемы с обработкой больших картинок. Поэтому лучше
воспользоваться компилятором hlp фирмы Microsoft. Рабочий экран компилятора
приведен ниже.
Для задания управляющих символов используются:
Символ
Назначение
Символ
Назначение
Начало раздела.
Имя главы.
#
$
Управляющие символы включаются в документ как сноски.
Подключение графических файлов возможно либо командой {BMC <имя файла
Ключевое слово.
Порядок просмотра глав.
K
+
BMP>}, либо их можно просто включить в исходный документ.
Пример системы помощи:
Стр. 1
Стр. 3
А.В. Красов «Программирование под MsWindows на Borland C»
28 Содержание системы
помощи
Первый пункт menu
1
#Заголовок второго пункта
Второй пункт menu
2
Третий пункт menu
3
_______
#menu2
Стр. 4
#Заголовок третьего пункта
Стр. 2
#Заголовок первого пункта
_______
#menu1
При написании системы помощи заголовки выделяются двойным подчеркиванием,
после названия раздела идет метка страницы, на которую происходит переход при
выборе данного пункта. Он пишется скрытым текстом, этот режим задается в опциях
Word – Формат \ шрифт. Разделы системы помощи разделяются разрывами страницы. В
каждом разделе ставится сноска «#», связывающая раздел с меткой, по которой
происходит переход.
_______
#menu3
Кроме текста системы помощи, необходимо сформировать файл проекта, он
создается как обычный текстовый файл.
[OPTIONS]
TITLE=Help to PKI02
CONTENTS=CONTENTS
[FILES]
pki02.rtf
[CONFIG]
BrowseButtons()
[MAP]
Назначение полей в этом файле:
TITLE задание заголовка справочной системы.
[FILES] – имена RTF файлов для трансляции.
[CONFIG] – указывается, что в создаваемой справочной системе должны
присутствовать стандартные кнопки просмотра, обрабатываемые стандартной функцией
BrowsButtons().
Вызов справочной системы из программы осуществляет функция WinHelp(HWND,
<Имя hlpфайла>, HELP_CONTENTS, 0L). В принципе можно при вызове справочной
системы прейти сразу на конкретный раздел. Функция WinHelp создаст независимое
окно. Систему справки можно вызывать и отдельно из Windows.
А.В. Красов «Программирование под MsWindows на Borland C»
29
Лекция "Рисование в окне в си"
Лекция "Рисование в окне в си"
Лекция "Рисование в окне в си"
Лекция "Рисование в окне в си"
Лекция "Рисование в окне в си"
Лекция "Рисование в окне в си"
Лекция "Рисование в окне в си"
Лекция "Рисование в окне в си"
Лекция "Рисование в окне в си"
Лекция "Рисование в окне в си"
Лекция "Рисование в окне в си"
Лекция "Рисование в окне в си"
Лекция "Рисование в окне в си"
Лекция "Рисование в окне в си"
Лекция "Рисование в окне в си"
Лекция "Рисование в окне в си"
Лекция "Рисование в окне в си"
Лекция "Рисование в окне в си"
Лекция "Рисование в окне в си"
Лекция "Рисование в окне в си"
Лекция "Рисование в окне в си"
Лекция "Рисование в окне в си"
Лекция "Рисование в окне в си"
Лекция "Рисование в окне в си"
Лекция "Рисование в окне в си"
Лекция "Рисование в окне в си"
Лекция "Рисование в окне в си"
Лекция "Рисование в окне в си"
Лекция "Рисование в окне в си"
Материалы на данной страницы взяты из открытых истончиков либо размещены пользователем в соответствии с договором-офертой сайта. Вы можете сообщить о нарушении.