📄 cpi_interface.c
字号:
BOOL bSizeChanged;
rNewPos.left = pWP->x;
rNewPos.right = pWP->x + pWP->cx;
rNewPos.top = pWP->y;
rNewPos.bottom = pWP->y + pWP->cy;
bSizeChanged = (pWP->flags & SWP_NOSIZE) ? FALSE : TRUE;
pState->m_ptWindowPos.x = pWP->x;
pState->m_ptWindowPos.y = pWP->y;
pState->m_szWindowSize.cx = pWP->cx;
pState->m_szWindowSize.cy = pWP->cy;
if(bSizeChanged)
{
IF_UpdateSubPartLayout(pState);
IF_RebuildRegion(pState);
}
// Perform callback
if(pState->m_hndlr_onPosChange)
pState->m_hndlr_onPosChange(pState, &rNewPos, bSizeChanged);
}
return 0;
case WM_NCCALCSIZE:
// We do not wish to have any window area lost to captions etc (also prevent the system
// from preserving our window contents during a resize
return WVR_REDRAW;
case WM_NCACTIVATE:
return TRUE;
case WM_NCPAINT:
return 0;
case WM_NCMOUSEMOVE:
IF_SetFloatActiveSubPart(pState, NULL);
return 0;
case WM_MOUSELEAVE:
IF_SetFloatActiveSubPart(pState, NULL);
pState->m_bMouseLeaveEventSet = FALSE;
return 0;
case WM_CLOSE:
if(pState->m_hndlr_onClose)
{
pState->m_hndlr_onClose(pState);
return 0;
}
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
CPs_DrawContext drawcontext;
// Prepare for draw
drawcontext.m_dcDraw = BeginPaint(hWnd, &ps);
drawcontext.m_ptOffset.x = 0;
drawcontext.m_ptOffset.y = 0;
GetClipBox(drawcontext.m_dcDraw, &drawcontext.m_rClip);
IF_PaintWindow(pState, &drawcontext);
// Cleanup
EndPaint(hWnd, &ps);
}
return 0;
case WM_ACTIVATE:
if(LOWORD(wParam) == WA_ACTIVE)
SetFocus(hWnd);
return 0;
case WM_SYSKEYDOWN:
case WM_KEYDOWN:
if(pState->m_hndlr_onKeyDown)
{
const BOOL bAltIsDown = (GetAsyncKeyState(VK_MENU) & 0x8000) ? TRUE : FALSE;
const BOOL bCtrlIsDown = (GetAsyncKeyState(VK_CONTROL) & 0x8000) ? TRUE : FALSE;
const BOOL bShiftIsDown = (GetAsyncKeyState(VK_SHIFT) & 0x8000) ? TRUE : FALSE;
pState->m_hndlr_onKeyDown(pState, (unsigned int)wParam, bAltIsDown, bCtrlIsDown, bShiftIsDown);
}
return 0;
case WM_DROPFILES:
if(pState->m_hndlr_onDropFiles)
pState->m_hndlr_onDropFiles(pState, (HDROP)wParam);
return 0;
case WM_GETMINMAXINFO:
{
MINMAXINFO* pMinMaxInfo = (MINMAXINFO*)lParam;
RECT rWorkArea;
if(pfnGetMonitorInfo)
{
// Multimonitors are supported by this OS
MONITORINFO mi;
HMONITOR hmon = pfnMonitorFromWindow(pState->m_hWnd, MONITOR_DEFAULTTOPRIMARY);
mi.cbSize = sizeof(mi);
pfnGetMonitorInfo(hmon, &mi);
// Get the work area of this monitor - as an offset from this monitors virtual space
rWorkArea.left = mi.rcWork.left - mi.rcMonitor.left;
rWorkArea.right = mi.rcWork.right - mi.rcMonitor.left;
rWorkArea.top = mi.rcWork.top - mi.rcMonitor.top;
rWorkArea.bottom = mi.rcWork.bottom - mi.rcMonitor.top;
}
else
{
// Single monitor only OS
SystemParametersInfo(SPI_GETWORKAREA, 0, &rWorkArea, 0);
}
pMinMaxInfo->ptMinTrackSize.x = pState->m_szMinSize.cx;
pMinMaxInfo->ptMinTrackSize.y = pState->m_szMinSize.cy;
pMinMaxInfo->ptMaxPosition.x = rWorkArea.left;
pMinMaxInfo->ptMaxPosition.y = rWorkArea.top;
pMinMaxInfo->ptMaxSize.x = rWorkArea.right-rWorkArea.left;
pMinMaxInfo->ptMaxSize.y = rWorkArea.bottom-rWorkArea.top;
pMinMaxInfo->ptMaxTrackSize.x = pMinMaxInfo->ptMaxSize.x;
pMinMaxInfo->ptMaxTrackSize.y = pMinMaxInfo->ptMaxSize.y;
}
return 0;
case WM_SETFOCUS:
if(pState->m_hndlr_onFocus)
pState->m_hndlr_onFocus(pState, TRUE);
return 0;
case WM_KILLFOCUS:
if(pState->m_hndlr_onFocus)
pState->m_hndlr_onFocus(pState, FALSE);
return 0;
case WM_COMMAND:
if(pState->m_hndlr_onCommandMessage)
pState->m_hndlr_onCommandMessage(pState, wParam, lParam);
return 0;
}
// Route message (to windows if it isn't handled)
if(uiMessage >= WM_APP && pState->m_hndlr_onAppMessage)
return pState->m_hndlr_onAppMessage(pState, uiMessage, wParam, lParam);
return DefWindowProc(hWnd, uiMessage, wParam, lParam);
}
//
//
//
void IF_RebuildRegion(CP_HINTERFACE hInterface)
{
CPs_InterfaceWindowState* pState;
HBITMAP bmOld;
HBITMAP bmSurface;
HDC dcDraw;
RECT rClient;
HDC dcScreen;
HRGN rgnWindow;
// Init
pState = (CPs_InterfaceWindowState*)hInterface;
CP_CHECKOBJECT(pState);
// There was no region last time - don't bother looking for one now
if(pState->m_bSkipRegion)
return;
// Create an offscreen
GetClientRect(pState->m_hWnd, &rClient);
bmSurface = CreateBitmap(rClient.right, rClient.bottom, 1, 1, NULL);
dcScreen = GetDC(pState->m_hWnd);
dcDraw = CreateCompatibleDC(dcScreen);
bmOld = (HBITMAP)SelectObject(dcDraw, bmSurface);
ReleaseDC(pState->m_hWnd, dcScreen);
// Draw the window
{
CPs_DrawContext drawcontext;
drawcontext.m_dcDraw = dcDraw;
drawcontext.m_ptOffset.x = 0;
drawcontext.m_ptOffset.y = 0;
drawcontext.m_rClip = rClient;
IF_PaintWindow(pState, &drawcontext);
}
// Cleanup
SelectObject(dcDraw, bmOld);
DeleteDC(dcDraw);
// Setup region
rgnWindow = main_bitmap_to_region_1bit(bmSurface, glb_pSkin->m_clrTransparent);
DeleteObject(bmSurface);
SetWindowRgn( pState->m_hWnd,
rgnWindow,
TRUE);
if(!rgnWindow)
pState->m_bSkipRegion = TRUE;
}
//
//
//
void IF_PaintWindow(CPs_InterfaceWindowState* pState, CPs_DrawContext* pContext)
{
// Walk through list drawing and adding to the valid rects list
CPs_InterfacePart* pSubPart_Cursor;
for(pSubPart_Cursor = pState->m_pFirstSubPart; pSubPart_Cursor; pSubPart_Cursor = (CPs_InterfacePart*)pSubPart_Cursor->m_hNext)
{
if(pSubPart_Cursor->Draw)
{
pSubPart_Cursor->Draw(pSubPart_Cursor, pContext);
ExcludeClipRect(pContext->m_dcDraw,
pSubPart_Cursor->m_rLocation.left, pSubPart_Cursor->m_rLocation.top,
pSubPart_Cursor->m_rLocation.right, pSubPart_Cursor->m_rLocation.bottom);
}
}
// Perform callback
if(pState->m_hndlr_onDraw)
pState->m_hndlr_onDraw(pState, pContext);
}
//
//
//
void IF_SetMinSize(CP_HINTERFACE hInterface, const SIZE* pMinSize)
{
CPs_InterfaceWindowState* pState;
// Init
pState = (CPs_InterfaceWindowState*)hInterface;
CP_CHECKOBJECT(pState);
pState->m_szMinSize = *pMinSize;
}
//
//
//
void IF_PostAppMessage(CP_HINTERFACE hInterface, const UINT uiMessage, const WPARAM wParam, const LPARAM lParam)
{
CPs_InterfaceWindowState* pState;
// Init
pState = (CPs_InterfaceWindowState*)hInterface;
CP_CHECKOBJECT(pState);
CP_ASSERT(uiMessage >= WM_APP);
PostMessage(pState->m_hWnd, uiMessage, wParam, lParam);
}
//
//
//
void IF_SetMouseCapture(CP_HINTERFACE hInterface, wp_IF_onMouseMessage pfn_onMouseMove, wp_IF_onMouseMessage pfn_onMouseButton_LUp)
{
CPs_InterfaceWindowState* pState;
// Init
pState = (CPs_InterfaceWindowState*)hInterface;
CP_CHECKOBJECT(pState);
pState->m_bMouseCaptured = TRUE;
pState->m_hndlr_onMouseMove = pfn_onMouseMove;
pState->m_hndlr_onMouseButton_LUp = pfn_onMouseButton_LUp;
SetCapture(pState->m_hWnd);
}
//
//
//
void IF_ReleaseMouseCapture(CP_HINTERFACE hInterface)
{
CPs_InterfaceWindowState* pState;
// Init
pState = (CPs_InterfaceWindowState*)hInterface;
CP_CHECKOBJECT(pState);
pState->m_bMouseCaptured = FALSE;
ReleaseCapture();
}
//
//
//
void IF_RemoveAllSubparts(CP_HINTERFACE hInterface)
{
CPs_InterfaceWindowState* pState;
CPs_InterfacePart* pSubPart_Cursor;
CPs_InterfacePart* pSubPart_Next;
// Init
pState = (CPs_InterfaceWindowState*)hInterface;
CP_CHECKOBJECT(pState);
// Walk through list destroying subparts
for(pSubPart_Cursor = pState->m_pFirstSubPart; pSubPart_Cursor; pSubPart_Cursor = pSubPart_Next)
{
pSubPart_Next = (CPs_InterfacePart*)pSubPart_Cursor->m_hNext;
IP_Destroy(pSubPart_Cursor);
}
pState->m_pFirstSubPart = NULL;
}
//
//
//
void IF_AddSubPart_CommandButton( CP_HINTERFACE hInterface,
const DWORD dwAlign,
const POINT* pptOffset,
CPs_Image_WithState* pStateImage,
wp_Verb pfnVerb)
{
CPs_InterfaceWindowState* pState;
CPs_InterfacePart* pSubPart_Next;
// Init
pState = (CPs_InterfaceWindowState*)hInterface;
CP_CHECKOBJECT(pState);
// Add new head to list
pSubPart_Next = pState->m_pFirstSubPart;
// Setup new part
pState->m_pFirstSubPart = IP_Create_CommandButton(pfnVerb, pStateImage);
pState->m_pFirstSubPart->m_hNext = pSubPart_Next;
pState->m_pFirstSubPart->m_hOwner = hInterface;
pState->m_pFirstSubPart->m_dwAlign = dwAlign;
pState->m_pFirstSubPart->m_bRectAlignMode = FALSE;
pState->m_pFirstSubPart->m_ptOffset = *pptOffset;
pState->m_pFirstSubPart->m_szSize.cx = pStateImage->m_pImage->m_szSize.cx;
pState->m_pFirstSubPart->m_szSize.cy = pStateImage->m_iStateHeight;
}
//
//
//
void IF_AddSubPart_Indicator( CP_HINTERFACE hInterface,
const char* pcName,
const DWORD dwAlign,
const RECT* prPosition)
{
CPs_InterfaceWindowState* pState;
CPs_InterfacePart* pSubPart_Next;
// Init
pState = (CPs_InterfaceWindowState*)hInterface;
CP_CHECKOBJECT(pState);
// Add new head to list
pSubPart_Next = pState->m_pFirstSubPart;
// Setup new part
pState->m_pFirstSubPart = IP_Create_Indicator(pcName);
pState->m_pFirstSubPart->m_hNext = pSubPart_Next;
pState->m_pFirstSubPart->m_hOwner = hInterface;
pState->m_pFirstSubPart->m_dwAlign = dwAlign;
pState->m_pFirstSubPart->m_bRectAlignMode = TRUE;
pState->m_pFirstSubPart->m_rPosition = *prPosition;
}
//
//
//
void IF_UpdateSubPartLayout(CP_HINTERFACE hInterface)
{
CPs_InterfaceWindowState* pState;
CPs_InterfacePart* pSubPart_Cursor;
// Init
pState = (CPs_InterfaceWindowState*)hInterface;
CP_CHECKOBJECT(pState);
// Walk through list setting position
for(pSubPart_Cursor = pState->m_pFirstSubPart; pSubPart_Cursor; pSubPart_Cursor = (CPs_InterfacePart*)pSubPart_Cursor->m_hNext)
{
if(pSubPart_Cursor->m_bRectAlignMode == TRUE)
{
// Set position
// - left
if(pSubPart_Cursor->m_dwAlign & CPC_COMMANDTARGET_ALIGN_LEFT)
pSubPart_Cursor->m_rLocation.left = pSubPart_Cursor->m_rPosition.left;
else
{
CP_ASSERT(pSubPart_Cursor->m_dwAlign & CPC_COMMANDTARGET_ALIGN_RIGHT);
pSubPart_Cursor->m_rLocation.left = pState->m_szWindowSize.cx - pSubPart_Cursor->m_rPosition.right - pSubPart_Cursor->m_rPosition.left;
}
// - right
if(pSubPart_Cursor->m_dwAlign & CPC_COMMANDTARGET_ALIGN_RIGHT)
pSubPart_Cursor->m_rLocation.right = pState->m_szWindowSize.cx - pSubPart_Cursor->m_rPosition.right;
else
{
CP_ASSERT(pSubPart_Cursor->m_dwAlign & CPC_COMMANDTARGET_ALIGN_LEFT);
pSubPart_Cursor->m_rLocation.right = pSubPart_Cursor->m_rLocation.left + pSubPart_Cursor->m_rPosition.right;
}
// - top
if(pSubPart_Cursor->m_dwAlign & CPC_COMMANDTARGET_ALIGN_TOP)
pSubPart_Cursor->m_rLocation.top = pSubPart_Cursor->m_rPosition.top;
else
{
CP_ASSERT(pSubPart_Cursor->m_dwAlign & CPC_COMMANDTARGET_ALIGN_BOTTOM);
pSubPart_Cursor->m_rLocation.top = pState->m_szWindowSize.cy - pSubPart_Cursor->m_rPosition.bottom - pSubPart_Cursor->m_rPosition.top;
}
// - bottom
if(pSubPart_Cursor->m_dwAlign & CPC_COMMANDTARGET_ALIGN_BOTTOM)
pSubPart_Cursor->m_rLocation.bottom = pState->m_szWindowSize.cy - pSubPart_Cursor->m_rPosition.bottom;
else
{
CP_ASSERT(pSubPart_Cursor->m_dwAlign & CPC_COMMANDTARGET_ALIGN_TOP);
pSubPart_Cursor->m_rLocation.bottom = pSubPart_Cursor->m_rLocation.top + pSubPart_Cursor->m_rPosition.bottom;
}
}
else
{
// Set position
if(pSubPart_Cursor->m_dwAlign & CPC_COMMANDTARGET_ALIGN_LEFT)
pSubPart_Cursor->m_rLocation.left = pSubPart_Cursor->m_ptOffset.x;
else
{
CP_ASSERT(pSubPart_Cursor->m_dwAlign & CPC_COMMANDTARGET_ALIGN_RIGHT);
pSubPart_Cursor->m_rLocation.left = pState->m_szWindowSize.cx - pSubPart_Cursor->m_szSize.cx - pSubPart_Cursor->m_ptOffset.x;
}
pSubPart_Cursor->m_rLocation.right = pSubPart_Cursor->m_rLocation.left + pSubPart_Cursor->m_szSize.cx;
if(pSubPart_Cursor->m_dwAlign & CPC_COMMANDTARGET_ALIGN_TOP)
pSubPart_Cursor->m_rLocation.top = pSubPart_Cursor->m_ptOffset.y;
else
{
CP_ASSERT(pSubPart_Cursor->m_dwAlign & CPC_COMMANDTARGET_ALIGN_BOTTOM);
pSubPart_Cursor->m_rLocation.top = pState->m_szWindowSize.cy - pSubPart_Cursor->m_szSize.cy - pSubPart_Cursor->m_ptOffset.y;
}
pSubPart_Cursor->m_rLocation.bottom = pSubPart_Cursor->m_rLocation.top + pSubPart_Cursor->m_szSize.cy;
}
}
}
//
//
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -