Notice
Link
- Today
- Total
Recent Posts
Recent Comments
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- SQL 첫날
- ffmpeg
- rn
- CentOS
- kill -9
- springboot 재가동
- 터치좌표 view
- springboot
- MariaDB
- 텍스트컬러
- MySQL
- Back 키 클릭 감지
- pid 찾아 kill
- vc++
- 피쉬랜드
- 스크롤적용
- SQL 마지막날
- 코드로 서버 재실행
- view 획득
- sql exception
- 가변영역 스크롤
- Activity 전체화면
- DB 계정생성
- 파티션 빠른 삭제
- mybatis exception
- MFC
- CSS
- reactnative
- 말줌임 CSS
- c언어
Archives
개발은 하는건가..
[MFC] Custom slide control 본문
반응형
CSkinSliderCtrl 을 상속받아 원하는 클래스를 만든 후 아래와 같이 CustomDrawSliderBg, CustomDrawThumb, OnSliderPosChange 를 override 하여 원하는 형태로 DC 에 그리고 필요한 이벤트를 연결하면된다.
이벤트를 연결하면된다
#pragma once
#include "SkinSliderCtrl.h"
class CTestSliderCtrl :public CSkinSliderCtrl
{
public:
CGCSSliderCtrl();
virtual ~CGCSSliderCtrl();
struct CSCallback {
void (*OnSliderPosChange)(CGCSSliderCtrl *pSlider, int pos, void *pOwner);
void *pOwner;
CSCallback::CSCallback() { ZeroMemory(this, sizeof(CSCallback)); };
};
void InitControl(CSCallback *pCb = NULL, int startPos = 127, int min = 0, int max = 255);
inline int GetPos() { return _GetPos(); };
inline void SetPos(int pos) { _SetPos(pos); };
private:
BOOL m_bInit = FALSE;
CFont m_fntText;
CSCallback m_csCallback;
virtual BOOL CustomDrawSliderBg(RECT *pCtrlRect, CDC *pDC);
virtual BOOL CustomDrawThumb(RECT *pThumbRect, CDC *pDC);
virtual void OnSliderPosChange(int value);
};
CSkinSliderCtrl.h
#pragma once
#define WM_FREEZE WM_USER + 0xF003
#define MESSAGE_SLIDER_EVENT WM_USER + 100
#define SLIDER_BEFORE_MOVE 1
#define SLIDER_AFTER_MOVE 2
#define SLIDER_SETPOS_MOVE 3
typedef struct {
void *pThis;
LONGLONG llValue;
} CSliderParam;
class CSkinSliderCtrl : public CSliderCtrl
{
DECLARE_DYNAMIC(CSkinSliderCtrl)
public:
void _GetRange(int& nLower, int& nUpper);
void _SetRange(short nLower, short nUpper);
void _SetRange32(int nLower, int nUpper);
COLORREF _SetBkColor(COLORREF clrNew);
COLORREF _SetThumbColor(COLORREF clrNew);
COLORREF _SetChColor(COLORREF clrNew);
int _GetPos(void);
int _OffsetPos(int nPos);
int _SetPos(int nPos);
int _SetStep(int nStep);
int _StepIt(void);
BOOL Freeze(void);
void SetFreeze(BOOL freeze);
inline BOOL IsFreeze() { return m_bFreezed; };
HRESULT _EnableBorders(BOOL bEnable=TRUE);
BOOL _IsEnabled(void);
void setThumbSkin(UINT imgOut, UINT imgOver = -1);
void setProgressSkin(UINT img);
void setBackground(UINT img);
BOOL isDrag();
inline void SetHighLightRange(int nStart, int nEnd) { m_HiLightStart = nStart; m_HiLightEnd = nEnd; };
public:
CSkinSliderCtrl();
virtual ~CSkinSliderCtrl();
virtual BOOL CustomDrawSliderBg(RECT *pCtrlRect, CDC *pDC);
virtual BOOL CustomDrawThumb(RECT *pThumbRect, CDC *pDC);
virtual void OnSliderPosChange(int value);
protected:
DECLARE_MESSAGE_MAP()
void Draw(LPNMCUSTOMDRAW pNMCD);
void RecursiveRect(CDC *pDC, CRect rc, COLORREF nClr, BOOL First=FALSE);
void RecursiveChannel(CDC *pDC, CRect rc, COLORREF nClr, BOOL First=FALSE, BOOL Vertical=FALSE,BYTE StepSize=30);
protected:
COLORREF m_ProBkColor;
COLORREF m_ProgressBarColor;
PBRANGE m_ProRange;
int m_ProgressPos;
int m_ProgressStep;
int m_HiLightStart = -1;
int m_HiLightEnd = -1;
DWORD m_Direction;
COLORREF m_ThClOver;
COLORREF m_ThClOut;
COLORREF m_ThClPre;
COLORREF m_ThClDef;
BOOL m_bBorders;
BOOL m_bFreezed;
COLORREF tmp1,tmp2;
BOOL m_bBlink;
BOOL isKeyDown;
BOOL isLbuttonDown;
HBITMAP m_hbmMask;
CBitmap *m_pbtmThumbDef;
CBitmap *m_pbtmThumbOut;
CBitmap *m_pbtmThumbOver;
CBitmap *m_pbtmProgress;
CBitmap *m_pbtmBackgrand;
protected:
HRESULT DrawSliderThumb(LPNMCUSTOMDRAW pNMCD);
HRESULT DrawSliderBorder(LPNMCUSTOMDRAW pNMCD);
HRESULT DrawSliderChannel(LPNMCUSTOMDRAW pNMCD);
void createMask(HDC hDC, CBitmap *bmp);
void drawThumb(HDC hDC, int x, int y);
void drawProgress(HDC hDC, CRect rc);
void drawBackground(HDC hDC, CRect rc);
CRect getThumbRect();
void setPointToPos(CPoint point);
public:
afx_msg void OnNMCustomdraw(NMHDR *pNMHDR, LRESULT *pResult);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void OnTimer(UINT nIDEvent);
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags);
afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt);
};
CSkinSliderCtrl.cpp
#include "../pch.h"
#include "SkinSliderCtrl.h"
IMPLEMENT_DYNAMIC(CSkinSliderCtrl, CSliderCtrl)
CSkinSliderCtrl::CSkinSliderCtrl()
{
m_ProBkColor = RGB(0, 54, 68);
m_ThClOver = RGB(25, 25, 40);
m_ThClOut = RGB(25, 25, 40);
m_ThClPre = RGB(45, 45, 60);
m_ProgressBarColor = RGB(0, 225, 225);
m_ThClDef = m_ThClOut;
m_ProgressStep = 10;
m_bBorders = TRUE;
m_bFreezed = FALSE;
m_bBlink = FALSE;
m_hbmMask = NULL;
isKeyDown = FALSE;
isLbuttonDown = FALSE;
m_pbtmThumbDef = NULL;
m_pbtmThumbOut = NULL;
m_pbtmThumbOver = NULL;
m_pbtmProgress = NULL;
m_pbtmBackgrand = NULL;
}
CSkinSliderCtrl::~CSkinSliderCtrl()
{
if (m_pbtmThumbOut != NULL) {
delete m_pbtmThumbOut;
m_pbtmThumbOut = NULL;
}
if (m_pbtmThumbOver != NULL) {
delete m_pbtmThumbOver;
m_pbtmThumbOver = NULL;
}
if (m_pbtmProgress != NULL) {
delete m_pbtmProgress;
m_pbtmProgress = NULL;
}
if (m_pbtmBackgrand != NULL) {
delete m_pbtmBackgrand;
m_pbtmBackgrand = NULL;
}
}
BEGIN_MESSAGE_MAP(CSkinSliderCtrl, CSliderCtrl)
ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, OnNMCustomdraw)
ON_WM_MOUSEMOVE()
// ON_WM_TIMER()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_KEYDOWN()
ON_WM_KEYUP()
ON_WM_MOUSEWHEEL()
END_MESSAGE_MAP()
// CSkinSliderCtrl message handlers
// Custom control drawing operations
void CSkinSliderCtrl::OnNMCustomdraw(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMCUSTOMDRAW pNMCD = reinterpret_cast<LPNMCUSTOMDRAW>(pNMHDR);
switch(pNMCD->dwDrawStage)
{
case CDDS_POSTERASE: // After the erasing cycle is complete.
*pResult = CDRF_SKIPDEFAULT;
break;
case CDDS_POSTPAINT: // After the painting cycle is complete.
*pResult = CDRF_DODEFAULT;
break;
case CDDS_PREERASE: // Before the erasing cycle begins.
*pResult = CDRF_SKIPDEFAULT;
break;
case CDDS_PREPAINT: // Before the painting cycle begins.
*pResult = CDRF_NOTIFYITEMDRAW;
break;
case CDDS_ITEMPREPAINT: // Before an item is drawn.
switch(pNMCD->dwItemSpec)
{
// Identifies the channel that the slider control's thumb marker slides along.
case TBCD_CHANNEL:
if (m_bBorders) {
DrawSliderBorder(pNMCD);
}
DrawSliderChannel(pNMCD);
*pResult = CDRF_SKIPDEFAULT;
break;
// Identifies the increment tick marks that appear along the edge of the slider control.
case TBCD_TICS:
*pResult = CDRF_DODEFAULT;
break;
// Identifies the slider control's thumb marker. This is the portion of
// the control that the user moves.
case TBCD_THUMB:
if (DrawSliderThumb(pNMCD) == S_OK) {
*pResult = CDRF_SKIPDEFAULT;
}
else
*pResult = CDRF_DODEFAULT;
break;
default:
*pResult = CDRF_SKIPDEFAULT;
break;
}
break;
default:
*pResult = CDRF_DODEFAULT;
break;
}
}
void CSkinSliderCtrl::_GetRange(int& nLower, int& nUpper)
{
nLower = m_ProRange.iLow;
nUpper = m_ProRange.iHigh;
return;
}
void CSkinSliderCtrl::_SetRange(short nLower, short nUpper)
{
m_ProRange.iLow = nLower;
m_ProRange.iHigh = nUpper;
return;
}
void CSkinSliderCtrl::_SetRange32(int nLower, int nUpper)
{
m_ProRange.iLow = nLower;
m_ProRange.iHigh = nUpper;
CSliderCtrl::SetRange(nLower, nUpper);
return;
}
COLORREF CSkinSliderCtrl::_SetBkColor(COLORREF clrNew)
{
COLORREF m_tmp = m_ProBkColor;
m_ProBkColor = clrNew;
int min,max;
GetRange(min,max);
CSliderCtrl::SetRange(min,max,TRUE);
return m_tmp;
}
COLORREF CSkinSliderCtrl::_SetThumbColor(COLORREF clrNew)
{
COLORREF m_tmp = m_ThClDef;
m_ThClDef = clrNew;
int min,max;
GetRange(min,max);
CSliderCtrl::SetRange(min,max,TRUE);
return m_tmp;
}
COLORREF CSkinSliderCtrl::_SetChColor(COLORREF clrNew)
{
COLORREF m_tmp = m_ProgressBarColor;
m_ProgressBarColor = clrNew;
int min,max;
GetRange(min,max);
CSliderCtrl::SetRange(min,max,TRUE);
return m_tmp;
}
int CSkinSliderCtrl::_GetPos(void)
{
return (m_ProgressPos);
}
int CSkinSliderCtrl::_OffsetPos(int nPos)
{
int curr = m_ProgressPos;
m_ProgressPos+= nPos;
int min,max;
GetRange(min,max);
CSliderCtrl::SetRange(min,max,TRUE);
return(curr);
}
int CSkinSliderCtrl::_SetPos(int nPos)
{
int curr = m_ProgressPos;
m_ProgressPos = nPos;
int min,max;
GetRange(min,max);
if (isKeyDown == FALSE) {
CSliderCtrl::SetPos(nPos);
CSliderCtrl::SetRange(min, max, TRUE);
}
CSliderParam sp;
sp.pThis = this;
sp.llValue = nPos;
GetParent()->SendMessage(MESSAGE_SLIDER_EVENT, SLIDER_SETPOS_MOVE, (LPARAM)&sp);
return(curr);
}
int CSkinSliderCtrl::_SetStep(int nStep)
{
int curr = m_ProgressStep;
m_ProgressStep = nStep;
return curr;
}
int CSkinSliderCtrl::_StepIt(void)
{
int curr = m_ProgressPos;
int min,max;
GetRange(min,max);
m_ProgressPos + m_ProgressStep >= max ? m_ProgressPos += m_ProgressStep-max : m_ProgressPos += m_ProgressStep;
CSliderCtrl::SetRange(min,max,TRUE);
return(curr);
}
HRESULT CSkinSliderCtrl::DrawSliderBorder(LPNMCUSTOMDRAW pNMCD)
{
RECT border;
GetClientRect(&border);
CDC *pDC = CDC::FromHandle(pNMCD->hdc);
if (pDC != NULL)
{
pDC->FillSolidRect(&border, m_ProBkColor);
CustomDrawSliderBg(&border, pDC);
ReleaseDC(pDC);
}
return S_OK;
}
BOOL CSkinSliderCtrl::CustomDrawSliderBg(RECT *pCtrlRect, CDC *pDC)
{
// override
return FALSE;
}
BOOL CSkinSliderCtrl::CustomDrawThumb(RECT *pThumbRect, CDC *pDC)
{
// override
return FALSE;
}
void CSkinSliderCtrl::OnSliderPosChange(int value)
{
// override
}
HRESULT CSkinSliderCtrl::DrawSliderChannel(LPNMCUSTOMDRAW pNMCD)
{
CRect crect, rcHiLight;
double rr;
CDC *pDC = CDC::FromHandle(pNMCD->hdc);
crect.CopyRect(&pNMCD->rc);
BOOL Vert=FALSE;
if(crect.Height()>crect.Width()) Vert=TRUE;
switch(Vert)
{
case TRUE:
crect.InflateRect(3, 0, 3, 0);
DrawEdge(pNMCD->hdc, &crect, BDR_SUNKENINNER, BF_RECT | BF_SOFT | BF_MONO);
crect.InflateRect(1, 0, 1, 0);
if (m_ProRange.iHigh != 0) {
rr = (crect.Height() * m_ProgressPos) / m_ProRange.iHigh;
crect.bottom = (LONG)rr + crect.top;
}
else {
crect.bottom = crect.top;
}
//crect.top = 9;
RecursiveChannel(pDC, crect, m_ProgressBarColor, TRUE, TRUE);
break;
case FALSE:
crect.InflateRect(0, 3, 0, 3);
rcHiLight = crect;
if (m_pbtmBackgrand == NULL)
{
pDC->FillSolidRect(crect, RGB(0, 40, 40));
pDC->FillSolidRect(crect.left+1, crect.top+1, crect.Width()-1, crect.Height()-1, RGB(225, 225, 225));
pDC->FillSolidRect(crect.left+1, crect.top+1, crect.Width()-2, crect.Height()-2, m_ProgressBarColor);
//DrawEdge(pNMCD->hdc, &crect, BDR_SUNKENINNER, BF_RIGHT | BF_BOTTOM | BF_SOFT | BF_MONO);
}
else {
drawBackground(pNMCD->hdc, crect);
}
if (m_ProRange.iHigh != 0) {
rr = (crect.Width() * m_ProgressPos) / m_ProRange.iHigh;
crect.right = (LONG)rr + crect.left;
}
else {
crect.right = crect.left;
}
#if 0
if (m_pbtmProgress == NULL) {
RecursiveChannel(pDC, crect, m_ProgressBarColor, TRUE);
}
else {
drawProgress(pNMCD->hdc, crect);
}
#endif
if (m_HiLightStart != -1 && m_HiLightEnd != -1 && m_ProRange.iHigh != 0) {
int ww = rcHiLight.Width();
rcHiLight.left += (ww * m_HiLightStart) / m_ProRange.iHigh;
rcHiLight.right = (ww * m_HiLightEnd) / m_ProRange.iHigh;
RecursiveChannel(pDC, rcHiLight, RGB(174, 76, 98), TRUE);
}
break;
}
ReleaseDC(pDC);
return S_OK;
}
__inline void CSkinSliderCtrl::RecursiveChannel(CDC *pDC,
CRect rc, COLORREF nClr,
BOOL First/*=FALSE*/,
BOOL Vertical/*=FALSE*/,
BYTE StepSize/*=20*/)
{
if (pDC == NULL) {
return;
}
#if 1
UINT borderColor = nClr;
BYTE r, g, b;
r = (BYTE)(GetRValue(nClr) * 0.5);
g = (BYTE)(GetGValue(nClr) * 0.5);
b = (BYTE)(GetBValue(nClr) * 0.5);
pDC->FillSolidRect(rc, RGB(r, b, g));
rc.DeflateRect(1, 1);
pDC->FillSolidRect(rc, nClr);
#else
CBrush Brush;
Brush.CreateSolidBrush(nClr);
HGDIOBJ old = pDC->SelectObject(Brush);
CPen Pen;
Pen.CreatePen(PS_SOLID, 1, nClr);
CPen* pOldPen = pDC->SelectObject(&Pen);
//pDC->RoundRect(rc,CPoint(rc.Width() / 2, rc.Height() / 2));
pDC->RoundRect(rc, CPoint(1, 1));
First ? rc.DeflateRect(1, 1) : Vertical ? rc.DeflateRect(1, 0) : rc.DeflateRect(0, 1);
BYTE r, g, b;
r = GetRValue(nClr);
g = GetGValue(nClr);
b = GetBValue(nClr);
StepSize + r >= 255 ? r = 255 : r = StepSize + r; // r+=Stepsize gives warning C4244
StepSize + g >= 255 ? g = 255 : g = StepSize + g;
StepSize + b >= 255 ? b = 255 : b = StepSize + b;
if (!rc.IsRectEmpty()) RecursiveRect(pDC, rc, RGB(r, g, b));
pDC->SelectObject(old);
pDC->SelectObject(pOldPen);
::DeleteObject(Brush);
::DeleteObject(Pen);
#endif
}
HRESULT CSkinSliderCtrl::DrawSliderThumb(LPNMCUSTOMDRAW pNMCD)
{
if (pNMCD->uItemState & CDIS_SELECTED) {
this->m_ThClDef = this->m_ThClPre;
}
Draw(pNMCD);
return S_OK;
}
__inline void CSkinSliderCtrl::Draw(LPNMCUSTOMDRAW pNMCD)
{
CRect rect = getThumbRect();
if (m_pbtmThumbDef != NULL) {
drawThumb(pNMCD->hdc, rect.left, rect.top);
}
else {
CDC *pDC = CDC::FromHandle(pNMCD->hdc);
if (pDC != NULL)
{
if (CustomDrawThumb(&rect, pDC) == FALSE) {
if (this->IsWindowEnabled() == FALSE)
RecursiveChannel(pDC, &rect, RGB(10, 10, 10), TRUE);
else
RecursiveChannel(pDC, &rect, RGB(255, 255, 255), TRUE);
}
ReleaseDC(pDC);
}
}
return;
}
__inline void CSkinSliderCtrl::RecursiveRect(CDC *pDC, CRect rc, COLORREF nClr, BOOL First/*=FALSE*/)
{
CBrush Brush;
Brush.CreateSolidBrush(nClr);
HGDIOBJ old = pDC->SelectObject(Brush);
CPen Pen;
Pen.CreatePen(PS_SOLID,1,nClr);
CPen* pOldPen = pDC->SelectObject(&Pen);
//pDC->RoundRect(rc,CPoint(rc.Width() / 2, rc.Height() / 2));
pDC->RoundRect(rc, CPoint(1, 1));
First?rc.DeflateRect(1,1):this->GetStyle()&TBS_VERT?rc.DeflateRect(1,0):rc.DeflateRect(0,1);
BYTE r,g,b;
r = GetRValue(nClr);
g = GetGValue(nClr);
b = GetBValue(nClr);
if(r<=245) r+=10;
if(g<=245) g+=10;
if(b<=245) b+=10;
//if(!rc.IsRectEmpty()) RecursiveRect(pDC,rc,RGB(r,g,b));
pDC->SelectObject(old);
pDC->SelectObject(pOldPen);
::DeleteObject(Brush);
::DeleteObject(Pen);
}
void CSkinSliderCtrl::OnMouseMove(UINT nFlags, CPoint point)
{
CRect tRect = getThumbRect();
if(tRect.PtInRect(point))
{
if (m_pbtmThumbOver != NULL) {
m_pbtmThumbDef = m_pbtmThumbOver;
}
else {
m_ThClDef = m_ThClOver;
}
}
else {
if (m_pbtmThumbOut != NULL) {
m_pbtmThumbDef = m_pbtmThumbOut;
}
else {
m_ThClDef = m_ThClOut;
}
}
if (isLbuttonDown) {
setPointToPos(point);
Invalidate(FALSE);
}
else {
int min, max;
GetRange(min, max);
CSliderCtrl::SetRange(min, max, TRUE);
}
}
void CSkinSliderCtrl::createMask(HDC hDC, CBitmap *pBmp)
{
// 기존의 마스크를 모두 없앤다.
if (m_hbmMask) {
::DeleteObject(m_hbmMask);
}
BITMAP bm;
pBmp->GetObject(sizeof(bm), &bm);
// 작업 할 메모리 DC를 만듭니다.
HDC hdcMask = ::CreateCompatibleDC(hDC);
HDC hdcImage = ::CreateCompatibleDC(hDC);
// 마스크의 단색 비트 맵을 만듭니다.
m_hbmMask = ::CreateBitmap(bm.bmWidth, bm.bmHeight, 1, 1, NULL);
// DC에 모노 비트 맵을 선택하십시오.
HBITMAP hbmOldMask = (HBITMAP)::SelectObject(hdcMask, m_hbmMask);
// DC에 이미지 비트 맵을 선택하십시오.
HBITMAP hbmOldImage = (HBITMAP)::SelectObject(hdcImage, pBmp->m_hObject);
// 투명도 색상을 왼쪽 위 픽셀로 설정합니다.
::SetBkColor(hdcImage, ::GetPixel(hdcImage, 0, 0));
// 마스크를 만드십시오.
::BitBlt(hdcMask, 0, 0, bm.bmWidth, bm.bmHeight, hdcImage, 0, 0, SRCCOPY);
// Tidy up.
::SelectObject(hdcMask, hbmOldMask);
::SelectObject(hdcImage, hbmOldImage);
::DeleteDC(hdcMask);
::DeleteDC(hdcImage);
}
void CSkinSliderCtrl::drawThumb(HDC hDC, int x, int y)
{
ASSERT(hDC);
if (!m_hbmMask) createMask(hDC, m_pbtmThumbDef);
ASSERT(m_hbmMask);
BITMAP bm;
m_pbtmThumbDef->GetObject(sizeof(bm), &bm);
int dx = bm.bmWidth;
int dy = bm.bmHeight;
// 그릴 메모리 DC를 만듭니다.
HDC hdcOffScr = ::CreateCompatibleDC(hDC);
// 대상 DC와 실제로 색상이 호환되는 오프 스크린 DC 용 비트 맵을 만듭니다.
HBITMAP hbmOffScr = ::CreateBitmap(dx, dy,
(BYTE)GetDeviceCaps(hDC, PLANES),
(BYTE)GetDeviceCaps(hDC, BITSPIXEL),
NULL);
// 오프 스크린 DC로 버퍼 비트 맵을 선택하십시오.
HBITMAP hbmOldOffScr = (HBITMAP)::SelectObject(hdcOffScr, hbmOffScr);
// 목적지 직사각형의 이미지를 오프 스크린 버퍼 DC에 복사한다. 그래서 우리는 그것을 플레이 할 수있다.
::BitBlt(hdcOffScr, 0, 0, dx, dy, hDC, x, y, SRCCOPY);
// 원본 이미지에 대한 메모리 DC를 만듭니다.
HDC hdcImage = ::CreateCompatibleDC(hDC);
HBITMAP hbmOldImage = (HBITMAP)::SelectObject(hdcImage, m_pbtmThumbDef->m_hObject);
// 마스크에 대한 메모리 DC를 만듭니다.
HDC hdcMask = ::CreateCompatibleDC(hDC);
HBITMAP hbmOldMask = (HBITMAP)::SelectObject(hdcMask, m_hbmMask);
DWORD DSx = SRCINVERT, DSa = SRCAND;
// 이미지를 대상과 XOR합니다.
::SetBkColor(hdcOffScr, RGB(255, 255, 255));
::BitBlt(hdcOffScr, 0, 0, dx, dy, hdcImage, 0, 0, DSx);
// 대상과 마스크를 AND합니다.
::BitBlt(hdcOffScr, 0, 0, dx, dy, hdcMask, 0, 0, DSa);
// 이미지와 대상을 다시 XOR합니다.
::BitBlt(hdcOffScr, 0, 0, dx, dy, hdcImage, 0, 0, DSx);
// 결과 이미지를 화면 DC로 다시 복사합니다.
::BitBlt(hDC, x, y, dx, dy, hdcOffScr, 0, 0, SRCCOPY);
// Tidy up.
::SelectObject(hdcOffScr, hbmOldOffScr);
::SelectObject(hdcImage, hbmOldImage);
::SelectObject(hdcMask, hbmOldMask);
::DeleteObject(hbmOffScr);
::DeleteDC(hdcOffScr);
::DeleteDC(hdcImage);
::DeleteDC(hdcMask);
}
void CSkinSliderCtrl::drawProgress(HDC hDC, CRect rc)
{
ASSERT(hDC);
// Create a memory DC.
HDC hdcMem = ::CreateCompatibleDC(hDC);
BITMAP bm;
m_pbtmProgress->GetObject(sizeof(bm), &bm);
// Select the bitmap into the mem DC.
HBITMAP hbmold = (HBITMAP)::SelectObject(hdcMem, (HBITMAP)(m_pbtmProgress->m_hObject));
// Blt the bits.
::StretchBlt(hDC, rc.top, rc.left, rc.right - rc.left, rc.bottom - rc.top, hdcMem, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);
::SelectObject(hdcMem, hbmold);
::DeleteDC(hdcMem);
}
void CSkinSliderCtrl::drawBackground(HDC hDC, CRect rc)
{
ASSERT(hDC);
// Create a memory DC.
HDC hdcMem = ::CreateCompatibleDC(hDC);
BITMAP bm;
m_pbtmBackgrand->GetObject(sizeof(bm), &bm);
// Select the bitmap into the mem DC.
HBITMAP hbmold = (HBITMAP)::SelectObject(hdcMem, (HBITMAP)(m_pbtmBackgrand->m_hObject));
// Blt the bits.
::StretchBlt(hDC, rc.top, rc.left, rc.right - rc.left, rc.bottom - rc.top, hdcMem, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);
::SelectObject(hdcMem, hbmold);
::DeleteDC(hdcMem);
}
CRect CSkinSliderCtrl::getThumbRect()
{
CRect thumbRect;
CRect rectchn;
int size = 0;
GetChannelRect(&rectchn);
GetThumbRect(&thumbRect);
if (GetRangeMax() > 0 && GetPos() > 0) {
if (rectchn.Height() < rectchn.Width()) {
size = rectchn.Width() * GetPos() / GetRangeMax();
}
else {
size = rectchn.Height() * GetPos() / GetRangeMax();
}
}
if (m_pbtmThumbDef != NULL) {
BITMAP bm;
m_pbtmThumbDef->GetObject(sizeof(bm), &bm);
if (rectchn.Height() < rectchn.Width()) {
thumbRect.left = rectchn.left + size - bm.bmWidth / 2;
thumbRect.right = thumbRect.left + bm.bmWidth;
thumbRect.top = (thumbRect.bottom - bm.bmHeight) / 2;
thumbRect.bottom = thumbRect.top + bm.bmHeight;
}
else {
thumbRect.left = (thumbRect.right - bm.bmWidth) / 2;
thumbRect.right = thumbRect.left + bm.bmWidth;
thumbRect.top = rectchn.top + size - bm.bmHeight / 2;
thumbRect.bottom = thumbRect.top + bm.bmHeight;
}
}
else {
int tempSize;
if (rectchn.Height() < rectchn.Width()) {
tempSize = (thumbRect.right - thumbRect.left) / 2;
thumbRect.left = size - tempSize + rectchn.left;
thumbRect.right = size + tempSize + rectchn.left;
}
else {
tempSize = (thumbRect.bottom - thumbRect.top) / 2;
thumbRect.top = size - tempSize + rectchn.top;
thumbRect.bottom = size + tempSize + rectchn.top;
}
}
return thumbRect;
}
void CSkinSliderCtrl::setPointToPos(CPoint point)
{
CRect rect;
GetChannelRect(&rect);
point.x = min(max(rect.left, point.x), rect.right);
int size = 0;
size = GetRangeMax() * (point.x - rect.left) / rect.Width();
size = (size >= GetRangeMax())? GetRangeMax() - 1 : size;
_SetPos(size);
CSliderParam sp;
sp.pThis = this;
sp.llValue = size;
GetParent()->SendMessage(MESSAGE_SLIDER_EVENT, SLIDER_BEFORE_MOVE, (LPARAM)&sp);
::SendMessage(GetSafeHwnd(), WM_KILLFOCUS, NULL, NULL);
}
// Enables/Disables window borders
HRESULT CSkinSliderCtrl::_EnableBorders(BOOL bEnable/*=TRUE*/)
{
m_bBorders = bEnable;
int min,max;
GetRange(min,max);
CSliderCtrl::SetRange(min,max,TRUE);
return S_OK;
}
BOOL CSkinSliderCtrl::_IsEnabled(void)
{
return m_bBorders;
}
BOOL CSkinSliderCtrl::Freeze(void)
{
BOOL Prev= m_bFreezed;
if(!Prev) // Freeze now
{
tmp1 = m_ThClDef;
tmp2 = m_ProBkColor;
SetTimer(WM_FREEZE,1000,NULL);
m_bFreezed = TRUE;
}
else {
KillTimer(WM_FREEZE);
m_bFreezed = FALSE;
m_ThClDef = tmp1;
m_ProBkColor = tmp2;
int min,max;
GetRange(min,max);
CSliderCtrl::SetRange(min,max,TRUE);
}
return Prev;
}
void CSkinSliderCtrl::SetFreeze(BOOL freeze)
{
m_bFreezed = freeze;
}
void CSkinSliderCtrl::setThumbSkin(UINT imgOut, UINT imgOver)
{
m_pbtmThumbOut = new CBitmap();
m_pbtmThumbOut->LoadBitmap(imgOut);
m_pbtmThumbDef = m_pbtmThumbOut;
if (imgOver != -1) {
m_pbtmThumbOver = new CBitmap();
m_pbtmThumbOver->LoadBitmap(imgOver);
}
}
void CSkinSliderCtrl::setProgressSkin(UINT img)
{
m_pbtmProgress = new CBitmap();
m_pbtmProgress->LoadBitmap(img);
}
void CSkinSliderCtrl::setBackground(UINT img)
{
m_pbtmBackgrand = new CBitmap();
m_pbtmBackgrand->LoadBitmap(img);
}
BOOL CSkinSliderCtrl::isDrag()
{
return isLbuttonDown;
}
// used for freezing operation
void CSkinSliderCtrl::OnTimer(UINT nIDEvent)
{
int min,max;
if (m_bBlink) {
m_ThClDef = RGB(102,102,204);
m_bBlink = FALSE;
m_ProBkColor = RGB(102,102,204);
GetRange(min,max);
CSliderCtrl::SetRange(min,max,TRUE);
}
else {
m_ThClDef = RGB(204,204,204);
m_ProBkColor = RGB(204,204,204);
GetRange(min,max);
CSliderCtrl::SetRange(min,max,TRUE);
m_bBlink = TRUE;
}
CSliderCtrl::OnTimer(nIDEvent);
}
void CSkinSliderCtrl::OnLButtonDown(UINT nFlags, CPoint point)
{
if (m_bFreezed) {
return;
}
isLbuttonDown = TRUE;
setPointToPos(point);
CSliderCtrl::OnLButtonDown(nFlags, point);
}
void CSkinSliderCtrl::OnLButtonUp(UINT nFlags, CPoint point)
{
CSliderCtrl::OnLButtonUp(nFlags, point);
if (m_bFreezed) {
return;
}
if (isLbuttonDown == TRUE) {
//_SetPos(GetPos());
int pos = GetPos();
/*double size;
size = pos * 0.044;
pos += size;*/
CSliderParam sp;
sp.pThis = this;
sp.llValue = pos;
GetParent()->SendMessage(MESSAGE_SLIDER_EVENT, SLIDER_AFTER_MOVE, (LPARAM)&sp);
OnSliderPosChange(pos);
isLbuttonDown = FALSE;
}
}
void CSkinSliderCtrl::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
isKeyDown = TRUE;
switch (nChar)
{
case VK_LEFT:
case VK_DOWN:
m_ProgressPos = GetPos() <= 0 ? 0 : GetPos() - GetLineSize();
Invalidate(FALSE);
break;
case VK_RIGHT:
case VK_UP:
m_ProgressPos = GetPos() >= GetRangeMax() ? GetRangeMax() - 1 : GetPos() + GetLineSize();
Invalidate(FALSE);
break;
default:
break;
}
CSliderCtrl::OnKeyDown(nChar, nRepCnt, nFlags);
}
void CSkinSliderCtrl::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
{
isKeyDown = FALSE;
switch (nChar)
{
case VK_LEFT:
case VK_RIGHT:
case VK_UP:
case VK_DOWN:
CSliderParam sp;
sp.pThis = this;
sp.llValue = GetPos();
GetParent()->SendMessage(MESSAGE_SLIDER_EVENT, SLIDER_AFTER_MOVE, (LPARAM)&sp);
Invalidate(FALSE);
break;
default:
break;
}
CSliderCtrl::OnKeyUp(nChar, nRepCnt, nFlags);
}
BOOL CSkinSliderCtrl::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
{
return TRUE;
}
'C, C++, MFC' 카테고리의 다른 글
GPS 위도, 경도 위치 간 거리 계산 (0) | 2023.04.06 |
---|---|
OpenSSL VC++ 용 빌드하기 (0) | 2023.03.27 |
[MFC] 배율에 따라 영향 받지 않도록 컨트롤 배치 (0) | 2022.11.09 |
[WinAPI] VC++ 윈도우 화면 배율 가져오기 (0) | 2022.11.09 |
[MFC] 가상 조이스틱 패드 컨트롤 (0) | 2022.10.27 |
Comments