vc 自定义喜木按扭类

  1. #if !defined(AFX_MYB_H__3832DDEF_0C12_11D5_B6BE_00E07D8144D0__INCLUDED_) 
  2. #define AFX_MYB_H__3832DDEF_0C12_11D5_B6BE_00E07D8144D0__INCLUDED_ 
  3. #if _MSC_VER > 1000 
  4. #pragma once 
  5. #endif 
  6. // CXMButton.h : header file 
  7. #define WM_CXSHADE_RADIO WM_USER+0x100 
  8. // CXMButton window 
  9. class CXMButton : public CButton 
  10.     // Construction 
  11. public
  12.     CXMButton(); 
  13.     
  14.     // Attributes 
  15. private
  16.     
  17.     // Operations 
  18. public
  19.     // Overrides 
  20.     // ClassWizard generated virtual function overrides 
  21.     //{{AFX_VIRTUAL(CxSkinButton) 
  22. public
  23.     virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct); 
  24. protected
  25.     virtual void PreSubclassWindow(); 
  26.     //}}AFX_VIRTUAL 
  27.     // Implementation 
  28. public
  29.     void SetToolTipText(CString s); 
  30.     COLORREF SetTextColor(COLORREF new_color); 
  31.     void SetSkin(UINT normal,UINT down, UINT over=0, UINT disabled=0, UINT focus=0,UINT mask=0, 
  32.         short drawmode=1,short border=1,short margin=4); 
  33.     virtual ~CXMButton(); 
  34.     // Generated message map functions 
  35. protected
  36.     bool m_Checked; //radio &amt; check buttons 
  37.     DWORD m_Style; //radio &amt; check buttons 
  38.     bool m_tracking; 
  39.     bool m_button_down; 
  40.     void RelayEvent(UINT message, WPARAM wParam, LPARAM lParam); 
  41.     CToolTipCtrl m_tooltip; 
  42.     CBitmap m_bNormal,m_bDown,m_bDisabled,m_bMask,m_bOver,m_bFocus; //skin bitmaps 
  43.     short m_FocusRectMargin; //dotted margin offset 
  44.     COLORREF m_TextColor; //button text color 
  45.     HRGN hClipRgn; //clipping region 
  46.     BOOL m_Border; //0=flat; 1=3D; 
  47.     short m_DrawMode; //0=normal; 1=stretch; 2=tiled; 
  48.     HRGN CreateRgnFromBitmap(HBITMAP hBmp, COLORREF color); 
  49.     void FillWithBitmap(CDC* dc, HBITMAP hbmp, RECT r); 
  50.     void DrawBitmap(CDC* dc, HBITMAP hbmp, RECT r, int DrawMode); 
  51.     int GetBitmapWidth (HBITMAP hBitmap); 
  52.     int GetBitmapHeight (HBITMAP hBitmap); 
  53.     //{{AFX_MSG(CxSkinButton) 
  54.     afx_msg BOOL OnEraseBkgnd(CDC* pDC); 
  55.     afx_msg void OnLButtonDown(UINT nFlags, CPoint point); 
  56.     afx_msg void OnLButtonUp(UINT nFlags, CPoint point); 
  57.     afx_msg void OnMouseMove(UINT nFlags, CPoint point); 
  58.     afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point); 
  59.     afx_msg void OnKillFocus(CWnd* pNewWnd); 
  60.     afx_msg BOOL OnClicked(); 
  61.     afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags); 
  62.     //}}AFX_MSG 
  63.     afx_msg LRESULT OnMouseLeave(WPARAMLPARAM); 
  64.     afx_msg LRESULT OnRadioInfo(WPARAMLPARAM); 
  65.     afx_msg LRESULT OnBMSetCheck(WPARAMLPARAM); 
  66.     afx_msg LRESULT OnBMGetCheck(WPARAMLPARAM); 
  67.     DECLARE_MESSAGE_MAP() 
  68. }; 
  69. //{{AFX_INSERT_LOCATION}} 
  70. // Microsoft Visual C++ will insert additional declarations immediately before the previous line. 
  71. #endif // !defined(AFX_MYB_H__3832DDEF_0C12_11D5_B6BE_00E07D8144D0__INCLUDED_)

 

  1. // XMButton.cpp : implementation file
  2. #include "stdafx.h" 
  3. #include "XMButton.h"
  4. #ifdef _DEBUG 
  5. #define new DEBUG_NEW 
  6. #undef THIS_FILE 
  7. static char THIS_FILE[] = __FILE__; 
  8. #endif 
  9. // CXMButton 
  10. CXMButton::CXMButton() 
  11. m_DrawMode=1; // normal drawing mode 
  12. m_FocusRectMargin=0; // disable focus dotted rect 
  13. hClipRgn=NULL; // no clipping region 
  14. m_TextColor=GetSysColor(COLOR_BTNTEXT); // default button text color 
  15. m_button_down = m_tracking = m_Checked = false
  16. CXMButton::~CXMButton() 
  17. if (hClipRgn) DeleteObject(hClipRgn); // free clip region 
  18. BEGIN_MESSAGE_MAP(CXMButton, CButton) 
  19. //{{AFX_MSG_MAP(CxSkinButton) 
  20. ON_WM_ERASEBKGND() 
  21. ON_WM_LBUTTONDOWN() 
  22. ON_WM_LBUTTONUP() 
  23. ON_WM_MOUSEMOVE() 
  24. ON_WM_LBUTTONDBLCLK() 
  25. ON_WM_KILLFOCUS() 
  26. //ON_CONTROL_REFLECT_EX(BN_CLICKED, OnClicked) 
  27. ON_WM_KEYDOWN() 
  28. //}}AFX_MSG_MAP 
  29. ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave) 
  30. ON_MESSAGE(WM_CXSHADE_RADIO , OnRadioInfo) 
  31. ON_MESSAGE(BM_SETCHECK , OnBMSetCheck) 
  32. ON_MESSAGE(BM_GETCHECK , OnBMGetCheck) 
  33. END_MESSAGE_MAP() 
  34. // CxSkinButton message handlers 
  35. void CXMButton::PreSubclassWindow() 
  36. m_Style=GetButtonStyle(); ///get specific BS_ styles 
  37. if ((m_Style & BS_AUTOCHECKBOX)==BS_AUTOCHECKBOX) 
  38. // ||((m_Style & BS_CHECKBOX)==BS_CHECKBOX)) 
  39. m_Style=BS_CHECKBOX; 
  40. else if ((m_Style & BS_AUTORADIOBUTTON)==BS_AUTORADIOBUTTON) 
  41. // ||((m_Style & BS_RADIOBUTTON)==BS_RADIOBUTTON)) 
  42. m_Style=BS_RADIOBUTTON; 
  43. else { m_Style=BS_PUSHBUTTON; } 
  44. CButton::PreSubclassWindow(); 
  45. ModifyStyle(0, BS_OWNERDRAW); 
  46. BOOL CXMButton::OnEraseBkgnd(CDC* pDC) 
  47. return 1; } // doesn't erase the button background 
  48. void CXMButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) 
  49. ASSERT (lpDrawItemStruct); 
  50. //TRACE("* Captured: >08X/n", ::GetCapture()); 
  51. //Check if the button state in not in inconsistent mode... 
  52. POINT mouse_position; 
  53. if ((m_button_down) && (::GetCapture() == m_hWnd) && (::GetCursorPos(&mouse_position))){ 
  54. if (::WindowFromPoint(mouse_position) == m_hWnd){ 
  55. if ((GetState() & BST_PUSHED) != BST_PUSHED) { 
  56. //TRACE("* Inconsistency up detected! Fixing./n"); 
  57. SetState(TRUE); 
  58. return
  59. else { 
  60. if ((GetState() & BST_PUSHED) == BST_PUSHED) { 
  61. //TRACE("* Inconsistency up detected! Fixing./n"); 
  62. SetState(FALSE); 
  63. return
  64. //TRACE("* Drawing: >08x/n", lpDrawItemStruct->itemState); 
  65. CString sCaption; 
  66. CDC *pDC = CDC::FromHandle(lpDrawItemStruct->hDC); // get device context 
  67. RECT r=lpDrawItemStruct->rcItem; // context rectangle 
  68. int cx = r.right - r.left ; // get width 
  69. int cy = r.bottom - r.top ; // get height 
  70. // get text box position 
  71. RECT tr={r.left+m_FocusRectMargin+2,r.top,r.right-m_FocusRectMargin-2,r.bottom}; 
  72. GetWindowText(sCaption); // get button text 
  73. pDC->SetBkMode(TRANSPARENT); 
  74. // Select the correct skin 
  75. if (lpDrawItemStruct->itemState & ODS_DISABLED){ // DISABLED BUTTON 
  76. if(m_bDisabled.m_hObject==NULL) 
  77. // no skin selected for disabled state -> standard button 
  78. pDC->FillSolidRect(&r,GetSysColor(COLOR_BTNFACE)); 
  79. else // paint the skin 
  80. DrawBitmap(pDC,(HBITMAP)m_bDisabled,r,m_DrawMode); 
  81. // if needed, draw the standard 3D rectangular border 
  82. if (m_Border) pDC->DrawEdge(&r,EDGE_RAISED,BF_RECT); 
  83. // paint the etched button text 
  84. pDC->SetTextColor(GetSysColor(COLOR_3DHILIGHT)); 
  85. pDC->DrawText(sCaption,&tr,DT_SINGLELINE|DT_VCENTER|DT_CENTER); 
  86. pDC->SetTextColor(GetSysColor(COLOR_GRAYTEXT)); 
  87. OffsetRect(&tr,-1,-1); 
  88. pDC->DrawText(sCaption,&tr,DT_SINGLELINE|DT_VCENTER|DT_CENTER); 
  89. else { // SELECTED (DOWN) BUTTON 
  90. if ((lpDrawItemStruct->itemState & ODS_SELECTED)||m_Checked){ 
  91. if(m_bDown.m_hObject==NULL) 
  92. // no skin selected for selected state -> standard button 
  93. pDC->FillSolidRect(&r,GetSysColor(COLOR_BTNFACE)); 
  94. else { // paint the skin 
  95. DrawBitmap(pDC,(HBITMAP)m_bDown,r,m_DrawMode); 
  96. OffsetRect(&tr,1,1); //shift text 
  97. // if needed, draw the standard 3D rectangular border 
  98. if (m_Border) pDC->DrawEdge(&r,EDGE_SUNKEN,BF_RECT); 
  99. else { // DEFAULT BUTTON 
  100. if(m_bNormal.m_hObject==NULL) 
  101. // no skin selected for normal state -> standard button 
  102. pDC->FillSolidRect(&r,GetSysColor(COLOR_BTNFACE)); 
  103. else // paint the skin 
  104. if ((m_tracking)&&(m_bOver.m_hObject!=NULL)){ 
  105. DrawBitmap(pDC,(HBITMAP)m_bOver,r,m_DrawMode); 
  106. else { 
  107. if ((lpDrawItemStruct->itemState & ODS_FOCUS)&&(m_bFocus.m_hObject!=NULL)){ 
  108. DrawBitmap(pDC,(HBITMAP)m_bFocus,r,m_DrawMode); 
  109. else { 
  110. DrawBitmap(pDC,(HBITMAP)m_bNormal,r,m_DrawMode); 
  111. // if needed, draw the standard 3D rectangular border 
  112. if (m_Border) pDC->DrawEdge(&r,EDGE_RAISED,BF_RECT); 
  113. // paint the focus rect 
  114. if ((lpDrawItemStruct->itemState & ODS_FOCUS)&&(m_FocusRectMargin>0)){ 
  115. r.left += m_FocusRectMargin ; 
  116. r.top += m_FocusRectMargin ; 
  117. r.right -= m_FocusRectMargin ; 
  118. r.bottom -= m_FocusRectMargin ; 
  119. DrawFocusRect (lpDrawItemStruct->hDC, &r) ; 
  120. // paint the enabled button text 
  121. pDC->SetTextColor(m_TextColor); 
  122. pDC->DrawText(sCaption,&tr,DT_SINGLELINE|DT_VCENTER|DT_CENTER); 
  123. int CXMButton::GetBitmapWidth (HBITMAP hBitmap) 
  124. { BITMAP bm; GetObject(hBitmap,sizeof(BITMAP),(PSTR)&bm); return bm.bmWidth;} 
  125. int CXMButton::GetBitmapHeight (HBITMAP hBitmap) 
  126. { BITMAP bm; GetObject(hBitmap,sizeof(BITMAP),(PSTR)&bm); return bm.bmHeight;} 
  127. void CXMButton::DrawBitmap(CDC* dc, HBITMAP hbmp, RECT r, int DrawMode) 
  128. // DrawMode: 0=Normal; 1=stretch; 2=tiled fill 
  129. if(DrawMode==2){ 
  130. FillWithBitmap(dc,hbmp,r); 
  131. return
  132. if(!hbmp) return//safe check 
  133. int cx=r.right - r.left; 
  134. int cy=r.bottom - r.top; 
  135. CDC dcBmp,dcMask; 
  136. dcBmp.CreateCompatibleDC(dc); 
  137. dcBmp.SelectObject(hbmp); 
  138. if (m_bMask.m_hObject!=NULL){ 
  139. dcMask.CreateCompatibleDC(dc); 
  140. dcMask.SelectObject(m_bMask); 
  141. CDC hdcMem; 
  142. hdcMem.CreateCompatibleDC(dc); 
  143. CBitmap hBitmap; 
  144. hBitmap.CreateCompatibleBitmap(dc,cx,cy); 
  145. hdcMem.SelectObject(hBitmap); 
  146. hdcMem.BitBlt(r.left,r.top,cx,cy,dc,0,0,SRCCOPY); 
  147. if(!DrawMode){ 
  148. hdcMem.BitBlt(r.left,r.top,cx,cy,&dcBmp,0,0,SRCINVERT); 
  149. hdcMem.BitBlt(r.left,r.top,cx,cy,&dcMask,0,0,SRCAND); 
  150. hdcMem.BitBlt(r.left,r.top,cx,cy,&dcBmp,0,0,SRCINVERT); 
  151. else { 
  152. int bx=GetBitmapWidth(hbmp); 
  153. int by=GetBitmapHeight(hbmp); 
  154. hdcMem.StretchBlt(r.left,r.top,cx,cy,&dcBmp,0,0,bx,by,SRCINVERT); 
  155. hdcMem.StretchBlt(r.left,r.top,cx,cy,&dcMask,0,0,bx,by,SRCAND); 
  156. hdcMem.StretchBlt(r.left,r.top,cx,cy,&dcBmp,0,0,bx,by,SRCINVERT); 
  157. dc->BitBlt(r.left,r.top,cx,cy,&hdcMem,0,0,SRCCOPY); 
  158. hdcMem.DeleteDC(); 
  159. hBitmap.DeleteObject(); 
  160. DeleteDC(dcMask); 
  161. else { 
  162. if(!DrawMode){ 
  163. dc->BitBlt(r.left,r.top,cx,cy,&dcBmp,0,0,SRCCOPY); 
  164. else { 
  165. int bx=GetBitmapWidth(hbmp); 
  166. int by=GetBitmapHeight(hbmp); 
  167. dc->StretchBlt(r.left,r.top,cx,cy,&dcBmp,0,0,bx,by,SRCCOPY); 
  168. DeleteDC(dcBmp); 
  169. void CXMButton::FillWithBitmap(CDC* dc, HBITMAP hbmp, RECT r) 
  170. if(!hbmp) return
  171. CDC memdc; 
  172. memdc.CreateCompatibleDC(dc); 
  173. memdc.SelectObject(hbmp); 
  174. int w = r.right - r.left; 
  175. int h = r.bottom - r.top; 
  176. int x,y,z; 
  177. int bx=GetBitmapWidth(hbmp); 
  178. int by=GetBitmapHeight(hbmp); 
  179. for (y = r.top ; y < h ; y += by){ 
  180. if ((y+by)>h) by=h-y; 
  181. z=bx; 
  182. for (x = r.left ; x < w ; x += z){ 
  183. if ((x+z)>w) z=w-x; 
  184. dc->BitBlt(x, y, z, by, &memdc, 0, 0, SRCCOPY); 
  185. DeleteDC(memdc); 
  186. void CXMButton::SetSkin(UINT normal,UINT down,UINT over,UINT disabled, UINT focus,UINT mask, 
  187. short drawmode, short border, short margin) 
  188. m_bNormal.DeleteObject(); //free previous allocated bitmap 
  189. m_bDown.DeleteObject(); 
  190. m_bOver.DeleteObject(); 
  191. m_bDisabled.DeleteObject(); 
  192. m_bMask.DeleteObject(); 
  193. m_bFocus.DeleteObject(); 
  194. if (normal>0) m_bNormal.LoadBitmap(normal); 
  195. if (down>0) m_bDown.LoadBitmap(down); 
  196. if (over>0) m_bOver.LoadBitmap(over); 
  197. if (focus>0) m_bFocus.LoadBitmap(focus); 
  198. if (disabled>0) m_bDisabled.LoadBitmap(disabled); 
  199. else if (normal>0) m_bDisabled.LoadBitmap(normal); 
  200. m_DrawMode=max(0,min(drawmode,2)); 
  201. m_Border=border; 
  202. m_FocusRectMargin=max(0,margin); 
  203. if (mask>0){ 
  204. m_bMask.LoadBitmap(mask); 
  205. if (hClipRgn) DeleteObject(hClipRgn); 
  206. hClipRgn = CreateRgnFromBitmap(m_bMask,RGB(255,255,255)); 
  207. if (hClipRgn){ 
  208. SetWindowRgn(hClipRgn, TRUE); 
  209. SelectClipRgn((HDC)GetDC(),hClipRgn); 
  210. if (m_DrawMode==0){ 
  211. SetWindowPos(NULL,0,0,GetBitmapWidth(m_bMask), 
  212. GetBitmapHeight(m_bMask),SWP_NOZORDER|SWP_NOMOVE); 
  213. HRGN CXMButton::CreateRgnFromBitmap(HBITMAP hBmp, COLORREF color) 
  214. if (!hBmp) return NULL; 
  215. BITMAP bm; 
  216. GetObject( hBmp, sizeof(BITMAP), &bm ); // get bitmap attributes 
  217. CDC dcBmp; 
  218. dcBmp.CreateCompatibleDC(GetDC()); //Creates a memory device context for the bitmap 
  219. dcBmp.SelectObject(hBmp); //selects the bitmap in the device context 
  220. const DWORD RDHDR = sizeof(RGNDATAHEADER); 
  221. const DWORD MAXBUF = 40; // size of one block in RECTs 
  222. // (i.e. MAXBUF*sizeof(RECT) in bytes) 
  223. LPRECT pRects; 
  224. DWORD cBlocks = 0; // number of allocated blocks 
  225. INT i, j; // current position in mask image 
  226. INT first = 0; // left position of current scan line 
  227. // where mask was found 
  228. bool wasfirst = false// set when if mask was found in current scan line 
  229. bool ismask; // set when current color is mask color 
  230. // allocate memory for region data 
  231. RGNDATAHEADER* pRgnData = (RGNDATAHEADER*)new BYTE[ RDHDR + ++cBlocks * MAXBUF * sizeof(RECT) ]; 
  232. memset( pRgnData, 0, RDHDR + cBlocks * MAXBUF * sizeof(RECT) ); 
  233. // fill it by default 
  234. pRgnData->dwSize = RDHDR; 
  235. pRgnData->iType = RDH_RECTANGLES; 
  236. pRgnData->nCount = 0; 
  237. for ( i = 0; i < bm.bmHeight; i++ ) 
  238. for ( j = 0; j < bm.bmWidth; j++ ){ 
  239. // get color 
  240. ismask=(dcBmp.GetPixel(j,bm.bmHeight-i-1)!=color); 
  241. // place part of scan line as RECT region if transparent color found after mask color or 
  242. // mask color found at the end of mask image 
  243. if (wasfirst && ((ismask && (j==(bm.bmWidth-1)))||(ismask ^ (j<bm.bmWidth)))){ 
  244. // get offset to RECT array if RGNDATA buffer 
  245. pRects = (LPRECT)((LPBYTE)pRgnData + RDHDR); 
  246. // save current RECT 
  247. pRects[ pRgnData->nCount++ ] = CRect( first, bm.bmHeight - i - 1, j+(j==(bm.bmWidth-1)), bm.bmHeight - i ); 
  248. // if buffer full reallocate it 
  249. if ( pRgnData->nCount >= cBlocks * MAXBUF ){ 
  250. LPBYTE pRgnDataNew = new BYTE[ RDHDR + ++cBlocks * MAXBUF * sizeof(RECT) ]; 
  251. memcpy( pRgnDataNew, pRgnData, RDHDR + (cBlocks - 1) * MAXBUF * sizeof(RECT) ); 
  252. delete pRgnData; 
  253. pRgnData = (RGNDATAHEADER*)pRgnDataNew; 
  254. wasfirst = false
  255. else if ( !wasfirst && ismask ){ // set wasfirst when mask is found 
  256. first = j; 
  257. wasfirst = true
  258. dcBmp.DeleteDC(); //release the bitmap 
  259. // create region 
  260. /* Under WinNT the ExtCreateRegion returns NULL (by Fable@aramszu.net) */ 
  261. // HRGN hRgn = ExtCreateRegion( NULL, RDHDR + pRgnData->nCount * sizeof(RECT), (LPRGNDATA)pRgnData ); 
  262. /* ExtCreateRegion replacement { */ 
  263. HRGN hRgn=CreateRectRgn(0, 0, 0, 0); 
  264. ASSERT( hRgn!=NULL ); 
  265. pRects = (LPRECT)((LPBYTE)pRgnData + RDHDR); 
  266. for(i=0;i<(int)pRgnData->nCount;i++) 
  267. HRGN hr=CreateRectRgn(pRects[i].left, pRects[i].top, pRects[i].right, pRects[i].bottom); 
  268. VERIFY(CombineRgn(hRgn, hRgn, hr, RGN_OR)!=ERROR); 
  269. if (hr) DeleteObject(hr); 
  270. ASSERT( hRgn!=NULL ); 
  271. /* } ExtCreateRegion replacement */ 
  272. delete pRgnData; 
  273. return hRgn; 
  274. COLORREF CXMButton::SetTextColor(COLORREF new_color) 
  275. COLORREF tmp_color=m_TextColor; 
  276. m_TextColor=new_color; 
  277. return tmp_color; //returns the previous color 
  278. void CXMButton::SetToolTipText(CString s) 
  279. if(m_tooltip.m_hWnd==NULL){ 
  280. if(m_tooltip.Create(this)) //first assignment 
  281. if(m_tooltip.AddTool(this, (LPCTSTR)s)) 
  282. m_tooltip.Activate(1); 
  283. else { 
  284. m_tooltip.UpdateTipText((LPCTSTR)s,this); 
  285. void CXMButton::RelayEvent(UINT message, WPARAM wParam, LPARAM lParam) 
  286. // This function will create a MSG structure, fill it in a pass it to 
  287. // the ToolTip control, m_ttip. Note that we ensure the point is in window 
  288. // coordinates (relative to the control's window). 
  289. if(NULL != m_tooltip.m_hWnd){ 
  290. MSG msg; 
  291. msg.hwnd = m_hWnd; 
  292. msg.message = message; 
  293. msg.wParam = wParam; 
  294. msg.lParam = lParam; 
  295. msg.time = 0; 
  296. msg.pt.x = LOWORD(lParam); 
  297. msg.pt.y = HIWORD(lParam); 
  298. m_tooltip.RelayEvent(&msg); 
  299. // 
  300. //Method......: OnLButtonDblClk 
  301. //Class.......: CxSkinButton 
  302. // 
  303. //Author......: Milan Gardian 
  304. //Created.....: MAR-2001 
  305. // 
  306. //Return value: NONE 
  307. //Parameters..: Used only to be forwarded as WM_LBUTTONDOWN message parameters 
  308. //Exceptions..: NONE 
  309. //------------ 
  310. //Description : 
  311. // 
  312. // > We do not care about doublelicks - handle this event 
  313. // like an ordinary left-button-down event 
  314. // 
  315. //--------------------------------------------------------- 
  316. void CXMButton::OnLButtonDblClk(UINT flags, CPoint point) 
  317. SendMessage(WM_LBUTTONDOWN, flags, MAKELPARAM(point.x, point.y)); 
  318. // 
  319. //Method......: OnLButtonDown 
  320. //Class.......: CxSkinButton 
  321. // 
  322. //Author......: Milan Gardian 
  323. //Created.....: MAR-2001 
  324. // 
  325. //Return value: NONE 
  326. //Parameters..: As follows 
  327. // > [in] nFlags: not used 
  328. // > [in] point: coordinates of the mouse pointer when this event was spawned 
  329. //Exceptions..: NONE 
  330. //------------ 
  331. //Description : 
  332. // 
  333. // > Handle event when left button is pressed down 
  334. // 
  335. //--------------------------------------------------------- 
  336. void CXMButton::OnLButtonDown(UINT nFlags, CPoint point) 
  337. //TRACE("* >08X: down/n", ::GetTickCount()); 
  338. //Pass this message to the ToolTip control 
  339. RelayEvent(WM_LBUTTONDOWN,(WPARAM)nFlags,MAKELPARAM(LOWORD(point.x),LOWORD(point.y))); 
  340. //If we are tracking this button, cancel it 
  341. if (m_tracking) { 
  342. TRACKMOUSEEVENT t = { 
  343. sizeof(TRACKMOUSEEVENT), 
  344. TME_CANCEL | TME_LEAVE, 
  345. m_hWnd, 
  346. }; 
  347. if (::_TrackMouseEvent(&t)) { 
  348. m_tracking = false
  349. //Default-process the message 
  350. CButton::OnLButtonDown(nFlags, point); 
  351. m_button_down = true
  352. // 
  353. //Method......: OnLButtonUp 
  354. //Class.......: CxSkinButton 
  355. // 
  356. //Author......: Milan Gardian 
  357. //Created.....: MAR-2001 
  358. // 
  359. //Return value: NONE 
  360. //Parameters..: As follows 
  361. // > [in] nFlags: not used 
  362. // > [in] point: coordinates of the mouse pointer when this event was spawned 
  363. //Exceptions..: NONE 
  364. //------------ 
  365. //Description : 
  366. // 
  367. // > Handle event when left button is released (goes up) 
  368. // 
  369. //--------------------------------------------------------- 
  370. void CXMButton::OnLButtonUp(UINT nFlags, CPoint point) 
  371. //TRACE("* >08X: up/n", ::GetTickCount()); 
  372. if (m_Style){ //track mouse for radio & check buttons 
  373. POINT p2 = point; 
  374. ::ClientToScreen(m_hWnd, &p2); 
  375. HWND mouse_wnd = ::WindowFromPoint(p2); 
  376. if (mouse_wnd == m_hWnd){ // mouse is in button 
  377. if (m_Style==BS_CHECKBOX) SetCheck(m_Checked ? 0 : 1); 
  378. if (m_Style==BS_RADIOBUTTON) SetCheck(1); 
  379. //Pass this message to the ToolTip control 
  380. RelayEvent(WM_LBUTTONUP,(WPARAM)nFlags,MAKELPARAM(LOWORD(point.x),LOWORD(point.y))); 
  381. //Default-process the message 
  382. m_button_down = false
  383. CButton::OnLButtonUp(nFlags, point); 
  384. // 
  385. //Method......: OnMouseMove 
  386. //Class.......: CxSkinButton 
  387. // 
  388. //Author......: Milan Gardian 
  389. //Created.....: MAR-2001 
  390. // 
  391. //Return value: NONE 
  392. //Parameters..: As follows 
  393. // > [in] nFlags: not used 
  394. // > [in] point: coordinates of the mouse pointer when this event was spawned 
  395. //Exceptions..: NONE 
  396. //------------ 
  397. //Description : 
  398. // 
  399. // > Handle change of mouse position: see the comments in the 
  400. // method for further info. 
  401. // 
  402. //--------------------------------------------------------- 
  403. void CXMButton::OnMouseMove(UINT nFlags, CPoint point) 
  404. //TRACE("* >08X: Mouse/n", ::GetTickCount()); 
  405. //Pass this message to the ToolTip control 
  406. RelayEvent(WM_MOUSEMOVE,(WPARAM)nFlags,MAKELPARAM(LOWORD(point.x),LOWORD(point.y))); 
  407. //If we are in capture mode, button has been pressed down 
  408. //recently and not yet released - therefore check is we are 
  409. //actually over the button or somewhere else. If the mouse 
  410. //position changed considerably (e.g. we moved mouse pointer 
  411. //from the button to some other place outside button area) 
  412. //force the control to redraw 
  413. // 
  414. if ((m_button_down) && (::GetCapture() == m_hWnd)) { 
  415. POINT p2 = point; 
  416. ::ClientToScreen(m_hWnd, &p2); 
  417. HWND mouse_wnd = ::WindowFromPoint(p2); 
  418. bool pressed = ((GetState() & BST_PUSHED) == BST_PUSHED); 
  419. bool need_pressed = (mouse_wnd == m_hWnd); 
  420. if (pressed != need_pressed) { 
  421. //TRACE("* >08X Redraw/n", GetTickCount()); 
  422. SetState(need_pressed ? TRUE : FALSE); 
  423. Invalidate(); 
  424. else { 
  425. //Otherwise the button is released. That means we should 
  426. //know when we leave its area - and so if we are not tracking 
  427. //this mouse leave event yet, start now! 
  428. // 
  429. if (!m_tracking) { 
  430. TRACKMOUSEEVENT t = { 
  431. sizeof(TRACKMOUSEEVENT), 
  432. TME_LEAVE, 
  433. m_hWnd, 
  434. }; 
  435. if (::_TrackMouseEvent(&t)) { 
  436. //TRACE("* Mouse enter/n"); 
  437. m_tracking = true
  438. Invalidate(); 
  439. //Forward this event to superclass 
  440. CButton::OnMouseMove(nFlags, point); 
  441. // 
  442. //Method......: OnMouseLeave 
  443. //Class.......: CxSkinButton 
  444. // 
  445. //Author......: Milan Gardian 
  446. //Created.....: MAR-2001 
  447. // 
  448. //Return value: NULL 
  449. //Parameters..: NOT USED 
  450. //Exceptions..: NONE 
  451. //------------ 
  452. //Description : 
  453. // 
  454. // > Handle situation when mouse cursor leaves area of this 
  455. // window (button). This event might be generated ONLY 
  456. // if we explicitely call 'TrackMouseEvent'. This is 
  457. // signalled by setting the m_tracking flag (see the assert 
  458. // precondition) - in 'OnMouseMove' method 
  459. // 
  460. // > When a mouse pointer leaves area of this button (i.e. 
  461. // when this method is invoked), presumably the look of 
  462. // the button changes (e.g. when hover/non-hover images are set) 
  463. // and therefore we force the control to redraw. 
  464. // 
  465. //--------------------------------------------------------- 
  466. LRESULT CXMButton::OnMouseLeave(WPARAMLPARAM
  467. ASSERT (m_tracking); 
  468. //TRACE("* Mouse leave/n"); 
  469. m_tracking = false
  470. Invalidate(); 
  471. return 0; 
  472. // 
  473. //Method......: OnKillFocus 
  474. //Class.......: CxSkinButton 
  475. // 
  476. //Author......: Milan Gardian 
  477. //Created.....: MAR-2001 
  478. // 
  479. //Return value: NONE 
  480. //Parameters..: See superclass documentation 
  481. //Exceptions..: NONE 
  482. //------------ 
  483. //Description : 
  484. // 
  485. // > If focus is killed during capture, we may no longer 
  486. // have the exclusive access to user input and therefore 
  487. // release it. 
  488. // 
  489. // > Such a situation might happens when the user left-clicks 
  490. // this button, keeps the button down and simultaneously 
  491. // presses TAB key. 
  492. // 
  493. //--------------------------------------------------------- 
  494. void CXMButton::OnKillFocus(CWnd *new_wnd) 
  495. if (::GetCapture() == m_hWnd) { 
  496. ::ReleaseCapture(); 
  497. ASSERT (!m_tracking); 
  498. m_button_down = false
  499. CButton::OnKillFocus(new_wnd); 
  500. // 
  501. //Method......: OnClicked 
  502. //Class.......: CxSkinButton 
  503. // 
  504. //Author......: Milan Gardian 
  505. //Created.....: MAR-2001 
  506. // 
  507. //Return value: FALSE (do not stop in this handler - forward to parent) 
  508. //Parameters..: NONE 
  509. //Exceptions..: NONE 
  510. //------------ 
  511. //Description : 
  512. // 
  513. // > Keep consistency of attributes of this instance before 
  514. // submitting click event to the parent. 
  515. // 
  516. // > Currently NOT used. To use, umcomment line 
  517. // "ON_CONTROL_REFLECT_EX(BN_CLICKED, OnClicked)" in message map 
  518. // at the beginning of this file. 
  519. // 
  520. //--------------------------------------------------------- 
  521. BOOL CXMButton::OnClicked() 
  522. if (::GetCapture() == m_hWnd) { 
  523. ::ReleaseCapture(); 
  524. ASSERT (!m_tracking); 
  525. m_button_down = false
  526. //Invalidate(); 
  527. return FALSE; 
  528. // 
  529. //Method......: OnRadioInfo 
  530. //Class.......: CxSkinButton 
  531. // 
  532. //Author......: Rainer Mangold 
  533. //Created.....: JUN-2001 
  534. // 
  535. //Return value: NULL 
  536. //Parameters..: WPARAM and LPARAM (LPARAM not used) 
  537. //Exceptions..: NONE 
  538. //------------ 
  539. //Description : 
  540. // 
  541. // > Handle notification, that a Button in the same group was pushed 
  542. // 
  543. //--------------------------------------------------------- 
  544. LRESULT CXMButton::OnRadioInfo(WPARAM wparam, LPARAM
  545. if (m_Checked){ //only checked buttons need to be unchecked 
  546. m_Checked = false
  547. Invalidate(); 
  548. return 0; 
  549. void CXMButton::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
  550. if ((m_Style)&&(nChar==' ')){ //needed stuff for check & radio buttons 
  551. if (m_Style==BS_CHECKBOX) SetCheck(m_Checked ? 0 : 1); 
  552. if (m_Style==BS_RADIOBUTTON) SetCheck(1); 
  553. CButton::OnKeyDown(nChar, nRepCnt, nFlags); 
  554. // 
  555. //Method......: SetCheck 
  556. //Class.......: CxSkinButton 
  557. // 
  558. //Author......: Rainer Mangold 
  559. //Created.....: JUN-2001 
  560. // 
  561. //Return value: NONE 
  562. //Parameters..: bool 
  563. //Exceptions..: NONE 
  564. //------------ 
  565. //Description : 
  566. // 
  567. // > Set the state of this button (pushed or not). 
  568. // Works for both, Radio and CheckBox - Buttons 
  569. // 
  570. //--------------------------------------------------------- 
  571. LRESULT CXMButton::OnBMSetCheck(WPARAM wparam, LPARAM
  572. m_Checked=wparam!=0; 
  573. switch (m_Style) 
  574. case BS_RADIOBUTTON: 
  575. if (m_Checked) { //uncheck the other radio buttons (in the same group) 
  576. HWND hthis,hwnd2,hpwnd; 
  577. hpwnd=GetParent()->GetSafeHwnd(); //get button parent handle 
  578. hwnd2=hthis=GetSafeHwnd(); //get this button handle 
  579. if (hthis && hpwnd){ //consistency check 
  580. for( ; ; ){ //scan the buttons within the group 
  581. hwnd2=::GetNextDlgGroupItem(hpwnd,hwnd2,0); 
  582. //until we reach again this button 
  583. if ((hwnd2==hthis)||(hwnd2==NULL)) break
  584. //post the uncheck message 
  585. ::PostMessage(hwnd2, WM_CXSHADE_RADIO, 0, 0); 
  586. break
  587. case BS_PUSHBUTTON: 
  588. m_Checked=false
  589. ASSERT(false); // Must be a Check or Radio button to use this function 
  590. Invalidate(); 
  591. return 0; 
  592. LRESULT CXMButton::OnBMGetCheck(WPARAM wparam, LPARAM
  593. return m_Checked; } //returns the state for check & radio buttons 
  594. //EOF 

 

m_Btncustom.SetSkin(IDB_BITMAP1,IDB_BITMAP3,IDB_BITMAP4,0,0,0,1,0,4);
 m_Btncustom.SetToolTipText("喜木自定义按扭");
 m_Btncustom.SetTextColor(RGB(255,255,255));

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值