'Visual C'에 관한 글 3개

GDI+에서 Round Rectangle 그리기.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
void GetRoundedRect(GraphicsPath* pPath, RectF baseRect, float radius){
    if( radius<=0.0F ){
        pPath->AddRectangle(baseRect);
        pPath->CloseFigure();
        return;
    }
    if( radius>=(min(baseRect.Width, baseRect.Height))/2.0){
        GetCapsule(pPath, baseRect);
        return;
    }
    float diameter = radius * 2.0F;
    RectF arc   ( baseRect.X, baseRect.Y, diameter, diameter);
    pPath->AddArc( arc, 180, 90 );
    arc.X = baseRect.GetRight() -diameter;
    pPath->AddArc( arc, 270, 90 );
    arc.Y = baseRect.GetBottom() -diameter;
    pPath->AddArc( arc, 0, 90 );
    arc.X = baseRect.GetLeft();
    pPath->AddArc( arc, 90, 90 );    
    pPath->CloseFigure();
}
 
void GetCapsule(GraphicsPath* pPath, RectF baseRect){
    float diameter;
    
    TRY{
        if( baseRect.Width > baseRect.Height){
            diameter = baseRect.Height;           
            RectF arc( baseRect.X, baseRect.Y, diameter, diameter);
            pPath->AddArc( arc, 90, 180);
            arc.X = baseRect.GetRight()-diameter;
            pPath->AddArc( arc, 270, 180);
        }else if( baseRect.Width < baseRect.Height ){
            diameter = baseRect.Width;
             
            RectF arc( baseRect.X, baseRect.Y, diameter, diameter );
            pPath->AddArc( arc, 180, 180 );
            arc.Y = baseRect.GetBottom() -diameter;
            pPath->AddArc( arc, 0, 180 );
        }else{
            pPath->AddEllipse( baseRect );
        }
    }CATCH(CException, ex){
        pPath->AddEllipse( baseRect );
    }
    END_CATCH
    pPath->CloseFigure();
}
사용 예)
1
2
3
4
5
6
7
8
9
10
RectF PaintRect(WndRect.Width()/2-200, WndRect.Height()/2-100, 400, 200);
 
LinearGradientBrush BackBrush(PaintRect , Color(255,255,255), Color(57,109,194), LinearGradientModeVertical);
Pen     BackPen  (Color(57,109,194), 3);
 
GraphicsPath RoundPath;
GetRoundedRect(&RoundPath, PaintRect, 10);
 
pMemG->FillPath(&BackBrush, &RoundPath);
pMemG->DrawPath(&BackPen,   &RoundPath);

자료 참고: codeproject.com

2008/03/14 19:00 2008/03/14 19:00
태그 : ,
글 걸기 주소 : 이 글에는 트랙백을 보낼 수 없습니다

VC macro __FUNCTION__ UNICODE에서 사용하기

디버깅 편의를 위하여
#define __T_PRINT(val)  val.Print(__FUNCTION__, __FILE__, __LINE__)
과 같이 이용하고 있습니다. 매번 __FUNCTION__, __FILE__을 명시하기 귀찮아서...

멀티바이트로 컴파일시에는 문제가 없으나 유니코드로 컴파일시에는 
error C2664: 'CTimeCounter::Print' : 매개 변수 1을(를) 'const char [26]'에서 'CString'(으)로 변환할 수 없습니다.
와 같이 오류가 발생하네요

1
#define __T_PRINT(val)  val.Print(_T(__FUNCTION__), _T(__FILE__), __LINE__)

혹은

1
2
3
4
5
6
7
8
9
#ifdef _UNICODE
    #define WIDEN(x)           L ## x
    #define WIDEN2(x)         WIDEN(x)
    #define __WFILE__          WIDEN2(__FILE__)
    #define __WFUNCTION__ WIDEN2(__FUNCTION__)
#else
    #define __WFILE__          __FILE__
    #define __WFUNCTION__ __FUNCTION__
#endif

와 같이 변경하여 사용해야 컴파일시 오류가 발생하지 않습니다.

_T()를 역추적하면...
#define __T(x)      L ## x
#define _T(x)       __T(x)
라고 되어있네요.

#define __WFUNCTION__ L ## __FUNCTION__
와 같이 바로 L ## x 로 변경시
error C2065: 'L__FUNCTION__' : 선언되지 않은 식별자입니다.
와 같은 오류가 나는것으로 봐서는 전처리 순서때문에 생기는 문제 같네요.

다국어 처리를 위한 Unicode변환.. 생각보다 손이 많이 가진다는..
2008/03/14 18:47 2008/03/14 18:47
태그 : ,
글 걸기 주소 : 이 글에는 트랙백을 보낼 수 없습니다

MulDiv

int MulDiv(int nNumber, int nNumerator, int nDenominator);
//nNumber * nNumerator / nDenominator

사용예)
    TRACE("%d", 12*34/12);
        //출력 = 34
    TRACE("%d", 1234567*8900000/1234567);
        //출력 = 907
    TRACE("%d", MulDiv(1234567, 8900000, 1234567));
        //출력 = 8900000
    TRACE("%ld", (LONGLONG)1234567*8900000/1234567);
        //출력 = 8900000
    TRACE("%d", MulDiv(1234567,8900000,0));
        //출력 = -1

각각의 차이점은??? ^^;

2007/12/12 14:53 2007/12/12 14:53
글 걸기 주소 : 이 글에는 트랙백을 보낼 수 없습니다