📄 xskinbutton.cpp
字号:
RGNDATAHEADER* pRgnData = (RGNDATAHEADER*)new BYTE[ RDHDR + ++cBlocks * MAXBUF * sizeof(RECT) ];
memset( pRgnData, 0, RDHDR + cBlocks * MAXBUF * sizeof(RECT) );
// fill it by default
pRgnData->dwSize = RDHDR;
pRgnData->iType = RDH_RECTANGLES;
pRgnData->nCount = 0;
for (i = 0; i < bm.bmHeight; i++)
{
for (j = 0; j < bm.bmWidth; j++)
{
// get color
ismask = (dcBmp.GetPixel(j,bm.bmHeight-i-1) != color);
// place part of scan line as RECT region if transparent color found after mask color or
// mask color found at the end of mask image
if (wasfirst && ((ismask && (j==(bm.bmWidth-1)))||(ismask ^ (j<bm.bmWidth))))
{
// get offset to RECT array if RGNDATA buffer
pRects = (LPRECT)((LPBYTE)pRgnData + RDHDR);
// save current RECT
pRects[ pRgnData->nCount++ ] = CRect( first, bm.bmHeight - i - 1, j+(j==(bm.bmWidth-1)), bm.bmHeight - i );
// if buffer full reallocate it
if ( pRgnData->nCount >= cBlocks * MAXBUF )
{
LPBYTE pRgnDataNew = new BYTE[ RDHDR + ++cBlocks * MAXBUF * sizeof(RECT) ];
memcpy( pRgnDataNew, pRgnData, RDHDR + (cBlocks - 1) * MAXBUF * sizeof(RECT) );
delete pRgnData;
pRgnData = (RGNDATAHEADER*)pRgnDataNew;
}
wasfirst = FALSE;
}
else if (!wasfirst && ismask )
{
// set wasfirst when mask is found
first = j;
wasfirst = true;
}
}
}
dcBmp.DeleteDC(); //release the bitmap
// create region
/* Under WinNT the ExtCreateRegion returns NULL (by Fable@aramszu.net) */
// HRGN hRgn = ExtCreateRegion( NULL, RDHDR + pRgnData->nCount * sizeof(RECT), (LPRGNDATA)pRgnData );
/* ExtCreateRegion replacement { */
HRGN hRgn=CreateRectRgn(0, 0, 0, 0);
ASSERT( hRgn!=NULL );
pRects = (LPRECT)((LPBYTE)pRgnData + RDHDR);
for(i=0;i<(int)pRgnData->nCount;i++)
{
HRGN hr=CreateRectRgn(pRects[i].left, pRects[i].top, pRects[i].right, pRects[i].bottom);
VERIFY(CombineRgn(hRgn, hRgn, hr, RGN_OR)!=ERROR);
if (hr) DeleteObject(hr);
}
ASSERT( hRgn!=NULL );
/* } ExtCreateRegion replacement */
delete pRgnData;
return hRgn;
}
/////////////////////////////////////////////////////////////////////////////
COLORREF CxSkinButton::SetTextColor(COLORREF newColor)
{
COLORREF tmp_color=m_clrText;
m_clrText = newColor;
return tmp_color; //returns the previous color
}
/////////////////////////////////////////////////////////////////////////////
//
//Method......: OnLButtonDblClk
//Class.......: CxSkinButton
//
//Author......: Milan Gardian
//Created.....: MAR-2001
//
//Return value: NONE
//Parameters..: Used only to be forwarded as WM_LBUTTONDOWN message parameters
//Exceptions..: NONE
//------------
//Description :
//
// > We do not care about doublelicks - handle this event
// like an ordinary left-button-down event
//
//---------------------------------------------------------
void CxSkinButton::OnLButtonDblClk(UINT flags, CPoint point)
{
SendMessage(WM_LBUTTONDOWN, flags, MAKELPARAM(point.x, point.y));
}
/////////////////////////////////////////////////////////////////////////////
//
//Method......: OnLButtonDown
//Class.......: CxSkinButton
//
//Author......: Milan Gardian
//Created.....: MAR-2001
//
//Return value: NONE
//Parameters..: As follows
// > [in] nFlags: not used
// > [in] point: coordinates of the mouse pointer when this event was spawned
//Exceptions..: NONE
//------------
//Description :
//
// > Handle event when left button is pressed down
//
//---------------------------------------------------------
void CxSkinButton::OnLButtonDown(UINT nFlags, CPoint point)
{
//Default-process the message
CButton::OnLButtonDown(nFlags, point);
m_bButtonDown = true;
}
/////////////////////////////////////////////////////////////////////////////
//
//Method......: OnLButtonUp
//Class.......: CxSkinButton
//
//Author......: Milan Gardian
//Created.....: MAR-2001
//
//Return value: NONE
//Parameters..: As follows
// > [in] nFlags: not used
// > [in] point: coordinates of the mouse pointer when this event was spawned
//Exceptions..: NONE
//------------
//Description :
//
// > Handle event when left button is released (goes up)
//
//---------------------------------------------------------
void CxSkinButton::OnLButtonUp(UINT nFlags, CPoint point)
{
if (m_nStyle)
{
// track mouse for radio & check buttons
POINT p2 = point;
::ClientToScreen(m_hWnd, &p2);
HWND mouse_wnd = ::WindowFromPoint(p2);
if (mouse_wnd == m_hWnd)
{
// mouse is in button
if (m_nStyle==BS_CHECKBOX) SetCheck(m_bChecked ? 0 : 1);
if (m_nStyle==BS_RADIOBUTTON) SetCheck(1);
}
}
//Default-process the message
m_bButtonDown = FALSE;
CButton::OnLButtonUp(nFlags, point);
}
/////////////////////////////////////////////////////////////////////////////
//
//Method......: OnMouseMove
//Class.......: CxSkinButton
//
//Author......: Milan Gardian
//Created.....: MAR-2001
//
//Return value: NONE
//Parameters..: As follows
// > [in] nFlags: not used
// > [in] point: coordinates of the mouse pointer when this event was spawned
//Exceptions..: NONE
//------------
//Description :
//
// > Handle change of mouse position: see the comments in the
// method for further info.
//
//---------------------------------------------------------
void CxSkinButton::OnMouseMove(UINT nFlags, CPoint point)
{
//If we are in capture mode, button has been pressed down
//recently and not yet released - therefore check is we are
//actually over the button or somewhere else. If the mouse
//position changed considerably (e.g. we moved mouse pointer
//from the button to some other place outside button area)
//force the control to redraw
//
if ((m_bButtonDown) && (::GetCapture() == m_hWnd))
{
POINT p2 = point;
::ClientToScreen(m_hWnd, &p2);
HWND mouse_wnd = ::WindowFromPoint(p2);
bool pressed = ((GetState() & BST_PUSHED) == BST_PUSHED);
bool need_pressed = (mouse_wnd == m_hWnd);
if (pressed != need_pressed)
{
//TRACE("* %08X Redraw\n", GetTickCount());
SetState(need_pressed ? TRUE : FALSE);
Invalidate();
}
}
//Forward this event to superclass
CButton::OnMouseMove(nFlags, point);
}
/////////////////////////////////////////////////////////////////////////////
//
//Method......: OnMouseLeave
//Class.......: CxSkinButton
//
//Author......: Milan Gardian
//Created.....: MAR-2001
//
//Return value: NULL
//Parameters..: NOT USED
//Exceptions..: NONE
//------------
//Description :
//
// > Handle situation when mouse cursor leaves area of this
// window (button). This event might be generated ONLY
// if we explicitely call 'TrackMouseEvent'. This is
// signalled by setting the m_tracking flag (see the assert
// precondition) - in 'OnMouseMove' method
//
// > When a mouse pointer leaves area of this button (i.e.
// when this method is invoked), presumably the look of
// the button changes (e.g. when hover/non-hover images are set)
// and therefore we force the control to redraw.
//
//---------------------------------------------------------
LRESULT CxSkinButton::OnMouseLeave(WPARAM, LPARAM)
{
Invalidate();
return 0;
}
/////////////////////////////////////////////////////////////////////////////
//
//Method......: OnKillFocus
//Class.......: CxSkinButton
//
//Author......: Milan Gardian
//Created.....: MAR-2001
//
//Return value: NONE
//Parameters..: See superclass documentation
//Exceptions..: NONE
//------------
//Description :
//
// > If focus is killed during capture, we may no longer
// have the exclusive access to user input and therefore
// release it.
//
// > Such a situation might happens when the user left-clicks
// this button, keeps the button down and simultaneously
// presses TAB key.
//
//---------------------------------------------------------
void CxSkinButton::OnKillFocus(CWnd *new_wnd)
{
if (::GetCapture() == m_hWnd)
{
::ReleaseCapture();
m_bButtonDown = FALSE;
}
CButton::OnKillFocus(new_wnd);
}
/////////////////////////////////////////////////////////////////////////////
//
//Method......: OnClicked
//Class.......: CxSkinButton
//
//Author......: Milan Gardian
//Created.....: MAR-2001
//
//Return value: FALSE (do not stop in this handler - forward to parent)
//Parameters..: NONE
//Exceptions..: NONE
//------------
//Description :
//
// > Keep consistency of attributes of this instance before
// submitting click event to the parent.
//
// > Currently NOT used. To use, umcomment line
// "ON_CONTROL_REFLECT_EX(BN_CLICKED, OnClicked)" in message map
// at the beginning of this file.
//
//---------------------------------------------------------
BOOL CxSkinButton::OnClicked()
{
if (::GetCapture() == m_hWnd)
{
::ReleaseCapture();
}
m_bButtonDown = FALSE;
//Invalidate();
return FALSE;
}
/////////////////////////////////////////////////////////////////////////////
//
//Method......: OnRadioInfo
//Class.......: CxSkinButton
//
//Author......: Rainer Mangold
//Created.....: JUN-2001
//
//Return value: NULL
//Parameters..: WPARAM and LPARAM (LPARAM not used)
//Exceptions..: NONE
//------------
//Description :
//
// > Handle notification, that a Button in the same group was pushed
//
//---------------------------------------------------------
LRESULT CxSkinButton::OnRadioInfo(WPARAM wp, LPARAM)
{
if (m_bChecked)
{
// only checked buttons need to be unchecked
m_bChecked = FALSE;
Invalidate();
}
return 0;
}
/////////////////////////////////////////////////////////////////////////////
void CxSkinButton::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
if ((m_nStyle)&&(nChar==' ')){ //needed stuff for check & radio buttons
if (m_nStyle==BS_CHECKBOX) SetCheck(m_bChecked ? 0 : 1);
if (m_nStyle==BS_RADIOBUTTON) SetCheck(1);
}
CButton::OnKeyDown(nChar, nRepCnt, nFlags);
}
/////////////////////////////////////////////////////////////////////////////
//
//Method......: SetCheck
//Class.......: CxSkinButton
//
//Author......: Rainer Mangold
//Created.....: JUN-2001
//
//Return value: NONE
//Parameters..: bool
//Exceptions..: NONE
//------------
//Description :
//
// > Set the state of this button (pushed or not).
// Works for both, Radio and CheckBox - Buttons
//
//---------------------------------------------------------
LRESULT CxSkinButton::OnBMSetCheck(WPARAM wp, LPARAM)
{
m_bChecked = (wp != 0);
switch (m_nStyle)
{
case BS_RADIOBUTTON:
{
if (m_bChecked)
{
// uncheck the other radio buttons (in the same group)
HWND hthis,hwnd2,hpwnd;
hpwnd=GetParent()->GetSafeHwnd(); //get button parent handle
hwnd2=hthis=GetSafeHwnd(); //get this button handle
if (hthis && hpwnd){ //consistency check
for( ; ; ){ //scan the buttons within the group
hwnd2=::GetNextDlgGroupItem(hpwnd,hwnd2,0);
//until we reach again this button
if ((hwnd2==hthis)||(hwnd2==NULL)) break;
//post the uncheck message
::PostMessage(hwnd2, WM_CXSHADE_RADIO, 0, 0);
}
}
}
}
break;
case BS_PUSHBUTTON:
m_bChecked = FALSE;
ASSERT(FALSE); // Must be a Check or Radio button to use this function
}
Invalidate();
return 0;
}
/////////////////////////////////////////////////////////////////////////////
LRESULT CxSkinButton::OnBMGetCheck(WPARAM wp, LPARAM)
{
return m_bChecked;
} //returns the state for check & radio buttons
/////////////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -