MiniGUI源码分析:GDI(1)-- GDI概览及Surface

MiniGUI源码分析--hellowworld(1) :MiniGUIMain中有什么奥秘 上一篇: MiniGUI源码分析-- 开始篇 接下来,通过剖析MiniGUI的最简单的例程,来详细说明MiniGUI程序是如何创建和运行的。 这个例程,可以从很多地方得到,凡是接触过MiniGUI的朋友,首先接触的便是这个例子,为了方便大家阅读,贴在下面 /* ** $Id: helloworld.c,v 1.38 2007-10-25 07:56:45 weiym Exp $ 阅读详情

上一篇:MiniGUI源码分析--Helloworld(3):消息概览


从本章开始,将逐步介绍MiniGUI部分GDI


GDI(Graphics Device Interface)是对绘图接口的描述,是MiniGUI的核心组成部分之一。


GDI虽然是GUI的基础,但是,它实际上不太适合作为GUI的组成部分之一的。因为GUI的核心功能在用户交互上,而不是如何绘制上。对MiniGUI来说,GDI是成也萧何败萧何:MiniGUI内置的GDI使得MiniGUI更紧凑和高效,但是由于其功能受限,使得MiniGUI在绘图精细度上,以及和其他优秀的界面库结合上,存在巨大的缺陷。由此也造成MiniGUI发展受限,无法赶上时代的潮流。


MiniGUI的GDI分成GAL、DC和Surface、位图管理、字体管理以及图元绘制(包括矩形、圆形的绘制和填充),可以用示意图表示:



GDI中涉及很多绘图的算法,这些可以通过查阅计算机图形学相关的书籍就可以了解,这不是我们的重点。我们的重点,在于了解他对显存的管理和操作。

所以,我们从Surface和DC说起。


Surface是管理显存的一个重要对象。它负责管理显存的大小、色深等信息。而且,可以把一块普通的内存看做一个显存,这样,我们就可以在内存中首先构造出该对象。

首先,看它的定义:(src/include/newgal.h)

typedef struct GAL_Surface {
    Uint32 flags;                       /* Read-only */
    GAL_PixelFormat *format;            /* Read-only */
    void *video;                        /* Read-only */
    int w, h;                           /* Read-only */
    Uint32 pitch;                       /* Read-only */
    void *pixels;                       /* Read-write */
    int offset;                         /* Private */

    /* Hardware-specific surface info */
    struct private_hwdata *hwdata;

    /* clipping information */
    GAL_Rect clip_rect;                 /* Read-only */

    /* info for fast blit mapping to other surfaces */
    struct GAL_BlitMap *map;             /* Private */

    /* format version, bumped at every change to invalidate blit maps */
    unsigned int format_version;        /* Private */

    /* Reference count -- used when freeing surface */
    int refcount;                       /* Read-mostly */
} GAL_Surface

有几个重要的成员:

format:表示像素的格式,是非常重要的成员

pxiels:是像素的地址指针

map:这是对像素做合并的时候,使用的合并方法。


其中,flags变量来标记surface的一些属性,例如,是硬件surface(surface的pixel指向的内存是显存)或者是软surface(pixel指向普通的内存)等。

由于硬surface和软surface没有太大的区别,所以我们可以先忽略这一部分。


Surface的重要的操作有:创建、删除、Surface的像素合并(BitBlt)。

Surface相关的操作都在src/newgal/surface.c中


首先,看Surface的创建过程。Surface的创建,主要是通过GAL_CreateRGBSurface函数创建的。它初始化一个Surface对象。先看下该函数的实现。

GAL_Surface * GAL_CreateRGBSurface (Uint32 flags,
            int width, int height, int depth,
            Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask)
{
    GAL_VideoDevice *video = current_video;
    GAL_VideoDevice *this  = current_video;
    GAL_Surface *screen;
    GAL_Surface *surface;

    /* Check to see if we desire the surface in video memory */
    if ( video ) {
        screen = GAL_PublicSurface;
    } else {
        screen = NULL;
    }
    if ( screen && ((screen->flags&GAL_HWSURFACE) == GAL_HWSURFACE) ) {
        if ( (flags&(GAL_SRCCOLORKEY|GAL_SRCALPHA)) != 0 ) {
            flags |= GAL_HWSURFACE;
        }
        if ( (flags & GAL_SRCCOLORKEY) == GAL_SRCCOLORKEY ) {
            if ( ! current_video->info.blit_hw_CC ) {
                flags &= ~GAL_HWSURFACE;
            }
        }
        if ( (flags & GAL_SRCALPHA) == GAL_SRCALPHA ) {
            if ( ! current_video->info.blit_hw_A ) {
                flags &= ~GAL_HWSURFACE;
            }
        }
    } else {
        flags &= ~GAL_HWSURFACE;
    }

    /* Allocate the surface */
    surface = (GAL_Surface *)malloc(sizeof(*surface));
    if ( surface == NULL ) {
        GAL_OutOfMemory();
        return(NULL);
    }
    if ((flags & GAL_HWSURFACE) == GAL_HWSURFACE)
        surface->video = current_video;
    else
        surface->video = NULL;

    surface->flags = GAL_SWSURFACE;

    if ( (flags & GAL_HWSURFACE) == GAL_HWSURFACE ) {
        depth = screen->format->BitsPerPixel;
        Rmask = screen->format->Rmask;
        Gmask = screen->format->Gmask;
        Bmask = screen->format->Bmask;
        Amask = screen->format->Amask;
    }
    surface->format = GAL_AllocFormat(depth, Rmask, Gmask, Bmask, Amask);
    if ( surface->format == NULL ) {
        free(surface);
        return(NULL);
    }
    if ( Amask ) {
        surface->flags |= GAL_SRCALPHA;
    }
    surface->w = width;
    surface->h = height;
    surface->pitch = GAL_CalculatePitch(surface);
    surface->pixels = NULL;
    surface->offset = 0;
    surface->hwdata = NULL;
    surface->map = NULL;
    surface->format_version = 0;
    GAL_SetClipRect(surface, NULL);

    /* Get the pixels */
    if ( ((flags&GAL_HWSURFACE) == GAL_SWSURFACE) || 
                (video->AllocHWSurface(this, surface) < 0) ) {
        if ( surface->w && surface->h ) {
            surface->pixels = malloc(surface->h*surface->pitch);
            if ( surface->pixels == NULL ) {
                GAL_FreeSurface(surface);
                GAL_OutOfMemory();
                return(NULL);
            }
            /* This is important for bitmaps */
            memset(surface->pixels, 0, surface->h*surface->pitch);
            surface->flags &= ~GAL_HWSURFACE;
        }
    }

    /* Allocate an empty mapping */
    surface->map = GAL_AllocBlitMap();
    if ( surface->map == NULL ) {
        GAL_FreeSurface(surface);
        return(NULL);
    }

    /* The surface is ready to go */
    surface->refcount = 1;
#ifdef CHECK_LEAKS
    ++surfaces_allocated;
#endif
    return(surface);
}
该函数创建一个GAL_Surface结构体对象,并初始化了其成员。这其中,我们需要重点注意对format成员和map成员的初始化。

对format成员,它调用了GAL_AllocFormat函数。首先,看下GAL_PixelFormat的定义:

typedef struct GAL_PixelFormat {
    GAL_Palette *palette;
    BOOL   DitheredPalette;
    Uint8  BitsPerPixel;
    Uint8  BytesPerPixel;
    Uint8  Rloss;
    Uint8  Gloss;
    Uint8  Bloss;
    Uint8  Aloss;
    Uint8  Rshift;
    Uint8  Gshift;
    Uint8  Bshift;
    Uint8  Ashift;
    Uint32 Rmask;
    Uint32 Gmask;
    Uint32 Bmask;
    Uint32 Amask;

    /* RGB color key information */
    gal_pixel colorkey;
    /* Alpha value information (per-surface alpha) */
    gal_uint8 alpha;
} GAL_PixelFormat;
palette成员主要用在8位及以下的像素中,不是考虑的重点。

BitsPerPixel是一个像素占用的位数,可以选择的是1,2,4,8,16,24,32

BytesPerPixel是一个像素占用的字节数,可以是,1,2,4等

下面的成员,按照R、G、B、A分成loss, shift, mask三组,它是相对于一个分量8位来说的,分别表示RGBA分量所丢失的位数、在像素中的偏移位数和掩码值

例如,对于16位以565格式保存的RGB像素格式来说,其高6位被R分量占用,Rloss为3,Rshift为11,Rmask则为0xF800; 中间6位被G分量占用,Gloss为2,GShift为5,Gmask为0x07E0;B分量占用剩余的5位,其中Bloss为3,Bshift为0,Bmask为0x001F,表示如下:

RRRR RGGG GGGB BBBB

用这些信息,就可以通过RGB分量计算出一个像素的值,如:

                Uint32 pixv = (r >> format->Rloss) << format->Rshift
            | (g >> format->Gloss) << format->Gshift
            | (b >> format->Bloss) << format->Bshift
            | ((a >> format->Aloss) << format->Ashift & format->Amask);

然后我们看下 GAL_AllocFormat函数的实现:

GAL_PixelFormat *GAL_AllocFormat(int bpp,
            Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask)
{
    GAL_PixelFormat *format;
    Uint32 mask;

    /* Allocate an empty pixel format structure */
    format = malloc(sizeof(*format));
    if ( format == NULL ) {
        GAL_OutOfMemory();
        return(NULL);
    }
    memset(format, 0, sizeof(*format));
    format->alpha = GAL_ALPHA_OPAQUE;

    /* Set up the format */
    format->BitsPerPixel = bpp;
    format->BytesPerPixel = (bpp+7)/8;
    format->DitheredPalette = FALSE;
    switch (bpp) {
        case 1:
            /* Create the 2 color black-white palette */
            format->palette = (GAL_Palette *)malloc(
                            sizeof(GAL_Palette));
            if ( format->palette == NULL ) {
                GAL_FreeFormat(format);
                GAL_OutOfMemory();
                return(NULL);
            }
            (format->palette)->ncolors = 2;
            (format->palette)->colors = (GAL_Color *)malloc(
                (format->palette)->ncolors*sizeof(GAL_Color));
            if ( (format->palette)->colors == NULL ) {
                GAL_FreeFormat(format);
                GAL_OutOfMemory();
                return(NULL);
            }
            format->palette->colors[0].r = 0xFF;
            format->palette->colors[0].g = 0xFF;
            format->palette->colors[0].b = 0xFF;
            format->palette->colors[1].r = 0x00;
            format->palette->colors[1].g = 0x00;
            format->palette->colors[1].b = 0x00;
            format->Rloss = 8;
            format->Gloss = 8;
            format->Bloss = 8;
            format->Aloss = 8;
            format->Rshift = 0;
            format->Gshift = 0;
            format->Bshift = 0;
            format->Ashift = 0;
            format->Rmask = 0;
            format->Gmask = 0;
            format->Bmask = 0;
            format->Amask = 0;
            break;

        case 4:
            /* Create the 16 color VGA palette */
            format->palette = (GAL_Palette *)malloc(
                            sizeof(GAL_Palette));
            if ( format->palette == NULL ) {
                GAL_FreeFormat(format);
                GAL_OutOfMemory();
                return(NULL);
            }
            (format->palette)->ncolors = 16;
            (format->palette)->colors = (GAL_Color *)malloc(
                (format->palette)->ncolors*sizeof(GAL_Color));
            if ( (format->palette)->colors == NULL ) {
                GAL_FreeFormat(format);
                GAL_OutOfMemory();
                return(NULL);
            }
            /* Punt for now, will this ever be used? */
            memset((format->palette)->colors, 0,
                (format->palette)->ncolors*sizeof(GAL_Color));

            /* Palettized formats have no mask info */
            format->Rloss = 8;
            format->Gloss = 8;
            format->Bloss = 8;
            format->Aloss = 8;
            format->Rshift = 0;
            format->Gshift = 0;
            format->Bshift = 0;
            format->Ashift = 0;
            format->Rmask = 0;
            format->Gmask = 0;
            format->Bmask = 0;
            format->Amask = 0;
            break;

        case 8:
            /* Create an empty 256 color palette */
            format->palette = (GAL_Palette *)malloc(
                            sizeof(GAL_Palette));
            if ( format->palette == NULL ) {
                GAL_FreeFormat(format);
                GAL_OutOfMemory();
                return(NULL);
            }
            (format->palette)->ncolors = 256;
            (format->palette)->colors = (GAL_Color *)malloc(
                (format->palette)->ncolors*sizeof(GAL_Color));
            if ( (format->palette)->colors == NULL ) {
                GAL_FreeFormat(format);
                GAL_OutOfMemory();
                return(NULL);
            }
            memset((format->palette)->colors, 0,
                (format->palette)->ncolors*sizeof(GAL_Color));

            /* Palettized formats have no mask info */
            format->Rloss = 8;
            format->Gloss = 8;
            format->Bloss = 8;
            format->Aloss = 8;
            format->Rshift = 0;
            format->Gshift = 0;
            format->Bshift = 0;
            format->Ashift = 0;
            format->Rmask = 0;
            format->Gmask = 0;
            format->Bmask = 0;
            format->Amask = 0;
            break;

        default:
            /* No palette, just packed pixel info */
            format->palette = NULL;
            format->Rshift = 0;
            format->Rloss = 8;
            if ( Rmask ) {
                for ( mask = Rmask; !(mask&0x01); mask >>= 1 )
                    ++format->Rshift;
                for ( ; (mask&0x01); mask >>= 1 )
                    --format->Rloss;
            }
            format->Gshift = 0;
            format->Gloss = 8;
            if ( Gmask ) {
                for ( mask = Gmask; !(mask&0x01); mask >>= 1 )
                    ++format->Gshift;
                for ( ; (mask&0x01); mask >>= 1 )
                    --format->Gloss;
            }
            format->Bshift = 0;
            format->Bloss = 8;
            if ( Bmask ) {
                for ( mask = Bmask; !(mask&0x01); mask >>= 1 )
                    ++format->Bshift;
                for ( ; (mask&0x01); mask >>= 1 )
                    --format->Bloss;
            }
            format->Ashift = 0;
            format->Aloss = 8;
            if ( Amask ) {
                for ( mask = Amask; !(mask&0x01); mask >>= 1 )
                    ++format->Ashift;
                for ( ; (mask&0x01); mask >>= 1 )
                    --format->Aloss;
            }
            format->Rmask = Rmask;
            format->Gmask = Gmask;
            format->Bmask = Bmask;
            format->Amask = Amask;
            break;
    }
    /* Calculate some standard bitmasks, if necessary 
     * Note:  This could conflict with an alpha mask, if given.
     */
    if ( (bpp > 8) && !format->Rmask && !format->Gmask && !format->Bmask ) {
        /* R-G-B */
        if ( bpp > 24 )
            bpp = 24;
        format->Rloss = 8-(bpp/3);
        format->Gloss = 8-(bpp/3)-(bpp%3);
        format->Bloss = 8-(bpp/3);
        format->Rshift = ((bpp/3)+(bpp%3))+(bpp/3);
        format->Gshift = (bpp/3);
        format->Bshift = 0;
        format->Rmask = ((0xFF>>format->Rloss)<<format->Rshift);
        format->Gmask = ((0xFF>>format->Gloss)<<format->Gshift);
        format->Bmask = ((0xFF>>format->Bloss)<<format->Bshift);
    }
    return(format);
}
代码很长,但是并不复杂。switch部分重点看default分支的代码。其余部分的代码,是当像素占用的字节数在一个字节以内的情况。这种情况下注意是通过调色板实现的,现在不常用了,不重点考虑。

default分支的代码,注意通过Rmask、Gmask、Bmask和Amask的值,计算得到loss和shift的,算法很简单。不再赘述。


另外一部分重要的代码是map成员变量的初始化。因为它关系到两个surface的混合。首先看下GAL_BitMap结构的定义

/* Blit mapping definition */
typedef struct GAL_BlitMap {
	GAL_Surface *dst;
	int identity;
	Uint8 *table;
	GAL_blit hw_blit;
	GAL_blit sw_blit;
	struct private_hwaccel *hw_data;
	struct private_swaccel *sw_data;

	/* the version count matches the destination; mismatch indicates
	   an invalid mapping */
        unsigned int format_version;
} GAL_BlitMap;

这里需要关注的重点是hw_blit和sw_blit变量,它们是主要指向blit的操作的回调。GAL_blit的定义是:

typedef int (*GAL_blit)(struct GAL_Surface *src, GAL_Rect *srcrect,
                        struct GAL_Surface *dst, GAL_Rect *dstrect);
关于它的用法,后面会详细介绍。下面看下GAL_AllocBlitMap的实现

GAL_BlitMap *GAL_AllocBlitMap(void)
{
    GAL_BlitMap *map;

    /* Allocate the empty map */
    map = (GAL_BlitMap *)malloc(sizeof(*map));
    if ( map == NULL ) {
        GAL_OutOfMemory();
        return(NULL);
    }
    memset(map, 0, sizeof(*map));

    /* Allocate the software blit data */
    map->sw_data = (struct private_swaccel *)malloc(sizeof(*map->sw_data));
    if ( map->sw_data == NULL ) {
        GAL_FreeBlitMap(map);
        GAL_OutOfMemory();
        return(NULL);
    }
    memset(map->sw_data, 0, sizeof(*map->sw_data));

    /* It's ready to go */
    return(map);
}
该函数只是做了分配空间的操作。


Surface的另外一个重要操作,就是做层之间的混合。它是通过GAL_LowerBlit来实现的(lower表示更接近于设备底层的实现),其代码如下:

int GAL_LowerBlit (GAL_Surface *src, GAL_Rect *srcrect,
                GAL_Surface *dst, GAL_Rect *dstrect)
{
    GAL_blit do_blit;

    /* Check to make sure the blit mapping is valid */
    if ( (src->map->dst != dst) ||
             (src->map->dst->format_version != src->map->format_version) ) {
        if ( GAL_MapSurface(src, dst) < 0 ) {
            return(-1);
        }
    }

    /* Figure out which blitter to use */
    if ( (src->flags & GAL_HWACCEL) == GAL_HWACCEL ) {
        do_blit = src->map->hw_blit;
    } else {
        do_blit = src->map->sw_blit;
    }
    return(do_blit(src, srcrect, dst, dstrect));
}


可以看到,它通过map的hw_blit或者sw_blit调用来实现的。

hw_blit是用硬件加速实现的函数,所以,它是由GAL层实现和设置的。每种不同的开发板有字节的实现方法,所以,这不是我们讨论的重点。

sw_blit只软件实现的混合函数,由MiniGUI自己提供,它的确定,是在GAL_MapSurface函数中确定。

当第一次调用GAL_LowerBlit的时候,src->map->dst必定为NULL所以,就会调用到该函数。

GAL_MapSurface会调用到GAL_CalculateBlit函数,还选择一个正确的sw_blit,该函数会计算并填充hw_blit和sw_blit函数。这是一个比较复杂的过程。不过最终,sw_blit大部分情况下,会得到GAL_SoftBlit函数的指针。


关于这部分的详细情况,可以查看相关代码。











易语言GDI画板模块源码解析与应用 本文还有配套的精品资源,点击获取 简介:GDI(图形设备接口)是Windows系统中用于图形输出的基础组件。本文包含易语言编写的GDI画板模块源码,专门用于图形用户界面应用程序的开发。源码展示了如何使用GDI函数进行图形绘制,包括直线、椭圆、矩形的绘制和文本显示等。开发者可以利用这些源码快速开发自定义绘图应用,并深入理解GDI的工作原理及易语言在图形编程中的应用。源码分析包... 阅读详情

相关推荐

Minigui开源GUI库源码解析及应用

Minigui 是一个专门针对嵌入式系统设计的小型图形用户界面库,具备轻量级和可移植的特点。在这一章节中,我们将简要介绍 Minigui 的基本概念,并深入探讨其开源特性,为读者提供对 Minigui 全面的初步认识。字体样式的自定义与优化是为了满足特定应用需求,对字体进行调整的过程。通过调整字体的权重、宽度、倾斜程度和样式(如斜体、粗体),开发者可以创建出适应不同视觉风格的字体变体。例如,为了适应屏幕较小的嵌入式设备,可以通过优化算法来减小字体文件的大小。

weixin_32661831的博客 1312

<minigui>GDI双缓冲之道

图形界面编程,常见棘手问题就是出现绘图出现闪屏。这一现象也严重影响用户体验。前段时间刚接触minigui就出现一个闪屏半天不得其解的一个问题,查了很多网络资料使用方法都尽人意。 双缓冲绘图原理: 双缓冲 双缓冲的原理可以这样形象的理解:把电脑屏幕看作一块黑板。首先我们在内存环境中建立一个“虚拟“的黑板,然后在这块黑板上绘制复杂的图形,等图形全部绘制完毕的时候,再一次性的把内存中绘

duola_rain的专栏 2847

gdi+各种绘图源码.rar

gdi+各种绘图源码 src,非常好的资源,值得学习和借鉴。学习c++的同鞋们赶紧下载吧!!!gdi+各种绘图源码 源代码可以参考的哦!!!

miniGUI源码分析:消息机制

miniGUI通过接收消息来和外界交互。消息由系统或应用程序产生,系统对输 入事件产生消息,系统对应用程序的响应也会产生消息,应用程序可以通过产生消息来完成 某个任务,或者与其它应用程序的窗口进行通讯。总而言之,miniGUI 是消息驱动的系统, 一切运作都围绕着消息进行。 MSG 消息结构 MSG 消息结构的成员包括该消息所属的窗口(hwnd)、消息标识(message)、消息的 WPARAM 型参数(wParam)、消息的 LPARAM 型参数(lParam)以及消息发生的时间。 typedef st

secretii的博客 876

GDI+源码库

没什么可说的

GDI+源代码

C#GDI+例程源代码,绘图例程

MiniGUI源码分析:GDI(2)-- DC分析

虽然MiniGUI的应用范围越来越窄,很多功能和思想都落后于时代的发展,但是,作为一款开源的优秀的GUI库,具有很好的学习和参考价值。基于这个考虑,在我忘掉MiniGUI之前,把我所知道的写下来。 前言 熟悉windows的朋友都了解,GDI对外提供一个HDC的DC句柄。DC为(Device Context)的缩写,表示一个抽象的设备当前绘图情况。 一般情况下,屏幕、打印设备、内存像素都可以

doon的专栏 5210

保姆级教程:用GD32F470的EXMC Bank0 Region0与FPGA实现16位并行通信(附完整代码)

本文详细介绍了如何利用GD32F470的EXMC Bank0 Region0与FPGA实现16位并行通信,涵盖硬件连接、寄存器配置、时序优化及FPGA接口设计等关键步骤。通过实例代码和调试技巧,帮助开发者快速掌握高效数据交互技术,提升嵌入式系统设计能力。

weixin_26918763的博客 226

MIniGui 内存DC绘图

内存 DC 和 BitBlt     新的 GDI 函数增强了内存 DC 操作函数。GDI 函数在建立内存 DC 时,将调用 GAL 的相应接口。如前所述,GAL 将尽量把内存 DC 建立在显示卡的显示内存当中。这样,可以充分利用显示卡的硬件加速功能,实现显示内存中两个不同区域之间位块的快速移动、复制等等,包括透明处理和 Alpha 混和。应用程序可以建立一个具有逐点 Alpha 特性的内存 D

jia0511的专栏 4083

【电机控制入门】——电机控制书籍推荐

电机控制入门书籍推荐及分享 阅读须知: 1.电机控制的入门是涉及到机械、电子与控制等复杂交叉学习,它需要持续投入时间才可以看到学习的效果,如同“一万小时定律”。俗话说,九层之台,起于垒土,因此电机控制入门没有所谓的速成培训班。相反,还需要夯实好一定的基础。为此,博主建议从基础理论抓起,故推荐相关的书籍并分享给大家。 2.学习电机贵在动手实践,无论是借助于MATLAB/Simulink仿真平台来验证理论分析,或是使用板子对所设计的控制系统进行物理实现,博主极力推荐在一定基础(看完部分以下推荐的书籍),一边动手

昔时扬尘处 3万+

Windows 11下manage-bde命令实战:BitLocker锁了别慌,手把手教你用命令行找回数据

本文详细介绍了在Windows 11系统下使用manage-bde命令解锁BitLocker加密驱动器的实战方法。通过命令行诊断、恢复密钥获取、解锁流程演示及高级故障排除,帮助用户在系统锁定后快速找回数据,特别适合IT技术人员和遇到紧急情况的用户。

weixin_30902251的博客 328

MiniGUI源码分析——开始篇

MiniGUI即将开源,大家可以关注官方微博 http://weibo.com/fm0minigui  文章中即将提到的很多内容点,主要基于开源版本1.6.10,对应的是即将开源的3.0版本,以前的1.3.0(对应商用的2.0.4版本)的内容差异很小,大家可以对照查阅。 大家可以从http://sourceforge.net/projects/minigui/files/minigui

曾经沧海 5447

MagicDraw小白必看:BDD图中模块的5种属性详解(含SysML v1.6最新端口配置指南)

本文面向MagicDraw初学者,详细解析SysML BDD图中模块的五种核心结构属性,包括组成部分、引用、值、约束属性及端口。重点阐述了SysML v1.6中端口设计的范式转移,对比了完整端口与代理端口的区别与应用场景,并通过实战案例指导如何利用代理端口进行清晰的接口定义与系统架构设计。

rum55的博客 372

minigui源码分析(一)

转载:https://blog.youkuaiyun.com/doon/article/details/7063159 背后的故事 从接触MiniGUI到现在已经5年了,在飞漫也工作了4年多。由于种种原因,加上android的冲击,minigui越来越式微。让人感觉很痛心。 如今赋闲在家,无所事事,正好利用年末和春节这段时间,把这几年来对minigui所做、所想、所悟分享出来,一来,对以往的工作做个总结; 二来趁minigui即将开源之际,对minigui推波助澜;三来,希望把这款优秀的开源软件介绍给大家,希望

TJH_I_CAN的博客 904

cJSON库用完后内存泄漏?手把手教你正确使用cJSON_Delete和free释放资源

本文深入解析cJSON库的内存管理机制,重点解决使用后的内存泄漏问题。通过详细讲解cJSON_Delete和free的正确使用方法,帮助开发者在处理JSON数据时有效释放资源,避免内存泄漏。特别适用于嵌入式系统和资源受限环境,提升开发效率和系统稳定性。

weixin_30808693的博客 418

制作 img系统镜像的详细方法

      I.MX6开发板目前支持从TF卡和eMMC启动,启动时,由于各个不同的启动文件对路径有不同的要求,例如uboot文件要求位于启动设备的某个块,dtb文件要求在FAT分区上,文件系统要求在Linux分区上,基于此,我们目前采用将映像制作成img文件的方式,这样可以更简单完成对启动卡的制作。 关于如何制作img,方法如下:方法一  Windows下面利用Win32工具1.   准备我司提供...

armkits的博客 4万+

MiniGUI显示引擎初始化流程

这次主要分析在MiniGUI中,显示引擎的初始化流程,让大家理解MiniGUI.cfg配置文件怎么影响到使用哪一个引擎的,如果需要开发一个新引擎的话,本文章也有帮助 因为使用MiniGUI的人数也少,写这些文章没有什么价值,以后可能就不再写这类文章了,之后会多写一点QT的文章

逐梦的博客 1656

【Zabbix实战之部署篇】Docker部署Zabbix+grafana监控平台

【Zabbix实战之部署篇】docker部署Zabbix+grafana监控平台

jks212454的博客 2577

MiniGUI——使用 GDI 函数

简介: 本文讲述 MiniGUI 中 GDI 函数及其使用。主要包括:设备上下文的概念、获取和释放;矩形操作和区域操作;基本绘图函数;位图操作函数;逻辑字体操作函数等。

在不断学习中。。。 5634

AI挖矿技术全景解析:从智能勘探到自主开采的2025年度技术演进与产业变革

随着全球关键矿产资源需求激增与开采难度加剧,人工智能(AI)技术正在重塑矿业全生命周期。本文系统综述了2025年AI挖矿技术的最新进展,涵盖从地质勘探、资源评估到自主开采、安全监控的完整技术链条。基于Elsevier 2025年发表的最新研究成果及IEEE会议前沿动态,本文深入分析了深度学习、强化学习、计算机视觉等核心技术在矿物识别、品位预测、设备维护等场景的应用机制。研究数据显示,AI技术已使勘探成功率提升45%,设备停机时间减少35%,整体运营效率提高40%以上。

nmdbbzcl的博客 2082

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

QT待续

<br /> 一个能够移植到多种硬件平台上的嵌入式GUI系统至少需要抽象出两类设备, 即负责显示图形界面的图形抽象层GAL (Graphic Abstract Layer)和负责接收及处理输入(一般输入设备为键盘、触摸屏)的输入抽象层IAL (Input Abstract Layer)。<br /> <br /> <br />目前在Qt/EmbeddedGAL层技术使用的是FrameBufer。<br />FrameBuffer 是出现在 2.2.xx 内核当中的一种驱动程序接口。这种接口将显示设<br /

drbinzhao的专栏 968

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

minigui相关硬件加速添加方法

一、关于硬件加速 1.1 介绍 以海思平台的TDE加速显示模块为例,它主要为OSD和GUI提供快速的图形绘制功能,主要有快速位图搬移,快速色彩填充,快速抗闪搬移、快速位图缩放,画点、画水平/垂直线、位图格式转换,位图alpha叠加,位图按布尔值运算、ColorKey等操作。 1.2 应用 如何在minigui上应用这些加速模块呢? 上一章详解minigui图片加载及显示介绍了从图片解码装载到bitmap,再由bitmap刷新到fb的整个大体流程。所有图片刷新或者window刷新都离不开后面刷新到fb的流程。

weixin_41176628的博客 999

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

Minigui开发心得 -- 不定期更新

BroadcastMessage发送广播的时候,不会确保各个主窗口会接收到消息,它只负责发送到HWND_DESKTOP,因此如果需要确保主窗口能够接收到消息的话,可以使用其他方式,比如SendMessage(); 最好不要在控件的过程函数消息中去新创建主窗口,因为主窗口在销毁的时候容易和该控件的某些消息逻辑掺杂在一块,引发异常;比较好的方法是控件发消息给自己的主窗口,然后让自己的主窗口去新创建主窗口; 主窗口在销毁的过程中,如果需要给另一个主窗口的某个控件发消息的话,最好不要使用SendMessage().

他山烈石 976

MiniGUI原理分析GAL

四. GAL分析 MiniGUI采用linux的framebuffer进行显示,打开/dev/fb0取得设备描述符,通过mmap映射将设备内存映射到用户空间,直接访问映射出来的用户空间就可以实现,通过内存写,就可以实现显示。   4.1 宏_MGGAL_FBCON的定义   static VideoBootStrap *bootstrap[] = { #ifdef _MGGAL_F

lieye_leaves的专栏 4348
上一篇: MiniGUI源码分析--Helloworld(3):消息概览
下一篇: 做好一个企业的忠告
漂流的代码
博客等级 码龄23年 188粉丝 99原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值