Форум программистов, компьютерный форум, киберфорум
Visual C++
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.57/7: Рейтинг темы: голосов - 7, средняя оценка - 4.57
0 / 0 / 0
Регистрация: 25.07.2013
Сообщений: 5

Графика при открытии модального окна

25.07.2013, 16:53. Показов 1448. Ответов 14
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день! Недавно начал изучать MFC. Столкнулся с такой проблемой: мне необходимо, чтобы при открытии модального окна сразу рисовался мой график.
Вот мои действия:
1. Создал основное окно программы (Dialog);
2. Cоздал меню;
3. Создал еще одно окно (Dialog2);
4. Написал обработчик, который по меню открывает Dialog2;

Дальше хочу, чтобы Dialog2 сразу открывался с прорисованным графиком. К сожалению не получилось.
Пытался писать код в OnInitDialog и OnShowWindow. Причем, если я добавляю в Dialog2 элемент Edit Control, присваиваю ему переменную, потом инициализирую переменную хоть в OnInitDialog и OnShowWindow - у меня Dialog2 открывается с значением инициализированной переменной в Edit Control. Также в Dialog2 сделал рисование графика при нажати в нем кнопки - график рисует. Но мне это лишнее действие не нужно. Подскажите, плиз, что не сделал. Спасибо.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
25.07.2013, 16:53
Ответы с готовыми решениями:

Ошибка при открытии диалогового окна
Диалоговое окно первый раз открывается нормально, а при втором открытии - возникает ошибка. В чем может быть проблема?

Вызов модального диалогового окна из Меню (AboutBox при выборе пункта "О программе")
Есть меню и пункт в нём - "О программе". Есть ресурс диалогового окна Как реализовать, чтобы при выборе этого пункта появлялось требуемое...

Ошибка при открытии модального окна Windows XP
Доброго времени суток. В первые столкнулся с тем, что при открытии модального окна на компьютерах с Win XP в логи вываливается...

14
Эксперт С++
2924 / 1274 / 114
Регистрация: 27.05.2008
Сообщений: 3,465
25.07.2013, 17:50
Подобные инициализирующие действия обычно делаются в OnInitDialog(). А вот данные, по которым ты собрался рисовать график, - в этот момент уже готовы и валидны?
0
0 / 0 / 0
Регистрация: 25.07.2013
Сообщений: 5
25.07.2013, 21:22  [ТС]
В OnInitDialog() вызываю функцию, которая расчитывает значения. а потом по этим точкам LineTo... Прошу прощения если глупый вопрос - а что значит "валидны"?
0
Эксперт С++
2924 / 1274 / 114
Регистрация: 27.05.2008
Сообщений: 3,465
26.07.2013, 15:56
Валидные - прямая калька с англ. valid - действительные, годные.

Приведи минимальный пример кода, как и что делаешь. Вероятно, где-то ошибка. Но мой телепатический угадыватель сломался :-(
0
0 / 0 / 0
Регистрация: 25.07.2013
Сообщений: 5
26.07.2013, 16:10  [ТС]
1. По нажатию кнопки открываю модальное окно:

C++
1
2
3
4
5
6
void MFCDlg::OnGr()
{
    // TODO: Add your command handler code here
    CGraph dlg1;
dlg1.DoModal();
}
2. В CGraph.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
BOOL CGraph::OnInitDialog()
{
    CDialog::OnInitDialog();
    // TODO: Add your message handler code here
    
    Invalidate ();
 
    UpdateWindow();
        CPaintDC pDC(this); 
        int m=20,g ;
        double x1=-10, x, dx=0.01, x0, y0, y;
        double x2=10;
        
        osi(50, 50, &pDC);
        
        LOGFONT logFont;
        logFont.lfHeight=24;
        logFont.lfWidth=0;
        logFont.lfEscapement=0;
        logFont.lfOrientation=0;
        logFont.lfWeight=FW_NORMAL;
        logFont.lfItalic=0;
        logFont.lfUnderline=0;
        logFont.lfStrikeOut=0;
        logFont.lfCharSet=ANSI_CHARSET;
        logFont.lfOutPrecision=OUT_DEFAULT_PRECIS;
        logFont.lfClipPrecision=CLIP_DEFAULT_PRECIS;
        logFont.lfQuality=PROOF_QUALITY;
        logFont.lfPitchAndFamily=VARIABLE_PITCH | FF_ROMAN;
        //wstrcpy(logFont.lfFaceName,"MS Sans Serif");
        CFont *font=new CFont();
        font->CreateFontIndirect(&logFont);
        CFont* oldFont=pDC.SelectObject(font);
        CBrush Brush;
        CPen Pen;
        CBrush *PtrOldBrush;
        CPen *PtrOldPen;
        Pen.CreatePen(PS_SOLID, 1, RGB(255,25,125));
        Brush.CreateSolidBrush(RGB(255,255,0));
        PtrOldPen=pDC.SelectObject(&Pen);
        PtrOldBrush=pDC.SelectObject(&Brush);
 
        for(x=x1; x<x2; x+=dx)
        {   x0=x-dx;
            f(x, y);
            f(x0, y0);
            //int m=20; //////
            pDC.MoveTo(int(m*x+319), int(-(239-y*m)));
            pDC.LineTo(int(m*x0+319), int(-(239-y0*m)));
            pDC.SelectObject(PtrOldPen);
            pDC.SelectObject(PtrOldBrush);
            pDC.SelectObject(oldFont);
            
        }
        return TRUE;
}
Добавлено через 4 минуты
Функции osi, f описаны в этом же файле. Этот же код рисует график, если я в CGraph.cpp пишу в обработчике на нажатие кнопки:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
void CGraph::OnBnClickedButton1()
{
    // TODO: Add your control notification handler code here
        Invalidate ();
 
    UpdateWindow();
        CPaintDC pDC(this); 
        int m=20,g ;
        double x1=-10, x, dx=0.01, x0, y0, y;
        double x2=10;
        //maxim(x1, x2, dx, m, g);
        osi(50, 50, &pDC);
        
        LOGFONT logFont;
        logFont.lfHeight=24;
        logFont.lfWidth=0;
        logFont.lfEscapement=0;
        logFont.lfOrientation=0;
        logFont.lfWeight=FW_NORMAL;
        logFont.lfItalic=0;
        logFont.lfUnderline=0;
        logFont.lfStrikeOut=0;
        logFont.lfCharSet=ANSI_CHARSET;
        logFont.lfOutPrecision=OUT_DEFAULT_PRECIS;
        logFont.lfClipPrecision=CLIP_DEFAULT_PRECIS;
        logFont.lfQuality=PROOF_QUALITY;
        logFont.lfPitchAndFamily=VARIABLE_PITCH | FF_ROMAN;
        //wstrcpy(logFont.lfFaceName,"MS Sans Serif");
        CFont *font=new CFont();
        font->CreateFontIndirect(&logFont);
        CFont* oldFont=pDC.SelectObject(font);
        CBrush Brush;
        CPen Pen;
        CBrush *PtrOldBrush;
        CPen *PtrOldPen;
        Pen.CreatePen(PS_SOLID, 1, RGB(255,25,125));
        Brush.CreateSolidBrush(RGB(255,255,0));
        PtrOldPen=pDC.SelectObject(&Pen);
        PtrOldBrush=pDC.SelectObject(&Brush);
 
        for(x=x1; x<x2; x+=dx)
        {   x0=x-dx;
            f(x, y);
            f(x0, y0);
            //int m=20; //////
            pDC.MoveTo(int(m*x+319), int(-(239-y*m)));
            pDC.LineTo(int(m*x0+319), int(-(239-y0*m)));
            pDC.SelectObject(PtrOldPen);
            pDC.SelectObject(PtrOldBrush);
            pDC.SelectObject(oldFont);
            
        }
}
0
Эксперт С++
2924 / 1274 / 114
Регистрация: 27.05.2008
Сообщений: 3,465
26.07.2013, 16:55
Ага. Ну, как я и подозревал, ничего таинственного нет. Лечится это так:

1. Создаешь свой класс "элемента отрисовки графика", наследуя его от CStatic, например. Название не принципиально, например, MyGraphClass. Это будет класс визуального элемента, который и рисует график.
2. В методе OnPaint() этого класса реализуешь всю отрисовку - т.е. переносишь в него код от CPaintDC pDC(this); до pDC.SelectObject(oldFont);
3. Код расчета отрисовочных данных (цикл) лучше всего вынести из этого метода в отдельный метод. Т.е. должно быть так:
- код расчета (он может быть и достаточно сложным) просто рассчитывает данные для отрисовки и где-то сохраняет,
- а код рисования их просто рисует, не интересуясь их происхождением и источником.
Это будет во-первых, разделение обязанностей, и во-вторых, снизит нагрузку при перерисовках (не надо каждый раз пересчитывать точки заново. Точки пересчитываются только при каком-то изменении в программе.)
3. На диалог кладешь статик (CStatic) и задаешь ему координаты и прочее....
4. Создаешь в диалоге переменную-контрол и привязываешь ее к этому статику. Воспользуйся Wizard'ом.
5. Руками в хидере или с помощью Визарда изменяешь класс этой переменной с CStatic на твой класс (п.1) - на MyGraphClass.
6. В OnInitDialog() вызовы Invalidate(); и UpdateWindow(); в начале не нужны. Ну и код рисования из OnInitDialog убрать весь.
7. Профит! Все должно будет заработать. OnBnClickedButton1() будет больше не нужен.

Добавлено через 10 минут
Да, метод OnInitDialog() - хороший кандидат на то, "куда переместить цикл расчета точек графика?"
0
0 / 0 / 0
Регистрация: 25.07.2013
Сообщений: 5
26.07.2013, 16:57  [ТС]
Спасибо. Вроде бы все понятно, кроме одного момента:
"3. На диалог кладешь статик (CStatic) и задаешь ему координаты и прочее..."
Поясните, плиз
0
Эксперт С++
2924 / 1274 / 114
Регистрация: 27.05.2008
Сообщений: 3,465
26.07.2013, 17:01
Выбираешь в Панели элементов Static, и в шаблоне диалога вставляешь в нужном месте статик. Задаешь ему свойства (по правой кнопке мыши). Черт, легче показать, чем описать! :-) В любой книжке по MFC этот "сложный" процесс описан.
0
0 / 0 / 0
Регистрация: 25.07.2013
Сообщений: 5
29.07.2013, 12:54  [ТС]
Спасибо, почитаю. Все, что описано - понятно, что надо сделать. Просто никак не найду на панели элемент "Static" - самое близкое "Static Text", но это как я понимаю не то.
0
1 / 1 / 0
Регистрация: 23.07.2013
Сообщений: 72
30.07.2013, 14:18
CheshireCat, Подскажите, пожалуйста, при построении графика функции зависящей от одной переменной, например, f(x)=sin(x) мы переменную х можем задавать в цикле, а у вычисляется, но y получается же дробным, координаты должны быть целочисленными, как это сделать?
0
Эксперт С++
2924 / 1274 / 114
Регистрация: 27.05.2008
Сообщений: 3,465
30.07.2013, 15:02
Округлять, вестимо. Как именно - зависит от вычисляемой функции.
1
1 / 1 / 0
Регистрация: 23.07.2013
Сообщений: 72
30.07.2013, 15:48
CheshireCat, если функция arcsin(x)-sin(2x)? какой функцией округлять в VC++? Извиняюсь, как понять вестимо?
0
Эксперт С++
2924 / 1274 / 114
Регистрация: 27.05.2008
Сообщений: 3,465
30.07.2013, 16:09
Вот если функция именно такая: arcsin(x) - sin(2x), то тебе нужно:
1. прикинуть область отображаемых на графике значений функции (arcsin имеет область значений от -pi/2 до pi/2, sin имеет область значений от -1 до +1),
2. прикинуть, в какой области окна ты будешь отображать график (грубо, сколько пикселей по вертикали и по горизонтали будет в рисунке),
3. исходя из пп.1 и 2 рассчитать масштабные множители для осей X и Y,
4. ну и рассчитать значения для отрисовки графика "в пикселях" - условно, составить таблицу [Xпикс -> Yпикс].
В большинстве случаев, округление для значений "в пикселях" можно делать тупым отбрасыванием дробной части - т.е. если получено значение 480.76 пикселей, то реально можно рисовать 480 - на глаз разница будет совершенно незаметна.
1
1 / 1 / 0
Регистрация: 23.07.2013
Сообщений: 72
30.07.2013, 19:23
CheshireCat, составить таблицу [Xпикс -> Yпикс] - это мне массив записать и из него уже строить?
Тупо одбросить дробную часть - это мне можно через (int) value сделать?
0
Эксперт С++
2924 / 1274 / 114
Регистрация: 27.05.2008
Сообщений: 3,465
30.07.2013, 21:46
Да.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
30.07.2013, 21:46
Помогаю со студенческими работами здесь

Как взять id пользователя из бд при открытии модального окна (bootstrap4)
Есть код &lt;?php $query = mysqli_query($link,&quot;SELECT * FROM students_marks_dis1_december&quot;); ...

Чтобы при открытии нового модального окна предыдущее закрывалось через onclick
Здравствуйте. У меня есть label, при нажатии на который открывается модальное окно. В этом модальном окне есть ещё один label, при...

При открытии модального окна, "дергается экран"
&lt;a href=&quot;#book-data&quot; id=&quot;data&quot; class=&quot;header-calendar-button&quot;&gt; &lt;span class=&quot;calendar-button__text&quot;&gt;book online &lt;br&gt;training&lt;/span&gt;&lt;/a&gt; ...

Как написать скрипт для скрытия модального окна при клике вне окна(на боди) ?
У меня модальное окно вообще даже не открывается при нажатии на кнопку,потому что у меня так прописано в скрипте ...

Запуск модального окна при загрузке
При клике по ссылке открывается модальное окно, как бы сделать так, чтобы оно открывалось при запуске страницы непосредственно? скорее...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Работа со звуком через SDL3_mixer
8Observer8 08.02.2026
Содержание блога Пошагово создадим проект для загрузки звукового файла и воспроизведения звука с помощью библиотеки SDL3_mixer. Звук будет воспроизводиться по клику мышки по холсту на Desktop и по. . .
SDL3 для Web (WebAssembly): Основы отладки веб-приложений на SDL3 по USB и Wi-Fi, запущенных в браузере мобильных устройств
8Observer8 07.02.2026
Содержание блога Браузер Chrome имеет средства для отладки мобильных веб-приложений по USB. В этой пошаговой инструкции ограничимся работой с консолью. Вывод в консоль - это часть процесса. . .
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru