简体   繁体   English

使用 TAB 键和箭头键控制内部 CTabControl 项

[英]Controlling Inner CTabControl Items with TAB and Arrow Keys

I have an issue Controlling CTabControl Inner tab items with TAB and Arrow keys.我在使用 TAB 键和箭头键控制 CTabControl 内部选项卡项时遇到问题。

here is my code and a few screenshots:这是我的代码和一些截图:

OnInitDialog() method of the main dialog window:主对话框窗口的 OnInitDialog() 方法:

BOOL PressetsDlg::OnInitDialog()
{
    CDialogEx::OnInitDialog();

    // AUTO GENERATED MFC DIALOGUE CODE HERE
    ...
    // ..

    // TODO: Add extra initialization here
    CTabCtrl* pTabCtrl = (CTabCtrl*)GetDlgItem(IDC_TAB1);
    m_one.Create(IDD_TAB_ONE, pTabCtrl);

    CTabCtrl* pTabCtrl2 = (CTabCtrl*)GetDlgItem(IDC_TAB1);
    m_two.Create(IDD_TAB_TWO, pTabCtrl2);

    TCITEM item1, item2, item3;
    item1.mask = TCIF_TEXT | TCIF_PARAM;
    item1.lParam = (LPARAM)&m_one;
    item1.pszText = L"Normal Presets";
    pTabCtrl->InsertItem(0, &item1);

    item2.mask = TCIF_TEXT | TCIF_PARAM;
    item2.lParam = (LPARAM)&m_two;
    item2.pszText = L"Movement Presets";
    pTabCtrl2->InsertItem(1, &item2);

    CRect rcItem;
    pTabCtrl->GetItemRect(0, &rcItem);
    m_one.SetWindowPos(NULL, rcItem.left, rcItem.bottom + 1, 0, 0, SWP_NOSIZE | SWP_NOZORDER);

    CRect rcItem2;
    pTabCtrl2->GetItemRect(0, &rcItem2);
    m_two.SetWindowPos(NULL, rcItem2.left, rcItem2.bottom + 1, 0, 0, SWP_NOSIZE | SWP_NOZORDER);

    m_one.ShowWindow(SW_SHOW);
    m_two.ShowWindow(SW_HIDE);

    return TRUE;  // return TRUE  unless you set the focus to a control
}

and the OnTcnSelchangeTab method:和 OnTcnSelchangeTab 方法:

void PressetsDlg::OnTcnSelchangeTab1(NMHDR* pNMHDR, LRESULT* pResult)
{
    // TODO: Add your control notification handler code here
    
    int nSelect = m_Tab.GetCurSel();

    if (nSelect == 0)
    {
        m_one.ShowWindow(SW_SHOW);
        m_two.ShowWindow(SW_HIDE);
    }
    else if (nSelect == 1)
    {
        m_two.ShowWindow(SW_SHOW);
        m_one.ShowWindow(SW_HIDE);
    }
    else
    {
        m_one.ShowWindow(SW_SHOW);
        m_two.ShowWindow(SW_HIDE);
    }
    *pResult = 0;
}

[ to see the tab design click here ]( https://i.stack.imgur.com/Tt8c1.jpg ) [要查看选项卡设计,请单击此处]( https://i.stack.imgur.com/Tt8c1.jpg )

I've set the tab order with Ctrl + D for each dialogue resource and set Tabstop property to either True or False and still nothing happens.我已经使用 Ctrl + D 为每个对话资源设置了 Tab 键顺序,并将 Tabstop 属性设置为 True 或 False,但仍然没有任何反应。

At first I thought that this feature is supposed to be supported automatically but it seems that it's not.起初我以为这个功能应该是自动支持的,但似乎不是。

the dialogue window moves between tabs and buttons that placed on it but as soon as I try to move to "inner Items" of each tab, it doesn't reach them.对话窗口在选项卡和放置在其上的按钮之间移动,但是一旦我尝试移动到每个选项卡的“内部项目”,它就不会到达它们。 I suspect the reason is probably that each tab is a separate window and that's probably the reason that the inner items are unreachable..我怀疑原因可能是每个选项卡都是一个单独的窗口,这可能是无法访问内部项目的原因。

I've made a few changes and now Moving with TAB and arrow keys functions properly.我做了一些更改,现在使用 TAB 和箭头键移动功能正常。

first of all I set the Control Property of both child dialogs to True.首先,我将两个子对话框的 Control 属性设置为 True。 You go to Resource View >> (Solution name) >> (project name) >> IDD + (the id you gave to the dialog) doble click on it >> Properties >> Control.你去资源视图>>(解决方案名称)>>(项目名称)>> IDD +(你给对话框的ID)双击它>>属性>>控制。

Essentially what it did is to add the flag WS_CONTROL as mentioned here early to each of the Child windows so that they could be accessed from the main dialog window that contains them.本质上,它所做的是将这里提到的标志 WS_CONTROL 添加到每个子窗口,以便可以从包含它们的主对话窗口访问它们。

Of course that alone didn't do much because I also had a few bugs in the code, after days of searching for it I found an example online which helped me solve the bugs.当然,仅此一项并没有太大作用,因为我的代码中也有一些错误,经过几天的搜索,我在网上找到了一个示例,它帮助我解决了这些错误。

Then I've changed my code to this: and it started working:然后我将我的代码更改为:它开始工作:

   // first we create two modeless dialogs and embed them as child windows
   // of CTabControlTutorialDlg. 
   // Have a look using Spy++ to see the layout of the controls as they
   // appear to windows
    m_one.Create(IDD_TAB_ONE, this);
    m_two.Create(IDD_TAB_TWO, this);

    // next we get the captions of the dialogs and use these as the caption
    // for the tab window. Of course we could just load a string from the 
    // resources or hard code a string for the text of the tab.
    
    TCITEM item1, item2;
    item1.mask = TCIF_TEXT | TCIF_PARAM;
    item1.lParam = (LPARAM)&m_one;
    item1.pszText = L"Normal Presets";
    m_Tab.InsertItem(0, &item1);

    item2.mask = TCIF_TEXT | TCIF_PARAM;
    item2.lParam = (LPARAM)&m_two;
    item2.pszText = L"Custom Presets";
    m_Tab.InsertItem(1, &item2);

    // finally we set the tab order correctly for the so that we can tab through the dialogs and into
    // the cancel and ok buttons. If we don;t do this then the tab order is tab control, ok button, cancel
    // button embedded dialogs.
    CRect rcItem;
    m_Tab.GetItemRect(0, &rcItem);
    m_one.SetWindowPos(NULL, rcItem.left, rcItem.bottom + 5, 0, 0, SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOZORDER);

    CRect rcItem2;
    m_Tab.GetItemRect(0, &rcItem2);
    m_two.SetWindowPos(NULL, rcItem2.left, rcItem2.bottom + 5, 0, 0, SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOZORDER);

    m_one.ShowWindow(SW_SHOW);

I found reference in this site: https://www.codeproject.com/Articles/4408/Creating-embedded-dialogs-in-MFC but in order to get their code example you need to register to the website.我在这个网站上找到了参考: https ://www.codeproject.com/Articles/4408/Creating-embedded-dialogs-in-MFC 但为了获得他们的代码示例,您需要在网站上注册。

It works!有用!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM