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.

935 lines
25 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 "ddbtn.h"
  7. #include "cddbtn.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. //----------------------------------------------------------------
  27. // <-Spec width>
  28. // <--> 12 point
  29. // +--------+--+
  30. // | | |
  31. // | | |
  32. // +--------+--+
  33. //----------------------------------------------------------------
  34. #define CXDROPDOWN 12
  35. #define TIMERID_MONITORPOS 0x0010
  36. #define WM_USER_COMMAND (WM_USER+400)
  37. //----------------------------------------------------------------
  38. //Get, Set LPCDDButton this pointer.
  39. //this is set to cbWndExtra.
  40. //See WinRegister()
  41. //----------------------------------------------------------------
  42. inline LPCDDButton GetThis(HWND hwnd)
  43. {
  44. #ifdef _WIN64
  45. return (LPCDDButton)GetWindowLongPtr(hwnd, 0);
  46. #else
  47. return (LPCDDButton)GetWindowLong(hwnd, 0);
  48. #endif
  49. }
  50. //----------------------------------------------------------------
  51. inline LPCDDButton SetThis(HWND hwnd, LPCDDButton lpDDB)
  52. {
  53. #ifdef _WIN64
  54. return (LPCDDButton)SetWindowLongPtr(hwnd, 0, (LONG_PTR)lpDDB);
  55. #else
  56. return (LPCDDButton)SetWindowLong(hwnd, 0, (LONG)lpDDB);
  57. #endif
  58. }
  59. //////////////////////////////////////////////////////////////////
  60. // Function : WndProc
  61. // Type : static LRESULT CALLBACK
  62. // Purpose : Window Procedure for Drop Down Button.
  63. // Args :
  64. // : HWND hwnd
  65. // : UINT uMsg
  66. // : WPARAM wParam
  67. // : LPARAM lParam
  68. // Return :
  69. // DATE : 970905
  70. //////////////////////////////////////////////////////////////////
  71. static LRESULT CALLBACK WndProc(HWND hwnd,
  72. UINT uMsg,
  73. WPARAM wParam,
  74. LPARAM lParam)
  75. {
  76. LPCDDButton lpDDB;
  77. if(uMsg == WM_CREATE) {
  78. lpDDB = (LPCDDButton)((LPCREATESTRUCT)lParam)->lpCreateParams;
  79. if(!lpDDB) {
  80. return 0; // do not create button
  81. }
  82. SetThis(hwnd, lpDDB);
  83. lpDDB->MsgCreate(hwnd, wParam, lParam);
  84. return 1;
  85. }
  86. if(uMsg == WM_DESTROY) {
  87. lpDDB = GetThis(hwnd);
  88. if(lpDDB) {
  89. delete lpDDB;
  90. PrintMemInfo();
  91. }
  92. SetThis(hwnd, (LPCDDButton)NULL);
  93. return DefWindowProc(hwnd, uMsg, wParam, lParam);
  94. }
  95. lpDDB = GetThis(hwnd);
  96. if(!lpDDB) {
  97. return DefWindowProc(hwnd, uMsg, wParam, lParam);
  98. }
  99. switch(uMsg) {
  100. case WM_PAINT:
  101. lpDDB->MsgPaint(hwnd, wParam, lParam);
  102. break;
  103. case WM_MOUSEMOVE:
  104. lpDDB->MsgMouseMove(hwnd, wParam, lParam);
  105. break;
  106. case WM_TIMER:
  107. lpDDB->MsgTimer(hwnd, wParam, lParam);
  108. break;
  109. case WM_SETFONT:
  110. return lpDDB->MsgSetFont(hwnd, wParam, lParam);
  111. case WM_LBUTTONDBLCLK:
  112. case WM_MBUTTONDBLCLK:
  113. case WM_RBUTTONDBLCLK:
  114. case WM_LBUTTONDOWN:
  115. case WM_MBUTTONDOWN:
  116. case WM_RBUTTONDOWN:
  117. lpDDB->MsgButtonDown(hwnd, uMsg, wParam, lParam);
  118. break;
  119. case WM_LBUTTONUP:
  120. case WM_MBUTTONUP:
  121. case WM_RBUTTONUP:
  122. lpDDB->MsgButtonUp(hwnd, uMsg, wParam, lParam);
  123. break;
  124. case WM_ENABLE:
  125. lpDDB->MsgEnable(hwnd, wParam, lParam);
  126. break;
  127. case WM_COMMAND:
  128. return lpDDB->MsgCommand(hwnd, wParam, lParam);
  129. case WM_USER_COMMAND:
  130. return lpDDB->MsgUserCommand(hwnd, wParam, lParam);
  131. case WM_EXITMENULOOP:
  132. lpDDB->MsgExitMenuLoop(hwnd, wParam, lParam);
  133. break;
  134. case WM_MEASUREITEM:
  135. return lpDDB->MsgMeasureItem(hwnd, wParam, lParam);
  136. case WM_DRAWITEM:
  137. return lpDDB->MsgDrawItem(hwnd, wParam, lParam);
  138. case DDBM_ADDITEM: return lpDDB->MsgDDB_AddItem (hwnd, wParam, lParam);
  139. case DDBM_INSERTITEM: return lpDDB->MsgDDB_InsertItem (hwnd, wParam, lParam);
  140. case DDBM_SETCURSEL: return lpDDB->MsgDDB_SetCurSel (hwnd, wParam, lParam);
  141. case DDBM_GETCURSEL: return lpDDB->MsgDDB_GetCurSel (hwnd, wParam, lParam);
  142. case DDBM_SETICON: return lpDDB->MsgDDB_SetIcon (hwnd, wParam, lParam);
  143. case DDBM_SETTEXT: return lpDDB->MsgDDB_SetText (hwnd, wParam, lParam);
  144. case DDBM_SETSTYLE: return lpDDB->MsgDDB_SetStyle (hwnd, wParam, lParam);
  145. #ifndef UNDER_CE // not support WM_ENTERIDLE
  146. case WM_ENTERIDLE:
  147. //----------------------------------------------------------------
  148. //980818:Bug found in PRC.
  149. //If Ctrl+Shift is assigned to switch IME,
  150. //Menu remains in spite of imepad has destroyed.
  151. //To prevent it, if Ctrl+Shift come while menu is poping up.
  152. //close it.
  153. //----------------------------------------------------------------
  154. {
  155. if((::GetKeyState(VK_CONTROL) & 0x8000) &&
  156. (::GetKeyState(VK_SHIFT) & 0x80000)) {
  157. Dbg(("VK_SHIFT_CONTROL COME\n"));
  158. ::SendMessage(hwnd, WM_CANCELMODE, 0, 0L);
  159. return 0;
  160. }
  161. }
  162. break;
  163. #endif // UNDER_CE
  164. default:
  165. //Dbg(("Msg [0x%08x]\n", uMsg));
  166. break;
  167. }
  168. return DefWindowProc(hwnd, uMsg, wParam, lParam);
  169. }
  170. //////////////////////////////////////////////////////////////////
  171. // Function : CDDButton
  172. // Type :
  173. // Purpose : Constructor
  174. // Args :
  175. // : HINSTANCE hInst
  176. // : HWND hwndParent
  177. // : DWORD dwStyle
  178. // Return :
  179. // DATE :
  180. //////////////////////////////////////////////////////////////////
  181. CDDButton::CDDButton(HINSTANCE hInst, HWND hwndParent, DWORD dwStyle, DWORD wID)
  182. {
  183. m_hInst = hInst;
  184. m_hwndParent = hwndParent;
  185. m_dwStyle = dwStyle;
  186. m_wID = wID;
  187. m_cxDropDown = CXDROPDOWN;
  188. m_bidDown = BID_UNDEF;
  189. m_curDDBItemIndex = -1;
  190. m_fEnable = TRUE;
  191. m_f16bitOnNT = FALSE;
  192. #ifndef UNDER_CE // Windows CE always 32bit application
  193. if(ExIsWinNT()) {
  194. char szBuf[256];
  195. DWORD dwType = 0;
  196. ::GetModuleFileName(NULL, szBuf, sizeof(szBuf));
  197. ::GetBinaryType(szBuf, &dwType);
  198. if(dwType == SCS_WOW_BINARY) {
  199. m_f16bitOnNT = TRUE;
  200. }
  201. }
  202. #endif // UNDER_CE
  203. #ifdef UNDER_CE // Windows CE does not support GetCursorPos
  204. m_ptEventPoint.x = -1;
  205. m_ptEventPoint.y = -1;
  206. #endif // UNDER_CE
  207. }
  208. //////////////////////////////////////////////////////////////////
  209. // Function : ~CDDButton
  210. // Type :
  211. // Purpose : Destructor
  212. // Args :
  213. // :
  214. // Return :
  215. // DATE :
  216. //////////////////////////////////////////////////////////////////
  217. CDDButton::~CDDButton()
  218. {
  219. Dbg(("~CDDButton \n"));
  220. if(m_hIcon) {
  221. Dbg(("DestroyIcon\n"));
  222. DestroyIcon(m_hIcon);
  223. m_hIcon = NULL;
  224. }
  225. if(m_hFont) {
  226. Dbg(("Delete FONT\n"));
  227. DeleteObject(m_hFont);
  228. m_hFont = NULL;
  229. }
  230. if(m_lpwstrText) {
  231. MemFree(m_lpwstrText);
  232. m_lpwstrText = NULL;
  233. }
  234. if(m_lpCDDBItem) {
  235. Dbg(("Delete CDDBItem List\n"));
  236. LPCDDBItem p, pTmp;
  237. for(p = m_lpCDDBItem; p; p = pTmp) {
  238. pTmp = p->next;
  239. delete p;
  240. }
  241. m_lpCDDBItem = NULL;
  242. }
  243. }
  244. //////////////////////////////////////////////////////////////////
  245. // Function : RegisterWinClass
  246. // Type : BOOL
  247. // Purpose :
  248. // Args :
  249. // : LPSTR lpstrClassName
  250. // Return :
  251. // DATE :
  252. //////////////////////////////////////////////////////////////////
  253. #ifndef UNDER_CE
  254. BOOL CDDButton::RegisterWinClass(LPSTR lpstrClass)
  255. #else // UNDER_CE
  256. BOOL CDDButton::RegisterWinClass(LPTSTR lpstrClass)
  257. #endif // UNDER_CE
  258. {
  259. ATOM ret;
  260. //----------------------------------------------------------------
  261. //check specified class is already exist or not
  262. //----------------------------------------------------------------
  263. #ifndef UNDER_CE // not support GetClassInfoEx
  264. if(::GetClassInfoEx(m_hInst, lpstrClass, &m_tmpWC)){
  265. //lpstrClass is already registerd.
  266. return TRUE;
  267. }
  268. #else // UNDER_CE
  269. if(::GetClassInfo(m_hInst, lpstrClass, &m_tmpWC)){
  270. //lpstrClass is already registerd.
  271. return TRUE;
  272. }
  273. #endif // UNDER_CE
  274. ::ZeroMemory(&m_tmpWC, sizeof(m_tmpWC));
  275. #ifndef UNDER_CE // not support RegisterClassEx
  276. m_tmpWC.cbSize = sizeof(m_tmpWC);
  277. #endif // UNDER_CE
  278. m_tmpWC.style = CS_HREDRAW | CS_VREDRAW; /* Class style(s). */
  279. m_tmpWC.lpfnWndProc = (WNDPROC)WndProc;
  280. m_tmpWC.cbClsExtra = 0; /* No per-class extra data.*/
  281. m_tmpWC.cbWndExtra = sizeof(LPCDDButton); // Set Object's pointer.
  282. m_tmpWC.hInstance = m_hInst; /* Application that owns the class. */
  283. m_tmpWC.hIcon = NULL;
  284. m_tmpWC.hCursor = LoadCursor(NULL, IDC_ARROW);
  285. m_tmpWC.hbrBackground = (HBRUSH)NULL;
  286. //m_tmpWC.hbrBackground = (HBRUSH)(COLOR_3DFACE+1);
  287. m_tmpWC.lpszMenuName = NULL; /* Name of menu resource in .RC file. */
  288. m_tmpWC.lpszClassName = lpstrClass; /* Name used in call to CreateWindow. */
  289. #ifndef UNDER_CE // not support RegisterClassEx
  290. m_tmpWC.hIconSm = NULL;
  291. ret = ::RegisterClassEx(&m_tmpWC);
  292. #else // UNDER_CE
  293. ret = ::RegisterClass(&m_tmpWC);
  294. #endif // UNDER_CE
  295. return ret ? TRUE: FALSE;
  296. }
  297. INT CDDButton::MsgCreate(HWND hwnd, WPARAM wParam, LPARAM lParam)
  298. {
  299. m_hwndFrame = hwnd;
  300. return 1;
  301. UnrefForMsg();
  302. }
  303. //////////////////////////////////////////////////////////////////
  304. // Function : CDDButton::MsgPaint
  305. // Type : INT
  306. // Purpose :
  307. // Args :
  308. // : HWND hwnd
  309. // : WPARAM wParam
  310. // : LPARAM lParam
  311. // Return :
  312. // DATE :
  313. //////////////////////////////////////////////////////////////////
  314. INT CDDButton::MsgPaint(HWND hwnd, WPARAM wParam, LPARAM lParam)
  315. {
  316. PAINTSTRUCT ps;
  317. RECT rc;
  318. HDC hDCMem;
  319. HDC hDC;
  320. HBITMAP hBitmap, hBitmapPrev;
  321. ::GetClientRect(hwnd, &rc);
  322. hDC = ::BeginPaint(hwnd, &ps);
  323. hDCMem = ::CreateCompatibleDC(hDC);
  324. hBitmap = ::CreateCompatibleBitmap(hDC, rc.right - rc.left, rc.bottom - rc.top);
  325. hBitmapPrev = (HBITMAP)::SelectObject(hDCMem, hBitmap);
  326. DrawButton(hDCMem, &rc);
  327. ::BitBlt(hDC, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top,
  328. hDCMem, 0, 0, SRCCOPY);
  329. ::SelectObject(hDCMem, hBitmapPrev );
  330. ::DeleteObject(hBitmap);
  331. ::DeleteDC(hDCMem);
  332. ::EndPaint(hwnd, &ps);
  333. return 0;
  334. UnrefForMsg();
  335. }
  336. INT CDDButton::MsgDestroy(HWND hwnd, WPARAM wParam, LPARAM lParam)
  337. {
  338. return 0;
  339. UnrefForMsg();
  340. }
  341. INT CDDButton::MsgTimer(HWND hwnd, WPARAM wParam, LPARAM lParam)
  342. {
  343. #ifndef UNDER_CE // no monitor position. (not support GetCursorPos)
  344. static RECT rc;
  345. static POINT pt;
  346. if(wParam == TIMERID_MONITORPOS) {
  347. ::GetWindowRect(hwnd, &rc);
  348. ::GetCursorPos(&pt);
  349. if(!PtInRect(&rc, pt)) {
  350. ::KillTimer(hwnd, wParam);
  351. ::InvalidateRect(hwnd, NULL, NULL);
  352. }
  353. }
  354. #endif // UNDER_CE
  355. return 0;
  356. UnrefForMsg();
  357. }
  358. //////////////////////////////////////////////////////////////////
  359. // Function : CDDButton::MsgMouseMove
  360. // Type : INT
  361. // Purpose :
  362. // Args :
  363. // : HWND hwnd
  364. // : WPARAM wParam
  365. // : LPARAM lParam
  366. // Return :
  367. // DATE :
  368. //////////////////////////////////////////////////////////////////
  369. INT CDDButton::MsgMouseMove(HWND hwnd, WPARAM wParam, LPARAM lParam)
  370. {
  371. #ifdef UNDER_CE // Windows CE does not support GetCursorPos
  372. m_ptEventPoint.x = (SHORT)LOWORD(lParam);
  373. m_ptEventPoint.y = (SHORT)HIWORD(lParam);
  374. #endif // UNDER_CE
  375. #ifndef UNDER_CE // no monitor position. (not support GetCursorPos)
  376. KillTimer(hwnd, TIMERID_MONITORPOS);
  377. SetTimer(hwnd, TIMERID_MONITORPOS, 100, NULL);
  378. #endif // UNDER_CE
  379. InvalidateRect(hwnd, NULL, FALSE);
  380. return 0;
  381. UnrefForMsg();
  382. }
  383. //////////////////////////////////////////////////////////////////
  384. // Function : CDDButton::MsgButtonDown
  385. // Type : INT
  386. // Purpose :
  387. // Args :
  388. // : HWND hwnd
  389. // : UINT uMsg
  390. // : WPARAM wParam
  391. // : LPARAM lParam
  392. // Return :
  393. // DATE :
  394. //////////////////////////////////////////////////////////////////
  395. INT CDDButton::MsgButtonDown(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  396. {
  397. static RECT rc;
  398. Dbg(("MsgButtonDown uMsg [0x%08x] x[%d] y[%d]\n",
  399. uMsg,
  400. LOWORD(lParam),
  401. HIWORD(lParam)));
  402. if(uMsg != WM_LBUTTONDOWN && uMsg != WM_LBUTTONDBLCLK ) {
  403. return 0;
  404. }
  405. if(!m_fEnable)
  406. {
  407. return 0;
  408. }
  409. #ifdef UNDER_CE // Windows CE does not support GetCursorPos
  410. m_ptEventPoint.x = (SHORT)LOWORD(lParam);
  411. m_ptEventPoint.y = (SHORT)HIWORD(lParam);
  412. #endif // UNDER_CE
  413. INT bID = GetButtonFromPos(LOWORD(lParam), HIWORD(lParam));
  414. Dbg(("bID[%d] m_fExitMenuLoop [%d]\n", bID, m_fExitMenuLoop));
  415. switch(bID) {
  416. case BID_BUTTON:
  417. if(m_fExitMenuLoop) {
  418. m_fExitMenuLoop = FALSE;
  419. }
  420. m_bidDown = bID;
  421. if(m_f16bitOnNT) {
  422. }
  423. else {
  424. ::SetCapture(hwnd);
  425. }
  426. break;
  427. case BID_ALL:
  428. case BID_DROPDOWN:
  429. if(m_fExitMenuLoop) {
  430. m_fExitMenuLoop = FALSE;
  431. m_bidDown = BID_UNDEF;
  432. return 0;
  433. }
  434. m_bidDown = bID;
  435. //----------------------------------------------------------------
  436. // do not call popup menu here.
  437. // first, end WM_XBUTTON down message and return to
  438. // window message loop.
  439. //----------------------------------------------------------------
  440. //::PostMessage(hwnd, WM_COMMAND, (WPARAM)CMD_DROPDOWN, 0L);
  441. ::PostMessage(hwnd, WM_USER_COMMAND, (WPARAM)CMD_DROPDOWN, 0L);
  442. break;
  443. case BID_UNDEF:
  444. default:
  445. break;
  446. }
  447. ::InvalidateRect(hwnd, NULL, FALSE);
  448. return 0;
  449. UnrefForMsg();
  450. }
  451. //////////////////////////////////////////////////////////////////
  452. // Function : CDDButton::MsgButtonUp
  453. // Type : INT
  454. // Purpose :
  455. // Args :
  456. // : HWND hwnd
  457. // : UINT uMsg
  458. // : WPARAM wParam
  459. // : LPARAM lParam
  460. // Return :
  461. // DATE :
  462. //////////////////////////////////////////////////////////////////
  463. INT CDDButton::MsgButtonUp(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  464. {
  465. if(!m_fEnable)
  466. {
  467. return 0;
  468. }
  469. #ifdef UNDER_CE // Windows CE does not support GetCursorPos
  470. m_ptEventPoint.x = (SHORT)LOWORD(lParam);
  471. m_ptEventPoint.y = (SHORT)HIWORD(lParam);
  472. #endif // UNDER_CE
  473. switch(m_bidDown) {
  474. case BID_BUTTON:
  475. {
  476. ReleaseCapture();
  477. INT bid = GetButtonFromPos(LOWORD(lParam), HIWORD(lParam));
  478. INT newIndex;
  479. if(bid == BID_BUTTON) {
  480. newIndex = IncrementIndex();
  481. NotifyToParent(DDBN_CLICKED);
  482. if(newIndex != -1) {
  483. NotifyToParent(DDBN_SELCHANGE);
  484. }
  485. }
  486. }
  487. break;
  488. case BID_ALL:
  489. case BID_DROPDOWN:
  490. if(m_f16bitOnNT) {
  491. m_bidDown = BID_UNDEF;
  492. }
  493. InvalidateRect(hwnd, NULL, FALSE);
  494. return 0;
  495. break;
  496. }
  497. m_bidDown = BID_UNDEF;
  498. InvalidateRect(hwnd, NULL, FALSE);
  499. return 0;
  500. Unref(uMsg);
  501. UnrefForMsg();
  502. }
  503. //////////////////////////////////////////////////////////////////
  504. // Function : CDDButton::MsgCaptureChanged
  505. // Type : INT
  506. // Purpose :
  507. // Args :
  508. // : HWND hwnd
  509. // : WPARAM wParam
  510. // : LPARAM lParam
  511. // Return :
  512. // DATE :
  513. //////////////////////////////////////////////////////////////////
  514. INT CDDButton::MsgCaptureChanged(HWND hwnd, WPARAM wParam, LPARAM lParam)
  515. {
  516. m_bidDown = BID_UNDEF;
  517. ::InvalidateRect(hwnd, NULL, FALSE);
  518. return 0;
  519. UnrefForMsg();
  520. }
  521. //////////////////////////////////////////////////////////////////
  522. // Function : CDDButton::MsgExitMenuLoop
  523. // Type : INT
  524. // Purpose :
  525. // Args :
  526. // : HWND hwnd
  527. // : WPARAM wParam
  528. // : LPARAM lParam
  529. // Return :
  530. // DATE :
  531. //////////////////////////////////////////////////////////////////
  532. INT CDDButton::MsgExitMenuLoop(HWND hwnd, WPARAM wParam, LPARAM lParam)
  533. {
  534. Dbg(("WM_EXITMENULOOP\n"));
  535. #ifndef UNDER_CE // Windows CE does not support GetCursorPos()
  536. ::GetCursorPos(&m_tmpPoint);
  537. ::GetClientRect(m_hwndFrame, &m_tmpRect);
  538. ::ScreenToClient(m_hwndFrame, &m_tmpPoint);
  539. if(PtInRect(&m_tmpRect, m_tmpPoint)) {
  540. m_fExitMenuLoop = TRUE;
  541. }
  542. else {
  543. m_fExitMenuLoop = FALSE;
  544. }
  545. #else // UNDER_CE
  546. m_fExitMenuLoop = FALSE;
  547. #endif // UNDER_CE
  548. return 0;
  549. UnrefForMsg();
  550. }
  551. //////////////////////////////////////////////////////////////////
  552. // Function : CDDButton::MsgCommand
  553. // Type : INT
  554. // Purpose :
  555. // Args :
  556. // : HWND hwnd
  557. // : WPARAM wParam
  558. // : LPARAM lParam
  559. // Return :
  560. // DATE :
  561. //////////////////////////////////////////////////////////////////
  562. INT CDDButton::MsgCommand(HWND hwnd, WPARAM wParam, LPARAM lParam)
  563. {
  564. INT index;
  565. switch(wParam) {
  566. case CMD_DROPDOWN:
  567. NotifyToParent(DDBN_DROPDOWN);
  568. index = DropDownItemList();
  569. m_bidDown = BID_UNDEF;
  570. InvalidateRect(hwnd, NULL, FALSE);
  571. NotifyToParent(DDBN_CLOSEUP);
  572. //Dbg(("new Index %d\n", index));
  573. if(index != -1 && index != m_curDDBItemIndex) {
  574. m_curDDBItemIndex = index;
  575. NotifyToParent(DDBN_SELCHANGE);
  576. }
  577. break;
  578. default:
  579. break;
  580. }
  581. return 0;
  582. UnrefForMsg();
  583. }
  584. INT CDDButton::MsgUserCommand(HWND hwnd, WPARAM wParam, LPARAM lParam)
  585. {
  586. return MsgCommand(hwnd, wParam, lParam);
  587. }
  588. INT CDDButton::MsgSetFont(HWND hwnd, WPARAM wParam, LPARAM lParam)
  589. {
  590. HFONT hFont = (HFONT)wParam;
  591. BOOL fRedraw = LOWORD(lParam);
  592. HFONT hFontNew;
  593. if(!hFont) {
  594. return 0;
  595. }
  596. #ifndef UNDER_CE
  597. LOGFONTA logFont;
  598. #else // UNDER_CE
  599. LOGFONT logFont;
  600. #endif // UNDER_CE
  601. ::GetObject(hFont, sizeof(logFont), &logFont);
  602. hFontNew = ::CreateFontIndirect(&logFont);
  603. if(!hFontNew) {
  604. return 0;
  605. }
  606. if(m_hFont) {
  607. ::DeleteObject(m_hFont);
  608. }
  609. m_hFont = hFontNew;
  610. if(fRedraw) {
  611. ::InvalidateRect(hwnd, NULL, TRUE);
  612. }
  613. return 0;
  614. }
  615. INT CDDButton::MsgMeasureItem(HWND hwnd, WPARAM wParam, LPARAM lParam)
  616. {
  617. Dbg(("MsgMeasureItem START\n"));
  618. LPMEASUREITEMSTRUCT lpmis = (LPMEASUREITEMSTRUCT)lParam;
  619. switch(lpmis->CtlType) {
  620. case ODT_MENU:
  621. Dbg(("MsgMeasureItem END\n"));
  622. return MenuMeasureItem(hwnd, lpmis);
  623. break;
  624. }
  625. return 0;
  626. UnrefForMsg();
  627. }
  628. INT CDDButton::MsgDrawItem(HWND hwnd, WPARAM wParam, LPARAM lParam)
  629. {
  630. LPDRAWITEMSTRUCT lpdis = (LPDRAWITEMSTRUCT)lParam;
  631. switch(lpdis->CtlType) {
  632. case ODT_MENU:
  633. return MenuDrawItem(hwnd, lpdis);
  634. break;
  635. default:
  636. break;
  637. }
  638. return 0;
  639. UnrefForMsg();
  640. }
  641. //////////////////////////////////////////////////////////////////
  642. // Function : CDDButton::MsgDDB_AddItem
  643. // Type : INT
  644. // Purpose :
  645. // Args :
  646. // : HWND hwnd
  647. // : WPARAM wParam
  648. // : LPARAM lParam
  649. // Return :
  650. // DATE :
  651. //////////////////////////////////////////////////////////////////
  652. INT CDDButton::MsgDDB_AddItem(HWND hwnd, WPARAM wParam, LPARAM lParam)
  653. {
  654. LPDDBITEM lpItem = (LPDDBITEM)lParam;
  655. LPCDDBItem lpCItem = new CDDBItem;
  656. if(!lpCItem) {
  657. return -1;
  658. }
  659. lpCItem->SetTextW(lpItem->lpwstr);
  660. InsertDDBItem(lpCItem, -1);
  661. return 0;
  662. UnrefForMsg();
  663. }
  664. //////////////////////////////////////////////////////////////////
  665. // Function : CDDButton::MsgDDB_InsertItem
  666. // Type : INT
  667. // Purpose :
  668. // Args :
  669. // : HWND hwnd
  670. // : WPARAM wParam
  671. // : LPARAM lParam
  672. // Return :
  673. // DATE :
  674. //////////////////////////////////////////////////////////////////
  675. INT CDDButton::MsgDDB_InsertItem(HWND hwnd, WPARAM wParam, LPARAM lParam)
  676. {
  677. LPDDBITEM lpItem = (LPDDBITEM)lParam;
  678. LPCDDBItem lpCItem = new CDDBItem;
  679. if(!lpCItem) {
  680. return -1;
  681. }
  682. lpCItem->SetTextW(lpItem->lpwstr);
  683. InsertDDBItem(lpCItem, (INT)wParam);
  684. return 0;
  685. UnrefForMsg();
  686. }
  687. //////////////////////////////////////////////////////////////////
  688. // Function : CDDButton::MsgDDB_SetCurSel
  689. // Type : INT
  690. // Purpose : Set current selection.
  691. // Args :
  692. // : HWND hwnd
  693. // : WPARAM wParam INT index
  694. // : LPARAM lParam no use:
  695. // Return :
  696. // DATE :
  697. //////////////////////////////////////////////////////////////////
  698. INT CDDButton::MsgDDB_SetCurSel(HWND hwnd, WPARAM wParam, LPARAM lParam)
  699. {
  700. INT count = GetDDBItemCount();
  701. if(count <=0) {
  702. return -1;
  703. }
  704. if(0 <= (INT)wParam && count <= (INT)wParam) {
  705. return -1;
  706. }
  707. m_curDDBItemIndex = (INT)wParam;
  708. return 0;
  709. UnrefForMsg();
  710. }
  711. //////////////////////////////////////////////////////////////////
  712. // Function : CDDButton::MsgDDB_GetCurSel
  713. // Type : INT
  714. // Purpose :
  715. // Args :
  716. // : HWND hwnd
  717. // : WPARAM wParam no use.
  718. // : LPARAM lParam no use.
  719. // Return : return current item's index. (ZERO based)
  720. // DATE :
  721. //////////////////////////////////////////////////////////////////
  722. INT CDDButton::MsgDDB_GetCurSel(HWND hwnd, WPARAM wParam, LPARAM lParam)
  723. {
  724. return m_curDDBItemIndex;
  725. UnrefForMsg();
  726. }
  727. //////////////////////////////////////////////////////////////////
  728. // Function : CDDButton::MsgDDB_SetIcon
  729. // Type : INT
  730. // Purpose : Set new icon.
  731. // Args :
  732. // : HWND hwnd
  733. // : WPARAM wParam HICON hIcon.
  734. // : LPARAM lParam no use.
  735. // Return :
  736. // DATE :
  737. //////////////////////////////////////////////////////////////////
  738. INT CDDButton::MsgDDB_SetIcon(HWND hwnd, WPARAM wParam, LPARAM lParam)
  739. {
  740. Dbg(("MsgDDB_SetIcon: wParam[0x%08x] lParam[0x%08x]\n", wParam, lParam));
  741. if((HICON)wParam == NULL) {
  742. Dbg(("MsgDDB_SetIcon: ERROR END\n"));
  743. return -1;
  744. }
  745. //if icon style is not set, destroy specified icon
  746. if(!(m_dwStyle & DDBS_ICON)) {
  747. DestroyIcon((HICON)wParam);
  748. return -1;
  749. }
  750. if(m_hIcon) {
  751. DestroyIcon(m_hIcon);
  752. }
  753. m_hIcon = (HICON)wParam;
  754. //----------------------------------------------------------------
  755. //Get Icon width and height.
  756. //----------------------------------------------------------------
  757. #ifndef UNDER_CE // Windows CE does not support GetIconInfo()
  758. ZeroMemory(&m_tmpIconInfo, sizeof(m_tmpIconInfo));
  759. ::GetIconInfo(m_hIcon, &m_tmpIconInfo);
  760. Dbg(("fIcon [%d]\n", m_tmpIconInfo.fIcon ));
  761. Dbg(("xHotspot [%d]\n", m_tmpIconInfo.xHotspot ));
  762. Dbg(("yHotspot [%d]\n", m_tmpIconInfo.yHotspot ));
  763. Dbg(("hbmMask [0x%08x]\n", m_tmpIconInfo.hbmMask ));
  764. Dbg(("hbmColor [0x%08x]\n", m_tmpIconInfo.hbmColor ));
  765. if(m_tmpIconInfo.hbmMask) {
  766. GetObject(m_tmpIconInfo.hbmMask, sizeof(m_tmpBitmap), &m_tmpBitmap);
  767. Dbg(("bmWidth[%d] bmHeight[%d]\n",
  768. m_tmpBitmap.bmWidth,
  769. m_tmpBitmap.bmHeight));
  770. DeleteObject(m_tmpIconInfo.hbmMask);
  771. m_cxIcon = m_tmpBitmap.bmWidth;
  772. m_cyIcon = m_tmpBitmap.bmHeight;
  773. }
  774. if(m_tmpIconInfo.hbmColor) {
  775. DeleteObject(m_tmpIconInfo.hbmColor);
  776. }
  777. #else // UNDER_CE
  778. m_cxIcon = GetSystemMetrics(SM_CXSMICON);
  779. m_cyIcon = GetSystemMetrics(SM_CYSMICON);
  780. #endif // UNDER_CE
  781. InvalidateRect(hwnd, NULL, FALSE);
  782. return 0;
  783. UnrefForMsg();
  784. }
  785. //////////////////////////////////////////////////////////////////
  786. // Function : CDDButton::MsgDDB_SetText
  787. // Type : INT
  788. // Purpose :
  789. // Args :
  790. // : HWND hwnd
  791. // : WPARAM wParam LPWSTR lpwstr: null terminated Unicode string.
  792. // : LPARAM lParam no use.
  793. // Return :
  794. // DATE :
  795. //////////////////////////////////////////////////////////////////
  796. INT CDDButton::MsgDDB_SetText(HWND hwnd, WPARAM wParam, LPARAM lParam)
  797. {
  798. if(!(LPWSTR)wParam) {
  799. return -1;
  800. }
  801. if( ((LPWSTR)wParam)[0] == (WCHAR)0x0000) {
  802. return -1;
  803. }
  804. if(m_lpwstrText) {
  805. MemFree(m_lpwstrText);
  806. }
  807. m_lpwstrText = StrdupW((LPWSTR)wParam);
  808. #ifdef MSAA
  809. if(::IsWindowUnicode(hwnd)) {
  810. ::SetWindowTextW(hwnd, m_lpwstrText);
  811. }
  812. else {
  813. if(m_lpwstrText) {
  814. INT len = ::lstrlenW(m_lpwstrText);
  815. LPSTR lpstr = (LPSTR)MemAlloc((len + 1)*sizeof(WCHAR));
  816. if(lpstr) {
  817. #if 0 //for remove warning
  818. INT ret = ::WideCharToMultiByte(CP_ACP,
  819. WC_COMPOSITECHECK,
  820. m_lpwstrText, -1,
  821. lpstr, (len+1)*sizeof(WCHAR),
  822. 0, 0);
  823. #endif
  824. ::WideCharToMultiByte(CP_ACP,
  825. WC_COMPOSITECHECK,
  826. m_lpwstrText, -1,
  827. lpstr, (len+1)*sizeof(WCHAR),
  828. 0, 0);
  829. ::SetWindowTextA(hwnd, lpstr);
  830. MemFree(lpstr);
  831. }
  832. }
  833. }
  834. #endif
  835. InvalidateRect(hwnd, NULL, FALSE);
  836. return 0;
  837. Unref(lParam);
  838. }
  839. //////////////////////////////////////////////////////////////////
  840. // Function : CDDButton::MsgDDB_SetStyle
  841. // Type : INT
  842. // Purpose :
  843. // Args :
  844. // : HWND hwnd
  845. // : WPARAM wParam DWORD dwStyle:
  846. // : LPARAM lParam no use.
  847. // Return :
  848. // DATE :
  849. //////////////////////////////////////////////////////////////////
  850. INT CDDButton::MsgDDB_SetStyle(HWND hwnd, WPARAM wParam, LPARAM lParam)
  851. {
  852. DWORD dwStyle = (DWORD)wParam;
  853. #if 0 //DDBS_TEXT is 0...
  854. if((dwStyle & DDBS_TEXT) &&
  855. (dwStyle & DDBS_ICON)) {
  856. return -1;
  857. }
  858. #endif
  859. m_dwStyle = dwStyle;
  860. InvalidateRect(hwnd, NULL, FALSE);
  861. return 0;
  862. Unref(hwnd);
  863. Unref(lParam);
  864. }
  865. //////////////////////////////////////////////////////////////////
  866. // Function : CDDButton::MsgEnable
  867. // Type : INT
  868. // Purpose :
  869. // Args :
  870. // : HWND hwnd
  871. // : WPARAM wParam
  872. // : LPARAM lParam
  873. // Return :
  874. // DATE :
  875. //////////////////////////////////////////////////////////////////
  876. INT CDDButton::MsgEnable(HWND hwnd, WPARAM wParam, LPARAM lParam)
  877. {
  878. //Dbg(("MsgEnabled START wParam[%d]\n", wParam));
  879. m_fEnable = (BOOL)wParam;
  880. InvalidateRect(hwnd, NULL, FALSE);
  881. return 0;
  882. UnrefForMsg();
  883. }