• 第17章 文本和字体_17.6 一些有趣和新奇的内容


     17.6 一些有趣和新奇的内容

    17.6.1 GDI路径

    (1)路径的创建

      BeginPath(hdc);

            //1、使用任何绘制线的函数在DC上绘制,被存在GDI内部,但不显示出来。

            //2、可以在当前路径中创建一个新的子路径,其中每个子路径都是一系列互相连接的线。

            //3、每个子路径可以是闭合的,也可以是开放的。要闭合子路径时,可以用CloseFigure将子路径闭合,必要时会自动添加一条直线以达到些目的。其后用任何画线函数创建的都是新的子路径。

      EndPath(hdc);

    (2)五个与路径有关的函数(注意:下面的函数在用完之后,都会删除被定义的路径!

      ①StokePath(hdc):用当前画笔来绘制出路径出来。

      ②FillPath(hdc):用当前画刷,根据当前的多边形填充模式填充,会先闭合开放的路径。

      ③StrokeAndFillPath(hdc):一次性完成StrokePath和FillPath的功能。

      ④hRgn = PathToRegion(hdc);将路径转换成区域,会先闭合开放的路径。

      ⑤SelectClipPath(hdc,iCombine): 选择当前的路径作为设备环境的一个裁剪区域。

                                                           其中的iCombine指明的路径与当前的裁剪区域如何合并。

    (3)路径:对填充与裁剪来说,路径比区域更灵活,因为区域只能由矩形、椭圆和多组合组合来定义,但路径可用包括贝塞尔曲线或弧线定义。

    (4)在GDI中,路径和区域的存储截然不同,路径是由一个直线和曲线定义的集合,而区域是一个扫描线的集合。

    17.6.2 扩展画笔:hPen = ExtCreatePen(dwStyle, dwWidth,&lplb,0,NULL);

    参数

    含义

    DWORD dwStyle

    画笔的类型。与CreatePen函数的画笔类型一样,此外,还可以使用

    1、画笔类型:PS_GEOMETRIC、PS_COSMETIC等类型。

    2、线端点样式:

      ①PS_ENDCAP_ROUND:圆形

    ②PS_ENDCAP_SQUARE:方形,线的长度向外延伸了出宽度的一半。

    ③PS_ENDCAP_FLAT:平面样式

    3、线与线连接点的样式

      ①PS_JOIN_ROUND:圆形

    ②PS_JOIN_BEVEL:斜截,将连接点的末端切断

    ③PS_JOIN_MITER:斜接,连接点是个尖端。

    DWORD dwWidth

    画笔的宽度。PS_COSMETIC宽度必须是1。

    LOGBRUSH* lplb

    画笔的属性。在CreatePen中,该参数是颜色。但扩展画笔函数中,这个参数是画刷,可能为PS_GEOMETRIC样式的内部着色。这个画笔甚至可以是点阵位图。

    DWORD dwStyleCount

    自定义样式数组的元素个数

    DWORD *lpStyle

    自定义的样式数组

     【EndJoin程序】

    第一个V:端点、连接点都为圆形;
    第二个V:端点方形、连接点斜截 ;
    第三个V:端点平面、连接点斜接; 

    /*------------------------------------------------------------
    ENDJOIN.C -- Ends and Joins Demo
    (c) Charles Petzold, 1998
    ------------------------------------------------------------*/
    #include <windows.h>
    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                       PSTR szCmdLine, int iCmdShow)
    {
        static TCHAR szAppName[] = TEXT("EndJoin");
        HWND         hwnd;
        MSG          msg;
        WNDCLASSEX     wndclass;
        wndclass.style = CS_HREDRAW | CS_VREDRAW;
        wndclass.cbSize = sizeof(WNDCLASSEX);
        wndclass.lpfnWndProc = WndProc;
        wndclass.cbClsExtra = 0;
        wndclass.cbWndExtra = 0;
        wndclass.hInstance = hInstance;
        wndclass.hIcon = LoadIcon(hInstance, szAppName);
        wndclass.hIconSm = LoadIcon(hInstance, szAppName);
        wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
        wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
        wndclass.lpszMenuName = NULL;
        wndclass.lpszClassName = szAppName;
        if (!RegisterClassEx(&wndclass))
        {
            MessageBox(NULL, TEXT("This program requires Windows NT!"),
                       szAppName, MB_ICONERROR);
            return 0;
        }
    
        hwnd = CreateWindow(szAppName,                  // window class name
                            TEXT("Ends and Joins Demo"), // window caption
                            WS_OVERLAPPEDWINDOW,        // window style
                            CW_USEDEFAULT,              // initial x position
                            CW_USEDEFAULT,              // initial y position
                            CW_USEDEFAULT,              // initial x size
                            CW_USEDEFAULT,              // initial y size
                            NULL,                       // parent window handle
                            NULL,                       // window menu handle
                            hInstance,                  // program instance handle
                            NULL);                     // creation parameters
    
        ShowWindow(hwnd, iCmdShow);
        UpdateWindow(hwnd);
    
        while (GetMessage(&msg, NULL, 0, 0))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        return msg.wParam;
    }
    LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        static int iEnd[] = { PS_ENDCAP_ROUND, PS_ENDCAP_SQUARE, PS_ENDCAP_FLAT };
        static int iJoin[] = { PS_JOIN_ROUND, PS_JOIN_BEVEL, PS_JOIN_MITER };
        static int cxClient, cyClient;
        HDC         hdc;
        PAINTSTRUCT ps;
        static LOGBRUSH    lb;
    
        switch (message)
        {
        case WM_CREATE:
            lb.lbStyle = BS_SOLID;
            lb.lbColor = RGB(128, 128, 128);
            lb.lbHatch = 0;
            return 0;
        case WM_SIZE:
            cxClient = LOWORD(lParam);
            cyClient = LOWORD(lParam);
            return 0;
        case WM_PAINT:
            hdc = BeginPaint(hwnd, &ps);
    
            SetMapMode(hdc, MM_ANISOTROPIC);
            SetWindowExtEx(hdc, 100, 100, NULL);
            SetViewportExtEx(hdc, cxClient, cyClient, NULL);
            for (int i = 0; i < 3; i++)
            {
                SelectObject(hdc, ExtCreatePen(PS_SOLID | PS_GEOMETRIC |
                    iEnd[i] | iJoin[i], 10, &lb, 0, NULL));
                BeginPath(hdc);
                //用扩展画笔画出来。
                MoveToEx(hdc, 10 + 30 * i, 25, NULL);
                LineTo(hdc, 20 + 30 * i, 75);
                LineTo(hdc, 30 + 30 * i, 25);
                EndPath(hdc);
                StrokePath(hdc);
                DeleteObject(SelectObject(hdc, GetStockObject(BLACK_PEN)));
    
                //写宽度为1为画笔写出3个V
                MoveToEx(hdc, 10 + 30 * i, 25, NULL);
                LineTo(hdc, 20 + 30 * i, 75);
                LineTo(hdc, 30 + 30 * i, 25);
    
            }
    
            EndPaint(hwnd, &ps);
            return 0;
    
        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
        }
        return DefWindowProc(hwnd, message, wParam, lParam);
    }

    17.6.3 四个范例程序

    (1)FontOut1程序

       ①定义路径:

        BeginPath(hdc);

        TextOut(…); //此处是在定义的路径,并不会在GDI中立即显示出来

        EndPath(hdc)

      ②StrokePath(hdc); //用当前画笔描边路径

      ③默认的文本背景模式是OPAQUE,所以文本框和字符轮廓都是路径的一部分。

    【FontOut1程序】

     

    /*------------------------------------------------
    FONTOUT1 —— Using Path to Outline Font
    (c) Charles Petzold,1998
    -------------------------------------------------*/
    #include <windows.h>
    #include "EzFont.h"
    TCHAR szAppName[] = TEXT("FontOut1");
    TCHAR szTitle[] = TEXT("FontOut1:Using Path to Outline Font");
    void PaintRoutine(HWND hwnd, HDC hdc, int cxArea, int cyArea)
    {
        static TCHAR szString[] = TEXT("Outline");
        HFONT  hFont;
        SIZE  size;
        //创建144磅的字体
        hFont = EzCreateFont(hdc, TEXT("Times New Roman"), 1440, 0, 0, TRUE);
        SelectObject(hdc, hFont);
    
        GetTextExtentPoint32(hdc, szString, lstrlen(szString), &size);
        //开始绘制路径,但保存在GDI内部,并不在DC上显示出来
        BeginPath(hdc);
    
        //在中间位置显示出来
        //注意:输出文本包含两个部分,1个是文本框,一个是字符部分,所有在默认的SetBkMode(OPAQUE)模式
        //下,文本框的边框也会被当成一条路径来画,因此该示例用画笔描边路径后会有一个边框,也就是
        //文本框的轮廓也得了路径的一部分。
        TextOut(hdc, (cxArea - size.cx) / 2, (cyArea - size.cy) / 2, szString, lstrlen(szString));
        EndPath(hdc);
        StrokePath(hdc);  //用当前画笔描边路径
        SelectObject(hdc, GetStockObject(SYSTEM_FONT));
        DeleteObject(hFont);
    }

    //FontTest.c

    /*------------------------------------------------------------
    FONTTEST.C -- Test of FONT
    (c) Charles Petzold, 1998
    ------------------------------------------------------------*/
    #include <windows.h>
    #include "EzFont.h"
    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
    extern TCHAR szAppName[];
    extern TCHAR szTitle[];
    void PaintRoutine(HWND hwnd, HDC hdc, int cxArea, int cyArea);
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                       PSTR szCmdLine, int iCmdShow)
    {
        HWND         hwnd;
        MSG          msg;
        WNDCLASSEX     wndclass;
        wndclass.style = CS_HREDRAW | CS_VREDRAW;
        wndclass.cbSize = sizeof(WNDCLASSEX);
        wndclass.lpfnWndProc = WndProc;
        wndclass.cbClsExtra = 0;
        wndclass.cbWndExtra = 0;
        wndclass.hInstance = hInstance;
        wndclass.hIcon = LoadIcon(hInstance, szAppName);
        wndclass.hIconSm = LoadIcon(hInstance, szAppName);
        wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
        wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
        wndclass.lpszMenuName = NULL;
        wndclass.lpszClassName = szAppName;
        if (!RegisterClassEx(&wndclass))
        {
            MessageBox(NULL, TEXT("This program requires Windows NT!"),
                       szAppName, MB_ICONERROR);
            return 0;
        }
    
        hwnd = CreateWindow(szAppName,                  // window class name
                            szTitle, // window caption
                            WS_OVERLAPPEDWINDOW,        // window style
                            CW_USEDEFAULT,              // initial x position
                            CW_USEDEFAULT,              // initial y position
                            CW_USEDEFAULT,              // initial x size
                            CW_USEDEFAULT,              // initial y size
                            NULL,                       // parent window handle
                            NULL,                       // window menu handle
                            hInstance,                  // program instance handle
                            NULL);                     // creation parameters
    
        ShowWindow(hwnd, iCmdShow);
        UpdateWindow(hwnd);
    
        while (GetMessage(&msg, NULL, 0, 0))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        return msg.wParam;
    }
    LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        HDC         hdc;
        PAINTSTRUCT ps;
        static int cxClient, cyClient;
    
        switch (message)
        {
        case WM_SIZE:
            cxClient = LOWORD(lParam);
            cyClient = HIWORD(lParam);
            return 0;
        case WM_PAINT:
            hdc = BeginPaint(hwnd, &ps);
    
            PaintRoutine(hwnd, hdc, cxClient, cyClient);
            EndPaint(hwnd, &ps);
            return 0;
    
        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
        }
        return DefWindowProc(hwnd, message, wParam, lParam);
    }

    //EzFont.h

    /*----------------------------------------------------------
    EZFONT.H  header file
    ------------------------------------------------------------*/
    #pragma  once 
    #include <windows.h>
    //iDeciPtHeight:字体高度:(单位1/10磅)如,12磅字体时,iDeciPtHeight=120
    //iDecPtWidth:字体宽度(与上面单位一样)
    //iAttributes:字体属性,如粗、斜、下划线、删除线等
    //fLogRes:是否使用逻辑分辨率
    HFONT EzCreateFont(HDC hdc, TCHAR* szFaceName, int iDeciPtHeight,
                       int iDeciPtWidth, int iAttributes, BOOL fLogRes);
    #define EZ_ATTR_BOLD        1
    #define EZ_ATTR_ITATIC      2
    #define EZ_ATTR_UNDERLINE   4
    #define Ez_ATTR_STRIKEOUT   8

    //EzFont.c

    /*-------------------------------------------------------------
    EZFONT.C -- Easy Font Creation
    (c) Charles Petzold, 1998
    -------------------------------------------------------------*/
    #include <windows.h>
    #include <math.h>
    #include "EzFont.h"
    HFONT EzCreateFont(HDC hdc, TCHAR* szFaceName, int iDeciPtHeight,
                       int iDeciPtWidth, int iAttributes, BOOL fLogRes)
    {
        HFONT hFont;
        LOGFONT lf;
        TEXTMETRIC tm;
        FLOAT  cxDpi, cyDpi;
        POINT pt;
        SaveDC(hdc);
        //设置高级图形模式,此模式下可以通过矩阵实现逻辑坐标到设备坐标的转换。
        SetGraphicsMode(hdc, GM_ADVANCED);
        ModifyWorldTransform(hdc, NULL, MWT_IDENTITY); //恢复变换到初始状态
        SetViewportOrgEx(hdc, 0, 0, NULL);
        SetWindowOrgEx(hdc, 0, 0, NULL);
        if (fLogRes)
        {
            //使用逻辑分辨率(单位:像素/英寸)
            cxDpi = (FLOAT)GetDeviceCaps(hdc, LOGPIXELSX);
            cyDpi = (FLOAT)GetDeviceCaps(hdc, LOGPIXELSY);
        } else
        {
            //实际的分辨率(单位:像素/英寸)
            cxDpi = (FLOAT)(25.4 * GetDeviceCaps(hdc, HORZRES) /
                            GetDeviceCaps(hdc, HORZSIZE));
            cyDpi = (FLOAT)(25.4 * GetDeviceCaps(hdc, VERTRES) /
                            GetDeviceCaps(hdc, VERTSIZE));  //vertsize单位为mm
        }
        //求出指定磅值的字体,需要多少像素点
        pt.x = (int)(iDeciPtWidth* cxDpi / 72);  //像素大小(设备单位)
        pt.y = (int)(iDeciPtHeight* cyDpi / 72); //像素大小(设备单位)
        DPtoLP(hdc, &pt, 1); //将像素大小由设备单位转为逻辑单位,也就是字体在逻辑坐标系中的大小
        lf.lfHeight = -(int)(fabs(pt.y) / 10.0 + 0.5); //加0.5是为了向上取整
        lf.lfWidth = 0; //注意这里要先设0,因为系统根据lfHeight匹配字体,会得到其固有的width
        //而iDeciPtWidth会因高级图形模式允许对字体进行拉伸和缩放。
        lf.lfEscapement = 0;
        lf.lfOrientation = 0;
        lf.lfWeight = iAttributes & EZ_ATTR_BOLD ? 700 : 0;
        lf.lfItalic = iAttributes & EZ_ATTR_ITATIC ? 1 : 0;
        lf.lfUnderline = iAttributes& EZ_ATTR_UNDERLINE ? 1 : 0;
        lf.lfStrikeOut = iAttributes& Ez_ATTR_STRIKEOUT ? 1 : 0;
        lf.lfCharSet = DEFAULT_CHARSET; //默认字符集
        lf.lfOutPrecision = 0;
        lf.lfClipPrecision = 0;
        lf.lfQuality = 0;
        lf.lfPitchAndFamily = 0;
    
        lstrcpy(lf.lfFaceName, szFaceName);
        hFont = CreateFontIndirect(&lf);
        if (iDeciPtWidth != 0)
        {
            hFont = (HFONT)SelectObject(hdc, hFont); //选入,并返回旧字体
            GetTextMetrics(hdc, &tm); //获取新字体信息
            DeleteObject(SelectObject(hdc, hFont));//将旧的选入,交并删除新的字体
            //字体的被左右拉伸,能这样实现的前提是设为高级图形模式,即SetGraphicsMode(hdc, GM_ADVANCED);
            lf.lfWidth = (int)(tm.tmAveCharWidth*fabs(pt.x) / fabs(pt.y) + 0.5);
            hFont = CreateFontIndirect(&lf);
        }
        RestoreDC(hdc, -1);
        return hFont;
    }

    (2)FontOut2程序

      ①使用ExCreatePen创建的画笔,而不是默认的画笔来描边路径

      ②本例创建一个宽3 个像素(1/24英寸)的红色虚线画笔

      ③也可以给路径填充颜色或图案(用FillPath或StrokeAndFillPath函数)

    【FontOut2程序】

     

    /*------------------------------------------------
    FONTOUT2 —— Using Path to Outline Font
    (c) Charles Petzold,1998
    -------------------------------------------------*/
    #include <windows.h>
    #include "..\FontOut1\EzFont.h"
    TCHAR szAppName[] = TEXT("FontOut2");
    TCHAR szTitle[] = TEXT("FontOut2:Using Path to Outline Font");
    void PaintRoutine(HWND hwnd, HDC hdc, int cxArea, int cyArea)
    {
        static TCHAR szString[] = TEXT("Outline");
        HFONT  hFont;
        SIZE  size;
        LOGBRUSH lb;
        //创建144磅的字体
        hFont = EzCreateFont(hdc, TEXT("Times New Roman"), 1440, 0, 0, TRUE);
        SelectObject(hdc, hFont);
        SetBkMode(hdc, TRANSPARENT);  //设置为透明背景,则文本框(含轮廓线将不被创建)
        GetTextExtentPoint32(hdc, szString, lstrlen(szString), &size);
        //开始绘制路径,但保存在GDI内部,并不在DC上显示出来
        BeginPath(hdc);
    
        //在中间位置显示出来
        //注意:本例SetBkMode(hdc,TRANSPARENT)为透明模式,所以只有字符的轮廓,而没有文本框的轮廓
        TextOut(hdc, (cxArea - size.cx) / 2, (cyArea - size.cy) / 2, szString, lstrlen(szString));
        EndPath(hdc);
        lb.lbColor = RGB(255, 0, 0);
        lb.lbStyle = BS_SOLID;
        lb.lbHatch = 0;
        SelectObject(hdc, ExtCreatePen(PS_GEOMETRIC | PS_DOT,
            GetDeviceCaps(hdc, LOGPIXELSY) / 24, &lb, 0, NULL));  //创建3像素的点线
        StrokePath(hdc);  //用当前画笔描边路径
        DeleteObject(SelectObject(hdc, GetStockObject(BLACK_PEN)));
        SelectObject(hdc, GetStockObject(SYSTEM_FONT));
        DeleteObject(hFont);
    }

      //EzFont.h、EzFont.c、FontTest.c与本节中的FontOut1程序相同。

    (3)FillFont程序

      ①使用默认画笔绘制路径轮廓,用HS_DIAGCROSS样式创建红色阴影线填充

      ②创建路径时,设置背影为TRANSPARENT。即路径只保存字符的轮廓,不保留文本框的轮廓。

      ③描边并填充路径时,使用OPAQUE模式,因为路径内部的区域,其要用阴影线填充。

      ④注意:当路径转为区域时,会根据将路径包围的范围,划分成若干个区域。如本例中当绘制路径并设置为OPAQUE里,整个文本框内部并被文字划分成若干个区域,若干个区域的并集就是文本框的大小。所以当本例中第1个SetBkMode被注释掉,也就是默认的OPAQUE时,则填充区域视多边形的填充模式而定,如果设为WINDING模式,则填充整个文本框,若设为ALTERNATE,则填充文本框内部除去字符以外的部分。
    【FillFont程序】

     

    /*------------------------------------------------
    FONTFILL —— Using Path to Fill Font
    (c) Charles Petzold,1998
    -------------------------------------------------*/
    #include <windows.h>
    #include "..\FontOut1\EzFont.h"
    
    TCHAR szAppName[] = TEXT("FontOut2");
    TCHAR szTitle[] = TEXT("FontOut2:Using Path to Outline Font");
    void PaintRoutine(HWND hwnd, HDC hdc, int cxArea, int cyArea)
    {
        static TCHAR szString[] = TEXT("FillFont");
        HFONT  hFont;
        SIZE  size;
        //创建144磅的字体
        hFont = EzCreateFont(hdc, TEXT("Times New Roman"), 1440, 0, 0, TRUE);
        SelectObject(hdc, hFont);
        //设置为透明背景,则文本框(含轮廓线将不被创建)
        SetBkMode(hdc, TRANSPARENT);  //如果该句被注释掉,则路径中包含文本框和字符轮廓
        GetTextExtentPoint32(hdc, szString, lstrlen(szString), &size);
        //开始绘制路径,但保存在GDI内部,并不在DC上显示出来
        BeginPath(hdc);
    
        //在中间位置显示出来
        //注意:本例SetBkMode(hdc,TRANSPARENT)为透明模式,所以只有字符的轮廓,而没有文本框的轮廓
        TextOut(hdc, (cxArea - size.cx) / 2, (cyArea - size.cy) / 2, szString, lstrlen(szString));
        EndPath(hdc);
        //创建带阴影线的画刷
        SelectObject(hdc, CreateHatchBrush(HS_DIAGCROSS, RGB(255, 0, 0)));
        SetBkMode(hdc, OPAQUE);
        //SetPolyFillMode(hdc, WINDING);  //默认的填充模式为ALTERNATE(交替)填充
        //当第1个SetBkMode为OPAQUE,而此处为WINDING
        //时,会填充整个文本框(含字符内部),如果
        //为ALTERNATE,则填充文本框内部除(字符的部分)
        //当第1个SetBkMode为TRANSPARENT时,不管此处为
        //WINDING还是ALTERNATE,则只填充字体内部区域。
        StrokeAndFillPath(hdc);  //用默认画笔描边,并用刚创建的画刷填充路径。
        DeleteObject(SelectObject(hdc, GetStockObject(WHITE_BRUSH)));
        SelectObject(hdc, GetStockObject(SYSTEM_FONT));
        DeleteObject(hFont);
    }
       //EzFont.h、EzFont.c、FontTest.c与本节中的FontOut1程序相同。

    (4)FontClip程序

       ①先用TextOut画出路径,再将路径通过SelectClipPath设为裁剪区域

       ②如果绘制路径时,将SetBkMode设为TRANSPARENT,则区域为字体轮廓的内部。如果设为OPAQUE,则区域为整个文本框。
    【FontClip程序】

     

    /*------------------------------------------------
    FONTCLIP —— Using Path for Clipping on Font
    (c) Charles Petzold,1998
    -------------------------------------------------*/
    #include <windows.h>
    #include "..\FontOut1\EzFont.h"
    
    TCHAR szAppName[] = TEXT("FontClip");
    TCHAR szTitle[] = TEXT("FontClip:Using Path for Clipping on Font");
    void PaintRoutine(HWND hwnd, HDC hdc, int cxArea, int cyArea)
    {
        static TCHAR szString[] = TEXT("FillClip");
        HFONT  hFont;
        SIZE  size;
        int y, iOffset;
        POINT pt[4];
        //创建120磅的字体
        hFont = EzCreateFont(hdc, TEXT("Times New Roman"), 1200, 0, 0, TRUE);
        SelectObject(hdc, hFont);
        //设置为透明背景,则文本框(含轮廓线将不被创建)
        //SetBkMode(hdc,TRANSPARENT);  //如果该句被注释掉,则路径中包含文本框和字符轮廓
        GetTextExtentPoint32(hdc, szString, lstrlen(szString), &size);
        //开始绘制路径,但保存在GDI内部,并不在DC上显示出来
        BeginPath(hdc);
    
        //在中间位置显示出来
        //注意:本例SetBkMode(hdc,TRANSPARENT)为透明模式,所以只有字符的轮廓,而没有文本框的轮廓
        TextOut(hdc, (cxArea - size.cx) / 2, (cyArea - size.cy) / 2, szString, lstrlen(szString));
        EndPath(hdc);
        //将路径设为裁剪区域
        //SetPolyFillMode(hdc, WINDING);  
        SelectClipPath(hdc, RGN_COPY);  //1、如果SetBkMode(OPAQUE),当WINDING模式时,则整个文本框为裁剪区域
        //设为ALTERNATE时,则文本框除文字部分以外的区域为裁剪区域
        //2、如果SetBkMode(TRANSPARENT),不管是ALTERNATE或WINDING模式,
        //裁剪区域均为字符内部的区域。(与上面FontFill程序的原理是一样的。)
        //绘制Bezier样条线
        iOffset = (cxArea + cyArea) / 4;
        for (y = -iOffset; y < cyArea + iOffset; y++)
        {
            pt[0].x = 0;
            pt[0].y = y;
            pt[1].x = cxArea / 3;
            pt[1].y = y + iOffset;
            pt[2].x = 2 * cxArea / 3;
            pt[2].y = y - iOffset;
            pt[3].x = cxArea;
            pt[3].y = y;
            SelectObject(hdc, CreatePen(PS_SOLID, 1, RGB(rand() % 256, rand() % 256, rand() % 256)));
            PolyBezier(hdc, pt, 4);
            DeleteObject(SelectObject(hdc, GetStockObject(BLACK_PEN)));
        }
        SelectObject(hdc, GetStockObject(SYSTEM_FONT));
        DeleteObject(hFont);
    }

       //EzFont.h、EzFont.c、FontTest.c与本节中的FontOut1程序相同。

  • 相关阅读:
    紫色飞猪的研发之旅--07client-go实现进入pod模拟终端登录
    紫色飞猪的研发之旅--06go自定义状态码
    紫色飞猪的研发之旅--05go封装http请求
    紫色飞猪的研发之旅--04client-go客户端
    紫色飞猪的研发之旅--03golang:获取cookie
    支持remote write和exemplar的prometheus服务
    从头编写一个时序数据库
    解析Prometheus PromQL
    老板:把系统从单体架构升级到集群架构!
    小白自制Linux开发板 三. Linux内核与文件系统移植
  • 原文地址:https://www.cnblogs.com/5iedu/p/4701553.html
Copyright © 2020-2023  润新知