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

📄 win.c

📁 深圳市微逻辑电子有限公司 巨果&#8226 Kingmos&reg 系统核心
💻 C
📖 第 1 页 / 共 5 页
字号:
/******************************************************
Copyright(c) 版权所有,1998-2005微逻辑。保留所有权利。
******************************************************/


/*****************************************************
文件说明:窗口管理模块
版本号:3.0.0
开发时期:1998
作者:李林
修改记录:
2005-03-25, 修改 RemovePopupWindow, 用 新的方法(裁剪树枝)
2005-03-12, 将 SendMessage 改为 WinMsg_Send
2005-01-08, 调整了 SetWindowLong 和 GetWindowLong的 case 顺序
2004-12-28,BeginPaint 移到上面做一次性处理 2004-12-20
2004-10-13, 修改 SetWindowLong 的 GWL_WNDPROC 的有关进程的检查
2004-09-09,隐含,清除所有鼠标消息
2004-08-30: 增加 WS_EX_NOFOCUS 风格
2004-08-04: 将 Win_SetPos 改为 _Win_SetPos
2003-02-24: 用 __GET_OBJECT_HANDLE 代替 PTR_TO_HANDLE 
2003-09-15 -》16日: SelectClipRgn, GetDCEx, WM_NCPAINT, ExtSelectClipRgn, SelectObject的
                    hrgn应是Client坐标, 以前是Screen坐标,现改之
2003-09-03  增加对lpFind->lpcClassName == NULL的处理
2003-08-04: 增加 WS_MINIMIZE 功能
2003-07-30: 解决互锁的问题
2003-07-01: Win_GetText,  将Thread改为Process
2003-06-19: Win_SetLong 当新的style 与 old style 相同时不处理
2003-06-03: 增加对 dwForegroundThreadID 的互斥

2003-06-02: SetWindowLong 删除对 GWL_HWNDPARENT的处理
2003-05-26: 增加对 _IsMinimized 的窗口的检查
2003-05-14: Win_Desktory 增加当前台窗口被破坏时,系统将前台窗口
2003-05-13:GetClassName 有错误
2003-04-23: error:当破坏任何window时,系统的dwForegroundThreadId都被设为NULL
              
2003-04-10:两个ap之间切换没有发WM_KILLFOUCS消息
            1.增加DoSetActive和DoSetFocus两个函数
			2.将Win_SetActive和Win_SetFocus的部分功能
			  放到DoSetActive和DoSetFocus
			3.修改Win_SetForeground
******************************************************/

#include <eframe.h>
#include <estring.h>
#include <eassert.h>
#include <ekeybrd.h>
#include <eapisrv.h>

#include <bheap.h>
#include <epwin.h>
#include <gwmeobj.h>
#include <winsrv.h>
#include <gdisrv.h>
#include <eobjcall.h>
#ifdef EML_DOS  
    #include <emouse.h>
#endif
#include <gdc.h>

extern BOOL ReleasePaintDC( HWND hWnd, HDC hdc );
extern HDC GetPaintDC( HWND hwnd, LPCRECT lprect, HRGN hrgnClip, UINT uiFlags );
extern int _GetRgnInfo(HRGN hrgn);

_LPWINDATA lphwndRoot = NULL;

static _REGCLASS classScreen;

//extern proc define
extern BOOL CALLBACK __LockRepaintRgn( HRGN * lphrgn );
extern BOOL CALLBACK __UnlockRepaintRgn( void );

extern void FreeStr( LPSTR lpstr );

// private proc define start
static HRGN _GetNClientRegion( _LPWINDATA lpws );
static BOOL CALLBACK HitTest( HWND hwnd, LPARAM lParam );
static BOOL CALLBACK EnumTest( HWND hwnd, LPARAM lParam );
static _LPWINDATA _BottomChildWindow( _LPWINDATA );
static BOOL _ChangeBound( HWND hWnd, LPRECT lpWindowRect, LPRECT lpClientRect );
static BOOL _DeleteWinObject( _LPWINDATA );
#define GET_Z_ORDER_UP( lpws ) ( ( (lpws)->dwMainStyle & WS_CHILD ) ? (lpws)->lpwsParent : (&hwndScreen) )

static HWND _GetHitedWindow();
static int _GetTopHeight( DWORD dwMainStyle, DWORD dwSubStyle );
static int _GetLeftBorderWidth( DWORD dwMainStyle, DWORD dwSubStyle );
static int _GetBottomHight( DWORD dwMainStyle, DWORD dwSubStyle );
static int _GetRightWidth( DWORD dwMainStyle, DWORD dwSubStyle );
static int _GetMenuHeight( void );
static int _SetState( _LPWINDATA lpws, DWORD style, BOOL bEnable );

static LRESULT _CalcClientBound( HWND hWnd, LPRECT lprect );
static BOOL Link_InsertWindowToScreen( _LPWINDATA lpws );
static BOOL Link_InsertWindowAfter( _LPWINDATA lpwsInsertAfter, _LPWINDATA lpws, _LPWINDATA lpwsTop );
static BOOL Link_InsertToParent( _LPWINDATA lpwsInsertAfter, _LPWINDATA lpws, _LPWINDATA lpwsParent );
static BOOL _IsWindowStyle( HWND hWnd, DWORD dwStyle );
static BOOL _IsMinimized( HWND );
static void _MapAbsCoordinate( HWND, LPPOINT );
static HWND _PrevTopmostWindow( HWND );
void CALLBACK __PutPaintEvent( LPMSG );
static BOOL Link_RemoveWindow( _LPWINDATA );
static BOOL _SetWinParam( _LPWINDATA pws, LPCREATESTRUCT pcs );
static HANDLE _AllocWinObjectHandle( int s );
static HWND DoSetActive( LPGWEDATA lpgwe, _LPWINDATA lpws, BOOL bSync );
static HWND DoSetFocus( LPGWEDATA lpgwe, _LPWINDATA lpws, BOOL bSync );
static BOOL DoEnumWindow( _LPWINDATA lpwsChild, BOOL bEnumChild, CALLBACKDATA * lpcd, LPARAM lParam );

#define WDF_HIDE           0x1
#define WDF_CLEAR          0x2

#define IS_SHOWENABLE( dwStyle ) ( ( (dwStyle) & WS_VISIBLE ) && ( (dwStyle) & WS_MINIMIZE ) == 0 )

static BOOL _Win_Destroy( _LPWINDATA lpws, DWORD dwCurThreadID, UINT uiFlag );
static _LPWINDATA _GetSafeOwner( _LPWINDATA lpwsParent );
static HWND GetDesktopExplore( void );
static BOOL WINAPI _Win_SetPos( _LPWINDATA lpws, HWND hWndInsertAfter,
                   int x, int y, int cx, int cy,
                   UINT uFlags );

static CRITICAL_SECTION csWindow;
static DWORD dwForegroundThreadId = 0;
static CRITICAL_SECTION csForegroundThreadId;

#define MAGIC_NUM 0xCAFEEFAC
#define __GET_OBJECT_ADDR( h ) ( (_LPWINDATA)HANDLE_TO_PTR( h ) )
#define __GET_OBJECT_HANDLE( ptr ) PTR_TO_HANDLE( ptr )

// **************************************************
// 声明:static LONG _GetLong( const LPBYTE lpBuffer )
// 参数:
// 	IN lpBuffer - 内存地址
// 返回值:
//	long 型值
// 功能描述:
//	从一个内存里得到一个整型值
// 引用: 
//	
// ************************************************

static LONG _GetLong( const LPBYTE lpBuffer )
{
    LONG d;
    memcpy( &d, lpBuffer, sizeof( LONG ) );
    return d;
}

// **************************************************
// 声明:static void _SetLong( LPBYTE lpBuffer, LONG d )
// 参数:
// 	IN lpBuffer - 内存地址
//	IN d - 整型值
// 返回值:
//	无
// 功能描述:
//	设置一个整型值到内存
// 引用: 
//	
// ************************************************

static void _SetLong( LPBYTE lpBuffer, LONG d )
{
    memcpy( lpBuffer, &d, sizeof( LONG ) );
}

// **************************************************
// 声明:static LRESULT WINAPI _ScreenWndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
// 参数:
// 	
// 返回值:
//	
// 功能描述:
//	根窗口除了函数,无实际用途
// 引用: 
//	
// ************************************************

static LRESULT WINAPI _ScreenWndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
    return 0;
}

// **************************************************
// 声明:void LockCSWindow( void )
// 参数:
// 	无
// 返回值:
//	无
// 功能描述:
//	锁住窗口
// 引用: 
//	测试
// ************************************************

//       TEST-code
void LockCSWindow( void )
{
	EnterCriticalSection( &csWindow );
}

// **************************************************
// 声明:void UnlockCSWindow( void )
// 参数:
// 	无
// 返回值:
//	无
// 功能描述:
//	解锁
// 引用: 
//	
// ************************************************

void UnlockCSWindow( void )
{
	LeaveCriticalSection( &csWindow );
}

// **************************************************
// 声明:BOOL _InitWindowManager( HINSTANCE hInst )
// 参数:
// 	IN hInst - 进程实例句柄
// 返回值:
//	假如成功,返回TRUE;否则,返回FALSE
// 功能描述:
//	初始化窗口管理器
// 引用: 
//	被 gwme.c 调用
// ************************************************

BOOL _InitWindowManager( HINSTANCE hInst )
{	
	//初始化窗口冲突段
    InitializeCriticalSection( &csWindow );
	csWindow.lpcsName = "CS-WIN";
	//初始化前景窗口设置冲突段
	InitializeCriticalSection( &csForegroundThreadId );
	//初始化窗口块堆
	//初始化屏幕类
	memset( &classScreen , 0, sizeof( classScreen ) );    
	classScreen.objType = OBJ_CLASS;
	classScreen.hOwnerProcess = hgwmeProcess;
	classScreen.nRefCount = 1;
	classScreen.wc.hInstance = hInst;
    classScreen.wc.lpszClassName= "___winsys___";
    classScreen.wc.lpfnWndProc = (WNDPROC)_ScreenWndProc;
	//分配根窗口类
	lphwndRoot = BlockHeap_Alloc( hgwmeBlockHeap, 0, sizeof(hwndScreen) );
	
	//初始化根窗口类
	memset( &hwndScreen, 0, sizeof( hwndScreen ) );
    hwndScreen.objType = OBJ_WINDOW;
    hwndScreen.rectWindow.right = WinSys_GetMetrics( SM_CXSCREEN );
    hwndScreen.rectWindow.bottom = WinSys_GetMetrics( SM_CYSCREEN );
    hwndScreen.rectClient.right = WinSys_GetMetrics( SM_CXSCREEN );
    hwndScreen.rectClient.bottom = WinSys_GetMetrics( SM_CYSCREEN );
    hwndScreen.dwMainStyle = WS_POPUP | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
	
	hwndScreen.lpClass = &classScreen;
    hwndScreen.lpfnWndProc = _ScreenWndProc;
	hwndScreen.hThis = (HANDLE)__GET_OBJECT_HANDLE(&hwndScreen);

    return TRUE;
}

// **************************************************
// 声明:DWORD LockForegroundThreadId( void )
// 参数:
// 	无
// 返回值:
//	返回当前的前景窗口ID
// 功能描述:
//	锁住并得到当前的前景窗口ID
// 引用: 
//	
// ************************************************

DWORD LockForegroundThreadId( void )
{
	EnterCriticalSection( &csForegroundThreadId );
	return dwForegroundThreadId;
}

// **************************************************
// 声明:void UnlockForegroundThreadId( void )
// 参数:
// 	无
// 返回值:
//	无
// 功能描述:
//	解锁
// 引用: 
//	
// ************************************************

void UnlockForegroundThreadId( void )
{
	LeaveCriticalSection( &csForegroundThreadId );
}

// **************************************************
// 声明:void SetForegroundThreadId( DWORD dwNewId )
// 参数:
// 	IN dwNewId - 线程ID
// 返回值:
//	无
// 功能描述:
//	设置当前的前景线程
// 引用: 
//	
// ************************************************

void SetForegroundThreadId( DWORD dwNewId )
{
	EnterCriticalSection( &csForegroundThreadId );
	if( dwForegroundThreadId )
	{
		Thread_ChangeRotate( dwForegroundThreadId, -2 ); 
	}
	if( dwNewId )
	{
		Thread_ChangeRotate( dwNewId, 2 ); 
	}
	dwForegroundThreadId = dwNewId;
	
	LeaveCriticalSection( &csForegroundThreadId );
}

// **************************************************
// 声明:void ExchangeForegroundThreadId( DWORD dwNewId, DWORD dwCompareId )
// 参数:
// 	IN dwNewId - 新的前景线程ID
//	IN dwCompareId - 需要比较的前景线程ID
// 返回值:
//	无
// 功能描述:
//	假如当前的前景线程等于 dwCompareId,则设置dwNewId为当前的前景线程
// 引用: 
//	
// ************************************************

void ExchangeForegroundThreadId( DWORD dwNewId, DWORD dwCompareId )
{
	EnterCriticalSection( &csForegroundThreadId );
	if( dwCompareId == dwForegroundThreadId )
	{
		if( dwForegroundThreadId )
		{
			Thread_ChangeRotate( dwForegroundThreadId, -2 ); 
		}
		if( dwNewId )
		{
			Thread_ChangeRotate( dwNewId, 2 ); 
		}

	    dwForegroundThreadId = dwNewId;
	}
	LeaveCriticalSection( &csForegroundThreadId );
}

// **************************************************
// 声明:BOOL IsForegroundThread( void )
// 参数:
// 	无
// 返回值:
//	假如是,返回TRUE;否则,返回FALSE
// 功能描述:
//	判断当前的线程是否前景线程
// 引用: 
//	
// ************************************************

BOOL IsForegroundThread( void )
{
	return dwForegroundThreadId == GetCurrentThreadId() ? TRUE : FALSE;
}

// **************************************************
// 声明:BOOL _DeInitWindowManager( void )
// 参数:
// 	无
// 返回值:
//	假如成功,返回TRUE;否则,返回FALSE
// 功能描述:
//	释放窗口管理器(当系统退出时会调用该函数)
// 引用: 
//	
// ************************************************

BOOL _DeInitWindowManager( void )
{
    BlockHeap_Free( hgwmeBlockHeap, 0, lphwndRoot, sizeof(_WINDATA) );
	DeleteCriticalSection( &csWindow );
	return TRUE;
}

// **************************************************
// 声明:static HWND GetDesktopExplore( void )
// 参数:
// 	无
// 返回值:
//	假如成功,返回当前的桌面窗口句柄;否则,返回NULL
// 功能描述:
//	得到当前的桌面窗口句柄
// 引用: 
//	
// ************************************************

static HWND GetDesktopExplore( void )
{
#ifdef INLINE_PROGRAM
	extern const char classDESKTOP[];	
#else
	const char classDESKTOP[] = "_DESKTOP_CLASS_";
#endif
	static HWND hDesktop = NULL;
	if( hDesktop == NULL )
	{
	    hDesktop = Win_Find( classDESKTOP, NULL );
	}
	return hDesktop;
}

// **************************************************
// 声明:BOOL WINAPI Win_AdjustRectEx( LPRECT lpRect, DWORD dwMainStyle, BOOL bMenu, DWORD dwSubStyle )
// 参数:
// 	IN/OUT lpRect - 窗口矩形
//	IN dwMainStyle - 窗口风格
//	IN bMenu - 窗口是否包含菜单
//	IN dwSubStyle - 窗口的扩展风格
// 返回值:
//	假如成功,返回TRUE;否则,返回FALSE
// 功能描述:
//	计算,得到真实的窗口矩形
// 引用: 
//	系统API
// ************************************************

BOOL WINAPI Win_AdjustRectEx( LPRECT lpRect, DWORD dwMainStyle, BOOL bMenu, DWORD dwSubStyle )
{
    lpRect->top -= _GetTopHeight( dwMainStyle, dwSubStyle );
    lpRect->left -= _GetLeftBorderWidth( dwMainStyle, dwSubStyle );
    lpRect->bottom += _GetBottomHight( dwMainStyle, dwSubStyle );
    lpRect->right += _GetRightWidth( dwMainStyle, dwSubStyle );
    if( bMenu )
        lpRect->top -= _GetMenuHeight();
    return TRUE;
}

// **************************************************
// 声明:HDC WINAPI WinGdi_GetDCEx(HWND hWnd, HRGN hrgn, DWORD flags)
// 参数:
//	IN hWnd-窗口句柄
//	IN hrgn-剪裁区域
//	IN flags-标志,包含:
//    DCX_WINDOW-返回窗口区域的DC而不是客户区域的DC
//    DCX_CLIPCHILDREN-剪裁掉该窗口的子窗口
//    DCX_CLIPSIBLINGS-剪裁掉该窗口的兄弟窗口
//    DCX_EXCLUDERGN-剪裁掉hrgnClip区域
//    DCX_INTERSECTRGN-内交hrgnClip区域
//    DCX_VALIDATE-当与DCX_INTERSECTUPDATE组合时,与BeginPaint类似
//    DCX_PARENTCLIP-用父窗口的可视区域
// 返回值:
//	成功:返回DC句柄
//	否则:返回NULL
// 功能描述:

⌨️ 快捷键说明

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