Инисиализация CListCtrl
От: ice_vita  
Дата: 08.05.05 21:52
Оценка:
Создается property sheet, делается AddPage страниц. В OnInitDialog каждой страницы:
VERIFY(m_list.InsertColumn(column++, L"бла1", LVCFMT_LEFT, 60) != -1);
VERIFY(m_list.InsertColumn(column++, L"бла2", LVCFMT_LEFT, 60) != -1);
VERIFY(m_list.InsertColumn(column++, L"бла3", LVCFMT_LEFT, 60) != -1);
Необходимо добавить эти колонки раньше- в конструкторе, т.к. к листконтролу обращаются до вызова функции OnInitDialog. Но если добавить эти строчки в конструктор то выходит глюк. видимо m_list еще нету. Как поступить?
Re: Инисиализация CListCtrl
От: Vinni-puh Россия  
Дата: 08.05.05 22:38
Оценка: 2 (1)
Здравствуйте, ice_vita, Вы писали:

_> [skip]

_>Необходимо добавить эти колонки раньше- в конструкторе, т.к. к листконтролу обращаются до вызова функции OnInitDialog. Но если добавить эти строчки в конструктор то выходит глюк. видимо m_list еще нету. Как поступить?

m_list инициализируется (привязывается к реальному окну) при первом вызове UpdateData(), либо можно вручную через m_list.AttachWindow(GetDlgItem(IDC_THE_LIST)).

В конструкторе или CreateWindow делать какие-либо действия с окном, привязанным к m_list нельзя, потому что этого list-окна в windows ещё не существует.

Здесь можно поступать по-разному в зависимости от того, какие действия требуется провести с листконтролом до вызова OnInitDialog()
Re[2]: Инисиализация CListCtrl
От: ice_vita  
Дата: 08.05.05 22:49
Оценка:
Здравствуйте, Vinni-puh, Вы писали:

VP>Здравствуйте, ice_vita, Вы писали:


_>> [skip]

_>>Необходимо добавить эти колонки раньше- в конструкторе, т.к. к листконтролу обращаются до вызова функции OnInitDialog. Но если добавить эти строчки в конструктор то выходит глюк. видимо m_list еще нету. Как поступить?

VP>m_list инициализируется (привязывается к реальному окну) при первом вызове UpdateData(), либо можно вручную через m_list.AttachWindow(GetDlgItem(IDC_THE_LIST)).


VP>В конструкторе или CreateWindow делать какие-либо действия с окном, привязанным к m_list нельзя, потому что этого list-окна в windows ещё не существует.


VP>Здесь можно поступать по-разному в зависимости от того, какие действия требуется провести с листконтролом до вызова OnInitDialog()


функция из другого потока обращается к функции (которая добавляет запись в листконтрол) касса этого окна до того как оно проинициализировано OnInitDialog-ом. Может возможно иницализировать это окно в функции, если оно не проиницализировано ранее.
Re[3]: Инисиализация CListCtrl
От: Vinni-puh Россия  
Дата: 08.05.05 23:23
Оценка: 2 (1)
Здравствуйте, ice_vita, Вы писали:

_>функция из другого потока обращается к функции (которая добавляет запись в листконтрол) касса этого окна до того как оно проинициализировано OnInitDialog-ом. Может возможно иницализировать это окно в функции, если оно не проиницализировано ранее.


Во-первых крайне не рекомендовал бы из одного потока производить махинации с окнами, принажлежащими другому. На это, в частности, плохо реагирует ASSERT_VALID(). Уж лучше (IMHO) в вызывающем потоке делать так:
UINT wmCommand1=RegisterWindowMessage("Команда 1 от потока к странце свойств")

...

struct Command1Info {
  Command1Info( /* some parameters */ ) {...}
  // some info
}
...
// В потоке:
::PostMessage(hwndThePage,wmCommand1,(WPARAM)(new CommandInfo(/*параметры*/)),0)

А в странице свойств сделать обработчик сообщения wmCommand1 (например, через ON_REGISTERED_MESSAGE) :

LRESULT CThePage::OnCommand1(WPARAM wParam,LPARAM)
{
  Command1Info*pI=(Command1Info*)wParam;
  // Пару ASSERT-ов на корректность данных
  // Дальше какие-то действия...

  delete pI;
  return 0;
}


По крайней мере я всегда так делаю, когда у меня несколько потоков.

Что касается, собственно, subject-а. В MFC инициализация диалога происходит в следующей последовательности.
1. Конструктор
2. PreCreateWindow
3. CreateWindow
4. OnInitDialog.
И ещё, по-моему в CDialog::OnInitDialog вызывается UpdateData() и происходит призвязка контролов-членов к вновь созданным child-окнам.

Рекомендовал бы делать так, как выше изложено: через PostMessage. Тогда, если уже известен хандлер диалога (в нашем случае CThePage), то OnCommand1 будет вызвана уже после всех инициализаций.
Re: Инисиализация CListCtrl
От: _swf_  
Дата: 10.05.05 12:15
Оценка:
Здравствуйте, ice_vita, Вы писали:

_>Создается property sheet, делается AddPage страниц. В OnInitDialog каждой страницы:

_> VERIFY(m_list.InsertColumn(column++, L"бла1", LVCFMT_LEFT, 60) != -1);
_> VERIFY(m_list.InsertColumn(column++, L"бла2", LVCFMT_LEFT, 60) != -1);
_> VERIFY(m_list.InsertColumn(column++, L"бла3", LVCFMT_LEFT, 60) != -1);
_>Необходимо добавить эти колонки раньше- в конструкторе, т.к. к листконтролу обращаются до вызова функции OnInitDialog. Но если добавить эти строчки в конструктор то выходит глюк. видимо m_list еще нету. Как поступить?

Может проблема тут?
Цитата из MSDN:
AddPage adds the CPropertyPage object to the CPropertySheet object's list of pages but does not actually create the window for the page. The framework postpones creation of the window for the page until the user selects that page.

Т.е. страницы создаются только когда пользователь нажмёт на соответствующую им вкладку.
Например вот такой код:


CPropertySheet ps( "Sheet", this, 0 );
ps.AddPage(&page1);
ps.AddPage(&page2);
ps.DoModal();


И не выйдет из другого потока обратиться к элементу на странице page2, так как он не создан.


Но можно изменить код так:


CPropertySheet ps( "Sheet", this, 0 );
ps.AddPage(&page1);
ps.AddPage(&page2);
// перебираем все страницы
int i;
int nPages = ps.GetPageCount();
for( i = 0; i < nPages; i++ ) ps.SetActivePage( i );
// устанавливаем нужную
ps.SetActivePage( 0 );
// показываем окно
ps.DoModal();



В этом случае все страницы будут созданы не дожидаясь пока пользователь кликнет на нужную вкладку. И все контролы на страницах будут также созданы.


ps. Писал по памяти, может что и упустил.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.