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

ClientDC和CPaintDC(5月26日)  今天还是继续昨天的事情:自己堆砌MFC。我在WM_PAINT的消息响应函数OnPaint()里面调用DC去drawtext,可是发现他老是重绘。于是找原因,原来是这样的:我用的是:CRect rect; GetClientRect(&rect); CPaintDC myDC(this);//这里不能用CClientDC,只有CPaintDC才能把WM_PAINT消息从消息联里面删除,否则 阅读详情

虽然MiniGUI的应用范围越来越窄,很多功能和思想都落后于时代的发展,但是,作为一款开源的优秀的GUI库,具有很好的学习和参考价值。基于这个考虑,在我忘掉MiniGUI之前,把我所知道的写下来。

前言

熟悉windows的朋友都了解,GDI对外提供一个HDC的DC句柄。DC为(Device Context)的缩写,表示一个抽象的设备当前绘图情况。

一般情况下,屏幕、打印设备、内存像素都可以抽象出一个HDC句柄。 一个设备可以抽象多个HDC句柄,每个HDC句柄,都有自己独立的上下文信息。

在MiniGUI中,从窗口创建的DC都称为硬件DC,而从位图或者其他DC衍生的DC,称为MemDC。


注:MiniGUI源码目录中有gdi和newgdi两个目录。其中gdi已经被废弃,newgdi是目前使用的。但gdi和newgdi很多文件和函数名都是一样的,容易发生混淆,阅读源码时,要注意区分。


通常,在DC中保存的上下文信息有

当前点,当调用LineTo一类函数时,会绘制一条从当前点到LineTo指定参数的线。可以通过MoveTo来改变;

当前画笔的属性,如:画笔宽度(SetPenWidth), 颜色(SetPenColor),线段连接类型(SetPenJoinStyle), 线段端点的类型(SetPenCapStyle)

当前画刷的属性,如:画刷类型(SetBrushType),颜色(SetBrushColor),等

当前文字的信息:如,选择当前字体(SelectFont),文字颜色(SetTextColor)等

当前剪切域信息:如,SelectClipRect, SelectClipRgn等

逻辑坐标的信息:如,SetWindowOrg,SetWindowExt等。


几乎所有绘图函数,都是通过HDC来操作的。


HDC及tagDC

HDC只是一个简单的句柄,被定义为

typedef unsigned long HDC;

而它真正对应的结构体就是tagDC。 HDC就是将tagDC的指针转为unsigned long后的值。

tagDC的定义如下

/* Device Context */
struct tagDC
{
    short DataType;  /* the data type, always be TYPE_HDC */
    short DCType;    /* the dc type */
            
    BOOL inuse; //对于硬件DC,它从一个固定长度的数组缓存中获取一个DC对象。inuse TRUE表示这个DC已经被分配出去了,FALSE表示空闲。这是为了避免频繁调用malloc和free函数。
    HWND hwnd; //和硬件DC关联的 (DCType == TYPE_GENDC)

    /* surface of this DC */
    GAL_Surface* surface; //DC所依赖的surface,最重要的数据结构

    /* background color */
    gal_pixel bkcolor;

    /* pen color */
    gal_pixel pencolor;

    /* solid brush color */
    gal_pixel brushcolor;

    /* text color */
    gal_pixel textcolor;

    int bkmode;

    int tabstop;
    int cExtra;     /* Character extra */
    int alExtra;    /* Above line extra */
    int blExtra;    /* Bellow line extra */

    int mapmode;    /* mappping mode */

    int ta_flags;   /* Text alignment flags */

#ifdef _MGHAVE_ADV_2DAPI
    /* pen attributes */
    int pen_type;
    int pen_cap_style;
    int pen_join_style;
    unsigned int pen_width;

    /* brush attributes */
    int brush_type;

    POINT brush_orig;
    const BITMAP* brush_tile;
    const STIPPLE* brush_stipple;

    /* custom dash info */
    int dash_offset;
    const unsigned char* dash_list;
    size_t dash_list_len;
#endif

    PLOGFONT pLogFont;

    POINT CurPenPos;
    POINT CurTextPos;

    POINT ViewOrig;
    POINT ViewExtent;
    POINT WindowOrig;
    POINT WindowExtent;

    /* raster operation */
    int rop;

    /* used by the text rendering for anti-aliasing fonts. */
    gal_pixel gray_pixels [17];
    /* used by the text rendering for low-pass filtering. */
    gal_pixel filter_pixels [17];
    GAL_PixelFormat* alpha_pixel_format;

    /* pixel and line operation */
    CB_COMP_SETPIXEL draw_pixel;
    CB_COMP_SETHLINE draw_pixel_span;
    CB_COMP_PUTHLINE draw_src_span;
    DC_MOVE_TO move_to;
    DC_STEP_X  step_x;

    /* === context information. ============================================= */
    /* DK[01/22/10]:This segment is binary compatible with _COMP_CTXT struct */
    int step;
    gal_uint8* cur_dst;
    gal_pixel skip_pixel;
    gal_pixel cur_pixel;
    void * user_comp_ctxt;
    /* ====================================================================== */

    CLIPRECT* cur_ban;
    RECT rc_output;

    /* local clip region information */
    CLIPRGN  lcrgn;

    /* effective clip region information */
    CLIPRGN  ecrgn;

    /* device rect */
    BOOL bIsClient;
    RECT DevRC;

    PGCRINFO pGCRInfo;
    unsigned int oldage;

    CB_BITMAP_SCALER_FUNC bitmap_scaler; //图片绘制所使用的数据结构
};


和窗口相关的DC

和窗口相关的DC,有几个重要函数:

BeginPaint/EndPaint, GetDC, GetClientDC/ReleaseDC。还有一种PrivateDC,是一个历史遗留的DC,现在几乎不使用,不必考虑它。


BeginPaint/EndPaint是必须用在窗口回调的MSG_PAINT消息中的。之所以这样做,是因为BeginPaint会清除窗口的无效区域(详细了解 MiniGUI源码分析--Helloworld(3):消息概览)。

GetDC针对整个窗口,而GetClientDC则针对客户区。 这两个函数在MSG_CREATE消息中和所有的key, mouse消息等都可以使用。但是对于 MSG_NCCREATE, MSG_SIZECHANGING的极个别消息不能使用。

这些DC创建方法大同小异,我以GetClientDC为例来说明

HDC GUIAPI GetClientDC(HWND hWnd)
{
    int i;

#ifndef _LITE_VERSION
    pthread_mutex_lock (&dcslot);
#endif
    for (i = 0; i < DCSLOTNUMBER; i++) { //从固定缓冲区分配
        if (!DCSlot[i].inuse) {
            DCSlot[i].inuse = TRUE;
            DCSlot[i].DataType = TYPE_HDC;
            DCSlot[i].DCType   = TYPE_GENDC;
            break; 
        }
    }
#ifndef _LITE_VERSION
    pthread_mutex_unlock (&dcslot);
#endif

    if (i >= DCSLOTNUMBER)
        return HDC_SCREEN;

    dc_InitDC (DCSlot + i, hWnd, TRUE); //这是关键函数
    return (HDC) (DCSlot + i);
}
GetClientDC和GetDC都是通过dc_InitDC来初始化的,这是DC创建的关键点 (请仔细看注释)

/* This function initializes a DC: set the default parameters. */
static void dc_InitDC (PDC pdc, HWND hWnd, BOOL bIsClient)
{
    PCONTROL pCtrl;
    CLIPRGN ergn;

    pdc->hwnd = hWnd; //关联窗口

    //初始化上下文代码的内容,基本可以跳过不看
    memset (pdc->gray_pixels, 0, sizeof (pdc->gray_pixels));
    memset (pdc->filter_pixels, 0, sizeof (pdc->filter_pixels));

    pdc->bkcolor = GAL_MapRGB (pdc->surface->format, 0xFF, 0xFF, 0xFF);
    pdc->bkmode = 0;

    pdc->pencolor = GAL_MapRGB (pdc->surface->format, 0x00, 0x00, 0x00);
    pdc->brushcolor = GAL_MapRGB (pdc->surface->format, 0xFF, 0xFF, 0xFF);

    pdc->textcolor = GAL_MapRGB (pdc->surface->format, 0x00, 0x00, 0x00);
    if (!(pdc->pLogFont = GetWindowFont (hWnd)))
        pdc->pLogFont = GetSystemFont (SYSLOGFONT_WCHAR_DEF);
    pdc->tabstop = 8;
    pdc->CurTextPos.x = pdc->CurTextPos.y = 0;
    pdc->cExtra = pdc->alExtra = pdc->blExtra = 0;

    pdc->mapmode = MM_TEXT;
    pdc->ta_flags = TA_LEFT | TA_TOP | TA_NOUPDATECP;

    pdc->ViewOrig.x = pdc->ViewOrig.y = 0;
    pdc->ViewExtent.x = pdc->ViewExtent.y = 1;
    pdc->WindowOrig.x = pdc->WindowOrig.y = 0;
    pdc->WindowExtent.x = pdc->WindowExtent.y = 1;

#ifdef _MGHAVE_ADV_2DAPI
    pdc->pen_type = PT_SOLID;
    pdc->pen_cap_style = PT_CAP_BUTT;
    pdc->pen_join_style = PT_JOIN_MITER;
    pdc->pen_width = 0;
    pdc->dash_offset = 0;
    pdc->dash_list = NULL;
    pdc->dash_list_len = 0;

    pdc->brush_type = BT_SOLID;
    pdc->brush_orig.x = pdc->brush_orig.y = 0;
    pdc->brush_tile = NULL;
    pdc->brush_stipple = NULL;
#endif

    /* Assume that the local clip region is empty. */
    /* Get global clip region info and generate effective clip region. */
    if (dc_IsGeneralDC (pdc)) {
        RECT minimal;

        pdc->pGCRInfo = kernel_GetGCRgnInfo (hWnd);
        LOCK_GCRINFO (pdc);

        pdc->oldage = pdc->pGCRInfo->age;
        ClipRgnCopy (&pdc->ecrgn, &pdc->pGCRInfo->crgn); 

        pdc->bIsClient = bIsClient;
        if (bIsClient)  // 限制DC的剪切域为客户区/整个窗口
            WndClientRect (pdc->hwnd, &pdc->DevRC);
        else
            WndRect (pdc->hwnd, &pdc->DevRC);

        minimal = pdc->DevRC;

        pCtrl = gui_Control (pdc->hwnd);

        if (pCtrl && !(pCtrl->dwExStyle & WS_EX_CTRLASMAINWIN))
        {
            InitClipRgn (&ergn, &__mg_FreeClipRectList);

            if (RestrictControlECRGNEx (&minimal, pCtrl, &ergn)) {
                ClipRgnIntersect (&pdc->ecrgn, &pdc->ecrgn, &ergn);
                EmptyClipRgn (&ergn);
            }
            else {
                EmptyClipRgn (&pdc->ecrgn);
            }
        }
        else {
            IntersectClipRect (&pdc->ecrgn, &minimal);
        }

        UNLOCK_GCRINFO (pdc);
    }

    /* context info and raster operations. */
    pdc->CurPenPos.x = pdc->CurTextPos.x = 0;
    pdc->CurPenPos.y = pdc->CurTextPos.y = 0;

    //设置图像和背景的混合方法,同windows中的 NOT画笔、异或笔等类型的功能
    pdc->rop = ROP_SET;
    pdc->step = 1;
    //每种混合方式都有对应的函数,这是为了提高绘制速度
    pdc->draw_pixel = draw_pixel_ops [pdc->rop]  
        [pdc->surface->format->BytesPerPixel - 1];
    pdc->draw_pixel_span = draw_pixel_span_ops [pdc->rop]
        [pdc->surface->format->BytesPerPixel - 1];
    pdc->draw_src_span = draw_src_span_ops [pdc->rop]
        [pdc->surface->format->BytesPerPixel - 1];
    //设置dc的像素起点值
    pdc->cur_dst = (BYTE*)pdc->surface->pixels 
            + pdc->surface->pitch * pdc->DevRC.top
            + pdc->surface->format->BytesPerPixel * pdc->DevRC.left;

    pdc->move_to = move_to_ops [pdc->surface->format->BytesPerPixel - 1];
    pdc->step_x = step_x_ops [pdc->surface->format->BytesPerPixel - 1];

    pdc->alpha_pixel_format = NULL;
    SetBitmapScalerType((HDC)pdc, BITMAP_SCALER_DDA); //设置默认的位图缩放算法:DDA 这是一种速度快但是效果差的缩放算法
}

这里,值得一提的是关于HDC如何确定像素的内存地址的。这需要一个重要的概念:pitch。pitch表示一行像素的字节宽度(单位为字节)。

像素在显存(内存)中,是一段连续的内存。如 800x600-16bpp的一个屏幕,它的像素占用的内存是 800*2*600 = 960000 byte。 每一行占用的字节数为800x2 = 1600。那么,它的pitch=1600。

pitch和3个因素相关:像素矩阵的宽度、单个像素占用的字节数和对齐。在32位设备上,每一行像素必须是4的倍数。宽度为799的像素矩阵,其pitch = 1600,因为最后两个字节因为对其的原因,必须是补充进来。


上图中,外层为屏幕的surface的像素矩阵;内层位DC的大小和位置。DecRC表示的DC在surface中的大小和位置。


cur_dst的像素指针为

   pdc->cur_dst = (BYTE*)pdc->surface->pixels 
            + pdc->surface->pitch * pdc->DevRC.top
            + pdc->surface->format->BytesPerPixel * pdc->DevRC.left;
如果要计算DC中某个点(a,b)的像素位置,只要进行如下运算:

pixel = cur_dst + a + b * pitch;

兼容的MemDC

兼容的概念指,创建的内存DC的像素格式和屏幕的像素格式一样。

创建兼容DC,使用CreateCompatibleDCEx。这个函数,接受一个HDC参数(可以是任意一个有效的HDC)。

它们的实际实现是,根据传递的DC类型,创建一个和DC的像素格式一样的内存DC。 

但是CreateComnpatibleDCEx将直接分配内存来供新的DC来使用。


自定义的MemDC

另外,我们还可以创建的DC包括CreateMemDCEx和CreateMemDCFromBitmap。CreateMemDC(CreateMemDCEx)这个函数会为dc生成专门的surface,而CreateMemDCFromBitmap则利用位图的像素矩阵作为surface。 这样做就可以在一个位图上绘制信息了。


Sub DC

SubDC的含义为子DC。即在原DC的基础上,创建一个区域小于或者等于原DC的新DC。这个DC将继承原DC的所有属性值。SubDC和原DC都基于同一个surface,这样,SubDC和原DC都可以在同一位置绘制了。

SubDC的概念来自于java的AWT。主要用于窗口的绘制(从父窗口向子窗口绘制时,创建一个SubDC,可以避免子窗口的绘制上下文污染父窗口)

涉及的函数包括 GetSubDC(针对BeginPaint, GetDC和GetClientDC得到的dc)和CreateSubMemDC。


Secondary DC

SecondaryDC是在MiniGUI 3.0引入的。它是和窗口关联的一个后备缓冲区。起到的作用是防止闪烁(实际有限)和在窗口不可见的情况下获取窗口的内容(目的是为了实现窗口特效)。

SecondaryDC只有主窗口才有,子窗口是没有SecondaryDC的。通过给窗口的扩展风格,增加WS_EX_AUTOSECONDARYDC(必须在窗口创建时),可以自动创建一个SecondaryDC。 通过GetSecondaryDC能够获取到该DC。


个人认为SecondaryDC的设置不是很成功,读者不需要给予过多关注。


MiniGui开发问题锦集 前言 本文记录了我学习MiniGui开发过程中遇到的一些有意思问题与解决方法,会随着我学习的深入慢慢的更新下去。文章中窗口指的是通过CreateMainWindow创建的窗口,控件是指CreateWindow或CreateWindowEx创建的控件。 1 创建透明背景窗口 方法一:窗口创建时,在界面的窗口过程函数里添加MSG_ERASEBKGND监听,什么也不画就是透明背景,这种方法有... 阅读详情

相关推荐

Minigui学习--DC

1.相关函数: MG_EXPORT HDC GUIAPI GetDC (HWND hwnd); //gets a window DC of the specified \a hwnd, and returns  the handle to the DC. MiniGUI will try to return an unused DC from the internal DC pool, rath

hehongjihhh的专栏 1458

[00012]-[2015-08-27]-[00]-[Windows 程序设计 ---GetWindowDC GetWindowRect GetClientDC(GetDC) GetClientRec...

::GetWindowDC(m_hWnd); // 表示GetWindowDC()是一个全局函数,作用域大 GetWindowDC()获得的设备环境覆盖了整个窗口(包括非客户区),例如标题栏、菜单、滚动条,以及边框 GetWindowRect() rect表示应用程序窗口在屏幕中的位置rigth left top bottom GetDC()  获取的是应用程序中客户区的环...

weixin_30321449的博客 312

CCC数字钥匙3.0标准解读(22)

介绍设备制造商服务器和车辆制造商服务器之间的通信协议.

weixin_41738640的博客 1748

Win32 DC的数据结构

typedef struct tagDC {    GDIOBJHDR        header;    HDC            hSelf;                 /* Handle to this DC */    const struct    tagDC_FUNCS *funcs; /* DC function table */    PHYSDEV   

zengwh的专栏 3303

5步搞定ABB机器人RobotStudio与S7-1500PLC的Profinet通讯(附PLCSIM调试技巧)

本文详细介绍了如何利用RobotStudio与TIA Portal软件,结合PLCSIM Advanced仿真器,在零硬件条件下实现ABB机器人与西门子S7-1500 PLC之间的Profinet通讯虚拟调试。通过五个核心步骤,从环境搭建、网络配置、信号映射到联合仿真与高级调试,帮助工程师在项目前期高效验证逻辑、压缩现场调试周期,并掌握实用的PLCSIM调试技巧。

weixin_29188043的博客 505

SVG文件上传漏洞实战:从XSS攻击到防御策略

本文深入剖析了SVG文件上传漏洞的成因与危害,揭示了攻击者如何利用SVG的XML本质构造恶意文件,绕过常规检查实现存储型XSS攻击。文章通过实战复现演示了完整的攻击链,并提供了从严格内容检查、安全解析过滤到设置CSP策略等多层次的纵深防御方案,帮助开发者从根本上加固文件上传功能。

weixin_29230805的博客 395

releaseDC和deleteDC的区别

DeleteDC 与 CreateDC 对应使用 ReleaseDC 与 GetDC 对应使用 所以:DeleteDC 与ReleaseDC的区别 实际就是 CreateDC和GetDC的区别 windows系统DC只能release     自己建的要delete

GAMELOFT9----纸上得来终觉浅,绝知此事要躬行 2433

状态机设计与实现( stm32小车避障为例)

本文以STM32小车避障为例,介绍了状态机设计与实现方法。首先阐述了状态机的事件驱动特性、清晰结构和易扩展优势,并给出硬件组成框架。核心实现部分展示了状态枚举定义、状态转移图和主循环框架,通过switch-case结构实现状态切换。关键状态示例包括前方扫描和转向决策逻辑,通过传感器数据驱动状态转移。总结指出状态机设计需定义枚举状态、实现状态函数、使用switch跳转并更新全局状态。文章最后声明内容为学习笔记,欢迎读者指正交流。全文结构清晰,代码示例具体,为嵌入式系统状态机设计提供了实用参考。

2302_80219536的博客 1046

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

上一篇:MiniGUI源码分析--Helloworld(3):消息概览 从本章开始,将逐步介绍MiniGUI部分GDI GDI(Graphics Device Interface)是对绘图接口的描述,是MiniGUI的核心组成部分之一。 GDI虽然是GUI的基础,但是,它实际上不太适合作为GUI的组成部分之一的。因为GUI的核心功能在用户交互上,而不是如何绘制上。对M

doon的专栏 5075

STM32CubeIDE中文注释变乱码终极解决方案:3步设置永久解决锟斤拷问题!

你是否在STM32CubeIDE中遇到过这样的崩溃场景?——精心编写的中文注释在重新生成代码后变成“锟斤拷”乱码,不仅影响代码可读性,反复修改更是浪费大量时间!作为STM32开发者,我曾被这个问题困扰许久,试过修改软件设置、工程编码却始终治标不治本。直到发现这个基于Java环境变量的终极解决方案,才彻底解决了中文乱码难题。

smart_boy__的博客 2955

STM32 USB AUDIO实战指南——从零构建音频设备

本文详细介绍了如何使用STM32F407构建USB音频设备,从硬件准备到软件配置,再到音频播放和录制功能的实现。通过STM32CubeMX配置和实战代码示例,帮助开发者快速掌握USB Audio Class规范,实现低延迟、高质量的音频传输,适用于语音交互、音乐播放等多种场景。

weixin_42549037的博客 484

MiniGUI源码分析——DC分析

熟悉windows的朋友都了解,GDI对外提供一个HDC的DC句柄。DC为(Device Context)的缩写,表示一个抽象的设备当前绘图情况。 一般情况下,屏幕、打印设备、内存像素都可以抽象出一个HDC句柄。 一个设备可以抽象多个HDC句柄,每个HDC句柄,都有自己独立的上下文信息。 在MiniGUI中,从窗口创建的DC都称为硬件DC,而从位图或者其他DC衍生的DC,称为MemDC。 注

曾经沧海 2495

面试问题总结——关于YOLO系列(三)

接着上篇的的YOLO系列面试问题总结,加油,冲! 三.YOLOv3 1.YOLOv3主干网络BackBone——Darknet-53网络结构(因为有53个卷积层) (原论文中Darknet53的尺寸是在图片分类训练集上训练的,所以输入的图像尺寸是256x256,而在YOLOv3中输入尺寸是416×416)   ①上图中,Top-1 Accuracy和Top-5 Accuracy是指什么呢?区别在哪呢?   我们知道ImageNet有大概1000个分类,而模型预测某张图片时,会给出1000个按概率从高.

boss-dog 1万+

MiniGUI源码分析——GDI概览及Surface

GDI(Graphics Device Interface)是对绘图接口的描述,是MiniGUI的核心组成部分之一。 GDI虽然是GUI的基础,但是,它实际上不太适合作为GUI的组成部分之一的。因为GUI的核心功能在用户交互上,而不是如何绘制上。对MiniGUI来说,GDI是成也萧何败萧何:MiniGUI内置的GDI使得MiniGUI更紧凑和高效,但是由于其功能受限,使得MiniGUI在

曾经沧海 1651

42、多媒体与虚拟现实在艺术和影视领域的创新应用

本文探讨了多媒体与虚拟现实在艺术和影视领域的创新应用,涵盖三个典型案例:影视与人类学融合项目通过协作模式模糊作者与观众界限,推动文化文献的发展;交互式数字短片《分手》利用基于对象的广播技术探索个性化影视体验;威尼斯双年展瑞士馆4D项目则通过虚拟现实技术实现文化遗产的数字化展示。这些案例展示了技术在叙事、用户体验及文化保护中的深度应用,并展望了未来技术融合、个性化深化与文化遗产传承的发展趋势。

kappa的博客 114

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

MiniGUI源码分析

MiniGUI-thread模式

aldxa的专栏 569

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

minigui学习笔记五

界面外观及特效 一.外观渲染器及窗口元素属性 1.前言 1.1为什么引入渲染器 以前的版本在编译前就必须进行编译配置,选定界面风格,在 fashion、 classic 和 flat 中选其一 1.2优点 可以通过MiniGUI配置文件来修改界面外观 也可以通过函数接口来控制界面外观 1.3作用 实现窗口以及控件外观的绘制 1.4实现 窗口元素的属性,包括窗口元素的颜色、尺寸、字体等信息 窗口元素的渲染方法,定义如何绘制窗口元素 1.5四种渲染器 classic、 flat、 fashion、 sk

qq_43601873的博客 1208

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

android 蓝牙通讯demo

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

抓屏

 一.截取整个屏幕: CDC dc;dc.CreateDC("DISPLAY",NULL,NULL,NULL);CBitmap bm;CRect rect;GetClientRect(&rect);//int Width=GetSystemMetrics(SM_CXSCREEN);//int Height=GetSystemMetrics(SM_CYSCREEN);int Width=

西子湖畔 2340

MFC中客户区和非客户区的区别&OnPaint和OnDrawn的区别

1.客户区和非客户区的区别: 在一个MDI(多文档)应用程序中每个概念如下图所示:   窗口框架客户区即蓝色方框内区域,窗口框架非客户区指蓝色方框之外的窗口区域,包括程序图标、标题栏、菜单栏、最大\最小\关闭按钮,左右边框和底下的状态条。 视图的客户区指图中绿色部分,即红色方框内区域,非客户区指视图部分红色方框之外的区域,包括文件图标、标题栏、三个按钮和两个滚动条。

Cherish_now的专栏 2017

使用Windows API画位图(BITMAP) (原帖由niesongsong发表)

标   题:【原创】使用Windows API画位图(BITMAP)<br />作   者: niesongsong<br />邮   箱:nie@song.ah.cn<br />关键字:C语言、Windows API、BitBlt、StretchBlt、DC <br />时   间:2010-09-04<br /><br />【前言】<br />有人说不要重新发明轮子,诚然,我同意这种说法,作为运行在Windows上的用户级程序均构架在Windows API之上。如果你了解或者深究Windows API,

mycaibo编程 1975

MFC中的GDI/GDI+和双缓冲绘图

1、GDI概述   GDI在全称是Graphics Device Interface,即图形设备接口。是图形显示与实际物理设备之间的桥梁。         GDI使得用户无需关心具体设备的细节,而只需在一个虚拟的环境(即逻辑设备)中进行操作。它的桥梁作用体现在:      (1)用户通过调用GDI函数将逻辑空间的操作转化为具体针对设备驱动程序的调用。      为实现图形设

Invoker's Tower 8084

minigui hdc 画图

#include #include #include #include  /* for strerror */ #include    // for gettimeofday() #include #include "libyuv.h" #include #include #include #include #include long getTime(

学海无涯 2233

MINIGUI学习总结一

(一)MiniGUI的各种消息的区别MiniGUI中的消息种类通常可分为系统消息、对话框消息、窗口绘制消息、窗口创建和销毁消息、键盘和鼠标(后处理)消息以及用户自定义消息。总结使用消息时需注意的问题:1. PostMessage和SendMessage函数的区别即前者将消息置于指定窗口的消息队列后便返回,通常用于发送一些非关键性信息(如键盘和鼠标消息),而后者则是通知指定窗口的窗口过程立即完成某项

LL-Studio的专栏 5026

MiniGUI原理分析GAL

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

lieye_leaves的专栏 4348

MiniGUI源码走读

作者:Hily 原始链接:http://hily.me/blog/2007/05/minigui-code-reading/版权声明:可以转载,转载时务必以超链接形式标明文章原始出处和作者信息及版权声明注:这里是针对以下配置的MiniGUI v1.3.3进行解读:使用thread模式资源内置(Resource Incore)使用旧版本GAL使用native gal引擎

idoit0204的专栏 968
上一篇: webkit内核源代码导读3:HTML的解析过程
下一篇: 现代浏览器的后台工作原理
漂流的代码
博客等级 码龄23年 188粉丝 99原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值