CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 15 of 15
  1. #1
    Join Date
    Dec 2006
    Location
    Minneapolis, Minnesota
    Posts
    33

    Tab via menu item selection.

    I need to move to a different tab via a menu item selection.

    The user needs to be able to change via the menu selection.

    My current CTabCtrl changes tabs with a mouse and does it well.

    How do I do it via a menu selection?

  2. #2
    Join Date
    Nov 2003
    Location
    Belgium
    Posts
    8,150

    Re: Tab via menu item selection.

    Try CTabCtrl::SetCurFocus
    Marc Gregoire - NuonSoft (http://www.nuonsoft.com)
    My Blog
    Wallpaper Cycler 3.5.0.97

    Author of Professional C++, 4th Edition by Wiley/Wrox (includes C++17 features)
    ISBN: 978-1-119-42130-6
    [ http://www.facebook.com/professionalcpp ]

  3. #3
    Join Date
    Dec 2006
    Location
    Minneapolis, Minnesota
    Posts
    33

    Re: Tab via menu item selection.

    Thank you for your suggestion. Unfortunately, it doesn't work. The code ASSERTs because my m_hWnd returns false on the underlying IsWindow() call.

  4. #4
    Join Date
    Nov 2003
    Location
    Belgium
    Posts
    8,150

    Re: Tab via menu item selection.

    How are you calling SetCurFocus? You are calling it on a valid tabctrl or not?
    Marc Gregoire - NuonSoft (http://www.nuonsoft.com)
    My Blog
    Wallpaper Cycler 3.5.0.97

    Author of Professional C++, 4th Edition by Wiley/Wrox (includes C++17 features)
    ISBN: 978-1-119-42130-6
    [ http://www.facebook.com/professionalcpp ]

  5. #5
    Join Date
    Dec 2006
    Location
    Minneapolis, Minnesota
    Posts
    33

    Re: Tab via menu item selection.

    I am calling SetCurFocus from the CWinApp class called CPCTesterApp.

    The message map in CPCTesterApp has a call:
    ON_COMMAND(ID_VIEW_NOTES, &CPCTesterApp::OnViewNotes)

    Here is the code for OnViewNotes:

    void CPCTesterApp::OnViewNotes(void)
    {
    SetCurFocus(1);
    }

    The Notes tab is index = 1.
    When I call SetCurFocus, I get an ASSERT because IsWindow(m_hWnd) returns false.
    m_hWnd does not appear to be valid. However, I don't know how to pass the correct m_hWnd (even if I do the long-hand ::SendMessage() call.

  6. #6
    Join Date
    Nov 2003
    Location
    Belgium
    Posts
    8,150

    Re: Tab via menu item selection.

    You don't call it from CWinApp. You have to call it on your tabctlr, for example: mytabctrl.SetCurFocus(1);
    Marc Gregoire - NuonSoft (http://www.nuonsoft.com)
    My Blog
    Wallpaper Cycler 3.5.0.97

    Author of Professional C++, 4th Edition by Wiley/Wrox (includes C++17 features)
    ISBN: 978-1-119-42130-6
    [ http://www.facebook.com/professionalcpp ]

  7. #7
    Join Date
    Dec 2006
    Location
    Minneapolis, Minnesota
    Posts
    33

    Re: Tab via menu item selection.

    Thank you, Marc G, for your patience. I have tried what you suggest. It fails for the same reason: m_hWnd is invalid.

    Here is my belief: The ON_COMMAND call in CWinApp creates a new instance of CTabCtrl. When SetCurFocus runs, it doesn't have the m_hWnd data that was used when the application originally created the tabs.

    The one thing I don't get is how, when I click on a tab, the information is available to show and hide the various dialogs. If I could figure out how that worked, I could get the menu selection to work, too.

  8. #8
    Join Date
    Dec 2006
    Location
    Minneapolis, Minnesota
    Posts
    33

    Re: Tab via menu item selection.

    By the way, if I make mytabctrl a static variable, SetCurFocus works. But this doesn't appear to be a good reason for making mytabctrl a static.

  9. #9
    Join Date
    Nov 2003
    Location
    Belgium
    Posts
    8,150

    Re: Tab via menu item selection.

    Is this a big project? Could you post it? Please remove temporary files like .ncb.
    Marc Gregoire - NuonSoft (http://www.nuonsoft.com)
    My Blog
    Wallpaper Cycler 3.5.0.97

    Author of Professional C++, 4th Edition by Wiley/Wrox (includes C++17 features)
    ISBN: 978-1-119-42130-6
    [ http://www.facebook.com/professionalcpp ]

  10. #10
    Join Date
    Dec 2006
    Location
    Minneapolis, Minnesota
    Posts
    33

    Re: Tab via menu item selection.

    Thank you, Marc G. I am unable to post it both by size and by legal issues.

  11. #11
    Join Date
    Dec 2006
    Location
    Minneapolis, Minnesota
    Posts
    33

    Re: Tab via menu item selection.

    I could post parts of it. Anything in particular that you would like to see?

  12. #12
    Join Date
    Nov 2003
    Location
    Belgium
    Posts
    8,150

    Re: Tab via menu item selection.

    Then post the exact piece of code where you are calling SetCurFocus.
    Marc Gregoire - NuonSoft (http://www.nuonsoft.com)
    My Blog
    Wallpaper Cycler 3.5.0.97

    Author of Professional C++, 4th Edition by Wiley/Wrox (includes C++17 features)
    ISBN: 978-1-119-42130-6
    [ http://www.facebook.com/professionalcpp ]

  13. #13
    Join Date
    Dec 2006
    Location
    Minneapolis, Minnesota
    Posts
    33

    Re: Tab via menu item selection.

    Thanks Marc for reviewing the code.
    The First Section is CScreentestTesterApp.CPP.
    Then follows PCScreenTesterView.h and PCScreenTesterView.cpp. Finally is shown CUtility.h and CUtility.cpp.
    The menu item commands start below about 7 lines.

    Code:
    // CScreentestTesterApp.cpp
    BEGIN_MESSAGE_MAP(CScreentestTesterApp, CWinApp)
    ON_COMMAND(ID_APP_ABOUT, &CScreentestTesterApp::OnAppAbout)
    ON_COMMAND(ID_FILE_NEW, &CWinApp::OnFileNew)
    ON_COMMAND(ID_FILE_OPEN, &CWinApp::OnFileOpen)
    ON_COMMAND(ID_EXIT_NOW, &CScreentestTesterApp::OnExitNow)
    ON_COMMAND(ID_VIEW_SCREENSCAN, &CScreentestTesterView::OnViewScreenscan)
    ON_COMMAND(ID_VIEW_DRIVETEST, &CScreentestTesterView::OnViewDrivetest)
    ON_COMMAND(ID_VIEW_FIXEDTEST, &CScreentestTesterView::OnViewFixedtest)
    ON_COMMAND(ID_VIEW_NOTES, &CScreentestTesterView::OnViewNotes)
    ON_COMMAND(ID_VIEW_SCREENPLAN, &CScreentestTesterView::OnViewScreenplan)
    END_MESSAGE_MAP()
    CScreentestTesterApp::CScreentestTesterApp() {
    EnableHtmlHelp();
    }
    CScreentestTesterApp::~CScreentestTesterApp(){
    }
    CScreentestTesterApp theApp;
    BOOL CScreentestTesterApp::InitInstance(){
    ::SetPriorityClass(GetCurrentProcess(), BELOW_NORMAL_PRIORITY_CLASS);
    INITCOMMONCONTROLSEX InitCtrls;
    InitCtrls.dwSize = sizeof(InitCtrls);
    InitCtrls.dwICC = ICC_WIN95_CLASSES;
    InitCommonControlsEx(&InitCtrls);
    CWinApp::InitInstance();
    if (!AfxSocketInit()) {
    AfxMessageBox(IDP_SOCKETS_INIT_FAILED);
    return FALSE;
    }
    if (!AfxOleInit()) {
    AfxMessageBox(IDP_OLE_INIT_FAILED);
    return FALSE;
    }
    AfxEnableControlContainer();
    CSingleDocTemplate* pDocTemplate;
    pDocTemplate = new CSingleDocTemplate(
    IDR_MAINFRAME,
    RUNTIME_CLASS(CScreentestTesterDoc),
    RUNTIME_CLASS(CScreentestTesterMainFrame),	 // main SDI frame window
    RUNTIME_CLASS(CScreentestTesterView));
    if (!pDocTemplate)
    return FALSE;
    AddDocTemplate(pDocTemplate);
    EnableShellOpen();
    RegisterShellFileTypes(TRUE);
    CCommandLineInfo cmdInfo;
    ParseCommandLine(cmdInfo);
    if (!ProcessShellCommand(cmdInfo))
    return FALSE;
    m_pMainWnd->ShowWindow(SW_SHOW);
    m_pMainWnd->UpdateWindow();
    m_pMainWnd->DragAcceptFiles();
    return TRUE;
    }
    // PCScreenTesterView.h : interface of the CPCScreenTesterView class
    #pragma once
    #include "UtilityTabs.h"
    class CPCScreenTesterView : public CFormView
    {
    protected: 
    CPCScreenTesterView();
    DECLARE_DYNCREATE(CPCScreenTesterView)
    public:
    enum{ IDD = IDD_USERINTERFACE_DLG };
    public:
    CPCScreenTesterDoc* GetDocument() const;
    public:
    virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
    protected:
    virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV support
    virtual void OnInitialUpdate(); // called first time after construct
    public:
    virtual ~CPCScreenTesterView();
    protected:
    DECLARE_MESSAGE_MAP()
    public:
    static CUtilityTabs m_oTabControl;
    public:
    afx_msg void OnViewScreenScan();
    afx_msg void OnViewScreentest();
    afx_msg void OnViewFixedtest();
    afx_msg void OnViewNotes();
    afx_msg void OnViewScreenplan();
    };
    // PCScreenTesterView.cpp : implementation of the CPCScreenTesterView class
    #include "stdafx.h"
    #include "PCScreenTester.h"
    #include "PCScreenTesterDoc.h"
    #include "ScreenScanDlg.h"
    #include "FixedScreenTestDlg.h"
    #include "MobileScreenTestDlg.h"
    #include "ScreenPlanDlg.h"
    #include "AdditionalNotesDlg.h"
    CUtilityTabs CPCScreenTesterView::m_oTabControl;
    // CPCScreenTesterView
    IMPLEMENT_DYNCREATE(CPCScreenTesterView, CFormView)
    BEGIN_MESSAGE_MAP(CPCScreenTesterView, CFormView)
    END_MESSAGE_MAP()
    // CPCScreenTesterView construction/destruction
    CPCScreenTesterView::CPCScreenTesterView()
    : CFormView(CPCScreenTesterView::IDD){
    }
    CPCScreenTesterView::~CPCScreenTesterView(){
    }
    void CPCScreenTesterView::DoDataExchange(CDataExchange* pDX){
    CFormView::DoDataExchange(pDX);
    DDX_Control(pDX, IDC_TABCNTRL, m_oTabControl);
    }
    BOOL CPCScreenTesterView::PreCreateWindow(CREATESTRUCT& cs){
    return CFormView::PreCreateWindow(cs);
    }
    void CPCScreenTesterView::OnInitialUpdate(){
    CFormView::OnInitialUpdate();
    GetParentFrame()->RecalcLayout();
    ResizeParentToFit();
    try {
    CString cszScreenScan, cszFixedScreenTest, cszMobileScreenTest, cszScreenPlans, cszAdditionalNotes;
    cszScreenScan.LoadString(IDS_SCREENSCANTAB_STR);
    cszFixedScreenTest.LoadString(IDS_FIXEDSCREENTESTTAB_STR);
    cszMobileScreenTest.LoadString(IDS_MOBILESCREENTESTTAB_STR);
    cszScreenPlans.LoadString(IDS_SCREENPLANTAB_STR);
    cszAdditionalNotes.LoadString(IDS_ADDITIONALNOTESTAB_STR);
    m_oTabControl.AddTabs(IDD_SCREENSCAN_DLG, RUNTIME_CLASS(CSCREENSCANDlg), cszScreenScan);
    m_oTabControl.AddTabs(IDD_MOBILESCREENTEST_DLG, RUNTIME_CLASS(CMobileScreenTestDlg), cszMobileScreenTest);
    m_oTabControl.AddTabs(IDD_FIXEDSCREENTEST_DLG, RUNTIME_CLASS(CFixedScreenTestDlg), cszFixedScreenTest);
    m_oTabControl.AddTabs(IDD_ADDITIONALNOTES_DLG, RUNTIME_CLASS(CAdditionalNotesDlg), cszAdditionalNotes);
    m_oTabControl.AddTabs(IDD_SCREENPLAN_DLG, RUNTIME_CLASS(CScreenPlanDlg), cszScreenPlans);
    }
    catch (...){
    (void)AfxMessageBox(_T("Selecting of dialog boxes failed"), MB_ICONSTOP);
    }
    }
    void CPCScreenTesterView::OnViewScreenScan(){
    m_oTabControl.SetCurFocus(SCAN);
    }
    void CPCScreenTesterView::OnViewScreentest(){
    m_oTabControl.SetCurFocus(DRIVE);
    }
    void CPCScreenTesterView::OnViewFixedtest(){
    m_oTabControl.SetCurFocus(FIX);
    }
    void CPCScreenTesterView::OnViewNotes(){
    m_oTabControl.SetCurFocus(NOTES);
    }
    void CPCScreenTesterView::OnViewScreenplan(){
    m_oTabControl.SetCurFocus(PLAN);
    }
    // CPCScreenTesterView message handlers
    #pragma once
    #include "afxcoll.h"
    // CUtilityTabs
    class CUtilityTabs : public CTabCtrl {
    DECLARE_DYNAMIC(CUtilityTabs)
    public:
    CUtilityTabs();
    virtual ~CUtilityTabs();
    protected:
    DECLARE_MESSAGE_MAP()
    public:
    void AddTabs(UINT nIDTemplate, CRuntimeClass* pClass, LPCTSTR pszText);
    protected:
    CObArray m_oTabArrays;
    afx_msg void OnTcnSelchangeTabcntrl(NMHDR* pNMHDR, LRESULT* pResult);
    };
    // UtilityTabs.cpp : implementation file
    //
    #include "stdafx.h"
    #include "ScreentestTester.h"
    #include "UtilityTabs.h"
    // CUtilityTabs
    IMPLEMENT_DYNAMIC(CUtilityTabs, CTabCtrl)
    CUtilityTabs::CUtilityTabs(){
    }
    CUtilityTabs::~CUtilityTabs(){
    }
    BEGIN_MESSAGE_MAP(CUtilityTabs, CTabCtrl)
    ON_NOTIFY_REFLECT(TCN_SELCHANGE, OnTcnSelchangeTabcntrl)
    ON_NOTIFY_REFLECT(TCN_SELCHANGING, OnTcnSelchangeTabcntrl)
    ON_WM_NCDESTROY()
    END_MESSAGE_MAP()
    // Adds tabs to dialog box to display and execute each user utility
    void CUtilityTabs::AddTabs(UINT nIDTemplate, CRuntimeClass* pClass, LPCTSTR pszText){
    try {
    ASSERT(nIDTemplate);
    ASSERT(pClass);
    ASSERT(pszText);
    const int nCount = GetItemCount();
    if (InsertItem(nCount, pszText) == -1)
    throw _T("Error in creating a tabl in the Dialog window in AddTabs");
    CDialog* pDlg = (CDialog*)pClass->CreateObject();
    if ((pDlg == static_cast<CDialog*>(0))) 
    throw _T("Error in creating Dialog Class in AddTabs");
    if (pDlg->Create(nIDTemplate, this) == FALSE) 
    throw _T("Error in creating Dialog window in AddTabs");
    CRect DispRect = CRect();
    ASSERT(DispRect);
    GetClientRect(DispRect);
    AdjustRect(false, DispRect);
    const INT_PTR ipTabNumbers = m_oTabArrays.Add(pDlg);
    pDlg->MoveWindow(DispRect);
    if (nCount == 0) 
    (void)pDlg->ShowWindow(SW_SHOW);
    }
    catch (wstring wszError) {
    (void)AfxMessageBox(wszError.c_str(), MB_ICONSTOP);
    }
    catch (...) {
    (void)AfxMessageBox(_T("Creation of dialog boxes failed"), MB_ICONSTOP);
    }
    }
    // CUtilityTabs message handlers
    void CUtilityTabs::OnTcnSelchangeTabcntrl(NMHDR *pNMHDR, LRESULT *pResult)
    {
    try {
    ASSERT(pNMHDR);
    ASSERT(pResult);
    const int iCurSel = GetCurSel();
    const INT_PTR iSize = m_oTabArrays.GetSize();
    for (int iIndex = 0; iIndex < static_cast<int>(iSize); ++iIndex)
    if (iCurSel == iIndex) 
    	BOOL bShow = ((CDialog*)m_oTabArrays[iIndex])->ShowWindow(SW_SHOW);
    else
    	BOOL bShow = ((CDialog*)m_oTabArrays[iIndex])->ShowWindow(SW_HIDE);
    *pResult = static_cast<LRESULT>(0);
    }
    catch (...) {
    (void)AfxMessageBox(_T("Selecting of dialog boxes failed"), MB_ICONSTOP);
    *pResult = static_cast<LRESULT>(0);
    }
    }

  14. #14
    Join Date
    Nov 2003
    Location
    Belgium
    Posts
    8,150

    Re: Tab via menu item selection.

    First, that code is barely readable without any tabs...

    Second, I cannot immediately find the problem. Are you sure you are not calling any of the OnViewScreenScan(); OnViewScreentest(); OnViewFixedtest(); OnViewNotes(); OnViewScreenplan(); functions before the tab is created?
    Marc Gregoire - NuonSoft (http://www.nuonsoft.com)
    My Blog
    Wallpaper Cycler 3.5.0.97

    Author of Professional C++, 4th Edition by Wiley/Wrox (includes C++17 features)
    ISBN: 978-1-119-42130-6
    [ http://www.facebook.com/professionalcpp ]

  15. #15
    Join Date
    Dec 2006
    Location
    Minneapolis, Minnesota
    Posts
    33

    Re: Tab via menu item selection.

    Thank you, Mark for your help.

    These methods are called by the user through a menu selection. So the tabs exist before the calls are made.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured