我已經找到了解決這個問題的方法,但只是想知道是否有人知道實際發生了什麼事情會導致我看到的問題。我的猜測是它與字符串的可變性有關,但我認爲CString對象在拷貝構造函數中佔了這一地位。爲什麼使用DT_MODIFYSTRING選項將副本傳遞給DrawText函數時,原始CString會被覆蓋?
下面的代碼將導致mFileName被覆蓋:
class File {
public:
...
CString GetFilename() {return mFileName;}
private:
CString mFileName;
};
class FileContainer {
private: File* mFile;
public:
FileContainer() {
mFile = new File("C:\temp.txt");
}
GetFilename(CString& fileName) {
fileName = mFile->GetFileName();
}
}
void UpdateText() {
FileContainer fileCnt;
CString filePath(L"");
this->fileCnt.GetFilename(filePath);
...
::DrawText(hDC, filePath, -1, &destRect, DT_PATH_ELLIPSIS | DT_MODIFYSTRING | DT_CALCRECT);
}
什麼情況是,第一次UPDATETEXT被調用時,用GetFileName返回C:\ TEMP.TXT。假設邊界矩形導致文本在第一次調用時被截斷爲「... \ temp.txt」,則「... \ temp.txt」是在第二次調用UpdateText時從GetFilename返回的內容。
更令人費解的是,這並沒有引起mFileName改變:
void UpdateText() {
FileContainer fileCnt;
CString filePath(L"");
this->fileCnt->GetFilename(filePath);
filePath = L"TEST";
}
用GetFileName總是返回C:\ TEMP.TXT。所以看起來,DrawText函數是以某種方式找到原始的CString並修改它。但是如何?
更新:我想我會扔另一個代碼塊奇也導致mFileName被覆蓋:
class File {
public:
...
CString GetFilename() {return CString(mFileName);}
private:
CString mFileName;
};
這似乎像它應該創建一個新的對象,並返回該新對象。然而,不知何故,DrawText仍然會覆蓋mFileName。
如果我改變了代碼以下,我沒有任何問題:
class File {
public:
...
CString GetFilename() {return CString(mFileName.GetBuffer());}
private:
CString mFileName;
};
,似乎解決問題的唯一的事情是建立一個新的CString我的解決方法顯示的方式。當我通過DT_MODIFYSTRING選項時DrawText在做什麼?