Я на свой диалог повесил табконтрол IDC_TAB1 (тип CTabCtrl, переменная m_IDC_TAB1).
На этот табконтрол я поместил две закладки--"Исходные НУ" и "Расчёт". Каждой из этих закладок соответствует по одной странице (диалогу). Обе эти страницы пока пустые (без компонентов), так как я хотел бы, чтобы первоначально просто нормально бы работал этот табконтрол.
Первоначально табконтрол находится на странице "Исходные НУ". При нажатии на страницу "Расчёт" в отладчике появляется два раза сообщение--в функции OnTcnSelchangingTab1 и в функции OnTcnSelchangeTab1:
Debug Assertion Failed!
Program: C:\WINDOWS\SYSTEM32\mfc110d.dll
File: f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\winocc.cpp
Line: 329
После этого тем не менее происходит переход и отображение диалога "Расчёт".
Если же на диалоге "Расчёт" нажать на страницу "Исходные НУ", то также в отладчике будет два раза появляться точно такое же сообщение об ошибке--в функции OnTcnSelchangingTab1 и в функции OnTcnSelchangeTab1, после чего происходит переход и отображение диалога "Исходные НУ".
В чём причина этого? Как сделать так, чтобы этого сообщения не появлялось?
Код:
BOOL CSO_LifeTimeDlg::OnInitDialog()
{
CNUDialog *pNUPage;
CCalcDialog *pCalcPage;
CDialogEx::OnInitDialog();
// Добавление пункта "О программе..." в системное меню.
// IDM_ABOUTBOX должен быть в пределах системной команды.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Задает значок для этого диалогового окна. Среда делает это автоматически,
// если главное окно приложения не является диалоговым
SetIcon(m_hIcon, TRUE); // Крупный значок
SetIcon(m_hIcon, FALSE); // Мелкий значок
// TODO: добавьте дополнительную инициализацию
TCITEM TabItem;
TabItem.mask = TCIF_TEXT;
TabItem.pszText = "Исходные НУ";
m_IDC_TAB1.InsertItem(0,&TabItem);
TabItem.pszText = "Расчёт";
m_IDC_TAB1.InsertItem(1,&TabItem);
pNUPage = new CNUDialog(this);
pCalcPage = new CCalcDialog(this);
TabItem.mask = TCIF_PARAM;
TabItem.lParam = (LPARAM)pNUPage;
m_IDC_TAB1.SetItem(0,&TabItem);
TabItem.mask = TCIF_PARAM;
TabItem.lParam = (LPARAM)pCalcPage;
m_IDC_TAB1.SetItem(1,&TabItem);
return TRUE; // возврат значения TRUE, если фокус не передан элементу управления
}
void CSO_LifeTimeDlg::OnTcnSelchangeTab1(NMHDR *pNMHDR, LRESULT *pResult)
{
// TODO: добавьте свой код обработчика уведомлений
int nTab = m_IDC_TAB1.GetCurSel();
TC_ITEM tci;
tci.mask = TCIF_PARAM;
m_IDC_TAB1.GetItem(nTab,&tci);
ASSERT(tci.lParam);
CWnd *pWnd = (CWnd*)tci.lParam;
//
pWnd->ShowWindow(SW_SHOW); // здесь выскакивает сообщение об ошибке
*pResult = 0;
}
void CSO_LifeTimeDlg::OnTcnSelchangingTab1(NMHDR *pNMHDR, LRESULT *pResult)
{
// TODO: добавьте свой код обработчика уведомлений
int nTab = m_IDC_TAB1.GetCurSel();
TC_ITEM tci;
tci.mask = TCIF_PARAM;
m_IDC_TAB1.GetItem(nTab,&tci);
ASSERT(tci.lParam);
CWnd *pWnd = (CWnd*)tci.lParam;
//
pWnd->ShowWindow(SW_HIDE); // здесь выскакивает сообщение об ошибке
*pResult = 0;
}
1613 г. = 2024 г.
Здравствуйте, RussianFellow, Вы писали:
Здесь надо для дочерних диалогов Create вызывать.
ASSERT вылезает из-за того, что ShowWindow зовется при m_hWnd == NULL.
RF>RF> TCITEM TabItem;
RF> TabItem.mask = TCIF_TEXT;
RF> TabItem.pszText = "Исходные НУ";
RF> m_IDC_TAB1.InsertItem(0,&TabItem);
RF> TabItem.pszText = "Расчёт";
RF> m_IDC_TAB1.InsertItem(1,&TabItem);
RF> pNUPage = new CNUDialog(this);
RF> pCalcPage = new CCalcDialog(this);
RF> TabItem.mask = TCIF_PARAM;
RF> TabItem.lParam = (LPARAM)pNUPage;
RF> m_IDC_TAB1.SetItem(0,&TabItem);
RF> TabItem.mask = TCIF_PARAM;
RF> TabItem.lParam = (LPARAM)pCalcPage;
RF> m_IDC_TAB1.SetItem(1,&TabItem);
Еще надо посмотреть в редакторе ресурсов, чтобы для дочерних диалогов стояли стили child и control parent.
Точно нужен таб контрол в диалоге?
Если на диалоге только странички (нет какой-то общей части), то гораздо проще и приятнее пользоваться связкой CPropertySheet + CPropertyPage.
P.S. Код ужасен.
Здравствуйте, qaz77, Вы писали:
Q>Здравствуйте, RussianFellow, Вы писали:
Q>Здесь надо для дочерних диалогов Create вызывать.
Q>ASSERT вылезает из-за того, что ShowWindow зовется при m_hWnd == NULL.
Да, верно--посмотрел своё предыдущее решение, там тоже на табконтроле диалоги размещаются--действительно, нужно вызвать для pNUPage и pCalcPage сначала функции Create, потом функции SetWindowsPos, а затем функции ShowWindow (для pNUPage как для страницы первой вкладки с параметром SW_SHOW, для pCalcPage как для страницы последующей вкладки с параметром SW_HIDE). И всё заработало!
Спасибо за подсказку!
1613 г. = 2024 г.