zoukankan      html  css  js  c++  java
  • (转)用AGG实现高质量图形输出(四)

    AGG的字符输出

    字符输出,对于AGG来说,这个功能可以处于显示流程的 不同位置。比如字体引擎可直接处于“Scanline Rasterizer”层向渲染器提供已处理完毕的扫描线,也可以处于“Vertex Source顶点源”层提供字体的顶点数据。

    下面,我们开始学习AGG不同的字符输出方式。如没有特殊说明,所以示例代码都基于此处代码

    方式一、使用gsv_text对象

    gsv_text属于顶点源层的对象,它的用法也很简单,直接看下例:

    引用头文件:#include <agg_gsv_text.h>

    在on_draw()方法的最后加入下面的代码

    // gsv_text类
        agg::gsv_text txt;
        agg::conv_stroke<agg::gsv_text> cstxt(txt);
        // 设置大小及是否反转
        txt.flip(true);
        txt.size(18);
        // 设置位置和文字
        txt.start_point(20,100);
        txt.text("cpp");
        // 以红色输出上面的文字
        ras.add_path(cstxt);
        agg::render_scanlines_aa_solid(ras,sl,renb,agg::rgba(1,0,0));
        // 设置新的位置和文字
        txt.start_point(20+txt.text_width(),100);
        txt.text("prog.com");
        // 以蓝色输出上面的文字
        ras.add_path(cstxt);
        agg::render_scanlines_aa_solid(ras,sl,renb,agg::rgba(0,0,1));

    显示效果

    20090901091523355

    注:gsv_text的flip ()方法指出是否上下反转输出,这里设置了flip是因为在Windows下agg::platform_support的rbuf_window()其 实是一个DIB缓存,它的方向是从下到上的。

    gsv_text必须用conv_stroke转 换才能正确输出文字,否则会被当作多边形处理。为了使用方便,AGG提供了gsv_text_outline包 装,它实现了conv_stroke和坐标转换,代码很短:

    template<class Transformer = trans_affine> class gsv_text_outline
        {
        public:
            gsv_text_outline(gsv_text& text, const Transformer& trans) :
              m_polyline(text),
              m_trans(m_polyline, trans){}
         
            void width(double w){
                m_polyline.width(w);
            }
         
            void transformer(const Transformer* trans){
                m_trans->transformer(trans);
            }
         
            void rewind(unsigned path_id) {
                m_trans.rewind(path_id);
                m_polyline.line_join(round_join);
                m_polyline.line_cap(round_cap);
            }
         
            unsigned vertex(double* x, double* y) {
                return m_trans.vertex(x, y);
            }
         
        private:
            conv_stroke<gsv_text> m_polyline;
            conv_transform<conv_stroke<gsv_text>, Transformer> m_trans;
        };

    我们使用gsv_text_outline重写上面的代码:

    #include <agg_gsv_text.h>
        #include <agg_trans_single_path.h>
        ...
        /////////////////////////////////////////////////
        // gsv_text及gsv_text_outline
        agg::gsv_text txt;
        agg::trans_single_path tran_path; //使用trans_single_path作为变换器
        agg::gsv_text_outline<agg::trans_single_path> txtol(txt,tran_path);
        // 设置变换器
        tran_path.add_path(ell);
        /////////////////////////////////////////////////
        // 设置大小及是否反转
        txt.flip(true);
        txt.size(24);
        // 设置位置和文字
        txt.start_point(0,0);
        txt.text("cpp");
        // 以红色输出上面的文字
        ras.add_path(txtol);
        agg::render_scanlines_aa_solid(ras,sl,renb,agg::rgba(1,0,0));
         
        // 设置新的位置和文字
        txt.start_point(0+txt.text_width(),0);
        txt.text("prog.com");
        // 以蓝色输出上面的文字
        ras.add_path(txtol);
        agg::render_scanlines_aa_solid(ras,sl,renb,agg::rgba(0,0,1));

    显示效果

    20090901091523201

    gsv_text的使用很简单,不过要了解的一点是:它只能输出ASCII可显示字符,对于汉字是无能为力的(你可以试试输出"C++编程")。如果要输出汉字,我 们得继续寻找其它字符输出方式。

    方式二、使用字体引擎(Font Engine)

    AGG的字体引擎利用WinAPI:GetGlyphOutline或FreeType库得到字体数据(字模),它可以处于 “Scanline Rasterizer”层或“顶点源”层。要使用字体引擎,要把相应的字体引擎源码(agg_font_win32_tt.cpp或 agg_font_freetype.cpp)加入项目一起编译。

    头文件

    #include &lt;agg_font_win32_tt.h&gt;
    #include &lt;agg_font_freetype.h&gt;

    注意,它们都有自己的文件夹,不是在agg的include文件夹里。

    类型
    agg::font_engine_win32_tt_int16
    agg::font_engine_win32_tt_int32
    agg::font_engine_freetype_int16
    agg::font_engine_freetype_int32

    显然,前两个利用WinAPI实现,后两个利用FreeType库实现。类型后面的_int16或_int32后缀用于指定坐标单位, 一般int16已经可以满足要求。

    成员类型定义:
    typedef path_adaptor_type 把字体数据包装成顶点源的类
    typedef gray8_adaptor_type 把字体数据包装成Scanline Rasterizer的类
    typedef mono_adaptor_type 把字体数据包装成Scanline Rasterizer的类,但无AA效果
    成员属性:
    double: height 字体高度,单位为Point(和Word里的单位一样)
    double: width 字体宽度,单位为Point*2.4。0表示规则大小(height/2.4)
    bool: italic 斜体
    bool: flip_y 上下翻转
    bool: hinting 字体修正
    unsigned: resolution 字体解析度,单位为dpi
    成员方法:
    void transform(const trans_affine& affine); 按矩阵变换
    bool create_font(const char* typeface_, glyph_rendering ren_type);

    font_engine_win32_tt_*专有方法
    建立字体,typeface_为字体名,ren_type稍后再说

    bool load_font(const char* font_name,
        unsigned face_index,
        glyph_rendering ren_type,
        const char* font_mem = 0,
        const long font_mem_size = 0);

    font_engine_freetype_*专有方法
    建立字体,font_name是字体文件名或字体名

    bool prepare_glyph(unsigned glyph_code)
    unsigned data_size() const
    void write_glyph_to(int8u* data) const

    得到字体数据(字模)所需方法

    字体引擎的create_font()方法和load_font()方法需要一个glyph_rendering类型的ren_type参数,它决定了字 体数据的形式。三个成员类型定义:path_adaptor_type、gray8_adaptor_type和mono_adaptor_type所包 装的字体数据是 不一样的,只有与ren_type参数对应才能生成正确的AGG显示节点。

    glyph_rendering是一个枚举类型,定义是:

    enum agg::glyph_rendering{
            glyph_ren_native_mono,   //对应mono_adaptor_type
            glyph_ren_native_gray8,   //对应gray8_adaptor_type
            glyph_ren_outline,    //对应path_adaptor_type
            glyph_ren_agg_mono,   //对应mono_adaptor_type
            glyph_ren_agg_gray8    //对应gray8_adaptor_type
        };
    示例代码1 - 从顶点源层输出文字
    typedef agg::font_engine_win32_tt_int16 fe_type;
        typedef fe_type::path_adaptor_type vs_type;
        // 字体引擎
        fe_type fe( ::GetDC(::GetActiveWindow()) ); //注意,实际应用时要释放HDC
        fe.height(36.0);
        fe.flip_y(true);
        fe.hinting(true);
        // 注意后面的glyph_rendering ren_type参数
        fe.create_font("黑体",agg::glyph_ren_outline);
        // 字体串
        wchar_t *s = L"C++编程";
        // 存放字体数据
        std::vector<agg::int8u> data;
        // 顶点源
        vs_type vs;
        // 注意这里,使用conv_curve转换
        agg::conv_curve<vs_type> ccvs(vs);
        // 字符输出的位置
        int x=20,y=100;
        for(;*s;s++)
        {
            // 让字体引擎准备好字体数据
            if(!fe.prepare_glyph(*s)) continue;
            // 把字体数据放到容器里
            data.resize( fe.data_size() );
            fe.write_glyph_to( &data[0] );
            // 从字体数据中得到顶点源
            vs.init(&data[0], data.size(), x, y);
            // 移动输出位置
            x += fe.advance_x();
            y += fe.advance_y();
            // 输出
            ras.add_path(ccvs);
            agg::render_scanlines_aa_solid(ras,sl,renb,agg::rgba(0,0,1));
        }

    由于字体顶点源可能会包含带Curve命令的顶点,所以要用conv_curve来 转换。你可以试试去掉这层转换,字符'C' 就不会那么平滑了。

    示例代码2 - 从Scanline Rasterizer层输出文字
    // 字体引擎类型定义
        typedef agg::font_engine_win32_tt_int16 fe_type;
        typedef fe_type::gray8_adaptor_type ras_type;
        typedef ras_type::embedded_scanline sl_type;
        // 字体引擎
        fe_type fe( ::GetDC(::GetActiveWindow()) ); //注意,实际应用时要释放HDC
        fe.height(36.0);
        fe.flip_y(true);
        fe.hinting(true);
        // 注意后面的glyph_rendering ren_type参数
        fe.create_font("黑体",agg::glyph_ren_agg_gray8);
        // 字体串
        wchar_t *s = L"C++编程";
        // 存放字体数据
        std::vector<agg::int8u> data;
        // Rasterizer和Scanline
        ras_type ras_font;
        sl_type sl_font;
        // 字符输出的位置
        int x=20,y=100;
        for(;*s;s++)
        {
            // 让字体引擎准备好字体数据
            if(!fe.prepare_glyph(*s)) continue;
            // 把字体数据放到容器里
            data.resize( fe.data_size() );
            fe.write_glyph_to( &data[0] );
            // 从字体数据中得到Rasterizer
            ras_font.init(&data[0], data.size(), x, y);
            // 移动输出位置
            x += fe.advance_x();
            y += fe.advance_y();
            // 输出
            agg::render_scanlines_aa_solid(ras_font,sl_font,renb,agg::rgba(0,0,1));
        }
    显示效果

    20090901091523320

    Linux、 FreeBSD等开源操作系统里一般使用FreeType来显示文字,Windows下的一些软件如Foxit也有FreeType的身影。

    AGG的font_engine_freetype_int16字 体引擎就使用FreeType来取得字模,在Windows里,在使用font_engine_freetype_int16之前,我们得先编译好 FreeType:

    1. www.freetype.org下 载FreeType2,偶下载的是目前最新的freetype-2.3.9,解压。
    2. 以VC2005 Express为例,直接打开\builds\win32\vc2005里的freetype.sln编译即可。(不过这个版本的 freetype.sln好 像好点问题,要用文本编辑器打开,把第一行“Microsoft Visual Studio Solution File, Format Version 10.00”后面的“10.00”改成“9.00”才行)
    3. 对于其它编译器,如C++Builder,直接把\docs\INSTALL.ANY里列出的文件加入项目即可(不过加入这些东 西还真是比较麻烦,可以点这里下载C++Builder的FreeType2库编译工程)。
    4. 把编译后的库文件(在\objs\win32里,注意编译版本)加入项目,并设置include路径为freetype- 2.3.9\include就可 以了
    AGG使用FreeType的源代码:
    typedef agg::font_engine_freetype_int16 fe_type;
        typedef fe_type::path_adaptor_type vs_type;
         
        fe_type fe;
        if(!fe.load_font("c:\\windows\\fonts\\simhei.ttf",0,agg::glyph_ren_outline)) return;
        fe.height(36.0);
        fe.flip_y(true);
        fe.hinting(true);
         
        wchar_t *s = L"C++编程";
        std::vector<agg::int8u> data;
        vs_type vs;
        agg::conv_curve<vs_type> ccvs(vs);
        int x=20,y=100;
        for(;*s;s++)
        {
            if(!fe.prepare_glyph(*s)) continue;
            data.resize( fe.data_size() );
            fe.write_glyph_to( &data[0] );
            vs.init(&data[0], data.size(), x, y);
            x += fe.advance_x();
            y += fe.advance_y();
            ras.add_path(ccvs);
            agg::render_scanlines_aa_solid(ras,sl,renb,agg::rgba(0,0,1));
        }

    方式三、使用字体缓存管理器

    每次都重新读字模是很费时的,比如前面的例子,"C++" 里的两个'+' 就读两次字模,效率可以想象。

    一个好的办法是把已读出来的字模缓存起来,下次再遇到这个字时就不用从字体引擎里读取了,AGG提供的font_cache_manager类就是 负责这项工作的。

    头文件
    #include "agg_font_cache_manager.h"
    类型
    template<class FontEngine> class font_cache_manager;

    模板参数FontEngine指定管理器所用的字体引擎。另外构造参数也是FontEngine。

    成员方法
    const glyph_cache* glyph(unsigned glyph_code);

    获得字模并缓存,glyph_cache类的定义是:

    struct glyph_cache
    {
     unsigned glyph_index;
     int8u* data;
     unsigned data_size;
     glyph_data_type data_type;
     rect_i bounds;
     double advance_x;
     double advance_y;
    };
    path_adaptor_type& path_adaptor();
    字体引擎的path_adaptor_type实例
    gray8_adaptor_type&  gray8_adaptor();
    gray8_scanline_type& gray8_scanline();
    字体引擎的gray8_adaptor_type实例以及对应的Scanline
    mono_adaptor_type&   mono_adaptor();
    mono_scanline_type&  mono_scanline();
    字体引擎的mono_adaptor_type实例以及对应的Scanline
    void init_embedded_adaptors(const glyph_cache* gl,
                                double x, double y,
                                double scale=1.0);
    初始化上面的adaptor成员实例(与字体引擎的ren_type设置相关)
    bool add_kerning(double* x, double* y);
    调整坐标
    agg::font_engine_win32_tt_int16 font(dc);
        agg::font_cache_manager<
            agg::font_engine_win32_tt_int16
            > font_manager(font);
        font.height(72.0);
        font.width(0);
        font.italic(true);
        font.flip_y(true);
        font.hinting(true);
         
        font.transform(agg::trans_affine_rotation(agg::deg2rad(4.0)));
        font.create_font("宋体",agg::glyph_ren_agg_gray8);
         
        double x=10, y=72; //起始位置
        wchar_t *text = L"C++编程网";
        // 画所有字符
        for(;*text;text++)
        {
            //取字模
            const agg::glyph_cache* glyph = font_manager.glyph(*text);
            if(glyph)
            {
                // 初始化gray8_adaptor实例
                font_manager.init_embedded_adaptors(glyph, x, y);
         
                agg::render_scanlines_aa_solid(font_manager.gray8_adaptor(),
                                      font_manager.gray8_scanline(),
                                      renb, agg::rgba8(0, 0, 0));
               
                // 前进
                x += glyph->advance_x;
                y += glyph->advance_y;
            }
        }
    显示效果

    20090901091523577

    示例代码2-作为顶点源渲染:
    typedef agg::font_engine_win32_tt_int16 fe_type;
        fe_type font(GetDC(0));
        typedef agg::font_cache_manager<fe_type> fcman_type;
        fcman_type font_manager(font);
        font.height(72.0);
        font.width(0);
        font.italic(true);
        font.flip_y(true);
        font.hinting(true);
         
        font.transform(agg::trans_affine_rotation(agg::deg2rad(4.0)));
        font.create_font("宋体",agg::glyph_ren_outline);
         
        double x=10, y=72; //起始位置
        wchar_t *text = L"C++编程网";
        // 画所有字符
        for(;*text;text++)
        {
            const agg::glyph_cache* glyph = font_manager.glyph(*text);
            if(glyph)
            {
                // 准备*_adaptor
                font_manager.init_embedded_adaptors(glyph, x, y);
               
                // 先用conv_curve
                typedef agg::conv_curve<
                    fcman_type::path_adaptor_type
                > cc_pa_type;
                cc_pa_type ccpath(font_manager.path_adaptor());
         
                // 画轮廓
                typedef agg::conv_stroke<cc_pa_type> cs_cc_pa_type;
                cs_cc_pa_type csccpath(ccpath);
         
                agg::rasterizer_scanline_aa<> ras;
                agg::scanline_u8 sl;
                ras.add_path(csccpath);
                agg::render_scanlines_aa_solid(ras, sl, renb, agg::rgba8(0, 0, 0));
         
                // 前进
                x += glyph->advance_x;
                y += glyph->advance_y;
            }
        }
    显示效果

    20090901091523443

    作为本文的结尾,这里放上一个用AGG生成不规则文字窗体的代码。它综合了我们之前学到的AGG字体引擎、坐标转换、颜色渐变等几大模 块。由于AGG的抗锯齿特性,使用生 成的窗体看上去边缘过渡非常自然,几乎看不到“毛边”。

    先放上最终生成的窗体的效果:

    200909010915233752009090109152370620090901091523378

    #define _WIN32_WINNT 0x0501
        #include <windows.h>
        #include <agg_array.h>
        #include <agg_pixfmt_rgba.h>
        #include <agg_scanline_u.h>
        #include <agg_renderer_scanline.h>
        #include <../font_win32_tt/agg_font_win32_tt.h>
        #include <agg_font_cache_manager.h>
        #include <agg_span_solid.h>
        #include <agg_span_interpolator_linear.h>
        #include <agg_span_gradient.h>
        #include <agg_span_allocator.h>
        #include <agg_conv_transform.h>
        #include <agg_ellipse.h>
        #include <agg_trans_single_path.h>
         
        typedef agg::font_engine_win32_tt_int16 fe_type;
        typedef agg::font_cache_manager<fe_type> fcman_type;
        typedef agg::renderer_base<agg::pixfmt_bgra32> renb_type;
         
        // 使用指定的顶点源和线段生成器输出文字
        template<class VS, class SpanGenerator>
        void AggDrawText(renb_type &renb,
                         fcman_type &font_manager,
                         VS &vs, SpanGenerator &span_gen,
                         const wchar_t *txt)
        {
            using namespace agg;
            
            span_allocator<rgba8> span_alloc;
            rasterizer_scanline_aa<> ras;
            scanline_u8 sl;
            
            double x=0, y=0;
            for(const wchar_t *p = txt; *p; p++)
            {
                const glyph_cache* gc = font_manager.glyph(*p);
                if(gc)
                {
                    font_manager.init_embedded_adaptors(gc, x, y);
         
                    ras.add_path(vs);
                    agg::render_scanlines_aa(ras, sl, renb, span_alloc, span_gen);
         
                    x += gc->advance_x;
                    y += gc->advance_y;
                }
            }
        }
         
        // 向renb的指定位置和半径输出http://www.cppprog.com ,有环绕效果
        void DrawUrl(HDC dc, renb_type &renb,
                     double ox, double oy, double rx, double ry)
        {
            using namespace agg;
            //字体引擎
            fe_type font(dc);
            fcman_type font_manager(font);
            font.height(18.0);
            font.flip_y(true);
            font.hinting(true);
            if(!font.create_font("Comic Sans MS",agg::glyph_ren_outline)) return;
            //坐标转换管道
            typedef conv_curve<
                fcman_type::path_adaptor_type
            > cc_pa_type;
            cc_pa_type ccpath(font_manager.path_adaptor());
         
            typedef conv_transform<cc_pa_type,
                trans_single_path> ct_cc_pa_type;
            trans_single_path trans_path;
            ct_cc_pa_type ctpath(ccpath, trans_path);
            
            ellipse ell(0,0,rx,ry);
            trans_affine ellmtx;
            conv_transform<ellipse> ctell(ell, ellmtx);
            ellmtx.rotate(agg::pi);
            ellmtx.translate(ox,oy);
            trans_path.add_path(ctell);
            // 线段生成器
            span_solid<rgba8> ss;
            ss.color(rgba(1,0,0));
         
            AggDrawText(renb, font_manager, ctpath, ss, L"http://www.cppprog.com");
        }
        // 向renb的指定位置输出“C++编程”几个字,有镜象效果
        void DrawName(HDC dc, renb_type &renb, double x, double y)
        {
            using namespace agg;
            // 字体引擎
            fe_type font(dc);
            fcman_type font_manager(font);
         
            font.height(30.0);
            font.flip_y(true);
            font.hinting(true);
            if(!font.create_font("黑体",agg::glyph_ren_outline)) return;
            // 坐标转换管道
            typedef conv_curve<
                fcman_type::path_adaptor_type
            > cc_pa_type;
            cc_pa_type ccpath(font_manager.path_adaptor());
         
            typedef conv_transform<cc_pa_type> ct_cc_pa_type;
            trans_affine mtx;
            ct_cc_pa_type ctpath( ccpath, mtx );
         
            mtx.translate(50,50);
            //线段生成器
            span_solid<rgba8> ss;
            ss.color(rgba(0,0,0));
         
            AggDrawText(renb, font_manager, ctpath, ss, L"C++编程");
            // 改变坐标转换矩阵(镜像)
            mtx.reset();
            mtx.flip_y();
            mtx.translate(50,60);
         
            // 渐变线段生成器
            typedef span_interpolator_linear<> interpolator_type;
            trans_affine img_mtx;
            interpolator_type ip(img_mtx);
         
            typedef gradient_y gradientF_type;
            gradientF_type grF;
         
            typedef gradient_linear_color<rgba8> colorF_type;
            colorF_type colorF(rgba(0,0,0), rgba(0,0,0,0));
            
            typedef span_gradient<rgba8,
                interpolator_type,
                gradientF_type,
                colorF_type> span_gen_type;
            span_gen_type span_gen(ip,grF,colorF,30,80);
            
            AggDrawText(renb, font_manager, ctpath, span_gen, L"C++编程");
        }
        // 调用DrawUrl和DrawName向renb输出文字
        void DrawIt(HDC dc, renb_type &renb)
        {
            // 以透明色填充
            renb.clear(rgba(0,0,0,0));
            // 输出文字
            DrawUrl(dc, renb, 100, 50, 80, 40);
            DrawName(dc, renb, 50, 50);
        }
        // 使用AGG处理图片后与hwnd关联
        void SetLayoutWin(HWND hwnd)
        {
            // 起始位置和窗体大小
            POINT ptWinPos = {500,200};
            SIZE sizeWindow = {200, 100};
         
            // 建立DIB
            BITMAPINFO bmp_info;
            ::ZeroMemory(&bmp_info, sizeof(bmp_info));
            bmp_info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
            bmp_info.bmiHeader.biWidth = sizeWindow.cx;
            bmp_info.bmiHeader.biHeight = sizeWindow.cy;
            bmp_info.bmiHeader.biPlanes = 1;
            bmp_info.bmiHeader.biBitCount = 32;
            bmp_info.bmiHeader.biCompression = BI_RGB;
            
            HDC hdcTemp = GetDC(0);
            HDC mem_dc = ::CreateCompatibleDC(hdcTemp);
            ReleaseDC(0, hdcTemp);
         
            void* buf = NULL;
            HBITMAP bmp = ::CreateDIBSection(
                mem_dc,
                &bmp_info,
                DIB_RGB_COLORS,
                &buf,
                0, 0
            );
            
            // 把bmp与mem_dc关联,这样AGG就可以和原生GDI一起工作了
            HBITMAP temp = (HBITMAP)::SelectObject(mem_dc, bmp);
            {
                // AGG处理
                agg::rendering_buffer rbuf(
                    (unsigned char*)buf,
                    sizeWindow.cx, sizeWindow.cy,
                    -sizeWindow.cx*4);
                agg::pixfmt_bgra32 pixf(rbuf);
                renb_type renb(pixf);
                DrawIt(mem_dc,renb);
            }
         
            // 把画好的mem_dc与hwnd关联到一起
            BLENDFUNCTION m_Blend={AC_SRC_OVER,0,255,AC_SRC_ALPHA};
            POINT ptSrc = {0, 0};
            BOOL bRet = UpdateLayeredWindow(hwnd, 0, &ptWinPos,
                                            &sizeWindow, mem_dc, &ptSrc,
                                            0, &m_Blend, ULW_ALPHA);
            // 回收
            ::DeleteObject(bmp);
            ::DeleteDC(mem_dc);
        }
         
        // Windows消息处理
        LRESULT CALLBACK WndProc (HWND hwnd, UINT umsg, WPARAM wParam,
                                  LPARAM lParam)
        {
          switch (umsg)
          {
            case WM_CLOSE:
              DestroyWindow (hwnd);
              return 0;
            case WM_DESTROY:
              PostQuitMessage (0);
              return 0;
            case WM_NCHITTEST:
              return HTCAPTION;
          }
          return DefWindowProc (hwnd, umsg, wParam, lParam);
        }
         
        int APIENTRY WinMain(HINSTANCE hInstance,
                             HINSTANCE hPrevInstance,
                             LPTSTR    lpCmdLine,
                             int       nCmdShow)
        {
            WNDCLASS wc={
                0,WndProc,
                0,0,
                hInstance,
                NULL,LoadCursor(NULL, IDC_ARROW),
                (HBRUSH)(COLOR_WINDOW+1),
                0,"AGGWIN"
            };
            ::RegisterClass(&wc);
         
            HWND hWnd = ::CreateWindowEx(WS_EX_LAYERED,"AGGWIN", NULL, WS_OVERLAPPEDWINDOW,
              CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
         
            if (!hWnd) return -1;
            SetLayoutWin(hWnd);
            ::ShowWindow(hWnd, nCmdShow);
         
            // 主消息循环:
            MSG msg;
            while (GetMessage(&msg, NULL, 0, 0))
            {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
         
            return (int) msg.wParam;
        }
    <<>>
    Pop Jungle是我的新作,希望大家喜欢
  • 相关阅读:
    中国剩余定理(SCAUOJ 1077)
    uva 11426 GCD
    LA 4119 Always an integer (数论+模拟)
    uva 12003 Array Transformer (线段树套平衡树)
    uva 10253 Series-Parallel Networks (整数划分+多重集)
    LA 4123 Glenbow Museum
    uva 11361 Investigating Div-Sum Property
    2013多校训练赛第二场 总结
    uva 11174 Stand in a Line (排列组合)
    canvas 画椭圆
  • 原文地址:https://www.cnblogs.com/CoolJie/p/2032017.html
Copyright © 2011-2022 走看看