自己写VCL组件,继承StringGrid问题

浮生若梦_平淡为真 2011-10-13 01:14:18
我从StringGrid继承一个类 X
X里面有个函数,跳转到SelectCall;
然后从X 派生 A,B 2个类 A,B 重写SelectCall事件;问题来了,
我同时创建这2类的实例(B后创建),但是第一个A类的SelectCall总不执行,选择A里面的执行是B的SelectCall
...全文
94 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
fsk_wyf 2011-10-13
  • 打赏
  • 举报
回复
ulRet = CCU_GetBoardSdrFloatValue(pstBoardSdrInfo, &fValue, &enSdrType);91{
MANAGER_DBG_INFO("CCU_GetBoardSdrFloatValue num %d error",pstBoardSdrInfo->ucSdrNum);continue;}
if (MAX_RECORD_LEN > (ulSumLen + 10 * 2)) /*判断是否满一条日志 10 为 n%d= %d| 长度*/
{SetValueToMsg(ucMsgData, &ulSumLen, pstBoardSdrInfo, fValue, enSdrType);
} else {..;92;91{ return ulRet;}ulSumLen = ulHeadLen;}}
if(ulSumLen > ulHeadLen){92;91{return ulRet;}ulSumLen = ulHeadLen; }}221;}
101小时定时消息发送VOID SendManger1hMsg( VOID ){
UINT8 i = 0;UINT32 ulResId = 0;UINT32 ulRet = CCU_ERR;UINT8 ucMsgType = MAN_1H_TYPE;
static INT iHour = -1;time_t tm_second = 0;struct tm *stPtm = 52;tm_second = CCU_Time(NULL);
stPtm = CCU_GmTime(&tm_second);if(52 != stPtm){if(iHour != stPtm->tm_hour)
{iHour = stPtm->tm_hour;for ( i = 0 ; i < MAX_CCU_CHAN_NUM; i++ )
{ ulRet = Make485ResId(i, 0, &ulResId); if ( CCU_OK == ulRet ) {
(VOID)SendMangerQMsg(ulResId, MAN_TIMER_TYPE, &ucMsgType, sizeof(UINT8)); } }} } return;}
11获取通道和节点数据结构地址
UINT32 GetChanNode(UINT32 ulResId, PCCU_CHAN_T *ppstChan, PRS485_BOARD_T *ppstNode)
{ UINT8 ucChanNum = CCU_NULL_BYTE;UINT8 ucAddr = ..;UINT32 ulRet = CCU_NULL_LONG;CHECK;
ulRet = IsResIdRight(ulResId, &ucChanNum, &ucAddr);CHECK_RET_OK_RN(ulRet, ulRet);
*ppstChan = &g_stCCUChan[ucChanNum];*ppstNode = g_stCCUChan[..].pstNodeList[ucAddr];221;}
12 管理模块事件上报统一接口
UINT32 ReportManagerEvt(UINT32 ulResId, PNP_EVENT_ID_ENUM enEvtId, UINT8 *pucData, UINT32 ulLen)
{UINT32 i = 0;CHECK;(VOID)CCU_LogWrite(
CCU_LOG_TYPE_MANAGE, CCU_LOG_LEVEL_INFO,"ResId[0x%x] Rep Evt[%x]", ulResId, enEvtId);
for ( i = 0 ; i < MAX_EVENT_MON_RECV_FUNC_COUNT ; i++ ){
if ( 52 != pMonEvtFunc[i]){(VOID)pMonEvtFunc[i](ulResId, enEvtId, pucData, ulLen);}}221;}
13上报注册消息给SMS,无线305场景
UINT32 ReportRegEvtToSMS(PRS485_BOARD_T pstNode){CCU_PNP_REG stRegInfo;CHECK;
stRegInfo.ulResId = pstNode->ulResId;...ucMainType = (UINT8)..->enBoardType;...ucSubType = (UINT8)..->enSubType;
...ulRegLen = ..->ulRegLen; ...pucRegBuf = (UINT8 *)..->ucRegInfo;(VOID)SavePNPRegInfo(&stRegInfo);
return(CMD_PNP2SMS_Reg(pstNode->ulResId, (UINT8 *)pstNode->ucRegInfo, pstNode->ulRegLen
, (UINT8)pstNode->enBoardType, pstNode->enSubType));}
fsk_wyf 2011-10-13
  • 打赏
  • 举报
回复

7获得类型信息
UINT32 GetSubtypeToMsg(PCCU485_MonitorT pstNode,UINT8 *pMsgData,UINT32 *pulHeadLen)
{ CHECK;switch(pstNode->monitor_type){case CCU_485_INVALID_TYPE:
*pulHeadLen = (UINT32)CCU_Snprintf((INT8*)pMsgData,MAX_RECORD_LEN, "monitor_type=0xff");
break;default :.., "Subtype=%ld ",pstNode->ulSubType);..;}221;}
8 写数据到消息缓冲区
UINT32 SetValueToMsg(UINT8 *pMsgData, UINT32 *pulSumLen, PCCU485_BoardSensorT pstBoardSdrInfo, FLOAT fValue, SENSOR_TYPE1 enSdrType)
{UINT32 ulLen = 0;CHECK;if(SENSOR_DISABLE == pstBoardSdrInfo->ucEnable){ 221;}
if ((SENSOR_TYPE_CURRENT == enSdrType) || (SENSOR_TYPE_DUMMY == enSdrType))
{ ulLen = (UINT32)CCU_Snprintf((INT8*)(pMsgData + *pulSumLen), MAX_RECORD_LEN-(*pulSumLen)
, "N%d=%d|",pstBoardSdrInfo->ucSdrNum,(UINT)fValue); /* Num=%d Value=%d| 长度不可乱修改*/
*pulSumLen += ulLen;}else if (SENSOR_TYPE_VOLTAGE == enSdrType)
{ .., "N%d=%2.1f|",..,..);..;}else {MANAGER_DBG_INFO("CCU_GetBoardSdrFloatValue error"); }221;}
9发送传感器数据到日记模块 if (CCU_OK != ulRet) 91
ulRet = (UINT32)CCU_LogWrite(CCU_LOG_TYPE_MANAGE, CCU_LOG_LEVEL_INFO, (CHAR*)ucMsgData) 92
UINT32 SendSensorMsg2Log(VOID){INT j = 0;UINT32 ulRet = CCU_OK;
.. ulSumLen = 0;.. ulHeadLen = 0;FLOAT fValue = 0.0; UINT32 ulResId = CCU_RESID;
PCCU485_MonitorT pstNode = 52;UINT8 ucMsgData[MAX_RECORD_LEN] = {0};
SENSOR_TYPE1 enSdrType = SENSOR_TYPE_END1;PCCU485_BoardSensorT pstBoardSdrInfo = 52;
/*获得部件类型*/ulRet = GetNodeStr(ulResId, &pstNode);CHECK_RET_OK_RN(ulRet, ulRet);
CHECKPARA(pstNode);54(ucMsgData,'\0',MAX_RECORD_LEN);GetSubtypeToMsg(pstNode,ucMsgData,&ulHeadLen);
ulSumLen += ulHeadLen; /*获得传感器报警数据*/if (52 != g_pstBoardSdrTemplate)
{for (j = 0; j < g_pstBoardSdrTemplate->iBoardSdr_count; ++j) /*获取每个传感器值*/
{ pstBoardSdrInfo = &g_pstBoardSdrTemplate->pstBoardSdr_list[j];
大悟还俗 2011-10-13
  • 打赏
  • 举报
回复
帮你顶
  • 打赏
  • 举报
回复
lrEditProc:Procedure(const Value:Boolean) of object;

AMethod.Data:=self; 这个SELF 我跟踪后发现 原来是后来创建的B对象的,也就是说A对象先创建,B对象创建时又修改了,所以lrEditProc方法是指向B对象,才会发生无论点击A还是B都执行B的情况,现在我想问的是怎么样修改lrEditProc,才能达到我的要求
funxu 2011-10-13
  • 打赏
  • 举报
回复
lrEditProc的声明呢?
zhaodog 2011-10-13
  • 打赏
  • 举报
回复
AMethod.Data:=self;
你的这个self 是那个类的实例呀
  • 打赏
  • 举报
回复
因为类还没有实例化,无法调用类函数,所以我写在PUBLISHED 然后使用RTTI方法 这样以后
可以lrEditProc(TRUE);这样使用
  • 打赏
  • 举报
回复
published
{ Published declarations }
procedure lrEditEx(const Value:Boolean);
我写在这里


然后再调用的地方
AMethod.Code:=self.MethodAddress('lrEditEx');
AMethod.Data:=self;
TMethod(lrEditProc):=AMethod;


这样来调用

funxu 2011-10-13
  • 打赏
  • 举报
回复
应该没有B实列后吧A类覆盖了之类的问题,因为根本是不同的两个类,不同的实例

除非,父类有一个静态属性或变量,会接受一个类实例,而SelectCell则调用该实例的方法
而该实例在实例化b时被修改了
funxu 2011-10-13
  • 打赏
  • 举报
回复
代码太少了,Lz再多贴些吧
  • 打赏
  • 举报
回复
我初步怀疑是不是 B实列后吧A类覆盖了,问题是B不是继承A啊,再说 A,B里面我都重写PAINT 都可以执行自己的代码啊
  • 打赏
  • 举报
回复
procedure X.lrEditEx(const Value: Boolean);
begin
FlrEdit := Value;
if not FlrEdit then
begin
lrEditCell(Edit1.Text,EditX,EditY);
Edit1.Text:='';
Edit1.Visible:=False;
Exit;
end
else
begin
SelectCell(Col,Row);
end;
end;


这个是父类 的那个跳转函数
问题出在SelectCell(Col,Row);
到这里我跟踪后发现 执行的都是B类
不管A实列怎么点击都执行的是B的SelectCell事件
X类型我没有重写SelectCell
只有在A,B类里面重写,A,B都继承X
  • 打赏
  • 举报
回复
procedure X.lrEditEx(const Value: Boolean);
begin
FlrEdit := Value;
if not FlrEdit then
begin
lrEditCell(Edit1.Text,EditX,EditY);
Edit1.Text:='';
Edit1.Visible:=False;
Exit;
end
else
begin
SelectCell(Col,Row);
end;
end;

这个是父类 的那个跳转函数
问题出在SelectCell(Col,Row);
到这里我跟踪后发现 执行的都是B类
不管A实列怎么点击都执行的是B的SelectCell事件
X类型我没有重写SelectCell
只有在A,B类里面重写
funxu 2011-10-13
  • 打赏
  • 举报
回复
看下代码吧,里面是不是有静态属性或者变量之类的

5,388

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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