📄 resource.c
字号:
/***************************************************************************** ------------ 子系统名称: 界面资源管理器* RESOURCE.C* ------------ 模块名称 : 资源核心管理程序** 包括以下函数:* 1. short NewResource ( PRESOURCE *pprNew, short nCount )* 2. short FreeResource ( short nRESID )** 3. short CreatRESFile ( char * pFileName )* 4. short OpenRESFile ( char *pFileName )* 5. short CloseRESFile ( BOOL nWriteHead )** 6. short LoadResource ( short nRESID, void **ppRES )* 7. short AppendResource ( PRESOURCE prTemp )****************************************************************************/#include "resource.h"/***************************************************************************** 全局变量定义****************************************************************************/FILE * pfRESFile; /* 资源文件指针 */RESFILEHEAD rfhRESFileHead; /* 资源文件头 */PRESOURCE prRESTable; /* 资源索引表 */char pRESVersion[MAXL_VERTEXT] = /* 标准版本信息 */ "PC-TMCS V1.0 RES\n";/***************************************************************************** 函数原型: NewResource ( PRESOURCE *prNew, short nCount )** 功 能: 创建 nCount 个资源索引项** 编程人员: Zhu haibin** 编码时间: 1994/09/13** 修改时间:** 入口参数: PRESOURCE prNew -- 资源项指针** 出口参数: OK 调用成功* ERR_NOMEMORY 没有足够的内存** 实现算法: 调用 malloc 申请内存** 上层调用:** 下层调用:****************************************************************************/short NewResource ( PRESOURCE *pprNew, short nCount ){ if ( ( (*pprNew) = (PRESOURCE)malloc ( nCount * sizeof ( RESOURCE ) ) ) == (PRESOURCE)NULL ) return ( ERR_NOMEMORY ); return ( OK );}/***************************************************************************** 函数原型: FreeResource ( short nRESID )** 功 能: 释放一个资源** 编程人员: Zhu haibin** 编码时间: 1994/09/13** 修改时间:** 入口参数: PRESOURCE presTemp -- 资源项指针** 出口参数: OK 调用成功* ERR_RES_INVALIDID 无效的资源标识号** 实现算法: 1. 查找指定的标识号* 2. 释放所对应的资源** 上层调用:** 下层调用: FreeMenu* FreeDialog****************************************************************************/short FreeResource ( short nRESID ){ short i; /* 查找指定的标识号 */ for ( i = 0; i < rfhRESFileHead.nCount; i++ ) if ( prRESTable[i].nRESID == nRESID ) break; /* 无效的标识号 */ if ( i >= rfhRESFileHead.nCount ) return ( ERR_RES_INVALIDID ); if ( prRESTable[i].pRES != (void*)NULL ) { switch ( prRESTable[i].nType ) { case RT_STRTBL : FreeStringTable ( (PSTRTBL)prRESTable[i].pRES ); break; case RT_MENU : FreeMenu ( (PMENU)prRESTable[i].pRES ); break; case RT_DIALOG : FreeDialog ( (PDIALOG)prRESTable[i].pRES ); break; } } return ( OK );}/***************************************************************************** 函数原型: short CreatRESFile ( char * pFileName )** 功 能: 创建一个资源文件** 编程人员: Zhu haibin** 编码时间: 1994/09/14** 修改时间:** 入口参数: char *pFileName -- 资源文件名** 出口参数: OK 调用成功* ERR_CFILE 创建文件错** 实现算法: 调用 fopen 创建文件** 上层调用:** 下层调用: 无****************************************************************************/short CreatRESFile ( char * pFileName ){ /* 创建文件 */ if ( ( pfRESFile = fopen ( pFileName, "wb" ) ) == (FILE*)NULL ) return ( ERR_CFILE ); /* 拷贝标准版本信息 */ strcpy ( rfhRESFileHead.pVersion, pRESVersion ); rfhRESFileHead.nCount = 0; rfhRESFileHead.nAddNum = 0; /* 写资源文件头 */ fseek ( pfRESFile, 0, SEEK_SET ); if ( fwrite ( (void*)&rfhRESFileHead, sizeof ( RESFILEHEAD), 1, pfRESFile ) != 1 ) return ( ERR_WFILE ); return ( OK );}/***************************************************************************** 函数原型: OpenRESFile ( char *pFileName )** 功 能: 打开一个已存在的资源文件, 检查其合法性, 读入资源索引** 编程人员: Zhu haibin** 编码时间: 1994/09/14** 修改时间:** 入口参数: char *pFileName -- 资源文件名** 出口参数: OK 调用成功* ERR_OFILE 打开文件失败* ERR_RFILE 读文件失败** 实现算法: 1. 以只读方式打开文件* 2. 读入文件头并检查其合法性* 3. 读入资源索引** 上层调用:** 下层调用: NewResource****************************************************************************/short OpenRESFile ( char *pFileName ){ short i; BYTE nAddNum; short nErrorID; /* 打开文件 */ if ( ( pfRESFile = fopen ( pFileName, "rb" ) ) == (FILE*)NULL ) return ( ERR_OFILE ); /* 读文件头 */ if ( fread ( (void*)&rfhRESFileHead, sizeof ( RESFILEHEAD ), 1, pfRESFile ) != 1 ) return ( ERR_RFILE ); /* 计算累加和 */ for ( i = nAddNum = 0; i < sizeof ( RESFILEHEAD ); i++ ) nAddNum += ((BYTE *)&rfhRESFileHead)[i]; /* 非法资源文件 */ if ( nAddNum != 0 ) return ( ERR_RES_INVALIDFILE ); /* 申请资源索引表内存 */ if ( NewResource ( &prRESTable, rfhRESFileHead.nCount ) < OK ) return ( ERR_NOMEMORY ); /* 读资源索引表 */ for ( i = 0; i < rfhRESFileHead.nCount; i++ ) { if ( fread ( (void*)&prRESTable[i], sizeof ( RESOURCE ), 1, pfRESFile ) != 1 ) { nErrorID = ERR_RFILE; break; } fseek ( pfRESFile, prRESTable[i].lNextOffset, SEEK_SET ); } if ( i < rfhRESFileHead.nCount ) return ( nErrorID ); /* 装入所有字符串表资源 */ LoadStrTblResource (); return ( OK );}/***************************************************************************** 函数原型: CloseRESFile ( BOOL nWriteHead )** 功 能: 关闭资源文件** 编程人员: Zhu haibin** 编码时间: 1994/09/14** 修改时间:** 入口参数: BOOL nWriteHead -- 是否需要重新写入文件头** 出口参数: OK 调用成功* ERR_WFILE 写文件失败** 实现算法: 1. 如果要重写文件头:* A 调整文件, 使文件头部空出文件头和索引表的空间* B 计算累加和* C 写入文件头* 2. 调用 fclose 关闭文件** 上层调用:** 下层调用: 无****************************************************************************/short CloseRESFile ( BOOL nWriteHead ){ short i; BYTE nAddNum; /* 如果要写文件头 */ if ( nWriteHead ) { /* 计算累加和 */ rfhRESFileHead.nAddNum = 0; for ( i = nAddNum = 0; i < sizeof ( RESFILEHEAD ) - 1; i++ ) nAddNum += ((BYTE *)&rfhRESFileHead)[i]; rfhRESFileHead.nAddNum = ~nAddNum + 1; /* 写资源文件头 */ fseek ( pfRESFile, 0, SEEK_SET ); if ( fwrite ( (void*)&rfhRESFileHead, sizeof ( RESFILEHEAD), 1, pfRESFile ) != 1 ) return ( ERR_WFILE ); } /* 关闭资源文件 */ fclose ( pfRESFile ); return ( OK );}/***************************************************************************** 函数原型: LoadResource ( short nRESID, void **ppRES )** 功 能: 从资源文件中读取标识号为 nRESID 的资源** 编程人员: Zhu haibin** 编码时间: 1994/09/15** 修改时间:** 入口参数: short nRESID 资源标识号* void **ppRES 资源地址** 出口参数: OK 调用成功, 资源指针返回在 ppRES 中* ERR_RES_INVALIDID 无效的资源识别号* ERR_RFILE 读文件失败* ERR_NOMEMORY 没有足够的内存** 实现算法: 1. 在资源索引表中查找指定的识别号 nRESID* 2. 读出资源** 上层调用:** 下层调用: 无****************************************************************************/short LoadResource ( short nRESID, void **ppRES ){ short i; /* 在资源索引表中查找指定标识号的资源索引项 */ for ( i = 0; i < rfhRESFileHead.nCount; i++ ) if ( prRESTable[i].nRESID == nRESID ) break; if ( i >= rfhRESFileHead.nCount ) return ( ERR_RES_INVALIDID ); switch ( prRESTable[i].nType ) { case RT_MENU : if ( i == 0 ) fseek ( pfRESFile, sizeof (RESFILEHEAD) + sizeof (RESOURCE), SEEK_SET ); else fseek ( pfRESFile, prRESTable[i].lRESOffset, SEEK_SET ); LoadMenu ( (PMENU*)&prRESTable[i].pRES, pfRESFile ) ; break; case RT_DIALOG : if ( i == 0 ) fseek ( pfRESFile, sizeof ( RESFILEHEAD ) + sizeof ( RESOURCE ), SEEK_SET ); else fseek ( pfRESFile, prRESTable[i].lRESOffset, SEEK_SET ); LoadDialog ( (PDIALOG*)&prRESTable[i].pRES, pfRESFile ); break; } (*ppRES) = prRESTable[i].pRES; return ( OK );}/***************************************************************************** 函数原型: AppendResource ( PRESOURCE prTemp )** 功 能: 向资源文件中追加一个资源** 编程人员: Zhu haibin** 编码时间: 1994/09/15** 修改时间:** 入口参数: PRESOURCE prTemp -- 资源指针** 出口参数: OK 调用成功* ERR_WFILE 写文件失败** 实现算法: 1. 写入资源索引项* 2. 写入资源数据** 上层调用:** 下层调用: 无****************************************************************************/short AppendResource ( PRESOURCE prTemp ){ /* 将文件指针移到文件尾 */ fseek ( pfRESFile, 0, SEEK_END ); prTemp->lRESOffset = ftell ( pfRESFile ) + sizeof ( RESOURCE ); switch ( prTemp->nType ) { case RT_STRTBL : prTemp->lNextOffset = prTemp->lRESOffset + StringTableSize ( (PSTRTBL)prTemp->pRES ); if ( fwrite ( prTemp, sizeof ( RESOURCE ), 1, pfRESFile ) != 1 ) return ( ERR_WFILE ); return ( SaveStringTable ( (PSTRTBL)prTemp->pRES, pfRESFile ) ); case RT_MENU : prTemp->lNextOffset = prTemp->lRESOffset + MenuSize ( (PMENU)prTemp->pRES ); if ( fwrite ( prTemp, sizeof ( RESOURCE ), 1, pfRESFile ) != 1 ) return ( ERR_WFILE ); return ( SaveMenu ( (PMENU)prTemp->pRES, pfRESFile ) ); case RT_DIALOG : prTemp->lNextOffset = prTemp->lRESOffset + DialogSize ( (PDIALOG)prTemp->pRES ); if ( fwrite ( prTemp, sizeof ( RESOURCE ), 1, pfRESFile ) != 1 ) return ( ERR_WFILE ); return ( SaveDialog ( (PDIALOG)prTemp->pRES, pfRESFile ) ); } return ( OK );}/***************************************************************************** 函数原型: LoadStrTblResource ( void )** 功 能: 装入所有字符串表资源** 编程人员: Zhu haibin** 编码时间: 1994/10/05** 修改时间:** 入口参数: PRESOURCE prTemp -- 资源指针** 出口参数: OK 调用成功* ERR_WFILE 写文件失败** 实现算法: 1. 写入资源索引项* 2. 写入资源数据** 上层调用:** 下层调用: 无****************************************************************************/short LoadStrTblResource ( void ){ short i; short nCount; unsigned short nBufSize; nCount = nBufSize = nSysStrTblCount = 0; for ( i = 0; i < rfhRESFileHead.nCount; i++ ) { if ( prRESTable[i].nType != RT_STRTBL ) continue; if ( i == 0 ) fseek ( pfRESFile, sizeof (RESFILEHEAD) + sizeof (RESOURCE), SEEK_SET ); else fseek ( pfRESFile, prRESTable[i].lRESOffset, SEEK_SET ); LoadStringTable ( (PSTRTBL*)&prRESTable[i].pRES, pfRESFile ) ; nCount += ((PSTRTBL)prRESTable[i].pRES)->nCount; nBufSize += ((PSTRTBL)prRESTable[i].pRES)->nBufSize; pSysStrTbl[nSysStrTblCount] = (PSTRTBL)prRESTable[i].pRES; nSysStrTblCount ++; } return ( OK );}/***************************************************************************** 函数原型: LoadString ( short nID, char *pBuf, short nBufSize )** 功 能: 从字符串表资源中取出指定字符串** 编程人员: Zhu haibin** 编码时间: 1994/10/05** 修改时间:** 入口参数: short nID -- 字符串标识号* char *pBuf -- 字符串缓冲区* short nBufSize -- 字符串缓冲区长度** 出口参数: 总为 OK** 实现算法:** 上层调用: FreeResource** 下层调用: 无****************************************************************************/short LoadString ( short nID, char *pBuf, short nBufSize ){ short i, j; for ( i = 0; i < nSysStrTblCount; i++ ) { for ( j = 0; j < pSysStrTbl[i]->nCount; j ++ ) if ( nID == pSysStrTbl[i]->pStrTblIndex[j].nID ) { fseek ( pfRESFile, pSysStrTbl[i]->lFPos + pSysStrTbl[i]->pStrTblIndex[j].nOffset, SEEK_SET ); if ( nBufSize > pSysStrTbl[i]->pStrTblIndex[j].nLen ) nBufSize = pSysStrTbl[i]->pStrTblIndex[j].nLen; fread ( pBuf, sizeof ( char ), nBufSize, pfRESFile ); pBuf[nBufSize] = 0; return ( nBufSize ); } } return ( FALSE );}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -