如何动态生成MSComm控件

choge 2011-01-04 10:47:37
新建一个工程,添加一个Unit2.代码如下:

Unit2.cpp
//---------------------------------------------------------------------------
#pragma hdrstop
#include "Unit2.h"
#include <vcl.h>
#pragma package(smart_init)
#pragma link "MSCommLib_OCX"
//---------------------------------------------------------------------------
Test test1;
//---------------------------------------------------------------------------
Test::Test()
{
CoInitialize(NULL);
MSComm1 = new TMSComm((void*)(0));
MSComm1->CommPort=1;
MSComm1->RThreshold=1;
MSComm1->Settings="9600,e,8,1";
MSComm1->InputMode=0;
}

Unit2.h
//---------------------------------------------------------------------------
#ifndef Unit2H
#define Unit2H
#include "MSCommLib_OCX.h"
#include <OleCtrls.hpp>
//---------------------------------------------------------------------------
class Test
{
public:
Test();
private:
TMSComm *MSComm1;
};
//---------------------------------------------------------------------------
extern PACKAGE Test test1;
//---------------------------------------------------------------------------
#endif

可以通过Build,但一运行就报错。如果去掉.h文件中的extern PACKAGE Test test1;
和.cpp文件中的Test test1;则可以运行

请各位帮忙分析解决
...全文
237 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
choge 2011-01-16
  • 打赏
  • 举报
回复
感谢BCBPLC,已解决
BCBPLC 2011-01-14
  • 打赏
  • 举报
回复
这次我编了一个多串口的数据采集,把串口通迅搞的很清楚了。就用MSCOMM32,
很好用。自动注册mscomm32.ocx的。
BCBPLC 2011-01-14
  • 打赏
  • 举报
回复
TMSComm *p=new TMSComm(this);
p->Parent=this;
p->InputMode=1; // 发送格式 0:文本 1:二进
p->RThreshold=1; // 让COM1产生接收事件
p->InputLen=0; // 每次接收的字符数
p->CommPort=port;
p->Settings=RS232->Text.Trim();
p->OnComm=MSComm1->OnComm; // 已经产生的事件

这是我的主要产生代码。事件产生的方法:
先放在一个MSCOMM1在桌面,双击事件产生事件方法:
写上注解,再删除刚产生的控件,这事件方法就静态产生了,
这属于Form1的一个方法,与MSCOMM1无关了。



BCBPLC 2011-01-14
  • 打赏
  • 举报
回复
#define RS232Count 21
TChannel * Channels[RS232Count];

void TForm1::InitModule() // 初始化
{
INIloaded=false;
CurDir=ExtractFilePath(Application->ExeName);
IniFile=ChangeFileExt(Application->ExeName,".INI");
ExeName=ChangeFileExt(ExtractFileName(Application->ExeName),"");
InRun=false;
TimerEnabled=false;
for (int i=0;i<RS232Count;i++)
Channels[i]=NULL;
}
bool TestRS232(int i) // 测试且打开某端口
{
bool stat=false;
TChannel *c=Channels[i];
if (c!=NULL)
{
TMSComm *p=c->mscomm;
if (!p->PortOpen) // 为假打开
try
{
p->PortOpen=true;
}
catch(...)
{
}
stat=p->PortOpen;
}
return(stat);
}
void TForm1::SetRS232(TMSComm *p,int port) // 仅设参数
{
p->InputMode=1; // 发送格式 0:文本 1:二进
p->RThreshold=1; // 让COM1产生接收事件
p->InputLen=0; // 每次接收的字符数
p->CommPort=port;
p->Settings=RS232->Text.Trim();
p->OnComm=MSComm1->OnComm;
}
void TForm1::NewRS232(int port) // 新建TMSComm
{
static bool first=true;
TChannel *c=new TChannel;
Channels[port]=c;
TMSComm *p;
if (first)
p=MSComm1;
else
p=new TMSComm(this);
p->Parent=this;
c->mscomm=p;
c->isIdle=true;
SetRS232(p,port);
bool yn=TestRS232(port);
if (first)
{
first=false;
RS232Stat->Caption=yn?"正常":"异常";
}
}
bool OpenRS232(int port) // 打开或创建端口,
{
bool stat=false;
if (port>=0 && port<RS232Count)
{
TChannel *c=Channels[port];
if (c==NULL)
{
Form1->NewRS232(port); // New时打开口一次
c=Channels[port];
}
stat=c->mscomm->PortOpen; // 非NEW保持不变
}
return(stat);
}
bool TestIdle(int port) // 通道是否空闭
{
return(Channels[port]->isIdle);
}

这是我用MSCOMM的一个片断,我同时用的串口较多,所以,MSCOmm控件在一个数组中。



choge 2011-01-14
  • 打赏
  • 举报
回复
感谢BCBPLC的回复。
我试了一下,在有静态产生的窗体上,确实可以动态生成MSComm。但在新建的Unit上运行就会出错,即使在Unit上动态创建一个窗体,将MSComm动态创建于此窗体中,同样会出错
choge 2011-01-12
  • 打赏
  • 举报
回复
真的没法解决了吗
BCBPLC 2011-01-06
  • 打赏
  • 举报
回复
我用动态生成的N个 MSCOMM32.ocx 没出问题。
RedProgramer 2011-01-06
  • 打赏
  • 举报
回复
那你最好看一下TMSComm的帮助,估计是没有生成该对象,所以对对象进行操作出问题;最好在操作该对象以前先判断一下该对象是否建立成功
choge 2011-01-06
  • 打赏
  • 举报
回复
BCBPLC能添个代码参考一下吗
choge 2011-01-05
  • 打赏
  • 举报
回复
感谢妖哥热心回复
我改成下面这样还是不行

Unit1.cpp
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
#include "Unit2.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
test1 = new TEST;
}

Unit1.h
//---------------------------------------------------------------------------
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include "Unit2.h"
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE-managed Components
private: // User declarations
TEST *test1;
public: // User declarations
__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif

//---------------------------------------------------------------------------
ccrun.com 2011-01-05
  • 打赏
  • 举报
回复
Unit1.cpp文件中

这一行:
TEST test1;

我不是跟你说了去掉这一行么?

choge 2011-01-05
  • 打赏
  • 举报
回复
请各位指教
choge 2011-01-05
  • 打赏
  • 举报
回复
unit1.cpp
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
#include "Unit2.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
TEST test1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------

unit2.cpp
//---------------------------------------------------------------------------
#pragma hdrstop
#include "Unit2.h"
#pragma link "MSCommLib_OCX"
//---------------------------------------------------------------------------

#pragma package(smart_init)
//TEST test1;

TEST::TEST()
{
CoInitialize(NULL);
MSComm1 = new TMSComm((void*)(0));
MSComm1->CommPort=1;
MSComm1->RThreshold=1;
MSComm1->Settings="9600,e,8,1";
MSComm1->InputMode=0;
}

unit2.h
//---------------------------------------------------------------------------
#ifndef Unit2H
#define Unit2H
#include "MSCommLib_OCX.h"
#include <OleCtrls.hpp>
//---------------------------------------------------------------------------
class TEST
{
public:
TEST();
protected:
private:
TMSComm *MSComm1;
};
//extern PACKAGE TEST test1;
#endif
choge 2011-01-05
  • 打赏
  • 举报
回复
出错信息:
Project project1.exe raised exception class EAccessViolation with message'Access
violation at adress 4016f4e8 in module 'vcl60.bpl'.Read of adress 00000000'.Process
stopped.Use Step or Run to Continue

如果改成这样这正常
Test::Test()
{
CoInitialize(NULL);
MSComm1 = new TMSComm((void*)(0));
//MSComm1->CommPort=1;
//MSComm1->RThreshold=1;
//MSComm1->Settings="9600,e,8,1";
//MSComm1->InputMode=0;
}
ccrun.com 2011-01-05
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 choge 的回复:]
用CCRUN的方法也不行,实例化就出问题。
[/Quote]

贴完整调用代码出来。
fxworld 2011-01-05
  • 打赏
  • 举报
回复
连出错信息都不给出?
choge 2011-01-05
  • 打赏
  • 举报
回复
用CCRUN的方法也不行,实例化就出问题。
RedProgramer 2011-01-05
  • 打赏
  • 举报
回复
我估计是在这里出的问题,你可以跟踪一下
Test::Test()
{
CoInitialize(NULL);
MSComm1 = new TMSComm((void*)(0));
MSComm1->CommPort=1;
MSComm1->RThreshold=1;
MSComm1->Settings="9600,e,8,1";
MSComm1->InputMode=0;
}
ccrun.com 2011-01-04
  • 打赏
  • 举报
回复
继承自VCL的组件类或者在自定义类中要动态生成VCL对象,建议用new的方式创建,如:
去掉.h文件中的extern PACKAGE Test test1和.cpp文件中的Test test1;
在需要调用的单元中,声明一个Test *test1对象,然后在程序的初始化中test1 = new Test; 程序结束时释放资源:delete test1;

1,315

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder 网络及通讯开发
社区管理员
  • 网络及通讯开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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