zoukankan      html  css  js  c++  java
  • GDI对象句柄表

    存在着GDI对象表,可以通过未有文档的函数GdiQueryTable查询到:此函数存在于GDI32中,

    在GDI对象表中,每个Cell应该是一个16字节的结构体:

    struct  
    {
    	void	*pKernel;
    	USHORT  nProcess;
    	USHORT  nCount;
    	USHORT  nUpper;
    	USHORT  nType;
    	void    *pUser;
    }GdiTableCell;


    pKernel指向的是内核地址(页面池),每个GDI对象都有GDI对象表指向的内核数据结构

    nProcess是进程标识符,说明GDI对象是进程相关的

    nCount一般为0,但是对于DDB来说,当它被选入一个DC中,nCount从0变为1,

    如果试图把它再选入另一个DC,就会失败,当DDB从第一个DC中取消时,nCount从1变为0, 说明DDB不能一次被选入一个以上的设备上下文

    所以做了个小代码测试:

    		CPaintDC dc(this);
    		CDC MemDC1,MemDC2;
    		MemDC1.CreateCompatibleDC(&dc);
    		MemDC2.CreateCompatibleDC(&dc);
    		CBitmap *pOld = NULL;
    		pOld = MemDC1.SelectObject(&m_ddb);
    		//MemDC1.SelectObject(pOld);
    		pOld = MemDC2.SelectObject(&m_ddb);
    		CRect rcClient;
    		GetClientRect(&rcClient);
    		dc.BitBlt(0, 0, rcClient.Width(), rcClient.Height(), &MemDC2, 0, 0, SRCCOPY);


    测试结果是由于MemDC1已选进了m_ddb,所以MemDC2失败了,返回NULL,也没有绘制出来,那么把//MemDC1.SelectObject(pOld);打开,就OK了,

    但是对于字体来说,nCount只是一个选择计数,所以把字体选入第二个DC成功后,nCount加1

      注意的是这张表是共享的,也就是这张表还包含了其他进程的GDI对象句柄,而进程终止时,GDI会搜索这张表,把有指定进程标识符的对象全部删除掉。

  • 相关阅读:
    About Face 摘录
    断言的使用
    C#中值传递和引用传递
    C++技巧之断言Assert
    About Face 一 目标导向设计
    About Face 二 设计行为与形态
    C++中引用传递与指针传递区别
    一个新的时代SoLoMo
    离散数学笔记算法部分
    汪教授的离散数学20110308 谓词与量词2
  • 原文地址:https://www.cnblogs.com/hgy413/p/3693502.html
Copyright © 2011-2022 走看看