2014-02-26 2 views
2

기본적으로 TextOut을 여러 번 호출하여 화면에 텍스트를 그립니다. Visual Studio 2012를 사용하는 C++ Win32 응용 프로그램입니다. 철자 오류 등을 표시 할 때 Word에서하는 방법으로 물결 모양 밑줄을 그릴 수 있습니까?Win32 TextOut으로 물결 모양 밑줄 그리는 방법

TEXTMETRIC에는 tmUnderlined라는 멤버가 있습니다.이 멤버는 밑줄이 그어진 텍스트로는 작동하지만 물결 모양 밑줄에는 사용할 수 없습니다. 또한 Microsoft의 RichEdit 컨트롤이 물결 모양 밑줄을 지원한다는 것을 알았지 만 사용할 수 없습니다.

물론 간단한 사인파를 사용하여 경로를 만들 수는 있지만이 작업을 수행하기 전에이 작업을 수행하는 표준 방법이 있는지 확인하고 싶습니다.

+1

'TextOut'으로 이것을 할 방법이 없습니다. –

+0

다른 길은 아마도? –

+0

그냥 GDI +의 DrawString 메서드를 확인했습니다. 물결 모양 밑줄이없는 FontStyle이라는 이름의 열거 형이 있습니다. –

답변

4

직접 구현했습니다. 다음의 경우 사람의 코드는 관심이있다 : 당신이 gotos 마음에 들지 않으면

BOOL SomeClass::drawWavyUnderline (WPPoint ptTextPos, int nWidth, COLORREF col) 
    // Draws a wavy underline below the position a run of text at the given 
    // position and of the given width would occupy. This method consults the 
    // height of the currently selected font in order to find the baseline where 
    // the underline is drawn. 
    // NOTE: The method will fail to find the correct position of the underline 
    // if the current text alignment is not set to TA_LEFT! 
    // @param ptTextPos (in): TextOut reference point. 
    // @return: TRUE on success, FALSE on failure. 
    { 
    BOOL bResult = FALSE; 
    Gdiplus::Graphics *pGfx = NULL; 
    Gdiplus::Pen *pPen = NULL; 
    Gdiplus::PointF *arrPts = NULL; 
    // Determine the number of points required. 
    static const float fNumPixelsPerSample = 1.2f; 
    int nNumPts = (int)(nWidth/fNumPixelsPerSample); 
    if (nNumPts <= 1) 
     { 
     goto outpoint; // width too small or even negative! 
     } 
    // Retrieve information about the current GDI font. 
    TEXTMETRIC tm; 
    if (!::GetTextMetrics (/* HDC... */, &tm)) 
     { 
     goto outpoint; // failed to retrieve TEXTMETRIC! 
     } 
    // Create points array. 
    arrPts = new Gdiplus::PointF [nNumPts]; 
    if (arrPts == NULL) 
     { 
     goto outpoint; // out of mem! 
     } 
    // Fill points array. 
    static const float fYOffset = 1.0f; 
    static const float fAmp = 1.5f; 
    Gdiplus::PointF *pScan = arrPts; 
    for (int i = 0; i < nNumPts; i++, pScan++) 
     { 
     pScan->X = (Gdiplus::REAL)(ptTextPos.x + (float) i * nWidth/(nNumPts - 1)); 
     // The amplitude is computed as a function of the absolute position x rather 
     // than the sample index i in order to make sure the waveform will start at 
     // the correct point when two runs are drawn very near each-other. 
     float fValue = (float)(fAmp * sin ((pScan->X/fNumPixelsPerSample)*(M_PI/3.0))); 
     pScan->Y = (Gdiplus::REAL)(ptTextPos.y + tm.tmAscent + tm.tmDescent*0.5f + fYOffset + fValue); 
     } 
    // Create GDI+ graphics object. 
    HDC hdc = /* code to retrieve the HDC... */ ; 
    if (hdc == NULL) 
     { 
     goto outpoint; // missing HDC 
     } 
    pGfx = new Gdiplus::Graphics (hdc); 
    if (pGfx == NULL) 
     { 
     goto outpoint; // out of mem! 
     } 
    // Draw the lines. 
    pPen = new Gdiplus::Pen (Gdiplus::Color (GetRValue (col), GetGValue (col), GetBValue (col))); 
    if (pPen == NULL) 
     { 
     goto outpoint; // out of mem! 
     } 
    pGfx->SetSmoothingMode (Gdiplus::SmoothingModeHighQuality); 
    if (pGfx->DrawLines (pPen, arrPts, nNumPts) != Gdiplus::Ok) 
     { 
     goto outpoint; // failed to draw the lines! 
     } 
    bResult = TRUE; 
    outpoint: 
    // Clean up. 
    if (pPen != NULL) delete pPen; 
    if (pGfx != NULL) delete pGfx; 
    if (arrPts != NULL) delete[] arrPts; 
    return bResult; 
    } 

P.S는 : 그것을 다시 대신시켜 try..catch 사용하여 주시기 바랍니다!

관련 문제