C++ 如果切换到其他应用程序,我的MFC应用程序将冻结

C++ 如果切换到其他应用程序,我的MFC应用程序将冻结,c++,visual-studio,visual-studio-2008,visual-c++,mfc,C++,Visual Studio,Visual Studio 2008,Visual C++,Mfc,从这个问题的第2.0版开始。 我的VC++MFC应用程序编译并运行良好。也就是说,直到我切换到另一个窗口。一旦我的程序失去焦点,它就会冻结;我无法切换回它,如果我移动它前面的一个窗口,我的应用程序窗口在另一个窗口覆盖的空间中显示白色 自从我第一次发布这个问题以来,我已经能够精确地指出我的程序的哪个部分导致了这种行为,但是我仍然不知道哪些代码行是错误的,或者为什么 我的MFC应用程序的主对话框包含一个名为m_MainTabControl的CTabCtrl。此主选项卡控件包含两个标签为“基本设计”和

从这个问题的第2.0版开始。

我的VC++MFC应用程序编译并运行良好。也就是说,直到我切换到另一个窗口。一旦我的程序失去焦点,它就会冻结;我无法切换回它,如果我移动它前面的一个窗口,我的应用程序窗口在另一个窗口覆盖的空间中显示白色

自从我第一次发布这个问题以来,我已经能够精确地指出我的程序的哪个部分导致了这种行为,但是我仍然不知道哪些代码行是错误的,或者为什么

我的MFC应用程序的主对话框包含一个名为m_MainTabControl的CTabCtrl。此主选项卡控件包含两个标签为“基本设计”和“高级设计”的选项卡,每个选项卡都绑定到各自的对话框。两个对话框都包含一个带有多个选项卡的CTabCtrl。我的问题就这样诞生了

当我第一次在选项卡结构中创建这个选项卡时,当我尝试在内部选项卡之间切换时,我的程序出现了冻结问题。不用说,我对此感到困惑,直到我注意到,如果我第一次单击某个内部选项卡上的控件,我就可以很好地切换选项卡。因此,在没有完全理解问题所在的情况下,我在程序启动时将焦点设置为第一个内部选项卡的第一个内部选项卡。问题解决了一半。当我运行这个程序时,我可以在第一组内部选项卡上随意点击;如果我切换到第二个外部选项卡并尝试在没有首先单击对话框控件的情况下单击其内部选项卡,它将再次冻结。因此,我创建了一个Focus函数来聚焦当前所选外部选项卡的当前所选内部选项卡,并在我的选项卡更改事件中调用该函数(当您单击另一个选项卡时,该事件将关闭)

这就是我第一次问这个问题时的观点。我认为我的程序运行得很好,直到我玩了它一点,发现当我在它和另一个窗口或程序之间来回切换时,它并没有很好地运行。更具体地说,一旦我的程序失去焦点,一些进程就会失控,占用整个CPU的处理时间

现在,我详细解释了我的小选项卡结构和焦点问题的原因:经过大量实验,我发现如果我注释掉外部选项卡结构上的第二个选项卡(即“高级设计”对话框及其所有小选项卡),我程序的剩余部分运行良好,我可以切换到另一个窗口,然后再回来,而不用打架。“太好了,”我想,“这只是我的程序的90%而已,我只是注释掉了它来让它工作。让我们试着把它进一步缩减。”我把“高级设计”选项卡对话框放回,但是注释掉了“高级设计”中的选项卡控件创建的选项卡对话框,一切仍然正常。我一个接一个地放回属于“Advanced Design”选项卡控件的选项卡对话框,每次我重新引入错误时,不管我取消注释了哪个选项卡。我还应该指出,我尝试放回的第一个选项卡(当然是单独放回的)是我的“边距”选项卡,这是一个MarginDlg类,我在“基本设计”选项卡下也使用它,没有任何问题。这让我相信,当我在选项卡式对话框中创建选项卡式对话框时,我必须做一些具体的事情,而我没有做,或者做得不正确,有点像一开始我必须搞乱聚焦以使其工作

如果能提供有关情况的任何信息,我将不胜感激。我包括我认为相关的代码片段;一如既往,如果需要更多,请告诉我

主对话框的.h文件中的变量声明:

//tab stuff
CTabCtrl m_MainTabControl;
vector<CDialog*> m_tabPages;
SimpDesDlg* simpDesDlg;
AdvDesDlg* advDesDlg;
m_MainTabControl的选项卡选择更改事件的代码:

void CspAceDlg::OnTcnSelchangeBuildtabs(NMHDR *pNMHDR, LRESULT *pResult)
{
    for (int i = 0; i < int(m_tabPages.size()); i++)
    {
        m_tabPages[i]->ShowWindow(m_MainTabControl.GetCurSel() == i ? SW_SHOW :
                                                   SW_HIDE);
    }

    Focus();

    *pResult = 0;
}
在选项卡式对话框中添加:

void AdvDesDlg::DrawTabs()
{
    //Make the dialogs for the tabs
    antennaDlg = new AntennaDlg;
    commSEDlg = new CommSEDlg;
    encryptorDlg = new EncryptorDlg;
    marginDlg = new MarginDlg;
    miscDlg = new MiscDlg;
    transRecDlg = new TransRecDlg;

    //add them all to the tabPages vector
    m_tabPages.push_back(antennaDlg);
    m_tabPages.push_back(commSEDlg);
    m_tabPages.push_back(encryptorDlg);
    m_tabPages.push_back(marginDlg);
    m_tabPages.push_back(miscDlg);
    m_tabPages.push_back(transRecDlg);

    //m_tabPages[0] = new AntennaDlg;
    //m_tabPages[1] = new CommSEDlg;
    //m_tabPages[2] = new EncryptorDlg;
    //m_tabPages[3] = new MarginDlg;
    //m_tabPages[4] = new MiscDlg;
    //m_tabPages[5] = new TransRecDlg;

    //antennaDlg = (AntennaDlg*) m_tabPages[0];
    //commSEDlg = (CommSEDlg*) m_tabPages[1];
    //encryptorDlg = (EncryptorDlg*) m_tabPages[2];
    //marginDlg = (MarginDlg*) m_tabPages[3];
    //miscDlg = (MiscDlg*) m_tabPages[4];
    //transRecDlg = (TransRecDlg*) m_tabPages[5];

    // create a tcItem to hold the name of each tab during creation
    // and then get inserted, and arrays holding the tab names and IDs of
    // the dialogs they refer to
    TC_ITEM tcItem;
    PSTR pszTabNames[] = {"Antenna", "Comm Support", "Encryptor", "Margins", "Misc", "Trasmitter/Receiver"};
    UINT pszTabItems[] = {IDD_ANTENNATAB, IDD_COMMSETAB, IDD_ENCRYPTORTAB, IDD_MARGINTAB, IDD_MISCTAB, IDD_TRANSRECTAB};

    //every member of m_tabPages[] will become a tab
    for (int i = 0; i < int(m_tabPages.size())/*(sizeof(m_tabPages)/sizeof(m_tabPages[0]))*/; i++)
    {
        //set up the tab name
        tcItem.mask = TCIF_TEXT;
        tcItem.pszText = pszTabNames[i];
        tcItem.cchTextMax = int(strlen(pszTabNames[i]));
        //insert the new tab into the tab control and create the dialog window
        advTab.InsertItem(i, &tcItem);
        m_tabPages[i]->Create(pszTabItems[i], &advTab);
    }

    //redraw so that the dialogs don't appear in upper left corner and cover the tabs
    CRect tabRect, itemRect;
    int nX, nY, nXc, nYc;

    advTab.GetClientRect(&tabRect);
    advTab.GetItemRect(0, &itemRect);

    nX=itemRect.left;
    nY=itemRect.bottom+1;
    nXc=tabRect.right-itemRect.left-1;
    nYc=tabRect.bottom-nY-1;

    //m_tabPages[0]->SetWindowPos(&wndTop, nX, nY, nXc, nYc, SWP_SHOWWINDOW);
    for(int nCount=/*1*/0; nCount < int(m_tabPages.size())/*(sizeof(m_tabPages)/sizeof(m_tabPages[0]))*/; nCount++){
        m_tabPages[nCount]->SetWindowPos(&wndTop, nX, nY, nXc, nYc, SWP_HIDEWINDOW);
    }
}
void advdlg::drawtab()
{
//为选项卡创建对话框
antennaDlg=新的antennaDlg;
commSEDlg=新commSEDlg;
encryptorDlg=新的encryptorDlg;
marginDlg=新marginDlg;
miscDlg=新的miscDlg;
transRecDlg=新的transRecDlg;
//将它们全部添加到tabPages向量
m_标签页。向后推_(天线标签);
m_tabPages.向后推(commSEDlg);
m_标签页。推回(encryptorDlg);
m_tabPages.向后推(marginDlg);
m_标签页。推回(miscDlg);
m_tabPages.向后推(transRecDlg);
//m_tabPages[0]=新天线LG;
//m_tabPages[1]=新的命令;
//m_tabPages[2]=新的EncryptorDlg;
//m_tabPages[3]=新边距lg;
//m_tabPages[4]=新的杂项;
//m_tabPages[5]=新的TransRecDlg;
//antennaDlg=(antennaDlg*)m_tabPages[0];
//commSEDlg=(commSEDlg*)m_tabPages[1];
//encryptorDlg=(encryptorDlg*)m_tabPages[2];
//marginDlg=(marginDlg*)m_tabPages[3];
//miscDlg=(miscDlg*)m_tabPages[4];
//transRecDlg=(transRecDlg*)m_tabPages[5];
//创建一个tcItem以在创建期间保存每个选项卡的名称
//然后被插入,数组中包含
//它们所指的对话框
TC_项目TC项目;
PSTR pszTabNames[]={“天线”、“通信支持”、“加密机”、“边距”、“杂项”、“传输/接收器”};
UINT pszTabItems[]={IDD_天线选项卡、IDD_通信选项卡、IDD_加密选项卡、IDD_边缘选项卡、IDD_MISCTAB、IDD_TRANSRECTAB};
//m_tabPages[]的每个成员都将成为一个选项卡
对于(int i=0;i创建(pszTabItems[i],&advTab);
}
//重新绘制,使对话框不会出现在左上角并覆盖选项卡
正确的tabRect,itemRect;
int nX,nY,nXc,nYc;
advTab.GetClientRect(&tabRect);
公元
void CspAceDlg::Focus()
{
    int curSel = m_MainTabControl.GetCurSel();
    m_tabPages[curSel]->SetFocus();

    //if it's the basic design, we need to focus its first tab
    if (curSel == 0)
    {
        simpDesDlg->Focus();
    }
    //if it's the advanced design, we need to focus its first tab
    else if (curSel == 1)
    {
        advDesDlg->Focus();
    }
}
void CspAceDlg::OnTcnSelchangeBuildtabs(NMHDR *pNMHDR, LRESULT *pResult)
{
    for (int i = 0; i < int(m_tabPages.size()); i++)
    {
        m_tabPages[i]->ShowWindow(m_MainTabControl.GetCurSel() == i ? SW_SHOW :
                                                   SW_HIDE);
    }

    Focus();

    *pResult = 0;
}
BOOL AdvDesDlg::OnInitDialog()
{
    CDialog::OnInitDialog();

    DrawTabs();

    return false;
}
void AdvDesDlg::DrawTabs()
{
    //Make the dialogs for the tabs
    antennaDlg = new AntennaDlg;
    commSEDlg = new CommSEDlg;
    encryptorDlg = new EncryptorDlg;
    marginDlg = new MarginDlg;
    miscDlg = new MiscDlg;
    transRecDlg = new TransRecDlg;

    //add them all to the tabPages vector
    m_tabPages.push_back(antennaDlg);
    m_tabPages.push_back(commSEDlg);
    m_tabPages.push_back(encryptorDlg);
    m_tabPages.push_back(marginDlg);
    m_tabPages.push_back(miscDlg);
    m_tabPages.push_back(transRecDlg);

    //m_tabPages[0] = new AntennaDlg;
    //m_tabPages[1] = new CommSEDlg;
    //m_tabPages[2] = new EncryptorDlg;
    //m_tabPages[3] = new MarginDlg;
    //m_tabPages[4] = new MiscDlg;
    //m_tabPages[5] = new TransRecDlg;

    //antennaDlg = (AntennaDlg*) m_tabPages[0];
    //commSEDlg = (CommSEDlg*) m_tabPages[1];
    //encryptorDlg = (EncryptorDlg*) m_tabPages[2];
    //marginDlg = (MarginDlg*) m_tabPages[3];
    //miscDlg = (MiscDlg*) m_tabPages[4];
    //transRecDlg = (TransRecDlg*) m_tabPages[5];

    // create a tcItem to hold the name of each tab during creation
    // and then get inserted, and arrays holding the tab names and IDs of
    // the dialogs they refer to
    TC_ITEM tcItem;
    PSTR pszTabNames[] = {"Antenna", "Comm Support", "Encryptor", "Margins", "Misc", "Trasmitter/Receiver"};
    UINT pszTabItems[] = {IDD_ANTENNATAB, IDD_COMMSETAB, IDD_ENCRYPTORTAB, IDD_MARGINTAB, IDD_MISCTAB, IDD_TRANSRECTAB};

    //every member of m_tabPages[] will become a tab
    for (int i = 0; i < int(m_tabPages.size())/*(sizeof(m_tabPages)/sizeof(m_tabPages[0]))*/; i++)
    {
        //set up the tab name
        tcItem.mask = TCIF_TEXT;
        tcItem.pszText = pszTabNames[i];
        tcItem.cchTextMax = int(strlen(pszTabNames[i]));
        //insert the new tab into the tab control and create the dialog window
        advTab.InsertItem(i, &tcItem);
        m_tabPages[i]->Create(pszTabItems[i], &advTab);
    }

    //redraw so that the dialogs don't appear in upper left corner and cover the tabs
    CRect tabRect, itemRect;
    int nX, nY, nXc, nYc;

    advTab.GetClientRect(&tabRect);
    advTab.GetItemRect(0, &itemRect);

    nX=itemRect.left;
    nY=itemRect.bottom+1;
    nXc=tabRect.right-itemRect.left-1;
    nYc=tabRect.bottom-nY-1;

    //m_tabPages[0]->SetWindowPos(&wndTop, nX, nY, nXc, nYc, SWP_SHOWWINDOW);
    for(int nCount=/*1*/0; nCount < int(m_tabPages.size())/*(sizeof(m_tabPages)/sizeof(m_tabPages[0]))*/; nCount++){
        m_tabPages[nCount]->SetWindowPos(&wndTop, nX, nY, nXc, nYc, SWP_HIDEWINDOW);
    }
}
void AdvDesDlg::Focus()
{
    this->SetFocus();
    for (int i = 0; i < int(m_tabPages.size())/*(sizeof(m_tabPages)/sizeof(m_tabPages[0]))*/; i++)
    {
        m_tabPages[i]->ShowWindow(advTab.GetCurSel() == i ? SW_SHOW :
                                                   SW_HIDE);
    }

    int curSel = advTab.GetCurSel();
    m_tabPages[curSel]->SetFocus();
}

void AdvDesDlg::OnTcnSelchangeAdvDesign(NMHDR *pNMHDR, LRESULT *pResult)
{
    for (int i = 0; i < int(m_tabPages.size())/*(sizeof(m_tabPages)/sizeof(m_tabPages[0]))*/; i++)
    {
        m_tabPages[i]->ShowWindow(advTab.GetCurSel() == i ? SW_SHOW :
                                                   SW_HIDE);
    }

    int curSel = advTab.GetCurSel();
    m_tabPages[curSel]->SetFocus();

    *pResult = 0;
}