2015-10-07 28 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