IMHO.WS

IMHO.WS (https://www.imho.ws/index.php)
-   Программирование (https://www.imho.ws/forumdisplay.php?f=40)
-   -   Тестирование, на Visual C++ (https://www.imho.ws/showthread.php?t=74926)

DeMx 03.12.2004 08:52

Тестирование, на Visual C++
 
Нужно создаться тест. Вопрос и 4 или более вариантов ответов. Никаких заморочек не надо.
Не хочу плодить много форм (надо 10 вопросов), поэтому решил после каждого вопроса менять подписи у Radio Box'а и сам вопрос в Edit Box'е, т.е. всё будет на одной форме, но её содержание будет меняться по ходу выполнения программы. Однако тут появилась трабла - после ответа на первый вопрос, события Radio Box'ов перестаются работать. Может можно как-то обновить окно или ещё что?
Вот код:
Код:

#include "stdafx.h"
#include "TestDualityProblem.h"
#include "TestDualityProblem_2.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CTestDualityProblem_2 dialog


CTestDualityProblem_2::CTestDualityProblem_2(CWnd* pParent /*=NULL*/)
        : CDialog(CTestDualityProblem_2::IDD, pParent)
{
        //{{AFX_DATA_INIT(CTestDualityProblem_2)
        m_question = _T("");
        //}}AFX_DATA_INIT
}


void CTestDualityProblem_2::DoDataExchange(CDataExchange* pDX)
{
        CDialog::DoDataExchange(pDX);
        //{{AFX_DATA_MAP(CTestDualityProblem_2)
        DDX_Text(pDX, IDC_EDIT1, m_question);
        //}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CTestDualityProblem_2, CDialog)
        //{{AFX_MSG_MAP(CTestDualityProblem_2)
        ON_BN_CLICKED(IDC_BUTTON3, OnButtonNext)
        ON_BN_CLICKED(IDC_RADIO1, OnRadio1)
        ON_BN_CLICKED(IDC_BUTTON4, OnButtonExit)
        ON_BN_CLICKED(IDC_RADIO2, OnRadio2)
        ON_BN_CLICKED(IDC_RADIO3, OnRadio3)
        ON_BN_CLICKED(IDC_RADIO4, OnRadio4)
        //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CTestDualityProblem_2 message handlers

BOOL CTestDualityProblem_2::OnInitDialog()
{
        CDialog::OnInitDialog();

        m_question = "Лучший игрок And1?";
        test = 1;
        q = 0;
        UpdateData(false);
       
        return TRUE;  // return TRUE unless you set the focus to a control
                      // EXCEPTION: OCX Property Pages should return FALSE
}

void CTestDualityProblem_2::OnButtonNext()
{
        UpdateData(true);
        CStdioFile File;
        File.Open("stat.txt", CFile::modeCreate|CFile::modeWrite|CFile::modeNoTruncate);
        File.SeekToEnd();
        if (test == 1) {
                File.WriteString("Вопрос 1: ");
                if (q == 2) {
                        File.WriteString("правильно.");
                }
                else
                        File.WriteString("не правильно.");
                test++;
        }
        if (test == 2) {
                File.WriteString("Вопрос 2: ");
                if (q == 1) {
                        File.WriteString("правильно.");
                }
                else
                        File.WriteString("не правильно.");
                m_question = "Лучший игрок NBA?";
                SetWindowText("Программа тестирования. Вопрос 2 из 10");
                GetDlgItem(IDC_RADIO1)->SetWindowText("Kobe Bryant");
                GetDlgItem(IDC_RADIO2)->SetWindowText("Tracy McGrady");
                GetDlgItem(IDC_RADIO3)->SetWindowText("Shaquille O'Neal");
                GetDlgItem(IDC_RADIO4)->SetWindowText("Kevin Garnett");
                test++;
                UpdateData(false);
        }
        if (test == 3) {
                File.WriteString("Вопрос 3: ");
                if (q == 1) {
                        File.WriteString("правильно.");
                }
                else
                        File.WriteString("не правильно.");
                m_question = "Лучший данкер Slam Nation?";
                SetWindowText("Программа тестирования. Вопрос 3 из 10");
                GetDlgItem(IDC_RADIO1)->SetWindowText("Кадур Зиани");
                GetDlgItem(IDC_RADIO2)->SetWindowText("Абдул Бамба");
                GetDlgItem(IDC_RADIO3)->SetWindowText("Саламон Сэми");
                GetDlgItem(IDC_RADIO4)->SetWindowText("Стиви Лоубел");
                test++;
                UpdateData(false);
        }
        File.Close();
}

void CTestDualityProblem_2::OnButtonExit()
{
        int status = MessageBox( "Вы хотите выйти?", "ВЫХОД", MB_OKCANCEL | MB_ICONQUESTION );
        if (status == IDOK) exit(0);       
}

void CTestDualityProblem_2::OnRadio1()
{
        q = 1;
}

void CTestDualityProblem_2::OnRadio2()
{
        q = 2;       
}

void CTestDualityProblem_2::OnRadio3()
{
        q = 3;       
}

void CTestDualityProblem_2::OnRadio4()
{
        q = 4;       
}

Что и где надо изменить?

b@dger 05.12.2004 19:04

Цитата:

DeMx:
события Radio Box'ов перестаются работать
А конкретнее?
И вообще у тебя ошибка в логике в функции void CTestDualityProblem_2::OnButtonNext(). В каждом условии стоит в конце стоит temp++ и получается так, что за один вызов этой функции все условия выполняются по порядку.
Вот так будет лучше:
Код:

void CTestDualityProblem_2::OnButtonNext()
{
        UpdateData(true);
        CStdioFile File;
        File.Open("stat.txt", CFile::modeCreate|CFile::modeWrite|CFile::modeNoTr  uncate);
        File.SeekToEnd();

        switch(test)
        {
        case 1:
                File.WriteString("Вопрос 1: ");
                if (q == 2) {
                        File.WriteString("правильно.");
                }
                else
                        File.WriteString("не правильно.");
                // ВОПРОС 2
                m_question = "Лучший игрок NBA?";
                SetWindowText("Программа тестирования. Вопрос 2 из 10");
                GetDlgItem(IDC_RADIO1)->SetWindowText("Kobe Bryant");
                GetDlgItem(IDC_RADIO2)->SetWindowText("Tracy McGrady");
                GetDlgItem(IDC_RADIO3)->SetWindowText("Shaquille O'Neal");
                GetDlgItem(IDC_RADIO4)->SetWindowText("Kevin Garnett");
                break;
        case 2:
                File.WriteString("Вопрос 2: ");
                if (q == 1) {
                        File.WriteString("правильно.");
                }
                else
                        File.WriteString("не правильно.");

                // ВОПРОС 3
                m_question = "Лучший данкер Slam Nation?";                                       
                SetWindowText("Программа тестирования. Вопрос 3 из 10");
                GetDlgItem(IDC_RADIO1)->SetWindowText("Кадур Зиани");
                GetDlgItem(IDC_RADIO2)->SetWindowText("Абдул Бамба");       
                GetDlgItem(IDC_RADIO3)->SetWindowText("Саламон Сэми");
                GetDlgItem(IDC_RADIO4)->SetWindowText("Стиви Лоубел");
                break;
        case 3:
                File.WriteString("Вопрос 3: ");
                if (q == 1) {
                        File.WriteString("правильно.");
                }
                else
                        File.WriteString("не правильно.");

                // ВОПРОС 4
                //  ...
                //
                break;
                // И далее в том же духе...
        }
        test++;
        UpdateData(false);
}


DeMx 05.12.2004 20:26

Вложений: 1
Да, ошибку в логике я потом сам нашёл, после публикации этой темы. :p
Однако дело не в этом. Попытаюсь объяснить, что происходит при выполнении программы:
Окно с заголовком "Вопрос 1 из 10". Выбираю один из Radio Box'ов, жму кнопку "Далее". Ничего не меняется. :confused: Жму ещё раз "Далее" - содержание окна меняется (меняются подписи у Radio Box'ов и Edit Box'а), заголовок теперь "Вопрос 2 из 10". Далее снова жму кнопку - окно меняется на третий вопрос...
Т.е. получается, что после первого нажатия кнопки, содержание окна почему то не изменяется, но результаты в файл записываются правильно.
Полагаю, что трабла пустиковая и абсолютно бестолковая... :)

Попутный вопрос: как убрать пометку у Radio Box'а? А то при переходе к следующему вопросу, в окне остаётся включённым ответ на предыдущий. Это не правильно. :)

Если мой проблема не понятно, то смотри вложение, там весь исходный код.

b@dger 05.12.2004 22:10

Вложений: 1
Ты опять же запутался в построенной тобой логике и невнимательно посмотрел мой код :p . Смотри: Когда ты нажимаешь кнопку Next, то у тебя проверяет значение test, далее обрабатывает это значение, а именно, проверяет q и записывает результат в файл, ну а затем нужно обновить данные в полях. А у тебя получается, к примеру, если test == 1 то при нажатии кнопки Next он проверяет q и записывает в файл, а затем test++. Затем, при следующем нажатии Next у тебя проверяет test, который равен 2, обрабатывает, проверяет q, записывает в файл результат, а затем только выводит 2 вопрос! Посмотри код в моем предыдущем топике повнимательнее.

Я бы на твоем месте сделал по другому: обновление полей текста вопроса и ответов зарядил в OnPaint, в зависимости от значения test. Смотри вложение. Снятие пометок чекбоксов тамже.

DeMx 06.12.2004 00:47

Млин, так и думал, что всё просто. :rolleyes:
Огромное спасибо! :молись:

Теперь я задался другим вопросом.
После ответов на все вопросы, в конце хочу, чтобы показывался итоговый результат. В принципе, это не проблема, но...
При ответе на каждый из вопросов, я записываю номер ответа, сам ответ и его "правильность" в файл, плюс ещё в начале имя отвечающего, т.е. файл в итоге будет выглядеть примерно так:
--------------------------------------------
SuperMan
вопрос 1: "Helicopter" - правильно
вопрос 2: "Tracy McGrady" - не правильно
...
итог: тест пройден
--------------------------------------------
С записью всего этого в файл тоже проблем нет, разберусь. :cool: Однако как потом считать всё это и отобрать только то, что относится к текущему ответчику (в файле будет содержатся инфа не только об одном ответчике)?
Ввод имени отвечающего у меня производится в другой форме (в предыдущей).
Получается нужно в начале считать из файл последнюю строку (имя) в какую-нибудь переменную, перед тем, как начать отвечать на вопросы, затем считать весь файл, найти ранее считанное имя и вывести на экран всё, что идёт после этого имени (включая само имя). :help: :confused: :eek: :idontnow: :)
Как вообще считать строку? :rolleyes: Может можно как-то проще всё сделать?

Уж извиняйте меня, но новичок я в Visual Cpp...

Вспомнил ещё вопрос:
Можно ли как-то вытащить подпись у помеченного Radio Box'а (выбранного варианта)?
Понимаю, что можно так (для первого вопроса):
Код:

char answer[20];
switch(q) {
case 1:
        strcpy(answer, "Skip");
        break;
case 2:
        strcpy(answer, "Helicopter");
        break;
case 3:
        strcpy(answer, "Hot Sauce");
        break;
case 4:
        strcpy(answer, "AO");
        break;
}

Затем в дальнейшем можно использовать переменную answer для записи в файл. Но не ужели нельзя проще? :confused:


Часовой пояс GMT +4, время: 10:41.

Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.