Цитата: regan32
Возможно поздно, но всеже.
[more=Вот когда-то давно писал, даже не знаю насколько работоспособно]
#include <stdio.h>
#include <conio.h>
#include <bios.h>
#include <string.h>
#include <stdlib.h>
#define FALSE 0
#define TRUE 1
// Коды клавишь используемых в меню
#define ESC 283
#define ENTER 7181
#define UP 18432
#define DOWN 20480
#define LEFT 19200
#define RIGHT 19712
// Константы для прорисовки рамок окон
const char up_left[3]={" ┌╔"}, up_right[3]={" ┐╗"}, down_left[3]={" └╚"};
const char down_right[3]={" ┘╝"}, line_g[3]={" -═"}, line_v[3]={" │║"};
// Структура - описатель элументов подменю
typedef struct _tagMenuSubItem
{
char *text;
struct _tagMenuSubItem *next;
}tagMenuSubItem;
// Структура - описатель элумунтов меню
typedef struct _tagMenuItem
{
char *text;
tagMenuSubItem *first;
struct _tagMenuItem *next;
}tagMenuItem;
void ShowWindow( int, int, int, int, char, char, char, char, char * );
tagMenuItem* AddItem( char *, tagMenuSubItem *, tagMenuItem * );
tagMenuSubItem* AddSubItem( char *, tagMenuSubItem * );
void DeleteMenuItem( tagMenuItem * );
tagMenuSubItem* ShowItemCursor( tagMenuItem *firstItem, int id, int *xCoor, char cursColor, char cursPaper );
void ShowMenuItem( tagMenuItem *, char, char );
void InitStatusLine( char * );
int ExecMenu( int *, int *, tagMenuItem *, char, char, char, char, char, char );
void InputData( void );
void FreeMatrix( void );
void InputMatrix( void );
void ShowMatrix( void );
int ShowMatrixSegment( int, int );
unsigned long memUsed = 0;
float **theMatrix;
int M, N;
int ExecMenu( int *id1, int *id2, tagMenuItem *firstItem,
char textColor, char textPaper,
char cursColor, char cursPaper,
char winBorder, char winShadow )
{
tagMenuItem *p, *p1;
tagMenuSubItem *pp, *pp1;
int key, iid1=1, iid2, iCount1=0, iCount2=0, xCoor, yCoor, i;
int wx1, wx2, wy1, wy2, maxLen, zSize;
char subOpen = FALSE, *zBuf;
zBuf = NULL;
p = firstItem;
_setcursortype( _NOCURSOR );
while( p )
{
p = p -> next;
iCount1++;
}
char quit=TRUE;
do{
// Show
ShowMenuItem( firstItem, textColor, textPaper );
// xCoor = ShowItemCursor( firstItem, iid1, CYAN, BLUE );
pp = ShowItemCursor( firstItem, iid1, &xCoor, cursColor, cursPaper );
if ( pp && subOpen )
{
pp1 = pp;
yCoor = wy1 + 1;
i = 1;
while( pp1 )
{
if ( i == iid2 )
{
textcolor( cursColor );
textbackground( cursPaper);
}
else
{
textcolor( textColor );
textbackground( textPaper);
}
gotoxy( wx1 + 1, yCoor );
cprintf( "%s", pp1 -> text );
pp1 = pp1 -> next;
yCoor++;
i++;
}
}
key = bioskey(0);
switch( key )
{
case ESC:
if ( subOpen )
{
if ( zBuf )
{
puttext( wx1,wy1,wx2+2,wy2+1, zBuf );
free( zBuf );
}
subOpen = FALSE;
}
else
{
quit=FALSE;
}
break;
case ENTER:
if ( subOpen )
{
quit = FALSE;
}
else
{
if ( pp )
{
subOpen = TRUE;
iid2 = 1;
///////////////////////////////////////////////////////////////////
if ( zBuf )
{
puttext( wx1,wy1,wx2+2,wy2+1, zBuf );
free( zBuf );
}
pp1 = pp;
iCount2 = 0;
maxLen = 0;
while( pp1 )
{
if ( maxLen < strlen( pp1 -> text ) )
maxLen = strlen( pp1 -> text );
pp1 = pp1 -> next;
iCount2++;
}
wx1 = xCoor - 1;
wx2 = wx1 + maxLen + 1;
wy1 = 2;
wy2 = wy1 + iCount2 + 1;
zSize = ( wx2 - wx1 + 2 ) + ( wy2 - wy1 + 1 );
zBuf = (char *) malloc( zSize );
if ( !zBuf )
{
printf("Not enough memory to allocate buffer\n");
exit(1); /* terminate program if out of memory */
}
// Show window
gettext( wx1,wy1,wx2+2,wy2+1, zBuf );
ShowWindow( wx1, wy1, wx2, wy2, textColor, textPaper, winBorder, winShadow, "" );
///////////////////////////////////////////////////////////////////
}
}
break;
case LEFT:
iid1--;
if ( iid1 < 1 ) iid1 = iCount1;
if ( subOpen )
{
iid2 = 1;
pp = ShowItemCursor( firstItem, iid1, &xCoor, CYAN, BLUE );
///////////////////////////////////////////////////////////////////
if ( zBuf )
{
puttext( wx1,wy1,wx2+2,wy2+1, zBuf );
free( zBuf );
}
pp1 = pp;
iCount2 = 0;
maxLen = 0;
while( pp1 )
{
if ( maxLen < strlen( pp1 -> text ) )
maxLen = strlen( pp1 -> text );
pp1 = pp1 -> next;
iCount2++;
}
wx1 = xCoor - 1;
wx2 = wx1 + maxLen + 1;
wy1 = 2;
wy2 = wy1 + iCount2 + 1;
zSize = ( wx2 - wx1 + 2 ) + ( wy2 - wy1 + 1 );
zBuf = (char *) malloc( zSize );
if ( !zBuf )
{
printf("Not enough memory to allocate buffer\n");
exit(1); /* terminate program if out of memory */
}
// Show window
gettext( wx1,wy1,wx2+2,wy2+1, zBuf );
ShowWindow( wx1, wy1, wx2, wy2, textColor, textPaper, winBorder, winShadow, "" );
///////////////////////////////////////////////////////////////////
}
break;
case RIGHT:
iid1++;
if ( iid1 > iCount1 ) iid1 = 1;
if ( subOpen )
{
iid2 = 1;
pp = ShowItemCursor( firstItem, iid1, &xCoor, CYAN, BLUE );
///////////////////////////////////////////////////////////////////
if ( zBuf )
{
puttext( wx1,wy1,wx2+2,wy2+1, zBuf );
free( zBuf );
}
pp1 = pp;
iCount2 = 0;
maxLen = 0;
while( pp1 )
{
if ( maxLen < strlen( pp1 -> text ) )
maxLen = strlen( pp1 -> text );
pp1 = pp1 -> next;
iCount2++;
}
wx1 = xCoor - 1;
wx2 = wx1 + maxLen + 1;
wy1 = 2;
wy2 = wy1 + iCount2 + 1;
zSize = ( wx2 - wx1 + 2 ) + ( wy2 - wy1 + 1 );
zBuf = (char *) malloc( zSize );
if ( !zBuf )
{
printf("Not enough memory to allocate buffer\n");
exit(1); /* terminate program if out of memory */
}
// Show window
gettext( wx1,wy1,wx2+2,wy2+1, zBuf );
ShowWindow( wx1, wy1, wx2, wy2, textColor, textPaper, winBorder, winShadow, "" );
///////////////////////////////////////////////////////////////////
}
break;
case UP:
if ( subOpen )
{
iid2--;
if ( iid2 < 1 ) iid2 = iCount2;
}
break;
case DOWN:
if ( subOpen )
{
iid2++;
if ( iid2 > iCount2 ) iid2 = 1;
}
break;
}
}while( quit );
_setcursortype( _NORMALCURSOR );
if ( zBuf )
{
puttext( wx1,wy1,wx2+2,wy2+1, zBuf );
free( zBuf );
}
ShowMenuItem( firstItem, textColor, textPaper );
*id1 = iid1;
*id2 = iid2;
return key;
}
tagMenuSubItem* ShowItemCursor( tagMenuItem *firstItem, int id, int *xCoor, char cursColor, char cursPaper )
{
tagMenuItem *p;
int x=2, i=1;
textcolor( cursColor );
textbackground( cursPaper );
p = firstItem;
gotoxy( 1,1 );
while( p )
{
if ( i == id )
{
gotoxy( x, 1 );
cprintf( "%s", p -> text );
*xCoor = x;
return p -> first;
}
x += strlen( p -> text );
p = p -> next;
i++;
}
return NULL;
}
void ShowMenuItem( tagMenuItem *firstItem, char lineColor, char linePaper )
{
tagMenuItem *p;
int x;
gotoxy(1,1);
textcolor( lineColor );
textbackground( linePaper );
for( x=1; x<=80; x++ )
cprintf( " " );
p = firstItem;
gotoxy( 2,1 );
while( p )
{
cprintf( "%s", p -> text );
p = p -> next;
}
}
void DeleteMenuItem( tagMenuItem *firstItem )
{
tagMenuItem *p, *p1;
tagMenuSubItem *pp, *pp1;
p = firstItem;
while( p ) // Цикл удаления элументов меню
{
p1 = p -> next;
pp = p -> first;
while( pp ) // Цикл удаления элементов под меню
{
pp1 = pp -> next;
free( pp -> text ); // Освобождаем память из под текстового поля
free( pp ); // Удаляем весь элемент подменю
pp = pp1;
}
free( p -> text ); // Освобождаем память из под текстового поля
free( p ); // Удаляем весь элемент меню
p = p1;
}
}
tagMenuSubItem* AddSubItem( char *str, tagMenuSubItem *nextItem )
{
tagMenuSubItem *p;
p = (tagMenuSubItem *) malloc( sizeof(tagMenuSubItem) );
if ( !p )
{
printf("Not enough memory to allocate buffer\n");
exit(1); /* terminate program if out of memory */
}
p -> text = (char *)malloc( strlen(str) + 1 );
if ( !p -> text )
{
printf("Not enough memory to allocate buffer\n");
exit(1); /* terminate program if out of memory */
}
strcpy( p -> text, str );
p -> next = nextItem;
return p;
}
tagMenuItem* AddItem( char *str, tagMenuSubItem *subItem, tagMenuItem *nextItem )
{
tagMenuItem *p;
p = (tagMenuItem *)malloc( sizeof(tagMenuItem) );
if ( !p )
{
printf("Not enough memory to allocate buffer\n");
exit(1); /* terminate program if out of memory */
}
p -> text = (char *)malloc( strlen(str) + 1 );
if ( !p -> text )
{
printf("Not enough memory to allocate buffer\n");
exit(1); /* terminate program if out of memory */
}
strcpy( p -> text, str );
p -> first = subItem;
p -> next = nextItem;
return p;
}
void ShowWindow( int x1, int y1, int x2, int y2, char wc, char wp, char b, char s, char *h )
{
int x,y,l;
char buf[200];
textcolor( wc );
textbackground( wp );
for( y=y1; y<=y2; y++ )
for( x=x1; x<=x2; x++ )
{
gotoxy( x,y );
cprintf(" ");
}
for( y=y1; y<=y2; y++ )
{
gotoxy( x1,y ); cprintf("%c", line_v[b]);
gotoxy( x2,y ); cprintf("%c", line_v[b]);
}
for( x=x1; x<=x2; x++ )
{
gotoxy( x,y1 ); cprintf("%c", line_g[b]);
gotoxy( x,y2 ); cprintf("%c", line_g[b]);
}
gotoxy( x1,y1 ); cprintf("%c",up_left[b]);
gotoxy( x2,y1 ); cprintf("%c",up_right[b]);
gotoxy( x1,y2 ); cprintf("%c",down_left[b]);
gotoxy( x2,y2 ); cprintf("%c",down_right[b]);
l = strlen( h );
y = (x2-x1)/2;
x = x1 + y - l/2 + 1;
gotoxy( x, y1 );
cprintf("%s", h );
if (s)
{
gettext( x2+1, y1+1, x2+2, y2+1, buf );
for( x=1; x<=170; x+=2 )
buf[x] = LIGHTGRAY;
puttext( x2+1, y1+1, x2+2, y2+1, buf );
gettext( x1+2, y2+1, x2+2, y2+1, buf );
for( x=1; x<=170; x+=2 )
buf[x] = LIGHTGRAY;
puttext( x1+2, y2+1, x2+2, y2+1, buf );
}
}
void InitStatusLine( char *s )
{
int x,a,l,c=FALSE;
l = strlen( s );
textcolor( BLACK );
textbackground( WHITE );
window( 1, 25, 80, 25 );
clrscr();
for( x=1, a=0; a<l; a++ )
{
gotoxy( x,25 );
if ( s[a]=='~' ) { c=!c; continue; }
if ( c ) textcolor( RED ); else textcolor( BLACK );
cprintf("%c", s[a] );
x++;
if ( x>80 ) break;
}
window( 1,1,80,25 );
}
void FreeMatrix( void )
{
int i;
if ( theMatrix )
{
for( i = 0; i <= M; i++ )
free( theMatrix[i] );
free( theMatrix );
}
}
void InputData( void )
{
int i;
char quit=TRUE;
FreeMatrix();
do{
ShowWindow( 1, 2, 80, 24, YELLOW, BLUE, 2, 0, "" );
gotoxy( 4,4 ); textcolor( CYAN ); textbackground( BLUE );
cprintf( "Размерность матрицы (MxN):" );
gotoxy( 8,6 ); textcolor( BLUE ); textbackground( WHITE );
cprintf(" ");
gotoxy( 30, 6 ); cprintf(" ");
gotoxy( 4,6 ); textcolor( CYAN ); textbackground( BLUE );
cprintf( "M =" );
gotoxy( 26,6 ); cprintf( "N =" );
_setcursortype( _NORMALCURSOR );
gotoxy( 8,6 ); textcolor( BLUE ); textbackground( WHITE );
scanf( "%d", &M );
gotoxy( 30,6 ); textcolor( BLUE ); textbackground( WHITE );
scanf( "%d", &N );
_setcursortype( _NOCURSOR );
theMatrix = (float**) malloc( sizeof(float*) * M );
if ( !theMatrix )
{
gotoxy( 4,8 ); textcolor( CYAN ); textbackground( BLUE );
cprintf( " Не хватает памяти для создания массива!" );
}
else
{
memUsed += ( sizeof(float*) * M );
for( i = 0; i <= M; i++ )
{
theMatrix[i] = (float*) malloc( sizeof(float) * N );
memset( theMatrix[i], 0, sizeof(float) * N );
if ( !theMatrix )
{
gotoxy( 4,8 ); textcolor( CYAN ); textbackground( BLUE );
cprintf( " Не хватает памяти для создания массива!" );
free( theMatrix );
memUsed -= ( sizeof(float*) * M );
}
else
{
quit = FALSE;
memUsed += ( sizeof(float) * N );
}
}
}
}while( quit );
//InputMatrix();
ShowMatrix();
}
void ShowMatrix( void )
{
int key, stat, xs = 0, ys = 0;
char quit = TRUE;
do{
stat = ShowMatrixSegment( ys , xs );
key = bioskey( 0 );
switch( key )
{
case ESC: quit = FALSE; break;
case DOWN:
if ( (stat == 1 || stat == 3) && ys < M )
ys++;
break;
case UP:
if ( ys >= 1 ) ys--;
break;
case LEFT:
if ( xs >= 1 ) xs--;
break;
case RIGHT:
if ( (stat == 2 || stat == 3) && xs < N )
xs++;
break;
}
}while (quit);
}
int ShowMatrixSegment( int is, int js )
{
int i, j, x, y;
int result = 0;
window( 2, 3, 79, 23 ); textbackground( BLUE ); clrscr();
window( 1, 1, 80, 25 ); textcolor( LIGHTGRAY );
gotoxy( 6, 3 ); cprintf( "N" );
gotoxy( 3, 4 ); cprintf( "M" );
for( x = 8, j = js; (j < N) && (x < 75); j++, x += 8 )
{
gotoxy( x, 3 ); cprintf( "%d", j+1 );
}
for( y = 5, i = is; (i < M) && (y < 24); i++, y++ )
{
gotoxy( 3, y ); cprintf( "%d", i+1 );
}
textcolor( BLUE ); textbackground( WHITE );
for( y = 5, i = is; (i < M) && (y < 24); i++, y++ )
{
for( x = 8, j = js; (j < N) && (x < 75); j++, x+= 8 )
{
gotoxy( x,y ); cprintf( "%-4.1f", theMatrix[i][j] );
}
}
if ( i < M && y >= 24 ) result = 1;
if ( j < N && x > 75 ) result = 2;
if (( i < M && y >= 24 ) && ( j < N && x > 75 )) result = 3;
return result;
}
void InputMatrix( void )
{
int i, j;
for( i = 0; i < M; i++ )
{
for( j = 0; j < N; j++ )
{
}
}
}
void main( void )
{
char quit=TRUE;
int key;
tagMenuItem *mainMenu;
textbackground( BLACK );
clrscr();
mainMenu = AddItem( " Файл ",
AddSubItem( " Ввод исходных данных ",
AddSubItem( " Редактирование данных ",
AddSubItem( " Сохранение данных ",
AddSubItem( " Вывод результатов ",
AddSubItem( " Выход ", NULL ))))),
AddItem( " Обработка ",
AddSubItem( " Произведение сумм ",
AddSubItem( " Min & Max ", NULL )),
AddItem( " Справка ",
AddSubItem( " О программе ... ",
AddSubItem( " Помощь ",
NULL )),
NULL )) );
int id1, id2;
ShowWindow( 1, 2, 80, 24, YELLOW, BLUE, 2, 0, "" );
InitStatusLine( " Памяти выделено: ~65535~ Min: ~YYYYYYYYYYY~ Max: ~ZZZZZZZZZ~ Матрица: ~MMM~x~NNN~" );
do{
key = ExecMenu( &id1, &id2, mainMenu, BLUE, CYAN, CYAN, BLUE, 2, 1 );
if ( key == ESC ) { id1 = 1; id2 = 5; }
switch( id1 )
{
case 1:
switch( id2 )
{
case 1:
char str[255];
InputData();
sprintf (str, " Памяти выделено: ~%ld~ Min: ~YYYYYYYYYYY~ Max: ~ZZZZZZZZZ~ Матрица: ~MMM~x~NNN~", memUsed);
InitStatusLine(str);
break;
case 2: ShowMatrix (); break;
case 3: break;
case 4: break;
case 5: quit = FALSE; break;
}
break;
case 2:
switch( id2 )
{
case 1: break;
case 2: break;
}
break;
case 3:
switch( id2 )
{
case 1: break;
case 2: break;
}
break;
}
}while( quit );
DeleteMenuItem( mainMenu );
FreeMatrix();
}
[/more]
[more=Второй вариант проще, но меню нужно будет вытянуть самому]
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <graphics.h>
#include <string.h>
#include <bios.h>
// Макроопределения кодов клавиш
#define ESC 283
#define F1 15104
#define ENTER 7181
#define UP 18432
#define DOWN 20480
#define LEFT 19200
#define RIGHT 19712
// Макрос вычисления адреса элемента в массиве
#define ITEM(Y,X,SIZE_X) (Y*SIZE_X + X)
// Размерность матрицы 7х8
#define ARRAY_SIZE_X 8
#define ARRAY_SIZE_Y 7
// Кол-во буферов (частей) заставки
#define IMG_BUF_COUNT 12
// ---------------------------------------------------------------------------
// Псевдографика для обрамления окошек
const char *LineG = {" ─═"};
const char *LineV = {" │║"};
const char *LeftUp = {" ┌╔"};
const char *RightUp = {" ┐╗"};
const char *LeftDown = {" └╚"};
const char *RightDown = {" ┘╝"};
// Пункты меню
// Главное меню
const char *MainMenuItems[] = {" Файл ",
" Обработка ",
" Справка "};
// Меню файл
const char *FileMenuItems[] = {" Загрузить данные ",
" Сохранить данные ",
" Ввод исходных данных ",
" Редактирование данных ",
" Заполнить случайными ",
" Вывод результатов ",
" Выход из программы "};
// Меню помощь
const char *HelpMenuItems[] = {" Руководство пользователя ",
" Об авторах ... "};
const UserGuideCount = 6; // Кол-во страниц в руководстве пользоваетеля
// Текст руководства пользователя
const char *UserGuideText[] = {
" Данные программный продукт предназначен для\r\n"
"обработки матриц.\r\n"
" Программа способна выполнять следующие функции:\r\n"
" 1. Формировать массив из модулей произведений "
"отрицательных элементов каждой строки; если таких"
"элементов в строке нет, результат будет = 0.\r\n"
" 2. Определять сумму произведений сформированного"
"массива и общее количество отрицательных\r\n"
"элементов строк.",
" 3. Определять минимальное и максимальное\r\n"
"значения произведений и менять местами строки\r\n"
"исходной матрицы, в которых они найдены.\r\n"
" Исходные данные могут быть введены как\r\n"
"с клавиатуры так и из файла, результат\r\n"
"также может быть сохранен в файл.\r\n"
" Меню файл - данное меню предоставляет\r\n"
"набор операций по вводу исходных данных.\r\n",
" Загрузить данные - данная опция\r\n"
"позволяет загрузить данные из файла,\r\n"
"при ее выборе программа просит ввести\r\n"
"имя загружаемого файла.\r\n"
" Сохранить данные - данная опция меню\r\n"
"позволяет сохранить исходный набор\r\n"
"данных в файле, для их последующего\r\n"
"использования. Для сохранения необходимо\r\n"
"ввести имя файла.\r\n",
" Ввод исходных данных - данный пункт меню\r\n"
"позволяет ввести данные с клавиатуры в режиме\r\n"
"диалога с пользователем.\r\n"
" Редактирование данных - данная опрция меню\r\n"
"позволяет отредактировать ранее введенные или\r\n"
"загруженные данные.\r\n"
" Заполнить случайными - программа производит\r\n"
"автозаполнение матрицы случайными числами.\r\n",
" Вывод результатов - данный пункт меню\r\n"
"позволяет пользователю просмотреть результаты\r\n"
"работы программы.\r\n"
"\r\n"
" Выход из программы - данные пункт меню\r\n"
"завершает работу программы и возвращает\r\n"
"управление ОС.\r\n",
" Меню обработка. Данное меню позволяет\r\n"
"выполнять функции над матрицей. Краткое\r\n"
"описание всех функций дано выше.\r\n"
" Меню справка позволяет получить\r\n"
"справочную информацию о программе и\r\n"
"ее авторах.\r\n"};
// ---------------------------------------------------------------------------
// Определения новых типов
typedef unsigned char byte; // байт
typedef unsigned int word; // слово
// ---------------------------------------------------------------------------
// Глобальные переменные
// Разрешение экрана в графическом режиме
int MaxX, MaxY;
// Для хранения Суммы, Мин, Мах, и кол-во отрицательных элементов
long gSum, gMin, gMax, gMinus;
// Номера строк с Мах и Мин элементами
int MinLine, MaxLine;
// Матрицы
int Matrix1 [ARRAY_SIZE_Y][ARRAY_SIZE_X]; // Исходная
int Matrix2 [ARRAY_SIZE_Y][ARRAY_SIZE_X]; // Результирующая
long VectorAbs [ARRAY_SIZE_Y]; // Результирующий массив произведений
// ---------------------------------------------------------------------------
// Описание прототипов функций
// Выбирает Мах из двух целых
int max(int value1, int value2);
// Выбирает Мин из двух целых
int min(int value1, int value2);
// Рисует окошко в графическом режиме
void ShowWindow (int x1, int y1, int x2, int y2, int color);
// Рисует кнопку в графическом режиме
void ShowKey (int x, int y, int paper, int color, char *text);
// Выводит заставку в графическом режиме
int SplashScreen (void);
// Инициализирует графику
void InitGraph (void);
// Запролняет экран белыми квадратиками (в точечку) в текстовом режиме
void DeskTop (void);
// Рисует окошко в текстовом режиме
void ShowWin (byte xPos, byte yPos, byte xSize, byte ySize, byte Bolder,
byte Shadow, byte Color, byte Paper, const char *Title);
// Показывает на экране один элемент меню в заданной позиции и заданным цветом
void ShowMenuItem (byte xPos, byte yPos, byte Paper, byte Color, const char *Item);
// Оконное меню
int Menu (byte xPos, byte yPos, byte xSize, byte ySize, byte Bolder,
byte Shadow, byte Color, byte Paper,
byte CursPaper, byte CursColor, const char *Title,
int item, const char *Items[], word defaultItem);
// Рисует строку внизу экрана и выводит на ней заданный текст
// текст заключенный в ~ТЕКСТ~ выводится красным цветом
void TaskBar (const char *Text);
// Выводит окошко диалога, и считывает с клавиатуры строку с именем файла
// считанную строку и возвращает
char *GetFileName (byte xPos, byte yPos, byte xSize);
// Сохраняет указанную матрицу
// *Vector - указатель на матрицу
// size_y,size_x размерность матрицы (7,8)
void SaveData (int *vector, word size_y, word size_x);
// Загружает данные из файла
void LoadData (int *vector, word size_y, word size_x);
// Рисует один элемент массива в заданных координатах с
// указанным цветом и фоном
void ShowVectItem (int item, word xPos, word yPos, byte Color, byte Paper);
// Для именения элемента
int ChangeItem (word x, word y);
// Рисует матрицу с возможностью редактирования
void ShowMatrix (int *vector, word size_y, word size_x);
// Выполняет ввод матрицы
void InputMatrix (int *vector, int size_y, int size_x);
// Заполняет матрицу случайными числами из диапозона [-50;50]
void RandMatrix (int *vector, int size_y, int size_x);
// Показывает резутаты работы
void ViewResult (int *m_vector, int size_y, int size_x, long *abs_vect,
long pMin, long pMax, long pSum, long pMinus, int *m_vect,
int nMin, int nMax);
// Выполняе решение
void CreateAbsVector (int *vector, int size_y, int size_x, long *resVector,
long *pMin, long *pMax, long *pSum, long *pMinus,
int *r_vect, int *n_Min, int *n_Max);
// Главная функция - управляет работой всей программы
void AppRun (void);
// Выводин информацию о разработчиках
void About (void);
// Выводит одну страницу руководства пользователя
void ShowUserGuide (const char *Text);
// Выполняет работу диалога руководство пользователя
void UserGuide (void);
// Востанавливает часть экрана
void RestoreScreen (byte xPos, byte yPos, byte xSize, byte ySize, byte *buf);
// Сохраняет часть экрана
byte *SaveScreen (byte xPos, byte yPos, byte xSize, byte ySize);
// ---------------------------------------------------------------------------
// Определения тел функций
// Выбирает Мах из двух целых
int max(int value1, int value2)
{
return ( (value1 > value2) ? value1 : value2);
}
// Выбирает Мин из двух целых
int min(int value1, int value2)
{
return ( (value1 < value2) ? value1 : value2);
}
// Рисует окошко в графическом режиме
void ShowWindow (int x1, int y1, int x2, int y2, int color)
{
setcolor (DARKGRAY);
rectangle (x1,y1,x2,y2);
rectangle (x1+3,y1+3,x2-3,y2-3);
line (x2,y1,x2-3,y1+3);
line (x1,y2,x1+3,y2-3);
setfillstyle (1,LIGHTGRAY);
floodfill (x1+2,y1+2,DARKGRAY);
setfillstyle (1,DARKGRAY);
floodfill (x2-2,y2-2,DARKGRAY);
setfillstyle (1,color);
floodfill (x1+6,y1+6,DARKGRAY);
}
// Рисует кнопку в графическом режиме
void ShowKey (int x, int y, int paper, int color, char *text)
{
int t = strlen (text);
setcolor (DARKGRAY);
rectangle (x, y, x + t * 8 + 10, y + 20);
rectangle (x + 3, y + 3, x + t * 8 + 7, y + 17);
line (x + t * 8 + 10, y, x + t * 8 + 7, y + 13);
line (x, y + 20, x + 3, y + 17);
setfillstyle (1, LIGHTGRAY);
floodfill (x + 2, y + 2, DARKGRAY);
setfillstyle (1, DARKGRAY);
floodfill (x + t * 8 + 8, y + 18, DARKGRAY);
setfillstyle (1, paper);
floodfill (x + 6, y + 6, DARKGRAY);
settextstyle (0,0,1);
setcolor (color);
settextjustify(LEFT_TEXT, TOP_TEXT);
outtextxy (x + 5, y + 7, text);
}
// Выводит заставку в графическом режиме
int SplashScreen (void)
{
InitGraph ();
randomize ();
setactivepage (1);
int midx = MaxX / 2;
setbkcolor (CYAN);
ShowWindow (141, 101, 499, 249, BLUE);
ShowKey (160,217,CYAN,BLUE,"F1 - About");
ShowKey (270,217,CYAN,BLUE,"Enter - Run");
ShowKey (390,217,CYAN,BLUE,"ESC - Exit");
setcolor (WHITE);
settextstyle (0, HORIZ_DIR, 1);
settextjustify(CENTER_TEXT, CENTER_TEXT);
setcolor (YELLOW);
// Вставить нужный текст
outtextxy (midx, 115, "The Matrix v.099"); // Название проги
outtextxy (midx, 125, "(C) April 2004"); // Типа Дата создания
setcolor (WHITE);
outtextxy (midx, 145, "Created by"); // Разработано
setcolor (LIGHTCYAN);
outtextxy (midx, 165, "Berov Andrey"); // ФИО
// outtextxy (midx, 180, "4-4b ISE"); // Курс, группа и т.д.
outtextxy (midx, 195, "Kamensk YRGTU 2004"); // Универ и т.д.
int step = (500 - 140) / IMG_BUF_COUNT;
int img_size = imagesize (140, 100, 140 + step, 250);
void *img_buf[IMG_BUF_COUNT];
for (int i = 0; i < IMG_BUF_COUNT; i++)
{
img_buf[i] = new char [img_size];
if (!img_buf[i])
{
printf("Нет свободной памяти! buffer %d, size %d, all size = %d\n",
i, img_size, img_size * IMG_BUF_COUNT);
bioskey (0);
exit (1);
}
getimage (140+step*i, 100, (140+step)+step*i, 250, img_buf[i]);
}
setactivepage (0);
setbkcolor (CYAN);
cleardevice ();
for (int y = 100; y >= 0; y--)
{
for (int i = 0; i < IMG_BUF_COUNT; i++)
{
if ( i % 2 )
putimage (140+step*i, 100+y, img_buf[i], COPY_PUT);
else
putimage (140+step*i, 100-y, img_buf[i], COPY_PUT);
}
}
for (int x = 0; x < IMG_BUF_COUNT; x++)
delete [] img_buf[x];
setactivepage (1);
setbkcolor (CYAN);
cleardevice ();
ShowWindow (141, 101, 499, 249, MAGENTA);
ShowKey (390,217,BLUE,YELLOW,"ESC - Exit");
settextstyle (0, HORIZ_DIR, 1);
settextjustify(CENTER_TEXT, CENTER_TEXT);
setcolor (YELLOW);
// Вставить нужный текст
outtextxy (midx, 115, "The Matrix v.099"); // Название проги
outtextxy (midx, 125, "(C) April 2004"); // Типа Дата создания
setcolor (WHITE);
outtextxy (midx, 145, "Демонстрационная программа");
outtextxy (midx, 165, "выполняет работу с массивами данных");
outtextxy (midx, 195, "Kamensk YRGTU 2004"); // Универ и т.д.
setactivepage (0);
int key;
for (;;)
{
key = bioskey (0);
switch (key)
{
case ESC: restorecrtmode (); return 0;
case F1: // Показываеть хелп, он на второй страницы
setvisualpage (1); // Переключим на вторую страницу
bioskey (0); // Подождем нажатия на кнопку
setvisualpage (0); // Вернем первую страницы
break;
case ENTER: restorecrtmode (); return 1;
}
}
}
// Инициализирует графику
void InitGraph (void)
{
// Выбран VGA дривер с 2-мя страницами видео памяти
int gdriver = VGA, gmode = VGAMED, errorcode;
// При необходимости изменить путь к драйверу (VGAEGA.BGI)
initgraph(&gdriver, &gmode, "");
errorcode = graphresult();
if (errorcode != grOk)
{
printf("Ошибка при работе с графикой: %s\n", grapherrormsg(errorcode));
printf("Нажмите любую клавишу для прекращения работы:");
bioskey (0);
exit(1); /* return with error code */
}
// Проинициализируем макимальным разрешением экрана
MaxX = getmaxx ();
MaxY = getmaxy ();
}
// Запролняет экран белыми квадратиками (в точечку) в текстовом режиме
void DeskTop (void)
{
textcolor (WHITE); // Цвет текста на экране
textbackground (BLUE); // Цвет фона экрана
_wscroll = 0;
for (int y = 1; y <= 25; y++)
for (int x = 1; x <= 80; x++)
{
gotoxy (x,y);
cprintf ("▒"); // Заполняем экран этим символом
}
_wscroll = 1;
}
// Рисует окошко в текстовом режиме
void ShowWin (byte xPos, byte yPos, byte xSize, byte ySize, byte Bolder,
byte Shadow, byte Color, byte Paper, const char *Title)
{
// Расчет недостоющих координат
int y, x, yEnd = yPos + ySize, xEnd = xPos + xSize;
// Установка цвета символов и фона
textcolor (Color);
textbackground (Paper);
// Рисуем квадратик
for (y = yPos; y <= yEnd; y++)
for (x = xPos; x <= xEnd; x++)
{
gotoxy (x, y);
cprintf (" ");
}
// Проводим вертикальные линии
for (y = yPos; y <= yEnd; y++)
{
gotoxy (xPos, y); cprintf ("%c", LineV [Bolder]);
gotoxy (xEnd, y); cprintf ("%c", LineV [Bolder]);
}
// Проводим горизонтальные линии
for (x = xPos; x <= xEnd; x++)
{
gotoxy (x, yPos); cprintf ("%c", LineG [Bolder]);
gotoxy (x, yEnd); cprintf ("%c", LineG [Bolder]);
}
// Рисуем уголки окошка
gotoxy (xPos, yPos); cprintf ("%c", LeftUp [Bolder]);
gotoxy (xPos, yEnd); cprintf ("%c", LeftDown [Bolder]);
gotoxy (xEnd, yPos); cprintf ("%c", RightUp [Bolder]);
gotoxy (xEnd, yEnd); cprintf ("%c", RightDown [Bolder]);
// Если есть надпись, то выведем ее в верху окошка
if (Title)
{
// Расчитаем середину окна
int midx = xPos + (xSize / 2) - (strlen (Title) / 2) + xSize % 2;
gotoxy (midx, yPos); cprintf ("%s", Title);
}
// Если окошко должно быть с тень, то нарисуем ее
if (Shadow)
{
int i;
word buf_size = xSize * 2 + 1;
byte *pbuf;
byte *buf = new byte [buf_size];
gettext (xPos + 2, yEnd + 1, xEnd + 2, yEnd + 1, buf);
for (pbuf=&buf[1], i=0; i<buf_size; *pbuf=1+2+4, i+=2, pbuf+=2);
puttext (xPos + 2, yEnd + 1, xEnd + 2, yEnd + 1, buf);
delete [] buf;
buf_size = ySize * 2 * 2 + 1;
buf = new byte [buf_size];
gettext (xEnd + 1, yPos + 1, xEnd + 2, yEnd, buf);
for (pbuf=&buf[1], i=0; i<buf_size; *pbuf=1+2+4, i+=2, pbuf+=2);
puttext (xEnd + 1, yPos + 1, xEnd + 2, yEnd, buf);
delete [] buf;
}
}
// Показывает на экране один элемент меню в заданной позиции и заданным цветом
void ShowMenuItem (byte xPos, byte yPos, byte Paper, byte Color, const char *Item)
{
textcolor (Color);
textbackground (Paper);
gotoxy (xPos, yPos);
cprintf ("%s", Item);
}
// Оконное меню
int Menu (byte xPos, byte yPos, byte xSize, byte ySize, byte Bolder,
byte Shadow, byte Color, byte Paper,
byte CursPaper, byte CursColor, const char *Title,
int item, const char *Items[], word defaultItem)
{
_setcursortype (_NOCURSOR); // вырубим мигающий курсор
// Нарисуем окошко
ShowWin (xPos, yPos, xSize, ySize, Bolder, Shadow, Color, Paper, Title);
int CurrItem = defaultItem;
byte bExit = 1;
int key;
// Нарисуем все элементы
for (int i=0; i < item; i++)
ShowMenuItem (xPos+2, yPos+1+i, Paper, Color, Items[i]);
// Цикл работы меню
while (bExit)
{
// Рисуем курсор
ShowMenuItem (xPos+2, yPos+1+CurrItem, CursPaper, CursColor, Items[CurrItem]);
key = bioskey (0); // Опрос клавиатуры
// Скрываем выделенный пункт
ShowMenuItem (xPos+2, yPos+1+CurrItem, Paper, Color, Items[CurrItem]);
// Обрабатываем нажатие клавиш
switch (key)
{
case DOWN: CurrItem++; // нажали вниз
if (CurrItem >= item) CurrItem = 0;
break;
case UP: CurrItem--; // нажали вверх
if (CurrItem < 0) CurrItem = item - 1;
break;
case ESC: CurrItem = -1; // ESCAPE
case ENTER: bExit = 0; break; // ENTER
}
}
_setcursortype (_NORMALCURSOR); // Включим курсор
return CurrItem; // Вернем номер выбранного пункта (начинается с 0)
}
// Рисует строку внизу экрана и выводит на ней заданный текст
// текст заключенный в ~ТЕКСТ~ выводится красным цветом
void TaskBar (const char *Text)
{
word i = 80;
byte color = 0;
_wscroll = 0; // Чтобы экран не "убегал" вверх
// установим начальную позицию и цвета
gotoxy (1,25);
textcolor (BLACK);
textbackground (WHITE);
// Рисуем линию из начальной позиции
while (i--)
cprintf (" ");
// Вывод текста
i = 0;
gotoxy (1,25);
while (Text[i])
{
// Если встретили в тексте ~, то переключим цвет
if (Text[i] == '~')
color = !color;
else // Иначе просто выведем очедной символ
cprintf ("%c", Text[i]);
// Установим цвет в соответсвии с выбранным
if (color)
textcolor (RED); // Красный
else
textcolor (BLACK); // Черный
i++; // Чтоб перейте к следующему символу в строку
}
_wscroll = 1; // Включим скролирование экрана
}
// Выводит окошко диалога, и считывает с клавиатуры строку с именем файла
// считанную строку и возвращает
char *GetFileName (byte xPos, byte yPos, byte xSize)
{
// Запомним кусочек экрана под окошком
byte *buf = SaveScreen (xPos, yPos, xSize + 2, 2 + 1);
char str[255], param[25], sparam[50] = {"%"};
ShowWin (xPos, yPos, xSize, 2, 1, 1, LIGHTCYAN, BLUE, " Укажите имя файла ");
gotoxy (xPos+1, yPos+1);
itoa(xSize, param, 10);
strcat (sparam, param);
strcat (sparam, "s");
scanf (sparam, str);
// Востановим испорченный кусочек экрана
RestoreScreen (xPos, yPos, xSize + 2, 2 + 1, buf);
return str;
}
// Сохраняет указанную матрицу
// *Vector - указатель на матрицу
// size_y,size_x размерность матрицы (7,8)
void SaveData (int *vector, word size_y, word size_x)
{
// Выведем диалог, чтобы нам написали имя файла
char *str = GetFileName (25, 5, 50);
// Откроем указанный файл
FILE *out = fopen (str, "wb");
// Если не получилось открыть файл, то ничего делать не будем
if (!out)
{
printf ("Ошибка! Не могу открыть файл данных.\n");
return;
}
// цикл записи данных в файл
for (int y = 0, *ptr = vector; y < size_y; y++)
{
for (int x = 0; x < size_x; x++, ptr++)
fprintf (out, "%d ", *ptr);
fprintf (out, "\n");
}
fclose (out); // Закроем файл
}
// Загружает данные из файла
void LoadData (int *vector, word size_y, word size_x)
{
// Выведем диалог, чтобы взять у пользователя имя файла
char *str = GetFileName (25, 5, 50);
FILE *in = fopen (str, "rb"); // Откроем файл
// Если не получилось, то ничего делать не будем
if (!in)
{
printf ("Ошибка! Не могу открыть файл данных.\n");
return;
}
// Цикл чтения данных из файла
for (int y = 0, *ptr = vector, data; y < size_y; y++)
for (int x = 0; x < size_x; x++, ptr++)
{
fscanf (in, "%d", &data);
*ptr = data;
}
fclose (in); // Закроем файл
}
// Рисует один элемент массива в заданных координатах с
// указанным цветом и фоном
void ShowVectItem (int item, word xPos, word yPos, byte Color, byte Paper)
{
textcolor (Color);
textbackground (Paper);
gotoxy (xPos, yPos);
cprintf ("%-3d", item);
}
// Для именения элемента
int ChangeItem (word x, word y)
{
// Запомним чать экрана
byte *buf = SaveScreen (x + 1, y + 1, 10 + 2, 2 + 1);
// выведем окошко
ShowWin (x + 1, y + 1, 10, 2, 1, 1, WHITE, RED, "");
int newitem;
gotoxy (x + 2, y + 2);
scanf ("%3d", &newitem); // Прочитаем новое значение с клавиатуры
// Востановим испорченный экран
RestoreScreen (x + 1, y + 1, 10 + 2, 2 + 1, buf);
return newitem;
}
// Рисует матрицу с возможностью редактирования
void ShowMatrix (int *vector, word size_y, word size_x)
{
_setcursortype (_NOCURSOR);
word xPos=1, yPos=1, xSize = min (80, size_x * 4), ySize = min (24, size_y + 1);
int *ptr = vector, data;
byte *buf = SaveScreen (xPos, yPos, xSize + 2, ySize + 1);
byte bExit = 1;
// Окошко для вывода
ShowWin (xPos, yPos, xSize, ySize, 2, 1, LIGHTCYAN, BLUE, " Матрица ");
// Цикл вывода данных на экран
for (int y = 0; y < size_y; y++)
{
for (int x = 0, pos = xPos + 1; x < size_x; x++, ptr++, pos += 4)
{
gotoxy (pos, y + yPos + 1);
printf ("%-3d", *ptr);
}
}
// Меню для редактирования
int x, key;
x = y = 0;
while (bExit)
{
ptr = vector + ITEM (y, x, size_x); // Вычислим Адрес текущего элемента
// Покажем его на экране другим цветом
ShowVectItem (*ptr, x*4 + xPos + 1, y + yPos + 1, BLUE, LIGHTCYAN);
key = bioskey (0); // Прочитам клавиатуру
// Потушим выделенный элемент
ShowVectItem (*ptr, x*4 + xPos + 1, y + yPos + 1, LIGHTCYAN, BLUE);
// Обработаем нажатую клавишу
switch (key)
{
case LEFT: x--; if (x<0) x = size_x-1; break; // нажали влево
case RIGHT: x++; if (x>=size_x) x = 0; break; // нажали вправо
case UP: y--; if (y<0) y = size_y - 1; break; // вниз
case DOWN: y++; if (y>=size_y) y = 0; break; // вверх
case ESC: bExit = 0; break; // отмена
// изменить текущий элемент
case ENTER: *ptr = ChangeItem (x*4+xPos+1, y+yPos+1); break;
}
}
// Востановим ипорченную часть экрана
RestoreScreen (xPos, yPos, xSize + 2, ySize + 1, buf);
_setcursortype (_NORMALCURSOR); // включим курсор
}
// Выполняет ввод матрицы
void InputMatrix (int *vector, int size_y, int size_x)
{
word xPos=1, yPos=1, xSize = min (80, size_x * 4), ySize = min (24, size_y + 1);
int *ptr = vector, data;
byte *buf = SaveScreen (xPos, yPos, xSize + 2, ySize + 1);
// Рисуем окошко
ShowWin (xPos, yPos, xSize, ySize, 2, 1, LIGHTCYAN, BLUE, " Матрица ");
// Цикл ввода
for (int y = 0; y < size_y; y++)
{
for (int x = 0, pos = xPos + 1; x < size_x; x++, ptr++, pos += 4)
{
gotoxy (pos, y + yPos + 1);
scanf ("%3d", &data);
*ptr = data;
}
}
bioskey (0); // Подождем нажатия на любую клавищу
RestoreScreen (xPos, yPos, xSize + 2, ySize + 1, buf);
}
// Заполняет матрицу случайными числами из диапозона [-50;50]
void RandMatrix (int *vector, int size_y, int size_x)
{
for (int y = 0, *ptr = vector; y < size_y; y++)
{
for (int x = 0; x < size_x; x++, ptr++)
*ptr = (random (99) - 50);
}
}
// Показывает резутаты работы
void ViewResult (int *m_vector, int size_y, int size_x, long *abs_vect,
long pMin, long pMax, long pSum, long pMinus, int *m_vect,
int nMin, int nMax)
{
_setcursortype (_NOCURSOR); // Выключаем курсор
// Расчитываем параметры окошек
word xPos=1, yPos=1, xSize = min (50, size_x * 4), ySize = min (12, size_y + 1);
word xPos1=60, yPos1=1, xSize1 = 18, ySize1 = 7;
word xPos2=xPos + xSize + 2 + 2, yPos2=1, xSize2 = 10, ySize2 = ySize;
word xPos3=1, yPos3=ySize + 1 + 2, xSize3 = xSize, ySize3 = ySize;
// Настраиваем указатели на данные
int *ptr = m_vector, data, *ptr1 = m_vect;
// Запомним кусочки экрана куда будут выводится окошки
byte *buf = SaveScreen (xPos, yPos, xSize + 2, ySize + 1);
byte *buf1 = SaveScreen (xPos1, yPos1, xSize1 + 2, ySize1 + 1);
byte *buf2 = SaveScreen (xPos2, yPos2, xSize2 + 2, ySize2 + 1);
byte *buf3 = SaveScreen (xPos3, yPos3, xSize3 + 2, ySize3 + 1);
// Нарисуем окошки
ShowWin (xPos, yPos, xSize, ySize, 2, 1, LIGHTCYAN, BLUE, " Исх. матрица ");
ShowWin (xPos1, yPos1, xSize1, ySize1, 2, 1, WHITE, MAGENTA, " Статистика ");
ShowWin (xPos2, yPos2, xSize2, ySize2, 2, 1, WHITE, GREEN, "");
ShowWin (xPos3, yPos3, xSize3, ySize3, 2, 1, WHITE, BLUE, " Рез. матрица ");
// Вывод инфы на экран
gotoxy (xPos1 + 2, yPos1 + 2); printf (" Min = %ld", pMin);
gotoxy (xPos1 + 2, yPos1 + 3); printf (" Max = %ld", pMax);
gotoxy (xPos1 + 2, yPos1 + 4); printf (" \"-\" = %ld", pMinus);
gotoxy (xPos1 + 2, yPos1 + 5); printf ("Сумма = %ld", pSum);
// Цикл вывода данных из матрицы на экран
for (int y = 0; y < size_y; y++)
{
// Подсветка строки с минимальным и максимальным произведением
if (y == nMin || y == nMax)
{
textbackground (CYAN);
for (int a = 0; a < size_x * 4 - 1; a++)
{
gotoxy (xPos+1+a, y + yPos + 1); cprintf (" ");
gotoxy (xPos+1+a, y + yPos3 + 1); cprintf (" ");
}
}
// Вывод данных из матрицы на экран
for (int x = 0, pos = xPos + 1; x < size_x; x++, ptr++, pos += 4, ptr1++)
{
gotoxy (pos, y + yPos + 1); // Первая матрица
printf ("%-3d", *ptr);
gotoxy (pos, y + yPos3 + 1); // вторая матрица
printf ("%-3d", *ptr1);
}
gotoxy (xPos2 + 1, y + yPos2 + 1); // массив произведений
printf ("%ld", abs_vect[y]);
}
bioskey (0); // ждем нажатия на любую клавишу
// востанавливаем испорченные кусочки экрана
RestoreScreen (xPos, yPos, xSize + 2, ySize + 1, buf);
RestoreScreen (xPos1, yPos1, xSize1 + 2, ySize1 + 1, buf1);
RestoreScreen (xPos2, yPos2, xSize2 + 2, ySize2 + 1, buf2);
RestoreScreen (xPos3, yPos3, xSize3 + 2, ySize3 + 1, buf3);
_setcursortype (_NORMALCURSOR); // включаем курсор
}
// Выполняе решение
void CreateAbsVector (int *vector, int size_y, int size_x, long *resVector,
long *pMin, long *pMax, long *pSum, long *pMinus,
int *r_vect, int *n_Min, int *n_Max)
{
long summ = 0; // Сумма произведений, пока 0
// Цикл стоит массив из модулей произведений отрицательных
// элементов каждой строки, если таких элементов в строке нет,
// то результат = 0
// а также считает кол-во отрицательных элементов
// и определяет сумму произведений сформированного массива
for (int y = 0, i = 0, *ptr = vector, abs_count = 0; y < size_y; y++, i++)
{
resVector[i] = 0; // снача = 0
for (int x = 0; x < size_x; x++, ptr++)
{
if (*ptr < 0) // элемент отрицательный
{
if (resVector[i] == 0) // пока 0
resVector[i] = abs (*ptr); // тогда пишем первое число
else // уже не 0
resVector[i] *= abs (*ptr); // тогда умножим на элемент
abs_count++; // счетчик отрицательных, увеличим
}
}
summ += resVector[i]; // не забудем прибавить к общей сумме
}
// уже вычисленные значения вернем через указатель
*pSum = summ;
*pMinus = abs_count;
// Найдем мин и мах элементы и поменяем строки местами
long Min, Max;
int nMin, nMax; // номера строк с мин и мах элементами
// цикл для нахождения
for (i = 0; i < size_y; i++)
{
if (!i) // если это первый элемент
{ // то положим его равным мин и мах и запомним номер строки
Max = Min = resVector [i];
nMin = nMax = i;
}
else // элеменет не первый
{ // тогда ищем
if (Max < resVector [i]) // выбор мах из очередной пары
{
Max = resVector [i];
nMax = i;
}
if (Min > resVector [i]) // выбор мин из очередной пары
{
Min = resVector [i];
nMin = i;
}
}
}
// вернем результаты
*pMin = Min;
*pMax = Max;
*n_Min = nMin;
*n_Max = nMax;
// поменяем строки с мин и мах местами
int *ptr_cpy = r_vect;
ptr = vector;
// скопируем первую матрицу во вторую
memcpy (ptr_cpy, ptr, sizeof (int) * size_y * size_x);
// Если надо менять строки в исходной матрице, то
// закоментировать следующие 2 строки и "в исходной"
// разкоментировать 2 строки "в результирующей"
// указатели на строки с мин и мах элементами, вычислим адресе
int *ptr_min = r_vect + ITEM (nMin, 0, size_x); // в исходной
int *ptr_max = r_vect + ITEM (nMax, 0, size_x); // в исходной
// это было чтобы менять в исходной матрицы строки
// int *ptr_min = vector + ITEM (nMin, 0, size_x); // в результирующей
// int *ptr_max = vector + ITEM (nMax, 0, size_x); // в результирующей
int *tmp = new int [size_x]; // временный массив для хранения строки
// поменяем местами строки, через временный массив
memcpy (tmp, ptr_min, sizeof (int) * size_x);
memcpy (ptr_min, ptr_max, sizeof (int) * size_x);
memcpy (ptr_max, tmp, sizeof (int) * size_x);
// освободим временный массив
delete [] tmp;
}
// Главная функция - управляет работой всей программы
void AppRun (void)
{
DeskTop (); // нарисуем экран
TaskBar (" ~ESC~ Выход"); // строку статуса
byte bExit = 1;
byte buf_size;
byte *buf;
// переменные для записи результатов работы меню
word MainMenuResult = 0, FileMenuResult, HelpMenuResult;
// основной цикл работы
while (bExit)
{
// вызов главного меню
MainMenuResult = Menu (5,3,18,4,2,1,YELLOW,BLUE,CYAN,BLUE,
" Главное меню ", 3, MainMenuItems, MainMenuResult);
// Обработка результатов работы главного меню
switch (MainMenuResult)
{
case -1: bExit = 0; break; // выход из программы
case 0:
// запуск меню "Файл"
buf = SaveScreen (20, 4, 28 + 2, 8 + 1);
FileMenuResult = Menu (20, 4, 28, 8, 2, 1, YELLOW,MAGENTA,
CYAN,BLUE, " Меню файл ", 7, FileMenuItems,0);
// обработка результатов работы меню файл
switch (FileMenuResult)
{
case -1: break;
case 0: LoadData (&Matrix1[0][0], ARRAY_SIZE_Y, ARRAY_SIZE_X); break; // load data
case 1: SaveData (&Matrix1[0][0], ARRAY_SIZE_Y, ARRAY_SIZE_X); break; // save data
case 2: InputMatrix (&Matrix1[0][0], ARRAY_SIZE_Y, ARRAY_SIZE_X); break; // input data
case 3: ShowMatrix (&Matrix1[0][0], ARRAY_SIZE_Y, ARRAY_SIZE_X); break; // edit data
case 4: RandMatrix (&Matrix1[0][0], ARRAY_SIZE_Y, ARRAY_SIZE_X); break; // random data
case 5:
ViewResult (&Matrix1[0][0], ARRAY_SIZE_Y, ARRAY_SIZE_X, VectorAbs, gMin, gMax, gSum, gMinus, &Matrix2[0][0], MinLine, MaxLine);
break; // show result
case 6: bExit = 0; break; // exit
}
RestoreScreen (20, 4, 28 + 2, 8 + 1, buf);
break;
case 1:
// выполнение вычислейний
CreateAbsVector (&Matrix1[0][0], ARRAY_SIZE_Y, ARRAY_SIZE_X,
&VectorAbs[0], &gMin, &gMax, &gSum, &gMinus,
&Matrix2[0][0], &MinLine, &MaxLine);
_setcursortype (_NOCURSOR);
buf = SaveScreen (20, 5, 44 + 2, 6 + 1);
ShowWin (20, 5, 44, 6, 2, 1, WHITE, MAGENTA, " Результат ");
gotoxy (32,7); printf ("Вычисления выполнены.");
gotoxy (24,9); printf ("Нажмите любую клавишу для продолжение");
bioskey (0);
RestoreScreen (20, 5, 44 + 2, 6 + 1, buf);
_setcursortype (_NORMALCURSOR);
break;
case 2:
// вызов меню "Справка"
buf = SaveScreen (20, 6, 31 + 2, 3 + 1);
HelpMenuResult = Menu (20, 6, 31, 3, 2, 1, YELLOW,MAGENTA,
CYAN,BLUE, " Меню справка ", 2, HelpMenuItems,0);
// обработка результатов меню справка
switch (HelpMenuResult)
{
case 0: UserGuide (); break; // User guide
case 1: About (); break; // About ...
}
RestoreScreen (20, 6, 31 + 2, 3 + 1, buf);
break;
}
}
}
// Выводин информацию о разработчиках
void About (void)
{
_setcursortype (_NOCURSOR);
byte *buf = SaveScreen (18, 7, 44 + 2, 11 + 1);
ShowWin (18, 7, 44, 11, 2, 1, BLUE, CYAN, " Об авторах ... ");
gotoxy (20, 9); printf ("Програмный продукт: ********************");
gotoxy (20,11); printf (" Разработчик: ********************");
gotoxy (20,13); printf (" Дата выпуска: ********************");
gotoxy (20,17); printf (" Нажмите любую клавишу для выхода ");
bioskey (0);
RestoreScreen (18, 7, 44 + 2, 11 + 1, buf);
_setcursortype (_NORMALCURSOR);
}
// Выводит одну страницу руководства пользователя
void ShowUserGuide (const char *Text)
{
ShowWin (15, 7, 50, 11, 2, 1, WHITE, GREEN, " Руководство пользователя ");
window (16,8,64,17);
cprintf ("%s", Text);
textcolor (BLUE);
gotoxy (9,10); cprintf ("ESC - Выход. Up, Down - Листать.");
window (1,1,80,25);
}
// Выполняет работу диалога руководство пользователя
void UserGuide (void)
{
_setcursortype (_NOCURSOR);
int key;
byte bExit = 1;
byte *buf = SaveScreen (15, 7, 50 + 2, 11 + 1);
int GuideCount = 0;
while (bExit)
{
ShowUserGuide (UserGuideText [GuideCount]);
key = bioskey (0);
switch (key)
{
case ESC: bExit = 0; break;
case UP: GuideCount--;
if (GuideCount < 0)
GuideCount = 0;
break;
case DOWN: GuideCount++;
if (GuideCount >= UserGuideCount - 1)
GuideCount = UserGuideCount - 1;
break;
}
}
RestoreScreen (15, 7, 50 + 2, 11 + 1, buf);
_setcursortype (_NORMALCURSOR);
}
// Востанавливает часть экрана
void RestoreScreen (byte xPos, byte yPos, byte xSize, byte ySize, byte *buf)
{
puttext (xPos, yPos, xPos + xSize, yPos + ySize, buf);
delete [] buf;
}
// Сохраняет часть экрана
byte *SaveScreen (byte xPos, byte yPos, byte xSize, byte ySize)
{
word buf_size = (xSize + 1) * (ySize + 1) * 2;
byte *buf = new byte [buf_size];
if (!buf)
{
printf ("Нет свободной памяти для выполнения операции!\n");
return NULL;
}
gettext (xPos, yPos, xPos + xSize, yPos + ySize, buf);
return buf;
}
// Главная функциия - отсюда происходит старт программы
void main (void)
{
if (SplashScreen ()) // вывод заставки, если пользователь не нажал выход
AppRun (); // то запускаем работу программы
}
[/more]