在 CdaoRecordset 派 生 類 的 對 象 中,VC 自 動 為Access 的“OLE 對 象” 域 生 成 一 個CLongBinary 對 象。
該 類 雖 然 較 簡 單, 在 程 序 裡 卻 需 要 使 用 全 局 函 數GlobalAlloc() 和GlobalFree() 處 理 與 它 的 內 存 句 柄m_hData 有 關 操 作, 訪 問 數 據 前 後 要 調 用GlobalLock() 和GlobalUnlock(), 而 且 還 要 給 它 的m_dwDataLength 賦 值, 使 用 起 來 相 對 復 雜, 所 以 一 般 推 薦 使 用CByteArray 類。 這 只 需 要 在CdaoRecordset 派 生 類 對象 的 數 據 說 明 裡 修 改 一 下, 並 把DoFIEldExchange() 裡 的 DFX_LongBinary() 改 成DFX_Binary() 即 可。
作 者 定 義 了 一 個 以CObject 為 基 類 的CDib 類(CDaoRecordVIEw 的派 生 類 裡 定 義 了CDib 對 象 成 員m_DIB), 其 中 包 括 一 下 成 員 和 方 法:
CByteArray m_bufDIB;
BOOL Create(CByteArray& ba);
BOOL Create(CFile& bmpFile);
BOOL Paint(HDC hDC);
m_bufDIB 是 存 儲 位 圖 數 據 的 緩 沖 區。 為 簡 便 起 見, 它 不 包 含 包 裝 信 息 和BITMAPFILEHEADER 結 構。 這 樣 對 數 據 庫更 新 後, 原 有 的“OLE 對 象” 類 型 將 變 成“ 長 二 進 制 數 據”, 不 能 在Access 裡 查 看 了。
第 一 個Create() 重 載 方 法 的 參 數ba 是 記 錄 集 的 位 圖 數 據( 比 如m_image), 使 用CByteArray::Copy() 把 數 據 復 制 給m_bufDIB; 第 二 個Create() 方 法 的 參 數bmpFile 是 已 打 開 的 位圖 文 件, 使 用CFile::ReadHuge() 把 文 件 裡 的 數 據 讀 入
m_bufDIB( 放 棄 前 面 的BITMAPFILEHEADER 結 構):
DWord dwBufSize;
dwBufSize = bmpFile.GetLength();// 獲 得 文 件 長 度
bmpFile.Seek((long)sizeof(BITMAPFILEHEADER),
CFile::begin);// 放 棄 文 件 頭
dwBufSize-=sizeof(BITMAPFILEHEADER);
m_bufDIB.SetSize(dwBufSize );// 設 置 緩 沖 區 大 小
file.ReadHuge((LPSTR)(m_bufDIB.GetData()), dwBufSize);
……
Paint() 方 法 調 用 了SetDIBitsToDevice() 函 數( 根 據 情 況也 可 以 使 用StretchDIBits ()), 參 數hDC 是CDaoRecordvIEw 的 資 源 中 的 一 個 靜 態 控 制 的 設 備 句 柄, 作 為
SetDIBitsToDevice() 的 第 一 個 參 數。
如 果 不 是16 或24 位 的 位圖, 還 需 要 建 立 和 設 置 調 色 板。Paint() 方 法 除 了 在CDaoRecordVIEw 派 生 類 的OnMove() 裡 調 用 外, 也 被OnPaint() 調用( 最 好 不 在OnDraw() 裡 調 用):
void CDerivedVIEw::OnPaint()
{
CPaintDC dc(this);
CClIEntDC dc1(&m_ctlImage);
if(m_DIB.Create(m_pSet->m_image))
m_DIB.Paint(dc1.m_hDC);
}
作 者 首 先 采 用 的 方 法 是, 每 當 打 開 一 個 位 圖 文 件,調 用m_DIB.Create() 和m_DIB.Paint(), 然 後 復 制 給m_pSet->m_image,再 設 置“ 髒” 標 識:
if(m_DIB.Create(bmpFile))
{
CClIEntDC dc(&m_ctlImage);
m_DIB.Paint(dc.m_hDC);
(m_pSet->m_image).Copy(m_DIB.m_bufDIB);
SetFIEldDirty(&(m_pSet->m_image));
}
記 錄 滾 動 時,OnMove() 調 用Update() 對 數 據 進 行 更 新。
但 是 這 樣 做 的 結 果 是, 只 有 在 域 的 內 容 不 為 空(NULL) 的時 候 才 能 更 新 數 據。 也 就 是 說, 添 加“ 長 二 進 制 數據” 不 能 實 現。
最 後 發 現 使 用SeIEldValue() 可 以 實 現 添 加 和 替 換。 但 由於 作 者 未 知 的 原 因, 還 需 要 把 另 外 某 個 域 設 置 為“ 髒” 才 行:
if(m_DIB.Create(bmpFile))
{
CClIEntDC dc(&m_ctlImage);
m_DIB.Paint(dc.m_hDC);
(m_pSet->m_image).Copy(m_DIB.m_bufDIB);
// 只 為OnPaint() 調 用 時 使 用
m_pSet->SetFIEldValue(_T("[image]"),
COleVariant(m_DIB.m_bufDIB));
m_pSet->SetFIEldDirty(&(m_pSet->m_name));
// 任 意 另 外 一 個 域
}
如 果 打 算 刪 除 數 據 庫 裡 的 位 圖 數 據, 可 以 把 一 個“ 空” 的CByteArray 對 象 替 換 原 來 的 就 行 了。