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

你可能感兴趣的:(File,null,button,border,RadioButton,styles)