提问人:Michaelinscarbororough 提问时间:11/13/2023 最后编辑:Michaelinscarbororough 更新时间:11/15/2023 访问量:121
TabControl 选项卡上的控件已禁用
control on TabControl tab is disabled
问:
更新-3这是解决方案:Minxin Yu 建议用指向“CMFCTabCtrl m_wndTab”控件的指针替换,而不是使用对窗体视图的引用。谢谢。对于代码,请比较我提供的答案。
Update-2:似乎所有 4 个标签页都删除了对话框标签页的标题栏。我在 InitialUpdaye 中使用的代码是:
m_wnd1.ModifyStyle(WS_CAPTION, 0);
m_wnd2.ModifyStyle(WS_CAPTION, 0);
m_wnd3.ModifyStyle(WS_CAPTION, 0);
m_wnd4.ModifyStyle(WS_CAPTION, 0);
Update-1:请注意,删除标题的代码位于 TabControlView 的 oninitialupdate 中.cpp,实现列表控件的代码位于 CPPL_4(.h 文件和 .cpp 文件中)。最后同样重要的是:请从下方提供的链接下载代码:https://github.com/microsoft/VCSamples/blob/master/VC2010Samples/MFC/Visual%20C%2B%2B%202008%20Feature%20Pack/TabControl/TabControlView.cpp。 谢谢。
我想实现以下目标:
有一个选项卡控件 (CTabCtrl),并在选项卡控件的每个选项卡上添加 1 个列表控件 (CListCtrl)。 列表控件通过数据库填充(1 个列表控件对应 1 个表)。在列表控件下,列是具有列表控件列宽度的编辑控件。这些是用于编辑列表控件的字段。
编辑控件下有一些操作按钮(包括删除、更新和添加记录集(列表控件中的行)以及向上/向下移动一行、上/下移动一页等。
由于这是我使用选项卡控件的第一个项目,因此我使用了此处的一些 MS 代码:
该解决方案很旧,在使用它时,Visual Studio 会将其转换为其 Visual Studio 解决方案的最新版本。代码正在工作。此示例程序的作者将“编辑”控件与选项卡控件一起使用,这意味着每个选项卡页都是一个编辑控件。操作记录发生在列表框中,通过按钮对选项卡控件进行视觉更改。
我更改了代码,以便选项卡页不是使用编辑控件,而是对话框(我使用了 CDialogEx)。
当我发现标题栏令人不安时,我在视图的 oninitialupdate 事件中使用程序代码将其删除。只要我没有将列表控件添加到标签页,这就可以工作。一旦我这样做了,标题就不是“可删除的”。列表控件位于选项卡 4 上。附上图像。
在第二个标签页标签二上,我添加了一个复选框。
这两个控件都无法访问(即我无法选中/取消选中复选框,当我尝试单击列表控件中的一行时没有显示任何选择,CCP_4.cpp文件末尾有一个单击事件代码,该代码永远不会到达(即书签永远不会停止执行!
我的目标是选项卡页 2 和 4 上的列表控件和复选框是可访问的,并且选项卡 4 中的标题栏应该消失,就像其他 3 个选项卡页一样。请帮忙。
我做了什么:
我使用了四个属性页(大)作为我的“对话框”。然后,我为每个对话框创建了类。对于第四个类(选项卡 4 的对话框),我添加了一个虚拟函数“OnInitialUpdate”,并在其中添加了列表控件代码。(请比较第三张图片。它包含对“添加资源”对话框以及“资源”对话框的说明,该对话框显示程序使用的对话框资源)
所有其他 4 个职业都是由 wizzard 类产生的。
以下是选项卡 4(类 CPPL_4)的代码,即 cpp 文件:
// CPPL_4.cpp : implementation file
//
#include "pch.h"
#include "stdafx.h"
#include "TabControl.h"
#include "afxdialogex.h"
#include "CPPL_4.h"
// CPPL_4 dialog
IMPLEMENT_DYNAMIC(CPPL_4, CDialogEx)
CPPL_4::CPPL_4(CWnd* pParent /*=nullptr*/)
: CDialogEx(IDD_PPL_4, pParent)
{
}
CPPL_4::~CPPL_4()
{
}
void CPPL_4::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
//DDX_Control(pDX, IDC_COLOR, m_list);
DDX_Control(pDX, IDC_LIST, m_list);
}
BEGIN_MESSAGE_MAP(CPPL_4, CDialogEx)
ON_WM_ACTIVATE()
ON_NOTIFY(NM_CLICK, IDC_LIST, &CPPL_4::OnClickList)
END_MESSAGE_MAP()
// CPPL_4 message handlers
BOOL CPPL_4::OnInitDialog()
{
CDialogEx::OnInitDialog();
m_list.InsertColumn(0, _T("Column 1"));
m_list.InsertColumn(1, _T("Column 2"));
m_list.SetColumnWidth(0, 200);
m_list.SetColumnWidth(1, 200);
m_list.InsertItem(0, _T(" 1 "));
m_list.InsertItem(1, _T(" 2 "));
m_list.SetItemText(0, 1, "11");
m_list.SetItemText(1, 1, "22");
return FALSE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
void CPPL_4::OnClickList(NMHDR* pNMHDR, LRESULT* pResult)
{
LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
// TODO: Add your control notification handler code here
m_list.SetFocus();
MessageBox("Got click event on list control!");
*pResult = 0;
}
下面是选项卡 4(类 CPPL_4)的代码,即 .h 文件:
#pragma once
#include "afxdialogex.h"
// CPPL_4 dialog
class CPPL_4 : public CDialogEx
{
DECLARE_DYNAMIC(CPPL_4)
public:
CPPL_4(CWnd* pParent = nullptr); // standard constructor
virtual ~CPPL_4();
// Dialog Data
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_PPL_4 };
#endif
protected:
// DDX/DDV support
virtual void DoDataExchange(CDataExchange* pDX);
DECLARE_MESSAGE_MAP()
public:
CListCtrl m_list;
virtual BOOL OnInitDialog();
afx_msg void OnClickList(NMHDR* pNMHDR, LRESULT* pResult);
};
其他 3 个选项卡的所有内容都相同,但虚拟 OnInitDialog 函数除外
这是我更新为最小骨架的表单视图文件;它应该概述我的问题:
#include "stdafx.h"
#include "TabControl.h"
#include "TabControlDoc.h"
#include "TabControlView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////
// CTabControlView
IMPLEMENT_DYNCREATE(CTabControlView, CFormView)
BEGIN_MESSAGE_MAP(CTabControlView, CFormView)
ON_WM_CONTEXTMENU()
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////
// CTabControlView construction/destruction
CTabControlView::CTabControlView()
: CFormView(CTabControlView::IDD)
{
}
CTabControlView::~CTabControlView()
{
}
void CTabControlView::DoDataExchange(CDataExchange* pDX)
{
CFormView::DoDataExchange(pDX);
DDX_Control(pDX, IDC_TAB, m_wndTabLoc);
//DDX_Control(pDX, IDC_STATIC_TABLOC, m_wndTabLoc);
}
BOOL CTabControlView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by
// modifying the CREATESTRUCT cs
return CFormView::PreCreateWindow(cs);
}
void CTabControlView::OnInitialUpdate()
{
// There is only one view ever, so it only needs to do
// the initial update once--otherwise the application is
// resized needlessly.
static BOOL bUpdatedOnce = FALSE;
if (bUpdatedOnce)
return;
bUpdatedOnce = TRUE;
CFormView::OnInitialUpdate();
GetParentFrame()->RecalcLayout();
if (m_wndTab.GetSafeHwnd () != NULL)
{
return;
}
CRect rectTab;
m_wndTabLoc.GetWindowRect (&rectTab);
ScreenToClient (&rectTab);
m_wndTab.Create (CMFCTabCtrl::STYLE_3D, rectTab, this, 1,
CMFCTabCtrl::LOCATION_TOP);
m_wnd1.Create(IDD_PPL_1, this);
// remove title bar of dialog
m_wnd1.ModifyStyle(WS_CAPTION, 0);
m_wnd2.Create(IDD_PPL_2, this);
// remove title bar of dialog
m_wnd2.ModifyStyle(WS_CAPTION, 0);
m_wnd3.Create(IDD_PPL_3, this);
// remove title bar of dialog
m_wnd3.ModifyStyle(WS_CAPTION, 0);
m_wnd4.Create(IDD_PPL_4, this);
// remove title bar of dialog
// This did not work out!!!!
m_wnd4.m_list.ModifyStyle(WS_CAPTION, 0);
m_wndTab.AddTab (&m_wnd1, _T("One"), 0, FALSE);
m_wndTab.AddTab (&m_wnd2, _T("Two"), 1, FALSE);
m_wndTab.AddTab (&m_wnd3, _T("Three"), 2, FALSE);
m_wndTab.AddTab (&m_wnd4, _T("Four"), 3, FALSE);
UpdateData (FALSE);
}
/////////////////////////////////////////////////////////////
// CTabControlView diagnostics
#ifdef _DEBUG
void CTabControlView::AssertValid() const
{
CFormView::AssertValid();
}
void CTabControlView::Dump(CDumpContext& dc) const
{
CFormView::Dump(dc);
}
CTabControlDoc* CTabControlView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CTabControlDoc)));
return (CTabControlDoc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////
// CTabControlView message handlers
void CTabControlView::OnContextMenu(CWnd*, CPoint point)
{
theApp.ShowPopupMenu (IDR_CONTEXT_MENU, point, this);
}
更新了 TabControlView.h
#pragma once
#include "CPPL_1.h"
#include "CPPL_2.h"
#include "CPPL_3.h"
#include "CPPL_4.h"
class CTabControlView : public CFormView
{
protected: // create from serialization only
CTabControlView();
DECLARE_DYNCREATE(CTabControlView)
public:
enum { IDD = IDD_TABCONTROL_FORM };
// Attributes
public:
CTabControlDoc* GetDocument();
protected:
CMFCTabCtrl m_wndTab;
// Operations
public:
CPPL_1 m_wnd1;
CPPL_2 m_wnd2;
CPPL_3 m_wnd3;
CPPL_4 m_wnd4;
// Overrides
public:
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
virtual void OnInitialUpdate(); // called first time after construct
// Implementation
public:
virtual ~CTabControlView();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
protected:
//void AddNotification (LPCTSTR lpszText);
protected:
afx_msg void OnContextMenu(CWnd*, CPoint point);
DECLARE_MESSAGE_MAP()
public:
//afx_msg void OnCbnSelchangeTabStyle();
//afx_msg void OnStnClickedTab();
CStatic m_wndTabLoc;
};
#ifndef _DEBUG // debug version in TabControlView.cpp
inline CTabControlDoc* CTabControlView::GetDocument()
{ return (CTabControlDoc*)m_pDocument; }
#endif
更新的 TabControlView.h 文件结束
答:
我想让你知道,俞敏欣想出了答案,我只想结束我的问题,因为我得到了我一开始要求的一切:
为什么有一个带有标题栏的选项卡式对话框页面,尽管标题栏样式 (WS_CAPTIOM) 已被删除:
有效的代码是:
m_wnd4.ModifyStyle(WS_CAPTION, 0);
其中 m_wnd4 是 CPPL_4 类型(请进一步比较代码)
为什么我无法访问选项卡式对话框中的控件?
这是俞敏欣的建议:
m_wnd1。创建(IDD_PPL_1, &m_wndTab);
其中原始代码有:
m_wnd1。创建(IDD_PPL_1,这个);
“this”是指向表单视图的指针,并且 &m_wndTab 是指向 MFCTabCtrl 类型的选项卡控件的指针。
请进一步查看完整代码!
感谢所有帮助过的人!!!
以下是代码,它实际上留下了一个悬而未决的问题,即: 为什么我必须从示例项目中复制控件才能获得选项卡式运行时控件。
void CTabControlView::OnInitialUpdate()
{
// There is only one view ever, so it only needs to do the initial
// update once--otherwise the application is resized needlessly.
static BOOL bUpdatedOnce = FALSE;
if (bUpdatedOnce)
return;
bUpdatedOnce = TRUE;
CFormView::OnInitialUpdate();
GetParentFrame()->RecalcLayout();
if (m_wndTab.GetSafeHwnd () != NULL)
return;
CRect rectTab;
m_wndTabLoc.GetWindowRect (&rectTab);
ScreenToClient (&rectTab);
m_wndTab.Create (CMFCTabCtrl::STYLE_3D, rectTab, this, 1, CMFCTabCtrl::LOCATION_TOP);
// MinXin Wu suggested to replace "this" by "&m_wndTab"
m_wnd1.Create(IDD_PPL_1, &m_wndTab);
// remove title bar of dialog
m_wnd1.ModifyStyle(WS_CAPTION, 0);
// MinXin Wu suggested to replace "this" by "&m_wndTab"
m_wnd2.Create(IDD_PPL_2, &m_wndTab);
// remove title bar of dialog
m_wnd2.ModifyStyle(WS_CAPTION, 0);
// MinXin Wu suggested to replace "this" by "&m_wndTab"
m_wnd3.Create(IDD_PPL_3, &m_wndTab);
// remove title bar of dialog
m_wnd3.ModifyStyle(WS_CAPTION, 0);
// MinXin Wu suggested to replace "this" by "&m_wndTab"
m_wnd4.Create(IDD_PPL_4, &m_wndTab);
// remove title bar of dialog
m_wnd4.ModifyStyle(WS_CAPTION, 0);
m_wndTab.AddTab (&m_wnd1, _T("One"), 0, FALSE);
m_wndTab.AddTab (&m_wnd2, _T("Two"), 1, FALSE);
m_wndTab.AddTab (&m_wnd3, _T("Three"), 2, FALSE);
m_wndTab.AddTab (&m_wnd4, _T("Four"), 3, FALSE);
UpdateData (FALSE);
}
CPPL_1 - CPPL_4类可以在问题中找到 这是表单视图的头文件!
// This is a part of the Microsoft Foundation Classes C++ library.
// Copyright (C) Microsoft Corporation
// All rights reserved.
//
// This source code is only intended as a supplement to the
// Microsoft Foundation Classes Reference and related
// electronic documentation provided with the library.
// See these sources for detailed information regarding the
// Microsoft Foundation Classes product.
#pragma once
#include "CPPL_1.h"
#include "CPPL_2.h"
#include "CPPL_3.h"
#include "CPPL_4.h"
class CTabControlView : public CFormView
{
protected: // create from serialization only
CTabControlView();
DECLARE_DYNCREATE(CTabControlView)
public:
enum { IDD = IDD_TABCONTROL_FORM };
// Attributes
public:
CTabControlDoc* GetDocument();
protected:
CMFCTabCtrl m_wndTab;
// Operations
public:
CPPL_1 m_wnd1;
CPPL_2 m_wnd2;
CPPL_3 m_wnd3;
CPPL_4 m_wnd4;
// Overrides
public:
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
virtual void OnInitialUpdate(); // called first time after construct
// Implementation
public:
virtual ~CTabControlView();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
protected:
//void AddNotification (LPCTSTR lpszText);
protected:
afx_msg void OnContextMenu(CWnd*, CPoint point);
DECLARE_MESSAGE_MAP()
public:
//afx_msg void OnCbnSelchangeTabStyle();
//afx_msg void OnStnClickedTab();
CStatic m_wndTabLoc;
afx_msg void OnStnClickedTab();
afx_msg void OnBnClickedButton1();
};
#ifndef _DEBUG // debug version in TabControlView.cpp
inline CTabControlDoc* CTabControlView::GetDocument()
{ return (CTabControlDoc*)m_pDocument; }
#endif
评论