2015-10-07 67 views
1

我需要在只讀多行編輯控件中以表格格式顯示一些數據。由於編輯控件的字體對於所有文本都沒有寬度,因此我無法使用此格式"%-20s",所以我選擇使用\t格式(請參閱下面的代碼)。但是這並不能完全幫助我,因爲它像圖像一樣顯示。

enter image description here

我嘗試使用GetTextExtentPoint32() API,但它無法找到\t確切的寬度。那麼,我如何正確對齊文本?Edit Control或MessageBox中的表格字符串格式化()

CString szMsg; 
szMsg.Format(_T("%s\t%s\t%s\r\n\r\n%s\t%s\t%s\r\n%s\t%s\t%s\r\n%s\t%s\t%s"), 
    _T("ITEM"), _T("VALUE"), _T("STATUS"), 
    _T("XXXXXXXX"), _T("1.0001"), _T("PASSED"), 
    _T("YYYYYYYYYYYYYYYY"), _T("-0.0001"), _T("FAILED"), 
    _T("ZZZ"), _T("0.0101"), _T("PASSED") 
    ); 
this->GetDlgItem(IDC_EDIT1)->SetWindowText(szMsg); 

注:
1.將在運行時生成,所以它可以是任何長度的字符串。
2.我不想使用ListCtrl或ListView,因爲我應該允許用戶複製/粘貼結果。

+4

我不認爲內置消息框適用於此。 – deviantfan

+2

我同意,在自定義對話框中使用listview控件可以獲得更好的結果。 –

+0

[mfc - 帶有豐富文本的MessageBox]的可能的副本(http://stackoverflow.com/questions/15402671/mfc-messagebox-with-rich-text) – user1

回答

0

我做了這樣的事情,

#define TAB_WIDTH 56 

/*codes skipped*/ 

CString szItems[4] = { _T("ITEM"), _T("XXXXXXXX"), _T("YYYYYYYYYYYYYYYY"), _T("ZZZ") }; 
CString szValues[4] = { _T("VALUE"), _T("1.0010"), _T("-0.0009"), _T("0.1001") }; 
CString szStatus[4] = { _T("STATUS"), _T("Passed"), _T("Failed"), _T("Passed") }; 
int nTabs[3][4] = { { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 } }; 

CDC *pDC = this->GetDC(); 

CFont *pOldFont = pDC->SelectObject(this->GetDlgItem(IDC_EDIT1)->GetFont()); 

SIZE sizeText; 

for (int ni = 0; ni < 4; ni++) 
{ 
    GetTextExtentPoint32(pDC->GetSafeHdc(), szItems[ni], szItems[ni].GetLength(), &sizeText); 
    nTabs[0][ni] = sizeText.cx/TAB_WIDTH; 

    GetTextExtentPoint32(pDC->GetSafeHdc(), szValues[ni], szValues[ni].GetLength(), &sizeText); 
    nTabs[1][ni] = sizeText.cx/TAB_WIDTH; 

    GetTextExtentPoint32(pDC->GetSafeHdc(), szStatus[ni], szStatus[ni].GetLength(), &sizeText); 
    nTabs[2][ni] = sizeText.cx/TAB_WIDTH; 
} 

pDC->SelectObject(pOldFont); 

int nBig[3] = { 0, 0, 0 }; 
nBig[0] = BiggestValue(nTabs[0], 4); 
nBig[1] = BiggestValue(nTabs[1], 4); 
nBig[2] = BiggestValue(nTabs[2], 4); 

CString szDispStr = _T(""); 

for (int ni = 0; ni < 4; ni++) 
{ 
    szDispStr += szItems[ni]; 

    for (int nj = nTabs[0][ni]; nj <= nBig[0]; nj++) 
     szDispStr += _T("\t"); 

    szDispStr += szValues[ni]; 

    for (int nj = nTabs[1][ni]; nj <= nBig[1]; nj++) 
     szDispStr += _T("\t"); 

    szDispStr += szStatus[ni]; 

    for (int nj = nTabs[2][ni]; nj <= nBig[2]; nj++) 
     szDispStr += _T("\t"); 

    szDispStr += _T("\r\n"); 

    if (ni == 0) 
     szDispStr += _T("\r\n"); 
} 

this->GetDlgItem(IDC_EDIT1)->SetWindowTextW(szDispStr); 

,並如預期輸出

編輯控件中顯示
enter image description here

並在MessageBox()顯示
enter image description here

here TAB_WIDTH是我手動計算像素的寬度\t。現在我必須通過代碼找到\t的寬度。

2

我認爲你在這裏使用了錯誤的工具。

,因爲你需要一些表格數據呈現給用戶,我寧願使用專門爲該設計了控制,像列表視圖控件(在報告模式)。你可以在裏面有一個帶有列表視圖控件的對話框,並用它來向用戶顯示你的數據。

由於您使用MFC標記標記了此問題,因此可以考慮在CodeProject上免費提供CListCtrl class(或其他幾個增強的列表視圖控件類)。

如果你真的想格式化表格數據的一些文本在「控制檯模式」的風格,您可能希望創建一個對話框,對話框有一個靜態文本控件(或只讀編輯控件)內,並將其字體設置爲固定寬度(非比例);但我認爲以前的列表視圖控制方法的質量更高。

+0

@ mr-c64我正在使用只讀編輯控件,因爲它已被使用,所以我無法更改字體。 – HariDev

+0

@WinAppy爲什麼你不能改變字體?但無論如何,像其他人所暗示的那樣,我使用了listview控件。 –

+0

@MichaelWalz由於該項目是遺產,我不能這樣做。我應該使用已經被使用的。無論如何,我幾乎找到了解決方案,請檢查我的答案。 – HariDev

1

在多行編輯控件中顯示錶格數據的正確方法是在設置文本之前設置製表位。請參閱EM_SETTABSTOPS message

這與現在已被遺忘的打字機選項卡相似,在該選項卡中按下TAB鍵可將插入符號移至最近的右側的製表符。儘管如此,您將無法對數字數據進行右對齊。爲此你需要使用ListView。

+0

即使你的回答沒有解決我的問題,但它幫助我找出在哪裏設置更好的tabstop。但我仍試圖完全解決它。謝謝。 – HariDev