Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1459 lines
39 KiB

  1. #ifndef WIN32_LEAN_AND_MEAN
  2. #define WIN32_LEAN_AND_MEAN
  3. #endif
  4. #include <windows.h>
  5. #include <windowsx.h>
  6. #include "exbtn.h"
  7. #include "cexbtn.h"
  8. #include "exgdiw.h"
  9. #include "dbg.h"
  10. static POSVERSIONINFO GetOSVersion(VOID)
  11. {
  12. static BOOL fFirst = TRUE;
  13. static OSVERSIONINFO os;
  14. if ( fFirst ) {
  15. os.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  16. if (GetVersionEx( &os ) ) {
  17. fFirst = FALSE;
  18. }
  19. }
  20. return &os;
  21. }
  22. static BOOL ExIsWinNT(VOID)
  23. {
  24. return (GetOSVersion()->dwPlatformId == VER_PLATFORM_WIN32_NT);
  25. }
  26. #define TIMERID_MONITORPOS 0x98
  27. //LIZHANG 10/27/97
  28. #define TIMERID_DOUBLEORSINGLECLICKED 0x99
  29. //----------------------------------------------------------------
  30. //Get, Set LPCEXButton this pointer.
  31. //this is set to cbWndExtra.
  32. //See WinRegister()
  33. //----------------------------------------------------------------
  34. inline LPCEXButton GetThis(HWND hwnd)
  35. {
  36. #ifdef _WIN64
  37. return (LPCEXButton)GetWindowLongPtr(hwnd, 0);
  38. #else
  39. return (LPCEXButton)GetWindowLong(hwnd, 0);
  40. #endif
  41. }
  42. //----------------------------------------------------------------
  43. inline LPCEXButton SetThis(HWND hwnd, LPCEXButton lpEXB)
  44. {
  45. #ifdef _WIN64
  46. return (LPCEXButton)SetWindowLongPtr(hwnd, 0, (LONG_PTR)lpEXB);
  47. #else
  48. return (LPCEXButton)SetWindowLong(hwnd, 0, (LONG)lpEXB);
  49. #endif
  50. }
  51. //////////////////////////////////////////////////////////////////
  52. // Function : WndProc
  53. // Type : static LRESULT CALLBACK
  54. // Purpose : Window Procedure for Extended button.
  55. // Args :
  56. // : HWND hwnd
  57. // : UINT uMsg
  58. // : WPARAM wParam
  59. // : LPARAM lParam
  60. // Return :
  61. // DATE : 970905
  62. //////////////////////////////////////////////////////////////////
  63. static LRESULT CALLBACK WndProc(HWND hwnd,
  64. UINT uMsg,
  65. WPARAM wParam,
  66. LPARAM lParam)
  67. {
  68. LPCEXButton lpEXB;
  69. //Dbg(("WndProc hwnd[0x%08x] uMsg[0x%08x]\n", hwnd, uMsg));
  70. #ifndef UNDER_CE // #ifdef _DEBUG ?
  71. HWND hwndCap = ::GetCapture();
  72. char szBuf[256];
  73. if(hwndCap) {
  74. ::GetClassNameA(hwndCap, szBuf, sizeof(szBuf));
  75. Dbg(("-->Capture [0x%08x][%s]\n", hwndCap, szBuf));
  76. }
  77. #endif // UNDER_CE
  78. if(uMsg == WM_CREATE) {
  79. lpEXB = (LPCEXButton)((LPCREATESTRUCT)lParam)->lpCreateParams;
  80. if(!lpEXB) {
  81. return 0; // do not create button
  82. }
  83. SetThis(hwnd, lpEXB);
  84. lpEXB->MsgCreate(hwnd, wParam, lParam);
  85. return 1;
  86. }
  87. if(uMsg == WM_DESTROY) {
  88. lpEXB = GetThis(hwnd);
  89. if(lpEXB) {
  90. delete lpEXB;
  91. }
  92. SetThis(hwnd, (LPCEXButton)NULL);
  93. return DefWindowProc(hwnd, uMsg, wParam, lParam);
  94. }
  95. lpEXB = GetThis(hwnd);
  96. if(!lpEXB) {
  97. return DefWindowProc(hwnd, uMsg, wParam, lParam);
  98. }
  99. switch(uMsg) {
  100. case WM_PAINT:
  101. return lpEXB->MsgPaint(hwnd, wParam, lParam);
  102. break;
  103. case WM_MOUSEMOVE:
  104. lpEXB->MsgMouseMove(hwnd, wParam, lParam);
  105. break;
  106. case WM_TIMER:
  107. return lpEXB->MsgTimer(hwnd, wParam, lParam);
  108. case WM_CAPTURECHANGED:
  109. return lpEXB->MsgCaptureChanged(hwnd, wParam, lParam);
  110. case WM_NCLBUTTONDBLCLK:
  111. case WM_NCRBUTTONDBLCLK:
  112. case WM_NCMBUTTONDBLCLK:
  113. case WM_NCLBUTTONDOWN:
  114. case WM_NCMBUTTONDOWN:
  115. case WM_NCRBUTTONDOWN:
  116. lpEXB->MsgNcButtonDown(hwnd, uMsg, wParam, lParam);
  117. break;
  118. case WM_NCLBUTTONUP:
  119. case WM_NCMBUTTONUP:
  120. case WM_NCRBUTTONUP:
  121. lpEXB->MsgNcButtonUp(hwnd, uMsg, wParam, lParam);
  122. break;
  123. case WM_NCMOUSEMOVE:
  124. lpEXB->MsgNcMouseMove(hwnd, wParam, lParam);
  125. break;
  126. case WM_LBUTTONDBLCLK:
  127. case WM_MBUTTONDBLCLK:
  128. case WM_RBUTTONDBLCLK:
  129. case WM_LBUTTONDOWN:
  130. case WM_MBUTTONDOWN:
  131. case WM_RBUTTONDOWN:
  132. lpEXB->MsgButtonDown(hwnd, uMsg, wParam, lParam);
  133. break;
  134. case WM_LBUTTONUP:
  135. case WM_MBUTTONUP:
  136. case WM_RBUTTONUP:
  137. lpEXB->MsgButtonUp(hwnd, uMsg, wParam, lParam);
  138. break;
  139. case WM_ENABLE:
  140. lpEXB->MsgEnable(hwnd, wParam, lParam);
  141. break;
  142. case WM_SETFONT:
  143. lpEXB->MsgSetFont(hwnd, wParam, lParam);
  144. break;
  145. case EXBM_GETCHECK: return lpEXB->MsgEXB_GetCheck (hwnd, wParam, lParam);
  146. case EXBM_SETCHECK: return lpEXB->MsgEXB_SetCheck (hwnd, wParam, lParam);
  147. case EXBM_SETICON: return lpEXB->MsgEXB_SetIcon (hwnd, wParam, lParam);
  148. case EXBM_SETTEXT: return lpEXB->MsgEXB_SetText (hwnd, wParam, lParam);
  149. case EXBM_SETSTYLE: return lpEXB->MsgEXB_SetStyle (hwnd, wParam, lParam);
  150. default:
  151. break;
  152. }
  153. return DefWindowProc(hwnd, uMsg, wParam, lParam);
  154. }
  155. //////////////////////////////////////////////////////////////////
  156. // Function : CEXButton
  157. // Type :
  158. // Purpose : Constructor
  159. // Args :
  160. // : HINSTANCE hInst
  161. // : HWND hwndParent
  162. // : DWORD dwStyle
  163. // Return :
  164. // DATE :
  165. //////////////////////////////////////////////////////////////////
  166. CEXButton::CEXButton(HINSTANCE hInst, HWND hwndParent, DWORD dwStyle, DWORD wID)
  167. {
  168. m_hInst = hInst;
  169. m_hwndParent = hwndParent;
  170. m_dwStyle = dwStyle;
  171. m_hFont = NULL;
  172. m_wID = wID;
  173. m_lpwstrText = NULL;
  174. m_fPushed = FALSE;
  175. m_fEnable = TRUE;
  176. m_fDblClked = FALSE; // kwada raid:#852
  177. m_fWaiting = FALSE; // kwada raid:#852
  178. m_fArmed = FALSE; // kwada raid:#852
  179. #ifdef NOTUSED // kwada raid:#852
  180. m_wNotifyMsg = EXBN_CLICKED;
  181. #endif
  182. //----------------------------------------------------------------
  183. // for 16bit Application(for Word6.0)
  184. //----------------------------------------------------------------
  185. m_f16bitOnNT = FALSE;
  186. #ifndef UNDER_CE // Windows CE always 32bit application
  187. if(ExIsWinNT()) {
  188. char szBuf[256];
  189. DWORD dwType = 0;
  190. ::GetModuleFileName(NULL, szBuf, sizeof(szBuf));
  191. ::GetBinaryType(szBuf, &dwType);
  192. if(dwType == SCS_WOW_BINARY) {
  193. m_f16bitOnNT = TRUE;
  194. }
  195. }
  196. #endif // UNDER_CE
  197. }
  198. //////////////////////////////////////////////////////////////////
  199. // Function : ~CEXButton
  200. // Type :
  201. // Purpose : Destructor
  202. // Args :
  203. // :
  204. // Return :
  205. // DATE :
  206. //////////////////////////////////////////////////////////////////
  207. CEXButton::~CEXButton()
  208. {
  209. Dbg(("~CEXButton \n"));
  210. if(m_hIcon) {
  211. Dbg(("DestroyIcon\n"));
  212. DestroyIcon(m_hIcon);
  213. m_hIcon = NULL;
  214. }
  215. if(m_hFont) {
  216. Dbg(("Delete FONT\n"));
  217. DeleteObject(m_hFont);
  218. m_hFont = NULL;
  219. }
  220. if(m_lpwstrText) {
  221. MemFree(m_lpwstrText);
  222. m_lpwstrText = NULL;
  223. }
  224. }
  225. //////////////////////////////////////////////////////////////////
  226. // Function : RegisterWinClass
  227. // Type : BOOL
  228. // Purpose :
  229. // Args :
  230. // : LPSTR lpstrClassName
  231. // Return :
  232. // DATE :
  233. //////////////////////////////////////////////////////////////////
  234. #ifndef UNDER_CE
  235. BOOL CEXButton::RegisterWinClass(LPSTR lpstrClass)
  236. #else // UNDER_CE
  237. BOOL CEXButton::RegisterWinClass(LPTSTR lpstrClass)
  238. #endif // UNDER_CE
  239. {
  240. ATOM ret;
  241. //----------------------------------------------------------------
  242. //check specified class is already exist or not
  243. //----------------------------------------------------------------
  244. #ifndef UNDER_CE // Windows CE does not support EX
  245. if(::GetClassInfoEx(m_hInst, lpstrClass, &m_tmpWC)){
  246. #else // UNDER_CE
  247. if(::GetClassInfo(m_hInst, lpstrClass, &m_tmpWC)){
  248. #endif // UNDER_CE
  249. //lpstrClass is already registerd.
  250. return TRUE;
  251. }
  252. ::ZeroMemory(&m_tmpWC, sizeof(m_tmpWC));
  253. #ifndef UNDER_CE // Windows CE does not support EX
  254. m_tmpWC.cbSize = sizeof(m_tmpWC);
  255. #endif // UNDER_CE
  256. m_tmpWC.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; /* Class style(s). */
  257. m_tmpWC.lpfnWndProc = (WNDPROC)WndProc;
  258. m_tmpWC.cbClsExtra = 0; /* No per-class extra data.*/
  259. m_tmpWC.cbWndExtra = sizeof(LPCEXButton); // Set Object's pointer.
  260. m_tmpWC.hInstance = m_hInst; /* Application that owns the class. */
  261. m_tmpWC.hIcon = NULL;
  262. m_tmpWC.hCursor = LoadCursor(NULL, IDC_ARROW);
  263. m_tmpWC.hbrBackground = (HBRUSH)NULL;
  264. //m_tmpWC.hbrBackground = (HBRUSH)(COLOR_3DFACE+1);
  265. m_tmpWC.lpszMenuName = NULL; /* Name of menu resource in .RC file. */
  266. m_tmpWC.lpszClassName = lpstrClass; /* Name used in call to CreateWindow. */
  267. #ifndef UNDER_CE // Windows CE does not support EX
  268. m_tmpWC.hIconSm = NULL;
  269. ret = ::RegisterClassEx(&m_tmpWC);
  270. #else // UNDER_CE
  271. ret = ::RegisterClass(&m_tmpWC);
  272. #endif // UNDER_CE
  273. return ret ? TRUE: FALSE;
  274. }
  275. INT CEXButton::MsgCreate(HWND hwnd, WPARAM wParam, LPARAM lParam)
  276. {
  277. m_hwndFrame = hwnd;
  278. return 1;
  279. UnrefForMsg();
  280. }
  281. //////////////////////////////////////////////////////////////////
  282. // Function : CEXButton::MsgPaint
  283. // Type : INT
  284. // Purpose :
  285. // Args :
  286. // : HWND hwnd
  287. // : WPARAM wParam
  288. // : LPARAM lParam
  289. // Return :
  290. // DATE :
  291. //////////////////////////////////////////////////////////////////
  292. INT CEXButton::MsgPaint(HWND hwnd, WPARAM wParam, LPARAM lParam)
  293. {
  294. PAINTSTRUCT ps;
  295. RECT rc;
  296. HDC hDCMem;
  297. HDC hDC;
  298. HBITMAP hBitmap, hBitmapPrev;
  299. ::GetClientRect(hwnd, &rc);
  300. hDC = ::BeginPaint(hwnd, &ps);
  301. hDCMem = ::CreateCompatibleDC(hDC);
  302. hBitmap = ::CreateCompatibleBitmap(hDC, rc.right - rc.left, rc.bottom - rc.top);
  303. hBitmapPrev = (HBITMAP)::SelectObject(hDCMem, hBitmap);
  304. DrawButton(hDCMem, &rc);
  305. ::BitBlt(hDC, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top,
  306. hDCMem, 0, 0, SRCCOPY);
  307. ::SelectObject(hDCMem, hBitmapPrev );
  308. ::DeleteObject(hBitmap);
  309. ::DeleteDC(hDCMem);
  310. ::EndPaint(hwnd, &ps);
  311. return 0;
  312. UnrefForMsg();
  313. }
  314. INT CEXButton::MsgDestroy(HWND hwnd, WPARAM wParam, LPARAM lParam)
  315. {
  316. return 0;
  317. UnrefForMsg();
  318. }
  319. //////////////////////////////////////////////////////////////////
  320. // Function : CEXButton::MsgTimer
  321. // Type : INT
  322. // Purpose : wait for the second click
  323. // Args :
  324. // : HWND hwnd
  325. // : WPARAM wParam
  326. // : LPARAM lParam
  327. // Return :
  328. // DATE :
  329. // : change for raid #852. kwada:980402
  330. //////////////////////////////////////////////////////////////////
  331. INT CEXButton::MsgTimer(HWND hwnd, WPARAM wParam, LPARAM lParam)
  332. {
  333. static RECT rc;
  334. static POINT pt;
  335. switch(wParam) {
  336. #ifndef UNDER_CE // no monitor position. (not support GetCursorPos)
  337. case TIMERID_MONITORPOS:
  338. Dbg(("MsgTimer TIMERID_MONITORPOS\n"));
  339. ::GetWindowRect(hwnd, &rc);
  340. ::GetCursorPos(&pt);
  341. if(!::PtInRect(&rc, pt)) {
  342. ::KillTimer(hwnd, wParam);
  343. ::InvalidateRect(hwnd, NULL, NULL);
  344. }
  345. break;
  346. #endif // UNDER_CE
  347. case TIMERID_DOUBLEORSINGLECLICKED:
  348. {
  349. Dbg(("MsgTimer TIMERID_DOUBLEORSINGLECLICKED\n"));
  350. KillTimer(hwnd, wParam);
  351. m_fWaiting = FALSE;
  352. if(!m_fDowned) // The second click didn't come. kwada raid:#852
  353. NotifyClickToParent(EXBN_CLICKED);
  354. }
  355. break;
  356. }
  357. return 0;
  358. UnrefForMsg();
  359. }
  360. //////////////////////////////////////////////////////////////////
  361. // Function : CEXButton::MsgMouseMove
  362. // Type : INT
  363. // Purpose :
  364. // Args :
  365. // : HWND hwnd
  366. // : WPARAM wParam
  367. // : LPARAM lParam
  368. // Return :
  369. // DATE :
  370. // : change for raid #852. kwada:980402
  371. //////////////////////////////////////////////////////////////////
  372. INT CEXButton::MsgMouseMove(HWND hwnd, WPARAM wParam, LPARAM lParam)
  373. {
  374. Dbg(("MsgMouseMove START \n"));
  375. if(m_fDowned) { // Mouse was already DOWNED,Captured.
  376. if(m_f16bitOnNT) {
  377. #ifndef UNDER_CE // Windows CE always 32bit application
  378. RECT rc;
  379. POINT pt;
  380. ::GetWindowRect(hwnd, &rc);
  381. ::GetCursorPos(&pt);
  382. if(!::PtInRect(&rc, pt)) {
  383. ::InvalidateRect(hwnd, NULL, NULL);
  384. return 0;
  385. }
  386. #endif // UNDER_CE
  387. }
  388. else { //normal case
  389. m_tmpPoint.x = LOWORD(lParam);
  390. m_tmpPoint.y = HIWORD(lParam);
  391. GetClientRect(hwnd, &m_tmpRect);
  392. if(PtInRect(&m_tmpRect, m_tmpPoint)) // moved to inside
  393. PressedState();
  394. else // moved to outside
  395. CancelPressedState();
  396. }
  397. }
  398. InvalidateRect(hwnd, NULL, FALSE);
  399. Dbg(("MsgMouseMove END\n"));
  400. return 0;
  401. UnrefForMsg();
  402. }
  403. INT CEXButton::MsgNcMouseMove(HWND hwnd, WPARAM wParam, LPARAM lParam)
  404. {
  405. Dbg(("MsgNcMouseMove START \n"));
  406. return 0;
  407. UnrefForMsg();
  408. }
  409. //////////////////////////////////////////////////////////////////
  410. // Function : CEXButton::MsgButtonDown
  411. // Type : INT
  412. // Purpose :
  413. // Args :
  414. // : HWND hwnd
  415. // : UINT uMsg
  416. // : WPARAM wParam
  417. // : LPARAM lParam
  418. // Return :
  419. // DATE :
  420. // : change for raid #852. kwada:980402
  421. //////////////////////////////////////////////////////////////////
  422. INT CEXButton::MsgButtonDown(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  423. {
  424. Dbg(("MsgButtonDown START wParam[0x%08x] lParam[0x%08x]\n", wParam, lParam));
  425. static RECT rc;
  426. POINT pt;
  427. pt.x = LOWORD(lParam);
  428. pt.y = HIWORD(lParam);
  429. if(uMsg != WM_LBUTTONDOWN && uMsg != WM_LBUTTONDBLCLK) {
  430. Dbg(("MsgButtonDown END\n"));
  431. return 0;
  432. }
  433. if(!m_fEnable) {
  434. Dbg(("MsgButtonDown END\n"));
  435. return 0;
  436. }
  437. GetClientRect(hwnd, &rc);
  438. if(m_dwStyle & EXBS_DBLCLKS) { // accept double clicks
  439. Dbg(("MsgButtonDown \n"));
  440. KillTimer(hwnd, TIMERID_DOUBLEORSINGLECLICKED);
  441. if ( uMsg == WM_LBUTTONDOWN ) {
  442. // mouse down
  443. //----------------------------------------------------------------
  444. //for 16bit application on WinNT, do not call SetCapture()
  445. //----------------------------------------------------------------
  446. if(m_f16bitOnNT) {
  447. #ifndef UNDER_CE // Windows CE always 32bit application
  448. #ifdef _DEBUG
  449. UINT_PTR ret = ::SetTimer(hwnd, TIMERID_MONITORPOS, 100, NULL);
  450. Dbg(("SetTimer [%p][%d]\n", ret, GetLastError()));
  451. #else
  452. ::SetTimer(hwnd, TIMERID_MONITORPOS, 100, NULL);
  453. #endif
  454. #endif // UNDER_CE
  455. }
  456. else {
  457. SetCapture(hwnd);
  458. }
  459. m_fDowned = TRUE;
  460. m_fDblClked = FALSE;
  461. PressedState();
  462. // timer on - wait for the second click.
  463. m_fWaiting = TRUE;
  464. SetTimer(hwnd, TIMERID_DOUBLEORSINGLECLICKED, GetDoubleClickTime(), NULL);
  465. }
  466. else { // uMsg == WM_LBUTTONDBLCLK
  467. Dbg(("MsgButtonDown \n"));
  468. // mouse down
  469. if(m_f16bitOnNT) {
  470. #ifdef _DEBUG
  471. UINT_PTR ret = ::SetTimer(hwnd, TIMERID_MONITORPOS, 100, NULL);
  472. Dbg(("SetTimer [%p][%d]\n", ret, GetLastError()));
  473. #else
  474. ::SetTimer(hwnd, TIMERID_MONITORPOS, 100, NULL);
  475. #endif
  476. }
  477. else {
  478. SetCapture(hwnd);
  479. }
  480. m_fDowned = TRUE;
  481. m_fDblClked = m_fWaiting ? TRUE : FALSE; // consider if DBLCLK comes after timeout
  482. m_fWaiting = FALSE;
  483. PressedState();
  484. }
  485. }else { // single click only
  486. // LBUTTONDOWN & LBUTTONDBLCLK
  487. // mouse down
  488. if(m_f16bitOnNT) {
  489. #ifndef UNDER_CE // Windows CE always 32bit application
  490. #ifdef _DEBUG
  491. UINT_PTR ret = ::SetTimer(hwnd, TIMERID_MONITORPOS, 100, NULL);
  492. Dbg(("SetTimer [%p][%d]\n", ret, GetLastError()));
  493. #else
  494. ::SetTimer(hwnd, TIMERID_MONITORPOS, 100, NULL);
  495. #endif
  496. #endif // UNDER_CE
  497. }
  498. else {
  499. SetCapture(hwnd);
  500. }
  501. m_fDowned = TRUE;
  502. m_fDblClked = FALSE;
  503. PressedState();
  504. }
  505. InvalidateRect(hwnd, NULL, FALSE);
  506. Dbg(("MsgButtonDown END\n"));
  507. return 0;
  508. UnrefForMsg();
  509. }
  510. INT CEXButton::MsgNcButtonDown(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  511. {
  512. Dbg(("MsgNcButtonDown START\n"));
  513. return 0;
  514. Unref(uMsg);
  515. UnrefForMsg();
  516. }
  517. INT CEXButton::MsgNcButtonUp(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  518. {
  519. Dbg(("MsgNcButtonUp START\n"));
  520. return 0;
  521. Unref(uMsg);
  522. UnrefForMsg();
  523. }
  524. //////////////////////////////////////////////////////////////////
  525. // Function : CEXButton::MsgButtonUp
  526. // Type : INT
  527. // Purpose :
  528. // Args :
  529. // : HWND hwnd
  530. // : UINT uMsg
  531. // : WPARAM wParam
  532. // : LPARAM lParam
  533. // Return :
  534. // DATE :
  535. // : change for raid #852. kwada:980402
  536. //////////////////////////////////////////////////////////////////
  537. INT CEXButton::MsgButtonUp(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  538. {
  539. Dbg(("MsgButtonUp START\n"));
  540. static RECT rc;
  541. POINT pt;
  542. if(uMsg != WM_LBUTTONUP) {
  543. Dbg(("MsgButtonUp END\n"));
  544. return 0;
  545. }
  546. if(!m_fEnable) {
  547. Dbg(("MsgButtonUp END\n"));
  548. return 0;
  549. }
  550. pt.x = LOWORD(lParam);
  551. pt.y = HIWORD(lParam);
  552. GetClientRect(hwnd, &rc);
  553. if(m_dwStyle & EXBS_DBLCLKS) {
  554. if(m_fDowned) // captured
  555. {
  556. if(PtInRect(&rc, pt)) // inside
  557. {
  558. if(m_fDblClked) { // end of double click
  559. m_fDblClked = FALSE;
  560. NotifyClickToParent(EXBN_DOUBLECLICKED);
  561. }
  562. else { // end of single click
  563. if(!m_fWaiting) // after timeout - second click won't come.
  564. NotifyClickToParent(EXBN_CLICKED);
  565. }
  566. }
  567. }
  568. }
  569. else { // single click only
  570. if(m_fDowned) // captured
  571. {
  572. if(PtInRect(&rc, pt))
  573. NotifyClickToParent(EXBN_CLICKED);
  574. else
  575. CancelPressedState();
  576. }
  577. }
  578. #ifndef UNDER_CE // Windows CE always 32bit application
  579. if(m_f16bitOnNT) {
  580. ::KillTimer(hwnd, TIMERID_MONITORPOS);
  581. }
  582. #endif // UNDER_CE
  583. //if(hwnd == GetCapture()) {
  584. ReleaseCapture();
  585. //}
  586. m_fDowned = FALSE;
  587. InvalidateRect(hwnd, NULL, FALSE);
  588. Dbg(("MsgButtonUp END\n"));
  589. return 0;
  590. Unref(uMsg);
  591. UnrefForMsg();
  592. }
  593. //////////////////////////////////////////////////////////////////
  594. // Function : CEXButton::MsgEnable
  595. // Type : INT
  596. // Purpose :
  597. // Args :
  598. // : HWND hwnd
  599. // : WPARAM wParam
  600. // : LPARAM lParam
  601. // Return :
  602. // DATE :
  603. //////////////////////////////////////////////////////////////////
  604. INT CEXButton::MsgEnable(HWND hwnd, WPARAM wParam, LPARAM lParam)
  605. {
  606. //Dbg(("MsgEnabled START wParam[%d]\n", wParam));
  607. m_fEnable = (BOOL)wParam;
  608. InvalidateRect(hwnd, NULL, FALSE);
  609. return 0;
  610. UnrefForMsg();
  611. }
  612. INT CEXButton::MsgSetFont(HWND hwnd, WPARAM wParam, LPARAM lParam)
  613. {
  614. HFONT hFont = (HFONT)wParam;
  615. BOOL fRedraw = LOWORD(lParam);
  616. HFONT hFontNew;
  617. if(!hFont) {
  618. return 0;
  619. }
  620. #ifndef UNDER_CE
  621. LOGFONTA logFont;
  622. #else // UNDER_CE
  623. LOGFONT logFont;
  624. #endif // UNDER_CE
  625. ::GetObject(hFont, sizeof(logFont), &logFont);
  626. hFontNew = ::CreateFontIndirect(&logFont);
  627. if(!hFontNew) {
  628. return 0;
  629. }
  630. if(m_hFont) {
  631. ::DeleteObject(m_hFont);
  632. }
  633. m_hFont = hFontNew;
  634. if(fRedraw) {
  635. ::InvalidateRect(hwnd, NULL, TRUE);
  636. }
  637. return 0;
  638. }
  639. //////////////////////////////////////////////////////////////////
  640. // Function : CEXButton::MsgCaptureChanged
  641. // Type : INT
  642. // Purpose :
  643. // Args :
  644. // : HWND hwnd
  645. // : WPARAM wParam
  646. // : LPARAM lParam
  647. // Return :
  648. // DATE :
  649. //////////////////////////////////////////////////////////////////
  650. INT CEXButton::MsgCaptureChanged(HWND hwnd, WPARAM wParam, LPARAM lParam)
  651. {
  652. Dbg(("MsgCaptureChanged START \n"));
  653. #ifdef _DEBUG
  654. HWND hwndCap = ::GetCapture();
  655. CHAR szBuf[256];
  656. szBuf[0] = (CHAR)0x00;
  657. ::GetClassName(hwndCap, szBuf, sizeof(szBuf));
  658. Dbg(("-->hwndCap [0x%08x][%s]\n", hwndCap, szBuf));
  659. #endif
  660. //m_fDowned = FALSE;
  661. InvalidateRect(hwnd, NULL, FALSE);
  662. return 0;
  663. UnrefForMsg();
  664. }
  665. //////////////////////////////////////////////////////////////////
  666. // Function : CEXButton::MsgEXB_GetCheck
  667. // Type : INT
  668. // Purpose :
  669. // Args :
  670. // : HWND hwnd
  671. // : WPARAM wParam
  672. // : LPARAM lParam
  673. // Return :
  674. // DATE :
  675. //////////////////////////////////////////////////////////////////
  676. INT CEXButton::MsgEXB_GetCheck(HWND hwnd, WPARAM wParam, LPARAM lParam)
  677. {
  678. return m_fPushed;
  679. UnrefForMsg();
  680. }
  681. //////////////////////////////////////////////////////////////////
  682. // Function : CEXButton::MsgEXB_SetCheck
  683. // Type : INT
  684. // Purpose :
  685. // Args :
  686. // : HWND hwnd
  687. // : WPARAM wParam
  688. // : LPARAM lParam
  689. // Return :
  690. // DATE :
  691. //////////////////////////////////////////////////////////////////
  692. INT CEXButton::MsgEXB_SetCheck(HWND hwnd, WPARAM wParam, LPARAM lParam)
  693. {
  694. BOOL fPrev = m_fPushed;
  695. //
  696. //m_fPushed is Always 1 or 0. do not set != 0 data as TRUE
  697. m_fPushed = (BOOL)wParam ? 1 : 0;
  698. if(m_dwStyle & EXBS_TOGGLE){
  699. if(fPrev != m_fPushed) {
  700. NotifyToParent(m_fPushed ? EXBN_ARMED : EXBN_DISARMED);
  701. }
  702. }
  703. m_fArmed = m_fPushed;
  704. InvalidateRect(hwnd, NULL, FALSE);
  705. return m_fPushed;
  706. UnrefForMsg();
  707. }
  708. //////////////////////////////////////////////////////////////////
  709. // Function : CEXButton::MsgEXB_SetIcon
  710. // Type : INT
  711. // Purpose : Set new icon.
  712. // Args :
  713. // : HWND hwnd
  714. // : WPARAM wParam HICON hIcon.
  715. // : LPARAM lParam no use.
  716. // Return :
  717. // DATE :
  718. //////////////////////////////////////////////////////////////////
  719. INT CEXButton::MsgEXB_SetIcon(HWND hwnd, WPARAM wParam, LPARAM lParam)
  720. {
  721. //Dbg(("MsgEXB_SetIcon: wParam[0x%08x] lParam[0x%08x]\n", wParam, lParam));
  722. if((HICON)wParam == NULL) {
  723. Dbg(("MsgEXB_SetIcon: ERROR END\n"));
  724. return -1;
  725. }
  726. //if icon style is not set, destroy specified icon
  727. if(!(m_dwStyle & EXBS_ICON)) {
  728. DestroyIcon((HICON)wParam);
  729. return -1;
  730. }
  731. if(m_hIcon) {
  732. DestroyIcon(m_hIcon);
  733. }
  734. m_hIcon = (HICON)wParam;
  735. //----------------------------------------------------------------
  736. //Get Icon width and height.
  737. //----------------------------------------------------------------
  738. #ifndef UNDER_CE // Windows CE does not support GetIconInfo()
  739. ZeroMemory(&m_tmpIconInfo, sizeof(m_tmpIconInfo));
  740. ::GetIconInfo(m_hIcon, &m_tmpIconInfo);
  741. //Dbg(("fIcon [%d]\n", m_tmpIconInfo.fIcon ));
  742. //Dbg(("xHotspot [%d]\n", m_tmpIconInfo.xHotspot ));
  743. //Dbg(("yHotspot [%d]\n", m_tmpIconInfo.yHotspot ));
  744. //Dbg(("hbmMask [0x%08x]\n", m_tmpIconInfo.hbmMask ));
  745. //Dbg(("hbmColor [0x%08x]\n", m_tmpIconInfo.hbmColor ));
  746. if(m_tmpIconInfo.hbmMask) {
  747. GetObject(m_tmpIconInfo.hbmMask, sizeof(m_tmpBitmap), &m_tmpBitmap);
  748. #if 0
  749. Dbg(("bmWidth[%d] bmHeight[%d]\n",
  750. m_tmpBitmap.bmWidth,
  751. m_tmpBitmap.bmHeight));
  752. #endif
  753. DeleteObject(m_tmpIconInfo.hbmMask);
  754. m_cxIcon = m_tmpBitmap.bmWidth;
  755. m_cyIcon = m_tmpBitmap.bmHeight;
  756. }
  757. if(m_tmpIconInfo.hbmColor) {
  758. DeleteObject(m_tmpIconInfo.hbmColor);
  759. }
  760. #else // UNDER_CE
  761. m_cxIcon = GetSystemMetrics(SM_CXSMICON);
  762. m_cyIcon = GetSystemMetrics(SM_CYSMICON);
  763. #endif // UNDER_CE
  764. InvalidateRect(hwnd, NULL, FALSE);
  765. UpdateWindow(hwnd);
  766. return 0;
  767. UnrefForMsg();
  768. }
  769. //////////////////////////////////////////////////////////////////
  770. // Function : CEXButton::MsgEXB_SetText
  771. // Type : INT
  772. // Purpose :
  773. // Args :
  774. // : HWND hwnd
  775. // : WPARAM wParam LPWSTR lpwstr: null terminated Unicode string.
  776. // : LPARAM lParam no use.
  777. // Return :
  778. // DATE :
  779. //////////////////////////////////////////////////////////////////
  780. INT CEXButton::MsgEXB_SetText(HWND hwnd, WPARAM wParam, LPARAM lParam)
  781. {
  782. //Dbg(("MsgEXB_SetText START wParam[0x%08x]\n", wParam));
  783. if(!(LPWSTR)wParam) {
  784. Dbg(("--->Error \n"));
  785. return -1;
  786. }
  787. if( ((LPWSTR)wParam)[0] == (WCHAR)0x0000) {
  788. Dbg(("--->Error \n"));
  789. return -1;
  790. }
  791. if(m_lpwstrText) {
  792. MemFree(m_lpwstrText);
  793. }
  794. m_lpwstrText = StrdupW((LPWSTR)wParam);
  795. //DBGW((L"--->NEW m_lpwstrText [%s]\n", m_lpwstrText));
  796. InvalidateRect(hwnd, NULL, FALSE);
  797. return 0;
  798. Unref(lParam);
  799. }
  800. //////////////////////////////////////////////////////////////////
  801. // Function : CEXButton::MsgEXB_SetStyle
  802. // Type : INT
  803. // Purpose :
  804. // Args :
  805. // : HWND hwnd
  806. // : WPARAM wParam DWORD dwStyle:
  807. // : LPARAM lParam no use.
  808. // Return :
  809. // DATE :
  810. // : modified by kwada:980402
  811. //////////////////////////////////////////////////////////////////
  812. INT CEXButton::MsgEXB_SetStyle(HWND hwnd, WPARAM wParam, LPARAM lParam)
  813. {
  814. DWORD dwStyle = (DWORD)wParam;
  815. m_dwStyle = dwStyle;
  816. if(m_dwStyle & EXBS_TOGGLE)
  817. m_fArmed = m_fPushed;
  818. else
  819. m_fArmed = m_fDowned;
  820. InvalidateRect(hwnd, NULL, FALSE);
  821. return 0;
  822. Unref(hwnd);
  823. Unref(lParam);
  824. }
  825. //----------------------------------------------------------------
  826. //Private method definition
  827. //----------------------------------------------------------------
  828. //////////////////////////////////////////////////////////////////
  829. // Function : CEXButton::NotifyToParent
  830. // Type : INT
  831. // Purpose : Send WM_COMMAND to Parent window procedure.
  832. // Args :
  833. // : INT notify
  834. // Return :
  835. // DATE :
  836. //////////////////////////////////////////////////////////////////
  837. INT CEXButton::NotifyToParent(INT notify)
  838. {
  839. SendMessage(m_hwndParent,
  840. WM_COMMAND,
  841. MAKEWPARAM(m_wID, notify),
  842. (LPARAM)m_hwndFrame);
  843. return 0;
  844. }
  845. //////////////////////////////////////////////////////////////////
  846. // Function : CEXButton::NotifyClickToParent
  847. // Type : INT
  848. // Purpose : Change state and send click to the parent window.
  849. // Args :
  850. // : INT notify (EXBN_CLICKED or EXBN_DOUBLECLICKED)
  851. // Return :
  852. // DATE : kwada:980402 for raid #852
  853. //////////////////////////////////////////////////////////////////
  854. INT CEXButton::NotifyClickToParent(INT notify)
  855. {
  856. if(m_dwStyle & EXBS_TOGGLE) { // toggle state for toggle button
  857. m_fPushed ^=1;
  858. if(m_fArmed && !m_fPushed) {
  859. NotifyToParent(EXBN_DISARMED);
  860. }
  861. else if(!m_fArmed && m_fPushed) {
  862. NotifyToParent(EXBN_ARMED);
  863. }
  864. m_fArmed = m_fPushed;
  865. }
  866. else { // push button
  867. if(m_fArmed) {
  868. m_fArmed = FALSE;
  869. NotifyToParent(EXBN_DISARMED);
  870. }
  871. }
  872. NotifyToParent(notify);
  873. return 0;
  874. }
  875. //////////////////////////////////////////////////////////////////
  876. // Function : CEXButton::PressedState
  877. // Type : INT
  878. // Purpose : Change apparence:turn to pressed state
  879. // Args :
  880. // :
  881. // Return :
  882. // DATE : kwada:980402 for raid #852
  883. //////////////////////////////////////////////////////////////////
  884. INT CEXButton::PressedState()
  885. {
  886. if(!m_fArmed){
  887. NotifyToParent(EXBN_ARMED);
  888. m_fArmed = TRUE;
  889. }
  890. return 0;
  891. }
  892. //////////////////////////////////////////////////////////////////
  893. // Function : CEXButton::CancelPressedState
  894. // Type : INT
  895. // Purpose : Change apparence:back to original state
  896. // Args :
  897. // :
  898. // Return :
  899. // DATE : kwada:980402 for raid #852
  900. //////////////////////////////////////////////////////////////////
  901. INT CEXButton::CancelPressedState()
  902. {
  903. if(m_dwStyle & EXBS_TOGGLE) {
  904. if(m_fArmed && !m_fPushed) {
  905. NotifyToParent(EXBN_DISARMED);
  906. }
  907. else if(!m_fArmed && m_fPushed) {
  908. NotifyToParent(EXBN_ARMED);
  909. }
  910. m_fArmed = m_fPushed;
  911. }
  912. else {
  913. if(m_fArmed) {
  914. NotifyToParent(EXBN_DISARMED);
  915. m_fArmed = FALSE;
  916. }
  917. }
  918. return 0;
  919. }
  920. //////////////////////////////////////////////////////////////////
  921. // Function : CEXButton::DrawButton
  922. // Type : INT
  923. // Purpose :
  924. // Args :
  925. // : HDC hDC
  926. // : LPRECT lpRc
  927. // Return :
  928. // DATE :
  929. //////////////////////////////////////////////////////////////////
  930. INT CEXButton::DrawButton(HDC hDC, LPRECT lpRc)
  931. {
  932. #if 0
  933. Dbg(("DrawButton Start l[%d] t[%d] r[%d] b[%d]\n",
  934. lpRc->left,
  935. lpRc->top,
  936. lpRc->right,
  937. lpRc->bottom));
  938. #endif
  939. #ifndef UNDER_CE // Windows CE does not support GetCursorPos()
  940. POINT pt;
  941. GetCursorPos(&pt);
  942. ScreenToClient(m_hwndFrame, &pt);
  943. #endif // UNDER_CE
  944. IMAGESTYLE styleBtn;
  945. DWORD dwOldTextColor, dwOldBkColor;
  946. BOOL fFlat = m_dwStyle & EXBS_FLAT;
  947. BOOL fToggle = (m_dwStyle & EXBS_TOGGLE) && m_fPushed;
  948. //Dbg(("m_dwStyle [0x%08x]\n", m_dwStyle));
  949. #if 0
  950. BOOL fMouseOnButton = PtInRect(lpRc, pt);
  951. Dbg(("fOnMouse [%d] fFlat[%d] fToggle[%d]\n",
  952. fMouseOnButton,
  953. fFlat,
  954. fToggle));
  955. #endif
  956. #ifndef UNDER_CE // Windows CE does not support GetCursorPos()
  957. if(fFlat && !PtInRect(lpRc, pt) && !m_fDowned) {
  958. #else // UNDER_CE
  959. if(fFlat && !m_fDowned) {
  960. #endif // UNDER_CE
  961. styleBtn = fToggle ? IS_PUSHED : IS_FLAT;
  962. }
  963. #ifdef OLD
  964. else if(PtInRect(lpRc, pt) && m_fDowned) {
  965. styleBtn = fToggle ? IS_POPED : IS_PUSHED;
  966. }
  967. else {
  968. styleBtn = fToggle ? IS_PUSHED : IS_POPED;
  969. }
  970. #else
  971. else {
  972. styleBtn = m_fArmed ? IS_PUSHED : IS_POPED; // kwada:980402 raid #852
  973. }
  974. #endif
  975. if(styleBtn == IS_PUSHED && (m_dwStyle & EXBS_TOGGLE) ) {
  976. // dither - kwada :raid #592
  977. HBITMAP hBitmap;
  978. HBRUSH hPatBrush,hOldBrush;
  979. WORD pat[8]={0x5555,0xAAAA,0x5555,0xAAAA,0x5555,0xAAAA,0x5555,0xAAAA};
  980. hPatBrush = NULL;
  981. hBitmap = ::CreateBitmap(8,8,1,1,pat);
  982. if(hBitmap)
  983. hPatBrush = ::CreatePatternBrush(hBitmap);
  984. if(hPatBrush) {
  985. hOldBrush = (HBRUSH)::SelectObject(hDC,hPatBrush);
  986. dwOldBkColor = ::SetBkColor(hDC,::GetSysColor(COLOR_3DHILIGHT));
  987. dwOldTextColor = ::SetTextColor(hDC,::GetSysColor(COLOR_3DFACE));
  988. ::FillRect(hDC, lpRc, hPatBrush);
  989. ::SetTextColor(hDC,dwOldTextColor);
  990. ::SetBkColor(hDC,dwOldBkColor);
  991. ::SelectObject(hDC,hOldBrush);
  992. ::DeleteObject(hPatBrush);
  993. }else
  994. #ifndef UNDER_CE
  995. ::FillRect(hDC, lpRc, (HBRUSH)(COLOR_3DHILIGHT +1));
  996. #else // UNDER_CE
  997. ::FillRect(hDC, lpRc, GetSysColorBrush(COLOR_3DHILIGHT));
  998. #endif // UNDER_CE
  999. if(hBitmap)
  1000. ::DeleteObject(hBitmap);
  1001. dwOldBkColor = ::SetBkColor(hDC, ::GetSysColor(COLOR_3DHILIGHT));
  1002. }
  1003. else {
  1004. #ifndef UNDER_CE
  1005. ::FillRect(hDC, lpRc, (HBRUSH)(COLOR_3DFACE +1));
  1006. #else // UNDER_CE
  1007. ::FillRect(hDC, lpRc, GetSysColorBrush(COLOR_3DFACE));
  1008. #endif // UNDER_CE
  1009. dwOldBkColor = ::SetBkColor(hDC, GetSysColor(COLOR_3DFACE));
  1010. }
  1011. dwOldTextColor = ::SetTextColor(hDC, GetSysColor(COLOR_WINDOWTEXT));
  1012. if(m_dwStyle & EXBS_THINEDGE) {
  1013. DrawThinEdge(hDC, lpRc, styleBtn);
  1014. }
  1015. else {
  1016. DrawThickEdge(hDC, lpRc, styleBtn);
  1017. }
  1018. if(m_dwStyle & EXBS_ICON) {
  1019. DrawIcon(hDC, lpRc, styleBtn);
  1020. }
  1021. else {
  1022. DrawText(hDC, lpRc, styleBtn);
  1023. }
  1024. ::SetBkColor(hDC, dwOldBkColor);
  1025. ::SetTextColor(hDC, dwOldTextColor);
  1026. return 0;
  1027. }
  1028. //////////////////////////////////////////////////////////////////
  1029. // Function : CEXButton::DrawThickEdge
  1030. // Type : INT
  1031. // Purpose :
  1032. // Args :
  1033. // : HDC hDC
  1034. // : LPRECT lpRc
  1035. // : IMAGESTYLE style
  1036. // Return :
  1037. // DATE :
  1038. //////////////////////////////////////////////////////////////////
  1039. INT CEXButton::DrawThickEdge(HDC hDC, LPRECT lpRc, IMAGESTYLE style)
  1040. {
  1041. if(style == IS_FLAT) {
  1042. return 0;
  1043. }
  1044. HPEN hPenOrig = NULL;
  1045. HPEN hPenWhite = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_3DHILIGHT));
  1046. HPEN hPenGlay = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_3DSHADOW));
  1047. HPEN hPenBlack = (HPEN)GetStockObject(BLACK_PEN);
  1048. switch(style) {
  1049. case IS_POPED:
  1050. hPenOrig = (HPEN)::SelectObject(hDC, hPenWhite);
  1051. DrawLine(hDC, lpRc->left, lpRc->top, lpRc->right-1, lpRc->top);
  1052. DrawLine(hDC, lpRc->left, lpRc->top, lpRc->left, lpRc->bottom - 1);
  1053. SelectObject(hDC, hPenGlay);
  1054. DrawLine(hDC, lpRc->right-2, lpRc->top+1, lpRc->right-2, lpRc->bottom - 1);
  1055. DrawLine(hDC, lpRc->left+1, lpRc->bottom-2, lpRc->right-1, lpRc->bottom - 2);
  1056. SelectObject(hDC, hPenBlack);
  1057. DrawLine(hDC, lpRc->right-1, lpRc->top, lpRc->right-1, lpRc->bottom);
  1058. DrawLine(hDC, lpRc->left, lpRc->bottom-1, lpRc->right, lpRc->bottom-1);
  1059. break;
  1060. case IS_PUSHED:
  1061. hPenOrig = (HPEN)::SelectObject(hDC, hPenBlack);
  1062. DrawLine(hDC, lpRc->left, lpRc->top, lpRc->right-1, lpRc->top);
  1063. DrawLine(hDC, lpRc->left, lpRc->top, lpRc->left, lpRc->bottom - 1);
  1064. SelectObject(hDC, hPenGlay);
  1065. DrawLine(hDC, lpRc->left+1, lpRc->top+1, lpRc->right-2, lpRc->top+1);
  1066. DrawLine(hDC, lpRc->left+1, lpRc->top+1, lpRc->left+1, lpRc->bottom - 2);
  1067. SelectObject(hDC, hPenWhite);
  1068. DrawLine(hDC, lpRc->right-1, lpRc->top, lpRc->right-1, lpRc->bottom);
  1069. DrawLine(hDC, lpRc->left, lpRc->bottom-1, lpRc->right-1, lpRc->bottom - 1);
  1070. break;
  1071. default:
  1072. break;
  1073. }
  1074. if(hPenOrig) {
  1075. SelectObject(hDC, hPenOrig);
  1076. }
  1077. DeleteObject(hPenWhite);
  1078. DeleteObject(hPenGlay);
  1079. return 0;
  1080. }
  1081. //////////////////////////////////////////////////////////////////
  1082. // Function : CEXButton::DrawThinEdge
  1083. // Type : INT
  1084. // Purpose :
  1085. // Args :
  1086. // : HDC hDC
  1087. // : LPRECT lpRc
  1088. // : IMAGESTYLE style
  1089. // Return :
  1090. // DATE :
  1091. //////////////////////////////////////////////////////////////////
  1092. INT CEXButton::DrawThinEdge(HDC hDC, LPRECT lpRc, IMAGESTYLE style)
  1093. {
  1094. HPEN hPenPrev;
  1095. HPEN hPenTopLeft=0;
  1096. HPEN hPenBottomRight=0;
  1097. switch(style) {
  1098. case IS_PUSHED:
  1099. hPenTopLeft = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_3DSHADOW));
  1100. hPenBottomRight = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_3DHILIGHT));
  1101. break;
  1102. case IS_POPED:
  1103. hPenTopLeft = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_3DHILIGHT));
  1104. hPenBottomRight = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_3DSHADOW));
  1105. break;
  1106. case IS_FLAT: // do not draw
  1107. return 0;
  1108. break;
  1109. }
  1110. hPenPrev = (HPEN)::SelectObject(hDC, hPenTopLeft);
  1111. #ifndef UNDER_CE // Windows CE does not support MoveToEx/LineTo. Use Polyline.
  1112. MoveToEx(hDC, lpRc->left, lpRc->top, NULL);
  1113. LineTo(hDC, lpRc->right, lpRc->top);
  1114. MoveToEx(hDC, lpRc->left, lpRc->top, NULL);
  1115. LineTo(hDC, lpRc->left, lpRc->bottom);
  1116. #else // UNDER_CE
  1117. {
  1118. POINT pts[] = {{lpRc->left, lpRc->bottom},
  1119. {lpRc->left, lpRc->top},
  1120. {lpRc->right, lpRc->top}};
  1121. Polyline(hDC, pts, sizeof pts / sizeof pts[0]);
  1122. }
  1123. #endif // UNDER_CE
  1124. SelectObject(hDC, hPenBottomRight);
  1125. #ifndef UNDER_CE // Windows CE does not support MoveToEx/LineTo. Use Polyline.
  1126. MoveToEx(hDC, lpRc->right -1, lpRc->top - 1, NULL);
  1127. LineTo(hDC, lpRc->right -1, lpRc->bottom);
  1128. MoveToEx(hDC, lpRc->left + 1, lpRc->bottom -1, NULL);
  1129. LineTo(hDC, lpRc->right -1, lpRc->bottom -1);
  1130. #else // UNDER_CE
  1131. {
  1132. POINT pts[] = {{lpRc->right - 1, lpRc->top - 1},
  1133. {lpRc->right - 1, lpRc->bottom - 1},
  1134. {lpRc->left + 1, lpRc->bottom - 1}};
  1135. Polyline(hDC, pts, sizeof pts / sizeof pts[0]);
  1136. }
  1137. #endif // UNDER_CE
  1138. SelectObject(hDC, hPenPrev);
  1139. DeleteObject(hPenTopLeft);
  1140. DeleteObject(hPenBottomRight);
  1141. return 0;
  1142. }
  1143. //////////////////////////////////////////////////////////////////
  1144. // Function : CEXButton::DrawLine
  1145. // Type : INT
  1146. // Purpose : Draw Line with current Pen.
  1147. // Args :
  1148. // : HDC hDC
  1149. // : INT x
  1150. // : INT y
  1151. // : INT destX
  1152. // : INT destY
  1153. // Return :
  1154. // DATE :
  1155. //////////////////////////////////////////////////////////////////
  1156. INT CEXButton::DrawLine(HDC hDC, INT x, INT y, INT destX, INT destY)
  1157. {
  1158. #ifndef UNDER_CE // Windows CE does not support MoveToEx/LineTo. Use Polyline.
  1159. MoveToEx(hDC, x, y, NULL);
  1160. LineTo (hDC, destX, destY);
  1161. #else // UNDER_CE
  1162. POINT pts[] = {{x, y}, {destX, destY}};
  1163. Polyline(hDC, pts, sizeof pts / sizeof pts[0]);
  1164. #endif // UNDER_CE
  1165. return 0;
  1166. }
  1167. //////////////////////////////////////////////////////////////////
  1168. // Function : CEXButton::DrawIcon
  1169. // Type : INT
  1170. // Purpose :
  1171. // Args :
  1172. // : HDC hDC
  1173. // : LPRECT lpRc
  1174. // : IMAGESTYLE style
  1175. // Return :
  1176. // DATE :
  1177. //////////////////////////////////////////////////////////////////
  1178. INT CEXButton::DrawIcon(HDC hDC, LPRECT lpRc, IMAGESTYLE style)
  1179. {
  1180. if(!m_hIcon) {
  1181. return -1;
  1182. }
  1183. INT sunken, xPos, yPos;
  1184. switch(style) {
  1185. case IS_PUSHED:
  1186. sunken = 1;
  1187. break;
  1188. case IS_POPED:
  1189. case IS_FLAT:
  1190. default:
  1191. sunken = 0;
  1192. break;
  1193. }
  1194. //----------------------------------------------------------------
  1195. //centering Icon
  1196. xPos = lpRc->left + ((lpRc->right - lpRc->left) - m_cxIcon)/2;
  1197. yPos = lpRc->top + ((lpRc->bottom - lpRc->top) - m_cyIcon)/2;
  1198. DrawIconEx(hDC, //HDC hdc,// handle to device context
  1199. xPos + sunken, //int xLeft,// x-coordinate of upper left corner
  1200. yPos + sunken, //int yTop,// y-coordinate of upper left corner
  1201. m_hIcon, //HICON hIcon,// handle to icon to draw
  1202. m_cxIcon, //int cxWidth,// width of the icon
  1203. m_cyIcon, //int cyWidth,// height of the icon
  1204. 0, //UINT istepIfAniCur,// index of frame in animated cursor
  1205. NULL, //HBRUSH hbrFlickerFreeDraw,// handle to background brush
  1206. DI_NORMAL); //UINT diFlags// icon-drawing flags
  1207. return 0;
  1208. }
  1209. //////////////////////////////////////////////////////////////////
  1210. // Function : CEXButton::DrawBitmap
  1211. // Type : INT
  1212. // Purpose :
  1213. // Args :
  1214. // : HDC hDC
  1215. // : LPRECT lpRc
  1216. // : IMAGESTYLE style
  1217. // Return :
  1218. // DATE :
  1219. //////////////////////////////////////////////////////////////////
  1220. INT CEXButton::DrawBitmap(HDC hDC, LPRECT lpRc, IMAGESTYLE style)
  1221. {
  1222. return 0;
  1223. Unref(hDC);
  1224. Unref(lpRc);
  1225. Unref(style);
  1226. }
  1227. //////////////////////////////////////////////////////////////////
  1228. // Function : CEXButton::DrawText
  1229. // Type : INT
  1230. // Purpose :
  1231. // Args :
  1232. // : HDC hDC
  1233. // : LPRECT lpRc
  1234. // : IMAGESTYLE style
  1235. // Return :
  1236. // DATE :
  1237. //////////////////////////////////////////////////////////////////
  1238. inline BOOL MIN(INT a, INT b)
  1239. {
  1240. if(a > b) {
  1241. return b;
  1242. }
  1243. else {
  1244. return a;
  1245. }
  1246. }
  1247. //////////////////////////////////////////////////////////////////
  1248. // Function : CEXButton::DrawText
  1249. // Type : INT
  1250. // Purpose :
  1251. // Args :
  1252. // : HDC hDC
  1253. // : LPRECT lpRc
  1254. // : IMAGESTYLE style
  1255. // Return :
  1256. // DATE :
  1257. //////////////////////////////////////////////////////////////////
  1258. INT CEXButton::DrawText(HDC hDC, LPRECT lpRc, IMAGESTYLE style)
  1259. {
  1260. #if 0
  1261. Dbg(("DrawText START style[%d]\n", style));
  1262. Dbg(("--->Clinet w[%d] h[%d]\n",
  1263. lpRc->right - lpRc->left,
  1264. lpRc->bottom - lpRc->top));
  1265. #endif
  1266. static POINT pt;
  1267. static RECT rc;
  1268. INT sunken, len;
  1269. if(!m_lpwstrText) {
  1270. Dbg(("--->Error m_lpwstrText is NULL\n"));
  1271. return -1;
  1272. }
  1273. len = lstrlenW(m_lpwstrText);
  1274. //DBGW((L"--->len [%d] str[%s]\n", len, m_lpwstrText));
  1275. HFONT hFontPrev;
  1276. if(m_hFont) {
  1277. hFontPrev = (HFONT)::SelectObject(hDC, m_hFont);
  1278. }
  1279. else {
  1280. hFontPrev = (HFONT)::SelectObject(hDC, GetStockObject(DEFAULT_GUI_FONT));
  1281. }
  1282. ExGetTextExtentPoint32W(hDC,
  1283. m_lpwstrText,
  1284. len,
  1285. &m_tmpSize);
  1286. //Dbg(("--->size.cx [%d] cy[%d]\n", m_tmpSize.cx, m_tmpSize.cy));
  1287. if((lpRc->right - lpRc->left) > m_tmpSize.cx) {
  1288. pt.x = lpRc->left + ((lpRc->right - lpRc->left) - m_tmpSize.cx)/2;
  1289. }
  1290. else {
  1291. pt.x = lpRc->left+2; //2 is edge space
  1292. }
  1293. if((lpRc->bottom - lpRc->top) > m_tmpSize.cy) {
  1294. pt.y = lpRc->top + ((lpRc->bottom - lpRc->top) - m_tmpSize.cy)/2;
  1295. }
  1296. else {
  1297. pt.y = lpRc->top+2; //2 is edge space
  1298. }
  1299. switch(style) {
  1300. case IS_PUSHED:
  1301. sunken = 1;
  1302. break;
  1303. case IS_POPED:
  1304. case IS_FLAT:
  1305. default:
  1306. sunken = 0;
  1307. }
  1308. rc.left = pt.x;
  1309. rc.right = lpRc->right - 2;
  1310. rc.top = pt.y;
  1311. rc.bottom = lpRc->bottom-2;
  1312. #if 0
  1313. Dbg(("--->rc l[%d] t[%d] r[%d] b[%d]\n",
  1314. rc.left,
  1315. rc.top,
  1316. rc.right,
  1317. rc.bottom));
  1318. #endif
  1319. if(m_fEnable) {
  1320. DWORD dwOldBk = ::SetBkMode(hDC, TRANSPARENT);
  1321. ExExtTextOutW(hDC,
  1322. pt.x + sunken,
  1323. pt.y + sunken,
  1324. ETO_CLIPPED,
  1325. &rc,
  1326. m_lpwstrText,
  1327. len,
  1328. NULL);
  1329. ::SetBkMode(hDC, dwOldBk);
  1330. }
  1331. else {
  1332. DWORD dwOldTC;
  1333. static RECT rcBk;
  1334. rcBk = rc;
  1335. rcBk.left +=1 ;
  1336. rcBk.top +=1 ;
  1337. rcBk.right +=1;
  1338. rcBk.bottom +=1;
  1339. //Draw white text.
  1340. dwOldTC = ::SetTextColor(hDC, GetSysColor(COLOR_3DHILIGHT));
  1341. ExExtTextOutW(hDC,
  1342. pt.x + sunken+1,
  1343. pt.y + sunken+1,
  1344. ETO_CLIPPED,
  1345. &rcBk,
  1346. m_lpwstrText,
  1347. len,
  1348. NULL);
  1349. ::SetTextColor(hDC, GetSysColor(COLOR_GRAYTEXT));
  1350. DWORD dwOldBk = ::SetBkMode(hDC, TRANSPARENT);
  1351. ExExtTextOutW(hDC,
  1352. pt.x + sunken,
  1353. pt.y + sunken,
  1354. ETO_CLIPPED,
  1355. &rc,
  1356. m_lpwstrText,
  1357. len,
  1358. NULL);
  1359. ::SetBkMode(hDC, dwOldBk);
  1360. ::SetTextColor(hDC, dwOldTC);
  1361. }
  1362. SelectObject(hDC, hFontPrev);
  1363. //Dbg(("--->DrawText END\n"));
  1364. return 0;
  1365. }