BtnST.cpp 50 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930
  1. #include "stdafx.h"
  2. #include "BtnST.h"
  3. // Download by http://www.codefans.net
  4. #ifdef _DEBUG
  5. #define new DEBUG_NEW
  6. #undef THIS_FILE
  7. static char THIS_FILE[] = __FILE__;
  8. #endif
  9. /////////////////////////////////////////////////////////////////////////////
  10. // CButtonST
  11. // Mask for control's type
  12. #define BS_TYPEMASK SS_TYPEMASK
  13. CButtonST::CButtonST()
  14. {
  15. m_bIsPressed = FALSE;
  16. m_bIsFocused = FALSE;
  17. m_bIsDisabled = FALSE;
  18. m_bMouseOnButton = FALSE;
  19. FreeResources(FALSE);
  20. // Default type is "flat" button
  21. m_bIsFlat = TRUE;
  22. // Button will be tracked also if when the window is inactive (like Internet Explorer)
  23. m_bAlwaysTrack = TRUE;
  24. // By default draw border in "flat" button
  25. m_bDrawBorder = TRUE;
  26. // By default icon is aligned horizontally
  27. m_byAlign = ST_ALIGN_HORIZ;
  28. // By default, for "flat" button, don't draw the focus rect
  29. m_bDrawFlatFocus = FALSE;
  30. // By default the button is not the default button
  31. m_bIsDefault = FALSE;
  32. // Invalid value, since type still unknown
  33. m_nTypeStyle = BS_TYPEMASK;
  34. // By default the button is not a checkbox
  35. m_bIsCheckBox = FALSE;
  36. m_nCheck = 0;
  37. // Set default colors
  38. SetDefaultColors(FALSE);
  39. // No tooltip created
  40. m_ToolTip.m_hWnd = NULL;
  41. // Do not draw as a transparent button
  42. m_bDrawTransparent = FALSE;
  43. m_pbmpOldBk = NULL;
  44. // No URL defined
  45. SetURL(NULL);
  46. // No cursor defined
  47. m_hCursor = NULL;
  48. m_nIsChoose = -1;
  49. // No associated menu
  50. #ifndef BTNST_USE_BCMENU
  51. m_hMenu = NULL;
  52. #endif
  53. m_hParentWndMenu = NULL;
  54. m_bMenuDisplayed = FALSE;
  55. m_bShowDisabledBitmap = TRUE;
  56. } // End of CButtonST
  57. CButtonST::~CButtonST()
  58. {
  59. // Restore old bitmap (if any)
  60. if (m_dcBk.m_hDC && m_pbmpOldBk)
  61. {
  62. m_dcBk.SelectObject(m_pbmpOldBk);
  63. } // if
  64. FreeResources();
  65. // Destroy the cursor (if any)
  66. if (m_hCursor) ::DestroyCursor(m_hCursor);
  67. // Destroy the menu (if any)
  68. #ifdef BTNST_USE_BCMENU
  69. if (m_menuPopup.m_hMenu) m_menuPopup.DestroyMenu();
  70. #else
  71. if (m_hMenu) ::DestroyMenu(m_hMenu);
  72. #endif
  73. } // End of ~CButtonST
  74. BEGIN_MESSAGE_MAP(CButtonST, CButton)
  75. //{{AFX_MSG_MAP(CButtonST)
  76. ON_WM_SETCURSOR()
  77. ON_WM_KILLFOCUS()
  78. ON_WM_MOUSEMOVE()
  79. ON_WM_SYSCOLORCHANGE()
  80. ON_CONTROL_REFLECT_EX(BN_CLICKED, OnClicked)
  81. ON_WM_ACTIVATE()
  82. ON_WM_ENABLE()
  83. ON_WM_CANCELMODE()
  84. ON_WM_GETDLGCODE()
  85. ON_WM_CTLCOLOR_REFLECT()
  86. //}}AFX_MSG_MAP
  87. #ifdef BTNST_USE_BCMENU
  88. ON_WM_MENUCHAR()
  89. ON_WM_MEASUREITEM()
  90. #endif
  91. ON_MESSAGE(BM_SETSTYLE, OnSetStyle)
  92. ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave)
  93. ON_MESSAGE(BM_SETCHECK, OnSetCheck)
  94. ON_MESSAGE(BM_GETCHECK, OnGetCheck)
  95. END_MESSAGE_MAP()
  96. void CButtonST::FreeResources(BOOL bCheckForNULL)
  97. {
  98. if (bCheckForNULL)
  99. {
  100. // Destroy icons
  101. // Note: the following two lines MUST be here! even if
  102. // BoundChecker says they are unnecessary!
  103. if (m_csIcons[0].hIcon) ::DestroyIcon(m_csIcons[0].hIcon);
  104. if (m_csIcons[1].hIcon) ::DestroyIcon(m_csIcons[1].hIcon);
  105. // Destroy bitmaps
  106. if (m_csBitmaps[0].hBitmap) ::DeleteObject(m_csBitmaps[0].hBitmap);
  107. if (m_csBitmaps[1].hBitmap) ::DeleteObject(m_csBitmaps[1].hBitmap);
  108. // Destroy mask bitmaps
  109. if (m_csBitmaps[0].hMask) ::DeleteObject(m_csBitmaps[0].hMask);
  110. if (m_csBitmaps[1].hMask) ::DeleteObject(m_csBitmaps[1].hMask);
  111. } // if
  112. ::ZeroMemory(&m_csIcons, sizeof(m_csIcons));
  113. ::ZeroMemory(&m_csBitmaps, sizeof(m_csBitmaps));
  114. } // End of FreeResources
  115. void CButtonST::PreSubclassWindow()
  116. {
  117. UINT nBS;
  118. nBS = GetButtonStyle();
  119. // Set initial control type
  120. m_nTypeStyle = nBS & BS_TYPEMASK;
  121. // Check if this is a checkbox
  122. if (nBS & BS_CHECKBOX) m_bIsCheckBox = TRUE;
  123. // Set initial default state flag
  124. if (m_nTypeStyle == BS_DEFPUSHBUTTON)
  125. {
  126. // Set default state for a default button
  127. m_bIsDefault = TRUE;
  128. // Adjust style for default button
  129. m_nTypeStyle = BS_PUSHBUTTON;
  130. } // If
  131. // You should not set the Owner Draw before this call
  132. // (don't use the resource editor "Owner Draw" or
  133. // ModifyStyle(0, BS_OWNERDRAW) before calling PreSubclassWindow() )
  134. ASSERT(m_nTypeStyle != BS_OWNERDRAW);
  135. // Switch to owner-draw
  136. ModifyStyle(BS_TYPEMASK, BS_OWNERDRAW, SWP_FRAMECHANGED);
  137. CButton::PreSubclassWindow();
  138. } // End of PreSubclassWindow
  139. UINT CButtonST::OnGetDlgCode()
  140. {
  141. UINT nCode = CButton::OnGetDlgCode();
  142. // Tell the system if we want default state handling
  143. // (losing default state always allowed)
  144. nCode |= (m_bIsDefault ? DLGC_DEFPUSHBUTTON : DLGC_UNDEFPUSHBUTTON);
  145. return nCode;
  146. } // End of OnGetDlgCode
  147. BOOL CButtonST::PreTranslateMessage(MSG* pMsg)
  148. {
  149. InitToolTip();
  150. m_ToolTip.RelayEvent(pMsg);
  151. return CButton::PreTranslateMessage(pMsg);
  152. } // End of PreTranslateMessage
  153. LRESULT CButtonST::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam)
  154. {
  155. if (message == WM_LBUTTONDBLCLK)
  156. {
  157. message = WM_LBUTTONDOWN;
  158. } // if
  159. /*
  160. switch (message)
  161. {
  162. case WM_LBUTTONDBLCLK:
  163. message = WM_LBUTTONDOWN;
  164. break;
  165. case WM_MOVE:
  166. CRect rect;
  167. GetClientRect(&rect);
  168. if (::IsWindow(m_ToolTip.m_hWnd))
  169. {
  170. if (m_ToolTip.GetToolCount() != 0)
  171. m_ToolTip.SetToolRect(this, 1, &rect);
  172. } // if
  173. break;
  174. } // switch
  175. */
  176. return CButton::DefWindowProc(message, wParam, lParam);
  177. } // End of DefWindowProc
  178. HBRUSH CButtonST::CtlColor(CDC* pDC, UINT nCtlColor)
  179. {
  180. return (HBRUSH)::GetStockObject(NULL_BRUSH);
  181. } // End of CtlColor
  182. void CButtonST::OnSysColorChange()
  183. {
  184. CButton::OnSysColorChange();
  185. m_dcBk.DeleteDC();
  186. m_bmpBk.DeleteObject();
  187. } // End of OnSysColorChange
  188. LRESULT CButtonST::OnSetStyle(WPARAM wParam, LPARAM lParam)
  189. {
  190. UINT nNewType = (wParam & BS_TYPEMASK);
  191. // Update default state flag
  192. if (nNewType == BS_DEFPUSHBUTTON)
  193. {
  194. m_bIsDefault = TRUE;
  195. } // if
  196. else if (nNewType == BS_PUSHBUTTON)
  197. {
  198. // Losing default state always allowed
  199. m_bIsDefault = FALSE;
  200. } // if
  201. // Can't change control type after owner-draw is set.
  202. // Let the system process changes to other style bits
  203. // and redrawing, while keeping owner-draw style
  204. return DefWindowProc(BM_SETSTYLE,
  205. (wParam & ~BS_TYPEMASK) | BS_OWNERDRAW, lParam);
  206. } // End of OnSetStyle
  207. LRESULT CButtonST::OnSetCheck(WPARAM wParam, LPARAM lParam)
  208. {
  209. ASSERT(m_bIsCheckBox);
  210. switch (wParam)
  211. {
  212. case BST_CHECKED:
  213. case BST_INDETERMINATE: // Indeterminate state is handled like checked state
  214. SetCheck(1);
  215. break;
  216. default:
  217. SetCheck(0);
  218. break;
  219. } // switch
  220. return 0;
  221. } // End of OnSetCheck
  222. LRESULT CButtonST::OnGetCheck(WPARAM wParam, LPARAM lParam)
  223. {
  224. ASSERT(m_bIsCheckBox);
  225. return GetCheck();
  226. } // End of OnGetCheck
  227. #ifdef BTNST_USE_BCMENU
  228. LRESULT CButtonST::OnMenuChar(UINT nChar, UINT nFlags, CMenu* pMenu)
  229. {
  230. LRESULT lResult;
  231. if (BCMenu::IsMenu(pMenu))
  232. lResult = BCMenu::FindKeyboardShortcut(nChar, nFlags, pMenu);
  233. else
  234. lResult = CButton::OnMenuChar(nChar, nFlags, pMenu);
  235. return lResult;
  236. } // End of OnMenuChar
  237. #endif
  238. #ifdef BTNST_USE_BCMENU
  239. void CButtonST::OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct)
  240. {
  241. BOOL bSetFlag = FALSE;
  242. if (lpMeasureItemStruct->CtlType == ODT_MENU)
  243. {
  244. if (IsMenu((HMENU)lpMeasureItemStruct->itemID) && BCMenu::IsMenu((HMENU)lpMeasureItemStruct->itemID))
  245. {
  246. m_menuPopup.MeasureItem(lpMeasureItemStruct);
  247. bSetFlag = TRUE;
  248. } // if
  249. } // if
  250. if (!bSetFlag) CButton::OnMeasureItem(nIDCtl, lpMeasureItemStruct);
  251. } // End of OnMeasureItem
  252. #endif
  253. void CButtonST::OnEnable(BOOL bEnable)
  254. {
  255. CButton::OnEnable(bEnable);
  256. if (bEnable == FALSE)
  257. {
  258. CWnd* pWnd = GetParent()->GetNextDlgTabItem(this);
  259. if (pWnd)
  260. pWnd->SetFocus();
  261. else
  262. GetParent()->SetFocus();
  263. CancelHover();
  264. } // if
  265. } // End of OnEnable
  266. void CButtonST::OnKillFocus(CWnd * pNewWnd)
  267. {
  268. CButton::OnKillFocus(pNewWnd);
  269. CancelHover();
  270. } // End of OnKillFocus
  271. void CButtonST::OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized)
  272. {
  273. CButton::OnActivate(nState, pWndOther, bMinimized);
  274. if (nState == WA_INACTIVE) CancelHover();
  275. } // End of OnActivate
  276. void CButtonST::OnCancelMode()
  277. {
  278. CButton::OnCancelMode();
  279. CancelHover();
  280. } // End of OnCancelMode
  281. BOOL CButtonST::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
  282. {
  283. // If a cursor was specified then use it!
  284. if (m_hCursor != NULL)
  285. {
  286. ::SetCursor(m_hCursor);
  287. return TRUE;
  288. } // if
  289. return CButton::OnSetCursor(pWnd, nHitTest, message);
  290. } // End of OnSetCursor
  291. void CButtonST::CancelHover()
  292. {
  293. // Only for flat buttons
  294. if (m_bIsFlat)
  295. {
  296. if (m_bMouseOnButton)
  297. {
  298. m_bMouseOnButton = FALSE;
  299. Invalidate();
  300. } // if
  301. } // if
  302. } // End of CancelHover
  303. void CButtonST::OnMouseMove(UINT nFlags, CPoint point)
  304. {
  305. //return ;
  306. CWnd* wndUnderMouse = NULL;
  307. CWnd* wndActive = this;
  308. TRACKMOUSEEVENT csTME;
  309. CButton::OnMouseMove(nFlags, point);
  310. ClientToScreen(&point);
  311. wndUnderMouse = WindowFromPoint(point);
  312. // If the mouse enter the button with the left button pressed then do nothing
  313. if (nFlags & MK_LBUTTON && m_bMouseOnButton == FALSE) return;
  314. // If our button is not flat then do nothing
  315. if (m_bIsFlat == FALSE) return;
  316. if (m_bAlwaysTrack == FALSE) wndActive = GetActiveWindow();
  317. if (wndUnderMouse && wndUnderMouse->m_hWnd == m_hWnd && wndActive)
  318. {
  319. if (!m_bMouseOnButton)
  320. {
  321. m_bMouseOnButton = TRUE;
  322. Invalidate();
  323. csTME.cbSize = sizeof(csTME);
  324. csTME.dwFlags = TME_LEAVE;
  325. csTME.hwndTrack = m_hWnd;
  326. ::_TrackMouseEvent(&csTME);
  327. } // if
  328. } else CancelHover();
  329. } // End of OnMouseMove
  330. // Handler for WM_MOUSELEAVE
  331. LRESULT CButtonST::OnMouseLeave(WPARAM wParam, LPARAM lParam)
  332. {
  333. CancelHover();
  334. return 0;
  335. } // End of OnMouseLeave
  336. BOOL CButtonST::OnClicked()
  337. {
  338. SetFocus();
  339. if (m_bIsCheckBox)
  340. {
  341. m_nCheck = !m_nCheck;
  342. Invalidate();
  343. } // if
  344. else
  345. {
  346. // Handle the menu (if any)
  347. #ifdef BTNST_USE_BCMENU
  348. if (m_menuPopup.m_hMenu)
  349. #else
  350. if (m_hMenu)
  351. #endif
  352. {
  353. CRect rWnd;
  354. GetWindowRect(rWnd);
  355. m_bMenuDisplayed = TRUE;
  356. Invalidate();
  357. #ifdef BTNST_USE_BCMENU
  358. BCMenu *psub = (BCMenu*)m_menuPopup.GetSubMenu(0);
  359. DWORD dwRetValue = psub->TrackPopupMenu(TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON | TPM_NONOTIFY | TPM_RETURNCMD, rWnd.left, rWnd.bottom, this, NULL);
  360. #else
  361. HMENU hSubMenu = ::GetSubMenu(m_hMenu, 0);
  362. //DWORD dwRetValue = ::TrackPopupMenuEx(hSubMenu, TPM_LEFTALIGN | TPM_LEFTBUTTON, rWnd.left, rWnd.bottom, m_hParentWndMenu, NULL);
  363. DWORD dwRetValue = ::TrackPopupMenuEx(hSubMenu, TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON | TPM_NONOTIFY | TPM_RETURNCMD, rWnd.left, rWnd.bottom, m_hParentWndMenu, NULL);
  364. #endif
  365. m_bMenuDisplayed = FALSE;
  366. Invalidate();
  367. if (dwRetValue)
  368. ::PostMessage(m_hParentWndMenu, WM_COMMAND, MAKEWPARAM(dwRetValue, 0), (LPARAM)NULL);
  369. } // if
  370. else
  371. {
  372. // Handle the URL (if any)
  373. if (_tcslen(m_szURL) > 0)
  374. {
  375. SHELLEXECUTEINFO csSEI;
  376. memset(&csSEI, 0, sizeof(csSEI));
  377. csSEI.cbSize = sizeof(SHELLEXECUTEINFO);
  378. csSEI.fMask = SEE_MASK_FLAG_NO_UI;
  379. csSEI.lpVerb = _T("open");
  380. csSEI.lpFile = m_szURL;
  381. csSEI.nShow = SW_SHOWMAXIMIZED;
  382. ::ShellExecuteEx(&csSEI);
  383. } // if
  384. } // else
  385. } // else
  386. return FALSE;
  387. } // End of OnClicked
  388. void CButtonST::DrawItem(LPDRAWITEMSTRUCT lpDIS)
  389. {
  390. CDC* pDC = CDC::FromHandle(lpDIS->hDC);
  391. CPen* pOldPen;
  392. // Checkbox?
  393. if (m_bIsCheckBox)
  394. {
  395. m_bIsPressed = (lpDIS->itemState & ODS_SELECTED) || (m_nCheck != 0);
  396. } // if
  397. else // Normal button OR other button style ...
  398. {
  399. m_bIsPressed = (lpDIS->itemState & ODS_SELECTED);
  400. // If there is a menu and it's displayed, draw the button as pressed
  401. if (
  402. #ifdef BTNST_USE_BCMENU
  403. m_menuPopup.m_hMenu
  404. #else
  405. m_hMenu
  406. #endif
  407. && m_bMenuDisplayed) m_bIsPressed = TRUE;
  408. } // else
  409. m_bIsFocused = (lpDIS->itemState & ODS_FOCUS);
  410. m_bIsDisabled = (lpDIS->itemState & ODS_DISABLED);
  411. CRect itemRect = lpDIS->rcItem;
  412. pDC->SetBkMode(TRANSPARENT);
  413. if (m_bIsFlat == FALSE)
  414. {
  415. if (m_bIsFocused || m_bIsDefault)
  416. {
  417. CBrush br(RGB(0,0,0));
  418. pDC->FrameRect(&itemRect, &br);
  419. itemRect.DeflateRect(1, 1);
  420. } // if
  421. } // if
  422. // Prepare draw... paint button background
  423. // Draw transparent?
  424. if (m_bDrawTransparent)
  425. PaintBk(pDC);
  426. else
  427. OnDrawBackground(pDC, &itemRect);
  428. // Draw pressed button
  429. if (m_bIsPressed)
  430. {
  431. if (m_bIsFlat)
  432. {
  433. if (m_bDrawBorder)
  434. OnDrawBorder(pDC, &itemRect);
  435. }
  436. else
  437. {
  438. CBrush brBtnShadow(GetSysColor(COLOR_BTNSHADOW));
  439. pDC->FrameRect(&itemRect, &brBtnShadow);
  440. DeleteObject( brBtnShadow );
  441. }
  442. }
  443. else // ...else draw non pressed button
  444. {
  445. CPen penBtnHiLight(PS_SOLID, 0, GetSysColor(COLOR_BTNHILIGHT)); // White
  446. CPen pen3DLight(PS_SOLID, 0, GetSysColor(COLOR_3DLIGHT)); // Light gray
  447. CPen penBtnShadow(PS_SOLID, 0, GetSysColor(COLOR_BTNSHADOW)); // Dark gray
  448. CPen pen3DDKShadow(PS_SOLID, 0, GetSysColor(COLOR_3DDKSHADOW)); // Black
  449. if (m_bIsFlat)
  450. {
  451. if (m_bMouseOnButton && m_bDrawBorder)
  452. OnDrawBorder(pDC, &itemRect);
  453. }
  454. else
  455. {
  456. // Draw top-left borders
  457. // White line
  458. pOldPen = pDC->SelectObject(&penBtnHiLight);
  459. pDC->MoveTo(itemRect.left, itemRect.bottom-1);
  460. pDC->LineTo(itemRect.left, itemRect.top);
  461. pDC->LineTo(itemRect.right, itemRect.top);
  462. // Light gray line
  463. pDC->SelectObject(pen3DLight);
  464. pDC->MoveTo(itemRect.left+1, itemRect.bottom-1);
  465. pDC->LineTo(itemRect.left+1, itemRect.top+1);
  466. pDC->LineTo(itemRect.right, itemRect.top+1);
  467. // Draw bottom-right borders
  468. // Black line
  469. pDC->SelectObject(pen3DDKShadow);
  470. pDC->MoveTo(itemRect.left, itemRect.bottom-1);
  471. pDC->LineTo(itemRect.right-1, itemRect.bottom-1);
  472. pDC->LineTo(itemRect.right-1, itemRect.top-1);
  473. // Dark gray line
  474. pDC->SelectObject(penBtnShadow);
  475. pDC->MoveTo(itemRect.left+1, itemRect.bottom-2);
  476. pDC->LineTo(itemRect.right-2, itemRect.bottom-2);
  477. pDC->LineTo(itemRect.right-2, itemRect.top);
  478. //
  479. pDC->SelectObject(pOldPen);
  480. } // else
  481. DeleteObject( penBtnHiLight );
  482. DeleteObject( pen3DLight );
  483. DeleteObject( penBtnShadow );
  484. DeleteObject( pen3DDKShadow );
  485. } // else
  486. CFont font1;
  487. font1.CreateFont(25, // nHeight
  488. 0, // nWidth
  489. 0, // nEscapement
  490. 0, // nOrientation
  491. FW_BOLD, // nWeight
  492. false, // bItalic
  493. FALSE, // bUnderline
  494. 0, // cStrikeOut
  495. ANSI_CHARSET, // nCharSet
  496. OUT_DEFAULT_PRECIS, // nOutPrecision
  497. CLIP_DEFAULT_PRECIS, // nClipPrecision
  498. DEFAULT_QUALITY, // nQuality
  499. DEFAULT_PITCH | FF_SWISS, // nPitchAndFamily
  500. _T("ËÎÌå")); // lpszFac
  501. // Read the button's title
  502. CString sTitle;
  503. GetWindowText(sTitle);
  504. pDC->SelectObject( font1 );
  505. CRect captionRect = lpDIS->rcItem;
  506. // Draw the icon
  507. if (m_csIcons[0].hIcon)
  508. {
  509. DrawTheIcon(pDC, !sTitle.IsEmpty(), &lpDIS->rcItem, &captionRect, m_bIsPressed, m_bIsDisabled);
  510. } // if
  511. if (m_csBitmaps[0].hBitmap)
  512. {
  513. pDC->SetBkColor(RGB(255,255,255));
  514. DrawTheBitmap(pDC, !sTitle.IsEmpty(), &lpDIS->rcItem, &captionRect, m_bIsPressed, m_bIsDisabled);
  515. } // if
  516. // Write the button title (if any)
  517. if (sTitle.IsEmpty() == FALSE)
  518. {
  519. // Draw the button's title
  520. // If button is pressed then "press" title also
  521. if (m_bIsPressed && m_bIsCheckBox == FALSE)
  522. captionRect.OffsetRect(1, 1);
  523. // ONLY FOR DEBUG
  524. //CBrush brBtnShadow(RGB(255, 0, 0));
  525. //pDC->FrameRect(&captionRect, &brBtnShadow);
  526. // Center text
  527. CRect centerRect = captionRect;
  528. pDC->DrawText(sTitle, -1, captionRect, DT_WORDBREAK | DT_CENTER | DT_CALCRECT);
  529. captionRect.OffsetRect((centerRect.Width() - captionRect.Width())/2, (centerRect.Height() - captionRect.Height())/2);
  530. /* RFU
  531. captionRect.OffsetRect(0, (centerRect.Height() - captionRect.Height())/2);
  532. captionRect.OffsetRect((centerRect.Width() - captionRect.Width())-4, (centerRect.Height() - captionRect.Height())/2);
  533. */
  534. pDC->SetBkMode(TRANSPARENT);
  535. /*
  536. pDC->DrawState(captionRect.TopLeft(), captionRect.Size(), (LPCTSTR)sTitle, (bIsDisabled ? DSS_DISABLED : DSS_NORMAL),
  537. TRUE, 0, (CBrush*)NULL);
  538. */
  539. if (m_bIsDisabled)
  540. {
  541. captionRect.OffsetRect(1, 1);
  542. pDC->SetTextColor(::GetSysColor(COLOR_3DHILIGHT));
  543. pDC->DrawText(sTitle, -1, captionRect, DT_WORDBREAK | DT_CENTER);
  544. captionRect.OffsetRect(-1, -1);
  545. pDC->SetTextColor(::GetSysColor(COLOR_3DSHADOW));
  546. pDC->DrawText(sTitle, -1, captionRect, DT_WORDBREAK | DT_CENTER);
  547. } // if
  548. else
  549. {
  550. if (m_bMouseOnButton || m_bIsPressed)
  551. {
  552. pDC->SetTextColor(m_crColors[BTNST_COLOR_FG_IN]);
  553. pDC->SetBkColor(m_crColors[BTNST_COLOR_BK_IN]);
  554. } // if
  555. else
  556. {
  557. pDC->SetTextColor(m_crColors[BTNST_COLOR_FG_OUT]);
  558. pDC->SetBkColor(m_crColors[BTNST_COLOR_BK_OUT]);
  559. } // else
  560. if( m_nIsChoose==1 )
  561. pDC->SetTextColor( RGB(255,255,255) );
  562. else if( m_nIsChoose==-1 )
  563. pDC->SetTextColor( RGB(0,0,0) );
  564. pDC->DrawText(sTitle, -1, captionRect, DT_WORDBREAK | DT_CENTER);
  565. } // if
  566. } // if
  567. if (m_bIsFlat == FALSE || (m_bIsFlat && m_bDrawFlatFocus))
  568. {
  569. // Draw the focus rect
  570. if (m_bIsFocused)
  571. {
  572. CRect focusRect = itemRect;
  573. focusRect.DeflateRect(3, 3);
  574. pDC->DrawFocusRect(&focusRect);
  575. } // if
  576. } // if
  577. DeleteObject( pDC );
  578. DeleteObject( font1 );
  579. } // End of DrawItem
  580. void CButtonST::PaintBk(CDC* pDC)
  581. {
  582. CClientDC clDC(GetParent());
  583. CRect rect;
  584. CRect rect1;
  585. GetClientRect(rect);
  586. GetWindowRect(rect1);
  587. GetParent()->ScreenToClient(rect1);
  588. if (m_dcBk.m_hDC == NULL)
  589. {
  590. m_dcBk.CreateCompatibleDC(&clDC);
  591. m_bmpBk.CreateCompatibleBitmap(&clDC, rect.Width(), rect.Height());
  592. m_pbmpOldBk = m_dcBk.SelectObject(&m_bmpBk);
  593. m_dcBk.BitBlt(0, 0, rect.Width(), rect.Height(), &clDC, rect1.left, rect1.top, SRCCOPY);
  594. DeleteObject( m_dcBk );
  595. } // if
  596. pDC->BitBlt(0, 0, rect.Width(), rect.Height(), &m_dcBk, 0, 0, SRCCOPY);
  597. DeleteObject( clDC );
  598. } // End of PaintBk
  599. HBITMAP CButtonST::CreateBitmapMask(HBITMAP hSourceBitmap, DWORD dwWidth, DWORD dwHeight, COLORREF crTransColor)
  600. {
  601. HBITMAP hMask = NULL;
  602. HDC hdcSrc = NULL;
  603. HDC hdcDest = NULL;
  604. HBITMAP hbmSrcT = NULL;
  605. HBITMAP hbmDestT = NULL;
  606. COLORREF crSaveBk;
  607. COLORREF crSaveDestText;
  608. hMask = ::CreateBitmap(dwWidth, dwHeight, 1, 1, NULL);
  609. if (hMask == NULL) return NULL;
  610. hdcSrc = ::CreateCompatibleDC(NULL);
  611. hdcDest = ::CreateCompatibleDC(NULL);
  612. hbmSrcT = (HBITMAP)::SelectObject(hdcSrc, hSourceBitmap);
  613. hbmDestT = (HBITMAP)::SelectObject(hdcDest, hMask);
  614. crSaveBk = ::SetBkColor(hdcSrc, crTransColor);
  615. ::BitBlt(hdcDest, 0, 0, dwWidth, dwHeight, hdcSrc, 0, 0, SRCCOPY);
  616. crSaveDestText = ::SetTextColor(hdcSrc, RGB(255, 255, 255));
  617. ::SetBkColor(hdcSrc,RGB(0, 0, 0));
  618. ::BitBlt(hdcSrc, 0, 0, dwWidth, dwHeight, hdcDest, 0, 0, SRCAND);
  619. SetTextColor(hdcDest, crSaveDestText);
  620. ::SetBkColor(hdcSrc, crSaveBk);
  621. ::SelectObject(hdcSrc, hbmSrcT);
  622. ::SelectObject(hdcDest, hbmDestT);
  623. DeleteObject( hMask );
  624. ::DeleteDC(hdcSrc);
  625. ::DeleteDC(hdcDest);
  626. return hMask;
  627. } // End of CreateBitmapMask
  628. //
  629. // Parameters:
  630. // [IN] bHasTitle
  631. // TRUE if the button has a text
  632. // [IN] rpItem
  633. // A pointer to a RECT structure indicating the allowed paint area
  634. // [IN/OUT]rpTitle
  635. // A pointer to a CRect object indicating the paint area reserved for the
  636. // text. This structure will be modified if necessary.
  637. // [IN] bIsPressed
  638. // TRUE if the button is currently pressed
  639. // [IN] dwWidth
  640. // Width of the image (icon or bitmap)
  641. // [IN] dwHeight
  642. // Height of the image (icon or bitmap)
  643. // [OUT] rpImage
  644. // A pointer to a CRect object that will receive the area available to the image
  645. //
  646. void CButtonST::PrepareImageRect(BOOL bHasTitle, RECT* rpItem, CRect* rpTitle, BOOL bIsPressed, DWORD dwWidth, DWORD dwHeight, CRect* rpImage)
  647. {
  648. CRect rBtn;
  649. rpImage->CopyRect(rpItem);
  650. switch (m_byAlign)
  651. {
  652. case ST_ALIGN_HORIZ:
  653. if (bHasTitle == FALSE)
  654. {
  655. // Center image horizontally
  656. rpImage->left += ((rpImage->Width() - (long)dwWidth)/2);
  657. }
  658. else
  659. {
  660. // Image must be placed just inside the focus rect
  661. rpImage->left += 3;
  662. rpTitle->left += dwWidth + 3;
  663. }
  664. // Center image vertically
  665. rpImage->top += ((rpImage->Height() - (long)dwHeight)/2);
  666. break;
  667. case ST_ALIGN_HORIZ_RIGHT:
  668. GetClientRect(&rBtn);
  669. if (bHasTitle == FALSE)
  670. {
  671. // Center image horizontally
  672. rpImage->left += ((rpImage->Width() - (long)dwWidth)/2);
  673. }
  674. else
  675. {
  676. // Image must be placed just inside the focus rect
  677. rpTitle->right = rpTitle->Width() - dwWidth - 3;
  678. rpTitle->left = 3;
  679. rpImage->left = rBtn.right - dwWidth - 3;
  680. // Center image vertically
  681. rpImage->top += ((rpImage->Height() - (long)dwHeight)/2);
  682. }
  683. break;
  684. case ST_ALIGN_VERT:
  685. // Center image horizontally
  686. rpImage->left += ((rpImage->Width() - (long)dwWidth)/2);
  687. if (bHasTitle == FALSE)
  688. {
  689. // Center image vertically
  690. rpImage->top += ((rpImage->Height() - (long)dwHeight)/2);
  691. }
  692. else
  693. {
  694. rpImage->top = 3;
  695. rpTitle->top += dwHeight;
  696. }
  697. break;
  698. }
  699. // If button is pressed then press image also
  700. if (bIsPressed && m_bIsCheckBox == FALSE)
  701. rpImage->OffsetRect(1, 1);
  702. } // End of PrepareImageRect
  703. void CButtonST::DrawTheIcon(CDC* pDC, BOOL bHasTitle, RECT* rpItem, CRect* rpTitle, BOOL bIsPressed, BOOL bIsDisabled)
  704. {
  705. BYTE byIndex = 0;
  706. // Select the icon to use
  707. if ((m_bIsCheckBox && bIsPressed) || (!m_bIsCheckBox && (bIsPressed || m_bMouseOnButton)))
  708. byIndex = 0;
  709. else
  710. byIndex = (m_csIcons[1].hIcon == NULL ? 0 : 1);
  711. CRect rImage;
  712. PrepareImageRect(bHasTitle, rpItem, rpTitle, bIsPressed, m_csIcons[byIndex].dwWidth, m_csIcons[byIndex].dwHeight, &rImage);
  713. // Ole'!
  714. pDC->DrawState( rImage.TopLeft(),
  715. rImage.Size(),
  716. m_csIcons[byIndex].hIcon,
  717. (bIsDisabled ? DSS_DISABLED : DSS_NORMAL),
  718. (CBrush*)NULL);
  719. } // End of DrawTheIcon
  720. void CButtonST::DrawTheBitmap(CDC* pDC, BOOL bHasTitle, RECT* rItem, CRect *rCaption, BOOL bIsPressed, BOOL bIsDisabled)
  721. {
  722. HDC hdcBmpMem = NULL;
  723. HBITMAP hbmOldBmp = NULL;
  724. HDC hdcMem = NULL;
  725. HBITMAP hbmT = NULL;
  726. BYTE byIndex = 0;
  727. // Select the bitmap to use
  728. if ((m_bIsCheckBox && bIsPressed) || (!m_bIsCheckBox && (bIsPressed || m_bMouseOnButton)))
  729. byIndex = 0;
  730. else
  731. byIndex = (m_csBitmaps[1].hBitmap == NULL ? 0 : 1);
  732. CRect rImage;
  733. PrepareImageRect(bHasTitle, rItem, rCaption, bIsPressed, m_csBitmaps[byIndex].dwWidth, m_csBitmaps[byIndex].dwHeight, &rImage);
  734. hdcBmpMem = ::CreateCompatibleDC(pDC->m_hDC);
  735. hbmOldBmp = (HBITMAP)::SelectObject(hdcBmpMem, m_csBitmaps[byIndex].hBitmap);
  736. hdcMem = ::CreateCompatibleDC(NULL);
  737. hbmT = (HBITMAP)::SelectObject(hdcMem, m_csBitmaps[byIndex].hMask);
  738. if (bIsDisabled && m_bShowDisabledBitmap)
  739. {
  740. HDC hDC = NULL;
  741. HBITMAP hBitmap = NULL;
  742. hDC = ::CreateCompatibleDC(pDC->m_hDC);
  743. hBitmap = ::CreateCompatibleBitmap(pDC->m_hDC, m_csBitmaps[byIndex].dwWidth, m_csBitmaps[byIndex].dwHeight);
  744. HBITMAP hOldBmp2 = (HBITMAP)::SelectObject(hDC, hBitmap);
  745. RECT rRect;
  746. rRect.left = 0;
  747. rRect.top = 0;
  748. rRect.right = rImage.right + 1;
  749. rRect.bottom = rImage.bottom + 1;
  750. ::FillRect(hDC, &rRect, (HBRUSH)RGB(255, 255, 255));
  751. COLORREF crOldColor = ::SetBkColor(hDC, RGB(255,255,255));
  752. ::BitBlt(hDC, 0, 0, m_csBitmaps[byIndex].dwWidth, m_csBitmaps[byIndex].dwHeight, hdcMem, 0, 0, SRCAND);
  753. ::BitBlt(hDC, 0, 0, m_csBitmaps[byIndex].dwWidth, m_csBitmaps[byIndex].dwHeight, hdcBmpMem, 0, 0, SRCPAINT);
  754. ::SetBkColor(hDC, crOldColor);
  755. ::SelectObject(hDC, hOldBmp2);
  756. ::DeleteDC(hDC);
  757. pDC->DrawState( CPoint(rImage.left/*+1*/, rImage.top),
  758. CSize(m_csBitmaps[byIndex].dwWidth, m_csBitmaps[byIndex].dwHeight),
  759. hBitmap, DST_BITMAP | DSS_DISABLED);
  760. ::DeleteObject(hBitmap);
  761. } // if
  762. else
  763. {
  764. ::BitBlt(pDC->m_hDC, rImage.left, rImage.top, m_csBitmaps[byIndex].dwWidth, m_csBitmaps[byIndex].dwHeight, hdcMem, 0, 0, SRCAND);
  765. ::BitBlt(pDC->m_hDC, rImage.left, rImage.top, m_csBitmaps[byIndex].dwWidth, m_csBitmaps[byIndex].dwHeight, hdcBmpMem, 0, 0, SRCPAINT);
  766. } // else
  767. ::SelectObject(hdcMem, hbmT);
  768. ::DeleteDC(hdcMem);
  769. ::SelectObject(hdcBmpMem, hbmOldBmp);
  770. ::DeleteDC(hdcBmpMem);
  771. } // End of DrawTheBitmap
  772. // This function creates a grayscale icon starting from a given icon.
  773. // The resulting icon will have the same size of the original one.
  774. //
  775. // Parameters:
  776. // [IN] hIcon
  777. // Handle to the original icon.
  778. //
  779. // Return value:
  780. // If the function succeeds, the return value is the handle to the newly created
  781. // grayscale icon.
  782. // If the function fails, the return value is NULL.
  783. //
  784. HICON CButtonST::CreateGrayscaleIcon(HICON hIcon)
  785. {
  786. HICON hGrayIcon = NULL;
  787. HDC hMainDC = NULL, hMemDC1 = NULL, hMemDC2 = NULL;
  788. BITMAP bmp;
  789. HBITMAP hOldBmp1 = NULL, hOldBmp2 = NULL;
  790. ICONINFO csII, csGrayII;
  791. BOOL bRetValue = FALSE;
  792. bRetValue = ::GetIconInfo(hIcon, &csII);
  793. if (bRetValue == FALSE) return NULL;
  794. hMainDC = ::GetDC(m_hWnd);
  795. hMemDC1 = ::CreateCompatibleDC(hMainDC);
  796. hMemDC2 = ::CreateCompatibleDC(hMainDC);
  797. if (hMainDC == NULL || hMemDC1 == NULL || hMemDC2 == NULL) return NULL;
  798. if (::GetObject(csII.hbmColor, sizeof(BITMAP), &bmp))
  799. {
  800. csGrayII.hbmColor = ::CreateBitmap(csII.xHotspot*2, csII.yHotspot*2, bmp.bmPlanes, bmp.bmBitsPixel, NULL);
  801. if (csGrayII.hbmColor)
  802. {
  803. hOldBmp1 = (HBITMAP)::SelectObject(hMemDC1, csII.hbmColor);
  804. hOldBmp2 = (HBITMAP)::SelectObject(hMemDC2, csGrayII.hbmColor);
  805. ::BitBlt(hMemDC2, 0, 0, csII.xHotspot*2, csII.yHotspot*2, hMemDC1, 0, 0, SRCCOPY);
  806. DWORD dwLoopY = 0, dwLoopX = 0;
  807. COLORREF crPixel = 0;
  808. BYTE byNewPixel = 0;
  809. for (dwLoopY = 0; dwLoopY < csII.yHotspot*2; dwLoopY++)
  810. {
  811. for (dwLoopX = 0; dwLoopX < csII.xHotspot*2; dwLoopX++)
  812. {
  813. crPixel = ::GetPixel(hMemDC2, dwLoopX, dwLoopY);
  814. byNewPixel = (BYTE)((GetRValue(crPixel) * 0.299) + (GetGValue(crPixel) * 0.587) + (GetBValue(crPixel) * 0.114));
  815. if (crPixel) ::SetPixel(hMemDC2, dwLoopX, dwLoopY, RGB(byNewPixel, byNewPixel, byNewPixel));
  816. } // for
  817. } // for
  818. ::SelectObject(hMemDC1, hOldBmp1);
  819. ::SelectObject(hMemDC2, hOldBmp2);
  820. csGrayII.hbmMask = csII.hbmMask;
  821. csGrayII.fIcon = TRUE;
  822. hGrayIcon = ::CreateIconIndirect(&csGrayII);
  823. } // if
  824. ::DeleteObject(csGrayII.hbmColor);
  825. //::DeleteObject(csGrayII.hbmMask);
  826. } // if
  827. ::DeleteObject(csII.hbmColor);
  828. ::DeleteObject(csII.hbmMask);
  829. ::DeleteDC(hMemDC1);
  830. ::DeleteDC(hMemDC2);
  831. ::ReleaseDC(m_hWnd, hMainDC);
  832. return hGrayIcon;
  833. } // End of CreateGrayscaleIcon
  834. // This function assigns icons to the button.
  835. // Any previous icon or bitmap will be removed.
  836. //
  837. // Parameters:
  838. // [IN] nIconIn
  839. // ID number of the icon resource to show when the mouse is over the button.
  840. // Pass NULL to remove any icon from the button.
  841. // [IN] nIconOut
  842. // ID number of the icon resource to show when the mouse is outside the button.
  843. // Can be NULL.
  844. //
  845. // Return value:
  846. // BTNST_OK
  847. // Function executed successfully.
  848. // BTNST_INVALIDRESOURCE
  849. // Failed loading the specified resource.
  850. //
  851. DWORD CButtonST::SetIcon(int nIconIn, int nIconOut)
  852. {
  853. HICON hIconIn = NULL;
  854. HICON hIconOut = NULL;
  855. HINSTANCE hInstResource = NULL;
  856. // Find correct resource handle
  857. hInstResource = AfxFindResourceHandle(MAKEINTRESOURCE(nIconIn), RT_GROUP_ICON);
  858. // Set icon when the mouse is IN the button
  859. hIconIn = (HICON)::LoadImage(hInstResource, MAKEINTRESOURCE(nIconIn), IMAGE_ICON, 0, 0, 0);
  860. // Set icon when the mouse is OUT the button
  861. if (nIconOut)
  862. {
  863. if (nIconOut == (int)BTNST_AUTO_GRAY)
  864. hIconOut = BTNST_AUTO_GRAY;
  865. else
  866. hIconOut = (HICON)::LoadImage(hInstResource, MAKEINTRESOURCE(nIconOut), IMAGE_ICON, 0, 0, 0);
  867. } // if
  868. return SetIcon(hIconIn, hIconOut);
  869. } // End of SetIcon
  870. // This function assigns icons to the button.
  871. // Any previous icon or bitmap will be removed.
  872. //
  873. // Parameters:
  874. // [IN] hIconIn
  875. // Handle fo the icon to show when the mouse is over the button.
  876. // Pass NULL to remove any icon from the button.
  877. // [IN] hIconOut
  878. // Handle to the icon to show when the mouse is outside the button.
  879. // Can be NULL.
  880. //
  881. // Return value:
  882. // BTNST_OK
  883. // Function executed successfully.
  884. // BTNST_INVALIDRESOURCE
  885. // Failed loading the specified resource.
  886. //
  887. DWORD CButtonST::SetIcon(HICON hIconIn, HICON hIconOut)
  888. {
  889. BOOL bRetValue;
  890. ICONINFO ii;
  891. // Free any loaded resource
  892. FreeResources();
  893. if (hIconIn)
  894. {
  895. // Icon when mouse over button?
  896. m_csIcons[0].hIcon = hIconIn;
  897. // Get icon dimension
  898. ::ZeroMemory(&ii, sizeof(ICONINFO));
  899. bRetValue = ::GetIconInfo(hIconIn, &ii);
  900. if (bRetValue == FALSE)
  901. {
  902. FreeResources();
  903. return BTNST_INVALIDRESOURCE;
  904. } // if
  905. m_csIcons[0].dwWidth = (DWORD)(ii.xHotspot * 2);
  906. m_csIcons[0].dwHeight = (DWORD)(ii.yHotspot * 2);
  907. ::DeleteObject(ii.hbmMask);
  908. ::DeleteObject(ii.hbmColor);
  909. // Icon when mouse outside button?
  910. if (hIconOut)
  911. {
  912. if (hIconOut == BTNST_AUTO_GRAY)
  913. {
  914. hIconOut = CreateGrayscaleIcon(hIconIn);
  915. } // if
  916. m_csIcons[1].hIcon = hIconOut;
  917. // Get icon dimension
  918. ::ZeroMemory(&ii, sizeof(ICONINFO));
  919. bRetValue = ::GetIconInfo(hIconOut, &ii);
  920. if (bRetValue == FALSE)
  921. {
  922. FreeResources();
  923. return BTNST_INVALIDRESOURCE;
  924. } // if
  925. m_csIcons[1].dwWidth = (DWORD)(ii.xHotspot * 2);
  926. m_csIcons[1].dwHeight = (DWORD)(ii.yHotspot * 2);
  927. ::DeleteObject(ii.hbmMask);
  928. ::DeleteObject(ii.hbmColor);
  929. } // if
  930. } // if
  931. Invalidate();
  932. return BTNST_OK;
  933. } // End of SetIcon
  934. // This function assigns bitmaps to the button.
  935. // Any previous icon or bitmap will be removed.
  936. //
  937. // Parameters:
  938. // [IN] nBitmapIn
  939. // ID number of the bitmap resource to show when the mouse is over the button.
  940. // Pass NULL to remove any bitmap from the button.
  941. // [IN] crTransColorIn
  942. // Color (inside nBitmapIn) to be used as transparent color.
  943. // [IN] nBitmapOut
  944. // ID number of the bitmap resource to show when the mouse is outside the button.
  945. // Can be NULL.
  946. // [IN] crTransColorOut
  947. // Color (inside nBitmapOut) to be used as transparent color.
  948. //
  949. // Return value:
  950. // BTNST_OK
  951. // Function executed successfully.
  952. // BTNST_INVALIDRESOURCE
  953. // Failed loading the specified resource.
  954. // BTNST_FAILEDMASK
  955. // Failed creating mask bitmap.
  956. //
  957. DWORD CButtonST::SetBitmaps(int nBitmapIn, COLORREF crTransColorIn, int nBitmapOut, COLORREF crTransColorOut)
  958. {
  959. HBITMAP hBitmapIn = NULL;
  960. HBITMAP hBitmapOut = NULL;
  961. HINSTANCE hInstResource = NULL;
  962. // Find correct resource handle
  963. hInstResource = AfxFindResourceHandle(MAKEINTRESOURCE(nBitmapIn), RT_BITMAP);
  964. // Load bitmap In
  965. hBitmapIn = (HBITMAP)::LoadImage(hInstResource, MAKEINTRESOURCE(nBitmapIn), IMAGE_BITMAP, 0, 0, 0);
  966. // Load bitmap Out
  967. if (nBitmapOut)
  968. hBitmapOut = (HBITMAP)::LoadImage(hInstResource, MAKEINTRESOURCE(nBitmapOut), IMAGE_BITMAP, 0, 0, 0);
  969. return SetBitmaps(hBitmapIn, crTransColorIn, hBitmapOut, crTransColorOut);
  970. } // End of SetBitmaps
  971. // This function assigns bitmaps to the button.
  972. // Any previous icon or bitmap will be removed.
  973. //
  974. // Parameters:
  975. // [IN] hBitmapIn
  976. // Handle fo the bitmap to show when the mouse is over the button.
  977. // Pass NULL to remove any bitmap from the button.
  978. // [IN] crTransColorIn
  979. // Color (inside hBitmapIn) to be used as transparent color.
  980. // [IN] hBitmapOut
  981. // Handle to the bitmap to show when the mouse is outside the button.
  982. // Can be NULL.
  983. // [IN] crTransColorOut
  984. // Color (inside hBitmapOut) to be used as transparent color.
  985. //
  986. // Return value:
  987. // BTNST_OK
  988. // Function executed successfully.
  989. // BTNST_INVALIDRESOURCE
  990. // Failed loading the specified resource.
  991. // BTNST_FAILEDMASK
  992. // Failed creating mask bitmap.
  993. //
  994. DWORD CButtonST::SetBitmaps(HBITMAP hBitmapIn, COLORREF crTransColorIn, HBITMAP hBitmapOut, COLORREF crTransColorOut)
  995. {
  996. int nRetValue;
  997. BITMAP csBitmapSize;
  998. // Free any loaded resource
  999. FreeResources();
  1000. if (hBitmapIn)
  1001. {
  1002. m_csBitmaps[0].hBitmap = hBitmapIn;
  1003. m_csBitmaps[0].crTransparent = crTransColorIn;
  1004. // Get bitmap size
  1005. nRetValue = ::GetObject(hBitmapIn, sizeof(csBitmapSize), &csBitmapSize);
  1006. if (nRetValue == 0)
  1007. {
  1008. FreeResources();
  1009. return BTNST_INVALIDRESOURCE;
  1010. } // if
  1011. m_csBitmaps[0].dwWidth = (DWORD)csBitmapSize.bmWidth;
  1012. m_csBitmaps[0].dwHeight = (DWORD)csBitmapSize.bmHeight;
  1013. // Create mask for bitmap In
  1014. m_csBitmaps[0].hMask = CreateBitmapMask(hBitmapIn, m_csBitmaps[0].dwWidth, m_csBitmaps[0].dwHeight, crTransColorIn);
  1015. if (m_csBitmaps[0].hMask == NULL)
  1016. {
  1017. FreeResources();
  1018. return BTNST_FAILEDMASK;
  1019. } // if
  1020. if (hBitmapOut)
  1021. {
  1022. m_csBitmaps[1].hBitmap = hBitmapOut;
  1023. m_csBitmaps[1].crTransparent = crTransColorOut;
  1024. // Get bitmap size
  1025. nRetValue = ::GetObject(hBitmapOut, sizeof(csBitmapSize), &csBitmapSize);
  1026. if (nRetValue == 0)
  1027. {
  1028. FreeResources();
  1029. return BTNST_INVALIDRESOURCE;
  1030. } // if
  1031. m_csBitmaps[1].dwWidth = (DWORD)csBitmapSize.bmWidth;
  1032. m_csBitmaps[1].dwHeight = (DWORD)csBitmapSize.bmHeight;
  1033. // Create mask for bitmap Out
  1034. m_csBitmaps[1].hMask = CreateBitmapMask(hBitmapOut, m_csBitmaps[1].dwWidth, m_csBitmaps[1].dwHeight, crTransColorOut);
  1035. if (m_csBitmaps[1].hMask == NULL)
  1036. {
  1037. FreeResources();
  1038. return BTNST_FAILEDMASK;
  1039. } // if
  1040. } // if
  1041. } // if
  1042. Invalidate();
  1043. return BTNST_OK;
  1044. } // End of SetBitmaps
  1045. // This functions sets the button to have a standard or flat style.
  1046. //
  1047. // Parameters:
  1048. // [IN] bFlat
  1049. // If TRUE the button will have a flat style, else
  1050. // will have a standard style.
  1051. // By default, CButtonST buttons are flat.
  1052. // [IN] bRepaint
  1053. // If TRUE the control will be repainted.
  1054. //
  1055. // Return value:
  1056. // BTNST_OK
  1057. // Function executed successfully.
  1058. //
  1059. DWORD CButtonST::SetFlat(BOOL bFlat, BOOL bRepaint)
  1060. {
  1061. m_bIsFlat = bFlat;
  1062. if (bRepaint) Invalidate();
  1063. return BTNST_OK;
  1064. } // End of SetFlat
  1065. // This function sets the alignment type between icon/bitmap and text.
  1066. //
  1067. // Parameters:
  1068. // [IN] byAlign
  1069. // Alignment type. Can be one of the following values:
  1070. // ST_ALIGN_HORIZ Icon/bitmap on the left, text on the right
  1071. // ST_ALIGN_VERT Icon/bitmap on the top, text on the bottom
  1072. // ST_ALIGN_HORIZ_RIGHT Icon/bitmap on the right, text on the left
  1073. // By default, CButtonST buttons have ST_ALIGN_HORIZ alignment.
  1074. // [IN] bRepaint
  1075. // If TRUE the control will be repainted.
  1076. //
  1077. // Return value:
  1078. // BTNST_OK
  1079. // Function executed successfully.
  1080. // BTNST_INVALIDALIGN
  1081. // Alignment type not supported.
  1082. //
  1083. DWORD CButtonST::SetAlign(BYTE byAlign, BOOL bRepaint)
  1084. {
  1085. switch (byAlign)
  1086. {
  1087. case ST_ALIGN_HORIZ:
  1088. case ST_ALIGN_HORIZ_RIGHT:
  1089. case ST_ALIGN_VERT:
  1090. m_byAlign = byAlign;
  1091. if (bRepaint) Invalidate();
  1092. return BTNST_OK;
  1093. break;
  1094. } // switch
  1095. return BTNST_INVALIDALIGN;
  1096. } // End of SetAlign
  1097. // This function sets the state of the checkbox.
  1098. // If the button is not a checkbox, this function has no meaning.
  1099. //
  1100. // Parameters:
  1101. // [IN] nCheck
  1102. // 1 to check the checkbox.
  1103. // 0 to un-check the checkbox.
  1104. // [IN] bRepaint
  1105. // If TRUE the control will be repainted.
  1106. //
  1107. // Return value:
  1108. // BTNST_OK
  1109. // Function executed successfully.
  1110. //
  1111. DWORD CButtonST::SetCheck(int nCheck, BOOL bRepaint)
  1112. {
  1113. if (m_bIsCheckBox)
  1114. {
  1115. if (nCheck == 0) m_nCheck = 0;
  1116. else m_nCheck = 1;
  1117. if (bRepaint) Invalidate();
  1118. } // if
  1119. return BTNST_OK;
  1120. } // End of SetCheck
  1121. // This function returns the current state of the checkbox.
  1122. // If the button is not a checkbox, this function has no meaning.
  1123. //
  1124. // Return value:
  1125. // The current state of the checkbox.
  1126. // 1 if checked.
  1127. // 0 if not checked or the button is not a checkbox.
  1128. //
  1129. int CButtonST::GetCheck()
  1130. {
  1131. return m_nCheck;
  1132. } // End of GetCheck
  1133. // This function sets all colors to a default value.
  1134. //
  1135. // Parameters:
  1136. // [IN] bRepaint
  1137. // If TRUE the control will be repainted.
  1138. //
  1139. // Return value:
  1140. // BTNST_OK
  1141. // Function executed successfully.
  1142. //
  1143. DWORD CButtonST::SetDefaultColors(BOOL bRepaint)
  1144. {
  1145. m_crColors[BTNST_COLOR_BK_IN] = ::GetSysColor(COLOR_BTNFACE);
  1146. m_crColors[BTNST_COLOR_FG_IN] = ::GetSysColor(COLOR_BTNTEXT);
  1147. m_crColors[BTNST_COLOR_BK_OUT] = ::GetSysColor(COLOR_BTNFACE);
  1148. m_crColors[BTNST_COLOR_FG_OUT] = ::GetSysColor(COLOR_BTNTEXT);
  1149. m_crColors[BTNST_COLOR_BK_FOCUS] = ::GetSysColor(COLOR_BTNFACE);
  1150. m_crColors[BTNST_COLOR_FG_FOCUS] = ::GetSysColor(COLOR_BTNTEXT);
  1151. m_crColors[BTNST_COLOR_CHOOSE] = ::GetSysColor(COLOR_BTNTEXT);
  1152. m_crColors[BTNST_COLOR_NOTCHOOSE] = ::GetSysColor(COLOR_BTNTEXT);
  1153. if (bRepaint) Invalidate();
  1154. return BTNST_OK;
  1155. } // End of SetDefaultColors
  1156. // This function sets the color to use for a particular state.
  1157. //
  1158. // Parameters:
  1159. // [IN] byColorIndex
  1160. // Index of the color to set. Can be one of the following values:
  1161. // BTNST_COLOR_BK_IN Background color when mouse is over the button
  1162. // BTNST_COLOR_FG_IN Text color when mouse is over the button
  1163. // BTNST_COLOR_BK_OUT Background color when mouse is outside the button
  1164. // BTNST_COLOR_FG_OUT Text color when mouse is outside the button
  1165. // BTNST_COLOR_BK_FOCUS Background color when the button is focused
  1166. // BTNST_COLOR_FG_FOCUS Text color when the button is focused
  1167. // [IN] crColor
  1168. // New color.
  1169. // [IN] bRepaint
  1170. // If TRUE the control will be repainted.
  1171. //
  1172. // Return value:
  1173. // BTNST_OK
  1174. // Function executed successfully.
  1175. // BTNST_INVALIDINDEX
  1176. // Invalid color index.
  1177. //
  1178. DWORD CButtonST::SetColor(BYTE byColorIndex, COLORREF crColor, BOOL bRepaint)
  1179. {
  1180. if (byColorIndex >= BTNST_MAX_COLORS) return BTNST_INVALIDINDEX;
  1181. // Set new color
  1182. m_crColors[byColorIndex] = crColor;
  1183. if (bRepaint) Invalidate();
  1184. return BTNST_OK;
  1185. } // End of SetColor
  1186. // This functions returns the color used for a particular state.
  1187. //
  1188. // Parameters:
  1189. // [IN] byColorIndex
  1190. // Index of the color to get.
  1191. // See SetColor for the list of available colors.
  1192. // [OUT] crpColor
  1193. // A pointer to a COLORREF that will receive the color.
  1194. //
  1195. // Return value:
  1196. // BTNST_OK
  1197. // Function executed successfully.
  1198. // BTNST_INVALIDINDEX
  1199. // Invalid color index.
  1200. //
  1201. DWORD CButtonST::GetColor(BYTE byColorIndex, COLORREF* crpColor)
  1202. {
  1203. if (byColorIndex >= BTNST_MAX_COLORS) return BTNST_INVALIDINDEX;
  1204. // Get color
  1205. *crpColor = m_crColors[byColorIndex];
  1206. return BTNST_OK;
  1207. } // End of GetColor
  1208. // This function applies an offset to the RGB components of the specified color.
  1209. // This function can be seen as an easy way to make a color darker or lighter than
  1210. // its default value.
  1211. //
  1212. // Parameters:
  1213. // [IN] byColorIndex
  1214. // Index of the color to set.
  1215. // See SetColor for the list of available colors.
  1216. // [IN] shOffsetColor
  1217. // A short value indicating the offset to apply to the color.
  1218. // This value must be between -255 and 255.
  1219. // [IN] bRepaint
  1220. // If TRUE the control will be repainted.
  1221. //
  1222. // Return value:
  1223. // BTNST_OK
  1224. // Function executed successfully.
  1225. // BTNST_INVALIDINDEX
  1226. // Invalid color index.
  1227. // BTNST_BADPARAM
  1228. // The specified offset is out of range.
  1229. //
  1230. DWORD CButtonST::OffsetColor(BYTE byColorIndex, short shOffset, BOOL bRepaint)
  1231. {
  1232. BYTE byRed = 0;
  1233. BYTE byGreen = 0;
  1234. BYTE byBlue = 0;
  1235. short shOffsetR = shOffset;
  1236. short shOffsetG = shOffset;
  1237. short shOffsetB = shOffset;
  1238. if (byColorIndex >= BTNST_MAX_COLORS) return BTNST_INVALIDINDEX;
  1239. if (shOffset < -255 || shOffset > 255) return BTNST_BADPARAM;
  1240. // Get RGB components of specified color
  1241. byRed = GetRValue(m_crColors[byColorIndex]);
  1242. byGreen = GetGValue(m_crColors[byColorIndex]);
  1243. byBlue = GetBValue(m_crColors[byColorIndex]);
  1244. // Calculate max. allowed real offset
  1245. if (shOffset > 0)
  1246. {
  1247. if (byRed + shOffset > 255) shOffsetR = 255 - byRed;
  1248. if (byGreen + shOffset > 255) shOffsetG = 255 - byGreen;
  1249. if (byBlue + shOffset > 255) shOffsetB = 255 - byBlue;
  1250. shOffset = min(min(shOffsetR, shOffsetG), shOffsetB);
  1251. } // if
  1252. else
  1253. {
  1254. if (byRed + shOffset < 0) shOffsetR = -byRed;
  1255. if (byGreen + shOffset < 0) shOffsetG = -byGreen;
  1256. if (byBlue + shOffset < 0) shOffsetB = -byBlue;
  1257. shOffset = max(max(shOffsetR, shOffsetG), shOffsetB);
  1258. } // else
  1259. // Set new color
  1260. m_crColors[byColorIndex] = RGB(byRed + shOffset, byGreen + shOffset, byBlue + shOffset);
  1261. if (bRepaint) Invalidate();
  1262. return BTNST_OK;
  1263. } // End of OffsetColor
  1264. // This function sets the hilight logic for the button.
  1265. // Applies only to flat buttons.
  1266. //
  1267. // Parameters:
  1268. // [IN] bAlwaysTrack
  1269. // If TRUE the button will be hilighted even if the window that owns it, is
  1270. // not the active window.
  1271. // If FALSE the button will be hilighted only if the window that owns it,
  1272. // is the active window.
  1273. //
  1274. // Return value:
  1275. // BTNST_OK
  1276. // Function executed successfully.
  1277. //
  1278. DWORD CButtonST::SetAlwaysTrack(BOOL bAlwaysTrack)
  1279. {
  1280. m_bAlwaysTrack = bAlwaysTrack;
  1281. return BTNST_OK;
  1282. } // End of SetAlwaysTrack
  1283. // This function sets the cursor to be used when the mouse is over the button.
  1284. //
  1285. // Parameters:
  1286. // [IN] nCursorId
  1287. // ID number of the cursor resource.
  1288. // Pass NULL to remove a previously loaded cursor.
  1289. // [IN] bRepaint
  1290. // If TRUE the control will be repainted.
  1291. //
  1292. // Return value:
  1293. // BTNST_OK
  1294. // Function executed successfully.
  1295. // BTNST_INVALIDRESOURCE
  1296. // Failed loading the specified resource.
  1297. //
  1298. DWORD CButtonST::SetBtnCursor(int nCursorId, BOOL bRepaint)
  1299. {
  1300. HINSTANCE hInstResource = NULL;
  1301. // Destroy any previous cursor
  1302. if (m_hCursor)
  1303. {
  1304. ::DestroyCursor(m_hCursor);
  1305. m_hCursor = NULL;
  1306. } // if
  1307. // Load cursor
  1308. if (nCursorId)
  1309. {
  1310. hInstResource = AfxFindResourceHandle(MAKEINTRESOURCE(nCursorId), RT_GROUP_CURSOR);
  1311. // Load cursor resource
  1312. m_hCursor = (HCURSOR)::LoadImage(hInstResource, MAKEINTRESOURCE(nCursorId), IMAGE_CURSOR, 0, 0, 0);
  1313. // Repaint the button
  1314. if (bRepaint) Invalidate();
  1315. // If something wrong
  1316. if (m_hCursor == NULL) return BTNST_INVALIDRESOURCE;
  1317. } // if
  1318. return BTNST_OK;
  1319. } // End of SetBtnCursor
  1320. // This function sets if the button border must be drawn.
  1321. // Applies only to flat buttons.
  1322. //
  1323. // Parameters:
  1324. // [IN] bDrawBorder
  1325. // If TRUE the border will be drawn.
  1326. // [IN] bRepaint
  1327. // If TRUE the control will be repainted.
  1328. //
  1329. // Return value:
  1330. // BTNST_OK
  1331. // Function executed successfully.
  1332. //
  1333. DWORD CButtonST::DrawBorder(BOOL bDrawBorder, BOOL bRepaint)
  1334. {
  1335. m_bDrawBorder = bDrawBorder;
  1336. // Repaint the button
  1337. if (bRepaint) Invalidate();
  1338. return BTNST_OK;
  1339. } // End of DrawBorder
  1340. // This function sets if the focus rectangle must be drawn for flat buttons.
  1341. //
  1342. // Parameters:
  1343. // [IN] bDrawFlatFocus
  1344. // If TRUE the focus rectangle will be drawn also for flat buttons.
  1345. // [IN] bRepaint
  1346. // If TRUE the control will be repainted.
  1347. //
  1348. // Return value:
  1349. // BTNST_OK
  1350. // Function executed successfully.
  1351. //
  1352. DWORD CButtonST::DrawFlatFocus(BOOL bDrawFlatFocus, BOOL bRepaint)
  1353. {
  1354. m_bDrawFlatFocus = bDrawFlatFocus;
  1355. // Repaint the button
  1356. if (bRepaint) Invalidate();
  1357. return BTNST_OK;
  1358. } // End of DrawFlatFocus
  1359. void CButtonST::InitToolTip()
  1360. {
  1361. if (m_ToolTip.m_hWnd == NULL)
  1362. {
  1363. // Create ToolTip control
  1364. m_ToolTip.Create(this);
  1365. // Create inactive
  1366. m_ToolTip.Activate(FALSE);
  1367. // Enable multiline
  1368. m_ToolTip.SendMessage(TTM_SETMAXTIPWIDTH, 0, 400);
  1369. } // if
  1370. } // End of InitToolTip
  1371. // This function sets the text to show in the button tooltip.
  1372. //
  1373. // Parameters:
  1374. // [IN] nText
  1375. // ID number of the string resource containing the text to show.
  1376. // [IN] bActivate
  1377. // If TRUE the tooltip will be created active.
  1378. //
  1379. void CButtonST::SetTooltipText(int nText, BOOL bActivate)
  1380. {
  1381. CString sText;
  1382. // Load string resource
  1383. sText.LoadString(nText);
  1384. // If string resource is not empty
  1385. if (sText.IsEmpty() == FALSE) SetTooltipText((LPCTSTR)sText, bActivate);
  1386. } // End of SetTooltipText
  1387. // This function sets the text to show in the button tooltip.
  1388. //
  1389. // Parameters:
  1390. // [IN] lpszText
  1391. // Pointer to a null-terminated string containing the text to show.
  1392. // [IN] bActivate
  1393. // If TRUE the tooltip will be created active.
  1394. //
  1395. void CButtonST::SetTooltipText(LPCTSTR lpszText, BOOL bActivate)
  1396. {
  1397. // We cannot accept NULL pointer
  1398. if (lpszText == NULL) return;
  1399. // Initialize ToolTip
  1400. InitToolTip();
  1401. // If there is no tooltip defined then add it
  1402. if (m_ToolTip.GetToolCount() == 0)
  1403. {
  1404. CRect rectBtn;
  1405. GetClientRect(rectBtn);
  1406. m_ToolTip.AddTool(this, lpszText, rectBtn, 1);
  1407. } // if
  1408. // Set text for tooltip
  1409. m_ToolTip.UpdateTipText(lpszText, this, 1);
  1410. m_ToolTip.Activate(bActivate);
  1411. } // End of SetTooltipText
  1412. // This function enables or disables the button tooltip.
  1413. //
  1414. // Parameters:
  1415. // [IN] bActivate
  1416. // If TRUE the tooltip will be activated.
  1417. //
  1418. void CButtonST::ActivateTooltip(BOOL bActivate)
  1419. {
  1420. // If there is no tooltip then do nothing
  1421. if (m_ToolTip.GetToolCount() == 0) return;
  1422. // Activate tooltip
  1423. m_ToolTip.Activate(bActivate);
  1424. } // End of EnableTooltip
  1425. // This function returns if the button is the default button.
  1426. //
  1427. // Return value:
  1428. // TRUE
  1429. // The button is the default button.
  1430. // FALSE
  1431. // The button is not the default button.
  1432. //
  1433. BOOL CButtonST::GetDefault()
  1434. {
  1435. return m_bIsDefault;
  1436. } // End of GetDefault
  1437. // This function enables the transparent mode.
  1438. // Note: this operation is not reversible.
  1439. // DrawTransparent should be called just after the button is created.
  1440. // Do not use trasparent buttons until you really need it (you have a bitmapped
  1441. // background) since each transparent button makes a copy in memory of its background.
  1442. // This may bring unnecessary memory use and execution overload.
  1443. //
  1444. // Parameters:
  1445. // [IN] bRepaint
  1446. // If TRUE the control will be repainted.
  1447. //
  1448. void CButtonST::DrawTransparent(BOOL bRepaint)
  1449. {
  1450. m_bDrawTransparent = TRUE;
  1451. // Restore old bitmap (if any)
  1452. if (m_dcBk.m_hDC != NULL && m_pbmpOldBk != NULL)
  1453. {
  1454. m_dcBk.SelectObject(m_pbmpOldBk);
  1455. } // if
  1456. m_bmpBk.DeleteObject();
  1457. m_dcBk.DeleteDC();
  1458. // Repaint the button
  1459. if (bRepaint) Invalidate();
  1460. } // End of DrawTransparent
  1461. // This function sets the URL that will be opened when the button is clicked.
  1462. //
  1463. // Parameters:
  1464. // [IN] lpszURL
  1465. // Pointer to a null-terminated string that contains the URL.
  1466. // Pass NULL to removed any previously specified URL.
  1467. //
  1468. // Return value:
  1469. // BTNST_OK
  1470. // Function executed successfully.
  1471. //
  1472. DWORD CButtonST::SetURL(LPCTSTR lpszURL)
  1473. {
  1474. // Remove any existing URL
  1475. memset(m_szURL, 0, sizeof(m_szURL));
  1476. if (lpszURL)
  1477. {
  1478. // Store the URL
  1479. _tcsncpy(m_szURL, lpszURL, _MAX_PATH);
  1480. } // if
  1481. return BTNST_OK;
  1482. } // End of SetURL
  1483. // This function associates a menu to the button.
  1484. // The menu will be displayed clicking the button.
  1485. //
  1486. // Parameters:
  1487. // [IN] nMenu
  1488. // ID number of the menu resource.
  1489. // Pass NULL to remove any menu from the button.
  1490. // [IN] hParentWnd
  1491. // Handle to the window that owns the menu.
  1492. // This window receives all messages from the menu.
  1493. // [IN] bRepaint
  1494. // If TRUE the control will be repainted.
  1495. //
  1496. // Return value:
  1497. // BTNST_OK
  1498. // Function executed successfully.
  1499. // BTNST_INVALIDRESOURCE
  1500. // Failed loading the specified resource.
  1501. //
  1502. #ifndef BTNST_USE_BCMENU
  1503. DWORD CButtonST::SetMenu(UINT nMenu, HWND hParentWnd, BOOL bRepaint)
  1504. {
  1505. HINSTANCE hInstResource = NULL;
  1506. // Destroy any previous menu
  1507. if (m_hMenu)
  1508. {
  1509. ::DestroyMenu(m_hMenu);
  1510. m_hMenu = NULL;
  1511. m_hParentWndMenu = NULL;
  1512. m_bMenuDisplayed = FALSE;
  1513. } // if
  1514. // Load menu
  1515. if (nMenu)
  1516. {
  1517. // Find correct resource handle
  1518. hInstResource = AfxFindResourceHandle(MAKEINTRESOURCE(nMenu), RT_MENU);
  1519. // Load menu resource
  1520. m_hMenu = ::LoadMenu(hInstResource, MAKEINTRESOURCE(nMenu));
  1521. m_hParentWndMenu = hParentWnd;
  1522. // If something wrong
  1523. if (m_hMenu == NULL) return BTNST_INVALIDRESOURCE;
  1524. } // if
  1525. // Repaint the button
  1526. if (bRepaint) Invalidate();
  1527. return BTNST_OK;
  1528. } // End of SetMenu
  1529. #endif
  1530. // This function associates a menu to the button.
  1531. // The menu will be displayed clicking the button.
  1532. // The menu will be handled by the BCMenu class.
  1533. //
  1534. // Parameters:
  1535. // [IN] nMenu
  1536. // ID number of the menu resource.
  1537. // Pass NULL to remove any menu from the button.
  1538. // [IN] hParentWnd
  1539. // Handle to the window that owns the menu.
  1540. // This window receives all messages from the menu.
  1541. // [IN] bWinXPStyle
  1542. // If TRUE the menu will be displayed using the new Windows XP style.
  1543. // If FALSE the menu will be displayed using the standard style.
  1544. // [IN] nToolbarID
  1545. // Resource ID of the toolbar to be associated to the menu.
  1546. // [IN] sizeToolbarIcon
  1547. // A CSize object indicating the size (in pixels) of each icon into the toolbar.
  1548. // All icons into the toolbar must have the same size.
  1549. // [IN] crToolbarBk
  1550. // A COLORREF value indicating the color to use as background for the icons into the toolbar.
  1551. // This color will be used as the "transparent" color.
  1552. // [IN] bRepaint
  1553. // If TRUE the control will be repainted.
  1554. //
  1555. // Return value:
  1556. // BTNST_OK
  1557. // Function executed successfully.
  1558. // BTNST_INVALIDRESOURCE
  1559. // Failed loading the specified resource.
  1560. //
  1561. #ifdef BTNST_USE_BCMENU
  1562. DWORD CButtonST::SetMenu(UINT nMenu, HWND hParentWnd, BOOL bWinXPStyle, UINT nToolbarID, CSize sizeToolbarIcon, COLORREF crToolbarBk, BOOL bRepaint)
  1563. {
  1564. BOOL bRetValue = FALSE;
  1565. // Destroy any previous menu
  1566. if (m_menuPopup.m_hMenu)
  1567. {
  1568. m_menuPopup.DestroyMenu();
  1569. m_hParentWndMenu = NULL;
  1570. m_bMenuDisplayed = FALSE;
  1571. } // if
  1572. // Load menu
  1573. if (nMenu)
  1574. {
  1575. m_menuPopup.SetMenuDrawMode(bWinXPStyle);
  1576. // Load menu
  1577. bRetValue = m_menuPopup.LoadMenu(nMenu);
  1578. // If something wrong
  1579. if (bRetValue == FALSE) return BTNST_INVALIDRESOURCE;
  1580. // Load toolbar
  1581. if (nToolbarID)
  1582. {
  1583. m_menuPopup.SetBitmapBackground(crToolbarBk);
  1584. m_menuPopup.SetIconSize(sizeToolbarIcon.cx, sizeToolbarIcon.cy);
  1585. bRetValue = m_menuPopup.LoadToolbar(nToolbarID);
  1586. // If something wrong
  1587. if (bRetValue == FALSE)
  1588. {
  1589. m_menuPopup.DestroyMenu();
  1590. return BTNST_INVALIDRESOURCE;
  1591. } // if
  1592. } // if
  1593. m_hParentWndMenu = hParentWnd;
  1594. } // if
  1595. // Repaint the button
  1596. if (bRepaint) Invalidate();
  1597. return BTNST_OK;
  1598. } // End of SetMenu
  1599. #endif
  1600. // This function is called every time the button background needs to be painted.
  1601. // If the button is in transparent mode this function will NOT be called.
  1602. // This is a virtual function that can be rewritten in CButtonST-derived classes
  1603. // to produce a whole range of buttons not available by default.
  1604. //
  1605. // Parameters:
  1606. // [IN] pDC
  1607. // Pointer to a CDC object that indicates the device context.
  1608. // [IN] pRect
  1609. // Pointer to a CRect object that indicates the bounds of the
  1610. // area to be painted.
  1611. //
  1612. // Return value:
  1613. // BTNST_OK
  1614. // Function executed successfully.
  1615. //
  1616. DWORD CButtonST::OnDrawBackground(CDC* pDC, LPCRECT pRect)
  1617. {
  1618. COLORREF crColor;
  1619. if (m_bMouseOnButton || m_bIsPressed)
  1620. crColor = m_crColors[BTNST_COLOR_BK_IN];
  1621. else
  1622. {
  1623. if (m_bIsFocused)
  1624. crColor = m_crColors[BTNST_COLOR_BK_FOCUS];
  1625. else
  1626. crColor = m_crColors[BTNST_COLOR_BK_OUT];
  1627. if( m_nIsChoose==1 )
  1628. crColor = m_crColors[6];
  1629. else if( m_nIsChoose==-1 )
  1630. crColor = m_crColors[7];
  1631. } // else
  1632. CBrush brBackground(crColor);
  1633. pDC->FillRect(pRect, &brBackground);
  1634. return BTNST_OK;
  1635. } // End of OnDrawBackground
  1636. // This function is called every time the button border needs to be painted.
  1637. // If the button is in standard (not flat) mode this function will NOT be called.
  1638. // This is a virtual function that can be rewritten in CButtonST-derived classes
  1639. // to produce a whole range of buttons not available by default.
  1640. //
  1641. // Parameters:
  1642. // [IN] pDC
  1643. // Pointer to a CDC object that indicates the device context.
  1644. // [IN] pRect
  1645. // Pointer to a CRect object that indicates the bounds of the
  1646. // area to be painted.
  1647. //
  1648. // Return value:
  1649. // BTNST_OK
  1650. // Function executed successfully.
  1651. //
  1652. DWORD CButtonST::OnDrawBorder(CDC* pDC, LPCRECT pRect)
  1653. {
  1654. if (m_bIsPressed)
  1655. pDC->Draw3dRect(pRect, ::GetSysColor(COLOR_BTNSHADOW), ::GetSysColor(COLOR_BTNHILIGHT));
  1656. else
  1657. pDC->Draw3dRect(pRect, ::GetSysColor(COLOR_BTNHILIGHT), ::GetSysColor(COLOR_BTNSHADOW));
  1658. return BTNST_OK;
  1659. } // End of OnDrawBorder
  1660. #undef BS_TYPEMASK