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

📄 win.c

📁 深圳市微逻辑电子有限公司 巨果&#8226 Kingmos&reg 系统核心
💻 C
📖 第 1 页 / 共 5 页
字号:
//	向系统分配一个绘图DC
// 引用: 
//	系统API
// ************************************************

HDC WINAPI WinGdi_GetDCEx(HWND hWnd, HRGN hrgn, DWORD flags)
{
    _LPWINDATA lpws;
    HRGN hrgnExpose, hrgnDraw;
    RECT rect;
    HDC hdc;	

    if( hWnd == NULL || hWnd == hwndScreen.hThis )
    {	//屏幕窗口,得到一个全屏幕的DC
        rect = hwndScreen.rectWindow;
        hrgnDraw = WinRgn_CreateRect( rect.left, rect.top, rect.right, rect.bottom ); 
        hdc = GetPaintDC( hWnd, &rect, hrgnDraw, flags | DCF_GETDC_ALLOC );
#ifdef EML_DOS
        _HideMouse();
#endif
        return hdc;
    }
    lpws = _GetHWNDPtr( hWnd );
    if( lpws )
    {	//有效
        if( flags & DCX_WINDOW )
            rect = lpws->rectWindow;	//用窗口矩形
        else
        {	//用客户区矩形
            rect = lpws->rectClient;
            OffsetRect( &rect, lpws->rectWindow.left, lpws->rectWindow.top );
        }
		//初始化裁剪区
        hrgnDraw = WinRgn_CreateRect( 0, 0, 0, 0 );

        ASSERT( hrgnDraw );
		if( IS_SHOWENABLE( lpws->dwMainStyle ) )  //为 ShowDesktop修改
        {	//得到窗口的爆露矩形
			GetExposeRgn( hWnd, flags, &hrgnExpose );

            ASSERT( hrgnExpose );
			// hrgn是client 坐标, 偏移到screen
			if( hrgn )
			{
				WinRgn_Offset( hrgn, rect.left, rect.top );
			}
			
            if( flags & DCX_EXCLUDERGN )  //需要排除 hrgn吗 ?
                WinRgn_Combine( hrgnDraw, hrgnExpose, hrgn, RGN_DIFF );
            else if( flags & DCX_INTERSECTRGN )	//需要内交 hrgn吗 ?
                WinRgn_Combine( hrgnDraw, hrgnExpose, hrgn, RGN_AND );
            else	//需要拷贝 hrgn吗 ?
                WinRgn_Combine( hrgnDraw, hrgnExpose, 0, RGN_COPY );
            if( flags & DCX_VALIDATE )	//是否需要更新系统裁剪区
            {   // exlude hrgnExpose from update region
                if( flags & DCX_INTERSECTUPDATE )
                    WinRgn_Combine( hrgn, hrgn, hrgnExpose, RGN_DIFF );
            }
			// 恢复hrgn的原始状态
			if( hrgn )
			{
				WinRgn_Offset( hrgn, -rect.left, -rect.top );
			}
            WinGdi_DeleteObject( hrgnExpose );
        }
		//向系统申请/并初始化一个DC对象 
        hdc = GetPaintDC( hWnd, &rect, hrgnDraw, flags | DCF_GETDC_ALLOC );
    #ifdef EML_DOS
        _HideMouse();
    #endif
        return hdc;
    }
    return 0;
}

// **************************************************
// 声明:HDC WINAPI WinGdi_GetClientDC( HWND hWnd )
// 参数:
// 	IN hWnd-窗口句柄
// 返回值:
//	成功:返回该窗口客户区DC句柄
//	否则:返回NULL
// 功能描述:
//	得到客户区DC
// 引用: 
//	系统 API
// ************************************************

HDC WINAPI WinGdi_GetClientDC( HWND hWnd )
{
    return WinGdi_GetDCEx( hWnd, 0, DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN );
}

// **************************************************
// 声明:HDC WINAPI WinGdi_GetWindowDC( HWND hWnd )
// 参数:
// 	IN hWnd-窗口句柄
// 返回值:
//	成功:返回该窗口DC句柄
//	否则:返回NULL
// 功能描述:
//	得到窗口DC
// 引用: 
//	系统API
// ************************************************

HDC WINAPI WinGdi_GetWindowDC( HWND hWnd )
{
    return WinGdi_GetDCEx( hWnd, 0, DCX_CLIPSIBLINGS | DCX_WINDOW );
}

// **************************************************
// 声明:HDC WINAPI WinGdi_BeginPaint( HWND hWnd, LPPAINTSTRUCT lpPaint )
// 参数:
//	IN hWnd-窗口句柄
//	IN lpps-PAINTSTRUCT 结构指针
// 返回值:
//	成功:返回该窗口DC句柄
//	否则:返回NULL
// 功能描述:
//	准备窗口的绘图数据,并返回DC句柄
// 引用: 
//	系统API
// ************************************************

HDC WINAPI WinGdi_BeginPaint( HWND hWnd, LPPAINTSTRUCT lpPaint )
{
    _LPWINDATA lpws = _GetHWNDPtr( hWnd );
    DWORD flags = 0;
    HRGN hrgn, hrgnUpdate, hrgnRemove;
    RECT rc;
	
    if( lpws )
    {	//根据风格得到相关的 DC
        if( lpws->dwMainStyle & WS_CLIPSIBLINGS )
            flags |= DCX_CLIPSIBLINGS;
        if( lpws->dwMainStyle & WS_CLIPCHILDREN )
            flags |= DCX_CLIPCHILDREN;
        if( !(lpws->dwMainStyle & WS_CHILD) )
            flags |= DCX_CLIPSIBLINGS;
        if( lpws->dwMainStyle & WS_CHILD )
            flags |= DCX_WINDOW;
		flags |= DCX_VALIDATE | DCX_INTERSECTUPDATE;
		//清除该窗口的 WM_PAINT消息
		ClearThreadQueue( 0, hWnd, WM_PAINT, WM_PAINT );

		//EnterCriticalSection( &csWindow );
		//进入冲突段
		LockCSWindow(); //2004-12-28
		//得到该窗口的暴露区域
		GetExposeRgn( hWnd, flags, &hrgnUpdate );
		//得到窗口区域
		GetExposeRgn( hWnd, DCX_CLIPCHILDREN | DCX_WINDOW | flags, &hrgnRemove );

		UnlockCSWindow(); //2004-12-28
		
		//锁住系统无效区域
		__LockRepaintRgn( &hrgn );  // 2003.1.25        
		//窗口暴露区域与系统无效区域做内交
		WinRgn_Combine( hrgnUpdate, hrgnUpdate, hrgn, RGN_AND );
		//从系统无效区清除窗口区域
		WinRgn_Combine( hrgn, hrgn, hrgnRemove, RGN_DIFF );
		//解锁系统无效区域
		__UnlockRepaintRgn();   //2003.1.25

		WinGdi_DeleteObject(hrgnRemove); 
		
		
        if( lpws->dwMainStyle & WS_CHILD )
        {	//子窗口
			//得到裁剪区矩形
            WinRgn_GetBox(hrgnUpdate, &rc);
			//转化到客户坐标
            OffsetRect( &rc, -lpws->rectWindow.left, -lpws->rectWindow.top );
            if( !(rc.left >= lpws->rectClient.left &&
				rc.top >= lpws->rectClient.top &&
                rc.right <=  lpws->rectClient.right &&
                rc.bottom <= lpws->rectClient.bottom) )
            {
                HRGN hrgnNC;
				int xOffset = lpws->rectWindow.left;
				int yOffset = lpws->rectWindow.top;
				// hrgn是screen 坐标, 偏移到client
				WinRgn_Offset( hrgnUpdate, -xOffset, -yOffset );
				// 发送非客户区绘制消息
                WinMsg_Send( hWnd, WM_NCPAINT, (WPARAM)hrgnUpdate, 0 );
				//恢复
				WinRgn_Offset( hrgnUpdate, xOffset, yOffset );
				//得到非客户区区域
                hrgnNC = _GetNClientRegion( lpws );
				//去掉非客户区区域
                WinRgn_Combine( hrgnUpdate, hrgnUpdate, hrgnNC, RGN_DIFF );
                WinGdi_DeleteObject( hrgnNC );
            }
        }
        else
        {
        }
		//得到客户区矩形(窗口坐标)
        rc = lpws->rectClient;
		//转换到屏幕坐标
        OffsetRect( &rc, lpws->rectWindow.left, lpws->rectWindow.top );
        lpPaint->hdc = GetPaintDC( hWnd, &rc, hrgnUpdate, flags | DCF_BEGIN_PAINT_ALLOC );
		WinRgn_GetBox( hrgnUpdate, &lpPaint->rcPaint );
		//转换到客户区坐标
		OffsetRect( &lpPaint->rcPaint, -(lpws->rectWindow.left+lpws->rectClient.left), -(lpws->rectWindow.top+lpws->rectClient.top) ); 
		
#ifdef EML_DOS
        _HideMouse();
#endif
		//假如可能,隐藏caret
		if( lpPaint->hdc )
			_HideCaret( hWnd, lpPaint->hdc );

		//擦除背景		
        lpPaint->fErase = (BOOL)WinMsg_Send( hWnd, WM_ERASEBKGND, (WPARAM)lpPaint->hdc, 0 );
		
		
		
		return lpPaint->hdc;
    }
    return NULL;
}

// **************************************************
// 声明:int WINAPI WinGdi_ReleaseDC( HWND hWnd, HDC hdc )
// 参数:
// 	IN hWnd-窗口句柄
//	IN hdc-DC句柄
// 返回值:
//	成功:返回1
//	否则:返回0
// 功能描述:
//	释放DC
// 引用: 
//	系统API
// ************************************************

int WINAPI WinGdi_ReleaseDC( HWND hWnd, HDC hdc )
{
#ifdef EML_DOS
    _ShowMouse();
#endif
    return ReleasePaintDC( hWnd, hdc );
}

// **************************************************
// 声明:BOOL WINAPI WinGdi_EndPaint( HWND hWnd, const PAINTSTRUCT *lpPaint )
// 参数:
// 	IN hWnd-窗口句柄
//	IN lpPaint- PAINTSTRUCT结构指针
// 返回值:
//	假如成功,返回TRUE;否则,返回FALSE
// 功能描述:
//	结束并释放DC
// 引用: 
//	系统API
// ************************************************
#define DEBUG_WinGdi_EndPaint 0
BOOL WINAPI WinGdi_EndPaint( HWND hWnd, const PAINTSTRUCT *lpPaint )
{   
    if( lpPaint->hdc )
	{
        _ShowCaret( hWnd, lpPaint->hdc );
	    WinGdi_ReleaseDC( hWnd, lpPaint->hdc );
	}
	else
	{
		ASSERT( 0 );
		ERRORMSG( DEBUG_WinGdi_EndPaint, ( "error in WinGdi_EndPaint: invalid hdc.\r\n" ) );
	}
    
    return TRUE;
}

// **************************************************
// 声明:BOOL WINAPI Win_BringToTop( HWND hWnd )
// 参数:
// 	IN hWnd – 窗口句柄
// 返回值:
//	假如成功,返回TRUE;否则,返回FALSE
// 功能描述:
//	将窗口放到Z序的顶层
// 引用: 
//	系统API
// ************************************************

BOOL WINAPI Win_BringToTop( HWND hWnd )
{
    return Win_SetPos( hWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE );
}

// **************************************************
// 声明:LRESULT WINAPI Win_CallProc( WNDPROC lpPrevWndFunc, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam )
// 参数:
// 	IN lpPrevWndFunc – 前一个窗口消息处理函数
// 	IN hWnd – 窗口句柄
// 	IN msg – 窗口消息
// 	IN wParam – 第一个参数
// 	IN lParam – 第二个参数
// 返回值:
//	依赖于具体的消息
// 功能描述:
//	回调窗口消息处理函数
// 引用: 
//	系统API
// ************************************************

LRESULT WINAPI Win_CallProc( WNDPROC lpPrevWndFunc, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam )
{
    _LPWINDATA lpws;

    lpws = _GetHWNDPtr( hWnd );
    if( lpws )
	{
		if( (DWORD)lpPrevWndFunc == -1 )
			lpPrevWndFunc = lpws->lpClass->wc.lpfnWndProc; // 用类默认的消息处理函数
	    return _CallWindowProc( lpws, lpPrevWndFunc, Msg, wParam, lParam );
	}
	return -1;
}

// **************************************************
// 声明:HWND WINAPI Win_ChildFromPoint( HWND hParent, int x, int y, UINT uFlags )
// 参数:
// 	IN hParent - 父窗口
//	IN x - x 坐标(客户坐标)
//	IN y - y 坐标(客户坐标)
//	IN uFlags - 附加标志
// 返回值:
//	假如成功,返回拥有该点的子窗口;否则,返回NULL
// 功能描述:
//	得到拥有该点的子窗口
// 引用: 
//	系统API
// ************************************************

HWND WINAPI Win_ChildFromPoint( HWND hParent, int x, int y, UINT uFlags )
{
    _LPWINDATA lpwsParent = _GetHWNDPtr( hParent );
    HWND hwndHas = 0;
	POINT point;

	point.x = x;
	point.y = y;
    
	ASSERT( lpwsParent );

    if( lpwsParent )
    {	//父窗口有效
		_LPWINDATA lpwsChild = lpwsParent->lpwsChild;
		//将点转化到屏幕坐标
        Win_ClientToScreen( hParent, &point );
		//
        if( PtInRect( &lpwsParent->rectWindow, point ) )
        {   // 点在父窗口内 search all child windows
            hwndHas = hParent;
			//搜索所有的子窗口,检查是否拥有该点
            while( lpwsChild )
            {
                if( uFlags == CWP_ALL )
                {	//搜索所有的子窗口
                    if( PtInRect( &lpwsChild->rectWindow, point ) )
                    {	//在该子窗口
                        hwndHas = lpwsChild->hThis;
                        break;
                    }
                }
                else
                {	//仅仅搜索的有效的子窗口
                    if( (uFlags & CWP_SKIPINVISIBLE) &&
						IS_SHOWENABLE( lpwsChild->dwMainStyle ) == 0  //为 ShowDesktop修改						
					  )
                        goto CFP_NEXTWIN;
                    if( (uFlags & CWP_SKIPDISABLED) &&
                        (lpwsChild->dwMainStyle & WS_DISABLED ) )
                        goto CFP_NEXTWIN;
                    if( PtInRect( &lpwsChild->rectWindow, point ) )
                    {	//命中
                        hwndHas = lpwsChild->hThis;
                        break;
                    }
                }
    CFP_NEXTWIN:
                //下一个
				lpwsChild = lpwsChild->lpwsNext;
            }
        }
    }
    return hwndHas;
} 

// **************************************************
// 声明:BOOL WINAPI Win_ClientToScreen( HWND hWnd, LPPOINT lpPoint )
// 参数:
//	IN hWnd--窗口句柄
//	IN lpPoint--客户坐标,当成功返回时,将用来保存屏幕坐标
// 返回值:
//	假如成功,返回TRUE;否则,返回FALSE
// 功能描述:
//	客户坐标到屏幕坐标
// 引用: 
//	系统API
// ************************************************

BOOL WINAPI Win_ClientToScreen( HWND hWnd, LPPOINT lpPoint )
{
    _LPWINDATA lpws = _GetHWNDPtr( hWnd );

    if( lpws )
    {
        lpPoint->x += lpws->rectClient.left + lpws->rectWindow.left;
        lpPoint->y += lpws->rectClient.top + lpws->rectWindow.top;
        return TRUE;
    }
    return FALSE;
}

// **************************************************
// 声明:BOOL WINAPI Win_Close( HWND hWnd )
// 参数:
//	IN hWnd--窗口句柄
// 返回值:
//	假如成功,返回TRUE;否则,返回FALSE
// 功能描述:
//	关闭窗口
// 引用: 
//	系统API
// ************************************************

BOOL WINAPI Win_Close( HWND hWnd )
{   // minimize the window
    //Win_Show( hWnd, SW_MINIMIZE );
    return TRUE;
}

// **************************************************
// 声明:HWND WINAPI Win_CreateEx(                 
//						DWORD dwExStyle,
//						LPCBYTE lpClassName,
//						LPCBYTE lpText,
//						DWORD dwMainStyle,
//						int x, int y, int dx, int dy,
//						HWND hParent,
//						HMENU hMenu,
//						HINSTANCE hInstance,
//						LPVOID lpCreateParams )
// 参数:
//	IN dwExStyle-扩展风格,包含:
//			WS_EX_TOPMOST-顶层窗口
//	IN lpClassName-类名
//	IN lpText-标题
//	IN dwMainStyle-风格
//			WS_OVERLAPPED-可重叠式
//			WS_POPUP-弹出式
//			WS_CHILD-子窗口
//			WS_CLIPSIBLINGS-裁剪兄弟窗口
//			WS_CLIPCHILDREN-裁剪子窗口
//			WS_CAPTION-有标题
//			WS_BORDER-有单边框
//			WS_DLGFRAME-对话框边框
//			WS_VSCROLL-垂直滚动条
//			WS_HSCROLL-水平滚动条

⌨️ 快捷键说明

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