MFC MDI 设计用户首选项对话框 GUI 布局功能
MFC MDI Designing user preferences dialog GUI layout functionality
在这种情况下,我并没有“被卡住”,而是在寻找一些 'guidance' 如何执行有意义且易于构建的 GUI 布局机制。我使用的 TreeControl
在视觉上与 Winamp 的 options/preferences 对话框的所有设置和程序选项“匹配”。
需要说明的是:这不是我曾经尝试过的事情,我正在寻找用户输入来帮助我越过终点线。
我在 'tree'('parent')和 5 'subitems' 中有 6 个项目。我已经完全构建好了,我可以从 selected 的任何节点获取数据(我将在图像下方 post)。
我正在使用“do.Modal 对话框”,当我单击树节点时,我希望对话框的右侧更新为该节点功能所需的控件。通过“显示”和“隐藏”来执行控件对我来说似乎很容易。我遇到的问题是当每个“节点分页”控件在 design time
期间可能会或可能不会在视觉上位于彼此之上时如何在资源编辑器中执行可视化“静态”控件。在 运行 期间,当每个节点在节点上 selected 时,控件将处于活动状态,但在设计期间,我可能会将控件放在彼此之上,这将是一个后勤噩梦试图整理他们的职位等
如何解决构建它的那个方面?我认为它是 select: 'node' show: 'option page controls' 所以我明白了逻辑;我只是想知道我是否应该有单独的“弹出”页面并调用它们……或者直接处理控件。这有意义吗?
我已经搜索了一些有关如何执行此操作的信息,但示例随处可见,我认为在这里提问最有意义。我确信有多种方法可以做到这一点,我只是在寻找最短的路径和最容易维护的方法,并可能在未来扩展选项。
我正在使用的对话框示例和源代码:
初始化代码如下:
BOOL CSettingsDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// TODO: Add extra initialization here
HTREEITEM hParent, hToolbars, hColorScheme, hTabStyles, hPowerUser,
hResetApp;
//HTREEITEM hCompany, hLevel, hLevelNext; // Used in core example, not needed here
hParent = m_TreeCtrl.InsertItem((L"Preferences"), TVI_ROOT);
hToolbars = m_TreeCtrl.InsertItem((L"Toolbars"), hParent);
hColorScheme = m_TreeCtrl.InsertItem((L"Color Scheme"), hParent);
hTabStyles = m_TreeCtrl.InsertItem((L"Tab Styles"), hParent);
hPowerUser = m_TreeCtrl.InsertItem((L"Power User"), hParent);
hResetApp= m_TreeCtrl.InsertItem((L"Reset All Options"), hParent);
m_TreeCtrl.Expand(hParent, TVE_EXPAND);
m_TreeCtrl.SelectItem(hParent);
GetDlgItem(IDC_SETTINGS_CAPTION)->SetWindowText(_T("Preferences Settings"));
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
这是我从头开始的对话框框架,只是为了到达这里:
void CSettingsDlg::OnTvnSelchangedTree1(NMHDR *pNMHDR, LRESULT *pResult)
{
//LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);
//SetDlgItemInt(IDC_TXT_TREE1, m_TreeCtrl.GetItemData(pNMTreeView->itemNew.hItem));
//*pResult = 0;
HTREEITEM sel = m_TreeCtrl.GetSelectedItem();
CPoint point;
CString str;
GetCursorPos(&point);
m_TreeCtrl.ScreenToClient(&point);
UINT flags = 0;
HTREEITEM hitItem = m_TreeCtrl.HitTest(point, &flags);
if (hitItem && sel != hitItem)
{
sel = hitItem;
m_TreeCtrl.SelectItem(sel);
str = m_TreeCtrl.GetItemText(sel);
//MessageBox((LPCTSTR)str); // Just to verify.
}
if (str == "Preferences")
{
this->SetWindowText(_T("Preferences Settings"));
GetDlgItem(IDC_SETTINGS_CAPTION)->SetWindowText(_T("Preferences Settings"));
}
if (str == "Toolbars")
{
this->SetWindowText(_T("Toolbars Settings"));
GetDlgItem(IDC_SETTINGS_CAPTION)->SetWindowText(_T("Toolbars Settings"));
}
if (str == "Color Scheme")
{
this->SetWindowText(_T("Color Scheme"));
GetDlgItem(IDC_SETTINGS_CAPTION)->SetWindowText(_T("Color Scheme Settings"));
}
if (str == "Tab Styles")
{
this->SetWindowText(_T("Tab Styles Settings"));
GetDlgItem(IDC_SETTINGS_CAPTION)->SetWindowText(_T("Tab Styles Settings"));
}
if (str == "Power User")
{
this->SetWindowText(_T("Power User Settings"));
GetDlgItem(IDC_SETTINGS_CAPTION)->SetWindowText(_T("Power User Settings"));
}
if (str == "Reset All Options")
{
this->SetWindowText(_T("Reset All Settings"));
GetDlgItem(IDC_SETTINGS_CAPTION)->SetWindowText(_T("Reset All Settings"));
}
*pResult = 0;
}
如图所示,您可以看到我能够将静态标题更改为从树中 select 编辑的“活动”页面节点。我正在寻求解决处理右侧 GUI 元素的最佳方法....
一些控件例如:
Color scheme Node: 5 check boxes for theme changing
Toolbars Node: Radio button for Docked or Floating
Power User Node: Checkbox to disable user warning within program operation
Tab Styles Node: Radio buttons to select flat, 3d, whatever.
当用户“selects”将它写入注册表时,我调用函数来读取数据等等......
这就是我所在的位置。有没有人对行动方案有任何建议,所以我不会把自己逼到墙角?
虽然我不能说出“Winamp”软件的作者是如何实现他们的 UI,但我建议您考虑使用 property sheet 作为您的案例,其中每组控件可以实现为单独的 属性 页面 ,每个页面都将以与单个模式对话框非常相似的方式定义(在资源脚本和 C++ 代码中)盒子。
'classic'属性sheet每一页都有水平排的标签(通常在sheet的顶部)到select,如下例所示。事实上,一些 sources/platforms 将 属性 sheet 称为“选项卡式对话框”。
但是,新的(大概)CMFCPropertySheet
class allows you to replace that tab control with one of several other options, which will show as separate 'panes' (on the left-hand side of the sheet). To use one of these alternative styles, call the SetLook()
member function in your constructor override with the CMFCPropertySheet::PropSheetLook_Tree
enum value. The example shown in the link 并不是完全 您在问题中显示的内容,而是 CMFCPropertySheet
和 CMFCPropertyPage
类 允许对它们的外观和样式进行很多很多自定义。
我从未实际使用过 PropSheetLook_Tree
样式,但下图显示了 PropSheetLook_OutlookBar
样式的“我之前制作的一个”。
在这种情况下,我并没有“被卡住”,而是在寻找一些 'guidance' 如何执行有意义且易于构建的 GUI 布局机制。我使用的 TreeControl
在视觉上与 Winamp 的 options/preferences 对话框的所有设置和程序选项“匹配”。
需要说明的是:这不是我曾经尝试过的事情,我正在寻找用户输入来帮助我越过终点线。
我在 'tree'('parent')和 5 'subitems' 中有 6 个项目。我已经完全构建好了,我可以从 selected 的任何节点获取数据(我将在图像下方 post)。
我正在使用“do.Modal 对话框”,当我单击树节点时,我希望对话框的右侧更新为该节点功能所需的控件。通过“显示”和“隐藏”来执行控件对我来说似乎很容易。我遇到的问题是当每个“节点分页”控件在 design time
期间可能会或可能不会在视觉上位于彼此之上时如何在资源编辑器中执行可视化“静态”控件。在 运行 期间,当每个节点在节点上 selected 时,控件将处于活动状态,但在设计期间,我可能会将控件放在彼此之上,这将是一个后勤噩梦试图整理他们的职位等
如何解决构建它的那个方面?我认为它是 select: 'node' show: 'option page controls' 所以我明白了逻辑;我只是想知道我是否应该有单独的“弹出”页面并调用它们……或者直接处理控件。这有意义吗?
我已经搜索了一些有关如何执行此操作的信息,但示例随处可见,我认为在这里提问最有意义。我确信有多种方法可以做到这一点,我只是在寻找最短的路径和最容易维护的方法,并可能在未来扩展选项。
我正在使用的对话框示例和源代码:
初始化代码如下:
BOOL CSettingsDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// TODO: Add extra initialization here
HTREEITEM hParent, hToolbars, hColorScheme, hTabStyles, hPowerUser,
hResetApp;
//HTREEITEM hCompany, hLevel, hLevelNext; // Used in core example, not needed here
hParent = m_TreeCtrl.InsertItem((L"Preferences"), TVI_ROOT);
hToolbars = m_TreeCtrl.InsertItem((L"Toolbars"), hParent);
hColorScheme = m_TreeCtrl.InsertItem((L"Color Scheme"), hParent);
hTabStyles = m_TreeCtrl.InsertItem((L"Tab Styles"), hParent);
hPowerUser = m_TreeCtrl.InsertItem((L"Power User"), hParent);
hResetApp= m_TreeCtrl.InsertItem((L"Reset All Options"), hParent);
m_TreeCtrl.Expand(hParent, TVE_EXPAND);
m_TreeCtrl.SelectItem(hParent);
GetDlgItem(IDC_SETTINGS_CAPTION)->SetWindowText(_T("Preferences Settings"));
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
这是我从头开始的对话框框架,只是为了到达这里:
void CSettingsDlg::OnTvnSelchangedTree1(NMHDR *pNMHDR, LRESULT *pResult)
{
//LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);
//SetDlgItemInt(IDC_TXT_TREE1, m_TreeCtrl.GetItemData(pNMTreeView->itemNew.hItem));
//*pResult = 0;
HTREEITEM sel = m_TreeCtrl.GetSelectedItem();
CPoint point;
CString str;
GetCursorPos(&point);
m_TreeCtrl.ScreenToClient(&point);
UINT flags = 0;
HTREEITEM hitItem = m_TreeCtrl.HitTest(point, &flags);
if (hitItem && sel != hitItem)
{
sel = hitItem;
m_TreeCtrl.SelectItem(sel);
str = m_TreeCtrl.GetItemText(sel);
//MessageBox((LPCTSTR)str); // Just to verify.
}
if (str == "Preferences")
{
this->SetWindowText(_T("Preferences Settings"));
GetDlgItem(IDC_SETTINGS_CAPTION)->SetWindowText(_T("Preferences Settings"));
}
if (str == "Toolbars")
{
this->SetWindowText(_T("Toolbars Settings"));
GetDlgItem(IDC_SETTINGS_CAPTION)->SetWindowText(_T("Toolbars Settings"));
}
if (str == "Color Scheme")
{
this->SetWindowText(_T("Color Scheme"));
GetDlgItem(IDC_SETTINGS_CAPTION)->SetWindowText(_T("Color Scheme Settings"));
}
if (str == "Tab Styles")
{
this->SetWindowText(_T("Tab Styles Settings"));
GetDlgItem(IDC_SETTINGS_CAPTION)->SetWindowText(_T("Tab Styles Settings"));
}
if (str == "Power User")
{
this->SetWindowText(_T("Power User Settings"));
GetDlgItem(IDC_SETTINGS_CAPTION)->SetWindowText(_T("Power User Settings"));
}
if (str == "Reset All Options")
{
this->SetWindowText(_T("Reset All Settings"));
GetDlgItem(IDC_SETTINGS_CAPTION)->SetWindowText(_T("Reset All Settings"));
}
*pResult = 0;
}
如图所示,您可以看到我能够将静态标题更改为从树中 select 编辑的“活动”页面节点。我正在寻求解决处理右侧 GUI 元素的最佳方法....
一些控件例如:
Color scheme Node: 5 check boxes for theme changing
Toolbars Node: Radio button for Docked or Floating
Power User Node: Checkbox to disable user warning within program operation
Tab Styles Node: Radio buttons to select flat, 3d, whatever.
当用户“selects”将它写入注册表时,我调用函数来读取数据等等......
这就是我所在的位置。有没有人对行动方案有任何建议,所以我不会把自己逼到墙角?
虽然我不能说出“Winamp”软件的作者是如何实现他们的 UI,但我建议您考虑使用 property sheet 作为您的案例,其中每组控件可以实现为单独的 属性 页面 ,每个页面都将以与单个模式对话框非常相似的方式定义(在资源脚本和 C++ 代码中)盒子。
'classic'属性sheet每一页都有水平排的标签(通常在sheet的顶部)到select,如下例所示。事实上,一些 sources/platforms 将 属性 sheet 称为“选项卡式对话框”。
但是,新的(大概)CMFCPropertySheet
class allows you to replace that tab control with one of several other options, which will show as separate 'panes' (on the left-hand side of the sheet). To use one of these alternative styles, call the SetLook()
member function in your constructor override with the CMFCPropertySheet::PropSheetLook_Tree
enum value. The example shown in the link 并不是完全 您在问题中显示的内容,而是 CMFCPropertySheet
和 CMFCPropertyPage
类 允许对它们的外观和样式进行很多很多自定义。
我从未实际使用过 PropSheetLook_Tree
样式,但下图显示了 PropSheetLook_OutlookBar
样式的“我之前制作的一个”。