Назад | Начало урока | Вперед
Содержание

Глава 4 стр 37

Наполняем приложение функциональностью

Теперь будем наполнять наше приложение функциональностью.

В функцию OnInitDialog() внесем следующий код:

strFileName = "Впишите здесь имя файла и нажмите 'Выполнить' ";
//обновить значения в диалоговом окне
UpdateData(FALSE);

Теперь после компиляции мы видим, что в окне EditBox появилась надпись:
Впишите имя файла здесь и нажмите 'Выполнить'

Здесь функция UpdateData(FALSE); - ключ к работе с переменными, ассоциированными с элементами управления.

Эта функция получает доступ к данным, хранящихся в переменных (которые мы только что инициализировали) и обновляет на экране вид элементов управления так, чтобы отобразить значения этих переменных.

Она так же принимает данные от элементов управления, введенные пользователем, и заносит эти данные в переменные. Этот процесс управляется булевым параметром, передаваемом в качестве аргумента в функцию UpdateData(). Если значение параметра равно FALSE , то значениями которые хранятся в переменных, инициализируются элементы управления. Если значение параметра TRUE или он опущен, то в переменные записываются значения, которые в данный момент отображаются на экране в соответствующих им элементах управления.

------------------------
Далее, реакция на нажатие кнопки "Выход":

void CText_matrixDlg::OnBnClickedCancel() {

OnOK();
}

Далее в функцию OnBnClickedOk() нажатия кнопки "Выполнить" внесем код
открытия и закрытия потоков для считывания и записи файлов:

void CText_matrixDlg::OnBnClickedOk() {

ifstream from1("bukva.bmp");//открываем файл для считывания
if(!from1) {
MessageBox("Входной файл не найден");
from1.close(); // always pays to be tidy
}
ofstream to1("text2" ); // open for writing
if(!to1) {
MessageBox("Выходной файл не найден");
to1.close(); // always pays to be tidy
}
//////////////////

////////////////////
from1.close(); // always pays to be tidy
to1.close(); // always pays to be tidy

}

Откомпилируем. Получаем сообщение об ошибке. Это потому, что надо подключить к файлу
библиотеку fstream, в которой описаны потоки. Ну и включить инструкцию об использовании
пространства имен using namespace std.

#include <fstream>
using namespace std;

Далее добавим в функцию код, который считает из входного файла данные побайтно
и поместит их в вектор (массив).

//////////////////
vector charVec;

//считаем из файла в вектор
char ch;
while (from1.get(ch)) {

charVec.push_back(ch);
}

Теперь данные считаны и хранятся в векторе.
Обратите внимание на лаконичность кода. Таков С++!

Чтобы этот код не вызывал ошибок при компиляции, надо добавить библиотеку
для работы с векторами:

#include <vector>

//////////////////////////

Далее считаем данные из префикса файла в локальные переменные.

////////////////////////////////////////
////////////////////////////////////////
////////////////////////////////////////
int temp = 0;
int temp_l = 0;
int temp_h = 0;
int size_file = 0; //размер исходного bmp-файла (2-й, 3-й байты)
int chislo_str = 0; //размер картинки в байтах (34-й, 35-й байты)
int size_card = 0; //количество строк в картинке (22-й, 23-й байты)
int dlina_str = 0; //длина строки в выходном файле

char first_ch = ' ';
char second_ch = ' ';

//--------------------------------
//считаем данные из префикса файла

temp_l = (int)charVec[2];
if(temp_l<0)
temp_l = 256+temp_l;
temp_h = (int)charVec[3];
if(temp_h<0)
temp_h = 256+temp_h;
temp_h = 256*temp_h;
size_file = temp_h+temp_l;

temp_l = (int)charVec[22];
if(temp_l<0)
temp_l = 256+temp_l;
temp_h = (int)charVec[23];
if(temp_h<0)
temp_h = 256+temp_h;
temp_h = 256*temp_h;
chislo_str = temp_h+temp_l;

temp_l = (int)charVec[34];
if(temp_l<0)
temp_l = 256+temp_l;
temp_h = (int)charVec[35];
if(temp_h<0)
temp_h = 256+temp_h;
temp_h = 256*temp_h;
size_card = temp_h+temp_l;

dlina_str = size_card/chislo_str;

//-------------------------------------------

Откомпилируем. Все в порядке!

Теперь выведем имя файла в переменную strFileName2 типа CString, ассоциированную
с компонентом IDC_STATIC_FILENAME типа StaticText.

Теперь выведем размер файла в переменную strSizeFile типа CString, ассоциированную
с компонентом IDC_STATIC_SIZEFILE типа StaticText.

UpdateData(TRUE);
strFileName2.Format(strFileName);
strSizeFile.Format("%d",size_file);

Теперь после нажатия на кнопку "Выполнить" на сером фоне формы, через элементы StaticText будет выведено то, что напечатает пользователь в EditBox и выведен размер файла в байтах.

Теперь выведем подобным же образом другие переменные.

strSizeCard.Format("%d",size_card);
strChisloStr.Format("%d",chislo_str);
strDlinaStr.Format("%d",dlina_str);

Все работает!

Теперь надо бы, чтобы пользователь мог вводить имя файла, который он хочет
обработать.
Следующий код делает это:

UpdateData(TRUE);
ifstream from1(strFileName);//открываем файл для считывания

Здесь возникает одна проблема:
В случае, если имя файла набрано верно и такой файл есть в директории, то программа выполняется правильно. Если имя набрано неверно или если такого файла нет в директории
то выходит сообщение "Входной файл не найден", а далее программа завершается аварийно.
Надо чтобы программа завершалась корректно предварительно попросить ввести правильное имя.

Для этого в программу надо ввести окно Yes/No.
Продолжить ввод? Завершить программу

/////////////////////////////////////

int iResults;
iResults = MessageBox("Press the Yes,No,or Cancel button ",
"Yes,No Cancel Dialog",MB_YESNOCANCEL | MB_ICONINFORMATION);

int iResults;
iResults = MessageBox("Press the Abort,Retry,or Ignore button ",
"Abort,Retry,Ignore Dialog",MB_ABORTRETRYIGNORE | MB_ICONINFORMATION);

/////////////////////////////

void CDialogsDlg::OnBnClickedBabortretryignore() {

int iResults;
iResults = MessageBox("Press the Abort,Retry,or Ignore button ",
"Abort,Retry,Ignore Dialog",MB_ABORTRETRYIGNORE | MB_ICONINFORMATION);

switch(iResults) {

case IDABORT:
m_strResults = "ABORT,ABORT,ABORT";
break;

case IDRETRY:
m_strResults = "RETRY,RETRY,RETRY";
break;

case IDIGNORE:
m_strResults = "IGNORE,IGNORE,IGNORE";
break;

}
UpdateData(FALSE);
// TODO: Add your control notification handler code here
}


-------------------------
void CDialogsDlg::OnBnClickedByesnocancel() {

int iResults;
iResults = MessageBox("Press the Yes,No,or Cancel button ",
"Yes,No Cancel Dialog",MB_YESNOCANCEL | MB_ICONINFORMATION);

switch(iResults) {

case IDYES:
m_strResults = "Yes,Yes,Yes";
break;

case IDNO:
m_strResults = "No,No,No,no";
break;

case IDCANCEL:
m_strResults = "Sorry,canceled";

break;

}


UpdateData(FALSE);

}


Назад | Начало урока | Вверх | Вперед
Содержание

Hosted by uCoz