Visual студия, проблема с листбоксом

  • Автор темы Jarik
  • Дата начала
Статус
Закрыто для дальнейших ответов.
J

Jarik

#1
Всем добрый день, надеюсь, что запостил в нужный раздел.
Ситуация: программирую в Visual студии, хочу сделать listbow в диалоговом окне (класс Dial).

Диалог вызывается по нажатию кнопким (функция Button). Переменная, связанная с листбоксом -

m_list.
В классе Dial в методе DoDataExchange прописываю возможные значения листбокса:
m_list.AddString ("Value1");
m_list.AddString ("Value2");
...
В ф-ии Button прописываю обработку:

Dial dlg;
int result = dlg.DoModal ();
if (result == IDOK)
{
// вот тут проблема!
// надо переменной присвоить номер выбранной строки в листбоксе
// Вроде это должно делаться так:

variable = dlg.m_list.GetCurSel ();
Invalidate ();
}

Но после запуска, когда вызывается диалог и нажимается OK, появляется ошибка:
Debug Assertion Failed! ...

Что не так?
Заранее спасибо.
 
04.09.2006
2 566
3
#2
Запускай под отладкой и смотри какой код вызывает ошибку.
Вообще говоря, добавлять строки в DoDataExchange - это кощунство. Первый вызов DoDataExchange происходит из CDialog::OnInitDialog, т.е. скорее всего листбокс не создан, а ты пытаешся уже пихать в него данные, что и приводит к ошибке.
 
J

Jarik

#3
Гхм, есть проблема в том, что я не могу найти этот самый метод.
Надеюсь, я все правильно понимаю:
Есть класс Dial. У него есть методы, которые можно посмотреть или добавить в классвизарде. Их же можно посмотреть и редактировать в "Dial.cpp". Фича в том, что нету у класса Dial метода OnInitDialog. Может, я не там смотрю?
 

SunSanych

Well-known member
28.06.2006
71
0
#4
Прежде небольшое отступление: Если посмотреть в исходники MFC, то можно увидеть, что все функции классов работающие с окнами являются обертками для механизма сообщений. Эти сообщения посылаются окну с handle хранящимся в CWnd::m_hWnd. Ответ на эти сообщения и возвращается функциями. Перед отправкой сообщения MFC проверяет существует ли окно с таким handle. Если нет, в debug-сборке выводится предупреждение.
Теперь сама суть: в начале функции DoModal () все окна (диалоговое и его дети(child) ) создаются, а перед выходом из DoModal () все окна разрушаются и посылать сообщения уже некому. Поэтому в debug-версии появляется сообщение об ошибке, а в release-версии будет молча возвращено неверное значение.
Решение может быть таким:
1. в класс Dial добавить переменную-член int m_ListSelect.
2. в классе Dial переопределить виртуальный метод-член OnOK() класса CDialog
Код:
virtual void Dial::OnOK()
{
m_ListSelect = m_list.GetCurSel();
CDialog::OnOK();
}
3. в класс Dial добавить метод int Dial::GetListSelect() { return m_ListSelect; }

Или еще проще: связать переменную int m_ListSelect c id listbox-а (в разных студиях это делается немного по-разному).
В коде это равносильно ручками в DoDataExchange добавить строку:
Код:
DDX_LBIndex(pDX, IDC_LIST1, m_ListSelect);
Использовать так:
Код:
	Dial dlg;
int result = dlg.DoModal ();
if (result == IDOK)
variable = dlg.GetListSelect();
 
J

Jarik

#6
Всем спасибо, но у меня ничего не получается. Давайте разберемся.
Итак, надо добавить через wizard ф-ию OnInitDialog:
Захожу, выбираю Class names: Dial, Object ID's: Dial. Теперь в спмиске Messages надо выбрать OnInitDialog. Но его там нет.
Попробовал следующее:
Прописал в Dial.h в classе Dial ф-ию
Код:
virtual BOOL OnInitDialog ();
и попробовал потом ее описать в Dial.cpp:
Код:
BOOL Dial::OnInitDialog ()
{
m_list.AddString ("str1");
...
return true;
}
В общем, это опять не работает.
В чем дело?
 
G

gamecreator

#7
в карте сообщений. обычно в mfc каждый метод окна приурочен к какому-нибудь сообщению.
посмотри сообщения, начинающиеся с WM_INIT
 
J

Jarik

#9
Всем спасибо, все сделал. Простите за мое тотальное непонимание и еще раз спс за проявлнное терпение и помощь.
 
Статус
Закрыто для дальнейших ответов.