代码创建的控件为什么不能显示出来呢?

cranium 2009-01-07 05:44:02
基于对话框的MFC程序

#using<System.dll>
#using<System.Drawing.dll>
#using<System.Windows.Forms.dll>
#include <vcclr.h>

using namespace System;

在DLG类定义中增加
gcroot<System::Windows::Forms::PropertyGrid^>* m_Prop;

在DLG类的OnInitDialog函数实现中增加
m_Prop = new gcroot<System::Windows::Forms::PropertyGrid^>;
*m_Prop = gcnew System::Windows::Forms::PropertyGrid();
(*m_Prop)->Location = System::Drawing::Point( 10, 10 );
(*m_Prop)->Size = System::Drawing::Size( 400, 400 );
(*m_Prop)->Visible = true;
(*m_Prop)->Show();

运行后没有出现我想要的PropertyGrid控件,怎么做才可以显示出来呢?
...全文
301 6 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
fhinalibob 2009-01-09
  • 打赏
  • 举报
回复
up
cranium 2009-01-08
  • 打赏
  • 举报
回复
To Tinary3v0:
是的,原先我也是使用CWinFormsControl来实现,MSDN里也说这种方式是MFC与窗体控件的结合使用。
而在实际使用中这种方式无法得到正确的结果,我才试着发了这篇帖子看看直接创建的话有没有可能实现。

对于CWinFormsControl的使用,我没有像你这样在OnInitDialog中添加这些代码,而是使用数据绑定DDX:
DDX_ManagedControl(pDx,ID_PGRID, m_PropGrid)

还有你说的缺少指令集,这个是什么意思呢?不是很明白什么是指令集(汇编里有这个的吧,CPU的指令集)?使用过程中我也没有遇到缺少什么的情况,程序编译都很正常,所写的代码也都正常执行了的,仅是无法出现预期结果。如果是少其他NET类的支持,那同样也可以使用gcroot将其包含进来的吧。

另外:我相信你的这种写法跟我使用DDX的这种方式在正常情况下都可以正常执行,至少我使用的DDX是可以被一个普通的单文档MFC程序正常使用的,只是现在我要做的是将这种东西用于CAD2007中,随着时间推移,我渐渐认为CAD2007不属于可以使我们代码正确执行的那种正常情况。

即便是正确的MFC程序,放在CAD2007下也是不能够正确执行,一定为出现致命错误。中间可能的原因是工程的编译不能按照正常的方式区做,还有一点是资源的切换问题。对于资源问题,在使用CWinFormsControl时,如果指定资源句柄不正确,即无法找到正确的资源时,会提示一个“遇到无效参数”,当使用这确的资源句柄时,遇到的将是致命错误。
cranium 2009-01-08
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 cranium 的回复:]
原先我说的在CAD2007下致命的为问题原因也明白了,与以上代码遇到的问题一样,是由于异常“未将对象引用到对象实例”而没有处理引起的。
只不过DDX的方式发生在DDX_ManagedControl中,CreateManagedControl的方式是发生在属性调用时。
[/Quote]
补充下:异常的产生是因为CWinFormsControl的方法GetControl()返回了无效的引用,导致在DDX_ManagedControl中使用它GetControl()->Handle出异常,而在OnInitDialog中则是pGrid->SelectedObject出现了异常。
cranium 2009-01-08
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 Tinary3v0 的回复:]
要知道在WinForm程序里面 是通过this->Controls->Add(this->propertyGrid1);将创建的PropertyGrid控件添加到窗体的。
MFC里面没有找到这个Add对应的方法。
[/Quote]
你说的这个确有同感,MFC里是没有这个的,不知道他用的那个Control容器是不是也可以gcroot过来,估计难,呵呵,现在说下我刚发现的一些东西。

Tinary3v0,我参考了你在一楼写的代码,并且使用它到我的项目,在单文档的MFC中一切正常,控件显示出来了,正如使用DDX得到的一样。同时我也将它使用到了CAD2007中,编译执行中也没有什么错误,仅仅是无法显示出控件。

然后我修改了你的代码,添加了一句设置SelectedObject属性的语句,代码如下:

BOOL C**Dlg::OnInitDialog()
{
CRect rect;
GetDlgItem(IDC_CTRL1)->GetWindowRect(rect); //IDC_CTRL1是一个用来占位的Static控件,就是添加一个ID为IDC_CTRL1的CStatic控件到对话框窗口上,并调整到你要的大小
GetDlgItem(IDC_CTRL1)->DestroyWindow();
ScreenToClient(rect);

m_Prop.CreateManagedControl( WS_VISIBLE|WS_CHILD, rect, this, IDC_CTRL1 ); //创建一个托管控件
System::Windows::Forms::PropertyGrid^ pGrid=m_Prop.GetControl(); //将托管控件托付给一个PropertyGrid对象

pGrid->SelectedObject = pGrid; //这里会报异常:未将对象引用设置到对象实例。貌似到了这里时CAD2007在pGrid还没有初始化,设置属性便出了错

return TRUE; // return TRUE unless you set the focus to a control
// 异常: OCX 属性页应返回 FALSE
}


以上的代码在单文档MFC中是正确的。

原先我说的在CAD2007下致命的为问题原因也明白了,与以上代码遇到的问题一样,是由于异常“未将对象引用到对象实例”而没有处理引起的。
只不过DDX的方式发生在DDX_ManagedControl中,CreateManagedControl的方式是发生在属性调用时。

现在应该可以说CAD2007下问题的原因就是PropertyGrid未能正确初始化而引起的吧(作为PropertyGrid载体的对话框在处理了异常后可以显示出来了,说明对话框资源已经正确找到)。

那现在的问题就是:原本可以正确执行的代码为什么在CAD2007下就无法正确初始化PropertyGrid控件了呢?
Tinary3v0 2009-01-08
  • 打赏
  • 举报
回复
CAD2007实在是不懂 你说的这些问题也的确是存在的 怎么直接创建也不清楚(我估计不太容易实现)

MFC里面有一个基本的原则 就是窗体创建的过程中要制定父窗口 即便是NULL也是指定的桌面。
下面这两句
m_Prop.CreateManagedControl( WS_VISIBLE|WS_CHILD, rect, this, IDC_CTRL1 );
DDX_ManagedControl(pDx,ID_PGRID, m_PropGrid)

其实就是做的这个工作 反正是都要有一个窗体控件来给PropertyGrid提供一个位置 这个位置同时也指明了父窗体
说白了就是你要把PropertyGrid添加到那个窗体上去。

看你最上面的代码,从一开始我就找怎么把直接创建的PropertyGrid添加到窗体里面去 但是没有找到相应的方法。

要知道在WinForm程序里面 是通过this->Controls->Add(this->propertyGrid1);将创建的PropertyGrid控件添加到窗体的。
MFC里面没有找到这个Add对应的方法。如果不解决这个问题 即便你创佳控件成功了 也肯定无法显示。因为控件都不知道那个是它的父窗体
也就不知道从那里接收 创建、显示 等消息。(仅供参考)

我说的指令集 实际就是命名空间 呵呵 说习惯了 哈哈

Tinary3v0 2009-01-08
  • 打赏
  • 举报
回复
楼主按照我的步骤来试试:
1.需要添加的Using指令集
#include <afxwinforms.h>// MFC Windows Forms support
#using <system.dll>
#using <Microsoft.VisualC.Dll>
#using <System.Drawing.dll>
#using <System.Windows.Forms.dll>
#using <mscorlib.dll>
using namespace System;
using namespace System::Drawing;
using namespace System::Windows::Forms;
using namespace System::ComponentModel;
using namespace Microsoft::VisualC::MFC;


2.头文件中定义:
CWinFormsControl<System::Windows::Forms::PropertyGrid> m_Prop;


3.初始化的时候:
BOOL C**Dlg::OnInitDialog()
{
CRect rect;
GetDlgItem(IDC_CTRL1)->GetWindowRect(rect); //IDC_CTRL1是一个用来占位的Static控件,就是添加一个ID为IDC_CTRL1的CStatic控件到对话框窗口上,并调整到你要的大小
GetDlgItem(IDC_CTRL1)->DestroyWindow();
ScreenToClient(rect);

m_Prop.CreateManagedControl( WS_VISIBLE|WS_CHILD, rect, this, IDC_CTRL1 ); //创建一个托管控件
System::Windows::Forms::PropertyGrid^ pGrid=m_Prop.GetControl(); //将托管控件托付给一个PropertyGrid对象
//......
}

4.详细请参考:http://blog.joycode.com/jiangsheng/archive/2005/03/22/46065.aspx

一开始我也是想用你的代码上改来实现 但是发现有好多东西不能用 主要是缺少指令集 楼主也可以在添加指令集以后 按照你的思路去试试。

15,980

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧