我需要在只读的多行编辑控件中以表格格式显示一些数据。由于编辑控件的字体对于所有文本都没有均匀的宽度,因此我无法使用此格式"%-20s"
,因此我选择使用\t
格式(请参阅下面)。但这并没有完全帮助我,因为它在图像中显示出来。
我尝试使用GetTextExtentPoint32()
API,但无法找到\t
的确切宽度。那么,我如何正确对齐文本?
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,因为我应该允许用户复制/粘贴结果。
答案 0 :(得分:2)
我认为你在这里使用了错误的工具。
由于您需要向用户提供一些表格数据,我更倾向于使用专门为此设计的控件,例如列表视图控件(在报告中)模式)。您可以在其中放置一个带有列表视图控件的对话框,并使用它向用户显示您的数据。
由于您使用MFC标记标记了此问题,因此可以考虑CListCtrl
class(或CodeProject上免费提供的其他几个增强列表视图控件类)。
如果您真的想以“console-mode”样式格式化表格数据中的某些文本,您可能想要创建一个带有静态文本控件的对话框(或只读编辑)控制)里面,并将其字体设置为固定宽度(非比例);但我认为以前的列表视图控制方法质量更高。
答案 1 :(得分:1)
在多行编辑控件中显示表格数据的正确方法是在设置文本之前设置制表位。见EM_SETTABSTOPS message
这类似于现在忘记的打字机标签,其中按下TAB键将插入符号移动到最右边的最近的标签牌。您将无法右对齐数字数据;为此你需要使用ListView。
答案 2 :(得分: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);
并且输出符合预期
显示编辑控件
并显示了MessageBox()
这里TAB_WIDTH
是\t
的宽度,我手动计算了像素。现在我必须通过代码找到\t
的宽度。