BtnST.cpp 50 KB

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