怪异的字体 问:我们有一个MFC应用程序,主窗口是在客户区域内画些文本和图形. 我们希望能 在客户区域内显示文本,在不需要时则擦除.所以我们先得到一个DC(CClientDC), 然后设置字体和文本颜色就开始写文本,在擦除时,我们用同样的字体,同样的地方 用背景色 重写文本. 这种方法绝大部分情况下都工作得很好,但偶尔文本并不能完全擦除,有些像素 点依然可见. 好象在写文本时比通常略微胖了些,就象用粗体一样.字体是在写文 本时使用的,以后也没有 进行过任何的调整. 下面是我们使用的写与擦除的函数. void Csign::DrawSignName(CDC* pDC) { int OldBkMode; // select the appropriate font Cfont* pOldFont = (Cfont*) pDC->SelectObject(pSignNameFont); OldBkMode = pDC->SetBkMode(TRANSPARENT); // determine the colour of the text if (IsSignNameVisible()) pDC->SetTextColor(aColours[SIGN_NAME_COLOUR]); else pDC->SetTextColor(aColours[DEVICE_INVISIBLE_COLOUR]); // draw the text pDC->TextOut(m_pointNameCoords.x, m_pointNameCoords.y, m_strName); // restore the previously used font and background mode pDC->SelectObject(pOldFont); pDC->SetBkMode(OldBkMode); } // DrawSignName 函数是在消息句柄中调用的,而参数中的DC是这样建立的: CClientDC dc(AfxGetMainWnd()). 字体是在程序初始化时建立的: pSignNameFont = new Cfont; pSignNameFont->CreateFont(10,5,0,0,150, FALSE,FALSE,0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, "Helvetica"); 是不是一次使用两个指向同一个客户窗口的DC有问题?程序中的DrawSignName()被多个消息句柄 调用。 答:1)加入以下代码: { m_strName.Empty(); Invalidate(); UpdateWindow(); more stuff;;; } 上面代码会产生一个WM_ERASEBKGND消息,将会用背景色填满窗口,然后再调用 OnDraw(), 这时只要将字符串置空即可。 2)我不清楚为什么程序不能正常工作,但我有个主意(它会更快些)可以在显 示文本 的地方用一个背景色的矩形画一下即可。我也不清楚为什么你们为什么要 用透明文本, 它将会给图形系统带来大量的工作。字体之所以有这种情况,是否 你们安装了文本输出 的图形保真软件?它会给你们带来困惑的。 3)你只想简单的用一个指针来保存一个指向DC的GDI对象,并试图再次调用它 时期望它能 指向正确的对象。恕我直言,这不是正确的方法(我不知道是否这是 显示不正常的唯一原 因)将它转化为一个Windows句柄才是正确的: // // Creating: // pSignNameFont = new Cfont; pSignNameFont->CreateFont(10,5,0,0,150, FALSE,FALSE,0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, "Helvetica"); // Now converting into a windows handle m_hSNFont = (HFONT) pSignNameFont->GetSafeHandle(); 直接保存一个对象是不安全的。