📄 winsite.cpp
字号:
}
}
}
}
void
CHXWinSite::_SetSize(HXxSize size)
{
// generate an OS event
HX_ASSERT(m_pWindow && m_pWindow->window);
/*
* Change the size of the window using platform specific calls.
* Note: the size being requested is the "client" size for the
* window, so we need to actually determine the outer rect size.
* We do this by getting the current window rect and client rect,
* the difference is the "extra" size associated with any window
* dressing.
*/
HWND tempHwnd = (HWND) GetWindow()->window;
RECT rect1;
::GetWindowRect(tempHwnd,&rect1);
MapWindowPoints(NULL, GetParent(tempHwnd), (POINT*)&rect1, 2);
SafeMoveWindow( tempHwnd,
(int)rect1.left, (int)rect1.top,
(int)size.cx, (int)size.cy,
m_bIsVisible);
}
void CHXWinSite::_SetPosition(HXxPoint position)
{
//Since I just flattened the window structure this function has to
//me modified to take that into account.
if(m_pWindow->window && !m_bWindowCreatedByCreate)
{
SafeMoveWindow((HWND)m_pWindow->window,
(int)m_topleft.x,
(int)m_topleft.y,
(int)m_size.cx ,
(int)m_size.cy ,
m_bIsVisible);
}
else
{
SafeMoveWindow((HWND) GetWindow()->window,
(int)position.x,
(int)position.y,
(int)m_size.cx ,
(int)m_size.cy ,
m_bIsVisible);
}
}
void CHXWinSite::_DamageRect(HXxRect rect)
{
// if (m_pVideoSurface && m_pVideoSurface->m_nBltMode == HX_OVERLAY_BLT)
// {
// return;
// }
// // We need to tell the os that we are modifing the video window.
// // The mechanism for doing this is to call invaliadteRect, and
// // then to respond to the WM_PAINT. Of course we are going to
// // respond to the 'WM_PAINT' before we get the WM_PAINT by the
// // renderer calling forceRedraw. Thus, we will remember the rect
// // and see if it bounds the PaintStruct we get in our subsequent
// // paint. If so then we will ignore it. While this is not the
// // optimal solution, we have little choice due to dead locking
// // issues.
// HXxWindow* pwindow = GetWindow();
// if(pwindow && pwindow->window)
// {
// RECT overAllrect;
// HDC hdc = ::GetDC((HWND)pwindow->window);
// int retVal = ::GetClipBox(hdc, &overAllrect);
// ::IntersectRect( (RECT*)&rect, (RECT*)&rect, &overAllrect );
// if (retVal != NULLREGION)
// {
// //If any of a set of test points is not visible, then we
// //will assume there is a drop down menu over us and invalidate
// //it.
// //XXXgfw Currect test points will be four corners and center point.
// BOOL bVisible = TRUE;
// int middleY = rect.top+(rect.bottom-rect.top)/2;
// int middleX = rect.left+(rect.right-rect.left)/2;
// bVisible = bVisible && ::PtVisible( hdc, rect.left, rect.top);
// bVisible = bVisible && ::PtVisible( hdc, rect.right-1, rect.top);
// bVisible = bVisible && ::PtVisible( hdc, rect.left, rect.bottom-1);
// bVisible = bVisible && ::PtVisible( hdc, rect.right-1, rect.bottom-1);
// bVisible = bVisible && ::PtVisible( hdc, middleX, middleY );
// //XXXgfw We are still getting artifacts from drop down
// //menus that go too fast. Guess we have to invalidate our
// //whole window.
// if( !bVisible )
// {
// ::InvalidateRect((HWND)pwindow->window, (RECT*)NULL, FALSE);
// }
// }
// ReleaseDC((HWND)pwindow->window, hdc);
// }
}
BOOL CHXWinSite::_ShouldEnterForceRedraw()
{
if (InterlockedIncrement(&m_lBltEntryCount) > 1)
{
InterlockedDecrement(&m_lBltEntryCount);
return FALSE;
}
return TRUE;
}
void
CHXWinSite::_ExitForceRedraw()
{
InterlockedDecrement(&m_lBltEntryCount);
}
void
CHXWinSite::_SendOSUpdateMessage()
{
InvalidateRect((HWND) GetWindow()->window, NULL, FALSE);
SafeUpdateWindow((HWND) GetWindow()->window);
}
void
CHXWinSite::_ShowSite(BOOL bShow)
{
if( m_pWindow && m_pWindow->window)
{
SafeShowWindow((HWND)m_pWindow->window, bShow ? SW_SHOW : SW_HIDE);
}
}
BOOL
CHXWinSite::_AtSystemTime()
{
return (m_ulSiteThreadID == GetCurrentThreadId());
}
BOOL
CHXWinSite::_HandleOSEvents(HXxEvent* /*IN*/ pEvent)
{
BOOL ret = FALSE;
switch (pEvent->event)
{
case WM_NCHITTEST:
if (m_pTopLevelSite->m_bSetCaptureOn)
{
if( m_pTopLevelSite->m_pCaptureUser )
m_pTopLevelSite->m_pCaptureUser->HandleEvent(pEvent);
}
ret = TRUE;
break;
case WM_CHAR:
case WM_KEYDOWN:
case WM_KEYUP:
{
//Check to see if focus has been set if so send the message
//only to that window.
//XXXgfw, we need to revisit this idea of a focus site.
//with this code added only the site that was last clicked
//gets the native event. No children, no nothing. The user
//is bound to click a site at random just to bring the player
//to the top of the window stack for example...
// CHXBaseSite* pFocusSite;
// pFocusSite = m_pTopLevelSite->GetFocusSite();
// if (pFocusSite)
// {
// if (pFocusSite == this)
// {
// // we have already called HandleEvent on the original
// // user in HandleWndProc
// if (pEvent->window != GetWindow()->window)
// {
// m_pUser->HandleEvent(pEvent);
// }
// else
// {
// goto cleanup;
// }
// }
// else
// {
// pFocusSite->EventOccurred(pEvent);
// }
// }
// else
{
//Tell our user that the event has occured.
if (m_pUser)
m_pUser->HandleEvent(pEvent);
if( !pEvent->handled )
{
mapchanged1:
int mapCount = m_ChildrenMap.GetCount();
CHXMapPtrToPtr::Iterator i = m_ChildrenMap.Begin();
while( i!= m_ChildrenMap.End() && !pEvent->handled)
{
CHXWinSite* pSite = (CHXWinSite*) *i;
pSite->EventOccurred(pEvent);
//wow. :-(
if (m_ChildrenMap.GetCount() != mapCount)
{
goto mapchanged1;
}
++i;
}
}
}
//We always convert the event to an generic event now.
//If we don't we don't get generic events....
ret = FALSE;
break;
}
}
// cleanup:
return ret;
}
//XXXgfw, remove this if we end up not using it after release.
void CHXWinSite::_SizeSliders()
{
}
/************************************************************************
* Function:
* HXxWinHookSiteProc
*
*/
LRESULT HXEXPORT
HXxWinHookSiteProc
(
HWND hWnd,
UINT message,
WPARAM uParam,
LPARAM lParam
)
{
LRESULT lResult = 0;
CHXWinSite* pThis = 0;
CHXWinSite::zm_SubclassedWnds.Lookup((void*)hWnd,(void*&)pThis);
if (!pThis)
{
HX_ASSERT(0);
return DefWindowProc(hWnd, message, uParam, lParam);
}
if (pThis->HandleWndProc(hWnd,message,uParam,lParam,lResult))
{
return (lResult);
}
return CallWindowProc(pThis->m_oldWndProc, hWnd, message, uParam, lParam);
}
/************************************************************************
* Function:
* HXxWinHookChar
*
*/
//LRESULT HXEXPORT
LRESULT CALLBACK
HXxWinHookChar(int nCode,WPARAM wParam,LPARAM lParam)
{
if (nCode <0 || nCode != HC_NOREMOVE)
{
int isKeyDown = (KF_UP & lParam);
if (!isKeyDown)
{
LRESULT lResult = 0;
CHXWinSite* pThis;
CHXMapPtrToPtr::Iterator i = CHXWinSite::zm_SubclassedWnds.Begin();
for(;i!= CHXWinSite::zm_SubclassedWnds.End(); ++i)
{
pThis = (CHXWinSite*) *i;
if (pThis->IsFullScreen())
{
if (pThis->HandleWndProc((HWND)i.get_key(),WM_CHAR,wParam,lParam,lResult))
{
return (lResult);
}
}
}
}
}
/*
* Sweet Jesus. They do not give us a window handle. Ok. Call GetCurrentThreadId.
*/
DWORD id = GetCurrentThreadId();
CParentWindowThreadData* pData = NULL;
if (CHXWinSite::zm_ParentsThreadList.Lookup((void*)id, (void*&) pData))
{
return CallNextHookEx(pData->m_hHook,nCode,wParam,lParam);
}
/*
* If we get here we are in some SERIOUS hurt.
*/
HX_ASSERT(NO_HOOK_FOUND_RETURNING_WITH_ZERO);
return 0;
}
/************************************************************************
* Function:
* WinDrawHelperCallWndProc
*/
LRESULT HXEXPORT
HXxWinHookAllMessages
(
int nCode,
WPARAM wParam,
LPARAM lParam
)
{
CWPSTRUCT* pCWPStruct = (CWPSTRUCT*)lParam;
HWND hWnd = pCWPStruct->hwnd;
UINT message = pCWPStruct->message;
/*
* We watch for movement of the topmost parent of any of our
* windraw objects, and if so then we tell windraw to update
* the frame for those windraw objects. Outter check is for
* the message in question so that we don't waste too much time.
*/
const UINT msgMoving = WM_MOVING;
const UINT msgPosChanging = WM_WINDOWPOSCHANGING;
/*
* If I see any reason to use these other messages in the future
* message == WM_MOVING || message == WM_WINDOWPOSCHANGING
*/
if (message == WM_MOVE)
{
CHXSimpleList* pChildrenList;
if (CHXWinSite::zm_ParentWnds.Lookup((void*)hWnd,(void*&)pChildrenList))
{
CHXSimpleList::Iterator i = pChildrenList->Begin();
for(; i!= pChildrenList->End(); ++i)
{
CHXWinSite* pSite = (CHXWinSite*) *i;
pSite->HandleParentMessages(pCWPStruct->hwnd,pCWPStruct->message,pCWPStruct->wParam,pCWPStruct->lParam);
}
}
else
{
//Try to detect reparenting.
HWND hTmpWnd;
BOOL areWeDone = FALSE;
POSITION pos = CHXWinSite::zm_ParentWnds.GetStartPosition();
while(pos && !areWeDone)
{
CHXWinSite::zm_ParentWnds.GetNextAssoc(pos, (void*&) hTmpWnd, (void*&) pChildrenList);
//hTmpWnd = ::GetParent(hTmpWnd);
while( hTmpWnd && !areWeDone )
{
if( hTmpWnd == hWnd )
{
//reparent and leave
LISTPOSITION listpos = pChildrenList->GetHeadPosition();
CHXWinSite* pSite = (CHXWinSite*)pChildrenList->GetAt(listpos);
if( pSite && pSite->m_pTopLevelSite )
((CHXWinSite*)pSite->m_pTopLevelSite)->ReHookParents();
areWeDone = TRUE;
}
hTmpWnd = ::GetParent(hTmpWnd);
}
}
}
}
if (message == WM_DISPLAYCHANGE)
{
CHXSimpleList* pChildrenList;
if (CHXWinSite::zm_ParentWnds.Lookup((void*)hWnd,(void*&)pChildrenList))
{
CHXSimpleList::Iterator i = pChildrenList->Begin();
for(; i!= pChildrenList->End(); ++i)
{
CHXWinSite* pSite = (CHXWinSite*) *i;
pSite->CheckDisplayMode(NULL);
}
}
}
/*
* Sweet Jesus, they did not give us a window handle in the keyboard hook. So we might as
* well use the same messed up method here. Call GetCurrentThreadId. I hope to heck this
* works out.
*/
DWORD id = GetCurrentThreadId();
CParentWindowThreadData* pData = NULL;
if (CHXWinSite::zm_ParentsThreadList.Lookup((void*)id, (void*&) pData))
{
return CallNextHookEx(pData->m_hHookAllMessage,nCode,wParam,lParam);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -