📄 cbmouse.cpp
字号:
RECT MOUSE_LeftUp( int nPosX, int nPosY )
{
// clear the flag
if( MOUSE_bLeftDown )
{
MOUSE_bLeftDown = FALSE;
// set mouse cursor with old range
class CDDCursor *pCursor;
pCursor = CURSOR_Get();
Assert( pCursor != NULL );
Assert( rcOldRange.left == 0 && rcOldRange.top == 0 );
if( rcOldRange.left != 0 )
{
rcOldRange.left = rcOldRange.top = 0;
rcOldRange.right = GetSystemMetrics( SM_CXSCREEN );
rcOldRange.bottom = GetSystemMetrics( SM_CYSCREEN );
}
pCursor->SetRange( &rcOldRange );
}
else
{
SetRectEmpty( &MOUSE_rcDrag );
}
// change cursor state
MOUSE_testState( nPosX, nPosY );
return MOUSE_rcDrag;
}
// if mouse is moving with left button holds down, do dragging process
// nPosX, nPosY : mouse cursor position
void MOUSE_IsLeftDown( int nPosX, int nPosY )
{
// change cursor state
MOUSE_testState( nPosX, nPosY );
if( !MOUSE_bLeftDown )
{
return;
}
// 鼠标左键按下了
// if semaphore is not light, ignore this function
if( MOUSE_bSemaphore == FALSE ) return;
MOUSE_bSemaphore = FALSE;
// save old dragging rectangle
SetRect( &MOUSE_rcDragLast,
MOUSE_rcDrag.left, MOUSE_rcDrag.top,
MOUSE_rcDrag.right, MOUSE_rcDrag.bottom );
// set value to MOUSE_rcDrag
if( nPosX < MOUSE_ptFirst.x )
{
MOUSE_rcDrag.left = nPosX;
MOUSE_rcDrag.right = MOUSE_ptFirst.x;
}
else
{
MOUSE_rcDrag.left = MOUSE_ptFirst.x;
MOUSE_rcDrag.right = nPosX;
}
if( nPosY < MOUSE_ptFirst.y )
{
MOUSE_rcDrag.top = nPosY;
MOUSE_rcDrag.bottom = MOUSE_ptFirst.y;
}
else
{
MOUSE_rcDrag.top = MOUSE_ptFirst.y;
MOUSE_rcDrag.bottom = nPosY;
}
}
// display dragging rectangle to back buffer
void MOUSE_DrawDragRect()
{
if( !MOUSE_bLeftDown ) return;
// set synchronization flag
MOUSE_bSemaphore = TRUE;
// draw rectangle
DDC_FrameRect( &MOUSE_rcDrag, RGB(0,255,0), FALSE );
}
// update dragging rectangle to front buffer
void MOUSE_UpdateDrag()
{
if( !MOUSE_bLeftDownLast ) return;
MOUSE_bLeftDownLast = MOUSE_bLeftDown;
RECT rcUpdate;
// update old dragging rectangle
// update left border
SetRect( &rcUpdate,
MOUSE_rcDragLast.left, MOUSE_rcDragLast.top,
MOUSE_rcDragLast.left+1, MOUSE_rcDragLast.bottom+1 );
DDC_UpdateScreen( &rcUpdate );
// update top border
SetRect( &rcUpdate,
MOUSE_rcDragLast.left, MOUSE_rcDragLast.top,
MOUSE_rcDragLast.right+1, MOUSE_rcDragLast.top+1 );
DDC_UpdateScreen( &rcUpdate );
// update right border
SetRect( &rcUpdate,
MOUSE_rcDragLast.right-1, MOUSE_rcDragLast.top-1,
MOUSE_rcDragLast.right, MOUSE_rcDragLast.bottom );
DDC_UpdateScreen( &rcUpdate );
// update bottom border
SetRect( &rcUpdate,
MOUSE_rcDragLast.left-1, MOUSE_rcDragLast.bottom-1,
MOUSE_rcDragLast.right, MOUSE_rcDragLast.bottom );
DDC_UpdateScreen( &rcUpdate );
// udpate new dragging rectangle
// update left border
SetRect( &rcUpdate,
MOUSE_rcDrag.left, MOUSE_rcDrag.top,
MOUSE_rcDrag.left+1, MOUSE_rcDrag.bottom+1 );
DDC_UpdateScreen( &rcUpdate );
// update top border
SetRect( &rcUpdate,
MOUSE_rcDrag.left, MOUSE_rcDrag.top,
MOUSE_rcDrag.right+1, MOUSE_rcDrag.top+1 );
DDC_UpdateScreen( &rcUpdate );
// update right border
SetRect( &rcUpdate,
MOUSE_rcDrag.right-1, MOUSE_rcDrag.top-1,
MOUSE_rcDrag.right, MOUSE_rcDrag.bottom );
DDC_UpdateScreen( &rcUpdate );
// update bottom border
SetRect( &rcUpdate,
MOUSE_rcDrag.left-1, MOUSE_rcDrag.bottom-1,
MOUSE_rcDrag.right, MOUSE_rcDrag.bottom );
DDC_UpdateScreen( &rcUpdate );
}
/////////////////////
/////////////////////
// test if mouse hit in the minimap
// nPosX,nPosY : mouse hit position from screen, in grid
// return : the relative position to whole battlefield map that mouse hit,
// in grid
POINT MOUSE_InMiniMap( int nPosX, int nPosY )
{
POINT ptRet = {-1,-1};
// test if minimap loaded
if( MINI_Lib.nType == -1 ) return ptRet;
POINT ptHit;
ptHit.x = nPosX, ptHit.y = nPosY;
if( PtInRect( &MINI_Lib.rcMap[MINI_Lib.nType], ptHit ) )
{
ptRet.x = ptHit.x - MINI_Lib.rcMap[MINI_Lib.nType].left;
ptRet.y = (ptHit.y - MINI_Lib.rcMap[MINI_Lib.nType].top)<<2;
}
return ptRet;
}
/////////////////////
/////////////////////
// change grid position to point position
// ptPos: grid position
POINT MOUSE_Grid2Point( int nLayer, POINT ptPosG )
{
int top, left;
POINT ptPos;
top = (ptPosG.y*MAP_Lib.szItem.cy>>1);
top -= MAP_Lib.nHeight[nLayer+1];
if( (ptPosG.y&1) == 0 )
{
left = ptPosG.x*MAP_Lib.szItem.cx;
}
else
{
left = ptPosG.x*MAP_Lib.szItem.cx+(MAP_Lib.szItem.cx>>1);
}
// left = left - DRAW_ptScreenOffset.x;
// top = top - DRAW_ptScreenOffset.y;
left = left - DRAW_ptScreenOffset.x+(MAP_Lib.szItem.cx>>1);
top = top - DRAW_ptScreenOffset.y+(MAP_Lib.szItem.cy>>1);
ptPos.x = left, ptPos.y = top;
return ptPos;
}
// nState : new state
// bForce : TRUE if set the state exactly you give
void MOUSE_SetState( int nState, BOOL bForce /*=FALSE*/ )
{
// get cursor pointer
class CDDCursor *pCursor;
pCursor = CURSOR_Get();
Assert( pCursor );
MOUSE_nState = nState;
pCursor->SetState( nState );
if( bForce == TRUE )
{
if( GAME.nProgramState != PROGRAM_STATE_PLAY )
{
MOUSE_LeftUp( 0, 0 );
}
}
else
{
POINT ptPos = pCursor->GetPos();
MOUSE_testState( ptPos.x, ptPos.y );
}
}
void MOUSE_testState( int nPosX, int nPosY )
{
BOOL bReset = FALSE;
int nState;
class CDDCursor *pCursor;
if( !MOUSE_bEnableTest ) return;
// get cursor pointer
pCursor = CURSOR_Get();
Assert( pCursor );
nState = pCursor->GetState();
// 判断鼠标是否在客户区以内
if( DRAW_rcClient.left > nPosX
|| DRAW_rcClient.top > nPosY
|| DRAW_rcClient.right < nPosX
|| DRAW_rcClient.bottom < nPosY )
{ // 如果鼠标在客户区以外,临时设置其为NONE
if( nState!= MOUSE_STATE_NONE )
{
nState = MOUSE_STATE_NONE;
bReset = TRUE;
}
}
else
{
// 判断鼠标左键是否按下
if( !MOUSE_bLeftDown )
{ // 鼠标左键没有按下,根据鼠标的位置和状态改变其状态
// 如果鼠标曾经是按下的状态,恢复为原始状态
if( nState == MOUSE_STATE_DOWN )
{
nState = MOUSE_STATE_NONE;
bReset = TRUE;
}
// 如果鼠标刚刚进入客户区,恢复为原始状态
else if( nState == MOUSE_STATE_NONE
&& MOUSE_nState != nState )
{
nState = MOUSE_nState;
bReset = TRUE;
}
// 如果鼠标进入某个单元的选中范围,则变为相应状态
BOOL bFind = FALSE;
POINT pt;
struct MOUSE_HITRESULT_STRUCT hitResult;
pt.x = nPosX, pt.y = nPosY;
if( MOUSE_HitTestU( pt, &hitResult ) )
{ // 检测到单元
switch( MOUSE_nState )
{
case MOUSE_STATE_NONE: // 无命令时
// 目的地是单元
if( nState != MOUSE_STATE_EYE )
{
nState = MOUSE_STATE_EYE;
bReset = TRUE;
}
bFind = TRUE;
break;
case MOUSE_STATE_GONGJI: // 选中攻击命令后
{ // 目的地是敌方或我方的单元
struct UNIT_STRUCT *pUnit = MAP_GetUnit( hitResult.wCode );
Assert( pUnit );
if( nState == MOUSE_STATE_GONGJI )
{
if( EYE_PlayerIsAllied( GAME.nMe, pUnit->Draw.nPlayer ) )
nState = MOUSE_STATE_GONGJI_END1;
else
nState = MOUSE_STATE_GONGJI_END2;
bReset = TRUE;
}
bFind = TRUE;
}
break;
case MOUSE_STATE_YUNSONG: // 选中运送命令后
// 目的地是建筑类型的资源
{
struct UNIT_STRUCT *pUnit = MAP_GetUnit( hitResult.wCode );
Assert( pUnit );
//if( EYE_IfUnitIsRes( pUnit ) )
if( EYE_GetUResType( pUnit ) != QXZIYUAN )
{
if( nState == MOUSE_STATE_YUNSONG )
{
nState = MOUSE_STATE_YUNSONG_END;
bReset = TRUE;
}
bFind = TRUE;
}
}
break;
case MOUSE_STATE_JIARU: // 选中加入命令后
{ // 目的地是将领
struct UNIT_STRUCT *pUnit = MAP_GetUnit( hitResult.wCode );
Assert( pUnit );
if( EYE_IfSheIsMine( pUnit ) )
{
pUnit = EYE_GetGeneral( pUnit );
if( pUnit != NULL )
{
if( nState == MOUSE_STATE_JIARU )
{
nState = MOUSE_STATE_JIARU_END;
bReset = TRUE;
}
bFind = TRUE;
}
}
}
break;
}
}// End of if( MOUSE_HitTestU( pt, &hitResult ) )
else if( MOUSE_nState == MOUSE_STATE_YUNSONG )
{ // 未检测到单元
// 仅用于检测地形类型的资源
pt.y += 15;
if( MOUSE_HitTestG( pt, &hitResult )
&& EYE_GetGResType( hitResult.nLayer, hitResult.ptHit.x, hitResult.ptHit.y )
!= QXZIYUAN )
{ // 检测到地形类型的资源
if( nState == MOUSE_STATE_YUNSONG )
{
nState = MOUSE_STATE_YUNSONG_END;
bReset = TRUE;
}
bFind = TRUE;
}
}// End of else if( MOUSE_nState == MOUSE_STATE_YUNSONG )
// 是否恢复搜索状态
if( bFind == FALSE
&& nState != MOUSE_nState )
{ // 未检测到单元
nState = MOUSE_nState;
bReset = TRUE;
}// End of if( bFind == FALSE && nState != MOUSE_nState )
}// End of if( !MOUSE_bLeftDown )
else
{ // 左键按下了
if( nState != MOUSE_STATE_DOWN )
{
nState = MOUSE_STATE_DOWN;
bReset = TRUE;
}
}// End of else if( !MOUSE_bLeftDown )
}
// reset cursor state
if( bReset )
pCursor->SetState( nState );
}
void MOUSE_EnableTest( BOOL bEnable/*=TRUE*/ )
{
MOUSE_bEnableTest = bEnable;
}
/////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -