C++ C++;插入成功后MFC CTabCtrl项目调试断言失败winocc.cpp SetWindowPos
在OnInitDialog中调用的方法:C++ C++;插入成功后MFC CTabCtrl项目调试断言失败winocc.cpp SetWindowPos,c++,mfc,C++,Mfc,在OnInitDialog中调用的方法: void ChookDlg::add_tab_items() { tab_item_ptrs.push_back( tab_item_ptr( new CTabSLSensor ) ); tab_item_ptrs.push_back( tab_item_ptr(new user_dlg) ); tab_item_ptrs.push_back( tab_item_ptr( new admin_dlg
void ChookDlg::add_tab_items()
{
tab_item_ptrs.push_back( tab_item_ptr( new CTabSLSensor ) );
tab_item_ptrs.push_back( tab_item_ptr(new user_dlg) );
tab_item_ptrs.push_back( tab_item_ptr( new admin_dlg ) );
for ( auto tab_item_res_id = first_tab_item_res_id, idx = 0U; tab_item_res_id != last_tab_item_res_id + 1; ++tab_item_res_id, ++idx )
{
ASSERT(tab_item_ptrs.at(idx)->Create(tab_item_res_id, this)); // calls OnInitDialog
tab_item_ptrs.at(idx)->ShowWindow(SW_HIDE);
mapped_tab_items[static_cast< tab_item >(idx)] =
tab_item_image_container(
tab.InsertItem(tab.GetItemCount(), _T("SL Sensor"), tab_item_ptrs.back().get()),
tab_item_ptrs.at(idx)
);
}
}
LONG CMyTabCtrl::InsertItem(int nItem, LPCTSTR lpszItem, CMyTabCtrlTab *myTabCtrlTab)
{
UINT mask = TCIF_PARAM;
LPARAM lParam = reinterpret_cast<LPARAM>(myTabCtrlTab);
if (NULL != lpszItem) {
mask |= TCIF_TEXT;
}
ASSERT(myTabCtrlTab != NULL);
LONG retval = CTabCtrl::InsertItem(mask, nItem, lpszItem, 0, lParam);
if (retval < 0)
return retval;
CRect windowRect;
GetWindowRect(&windowRect);
AdjustRect(FALSE, &windowRect);
// The left border is 3 pixel, the bottom border 2 pixel and the right border 1 pixel
// Adjust to 1 pixel at each side.
// windowRect.left -= 2;
// windowRect.bottom += 1;
GetParent()->ScreenToClient(&windowRect);
myTabCtrlTab->SetWindowPos(&wndTop, windowRect.left, windowRect.top, windowRect.Width(), windowRect.Height(), SWP_HIDEWINDOW);
return retval;
}
BOOL CWnd::SetWindowPos(const CWnd* pWndInsertAfter, int x, int y, int cx,
int cy, UINT nFlags)
{
ASSERT(::IsWindow(m_hWnd) || (m_pCtrlSite != NULL));
BOOL ChookDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
ASSERT((IDM_RECONNECT & 0xFFF0) == IDM_RECONNECT);
ASSERT(IDM_RECONNECT < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
CString strReconnectMenu;
bNameValid = strReconnectMenu.LoadString(IDS_RECONNECT);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_RECONNECT, strReconnectMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// initialize tab item pointers container
add_tab_items();
tab.ChangeTab( static_cast< int >( tab_item::sensor ) );
return TRUE; // return TRUE unless you set the focus to a control
}
private:
CMyTabCtrl tab;
模板设置正确
这是OnInitDialog:
void ChookDlg::add_tab_items()
{
tab_item_ptrs.push_back( tab_item_ptr( new CTabSLSensor ) );
tab_item_ptrs.push_back( tab_item_ptr(new user_dlg) );
tab_item_ptrs.push_back( tab_item_ptr( new admin_dlg ) );
for ( auto tab_item_res_id = first_tab_item_res_id, idx = 0U; tab_item_res_id != last_tab_item_res_id + 1; ++tab_item_res_id, ++idx )
{
ASSERT(tab_item_ptrs.at(idx)->Create(tab_item_res_id, this)); // calls OnInitDialog
tab_item_ptrs.at(idx)->ShowWindow(SW_HIDE);
mapped_tab_items[static_cast< tab_item >(idx)] =
tab_item_image_container(
tab.InsertItem(tab.GetItemCount(), _T("SL Sensor"), tab_item_ptrs.back().get()),
tab_item_ptrs.at(idx)
);
}
}
LONG CMyTabCtrl::InsertItem(int nItem, LPCTSTR lpszItem, CMyTabCtrlTab *myTabCtrlTab)
{
UINT mask = TCIF_PARAM;
LPARAM lParam = reinterpret_cast<LPARAM>(myTabCtrlTab);
if (NULL != lpszItem) {
mask |= TCIF_TEXT;
}
ASSERT(myTabCtrlTab != NULL);
LONG retval = CTabCtrl::InsertItem(mask, nItem, lpszItem, 0, lParam);
if (retval < 0)
return retval;
CRect windowRect;
GetWindowRect(&windowRect);
AdjustRect(FALSE, &windowRect);
// The left border is 3 pixel, the bottom border 2 pixel and the right border 1 pixel
// Adjust to 1 pixel at each side.
// windowRect.left -= 2;
// windowRect.bottom += 1;
GetParent()->ScreenToClient(&windowRect);
myTabCtrlTab->SetWindowPos(&wndTop, windowRect.left, windowRect.top, windowRect.Width(), windowRect.Height(), SWP_HIDEWINDOW);
return retval;
}
BOOL CWnd::SetWindowPos(const CWnd* pWndInsertAfter, int x, int y, int cx,
int cy, UINT nFlags)
{
ASSERT(::IsWindow(m_hWnd) || (m_pCtrlSite != NULL));
BOOL ChookDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
ASSERT((IDM_RECONNECT & 0xFFF0) == IDM_RECONNECT);
ASSERT(IDM_RECONNECT < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
CString strReconnectMenu;
bNameValid = strReconnectMenu.LoadString(IDS_RECONNECT);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_RECONNECT, strReconnectMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// initialize tab item pointers container
add_tab_items();
tab.ChangeTab( static_cast< int >( tab_item::sensor ) );
return TRUE; // return TRUE unless you set the focus to a control
}
private:
CMyTabCtrl tab;
不确定这一点,因为MFC是一辈子以前的事了,但直觉告诉我,下面这句话是可疑的 GetParent()->ScreenToClient(&windowRect) 应该调用GetClientRect而不是ScreenToClient。在代码中
tab.InsertItem(tab.GetItemCount(), _T("SL Sensor"), tab_item_ptrs.back().get())
获取未初始化的对话框指针。它的形式应该是
tab.InsertItem(tab.GetItemCount(), _T("SL Sensor"), tab_item_ptrs.at(idx).get())
那么,是无效窗口句柄还是空m_pCtrlSite?m_hWnd应该是父句柄,m_pCtrlSite应该是选项卡项句柄。如果这是正确的,那么对话框应该是有效的(当所有行都在add_tab_items()中时)注释后,对话框显示为空选项卡。只是想知道您是如何在
ChookDlg
中定义tab
变量的。是否对此控件或DDE使用了“SubclassDlgItem”?调试器会说什么?其中一个无效,如果您将其添加到监视窗口并逐步查看代码,调试器会告诉您是哪一个断言失败。+myTabCtrlTab 0x0145ee10{hWnd=0x00000000{unused=???}CMyTabCtrlTab*这是输入到InsertItemwhere is&wndTop参数到SetWindowPos之后的数据。我没有看到它被声明或初始化。afxwin.h static AFX_data const CWnd wndTop;//SetWindowPos的pWndInsertAfterBTW,技术上你应该写CWnd::wndTop