⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gdi.c

📁 深圳市微逻辑电子有限公司 巨果&#8226 Kingmos&reg 系统核心
💻 C
📖 第 1 页 / 共 5 页
字号:
//	释放一个基于窗口的DC
// 引用: 
//	
// ************************************************

// the option export for win.c
BOOL ReleasePaintDC( HWND hWnd, HDC hdc )
{
    _LPGDCDATA lpdc = _GetHDCPtr( hdc );

    if( lpdc && lpdc->obj.objType == OBJ_DC )
    {	// 测试该DC是否与该窗口相关
		if( (LONG)hWnd == Interlock_TestExchange( (LONG*)&lpdc->hwnd, (LONG)hWnd, NULL ) )
		{	//是,释放它
			return DelSysDC( lpdc );
		}
		else
		{
    	    WARNMSG( 1, ( "error at ReleasePaintDC: the hdc(0x%x) did'nt alloc by the hWnd(0x%x).\r\n", hdc, hWnd ) );
		}
    }
    return FALSE;
}

// **************************************************
// 声明:HDC GetPaintDC( HWND hwnd, LPCRECT lprect, HRGN hrgnClip, UINT uiFlags )
// 参数:
// 	IN hwnd - 窗口句柄
// 	IN lprect - 窗口矩形(设备坐标)
//	 IN hrgnClip - 裁剪区域
// 	IN uiFlags - 标志
// 返回值:
//	假入成功,返回分配的DC句柄;否则,返回NULL
// 功能描述:
//	从系统分配一个DC用于绘图
// 引用: 
//	
// ************************************************

HDC GetPaintDC( HWND hwnd, LPCRECT lprect, HRGN hrgnClip, UINT uiFlags )
{
    _LPGDCDATA lpdc = _AllocGDCData();// 得到一个DC结构

    if( lpdc )
    {
		
        lpdc->hrgn = hrgnClip;
        lpdc->hPen = OEM_GetStockObject(BLACK_PEN);//系统默认的PEN
		lpdc->penAttrib = _GetHPENPtr( lpdc->hPen )->penAttrib;

        lpdc->hBrush = OEM_GetStockObject(WHITE_BRUSH);//系统默认刷子
		lpdc->brushAttrib = _GetHBRUSHPtr( lpdc->hBrush )->brushAttrib;

        lpdc->hFont = OEM_GetStockObject(SYSTEM_FONT);//系统默认的字体
		// 2004-02-16
        lpdc->hBitmap = (HBITMAP)hbmpDisplayBitmap;//lpDisplayBitmap;//系统默认位图
		//
		lpdc->lpDispDrv = lpDrvDisplayDefault;//系统默认图形驱动程序

        lpdc->deviceOrg.x = lprect->left;//窗口在设备的左上角x坐标
        lpdc->deviceOrg.y = lprect->top;//窗口在设备的左上角y坐标
        lpdc->deviceExt.cx = lprect->right - lprect->left;//窗口宽度
        lpdc->deviceExt.cy = lprect->bottom - lprect->top;//窗口高度
        lpdc->stretchMode = 0;//伸缩模式
        lpdc->mapMode = MM_TEXT;//映射模式MM_TEXT
        lpdc->rop = R2_COPYPEN;//笔操作模式
		lpdc->arcMode = AD_CLOCKWISE;//顺时针画弧, AD_COUNTERCLOCKWISE;
        lpdc->backMode = OPAQUE;//不透明背景
        lpdc->backColor = (DWORD)OEM_GetStockObject( SYS_STOCK_WHITE );//默认的背景色
        lpdc->textColor = (DWORD)OEM_GetStockObject( SYS_STOCK_BLACK );//默认的文本色
        lpdc->textAlign = TA_TOP | TA_LEFT;//文本对齐模式
        lpdc->position.x = lpdc->position.y = 0;//当前的默认绘图起点
        lpdc->windowOrg = lpdc->viewportOrg = lpdc->position;//窗口原点,视区原点

		lpdc->uiState = 0; // 状态
		lpdc->uiFlags = uiFlags;//标志
        lpdc->hwnd = hwnd;//关联窗口
		lpdc->lpdwPal = 0;  //默认的调色板
		lpdc->wPalNumber = 0;  //默认的调色板
		lpdc->wPalFormat = 0;  //默认的调色板

		return (HDC)PTR_TO_HANDLE( lpdc ); // 将DC指针转化为句柄
    }

	return NULL;

}

// **************************************************
// 声明:BOOL DeleteDCObject( HANDLE hOwner )
// 参数:
// 	IN hOwner - 拥有者句柄
// 返回值:
//	假入成功,返回TRUE;否则,返回FALSE
// 功能描述:
//	清除拥有者的所有之前分配而没有释放的DC。通常当一个进程退出时,调用该功能去清除
//	进程没有释放的DC
// 引用: 
//	
// ************************************************

BOOL DeleteDCObject( HANDLE hOwner )
{
    int i;
	_LPGDCDATA lpdc;

    EnterCriticalSection( &csDCList );//进入互斥段
	//清除所有的属于拥有者对象
    ObjList_Delete( &lpDCObjList, (ULONG)hOwner, DelMemDCObj, 0 );

    LeaveCriticalSection( &csDCList );//离开互斥段

	// release sysdc
	lpdc = lpSysDC;

    for( i = 0; i < _MAX_GDIOBJECT_NUM; i++, lpdc++ )
    {		
        if( lpdc->obj.objType != OBJ_NULL &&
			lpdc->obj.ulOwner == (ULONG)hOwner )  //属于拥有者 ?
        {   //是
			InterlockedExchange( (LONG*)&lpdc->hwnd, NULL );
			DelSysDC( lpdc );
        }
    }
	return 1;
}

// **************************************************
// 声明:HDC WINAPI WinGdi_CreateCompatibleDC(HDC hdc)
// 参数:
// 	IN hdc - DC句柄
// 返回值:
//	假入成功,返回DC句柄;否则,返回NULL
// 功能描述:
//	创建兼容于hdc的内存DC
// 引用: 
//	系统API
// ************************************************

HDC WINAPI WinGdi_CreateCompatibleDC(HDC hdc)
{
    _LPGDCDATA lpSrcDC = NULL;
	_LPGDCDATA lpdc;

    if( hdc )
	{
        lpSrcDC = _GetHDCPtr( hdc );
		if( lpSrcDC == NULL )
			return NULL;
	}

    lpdc = (_LPGDCDATA)BlockHeap_Alloc( hgwmeBlockHeap, BLOCKHEAP_ZERO_MEMORY, sizeof(_GDCDATA) ); // 分配DC结构
//    lpdc = (_LPGDCDATA)BLK_Alloc( 0, sizeof(_GDCDATA) ); // 分配DC结构

    if( lpdc )  // 分配成功?
    {	//是,初始化DC为1x1的黑白位图格式
		// hrgn 不能用 OEM_GetStockObject, 因为当选进bitmap后,需要改变其裁剪矩形的大小
		lpdc->lpDispDrv = &_drvDisplay1BPP;

		lpdc->lpdwPal = 0;  //默认的调色板
		lpdc->wPalNumber = 0;  //默认的调色板
		lpdc->wPalFormat = 0;  //默认的调色板

        lpdc->hrgn = WinRgn_CreateRect( 0, 0, 1, 1 );//OEM_GetStockObject(SYS_STOCK_RGN);
		//初始化为黑笔
        lpdc->hPen = OEM_GetStockObject(BLACK_PEN);
		//设置设备依赖笔数据结构
		lpdc->penAttrib = _GetHPENPtr( lpdc->hPen )->penAttrib;
		//设置设备依赖颜色
		lpdc->penAttrib.color = lpdc->lpDispDrv->lpRealizeColor(lpdc->penAttrib.clrRef, lpdc->lpdwPal, lpdc->wPalNumber, lpdc->wPalFormat ); 
		//设置设备依赖刷子数据结构
        lpdc->hBrush = OEM_GetStockObject(WHITE_BRUSH);
		lpdc->brushAttrib = _GetHBRUSHPtr( lpdc->hBrush )->brushAttrib;
		//设置设备依赖颜色
		lpdc->brushAttrib.color = lpdc->lpDispDrv->lpRealizeColor(lpdc->brushAttrib.clrRef, lpdc->lpdwPal, lpdc->wPalNumber, lpdc->wPalFormat); 
		//默认字体
        lpdc->hFont = OEM_GetStockObject(SYSTEM_FONT);
		//默认显示面
		lpdc->hBitmap = OEM_GetStockObject(SYS_STOCK_BITMAP1x1);
		ASSERT( lpdc->hBitmap );		
		//设备原点
        lpdc->deviceOrg.x = 0;
        lpdc->deviceOrg.y = 0;
        lpdc->deviceExt.cx = 0;
        lpdc->deviceExt.cy = 0;
        lpdc->stretchMode = 0;

        lpdc->mapMode = MM_TEXT;
        lpdc->rop = R2_COPYPEN;
        lpdc->backMode = OPAQUE;
        lpdc->backColor = 0xffffffffl;
        lpdc->textColor = 0;
        lpdc->textAlign = TA_TOP | TA_LEFT;
        lpdc->position.x = lpdc->position.y = 0;
        lpdc->windowOrg = lpdc->viewportOrg = lpdc->position;
        lpdc->hwnd = NULL;

    }
	if( lpdc )
	{	//插入DC对象链表
		EnterCriticalSection( &csDCList );
		ObjList_Init( &lpDCObjList, &lpdc->obj, OBJ_MEMDC, (ULONG)GetCallerProcess() );
		LeaveCriticalSection( &csDCList );

		return (HDC)PTR_TO_HANDLE( lpdc ); // 转化为句柄
	}

	return NULL;
}

// **************************************************
// 声明:HBITMAP WINAPI WinGdi_CreateCompatibleBitmap(HDC hdc, int iWidth, int iHeight)
// 参数:
//    IN hdc - 设备DC
//	IN iWidth - 位图宽度
//	IN iHeight - 位图高度
// 返回值:
//	假入成功,返回非NULL位图句柄;否则,返回NULL
// 功能描述:
//	创建兼容DC的位图
// 引用: 
//	系统API
// ************************************************

HBITMAP WINAPI WinGdi_CreateCompatibleBitmap(HDC hdc, int iWidth, int iHeight)
{
    if( hdc )
	{
		_LPGDCDATA lpdc = _GetHDCPtr( hdc );
		if( lpdc )
		{	//有效
			_LPBITMAPDATA lpImage = _GetHBITMAPPtr( lpdc->hBitmap );
			return lpImage ? WinGdi_CreateBitmap( iWidth, iHeight, lpImage->bmPlanes, lpImage->bmBitsPixel, 0 ) : NULL;
		}
	}
	else
	{   // 用屏幕DC, use screen dc
		return WinGdi_CreateBitmap( iWidth, iHeight, lpDisplayBitmap->bmPlanes, lpDisplayBitmap->bmBitsPixel, 0 );
	}
    return NULL;
}


// **************************************************
// 声明:_LPGDCDATA _GetSafeDrawPtr( HDC hdc )
// 参数:
// 	IN hdc - DC句柄 
// 返回值:
//	假如成功,返回_LPGDCDATA指针;否则,返回NULL
// 功能描述:
//	得到安全的DC.
//	1.检查DC是否合法; 2.检查DC的状态是否改变,如果是,更新它
// 引用: 
//	
// ************************************************

extern int _GetRgnInfo(HRGN hrgn);
#define DEBUG_GETSAFEDRAWPTR 0
_LPGDCDATA _GetSafeDrawPtr( HDC hdc )
{	// 由句柄得到其对象指针
	_LPGDCDATA lpdc = (_LPGDCDATA)HANDLE_TO_PTR( hdc );
	if( lpdc )
	{	
		if( ( (WORD)GET_OBJ_TYPE( lpdc) == OBJ_MEMDC || 
			  (WORD)GET_OBJ_TYPE( lpdc ) == OBJ_DC ) )
		{	// 类型有效
			if( lpdc->hwnd )
			{	// 该DC 与窗口关联,如果这时窗口坐标改变,需要同时更新DC
				int iUpdate = 0;
				int iRgn;
				while( lpdc->uiState &&  
					   Interlock_TestExchange( (LPLONG)&lpdc->uiState, 1, 0 ) )
				{	//改变
					_LPWINDATA lpws;
					RECT rect;
					HRGN hRgn;
					UINT uiFlags = lpdc->uiFlags;
					
					iUpdate++;  // use to test

					iRgn = SIMPLEREGION;
				    //由窗口句柄得到其指针对象
					lpws = _GetHWNDPtr( lpdc->hwnd );
					//得到DC的显示屏幕矩形
					if( uiFlags & DCX_WINDOW )
					{	//窗口DC
						rect = lpws->rectWindow;
					}
					else
					{	//客户DC
						rect = lpws->rectClient;
						OffsetRect( &rect, lpws->rectWindow.left, lpws->rectWindow.top );
					}
					//设备原点
					lpdc->deviceOrg.x = rect.left;
					lpdc->deviceOrg.y = rect.top;
					lpdc->deviceExt.cx = rect.right - rect.left;
					lpdc->deviceExt.cy = rect.bottom - rect.top;				
					
//					LockWindow();  ////2003.1.26
					//得到窗口的暴露矩形域
				    iRgn = GetExposeRgn( lpdc->hwnd, uiFlags, &hRgn );
					if( iRgn == NULLREGION ||
						iRgn == ERROR )
					{	//暴露矩形域为空或有一个错误
						WinRgn_SetRect( lpdc->hrgn, 0, 0, 0, 0 );
					}
					else
					{
						if( ( uiFlags & (DCX_VALIDATE | DCX_INTERSECTUPDATE) ) == (DCX_VALIDATE | DCX_INTERSECTUPDATE) )
						{   // 当前DC 用户调用BeginPaint返回的,需要与系统重绘区域进行运算 为a dc from beginpaint
							HRGN hClip;
							//锁住系统重绘区域
							__LockRepaintRgn( &hClip );  // 2003.1.26
							iRgn = WinRgn_Combine( lpdc->hrgn, lpdc->hrgn, hClip, RGN_OR );
							__UnlockRepaintRgn();   //2003.1.26
							if( !( iRgn == NULLREGION ||
								   iRgn == ERROR ) )
								iRgn = WinRgn_Combine( lpdc->hrgn, lpdc->hrgn, hRgn, RGN_AND );
							DEBUGMSG( DEBUG_GETSAFEDRAWPTR, ( "update dc from BeginPaint,%d,class=%s.\r\n", iUpdate, lpws->lpClass->wc.lpszClassName ) );
						}
						else
						{   // 将新的可视区域拷贝到DC now copy hRgn to dc
							WinRgn_Combine( lpdc->hrgn, hRgn, NULL, RGN_COPY );
						}
					}
					//删除临时 区域
					WinGdi_DeleteObject( hRgn );

//					UnlockWindow();   //2003.1.26
					 
					if( iRgn == NULLREGION ||
						iRgn == ERROR )
					{
						DEBUGMSG( DEBUG_GETSAFEDRAWPTR, ( "GetSafeDrawPtr_0:null rgn, class=%s, title=%s.\r\n", lpws->lpClass->wc.lpszClassName, lpws->lpWinText ) );
						return NULL;
					}
#ifdef __DEBUG
					if( iUpdate > 5 )
					{ 
						DEBUGMSG( DEBUG_GETSAFEDRAWPTR, ( "update dc loop...%d.\r\n", iUpdate ) );
					} 
#endif
				}
				if( _GetRgnInfo( lpdc->hrgn ) == NULLREGION )
				{
#ifdef __DEBUG
					//_LPWINDATA lpws = _GetHWNDPtr( ((_LPGDCDATA)hdc)->hwnd );
				
					//RETAILMSG( 1, ( "GetSafeDrawPtr_1:null rgn, class=%s, title=%s.\r\n", lpws->lpClass->wc.lpszClassName, lpws->lpWinText ) );
#endif
					return NULL;
				}
			}
			return lpdc;
		}
	}
	SetLastError( ERROR_INVALID_HANDLE );
	WARNMSG( 1, (TEXT( "Invalid hdc handle: 0x%x\r\n" ), hdc ) );
    return NULL;
}

// **************************************************
// 声明:_LPGDCDATA _GetHDCPtr( HDC hdc )
// 参数:
// 	IN hdc - DC 句柄
// 返回值:
//	假如成功,返回_LPGDCDATA指针;否则,返回NULL
// 功能描述:
//	得到安全的DC.
//	1.检查DC是否合法; 
// 引用: 
//	
// ************************************************

_LPGDCDATA _GetHDCPtr( HDC hdc )
{
	_LPGDCDATA lpdc = (_LPGDCDATA)HANDLE_TO_PTR( hdc );

	if( lpdc &&
		( (WORD)GET_OBJ_TYPE( lpdc) == OBJ_MEMDC || 
		  (WORD)GET_OBJ_TYPE( lpdc ) == OBJ_DC 
		) 
	  )
	{
		return lpdc;
	}
	SetLastError( ERROR_INVALID_HANDLE );
    WARNMSG( 1, ("error: Invalid HDC handle=0x%x\r\n", hdc) );
    return NULL;
}

// **************************************************
// 声明:DWORD _Gdi_UnrealizeColor( DWORD dwRealizeColor, DWORD * lpPal, UINT uiPalNum, UINT uiSrcColorType )
// 参数:
// 	IN dwRealizeColor - 设备相关的颜色值
//	IN uiSrcColorType - 颜色类型
//	IN lpPal - 色板指针
//	IN uiPalNum - 色板项目数
// 返回值:
//	假如成功,返回设备无关的颜色值;否则,返回0

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -