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.

1204 lines
30 KiB

  1. //
  2. // wpopup.cpp
  3. //
  4. #include "private.h"
  5. #include "wpopup.h"
  6. #include "wcand.h"
  7. #include "globals.h"
  8. #include "res.h"
  9. #include "candutil.h"
  10. #include "candui.h"
  11. #include "candmenu.h"
  12. // UI object IDs
  13. #define IDUIF_COMMENTLIST 0x00000001
  14. #define IDUIF_CLOSEBUTTON 0x00000002
  15. /*=============================================================================*/
  16. /* */
  17. /* C U I F C O M M E N T L I S T */
  18. /* */
  19. /*=============================================================================*/
  20. /* C U I F C O M M E N T L I S T */
  21. /*------------------------------------------------------------------------------
  22. Constructor of CUIFCommentList
  23. ------------------------------------------------------------------------------*/
  24. CUIFCommentList::CUIFCommentList( CUIFObject *pParent, DWORD dwID, const RECT *prc, DWORD dwStyle ) : CUIFListBase( pParent, dwID, prc, dwStyle )
  25. {
  26. m_cyTitle = 0;
  27. m_cyTitleMargin = 1;
  28. m_cxCommentMargin = 9;
  29. m_cyCommentMargin = 6;
  30. m_hFontTitle = (HFONT)GetStockObject( DEFAULT_GUI_FONT );
  31. m_hFontText = (HFONT)GetStockObject( DEFAULT_GUI_FONT );
  32. }
  33. /* ~ C U I F C O M M E N T L I S T */
  34. /*------------------------------------------------------------------------------
  35. Destructor of CUIFCommentList
  36. ------------------------------------------------------------------------------*/
  37. CUIFCommentList::~CUIFCommentList( void )
  38. {
  39. }
  40. /* S E T R E C T */
  41. /*------------------------------------------------------------------------------
  42. Set rect of UI object
  43. (CUIFObject method)
  44. ------------------------------------------------------------------------------*/
  45. void CUIFCommentList::SetRect( const RECT *prc )
  46. {
  47. BOOL fChangeWidth = ((GetRectRef().right - GetRectRef().left) != (prc->right - prc->left));
  48. CUIFListBase::SetRect( prc );
  49. if (fChangeWidth) {
  50. CalcItemHeight();
  51. }
  52. }
  53. /* A D D C O M M E N T I T E M */
  54. /*------------------------------------------------------------------------------
  55. Add comment item
  56. ------------------------------------------------------------------------------*/
  57. void CUIFCommentList::AddCommentItem( CCommentListItem *pListItem )
  58. {
  59. AddItem( pListItem );
  60. }
  61. /* G E T C O M M E N T I T E M */
  62. /*------------------------------------------------------------------------------
  63. Get comment item
  64. ------------------------------------------------------------------------------*/
  65. CCommentListItem *CUIFCommentList::GetCommentItem( int iListItem )
  66. {
  67. return (CCommentListItem *)GetItem( iListItem );
  68. }
  69. /* I N I T I T E M H E I G H T */
  70. /*------------------------------------------------------------------------------
  71. Intitalize item height
  72. NOTE: This must be called after set all comment list items
  73. ------------------------------------------------------------------------------*/
  74. void CUIFCommentList::InitItemHeight( void )
  75. {
  76. CalcTitleHeight();
  77. CalcItemHeight();
  78. }
  79. /* G E T T O T A L H E I G H T */
  80. /*------------------------------------------------------------------------------
  81. Get height of all items
  82. ------------------------------------------------------------------------------*/
  83. int CUIFCommentList::GetTotalHeight( void )
  84. {
  85. int nHeight = 0;
  86. int nItem = GetCount();
  87. int iItem;
  88. for (iItem = 0; iItem < nItem; iItem++) {
  89. nHeight += GetItemHeight( iItem );
  90. }
  91. return nHeight;
  92. }
  93. /* G E T M I N I M U M W I D T H */
  94. /*------------------------------------------------------------------------------
  95. Get minimum width
  96. ------------------------------------------------------------------------------*/
  97. int CUIFCommentList::GetMinimumWidth( void )
  98. {
  99. return CalcMinimumWidth();
  100. }
  101. /* S E T T I T L E F O N T */
  102. /*------------------------------------------------------------------------------
  103. ------------------------------------------------------------------------------*/
  104. void CUIFCommentList::SetTitleFont( HFONT hFont )
  105. {
  106. m_hFontTitle = hFont;
  107. }
  108. /* S E T T E X T F O N T */
  109. /*------------------------------------------------------------------------------
  110. ------------------------------------------------------------------------------*/
  111. void CUIFCommentList::SetTextFont( HFONT hFont )
  112. {
  113. m_hFontText = hFont;
  114. }
  115. /* G E T I T E M H E I G H T */
  116. /*------------------------------------------------------------------------------
  117. Get height of item
  118. (CUIFListBase method)
  119. ------------------------------------------------------------------------------*/
  120. int CUIFCommentList::GetItemHeight( int iItem )
  121. {
  122. CCommentListItem *pItem = GetCommentItem( iItem );
  123. Assert( pItem != NULL );
  124. return (pItem != NULL) ? pItem->GetHeight() + m_cyTitle : 0;
  125. }
  126. /* P A I N T I T E M P R O C */
  127. /*------------------------------------------------------------------------------
  128. Paint list item
  129. (CUIFListBase method )
  130. ------------------------------------------------------------------------------*/
  131. void CUIFCommentList::PaintItemProc( HDC hDC, RECT *prc, CListItemBase *pItem, BOOL fSelected )
  132. {
  133. CCommentListItem *pListItem = (CCommentListItem *)pItem;
  134. CCandidateItem *pCandItem;
  135. HFONT hFontOld;
  136. COLORREF colTextOld;
  137. int iBkModeOld;
  138. RECT rc;
  139. Assert( pListItem != NULL );
  140. pCandItem = pListItem->GetCandidateItem();
  141. Assert( pCandItem != NULL );
  142. hFontOld = (HFONT)GetCurrentObject( hDC, OBJ_FONT );
  143. colTextOld = GetTextColor( hDC );
  144. iBkModeOld = SetBkMode( hDC, TRANSPARENT );
  145. // paint title
  146. rc = *prc;
  147. rc.bottom = rc.top + m_cyTitle;
  148. if (IntersectRect( &rc, &rc, prc )) {
  149. LPCWSTR psz = pCandItem->GetString();
  150. HPEN hPen;
  151. HPEN hPenOld;
  152. SIZE size;
  153. InflateRect( &rc, 0, -m_cyTitleMargin );
  154. // draw title text
  155. SelectObject( hDC, m_hFontTitle );
  156. SetTextColor( hDC, GetUIFColor( UIFCOLOR_CTRLTEXT ) );
  157. FLExtTextOutW( hDC, rc.left, rc.top, ETO_CLIPPED, &rc, psz, wcslen(psz), NULL );
  158. FLExtTextOutW( hDC, rc.left+1, rc.top, ETO_CLIPPED, &rc, psz, wcslen(psz), NULL );
  159. // draw underline
  160. FLGetTextExtentPoint32( hDC, psz, wcslen(psz), &size );
  161. hPen = CreatePen( PS_SOLID, 0, GetUIFColor( UIFCOLOR_BORDEROUTER ) );
  162. hPenOld = (HPEN)SelectObject( hDC, hPen );
  163. MoveToEx( hDC, rc.left, rc.top + size.cy, NULL );
  164. LineTo( hDC, rc.right, rc.top + size.cy );
  165. SelectObject( hDC, hPenOld );
  166. DeleteObject( hPen );
  167. }
  168. // paint comment
  169. rc = *prc;
  170. rc.top = rc.top + m_cyTitle;
  171. if (IntersectRect( &rc, &rc, prc )){
  172. LPCWSTR psz;
  173. rc.left += m_cxCommentMargin;
  174. rc.top += m_cyCommentMargin;
  175. rc.bottom -= m_cyCommentMargin;
  176. SelectObject( hDC, m_hFontText );
  177. SetTextColor( hDC, GetSysColor( COLOR_WINDOWTEXT ) );
  178. psz = pCandItem->GetPopupComment();
  179. PaintCommentProc( hDC, &rc, psz, FALSE );
  180. }
  181. // restore device context settings
  182. SelectObject( hDC, hFontOld );
  183. SetTextColor( hDC, colTextOld );
  184. SetBkMode( hDC, iBkModeOld );
  185. }
  186. /* P A I N T C O M M E N T P R O C */
  187. /*------------------------------------------------------------------------------
  188. Paint comment text proc
  189. returns height of comment text
  190. ------------------------------------------------------------------------------*/
  191. int CUIFCommentList::PaintCommentProc( HDC hDC, const RECT *prc, LPCWSTR pwch, BOOL fCalcOnly )
  192. {
  193. return FLDrawTextW( hDC, pwch, wcslen(pwch), prc, DT_TOP | DT_LEFT | DT_WORDBREAK | DT_EDITCONTROL | (fCalcOnly ? DT_CALCRECT : 0) );
  194. }
  195. /* C A L C M I N I M U M W I D T H */
  196. /*------------------------------------------------------------------------------
  197. Calculate minimum width
  198. ------------------------------------------------------------------------------*/
  199. int CUIFCommentList::CalcMinimumWidth( void )
  200. {
  201. HDC hDC = GetDC( NULL );
  202. int nItem = GetCount();
  203. int iItem;
  204. HFONT hFontOld;
  205. int cxTitle = 0;
  206. // prepare DC
  207. hFontOld = (HFONT)SelectObject( hDC, m_hFontTitle );
  208. // calc height of all items
  209. for (iItem = 0; iItem < nItem; iItem++) {
  210. CCommentListItem *pItem = GetCommentItem( iItem );
  211. if (pItem != NULL) {
  212. CCandidateItem *pCandItem = pItem->GetCandidateItem();
  213. SIZE size;
  214. FLGetTextExtentPoint32( hDC, pCandItem->GetString(), wcslen(pCandItem->GetString()), &size );
  215. cxTitle = max( cxTitle, size.cx );
  216. }
  217. }
  218. // restore DC
  219. SelectObject( hDC, hFontOld );
  220. ReleaseDC( NULL, hDC );
  221. return cxTitle + 1;
  222. }
  223. /* C A L C T I T L E H E I G H T */
  224. /*------------------------------------------------------------------------------
  225. Calculate height of title
  226. ------------------------------------------------------------------------------*/
  227. void CUIFCommentList::CalcTitleHeight( void )
  228. {
  229. HDC hDC = GetDC( NULL );
  230. m_cyTitle = GetFontHeightOfFont( hDC, m_hFontTitle ) + m_cyTitleMargin * 2;
  231. ReleaseDC( NULL, hDC );
  232. }
  233. /* C A L C I T E M H E I G H T */
  234. /*------------------------------------------------------------------------------
  235. Calculate height of all items
  236. ------------------------------------------------------------------------------*/
  237. void CUIFCommentList::CalcItemHeight( void )
  238. {
  239. HDC hDC = GetDC( NULL );
  240. int nItem = GetCount();
  241. int iItem;
  242. HFONT hFontOld;
  243. // prepare DC
  244. hFontOld = (HFONT)SelectObject( hDC, m_hFontText );
  245. // calc height of all items
  246. for (iItem = 0; iItem < nItem; iItem++) {
  247. CCommentListItem *pItem = GetCommentItem( iItem );
  248. if (pItem != NULL) {
  249. CalcItemHeightProc( hDC, pItem );
  250. }
  251. }
  252. // restore DC
  253. SelectObject( hDC, hFontOld );
  254. ReleaseDC( NULL, hDC );
  255. }
  256. /* C A L C I T E M H E I G H T P R O C */
  257. /*------------------------------------------------------------------------------
  258. Calclate height of item main routine
  259. ------------------------------------------------------------------------------*/
  260. void CUIFCommentList::CalcItemHeightProc( HDC hDC, CCommentListItem *pListItem )
  261. {
  262. CCandidateItem *pCandItem = pListItem->GetCandidateItem();
  263. RECT rc;
  264. int cyComment;
  265. GetRect( &rc );
  266. rc.left += m_cxCommentMargin;
  267. cyComment = PaintCommentProc( hDC, &rc, pCandItem->GetPopupComment(), TRUE ) + m_cyCommentMargin * 2;
  268. pListItem->SetHeight( cyComment );
  269. }
  270. /*============================================================================*/
  271. /* */
  272. /* C P O P U P C O M M E N T W I N D O W */
  273. /* */
  274. /*============================================================================*/
  275. /* C P O P U P C O M M E N T W I N D O W */
  276. /*------------------------------------------------------------------------------
  277. Constructor of CPopupCommentWindow
  278. ------------------------------------------------------------------------------*/
  279. CPopupCommentWindow::CPopupCommentWindow( CCandWindow *pCandWnd, CCandidateUI *pCandUI ) : CUIFWindow( g_hInst, UIWINDOW_TOPMOST | UIWINDOW_TOOLWINDOW | UIWINDOW_OFC10WORKPANE | UIWINDOW_HASSHADOW )
  280. {
  281. m_pCandUI = pCandUI;
  282. m_pCandWnd = pCandWnd;
  283. m_pWndFrame = NULL;
  284. m_pCloseBtn = NULL;
  285. m_pCaption = NULL;
  286. m_pCommentList = NULL;
  287. m_hIconClose = NULL;
  288. m_fUserMoved = FALSE;
  289. // initialize event sinks
  290. CCandListEventSink::InitEventSink( m_pCandUI->GetCandListMgr() );
  291. CCandUIPropertyEventSink::InitEventSink( m_pCandUI->GetPropertyMgr() );
  292. // initialize resources
  293. m_hIconClose = (HICON)LoadImage( g_hInst, MAKEINTRESOURCE(IDI_ICONCLOSE), IMAGE_ICON, 0, 0, LR_LOADMAP3DCOLORS );
  294. }
  295. /* ~ C P O P U P C O M M E N T W I N D O W */
  296. /*------------------------------------------------------------------------------
  297. Destructor of CPopupCommentWindow
  298. ------------------------------------------------------------------------------*/
  299. CPopupCommentWindow::~CPopupCommentWindow( void )
  300. {
  301. // dispose resources
  302. DestroyIcon( m_hIconClose );
  303. //
  304. CCandUIPropertyEventSink::DoneEventSink();
  305. CCandListEventSink::DoneEventSink();
  306. }
  307. /* G E T C L A S S N A M E */
  308. /*------------------------------------------------------------------------------
  309. (CUIFWindow method)
  310. ------------------------------------------------------------------------------*/
  311. LPCTSTR CPopupCommentWindow::GetClassName( void )
  312. {
  313. return _T( WNDCLASS_POPUPWND );
  314. }
  315. /* G E T W N D T I T L E */
  316. /*------------------------------------------------------------------------------
  317. (CUIFWindow method)
  318. ------------------------------------------------------------------------------*/
  319. LPCTSTR CPopupCommentWindow::GetWndTitle( void )
  320. {
  321. return _T( WNDTITLE_POPUPWND );
  322. }
  323. /* O N S E T C A N D I D A T E L I S T */
  324. /*------------------------------------------------------------------------------
  325. Callback function on SetCandidateList
  326. (CCandListEventSink method)
  327. NOTE: Do not update candidate item in the callback functios
  328. ------------------------------------------------------------------------------*/
  329. void CPopupCommentWindow::OnSetCandidateList( void )
  330. {
  331. Assert( FInitialized() );
  332. SetCommentListProc();
  333. LayoutWindow();
  334. }
  335. /* O N C L E A R C A N D I D A T E L I S T */
  336. /*------------------------------------------------------------------------------
  337. Callback function on ClearCandidateList
  338. (CCandListEventSink method)
  339. NOTE: Do not update candidate item in the callback functios
  340. ------------------------------------------------------------------------------*/
  341. void CPopupCommentWindow::OnClearCandidateList( void )
  342. {
  343. Assert( FInitialized() );
  344. ClearCommentListProc();
  345. LayoutWindow();
  346. }
  347. /* O N C A N D I T E M U P D A T E */
  348. /*------------------------------------------------------------------------------
  349. Callback function of candiate item has been updated
  350. (CCandListEventSink method)
  351. NOTE: Do not update candidate item in the callback functios
  352. ------------------------------------------------------------------------------*/
  353. void CPopupCommentWindow::OnCandItemUpdate( void )
  354. {
  355. Assert( FInitialized() );
  356. SetCommentListProc();
  357. LayoutWindow();
  358. }
  359. /* O N S E L E C T I O N C H A N G E D */
  360. /*------------------------------------------------------------------------------
  361. Callback function of candiate selection has been changed
  362. (CCandListEventSink method)
  363. NOTE: Do not update candidate item in the callback functios
  364. ------------------------------------------------------------------------------*/
  365. void CPopupCommentWindow::OnSelectionChanged( void )
  366. {
  367. Assert( FInitialized() );
  368. }
  369. /* O N P R O P E R T Y U P D A T E D */
  370. /*------------------------------------------------------------------------------
  371. Callback function on update CandiateUI property
  372. (CCandUIPropertyEventSink method)
  373. ------------------------------------------------------------------------------*/
  374. void CPopupCommentWindow::OnPropertyUpdated( CANDUIPROPERTY prop, CANDUIPROPERTYEVENT event )
  375. {
  376. switch (prop) {
  377. case CANDUIPROP_POPUPCOMMENTWINDOW: {
  378. if (event == CANDUIPROPEV_UPDATEPOSITION) {
  379. POINT pt;
  380. RECT rc;
  381. GetPropertyMgr()->GetPopupCommentWindowProp()->GetPosition( &pt );
  382. rc.left = pt.x;
  383. rc.top = pt.y;
  384. rc.right = pt.x + _nWidth;
  385. rc.bottom = pt.y + _nHeight;
  386. AdjustWindowRect( NULL, &rc, &pt, FALSE );
  387. if (rc.left != _xWnd || rc.top != _yWnd) {
  388. Move( rc.left, rc.top, -1, -1 );
  389. }
  390. }
  391. else {
  392. LayoutWindow( TRUE /* resize/repos always */ );
  393. }
  394. break;
  395. }
  396. default: {
  397. LayoutWindow( TRUE /* resize/repos always */ );
  398. break;
  399. }
  400. }
  401. }
  402. /* I N I T I A L I Z E */
  403. /*------------------------------------------------------------------------------
  404. Initialize UI objects
  405. ------------------------------------------------------------------------------*/
  406. CUIFObject *CPopupCommentWindow::Initialize( void )
  407. {
  408. RECT rc = {0};
  409. //
  410. // create window frame
  411. //
  412. m_pWndFrame = new CUIFWndFrame( this, &rc, UIWNDFRAME_ROUNDTHICK | UIWNDFRAME_RESIZERIGHT );
  413. if (m_pWndFrame) {
  414. m_pWndFrame->Initialize();
  415. AddUIObj( m_pWndFrame );
  416. }
  417. //
  418. // create caption
  419. //
  420. m_pCaption = new CUIFWndCaption( this, 0, &rc, UIWNDCAPTION_MOVABLE );
  421. if (m_pCaption) {
  422. m_pCaption->Initialize();
  423. AddUIObj( m_pCaption );
  424. }
  425. //
  426. // create close button
  427. //
  428. m_pCloseBtn = new CUIFCaptionButton( this, IDUIF_CLOSEBUTTON, &rc, UIBUTTON_PUSH | UIBUTTON_CENTER | UIBUTTON_VCENTER );
  429. if (m_pCloseBtn) {
  430. m_pCloseBtn->Initialize();
  431. m_pCloseBtn->SetIcon( m_hIconClose );
  432. AddUIObj( m_pCloseBtn );
  433. }
  434. //
  435. // create list
  436. //
  437. m_pCommentList = new CUIFCommentList( this, IDUIF_COMMENTLIST, &rc, UILIST_HORZTB | UILIST_VARIABLEHEIGHT );
  438. if (m_pCommentList) {
  439. m_pCommentList->Initialize();
  440. AddUIObj( m_pCommentList );
  441. }
  442. return CUIFWindow::Initialize();
  443. }
  444. /* M O V E */
  445. /*------------------------------------------------------------------------------
  446. ------------------------------------------------------------------------------*/
  447. void CPopupCommentWindow::Move( int x, int y, int nWidth, int nHeight )
  448. {
  449. BOOL fResize = (nWidth != -1 || nHeight != -1);
  450. RECT rc;
  451. if (fResize) {
  452. RECT rcTest;
  453. int nHeightNew;
  454. //
  455. if (nWidth == -1) {
  456. nWidth = _nWidth;
  457. }
  458. if (nHeight == -1) {
  459. nHeight = _nHeight;
  460. }
  461. // get resizable width
  462. rc.left = _xWnd;
  463. rc.top = _yWnd;
  464. rc.right = _xWnd + nWidth;
  465. rc.bottom = _yWnd + nHeight;
  466. AdjustWindowRect( GetWnd(), &rc, NULL, TRUE );
  467. nWidth = rc.right - rc.left;
  468. // get expected window height
  469. rcTest.left = 0;
  470. rcTest.top = 0;
  471. rcTest.right = nWidth;
  472. rcTest.bottom = nHeight;
  473. nHeightNew = LayoutWindowProc( &rcTest );
  474. if (0 < nHeightNew) {
  475. nHeight = nHeightNew;
  476. }
  477. // adjust window pos again (because height might be changed)
  478. rc.left = _xWnd;
  479. rc.top = _yWnd;
  480. rc.right = _xWnd + nWidth;
  481. rc.bottom = _yWnd + nHeight;
  482. AdjustWindowRect( GetWnd(), &rc, NULL, FALSE );
  483. }
  484. else {
  485. m_fUserMoved = TRUE;
  486. // ensure window is on workarea
  487. rc.left = x;
  488. rc.top = y;
  489. rc.right = x + _nWidth;
  490. rc.bottom = y + _nHeight;
  491. AdjustWindowRect( GetWnd(), &rc, NULL, FALSE );
  492. }
  493. CUIFWindow::Move( rc.left, rc.top, nWidth, nHeight );
  494. if (fResize) {
  495. // re-layout child object again
  496. // (window size should not be changed by this...)
  497. LayoutWindow();
  498. }
  499. }
  500. /* O N W I N D O W P O S C H A N G E D */
  501. /*------------------------------------------------------------------------------
  502. ------------------------------------------------------------------------------*/
  503. LRESULT CPopupCommentWindow::OnWindowPosChanged( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
  504. {
  505. LRESULT lResult = CUIFWindow::OnWindowPosChanged( hWnd, uMsg, wParam, lParam );
  506. m_pCandWnd->OnCommentWindowMoved();
  507. return lResult;
  508. }
  509. /* O N O B J E C T N O T I F Y */
  510. /*------------------------------------------------------------------------------
  511. ------------------------------------------------------------------------------*/
  512. LRESULT CPopupCommentWindow::OnObjectNotify( CUIFObject *pUIObj, DWORD dwCommand, LPARAM lParam )
  513. {
  514. DWORD dwID = pUIObj->GetID();
  515. // comment list
  516. if (dwID == IDUIF_COMMENTLIST) {
  517. switch (dwCommand) {
  518. case UILIST_SELECTED: {
  519. int iCandItem = CandItemFromListItem( (int)lParam );
  520. m_pCandWnd->OnCommentSelected( iCandItem );
  521. break;
  522. }
  523. }
  524. }
  525. // close button
  526. else if (dwID == IDUIF_CLOSEBUTTON) {
  527. switch (dwCommand) {
  528. case UIBUTTON_PRESSED: {
  529. m_pCandWnd->OnCommentClose();
  530. break;
  531. }
  532. }
  533. }
  534. return 0;
  535. }
  536. /* O N C R E A T E */
  537. /*------------------------------------------------------------------------------
  538. on create
  539. ------------------------------------------------------------------------------*/
  540. void CPopupCommentWindow::OnCreate( HWND hWnd )
  541. {
  542. SetProp( hWnd, (LPCTSTR)GlobalAddAtom(_T("MicrosoftTabletPenServiceProperty")), (HANDLE)1 );
  543. }
  544. /* O N N C D E S T R O Y */
  545. /*------------------------------------------------------------------------------
  546. on n c destroy
  547. ------------------------------------------------------------------------------*/
  548. void CPopupCommentWindow::OnNCDestroy( HWND hWnd )
  549. {
  550. RemoveProp( hWnd, (LPCTSTR)GlobalAddAtom(_T("MicrosoftTabletPenServiceProperty")) );
  551. }
  552. /* D E S T R O Y W N D */
  553. /*------------------------------------------------------------------------------
  554. Destroy candidate window
  555. ------------------------------------------------------------------------------*/
  556. void CPopupCommentWindow::DestroyWnd( void )
  557. {
  558. DestroyWindow( GetWnd() );
  559. }
  560. /* L A Y O U T W I N D O W */
  561. /*------------------------------------------------------------------------------
  562. ------------------------------------------------------------------------------*/
  563. void CPopupCommentWindow::LayoutWindow( BOOL fResize )
  564. {
  565. RECT rcWnd = GetRectRef();
  566. int nHeight;
  567. // get expected window size
  568. nHeight = LayoutWindowProc( &rcWnd );
  569. // change window size if required
  570. if (fResize || ((0 < nHeight) && (GetRectRef().bottom - GetRectRef().top != nHeight))) {
  571. int nWidth = GetRectRef().right - GetRectRef().left;
  572. RECT rc;
  573. if (m_fUserMoved || !GetPropertyMgr()->GetPopupCommentWindowProp()->IsAutoMoveEnabled()) {
  574. rc.left = _xWnd;
  575. rc.top = _yWnd;
  576. rc.right = _xWnd + nWidth;
  577. rc.bottom = _yWnd + nHeight;
  578. AdjustWindowRect( GetWnd(), &rc, NULL, FALSE );
  579. CUIFWindow::Move( rc.left, rc.top, nWidth, nHeight );
  580. }
  581. else {
  582. POINT pt;
  583. CalcPos( &pt, nWidth, nHeight );
  584. CUIFWindow::Move( pt.x, pt.y, nWidth, nHeight );
  585. }
  586. // layout again
  587. rcWnd = GetRectRef();
  588. LayoutWindowProc( &rcWnd );
  589. }
  590. }
  591. /* L A Y O U T W I N D O W P R O C */
  592. /*------------------------------------------------------------------------------
  593. ------------------------------------------------------------------------------*/
  594. int CPopupCommentWindow::LayoutWindowProc( RECT *prcWnd )
  595. {
  596. RECT rcInt = *prcWnd;
  597. RECT rc;
  598. int cyFrame = 0;
  599. int cyList = 0;
  600. int cyCaption = 0;
  601. // set font
  602. if (m_pCommentList != NULL) {
  603. m_pCommentList->SetTitleFont( GetPropertyMgr()->GetPopupCommentTitleProp()->GetFont() );
  604. m_pCommentList->SetTextFont( GetPropertyMgr()->GetPopupCommentTextProp()->GetFont() );
  605. }
  606. // layout frame
  607. if (m_pWndFrame != NULL) {
  608. m_pWndFrame->SetRect( prcWnd );
  609. m_pWndFrame->Show( TRUE );
  610. m_pWndFrame->GetInternalRect( &rcInt );
  611. cyFrame = (prcWnd->bottom - prcWnd->top) - (rcInt.bottom - rcInt.top);
  612. }
  613. // layout caption
  614. if (m_pCaption != NULL) {
  615. rc.left = rcInt.left;
  616. rc.top = rcInt.top;
  617. rc.right = rcInt.right;
  618. rc.bottom = rcInt.top + 16;
  619. m_pCaption->SetRect( &rc );
  620. m_pCaption->Show( TRUE );
  621. cyCaption = 16;
  622. }
  623. // layout close button
  624. if (m_pCloseBtn != NULL) {
  625. rc.left = rcInt.right - cyCaption;
  626. rc.top = rcInt.top;
  627. rc.right = rcInt.right;
  628. rc.bottom = rcInt.top + cyCaption;
  629. m_pCloseBtn->SetRect( &rc );
  630. m_pCloseBtn->Show( TRUE );
  631. }
  632. // layout list
  633. if (m_pCommentList != NULL) {
  634. rc.left = rcInt.left + 6;
  635. rc.top = rcInt.top + 16;
  636. rc.right = rcInt.right - 6;
  637. rc.bottom = rcInt.bottom;
  638. m_pCommentList->SetRect( &rc );
  639. m_pCommentList->Show( TRUE );
  640. cyList = m_pCommentList->GetTotalHeight();
  641. }
  642. return ((cyList != 0) ? cyFrame + cyList + cyCaption : (-1));
  643. }
  644. /* O N C A N D W I N D O W M O V E */
  645. /*------------------------------------------------------------------------------
  646. ------------------------------------------------------------------------------*/
  647. void CPopupCommentWindow::OnCandWindowMove( BOOL fResetAnyway )
  648. {
  649. POINT pt;
  650. if (!fResetAnyway && m_fUserMoved) {
  651. return;
  652. }
  653. m_fUserMoved = FALSE;
  654. if (!GetPropertyMgr()->GetPopupCommentWindowProp()->IsAutoMoveEnabled()) {
  655. return;
  656. }
  657. CalcPos( &pt, _nWidth, _nHeight );
  658. CUIFWindow::Move( pt.x, pt.y, -1, -1 );
  659. }
  660. /* S E T C O M M E N T L I S T P R O C */
  661. /*------------------------------------------------------------------------------
  662. Set comment list
  663. ------------------------------------------------------------------------------*/
  664. void CPopupCommentWindow::SetCommentListProc( void )
  665. {
  666. CCandidateList *pCandList;
  667. int i;
  668. int nCandItem;
  669. int cxMinimum;
  670. RECT rc;
  671. SIZE sizeFrame = {0};
  672. SIZE size;
  673. if (m_pCommentList == NULL) {
  674. return;
  675. }
  676. pCandList = GetCandListMgr()->GetCandList();
  677. Assert( pCandList != NULL );
  678. // reset list item
  679. m_pCommentList->DelAllItem();
  680. // Windows#482518/Satori81#907 - prevent from AV in case that we cannot get candidate list instance
  681. if (pCandList == NULL) {
  682. return;
  683. }
  684. // add list item
  685. nCandItem = pCandList->GetItemCount();
  686. for (i = 0; i < nCandItem; i++) {
  687. CCandidateItem *pCandItem;
  688. pCandItem = pCandList->GetCandidateItem( i );
  689. if (pCandItem->IsVisible() && pCandItem->IsPopupCommentVisible()) {
  690. CCommentListItem *pListItem = new CCommentListItem( i, pCandItem );
  691. if (pListItem)
  692. m_pCommentList->AddCommentItem( pListItem );
  693. }
  694. }
  695. // get minimum width
  696. cxMinimum = m_pCommentList->GetMinimumWidth();
  697. if (m_pWndFrame != NULL) {
  698. m_pWndFrame->GetFrameSize( &sizeFrame );
  699. }
  700. size.cx = cxMinimum + sizeFrame.cx + sizeFrame.cx + 6 + 6;
  701. size.cy = -1;
  702. size.cx = max( size.cx, GetSystemMetrics( SM_CXMIN ) );
  703. // resize window when needed
  704. GetRect( &rc );
  705. if ((rc.right - rc.left) < size.cx) {
  706. Move( _xWnd, _yWnd, size.cx, size.cy );
  707. }
  708. // set minimum window size
  709. if (m_pWndFrame != NULL) {
  710. m_pWndFrame->SetMinimumSize( &size );
  711. }
  712. // calc list item height
  713. m_pCommentList->InitItemHeight();
  714. // update window
  715. if (m_hWnd != NULL) {
  716. InvalidateRect( m_hWnd, NULL, TRUE );
  717. }
  718. }
  719. /* C L E A R C O M M E N T L I S T P R O C */
  720. /*------------------------------------------------------------------------------
  721. Clear comment list
  722. ------------------------------------------------------------------------------*/
  723. void CPopupCommentWindow::ClearCommentListProc( void )
  724. {
  725. m_pCommentList->DelAllItem();
  726. }
  727. /* C A N D I T E M F R O M L I S T I T E M */
  728. /*------------------------------------------------------------------------------
  729. Get index of candidate item in candidate list data
  730. from index of item in UIList object
  731. ------------------------------------------------------------------------------*/
  732. int CPopupCommentWindow::CandItemFromListItem( int iListItem )
  733. {
  734. CCommentListItem *pListItem;
  735. if (m_pCommentList == NULL) {
  736. return ICANDITEM_NULL;
  737. }
  738. pListItem = m_pCommentList->GetCommentItem( iListItem );
  739. Assert( pListItem != NULL );
  740. return (pListItem != NULL) ? pListItem->GetICandItem() : ICANDITEM_NULL;
  741. }
  742. /* C A L C P O S */
  743. /*------------------------------------------------------------------------------
  744. ------------------------------------------------------------------------------*/
  745. void CPopupCommentWindow::CalcPos( POINT *ppt, int nWidth, int nHeight )
  746. {
  747. RECT rcCandWnd;
  748. RECT rc;
  749. int cxOffset;
  750. int cyOffset;
  751. CUIFBalloonWindow *pCandTipWnd;
  752. CCandMenu *pCandMenu;
  753. WNDALIGNH HAlign;
  754. WNDALIGNV VAlign;
  755. GetWindowRect( m_pCandWnd->GetWnd(), &rcCandWnd );
  756. // calc align
  757. switch (GetPropertyMgr()->GetCandWindowProp()->GetUIDirection()) {
  758. default:
  759. case CANDUIDIR_TOPTOBOTTOM: {
  760. HAlign = LOCATE_RIGHT;
  761. VAlign = ALIGN_TOP;
  762. break;
  763. }
  764. case CANDUIDIR_BOTTOMTOTOP: {
  765. HAlign = LOCATE_RIGHT;
  766. VAlign = ALIGN_BOTTOM;
  767. break;
  768. }
  769. case CANDUIDIR_RIGHTTOLEFT: {
  770. HAlign = ALIGN_LEFT;
  771. VAlign = LOCATE_BELLOW;
  772. break;
  773. }
  774. case CANDUIDIR_LEFTTORIGHT: {
  775. HAlign = ALIGN_LEFT;
  776. VAlign = LOCATE_BELLOW;
  777. break;
  778. }
  779. }
  780. // calc offset to don't overlap with tip
  781. cxOffset = 0;
  782. cyOffset = 0;
  783. pCandTipWnd = m_pCandWnd->GetCandTipWindowObj();
  784. if (pCandTipWnd != NULL && IsWindow( pCandTipWnd->GetWnd() ) && pCandTipWnd->IsVisible()) {
  785. RECT rcCandTipWnd;
  786. GetWindowRect( pCandTipWnd->GetWnd(), &rcCandTipWnd );
  787. switch (GetPropertyMgr()->GetCandWindowProp()->GetUIDirection()) {
  788. default:
  789. case CANDUIDIR_TOPTOBOTTOM: {
  790. cyOffset += rcCandTipWnd.bottom - rcCandWnd.top;
  791. break;
  792. }
  793. case CANDUIDIR_BOTTOMTOTOP: {
  794. cyOffset += rcCandTipWnd.top - rcCandWnd.bottom - 1;
  795. break;
  796. }
  797. case CANDUIDIR_RIGHTTOLEFT: {
  798. rcCandWnd.top = min( rcCandWnd.top, rcCandTipWnd.top );
  799. rcCandWnd.bottom = max( rcCandWnd.bottom, rcCandTipWnd.bottom );
  800. break;
  801. }
  802. case CANDUIDIR_LEFTTORIGHT: {
  803. rcCandWnd.top = min( rcCandWnd.top, rcCandTipWnd.top );
  804. rcCandWnd.bottom = max( rcCandWnd.bottom, rcCandTipWnd.bottom );
  805. break;
  806. }
  807. }
  808. }
  809. // calc pos
  810. CalcWindowRect( &rc, &rcCandWnd, nWidth, nHeight, cxOffset, cyOffset, HAlign, VAlign );
  811. // recalc pos to don't overlap with menu
  812. pCandMenu = m_pCandWnd->GetCandMenu();
  813. if (pCandMenu != NULL) {
  814. CUIFMenu *pCandMenuWnd;
  815. pCandMenuWnd = pCandMenu->GetMenuUI();
  816. if (pCandMenuWnd != NULL) {
  817. RECT rcCandMenu;
  818. RECT rcUnion;
  819. RECT rcIntersect;
  820. GetWindowRect( pCandMenuWnd->GetWnd(), &rcCandMenu );
  821. if (IntersectRect( &rcIntersect, &rc, &rcCandMenu )) {
  822. UnionRect( &rcUnion, &rcCandWnd, &rcCandMenu );
  823. switch (GetPropertyMgr()->GetCandWindowProp()->GetUIDirection()) {
  824. default:
  825. case CANDUIDIR_TOPTOBOTTOM: {
  826. cyOffset += rcCandWnd.top - min( rcCandWnd.top, rcUnion.top );
  827. break;
  828. }
  829. case CANDUIDIR_BOTTOMTOTOP: {
  830. cyOffset += rcCandWnd.bottom - max( rcCandWnd.bottom, rcUnion.bottom );
  831. break;
  832. }
  833. case CANDUIDIR_RIGHTTOLEFT: {
  834. // cxOffset = rcCandWnd.right - max( rcCandWnd.right, rcUnion.right );
  835. cxOffset += rcCandWnd.left - min( rcCandWnd.left, rcUnion.left );
  836. break;
  837. }
  838. case CANDUIDIR_LEFTTORIGHT: {
  839. cxOffset += rcCandWnd.left - min( rcCandWnd.left, rcUnion.left );
  840. break;
  841. }
  842. }
  843. CalcWindowRect( &rc, &rcUnion, nWidth, nHeight, cxOffset, cyOffset, HAlign, VAlign );
  844. }
  845. }
  846. }
  847. ppt->x = rc.left;
  848. ppt->y = rc.top;
  849. }