📄 win.c
字号:
/******************************************************
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 + -