莆仙生活网
当前位置: 莆仙生活网 > 知识库 >

colevariant

时间:2024-03-27 09:34:13 编辑:莆仙君

MFC在自己定义的头文件中如何引用对话框自己生成的头文件?对话框引用对话框的头文件就不错

这个一点都不扯。。。
系统自己生成的,同样需要声明的支持,只不过,在MFC框架里面,这些支持是给你写好的。
比如那个ID,是在resource.h中定义的。
一般来说,在自定义头文件中使用对话框类,比较合理和安全的办法,就是将对话框类cpp文件首部全部的包含include,按照原有顺序全部复制过来,放在自定义的CPP文件首部,并且在包含自定义头文件之前。(注意,是放在CPP文件,而不是.H文件),并且,在每个使用自定义头文件的地方,都使用这个包含顺序。
这样的好处,就是不会产生重复包含和相互包含的问题。当然也可以写在.H文件中,同样要保证,在包含对话框.H之前有其它必要的包含文件。


COleVariant是什么数据类型

用于ole自动化的VARRANT类型,可以用于存储多种格式





COleVariant 类通逢装了 VARIANT 结构。实际的数据就在 VARIANT 结构中。

VARIANT 结构包含两部分。其一是 VARTYPE 型的成员变量vt;其二是个联合类型,这个联合包含了VC常用的几乎所有类型。因为联合用的是相同的存储空间,因此对联合的内容的解释依赖于 vt。
例如,
若 vt 的值是 VT_UI2, 说明该联合被解释为short int. 并使用成员变量名 iVal。
若 vt 的的值是 VT_BSTR,说明该联合被解释为 BSTR 类型。并使用成员变量名 bstrVal。
若 vt 的的值是 VT_BSTR|VT_BYREF,说明该联合被解释为BSTR 型指针。并使用成员变量名 pbstrVal

Example:
------------------
VARIANT va;
:: VariantInit(&va); // 初始化
int a = 2002;
va.vt = VT_I4; // 指明long数据类型
va.lVal = a; // 赋值
--------------------------------
  为了方便处理VARIANT类型的变量,Windows还提供了这样一些非常有用的函数:

  VariantInit —— 将变量初始化为VT_EMPTY;

  VariantClear —— 消除并初始化VARIANT;

  VariantChangeType —— 改变VARIANT的类型;

  VariantCopy —— 释放与目标VARIANT相连的内存并复制源VARIANT。


COleVariant 具体如何用,有什么功能?

  COleVariant类是对VARIANT结构的封装。
  VARIANT 结构包含两部分。其一是 VARTYPE 型的成员变量vt;其二是个联合类型,这个联合包含了VC常用的几乎所有类型。因为联合用的是相同的存储空间,因此对联合的内容的解释依赖于 vt。
  例如,
  若 vt 的值是 VT_UI2, 说明该联合被解释为short int. 并使用成员变量名 iVal。
  若 vt 的的值是 VT_BSTR,说明该联合被解释为 BSTR 类型。并使用成员变量名 bstrVal。
  若 vt 的的值是 VT_BSTR|VT_BYREF,说明该联合被解释为BSTR 型指针。并使用成员变量名 pbstrVal。
  它的构造函数具有极为强大的功能,当对象构造时首先调用VariantInit进行 初始化,然后根据参数中的标准类型调用相应的构造函数,并使用VariantCopy进行转换赋值操作,当VARIANT对象不在有效范围时,它的析构函 数就会被自动调用,由于析构函数调用了VariantClear,因而相应的内存就会被自动清除。除此之外,COleVariant的赋值操作符在与 VARIANT类型转换中为我们提供极大的方便。


ColeVariant需要引用那个头文件?mfc问题

ColeVariant需要引用 #include 细节如下:COleVariant类是对VARIANT结构的封装。VARIANT 结构包含两部分。其一是 VARTYPE 型的成员变量vt;其二是个联合类型,这个联合包含了VC常用的几乎所有类型。因为联合用的是相同的存储空间,因此对联合的内容的解释依赖于 vt。COleVariant 本质上是一个枚举,用同一种类型来表达不同的子类型。如同boost中的variant。 

如何用VC6.0实现串口控件编程

首先创建一个VC6.0基于对话框的程序,然后在资源视图中,Project --- > Add To Project ---> compoents and controls...,如下图所示

在弹出的窗口选择“Registered ActiveX Controls”,双击进入该文件夹,如下图所示

在列表中找到“Microsoft Communications Control, version 6.0”,点击“Insert”按钮,如下图所示

接下来就会在资源视图中看到一个电话图标,如下图所示

右键该电话图标,选择“ClassWizard...”,如下图所示

在Member Variables下为该控件添加一个控件变量,如下图所示

在Message Maps下为该控件添加OnComm消息,如下图所示

在OnInitDialog()函数中,加入窗口控件初始化函数,如下图所示

在OnComm() 函数中,加入串口消息处理函数,处理串口接收的数据,如下图所示


vc++串口编程

例程1

打开VC++6.0,新建基于对话框的工程RS485Comm,在主对话框窗口IDD_RS485COMM_DIALOG上添加两个按钮,ID分别为IDC_SEND和IDC_RECEIVE,标题分别为“发送”和“接收”;添加一个静态文本框IDC_DISP,用于显示串口接收到的内容。

在RS485CommDlg.cpp文件中添加全局变量:

HANDLE hCom; //全局变量,串口句柄

在RS485CommDlg.cpp文件中的OnInitDialog()函数添加如下代码: // TODO: Add extra initialization here
hCom=CreateFile("COM1",//COM1口
GENERIC_READ|GENERIC_WRITE, //允许读和写
0, //独占方式
NULL,
OPEN_EXISTING, //打开而不是创建
0, //同步方式
NULL);
if(hCom==(HANDLE)-1)
{
AfxMessageBox("打开COM失败!");
return FALSE;
}

SetupComm(hCom,100,100); //输入缓冲区和输出缓冲区的大小都是1024

COMMTIMEOUTS TimeOuts;
//设定读超时
TimeOuts.ReadIntervalTimeout=MAXDWORD;
TimeOuts.ReadTotalTimeoutMultiplier=0;
TimeOuts.ReadTotalTimeoutConstant=0;
//在读一次输入缓冲区的内容后读操作就立即返回,
//而不管是否读入了要求的字符。


//设定写超时
TimeOuts.WriteTotalTimeoutMultiplier=100;
TimeOuts.WriteTotalTimeoutConstant=500;
SetCommTimeouts(hCom,&TimeOuts); //设置超时

DCB dcb;
GetCommState(hCom,&dcb);
dcb.BaudRate=9600; //波特率为9600
dcb.ByteSize=8; //每个字节有8位
dcb.Parity=NOPARITY; //无奇偶校验位
dcb.StopBits=TWOSTOPBITS; //两个停止位
SetCommState(hCom,&dcb);

PurgeComm(hCom,PURGE_TXCLEAR|PURGE_RXCLEAR);

分别双击IDC_SEND按钮和IDC_RECEIVE按钮,添加两个按钮的响应函数: void CRS485CommDlg::OnSend()
{
// TODO: Add your control notification handler code here
// 在此需要简单介绍百特公司XMA5000的通讯协议:
//该仪表RS485通讯采用主机广播方式通讯。
//串行半双工,帧11位,1个起始位(0),8个数据位,2个停止位(1)
//如:读仪表显示的瞬时值,主机发送:DC1 AAA BB ETX
//其中:DC1是标准ASCII码的一个控制符号,码值为11H(十进制的17)
//在XMA5000的通讯协议中,DC1表示读瞬时值
//AAA是从机地址码,也就是XMA5000显示仪表的通讯地址
//BB为通道号,读瞬时值时该值为01
//ETX也是标准ASCII码的一个控制符号,码值为03H
//在XMA5000的通讯协议中,ETX表示主机结束符

char lpOutBuffer[7];
memset(lpOutBuffer,''\0'',7); //前7个字节先清零
lpOutBuffer[0]=''\x11''; //发送缓冲区的第1个字节为DC1
lpOutBuffer[1]=''0''; //第2个字节为字符0(30H)
lpOutBuffer[2]=''0''; //第3个字节为字符0(30H)
lpOutBuffer[3]=''1''; // 第4个字节为字符1(31H)
lpOutBuffer[4]=''0''; //第5个字节为字符0(30H)
lpOutBuffer[5]=''1''; //第6个字节为字符1(31H)
lpOutBuffer[6]=''\x03''; //第7个字节为字符ETX
//从该段代码可以看出,仪表的通讯地址为001
DWORD dwBytesWrite=7;
COMSTAT ComStat;
DWORD dwErrorFlags;
BOOL bWriteStat;
ClearCommError(hCom,&dwErrorFlags,&ComStat);
bWriteStat=WriteFile(hCom,lpOutBuffer,dwBytesWrite,& dwBytesWrite,NULL);
if(!bWriteStat)
{
AfxMessageBox("写串口失败!");
}

}
void CRS485CommDlg::OnReceive()
{
// TODO: Add your control notification handler code here

char str[100];
memset(str,''\0'',100);
DWORD wCount=100;//读取的字节数
BOOL bReadStat;
bReadStat=ReadFile(hCom,str,wCount,&wCount,NULL);
if(!bReadStat)
AfxMessageBox("读串口失败!");
PurgeComm(hCom, PURGE_TXABORT|
PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);
m_disp=str;
UpdateData(FALSE);

}

您可以观察返回的字符串,其中有和仪表显示值相同的部分,您可以进行相应的字符串操作取出仪表的显示值。
打开ClassWizard,为静态文本框IDC_DISP添加CString类型变量m_disp,同时添加WM_CLOSE的相应函数: void CRS485CommDlg::OnClose()
{
// TODO: Add your message handler code here and/or call default
CloseHandle(hCom); //程序退出时关闭串口
CDialog::OnClose();
}

程序的相应部分已经在代码内部作了详细介绍。连接好硬件部分,编译运行程序,细心体会串口同步操作部分。


MFC读写EXCEL时,如何获取当前行号,列号,如何向指定的单元格写数据?

//通过OLE实现,获取当前活动单元格行号与列号
Range range=objApp.GetActiveCell();//objApp 为_Application类对象
long RowNum=range.GetRow();//获取行号
long ColNum=range.GetColumn();//获取列号
range.SetValue2(COleVariant("HELLO EXCEL!"));//向当前活动单元格写入HELLO EXCEL!


实现无符号整数到16进制表示字符串的转换,要求不能调用任何函数。程序如下,求注释,越详细越好。

#include
void intToHex(int n, char* s)
{
int temp = 0; 一个局部变量,保存变换的中间结果
char t[128]; 临时变量,记录变换结果
int index = 0; 记录目前操作字符串的当前位置,开始为0
while(n) 如果n不等于0,则继续循环
{
temp = n % 16; temp等于n除以16后的余数
if(temp > 9) 如果余数大于9
{
*(t + index++) = 'A' + temp - 10; 如果temp=10,则当前位置=A,11为B,12为C,13为D,14为E,15为F ,同时index+1,指向字符串操作的下一位 如果你知道ASCII码表,会很容易理解,如果不知道,那你必须学习一下。不懂ASCII是不可能学好编程的
}
else 如果不大于9
{
*(t + index++) = '0' + temp; 那么这位是多少就向字符串中写入,多少同时index+1,指向字符串操作的下一位。这个也和ASCII有关
}
n /= 16; 用n除以16,然后把商赋给n
} 当n等于0时,循环结束,index中记录了字符串的长度
*(t + index) = '\0'; 在当前位置写入字符串结束标记
int j = 0;
for(int i = index - 1; i >= 0; --i) 循环,把变换结果的每个字符赋给s,用于返回给main函数
{
*(s + j++) = *(t + i);
}
*(s + j) = '\0';
}
int main(void)
{
char s[128]; 声明一个字符串,用于保存结果
int n; 整形变量,用于保存输入数据
printf("Input a unsigned integer: "); 屏幕上显示提示输入
scanf("%d", &n); 用键盘输入一个整数,并存入变量n
intToHex(n, s); 把n中的整数变成16进制字符串,并把结果存入字符串s
printf("Your input: %s\n", s); 显示变换结果
return 0;
}
这个程序还有一个漏洞,就是在调用intToHex前应判断输入的整数应大于0,因为该算法是转换整数的。