?? tech.txt
字號:
// 指針所指向數據的格式見前面的描述。
// !!!只可讀取而不可更改其中的內容。
DWORD m_dwSubCodeAdr; // SDT_SUB_PTR,為子程序代碼地址指針。
MUNIT m_unit; // 窗口單元、菜單數據類型的數據。
void* m_pCompoundData;// 復合數據類型數據指針,指針所指向數據的格式見前面的描述。
// !!! 只可讀取而不可更改其中的內容。
void* m_pAryData; // 數組數據指針,指針所指向數據的格式見前面的描述。
// 注意如果為文本或字節集數組,則成員數據指針可能為NULL。
// !!! 只可讀取而不可更改其中的內容。
// 第二部分。
// 為指向變量地址的指針,僅當參數具有AS_RECEIVE_VAR或AS_RECEIVE_VAR_ARRAY或
// AS_RECEIVE_VAR_OR_ARRAY標志時才被使用。
BYTE* m_pByte; // SDT_BYTE 數據類型變量的地址,下同。
SHORT* m_pShort; // SDT_SHORT
INT* m_pInt; // SDT_INT
INT64* m_pInt64; // SDT_INT64
FLOAT* m_pFloat; // SDT_FLOAT
DOUBLE* m_pDouble; // SDT_DOUBLE
DATE* m_pDate; // SDT_DATE_TIME
BOOL* m_pBool; // SDT_BOOL
char** m_ppText; // SDT_TEXT,注意*m_ppText可能為NULL(代表空文本)。
// 寫入新值之前必須釋放前值,例句:NotifySys (NRS_MFREE, (DWORD)*m_ppText)。
// !!!不可直接更改*m_ppText所指向的內容,只能釋放原指針后設置入NULL(空文本)
// 或使用NRS_MALLOC通知分配的新內存地址指針(下同)。
LPBYTE* m_ppBin; // SDT_BIN,注意*m_ppBin可能為NULL(代表空字節集)。
// 寫入新值之前必須釋放前值,例句:NotifySys (NRS_MFREE, (DWORD)*m_ppBin)。
// !!!不可直接更改*m_ppBin所指向的內容,只能釋放原指針后設置入NULL(空字節集)
// 或新指針。
DWORD* m_pdwSubCodeAdr; // SDT_SUB_PTR,子程序代碼地址變量地址。
PMUNIT m_pUnit; // 窗口單元、菜單數據類型變量地址。
void** m_ppCompoundData; // 復合數據類型變量地址。
// !!!注意寫入新值之前必須使用NRS_MFREE通知逐一釋放所有成員(即:SDT_TEXT、
// SDT_BIN及復合數據類型成員)及原地址指針。
// !!!不可直接更改*m_ppCompoundData所指向的內容,只能釋放原指針后設置入新指針。
void** m_ppAryData; // 數組數據變量地址,注意:
// 1、寫入新值之前必須釋放原值,例句:NotifySys (NRS_FREE_ARY,
// m_dtDataType, (DWORD)*m_ppAryData),注意:此例句只適用于
// m_dtDataType為系統基本數據類型時的情況,如果為復合數據類型,
// 必須根據其定義信息逐一釋放。
// 2、如果為文本或字節集數組,則其中成員的數據指針可能為NULL。
// !!!不可直接更改*m_ppAryData所指向的內容,只能釋放原指針后設置入新指針。
};
// 1、當用作傳遞參數數據時,如果該參數具有 AS_RECEIVE_VAR_OR_ARRAY 或
// AS_RECEIVE_ALL_TYPE_DATA 標志,且為數組數據,則包含標志 DT_IS_ARY ,
// 這也是 DT_IS_ARY 標志的唯一使用場合。
// DT_IS_ARY 的定義為:
// #define DT_IS_ARY 0x20000000
// 2、當用作傳遞參數數據時,如果為空白數據,則為 _SDT_NULL 。
DATA_TYPE m_dtDataType;
};
typedef MDATA_INF* PMDATA_INF;
///////////////////////////////////////////////
下面給出一些具體的例子用來說明如何定義且實現全局命令,更多的例子請參見所提供的HtmlView支持庫的源代碼 。
///////////////////
首先給出一些例子中被使用到的公共輔助函數的實現代碼:
// 使用指定文本數據建立易程序中使用的文本數據。
char* CloneTextData (char* ps)
{
if (ps == NULL || *ps == '\0')
return NULL;
INT nTextLen = strlen (ps);
char* pd = (char*)NotifySys (NRS_MALLOC, (DWORD)(nTextLen + 1), 0);
memcpy (pd, ps, nTextLen);
pd [nTextLen] = '\0';
return pd;
}
// 使用指定文本數據建立易程序中使用的文本數據。
// nTextLen用作指定文本部分的長度(不包含結束零),
// 如果為-1,則取ps的全部長度。
char* CloneTextData (char* ps, INT nTextLen)
{
if (nTextLen <= 0)
return NULL;
char* pd = (char*)NotifySys (NRS_MALLOC, (DWORD)(nTextLen + 1), 0);
memcpy (pd, ps, nTextLen);
pd [nTextLen] = '\0';
return pd;
}
// 使用指定數據建立易程序中使用的字節集數據。
LPBYTE CloneBinData (LPBYTE pData, INT nDataSize)
{
if (nDataSize == 0)
return NULL;
LPBYTE pd = (LPBYTE)NotifySys (NRS_MALLOC, (DWORD)(sizeof (INT) * 2 + nDataSize), 0);
*(LPINT)pd = 1;
*(LPINT)(pd + sizeof (INT)) = nDataSize;
memcpy (pd + sizeof (INT) * 2, pData, nDataSize);
return pd;
}
// 報告運行時錯誤。
void GReportError (char* szErrText)
{
NotifySys (NRS_RUNTIME_ERR, (DWORD)szErrText, 0);
}
void* MMalloc (INT nSize)
{
return (void*)NotifySys (NRS_MALLOC, (DWORD)nSize, 0);
}
void MFree (void* p)
{
NotifySys (NRS_MFREE, (DWORD)p, 0);
}
// 返回數組的數據部分首地址及成員數目。
LPBYTE GetAryElementInf (void* pAryData, LPINT pnElementCount)
{
LPINT pnData = (LPINT)pAryData;
INT nArys = *pnData++; // 取得維數。
// 計算成員數目。
INT nElementCount = 1;
while (nArys > 0)
{
nElementCount *= *pnData++;
nArys--;
}
if (pnElementCount != NULL)
*pnElementCount = nElementCount;
return (LPBYTE)pnData;
}
#define DTT_IS_NULL_DATA_TYPE 0
#define DTT_IS_SYS_DATA_TYPE 1
#define DTT_IS_USER_DATA_TYPE 2
#define DTT_IS_LIB_DATA_TYPE 3
// 取回數據類型的類別。
INT GetDataTypeType (DATA_TYPE dtDataType)
{
if (dtDataType == _SDT_NULL)
return DTT_IS_NULL_DATA_TYPE;
DWORD dw = dtDataType & 0xC0000000;
return dw == DTM_SYS_DATA_TYPE_MASK ? DTT_IS_SYS_DATA_TYPE :
dw == DTM_USER_DATA_TYPE_MASK ? DTT_IS_USER_DATA_TYPE :
DTT_IS_LIB_DATA_TYPE;
}
// 絕對不會返回NULL或者窗口句柄無效的CWnd*指針。
CWnd* GetWndPtr (PMDATA_INF pInf)
{
return (CWnd*)NotifySys (NRS_GET_AND_CHECK_UNIT_PTR,
pInf [0].m_unit.m_dwFormID, pInf [0].m_unit.m_dwUnitID);
}
///////////////////
1、使用到 CMD_INFO 中的 CT_ALLOW_APPEND_NEW_ARG 標志的命令例子:
2、返回系統基本數據類型的命令例子:
// 求余數
static ARG_INFO s_ArgInfo[] =
{
{
/*name*/ _T("被除數"),
/*explain*/ NULL,
/*bmp inx*/ 0,
/*bmp num*/ 0,
/*type*/ SDT_DOUBLE,
/*default*/ 0,
/*state*/ NULL,
}, {
/*name*/ _T("除數"),
/*explain*/ NULL,
/*bmp inx*/ 0,
/*bmp num*/ 0,
/*type*/ SDT_DOUBLE,
/*default*/ 0,
/*state*/ NULL,
},
};
static CMD_INFO s_CmdInfo =
{
/*name*/ _T("求余數"),
/*egname*/ _T("mod"),
/*explain*/ _T("求出兩個數值的商,并返回余數部分,運算符號為“%”或“Mod”"),
/*category*/ 2,
/*state*/ CT_ALLOW_APPEND_NEW_ARG,
/*ret*/ SDT_DOUBLE,
/*reserved*/ 0,
/*level*/ LVL_SIMPLE,
/*bmp inx*/ 0,
/*bmp num*/ 0,
/*ArgCount*/ 2,
/*arg lp*/ s_ArgInfo,
},
// 命令實現函數
void fnMod (PMDATA_INF pRetData, INT nArgCount, PMDATA_INF pArgInf)
{
// 對于具有CT_ALLOW_APPEND_NEW_ARG標志的命令,需要讀取nArgCount以獲得實際參數數目。
DOUBLE db = pArgInf [0].m_double;
for (INT i = 1; i < nArgCount; i++)
{
pArgInf++;
if (pArgInf->m_double == 0)
GReportError ("不能求余數于零");
db = fmod (db, pArgInf->m_double);
}
// 設置返回的雙精度小數數據。
pRetData->m_double = db;
}
///////////////////
3、使用到 CMD_INFO 中的 CT_RETURN_ARRAY_DATA 標志的命令例子:
4、具有定義有 AS_DEFAULT_VALUE_IS_EMPTY 標志參數的命令例子:
// 分割文本
static ARG_INFO s_ArgInfo[] =
{
{
/*name*/ _T("待分割文本"),
/*explain*/ _T("如果參數值是一個長度為零的文本,則返回一個空數組,即沒有任何成員的數組"),
/*bmp inx*/ 0,
/*bmp num*/ 0,
/*type*/ SDT_TEXT,
/*default*/ 0,
/*state*/ NULL,
}, {
/*name*/ _T("用作分割的文本"),
/*explain*/ _T("參數值用于標識子文本邊界。如果被省略,"
"則默認使用半角逗號字符作為分隔符。如果是一個長度為零的文本,則返回的數組"
"僅包含一個成員,即完整的“待分割文本”"),
/*bmp inx*/ 0,
/*bmp num*/ 0,
/*type*/ SDT_TEXT,
/*default*/ 0,
/*state*/ AS_DEFAULT_VALUE_IS_EMPTY,
}, {
/*name*/ _T("要返回的子文本數目"),
/*explain*/ _T("如果被省略,則默認返回所有的子文本"),
/*bmp inx*/ 0,
/*bmp num*/ 0,
/*type*/ SDT_INT,
/*default*/ 0,
/*state*/ AS_DEFAULT_VALUE_IS_EMPTY,
}
};
static CMD_INFO s_CmdInfo =
{
/*name*/ _T("分割文本"),
/*egname*/ _T("split"),
/*explain*/ _T("將指定文本進行分割,返回分割后的一維文本數組"),
/*category*/ 9,
/*state*/ CT_RETRUN_ARY_TYPE_DATA,
/*ret*/ SDT_TEXT,
/*reserved*/ 0,
/*level*/ LVL_SIMPLE,
/*bmp inx*/ 0,
/*bmp num*/ 0,
/*ArgCount*/ 3,
/*arg lp*/ s_ArgInfo,
};
// 命令實現函數
void fnSplit (PMDATA_INF pRetData, INT nArgCount, PMDATA_INF pArgInf)
{
LPTSTR szBeSplited = pArgInf [0].m_pText;
// 如果某個具有 AS_DEFAULT_VALUE_IS_EMPTY 標志的參數用戶程序中沒有為其提供參數值,
// 則其數據類型為 _SDT_NULL 。
LPTSTR szMark = pArgInf [1].m_dtDataType == _SDT_NULL ? _T(",") : pArgInf [1].m_pText;
INT nCount = pArgInf [2].m_dtDataType == _SDT_NULL ? -1 : max (0, pArgInf [2].m_int);
INT nLen1 = strlen (szBeSplited);
INT nLen2 = strlen (szMark);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -