Source code of Windows XP (NT5)
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.

5244 lines
165 KiB

  1. /*************************************************************************/
  2. /* Copyright (C) 1999 Microsoft Corporation */
  3. /* File: MFBar.cpp */
  4. /* Description: Control that is scriptable and contains other controls. */
  5. /* Designed specifically for DVD/TV control plates. */
  6. /* Author: David Janecek */
  7. /*************************************************************************/
  8. #include "stdafx.h"
  9. #include "MFBar.h"
  10. #include "ccobj.h"
  11. #include "eobj.h"
  12. #include "CBitmap.h"
  13. /*************************************************************************/
  14. /* Local defines */
  15. /* Could not find these under windows headers, so if there is a conflict */
  16. /* it is good idea to ifdef these out. */
  17. /*************************************************************************/
  18. #define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp))
  19. #define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp))
  20. #define RECTWIDTH(lpRect) ((lpRect)->right - (lpRect)->left)
  21. #define RECTHEIGHT(lpRect) ((lpRect)->bottom - (lpRect)->top)
  22. #define NOHIT 1
  23. #define LEFT 2
  24. #define TOP 4
  25. #define RIGHT 8
  26. #define BOTTOM 16
  27. #define ID_EV_TIMER 0xff
  28. /*************************************************************************/
  29. /* Windows defines not present, remove when doing the real BUILD. */
  30. /*************************************************************************/
  31. typedef WINUSERAPI BOOL ( WINAPI * SETLAYEREDWINDATR)(
  32. HWND hwnd,
  33. COLORREF crKey,
  34. BYTE bAlpha,
  35. DWORD dwFlags);
  36. #if 0
  37. #define LWA_COLORKEY 0x00000001
  38. #endif
  39. /*************************************************************************/
  40. /* Local functions */
  41. /*************************************************************************/
  42. inline long MAX(long l1, long l2){return(l1 > l2 ? l1 : l2);}
  43. inline long MIN(long l1, long l2){return(l1 < l2 ? l1 : l2);}
  44. /*************************************************************************/
  45. /* Statics for window class info */
  46. /*************************************************************************/
  47. HICON CMFBar::m_hIcon = NULL;
  48. /*****************************************************************/
  49. /* change this depending if the file was saved as Unicode or not */
  50. /*****************************************************************/
  51. //#define _UNICODE_SCRIPT_FILE
  52. /*************************************************************************/
  53. /* CMFBar Implementation */
  54. /*************************************************************************/
  55. /*************************************************************************/
  56. /* Function: Init */
  57. /* Description: Initializes memeber variables. */
  58. /*************************************************************************/
  59. HRESULT CMFBar::Init(){
  60. HRESULT hr = S_OK;
  61. // #### BEGIN CONTAINER SUPPORT ####
  62. m_bCanWindowlessActivate = true;
  63. // #### END CONTAINER SUPPORT ####
  64. #if 1 // used for getting the windowed case working DJ
  65. m_bWindowOnly = TRUE;
  66. #endif
  67. m_fSelfHosted = false;
  68. // TODO: Investigate if it works in pallete mode
  69. m_clrBackColor = ::GetSysColor(COLOR_BTNFACE);
  70. m_lMinWidth = -1; // disable it
  71. m_lMinHeight = -1; // disable it by default
  72. m_fHandleHelp = false;
  73. m_blitType = DISABLE;
  74. m_bMouseDown = false;
  75. m_ptMouse.x = 0;
  76. m_ptMouse.y = 0;
  77. m_nReadyState = READYSTATE_LOADING;
  78. m_fAutoLoad = VARIANT_TRUE;
  79. m_pBackBitmap = NULL;
  80. m_fForceKey = false;
  81. m_lTimeout = 0;
  82. m_fUserActivity = false;
  83. m_fWaitingForActivity = false;
  84. // setup the default resource DLL to be this binary
  85. m_hRes = _Module.m_hInstResource; // set the resource DLL Name
  86. TCHAR szModule[_MAX_PATH+10];
  87. ::GetModuleFileName(m_hRes, szModule, _MAX_PATH);
  88. USES_CONVERSION;
  89. m_strResDLL = T2OLE(szModule);
  90. if(NULL == m_hIcon){
  91. m_hIcon = ::LoadIcon(m_hRes, MAKEINTRESOURCE(IDI_ICON1));
  92. //m_hIcon = (HICON)::LoadImage(_Module.m_hInstResource, MAKEINTRESOURCE(IDI_ICON1),
  93. // IMAGE_ICON, ::GetSystemMetrics(SM_CXSMICON), ::GetSystemMetrics(SM_CYSMICON), LR_DEFAULTCOLOR);
  94. }/* end of if statement */
  95. return(hr);
  96. }/* end of function Init */
  97. /*************************************************************************/
  98. /* Function: Cleanup */
  99. /* Description: Makes sure the script engine is released. Also cleans */
  100. /* up the contained objects in the containers. */
  101. /*************************************************************************/
  102. HRESULT CMFBar::Cleanup(){
  103. // ##### BEGIN ACTIVEX SCRIPTING SUPPORT #####
  104. // Release the language engine, since it may hold on to us
  105. if (m_psp){
  106. m_psp.Release();
  107. }/* end of if statement */
  108. if (m_ps){
  109. m_ps->Close();
  110. m_ps.Release();
  111. }/* end of if statement */
  112. // cleanup the event list
  113. for(CNTEVNT::iterator i = m_cntEvnt.begin(); false == m_cntEvnt.empty(); ){
  114. CEventObject* pObj = (*i);
  115. delete pObj;
  116. i = m_cntEvnt.erase(i);
  117. }/* end of if statement */
  118. CContainerObject* pSelfContainerObj = NULL;
  119. // cleanup the object list
  120. for(CNTOBJ::iterator j = m_cntObj.begin(); false == m_cntObj.empty(); ){
  121. CHostedObject* pObj = (*j);
  122. // delete the container object as well
  123. CContainerObject* pContainerObj;
  124. HRESULT hrCont = pObj->GetContainerObject(&pContainerObj);
  125. IUnknown* pUnk = pObj->GetUnknown();
  126. #if _DEBUG
  127. BSTR strOBJID = ::SysAllocString(pObj->GetID());
  128. #endif
  129. try {
  130. delete pObj;
  131. }
  132. catch(...){
  133. #if _DEBUG
  134. USES_CONVERSION;
  135. ATLTRACE(TEXT(" Failed to destroy %s "), OLE2T(strOBJID));
  136. ::SysFreeString(strOBJID);
  137. #endif
  138. }/* end of catch statement */
  139. if(SUCCEEDED(hrCont)){
  140. #if 1
  141. if(GetUnknown() != pUnk){
  142. delete pContainerObj; // do not delete our self
  143. }
  144. else {
  145. pSelfContainerObj = pContainerObj;
  146. }/* end of if statement */
  147. #endif
  148. }/* end of if statement */
  149. j = m_cntObj.erase(j);
  150. }/* end of if statement */
  151. ResetFocusArray();
  152. delete pSelfContainerObj;
  153. if(m_pBackBitmap){
  154. delete m_pBackBitmap;
  155. m_pBackBitmap = NULL;
  156. }/* end of if statement */
  157. HRESULT hr = Init();
  158. // ##### END ACTIVEX SCRIPTING SUPPORT #####
  159. return (hr);
  160. }/* end of function Cleanup */
  161. /*************************************************************************/
  162. /* Function: ~CMFBar */
  163. /*************************************************************************/
  164. CMFBar::~CMFBar(){
  165. Cleanup();
  166. ATLTRACE(TEXT("Exiting CMFBar destructor! \n"));
  167. }/* end of function ~CMFBar */
  168. /*************************************************************************/
  169. /* Message handling. */
  170. /*************************************************************************/
  171. /*************************************************************************/
  172. /* Function: OnPaint */
  173. /* Description: Had to overwrite the the deafult OnPaint so I could */
  174. /* somehow get the real update rects. */
  175. /*************************************************************************/
  176. LRESULT CMFBar::OnPaint(UINT /* uMsg */, WPARAM wParam,
  177. LPARAM /* lParam */, BOOL& /* lResult */){
  178. RECT rc;
  179. PAINTSTRUCT ps;
  180. HDC hdc = (wParam != NULL) ? (HDC)wParam : ::BeginPaint(m_hWndCD, &ps);
  181. if (hdc == NULL)
  182. return 0;
  183. ::GetClientRect(m_hWndCD, &rc);
  184. ATL_DRAWINFO di;
  185. memset(&di, 0, sizeof(di));
  186. di.cbSize = sizeof(di);
  187. di.dwDrawAspect = DVASPECT_CONTENT;
  188. di.lindex = -1;
  189. di.hdcDraw = hdc;
  190. // DJ change here, keep the real update rect from the PAINTSTRUCT
  191. // Set the window size to the size of the window
  192. di.prcWBounds = (LPCRECTL)&rc;
  193. di.prcBounds = (LPCRECTL)&ps.rcPaint;
  194. OnDrawAdvanced(di); // Eventually propagates to OnDraw
  195. if (wParam == NULL)
  196. ::EndPaint(m_hWndCD, &ps);
  197. return 0;
  198. }/* end of function OnPaint */
  199. /*************************************************************************/
  200. /* Function: OnDraw */
  201. /* Description: Just Draws the rectangular background and contained */
  202. /* windowless controls. */
  203. /*************************************************************************/
  204. HRESULT CMFBar::OnDraw(ATL_DRAWINFO& di){
  205. try {
  206. HDC hdc = di.hdcDraw;
  207. RECT rcClient = *(RECT*)di.prcBounds;
  208. RECT rcWClient = *(RECT*)di.prcWBounds;
  209. // this might not work if you overlapp the controls
  210. // controls like to be painted as a whole so if
  211. // we need to update the are that contains the control
  212. // we need to find all the controls that intersect it, combine the
  213. // rectangle and then repaint the whole region
  214. if(::IsWindow(m_hWnd)){
  215. if(!::EqualRect(&rcClient, &rcWClient)){
  216. RECT rcNewClient = rcClient; // the original update are which we are enlarging
  217. for(CNTOBJ::iterator i = m_cntObj.begin(); i!= m_cntObj.end(); i++){
  218. // iterate through all the contained objects and draw them
  219. CHostedObject* pObj = (*i);
  220. if((NULL != pObj) && (pObj->IsActive())){
  221. if(pObj->IsWindowless()){
  222. RECT rcCntrl;
  223. pObj->GetPos(&rcCntrl); // get the position of the object
  224. RECT rcInt;
  225. if(!::IntersectRect(&rcInt, &rcCntrl, &rcClient)){
  226. continue;
  227. }
  228. else {
  229. // OK we need to add this control rect to our rect union
  230. ::UnionRect(&rcNewClient, &rcClient, &rcCntrl);
  231. }/* end of if statement */
  232. }/* end of if statement */
  233. }/* end of if statement */
  234. }/* end of for loop */
  235. rcClient = rcNewClient; // update our are with enlarged client
  236. }/* end of if statement */
  237. // else if the rects are the same we are updating the whole
  238. // window so there is no point to do the calculations
  239. }/* end of if statement */
  240. COLORREF clr;
  241. HPALETTE hPal = NULL;
  242. if(m_pBackBitmap){
  243. hPal = m_pBackBitmap->GetPal();
  244. if(NULL != hPal){
  245. ::SelectPalette(hdc, hPal, FALSE);
  246. ::RealizePalette(hdc);
  247. }/* end of if statement */
  248. }/* end of if statement */
  249. ::OleTranslateColor (m_clrBackColor, hPal, &clr);
  250. // fill in the background and get ready to fill in the objects
  251. LONG lBmpWidth = RECTWIDTH(&rcWClient);
  252. LONG lBmpHeight = RECTHEIGHT(&rcWClient);
  253. HBITMAP hBitmap = ::CreateCompatibleBitmap(hdc, lBmpWidth, lBmpHeight);
  254. if(NULL == hBitmap){
  255. ATLASSERT(FALSE);
  256. return(0);
  257. }/* end of if statement */
  258. HDC hdcCompatible = ::CreateCompatibleDC(hdc);
  259. if(NULL == hBitmap){
  260. ATLASSERT(FALSE);
  261. ::DeleteObject(hBitmap);
  262. return(0);
  263. }/* end of if statement */
  264. // Draw background on the faceplate bitmap
  265. ::SelectObject(hdcCompatible, hBitmap);
  266. if (!m_pBackBitmap){
  267. // fill background of specific color
  268. HBRUSH hbrBack = ::CreateSolidBrush(clr);
  269. //::FillRect(hdc, &rcClient, hbrBack);
  270. ::FillRect(hdcCompatible, &rcClient, hbrBack);
  271. ::DeleteObject(hbrBack);
  272. }
  273. else {
  274. //BOOL bRet = m_pBackBitmap->PaintTransparentDIB(hdc, &rcWClient, &rcClient, m_blitType, true);
  275. BOOL bRet = m_pBackBitmap->PaintTransparentDIB(hdcCompatible, &rcWClient, &rcClient, m_blitType, true);
  276. if(!bRet){
  277. ATLTRACE(TEXT(" The transparent Blit did not work!"));
  278. }/* end of if statement */
  279. }/* end of if statement */
  280. for(CNTOBJ::iterator i = m_cntObj.begin(); i!= m_cntObj.end(); i++){
  281. // iterate through all the contained objects and draw them
  282. CHostedObject* pObj = (*i);
  283. CComPtr<IViewObjectEx> pViewObject = NULL;
  284. if((NULL != pObj) && (pObj->IsActive()) && (SUCCEEDED(pObj->GetViewObject(&pViewObject)))){
  285. if(pObj->IsWindowless()){
  286. if(pViewObject){
  287. if(GetUnknown() == pObj->GetUnknown()){
  288. // in case we are windowless and we are trying to draw our self again
  289. continue;
  290. }/* end of if statement */
  291. RECT rcCntrl;
  292. pObj->GetPos(&rcCntrl);
  293. RECT rcInt;
  294. if(!::IntersectRect(&rcInt, &rcCntrl, &rcClient)){
  295. continue;
  296. }/* end of if statement */
  297. LONG lBmpWidth = RECTWIDTH(&rcCntrl);
  298. LONG lBmpHeight = RECTHEIGHT(&rcCntrl);
  299. RECT rcCntrlBitmap = {0, 0, lBmpWidth, lBmpHeight};
  300. POINT ptNewOffset = {rcCntrl.left, rcCntrl.top};
  301. POINT ptOldOffset;
  302. ::GetViewportOrgEx(hdcCompatible, &ptOldOffset);
  303. LPtoDP(hdcCompatible, &ptNewOffset, 1);
  304. // offset the rect we are catually going to draw
  305. //::OffsetRect(&rcInt, -ptNewOffset.x, -ptNewOffset.y);
  306. // offset the DC
  307. ::OffsetViewportOrgEx(hdcCompatible, ptNewOffset.x, ptNewOffset.y, &ptOldOffset);
  308. // draw
  309. ATLTRACE2(atlTraceWindowing, 31, TEXT("Drawing CONTROL into rcClient.left = %d, rcClient.right = %d, rcClient.bottom =%d, rcClient.top = %d\n"),rcCntrl.left, rcCntrl.right, rcCntrl.bottom, rcCntrl.top);
  310. #if 1 // used to redraw the whole control, now we are just doinf part of it
  311. //HRGN hrgnOld = NULL;
  312. //HRGN hrgnNew = NULL;
  313. //if(::IsWindow(m_hWnd)){
  314. //
  315. // hrgnNew = ::CreateRectRgnIndirect(&rcInt);
  316. // hrgnOld = (HRGN)::SelectObject(hdc, hrgnNew);
  317. //}/* end of if statement */
  318. pViewObject->Draw(DVASPECT_CONTENT, -1, NULL, NULL, NULL, hdcCompatible, (RECTL*)&rcCntrlBitmap, (RECTL*)&rcCntrlBitmap, NULL, NULL);
  319. #else
  320. pViewObject->Draw(DVASPECT_CONTENT, -1, NULL, NULL, NULL, hdcCompatible, (RECTL*)&rcInt, (RECTL*)&rcCntrlBitmap, NULL, NULL);
  321. #endif
  322. ::SetViewportOrgEx(hdcCompatible, ptOldOffset.x, ptOldOffset.y, NULL);
  323. }
  324. #ifdef _DEBUG
  325. else {
  326. ATLTRACE2(atlTraceWindowing, 30,TEXT("FAILED Drawing the object since pView is NULL\n"));
  327. }/* end of if statement */
  328. #endif
  329. }/* end of if statement */
  330. }/* end of if statement */
  331. }/* end of for loop */
  332. ::BitBlt(hdc, rcClient.left, rcClient.top, lBmpWidth, lBmpHeight, hdcCompatible, rcClient.left, rcClient.top, SRCCOPY);
  333. // cleanup
  334. ::DeleteDC(hdcCompatible);
  335. ::DeleteObject(hBitmap);
  336. return(1);
  337. }/* end of try statement */
  338. catch(...){
  339. return(0);
  340. }/* end of catch statement */
  341. }/* end of function OnDraw */
  342. /*************************************************************************/
  343. /* Function: OnErase */
  344. /* Description: Skip the erasing to avoid flickers. */
  345. /*************************************************************************/
  346. LRESULT CMFBar::OnErase(UINT, WPARAM wParam, LPARAM lParam, BOOL& bHandled){
  347. ATLTRACE2(atlTraceWindowing, 32, TEXT("Received WM_ERASE MESSAGE \n"));
  348. #if 0
  349. POINT pt; pt.x =0; pt.y = 0;
  350. ::MapWindowPoints(m_hWnd, hWndPar, &pt, 1);
  351. ::OffsetWindowOrgEx(hdc, pt.x, pt.y, &pt);
  352. ::SendMessage(hWndPar, WM_ERASEBKGND, (WPARAM) hdc, 0);
  353. ::SetWindowOrgEx(hdc, pt.x, pt.y, NULL);
  354. #endif
  355. //InvalidateRect(&m_rcPos, FALSE);
  356. bHandled = TRUE;
  357. return 1;
  358. }/* end of function OnErase */
  359. /*************************************************************************/
  360. /* Function: OnQueryNewPalette */
  361. /* Description: Called when we are about to be instantiated. */
  362. /*************************************************************************/
  363. LRESULT CMFBar::OnQueryNewPalette(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled){
  364. if(NULL == ::IsWindow(m_hWnd)){
  365. bHandled = FALSE;
  366. return FALSE;
  367. }/* end of if statement */
  368. HPALETTE hPal = NULL;
  369. if(NULL == m_pBackBitmap){
  370. hPal = m_pBackBitmap->GetPal();
  371. }/* end of if statement */
  372. if(NULL == hPal){
  373. //bHandled = FALSE;
  374. return FALSE;
  375. }/* end of if statement */
  376. HDC hdc = ::GetDC(m_hWnd);
  377. ::SelectPalette(hdc, hPal, FALSE);
  378. ::RealizePalette(hdc);
  379. ::InvalidateRect(m_hWnd, NULL, FALSE);
  380. ::ReleaseDC(m_hWnd, hdc);
  381. return TRUE;
  382. }/* end of function OnQueryNewPalette */
  383. /*************************************************************************/
  384. /* Function: OnPaletteChanged */
  385. /* Description: Called when palette is chaning. */
  386. /*************************************************************************/
  387. LRESULT CMFBar::OnPaletteChanged(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled){
  388. if(NULL == ::IsWindow(m_hWnd)){
  389. bHandled = FALSE;
  390. return FALSE;
  391. }/* end of if statement */
  392. if((HWND) wParam == m_hWnd){
  393. bHandled = FALSE;
  394. return FALSE;
  395. }/* end of if statement */
  396. HPALETTE hPal = NULL;
  397. if(NULL == m_pBackBitmap){
  398. hPal = m_pBackBitmap->GetPal();
  399. }/* end of if statement */
  400. if(NULL == hPal){
  401. bHandled = FALSE;
  402. return FALSE;
  403. }/* end of if statement */
  404. HDC hdc = ::GetDC(m_hWnd);
  405. ::SelectPalette(hdc, hPal, FALSE);
  406. ::RealizePalette(hdc);
  407. ::UpdateColors(hdc);
  408. ::ReleaseDC(m_hWnd, hdc);
  409. bHandled = FALSE;
  410. return TRUE;
  411. }/* end of function OnPaletteChanged */
  412. /*************************************************************************/
  413. /* Function: OnClose */
  414. /* Description: Skip the erasing to avoid flickers. */
  415. /*************************************************************************/
  416. LRESULT CMFBar::OnClose(UINT, WPARAM wParam, LPARAM lParam, BOOL& bHandled){
  417. if(::IsWindow(m_hWnd)){
  418. ::DestroyWindow(m_hWnd);
  419. }/* end of if statement */
  420. HRESULT hr = Close(OLECLOSE_SAVEIFDIRTY);
  421. ATLTRACE(TEXT("Closing \n"));
  422. if(SUCCEEDED(hr)){
  423. bHandled = TRUE;
  424. }/* end of if statement */
  425. return 0;
  426. }/* end of function OnClose */
  427. /*************************************************************************/
  428. /* Function: OnSysCommand */
  429. /* Description: Handles the on syscommand. */
  430. /*************************************************************************/
  431. LRESULT CMFBar::OnSysCommand(UINT, WPARAM wParam, LPARAM lParam, BOOL& bHandled){
  432. ATLTRACE2(atlTraceWindowing, 20, TEXT("Received WM_SYSCOMMAND MESSAGE \n"));
  433. if(wParam == SC_CONTEXTHELP){
  434. m_fHandleHelp = true;
  435. }/* end of if statement */
  436. bHandled = FALSE;
  437. return(1);
  438. }/* end of function OnSysCommand */
  439. /*************************************************************************/
  440. /* Function: OnTimer */
  441. /* Description: Handles the timer message. */
  442. /*************************************************************************/
  443. LRESULT CMFBar::OnTimer(UINT, WPARAM wParam, LPARAM lParam, BOOL& bHandled){
  444. WPARAM wTimerID = wParam;
  445. if(ID_EV_TIMER == wTimerID){
  446. if(false == m_fUserActivity && false == m_fWaitingForActivity){
  447. // fire message that there is no activity going on
  448. m_fWaitingForActivity = true;
  449. Fire_ActivityDeclined();
  450. }/* end of if statement */
  451. m_fUserActivity = false; // reset the flag
  452. }
  453. else {
  454. if(::IsWindow(m_hWnd)){
  455. ::KillTimer(m_hWnd, wTimerID);
  456. }/* end of if statement */
  457. Fire_Timeout(wTimerID);
  458. }/* end of if statement */
  459. bHandled = TRUE;
  460. return(1);
  461. }/* end of function OnTimer */
  462. /*************************************************************************/
  463. /* Function: OnCaptureChanged */
  464. /* Description: Handles the on syscommand. */
  465. /*************************************************************************/
  466. LRESULT CMFBar::OnCaptureChanged(UINT, WPARAM wParam, LPARAM lParam, BOOL& bHandled){
  467. ATLTRACE2(atlTraceWindowing, 20, TEXT("Received WM_CAPTURECHANGED MESSAGE \n"));
  468. if(m_fHandleHelp){
  469. HWND h;
  470. if(SUCCEEDED(GetWindow(&h))){
  471. POINT pt;
  472. ::GetCursorPos(&pt);
  473. RECT rc;
  474. ::GetWindowRect(h, &rc);
  475. if(!::PtInRect(&rc, pt)){
  476. // we clicked somewhere outiside in our help mode
  477. m_fHandleHelp = false; // otherwise we are going to get lbutton up and we will
  478. // turn it off then
  479. }/* end of if statement */
  480. }
  481. else {
  482. m_fHandleHelp = false; // could not get the window, but better trun off
  483. // the help mode
  484. }/* end of if statement */
  485. }/* end of if statement */
  486. bHandled = TRUE;
  487. return(0);
  488. }/* end of function OnCaptureChanged */
  489. /*************************************************************************/
  490. /* Function: OnSetIcon */
  491. /* Description: Fires the help event. */
  492. /*************************************************************************/
  493. LRESULT CMFBar::OnSetIcon(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled){
  494. LRESULT lr = ::DefWindowProc(m_hWnd, uMsg, wParam, lParam);
  495. return(lr);
  496. }/* end of function OnSetIcon */
  497. /*************************************************************************/
  498. /* Function: OnInitDialog */
  499. /* Description: Fires the help event. */
  500. /*************************************************************************/
  501. LRESULT CMFBar::OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled){
  502. ATLASSERT(FALSE);
  503. LRESULT lr = ::DefWindowProc(m_hWnd, uMsg, wParam, lParam);
  504. return(lr);
  505. }/* end of function OnInitDialog */
  506. /*************************************************************************/
  507. /* Function: OnHelp */
  508. /* Description: Fires the help event. */
  509. /*************************************************************************/
  510. LRESULT CMFBar::OnHelp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled){
  511. HELPINFO* pHpi = (LPHELPINFO) lParam;
  512. bHandled = TRUE;
  513. if(NULL == pHpi){
  514. return 0;
  515. }/* end of if statement */
  516. // first check if we have fired help on message box
  517. HWND hCntrlWnd = (HWND)pHpi->hItemHandle;
  518. if(::GetWindowLong(hCntrlWnd, GWL_STYLE) & WS_DLGFRAME == WS_DLGFRAME){
  519. // we have a message box up
  520. HWND hwndText;
  521. hwndText = ::FindWindowEx(hCntrlWnd, NULL, TEXT("Static"), NULL);
  522. if(hwndText){
  523. TCHAR strWindowText[MAX_PATH];
  524. ::GetWindowText(hwndText, strWindowText, MAX_PATH);
  525. ::DestroyWindow(hCntrlWnd);
  526. BSTR strToolbarName;
  527. if(SUCCEEDED(GetToolbarName(&strToolbarName))){
  528. USES_CONVERSION;
  529. Fire_OnHelp(strToolbarName, ::SysAllocString(T2OLE(strWindowText)));
  530. }/* end of if statement */
  531. }
  532. else {
  533. ::DestroyWindow(hCntrlWnd);
  534. }/* end of if statement */
  535. return(TRUE);
  536. }/* end of if statement */
  537. // then check if a windowed control has fired help
  538. for(CNTOBJ::iterator i = m_cntObj.begin(); i!= m_cntObj.end(); i++){
  539. // iterate through all the contained controls
  540. CHostedObject* pObj = (*i);
  541. if(NULL == pObj){
  542. ATLASSERT(FALSE); // should not be null
  543. continue;
  544. }/* end of if statement */
  545. if(pObj->IsActive() && !pObj->IsWindowless()){
  546. HWND hwnd = NULL;
  547. HRESULT hr = pObj->GetWindow(&hwnd);
  548. if(FAILED(hr)){
  549. continue;
  550. }/* end of if statement */
  551. if(hwnd == hCntrlWnd){
  552. Fire_OnHelp(::SysAllocString(pObj->GetID()));
  553. return(TRUE);
  554. }/* end of if statement */
  555. }/* end of if statement */
  556. }/* end of for loop */
  557. // now look into windowless control
  558. POINT ptMouse = pHpi->MousePos;
  559. m_fHandleHelp = false; // get our self out of the help mode in case we clicked
  560. // on windowed control and we did not get notified about this
  561. // convert the point to client coordinates
  562. HWND h = NULL;
  563. HRESULT hr = GetWindow(&h);
  564. if(FAILED(hr)){
  565. ATLASSERT(FALSE);
  566. return(0);
  567. }/* end of if statement */
  568. if(!::ScreenToClient(h, &ptMouse)){
  569. ATLASSERT(FALSE);
  570. return(0);
  571. }/* end of if statement */
  572. for(i = m_cntObj.begin(); i!= m_cntObj.end(); i++){
  573. // iterate through all the contained controls
  574. CHostedObject* pObj = (*i);
  575. if(NULL == pObj){
  576. ATLASSERT(FALSE); // should not be null
  577. continue;
  578. }/* end of if statement */
  579. // send the message to the control over which we are howering or on which we
  580. // have clicked, check if we already are ready to send the message
  581. // in that case do not bother with the rect interstec bussines
  582. if(pObj->IsActive()){
  583. CComPtr<IViewObjectEx> pViewObject;
  584. HRESULT hr = pObj->GetViewObject(&pViewObject);
  585. if(FAILED(hr)){
  586. ATLASSERT(FALSE); // should have a view
  587. continue;
  588. }/* end of if statement */
  589. DWORD dwHitResult = HITRESULT_OUTSIDE;
  590. RECT rcCntrl;
  591. pObj->GetPos(&rcCntrl);
  592. pViewObject->QueryHitPoint(DVASPECT_CONTENT, &rcCntrl, ptMouse, 0, &dwHitResult);
  593. if(HITRESULT_HIT == dwHitResult){
  594. Fire_OnHelp(::SysAllocString(pObj->GetID()));
  595. return(TRUE);
  596. }/* end of if statement */
  597. }/* end of if statement */
  598. }/* end of for loop */
  599. // Get toolbar name
  600. BSTR strToolbarName;
  601. if(SUCCEEDED(GetToolbarName(&strToolbarName))){
  602. Fire_OnHelp(strToolbarName);
  603. }/* end of if statement */
  604. return(TRUE);
  605. }/* end of function OnHelp */
  606. /*************************************************************************/
  607. /* Function: OnSize */
  608. /* Description: Handles the onsize message if we are self contained. */
  609. /*************************************************************************/
  610. LRESULT CMFBar::OnSize(UINT, WPARAM wParam, LPARAM lParam, BOOL& bHandled){
  611. if(false == m_fSelfHosted){
  612. bHandled = FALSE;
  613. return 0;
  614. }/* end of if statement */
  615. LONG lWidth = LOWORD(lParam);
  616. LONG lHeight = HIWORD(lParam);
  617. Fire_OnResize(lWidth, lHeight, wParam);
  618. if (m_pBackBitmap) {
  619. InvalidateRgn();
  620. if (::IsWindow(m_hWnd))
  621. ::UpdateWindow(m_hWnd);
  622. }
  623. bHandled = true;
  624. return 0;
  625. }/* end of function OnSize */
  626. /*************************************************************************/
  627. /* Function: OnSizing */
  628. /* Description: Does not let us scale beyond the minimum size. If it */
  629. /* tries to we fix up the rect on it. */
  630. /*************************************************************************/
  631. LRESULT CMFBar::OnSizing(UINT, WPARAM wParam, LPARAM lParam, BOOL& bHandled){
  632. if(false == m_fSelfHosted){
  633. bHandled = FALSE;
  634. return 0;
  635. }/* end of if statement */
  636. RECT* lpRect = (LPRECT)lParam;
  637. LONG lWidth = RECTWIDTH(lpRect);
  638. LONG lHeight = RECTHEIGHT(lpRect);
  639. // if we are going to be to small fix the rect
  640. if(lWidth < m_lMinWidth){
  641. lpRect->right = lpRect->left + m_lMinWidth;
  642. }/* end of if statement */
  643. if(lHeight < m_lMinHeight){
  644. lpRect->bottom = lpRect->top + m_lMinHeight;
  645. }/* end of if statement */
  646. bHandled = true;
  647. return 0;
  648. }/* end of function OnSizing */
  649. /*************************************************************************/
  650. /* Function: Close */
  651. /* Description: Just exposes the underlaying Close functionality to our */
  652. /* custom interface. */
  653. /*************************************************************************/
  654. STDMETHODIMP CMFBar::Close(){
  655. if(::IsWindow(m_hWnd)){
  656. ::PostMessage(m_hWnd, WM_CLOSE, NULL, NULL);
  657. return(S_OK);
  658. //::DestroyWindow(m_hWnd);
  659. }/* end of if statement */
  660. return(Close(OLECLOSE_SAVEIFDIRTY));
  661. }/* end of function Close */
  662. /*************************************************************************/
  663. /* Function: Close */
  664. /* Description: Calls OLECLOSE the contained objects, then itself. */
  665. /* The cleans up the containers and send WM_QUIT if we are self hosting. */
  666. /*************************************************************************/
  667. STDMETHODIMP CMFBar::Close(DWORD dwSaveOption){
  668. HRESULT hr = DestroyScriptEngine();
  669. ATLASSERT(SUCCEEDED(hr));
  670. for(CNTOBJ::iterator i = m_cntObj.begin(); i!= m_cntObj.end(); i++){
  671. // iterate through all the contained objects and call on the Close
  672. CHostedObject* pObj = (*i);
  673. CComPtr<IOleObject> pIOleObject;
  674. HRESULT hrIOleObj = pObj->GetOleObject(&pIOleObject);
  675. if(FAILED(hr)){
  676. continue;
  677. }/* end of if statement */
  678. if(GetUnknown() == pObj->GetUnknown()){
  679. continue; // that is us we close our self later after the contained objects
  680. }/* end of if statement */
  681. pIOleObject->Close(dwSaveOption);
  682. //pIOleObject->Release(); // we added a reference, we better clean it up now
  683. }/* end of for loop */
  684. hr = IOleObjectImpl<CMFBar>::Close(dwSaveOption);
  685. bool fSelfHosted = m_fSelfHosted; // cache up the variable, since we are going to
  686. // wipe it out
  687. Cleanup(); // delete all the objects
  688. if(fSelfHosted){
  689. ::PostMessage(NULL, WM_QUIT, NULL, NULL); // tell our container to give up
  690. }/* end of if statement */
  691. return(hr);
  692. }/* end of function Close */
  693. /*************************************************************************/
  694. /* Function: AddFocusObject */
  695. /* Description: Adds an object to the end of the focus array. */
  696. /*************************************************************************/
  697. STDMETHODIMP CMFBar::AddFocusObject(BSTR strObjectID){
  698. HRESULT hr = S_OK;
  699. try {
  700. CHostedObject* pObj;
  701. hr = FindObject(strObjectID, &pObj);
  702. if(FAILED(hr)){
  703. throw(hr);
  704. }/* end of if statement */
  705. m_cntFocus.insert(m_cntFocus.end(), pObj);
  706. }
  707. catch(HRESULT hrTmp){
  708. hr = hrTmp;
  709. }
  710. catch(...){
  711. hr = E_UNEXPECTED;
  712. }/* end of try statement */
  713. return (hr);
  714. }/* end of function AddFocusObject */
  715. /*************************************************************************/
  716. /* Function: ResetFocusArray */
  717. /* Description: Resets the focus array. */
  718. /*************************************************************************/
  719. STDMETHODIMP CMFBar::ResetFocusArray(){
  720. HRESULT hr = S_OK;
  721. try {
  722. ResetFocusFlags();
  723. // cleanup the focus array
  724. for(CNTOBJ::iterator k = m_cntFocus.begin(); false == m_cntFocus.empty(); ){
  725. k = m_cntFocus.erase(k);
  726. }/* end of for loop */
  727. }
  728. catch(HRESULT hrTmp){
  729. hr = hrTmp;
  730. }
  731. catch(...){
  732. hr = E_UNEXPECTED;
  733. }/* end of try statement */
  734. return (hr);
  735. }/* end of function ResetFocusArray */
  736. /*************************************************************************/
  737. /* Function: OnSetFocus */
  738. /* Description: Iterates through the container and sends the focus */
  739. /* message to the control that thinks it has the focus. */
  740. /*************************************************************************/
  741. LRESULT CMFBar::OnSetFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled){
  742. bHandled = TRUE;
  743. LONG lRes = 0;
  744. if(m_cntObj.empty() == true){
  745. return 0;
  746. }/* end of if statement */
  747. MoveFocus(TRUE, lRes);
  748. return lRes;
  749. }/* end of function OnSetFocus */
  750. /*************************************************************************/
  751. /* Function: OnUserFocus */
  752. /* Description: Iterates through the container and sends the focus */
  753. /* message to the control that thinks it has the focus. In this case */
  754. /* the control is specified by hwnd and that it is a windowed control. */
  755. /*************************************************************************/
  756. LRESULT CMFBar::OnUserFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled){
  757. bHandled = TRUE;
  758. LONG lRes = 0;
  759. HRESULT hr = E_FAIL; // did not find the object
  760. for(CNTOBJ::iterator i = m_cntObj.begin(); i!= m_cntObj.end(); i++){
  761. CHostedObject* pObj = (*i);
  762. if(NULL == pObj){
  763. continue;
  764. }/* end of if statement */
  765. HWND hwndCtrl = NULL;
  766. hr = pObj->GetWindow(&hwndCtrl);
  767. if(FAILED(hr)){
  768. continue;
  769. }/* end of if statement */
  770. if(hwndCtrl == (HWND) wParam){
  771. SetClosestFocus(lRes, pObj);
  772. //SetObjectFocus(pObj, TRUE, lRes);
  773. return(lRes);
  774. }/* end of if statement */
  775. }/* end of for loop */
  776. return lRes;
  777. }/* end of function OnUserFocus */
  778. /*************************************************************************/
  779. /* Function: OnKillFocus */
  780. /* Description: Sends the kill focus message to the control that has */
  781. /* Itterates through the container and removes the focus */
  782. /* from the contained objects. */
  783. /*************************************************************************/
  784. LRESULT CMFBar::OnKillFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled){
  785. bHandled = TRUE;
  786. LONG lRes = 0;
  787. if(m_cntObj.empty() == true){
  788. return 0;
  789. }/* end of if statement */
  790. bool bFirstElement = true;
  791. CNTOBJ::iterator i;
  792. for(i = m_cntObj.begin(); i!= m_cntObj.end(); i++){
  793. CHostedObject* pObj = (*i);
  794. if(pObj->HasFocus()){
  795. HRESULT hr = SetObjectFocus(pObj, FALSE, lRes);
  796. if(SUCCEEDED(hr)){
  797. return lRes;
  798. }/* end of if statement */
  799. }/* end of if statement */
  800. }/* end of for loop */
  801. //ResetFocusFlags(); // cleanup the focus flags
  802. return lRes;
  803. }/* end of function OnKillFocus */
  804. /*************************************************************************/
  805. /* Function: OnMouseMessage */
  806. /* Description: Handles the mouse messages, distrubutes to proper */
  807. /* controls if needed. */
  808. /*************************************************************************/
  809. LRESULT CMFBar::OnMouseMessage(UINT uMsg, WPARAM wParam, LPARAM lParam,
  810. BOOL& bHandled){
  811. LONG lRes = 0;
  812. bHandled = FALSE; // indicated if we dispatched the message
  813. if(m_lTimeout > 0){
  814. //WM_MOUSEMOVE messages keep comming over even if we really do not move the mouse
  815. bool bResetActivity = false;
  816. if(WM_MOUSEMOVE == uMsg){
  817. static WPARAM wParTmp = 0;
  818. static LPARAM lParTmp = 0;
  819. if(wParam != wParTmp || lParam != lParTmp){
  820. bResetActivity = true;
  821. }/* end of if statement */
  822. if(wParam & MK_CONTROL ||
  823. wParam & MK_CONTROL ||
  824. wParam & MK_LBUTTON ||
  825. wParam & MK_MBUTTON ||
  826. wParam & MK_RBUTTON ||
  827. wParam & MK_SHIFT ){
  828. bResetActivity = true;
  829. }/* end of if statement */
  830. lParTmp = lParam;
  831. wParTmp = wParam;
  832. }
  833. else {
  834. bResetActivity = true;
  835. }/* end of if statement */
  836. if(bResetActivity){
  837. m_fUserActivity = true;
  838. if(m_fWaitingForActivity){
  839. Fire_ActivityStarted();
  840. m_fWaitingForActivity = false;
  841. }/* end of if statement */
  842. }/* end of if statement */
  843. }/* end of if statement */
  844. ATLTRACE2(atlTraceWindowing, 32, TEXT("R WM_ button message : "));
  845. if(!m_bMouseDown){
  846. CHostedObject* pMouseCaptureObj = NULL;
  847. // send the message to the control(s) that have the capture
  848. if(false == m_fHandleHelp && GetCapture() == S_OK){
  849. for(CNTOBJ::iterator i = m_cntObj.begin(); i!= m_cntObj.end(); i++){
  850. // iterate through all the contained controls
  851. CHostedObject* pObj = (*i);
  852. if(NULL == pObj){
  853. ATLASSERT(FALSE); // should not be null
  854. continue;
  855. }/* end of if statement */
  856. // need to be able send message to the button with the capture
  857. if(pObj->HasCapture()){
  858. ATLTRACE2(atlTraceUser, 31, TEXT("Sending WM_ buttons message to button %ls \n"), pObj->GetID());
  859. HRESULT hr = SendMessageToCtl(pObj, uMsg, wParam, lParam, bHandled, lRes);
  860. if(SUCCEEDED(hr)){
  861. if (WM_LBUTTONDOWN == uMsg) {
  862. CComPtr<IViewObjectEx> pViewObject;
  863. HRESULT hr = pObj->GetViewObject(&pViewObject);
  864. if(FAILED(hr)){
  865. ATLASSERT(FALSE); // should have a view
  866. continue;
  867. }/* end of if statement */
  868. DWORD dwHitResult = HITRESULT_OUTSIDE;
  869. POINT ptMouse = { LOWORD(lParam), HIWORD(lParam) };
  870. RECT rcCntrl;
  871. pObj->GetPos(&rcCntrl);
  872. pViewObject->QueryHitPoint(DVASPECT_CONTENT, &rcCntrl, ptMouse, 0, &dwHitResult);
  873. if(HITRESULT_HIT == dwHitResult){
  874. if (WM_LBUTTONDOWN == uMsg) {
  875. LONG lRes;
  876. //SetObjectFocus(pObj, TRUE, lRes);
  877. SetClosestFocus(lRes, pObj);
  878. }/* end of if statement */
  879. }/* end of if statement */
  880. }/* end of if statement */
  881. pMouseCaptureObj = pObj;
  882. break; // send mouse message to only the one control that has capture
  883. // then to the ones we hower over
  884. }/* end of if statement */
  885. }/* end of if statement */
  886. }/* end of for loop */
  887. }/* end of if statement */
  888. // send the message to the control(s) that we are over, but not to the one
  889. // that which had focus and we already send one
  890. for(CNTOBJ::iterator i = m_cntObj.begin(); i!= m_cntObj.end(); i++){
  891. // iterate through all the contained controls
  892. CHostedObject* pObj = (*i);
  893. if(NULL == pObj){
  894. ATLASSERT(FALSE); // should not be null
  895. continue;
  896. }/* end of if statement */
  897. // need to be able send message to the button with the capture
  898. // send the message to the control over which we are howering or on which we
  899. // have clicked, check if we already are ready to send the message
  900. // in that case do not bother with the rect interstec bussines
  901. if(!bHandled && pObj->IsWindowless() && pObj->IsActive()){
  902. CComPtr<IViewObjectEx> pViewObject;
  903. HRESULT hr = pObj->GetViewObject(&pViewObject);
  904. if(FAILED(hr)){
  905. ATLASSERT(FALSE); // should have a view
  906. continue;
  907. }/* end of if statement */
  908. DWORD dwHitResult = HITRESULT_OUTSIDE;
  909. POINT ptMouse = { LOWORD(lParam), HIWORD(lParam) };
  910. RECT rcCntrl;
  911. pObj->GetPos(&rcCntrl);
  912. pViewObject->QueryHitPoint(DVASPECT_CONTENT, &rcCntrl, ptMouse, 0, &dwHitResult);
  913. if(HITRESULT_HIT == dwHitResult){
  914. // see if we are handling help, if so do not do anything else, but
  915. // fire help with the control ID we are howering over
  916. if(m_fHandleHelp){
  917. if (WM_LBUTTONUP == uMsg) {
  918. Fire_OnHelp(::SysAllocString(pObj->GetID()));
  919. m_fHandleHelp = false;
  920. }/* end of if statement */
  921. bHandled = TRUE;
  922. return(lRes);
  923. }
  924. else {
  925. if(pMouseCaptureObj == pObj){
  926. continue; // we already have send message to this control
  927. // do not do it again
  928. }/* end of if statememt */
  929. ATLTRACE2(atlTraceUser, 31, TEXT("Sending WM_ buttons message to button %ls \n"), pObj->GetID());
  930. SendMessageToCtl(pObj, uMsg, wParam, lParam, bHandled, lRes);
  931. if (WM_LBUTTONDOWN == uMsg) {
  932. LONG lRes;
  933. //SetObjectFocus(pObj, TRUE, lRes);
  934. SetClosestFocus(lRes, pObj);
  935. }/* end of if statement */
  936. }/* end of if statement */
  937. }/* end of if statement */
  938. }/* end of if statement */
  939. }/* end of for loop */
  940. }/* end of if statement */
  941. if(TRUE == bHandled){
  942. // we send some messages to a control, so there is no need to handle container now
  943. return(lRes);
  944. }/* end of if statement */
  945. // we are not over any control so we might be over container itself, so handle
  946. // the mouse message appropriately
  947. ATLTRACE2(atlTraceWindowing, 32, TEXT("Not forwarding the message to the controls\n"));
  948. if(WM_LBUTTONUP == uMsg || WM_LBUTTONDBLCLK == uMsg){
  949. // TODO: Fire the click only if we are on our window or bitmap
  950. if(m_fHandleHelp){
  951. BSTR strToolbarName;
  952. if(SUCCEEDED(GetToolbarName(&strToolbarName))){
  953. Fire_OnHelp(strToolbarName);
  954. }/* end of if statement */
  955. m_fHandleHelp = false;
  956. }
  957. else {
  958. if(WM_LBUTTONUP == uMsg){
  959. Fire_OnClick();
  960. }
  961. else {
  962. Fire_OnDblClick();
  963. }/* end of if statement */
  964. }/* end of if statement */
  965. }/* end of if statement */
  966. // handle the moving of the container window
  967. if(m_fSelfHosted && !m_fHandleHelp){
  968. if(WM_LBUTTONDOWN == uMsg){
  969. OnButtonDown(uMsg, wParam, lParam, bHandled);
  970. }/* end of if statement */
  971. if(WM_MOUSEMOVE == uMsg){
  972. OnMouseMove(uMsg, wParam, lParam, bHandled);
  973. }/* end of if statement */
  974. if(WM_LBUTTONUP == uMsg){
  975. OnButtonUp(uMsg, wParam, lParam, bHandled);
  976. }/* end of if statement */
  977. }/* end of if statement */
  978. return(lRes);
  979. }/* end of function OnMouseMessage */
  980. /*************************************************************************/
  981. /* Function: OnKeyMessage */
  982. /* Description: Distrubutes the keyboard messages properly. */
  983. /*************************************************************************/
  984. LRESULT CMFBar::OnKeyMessage(UINT uMsg, WPARAM wParam, LPARAM lParam,
  985. BOOL& bHandled){
  986. m_fUserActivity = true;
  987. if(m_fWaitingForActivity){
  988. Fire_ActivityStarted();
  989. m_fWaitingForActivity = false;
  990. }/* end of if statement */
  991. bHandled = FALSE;
  992. LONG lRes = 0;
  993. VARIANT_BOOL fEat = VARIANT_FALSE;
  994. LONG lEnable = 1; // using long since the framework will not handle short
  995. LONG lVirtKey = (LONG)wParam;
  996. LONG lKeyData = (LONG) lParam;
  997. m_fForceKey = false; // reset the flag, the change in the value would indicate
  998. // that we have received call to force key during the event
  999. // processing
  1000. if(WM_KEYDOWN == uMsg){
  1001. Fire_OnKeyUp(lVirtKey, lKeyData);
  1002. }/* end of if statement */
  1003. if(WM_KEYUP == uMsg){
  1004. Fire_OnKeyDown(lVirtKey, lKeyData);
  1005. }/* end of if statement */
  1006. if(WM_SYSKEYDOWN == uMsg){
  1007. Fire_OnSysKeyUp(lVirtKey, lKeyData);
  1008. }/* end of if statement */
  1009. if(WM_SYSKEYUP == uMsg){
  1010. Fire_OnSysKeyDown(lVirtKey, lKeyData);
  1011. }/* end of if statement */
  1012. if(m_fForceKey){
  1013. fEat = m_fEat;
  1014. lVirtKey = m_lVirtKey;
  1015. lKeyData = m_lKeyData;
  1016. }/* end of if statement */
  1017. if(VARIANT_FALSE == fEat){
  1018. if(WM_KEYUP == uMsg ){
  1019. switch(lVirtKey){
  1020. case VK_TAB:
  1021. bool fForward = true;
  1022. if(::GetKeyState(VK_SHIFT) < 0){
  1023. fForward = false;
  1024. }/* end of if statement */
  1025. MoveFocus(fForward, lRes);
  1026. return(lRes);
  1027. }/* end of switch statement */
  1028. }/* end of if statement */
  1029. // iterates through the controls and send these key messages to the one
  1030. // with focus
  1031. CNTOBJ::iterator i;
  1032. for(i = m_cntObj.begin(); i!= m_cntObj.end(); i++){
  1033. // iterate through all the contained controls
  1034. CHostedObject* pObj = (*i);
  1035. if(NULL == pObj){
  1036. ATLASSERT(FALSE);
  1037. continue;
  1038. }/* end of if statement */
  1039. if(pObj->HasFocus()){
  1040. HRESULT hr = SendMessageToCtl(pObj, uMsg, lVirtKey, lKeyData, bHandled, lRes, false);
  1041. if(SUCCEEDED(hr)){
  1042. return(lRes);
  1043. }/* end of if statement */
  1044. }/* end of if statement */
  1045. }/* end of for loop */
  1046. }/* end of if statement */
  1047. return(lRes);
  1048. }/* end of function OnKeyMessage */
  1049. /*************************************************************************/
  1050. /* Function: AdvanceIterator */
  1051. /* Description: Helper inline function that helps to keep track which */
  1052. /* direction we are advancing. */
  1053. /*************************************************************************/
  1054. void AdvanceIterator(CNTOBJ::iterator& i, bool fForward){
  1055. if(fForward){
  1056. i++;
  1057. }
  1058. else {
  1059. i--;
  1060. }/* end of if statement */
  1061. }/* end of function AdvanceIterator */
  1062. /*************************************************************************/
  1063. /* Function: MoveFocus */
  1064. /* Descrition: Moves focus through the objects in forward or reverse */
  1065. /* direction. */
  1066. /*************************************************************************/
  1067. HRESULT CMFBar::MoveFocus(bool fForward, LONG& lRes){
  1068. HRESULT hr = S_OK;
  1069. // first remove the focus and remeber the object
  1070. CHostedObject* pLastFocusObject = NULL;
  1071. CNTOBJ::iterator i, iEnd;
  1072. if(fForward){
  1073. i = m_cntFocus.begin();
  1074. iEnd = m_cntFocus.end();
  1075. }
  1076. else {
  1077. i = m_cntFocus.end();
  1078. i--;
  1079. iEnd = m_cntFocus.begin();
  1080. }/* end of if statement */
  1081. for( ;i!= iEnd; AdvanceIterator(i, fForward)){
  1082. // iterate through all the contained controls
  1083. CHostedObject* pObj = (*i);
  1084. if(NULL == pObj){
  1085. ATLASSERT(FALSE);
  1086. continue;
  1087. }/* end of if statement */
  1088. if(pObj->HasFocus()){
  1089. LONG lRes;
  1090. SetObjectFocus(pObj, FALSE, lRes);
  1091. pLastFocusObject = pObj;
  1092. continue; // get to the next object
  1093. }/* end of if statement */
  1094. // try to set the focus to the next object
  1095. if(NULL != pLastFocusObject){
  1096. if(pObj->IsActive()){
  1097. LONG lRes = 0;
  1098. HRESULT hr = SetObjectFocus(pObj, TRUE, lRes);
  1099. if(FAILED(hr)){
  1100. continue; // this is the container so skip it
  1101. }/* end of if statement */
  1102. if(-1 == lRes){
  1103. // did not want to handle focus, since the button is disabled
  1104. SetObjectFocus(pObj, FALSE, lRes);
  1105. continue;
  1106. }/* end of if statement */
  1107. return(hr);
  1108. }/* end of if statement */
  1109. }/* end of if statement */
  1110. }/* end of for loop */
  1111. // OK lets try to set focus to somebody before
  1112. //CNTOBJ::iterator i;
  1113. if(fForward){
  1114. i = m_cntFocus.begin();
  1115. iEnd = m_cntFocus.end();
  1116. }
  1117. else {
  1118. i = m_cntFocus.end();
  1119. i--;
  1120. iEnd = m_cntFocus.begin();
  1121. }/* end of if statement */
  1122. for( ;i!= iEnd; AdvanceIterator(i, fForward)){
  1123. // iterate through all the contained controls
  1124. CHostedObject* pObj = (*i);
  1125. if(NULL == pObj){
  1126. ATLASSERT(FALSE);
  1127. continue;
  1128. }/* end of if statement */
  1129. if(pObj->IsActive()){
  1130. LONG lRes = 0;
  1131. HRESULT hr = SetObjectFocus(pObj, TRUE, lRes);
  1132. if(FAILED(hr)){
  1133. continue; // this is the container so skip it
  1134. }/* end of if statement */
  1135. if(-1 == lRes){
  1136. // did not want to handle focus, since the button is disabled
  1137. SetObjectFocus(pObj, FALSE, lRes);
  1138. continue;
  1139. }/* end of if statement */
  1140. return(hr);
  1141. }/* end of if statement */
  1142. }/* end of for loop */
  1143. //ATLASSERT(FALSE); // should not really hapen, to have all the objects disabled
  1144. return(hr);
  1145. }/* end of function MoveFocus */
  1146. /*************************************************************************/
  1147. /* Function: SetClosestFocus */
  1148. /* Descrition: Sets the focus to the closes object to pObj if specified. */
  1149. /*************************************************************************/
  1150. HRESULT CMFBar::SetClosestFocus(LONG& lRes, CHostedObject* pStartObj, bool fForward){
  1151. HRESULT hr = S_OK;
  1152. if(m_cntFocus.empty()){
  1153. hr = S_FALSE;
  1154. return(hr);
  1155. }/* end of if statement */
  1156. ResetFocusFlags();
  1157. // first remove the focus and remeber the object
  1158. bool fStartSettingFocus = false;
  1159. CNTOBJ::iterator i, iEnd;
  1160. if(fForward){
  1161. i = m_cntFocus.begin();
  1162. iEnd = m_cntFocus.end();
  1163. }
  1164. else {
  1165. i = m_cntFocus.end();
  1166. i--;
  1167. iEnd = m_cntFocus.begin();
  1168. }/* end of if statement */
  1169. if(NULL == pStartObj){
  1170. pStartObj = (*i); // initialize our start object
  1171. }/* end of if statement */
  1172. for( ;i!= iEnd; AdvanceIterator(i, fForward)){
  1173. // iterate through all the contained controls
  1174. CHostedObject* pObj = (*i);
  1175. if(NULL == pObj){
  1176. ATLASSERT(FALSE);
  1177. continue;
  1178. }/* end of if statement */
  1179. if(pObj == pStartObj){
  1180. fStartSettingFocus = true;
  1181. }/* end of if statement */
  1182. // try to set the focus to the next object
  1183. if(fStartSettingFocus ){
  1184. if(pObj->IsActive()){
  1185. LONG lRes = 0;
  1186. HRESULT hr = SetObjectFocus(pObj, TRUE, lRes);
  1187. if(FAILED(hr)){
  1188. continue; // this is the container so skip it
  1189. }/* end of if statement */
  1190. if(-1 == lRes){
  1191. // did not want to handle focus, since the button is disabled
  1192. SetObjectFocus(pObj, FALSE, lRes);
  1193. continue;
  1194. }/* end of if statement */
  1195. return(hr);
  1196. }/* end of if statement */
  1197. }/* end of if statement */
  1198. }/* end of for loop */
  1199. if(!fStartSettingFocus){
  1200. hr = S_FALSE;
  1201. return(hr);
  1202. }/* end of if statement */
  1203. // OK lets try to set focus to somebody before
  1204. //CNTOBJ::iterator i;
  1205. if(fForward){
  1206. i = m_cntFocus.begin();
  1207. iEnd = m_cntFocus.end();
  1208. }
  1209. else {
  1210. i = m_cntFocus.end();
  1211. i--;
  1212. iEnd = m_cntFocus.begin();
  1213. }/* end of if statement */
  1214. for( ;i!= iEnd; AdvanceIterator(i, fForward)){
  1215. // iterate through all the contained controls
  1216. CHostedObject* pObj = (*i);
  1217. if(NULL == pObj){
  1218. ATLASSERT(FALSE);
  1219. continue;
  1220. }/* end of if statement */
  1221. if(pObj->IsActive()){
  1222. LONG lRes = 0;
  1223. HRESULT hr = SetObjectFocus(pObj, TRUE, lRes);
  1224. if(FAILED(hr)){
  1225. continue; // this is the container so skip it
  1226. }/* end of if statement */
  1227. if(-1 == lRes){
  1228. // did not want to handle focus, since the button is disabled
  1229. SetObjectFocus(pObj, FALSE, lRes);
  1230. continue;
  1231. }/* end of if statement */
  1232. return(hr);
  1233. }/* end of if statement */
  1234. }/* end of for loop */
  1235. ATLASSERT(FALSE); // should not really hapen, to have all the objects disabled
  1236. return(hr);
  1237. }/* end of function SetClosestFocus */
  1238. /*************************************************************************/
  1239. /* Function: OnForwardMsg */
  1240. /* Description: Forwards the message to the active object. */
  1241. /*************************************************************************/
  1242. LRESULT CMFBar::OnForwardMsg(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/){
  1243. ATLTRACE2(atlTraceHosting, 2, TEXT("CMFBar::OnForwardMsg\n"));
  1244. ATLASSERT(lParam != 0);
  1245. LPMSG lpMsg = (LPMSG)lParam;
  1246. if(m_spActiveObject){
  1247. if(m_spActiveObject->TranslateAccelerator(lpMsg) == S_OK)
  1248. return 1;
  1249. }/* end of function OnForwardMessage */
  1250. return 0;
  1251. }/* end of function OnForwardMessage */
  1252. /*************************************************************************/
  1253. /* Function: ReflectNotifications */
  1254. /* Description: Reflects the messages to the child windows */
  1255. /*************************************************************************/
  1256. LRESULT CMFBar::ReflectNotifications(UINT uMsg, WPARAM wParam, LPARAM lParam,
  1257. BOOL& bHandled){
  1258. HWND hWndChild = NULL;
  1259. switch(uMsg){
  1260. case WM_COMMAND:
  1261. if(lParam != NULL) // not from a menu
  1262. hWndChild = (HWND)lParam;
  1263. break;
  1264. case WM_NOTIFY:
  1265. hWndChild = ((LPNMHDR)lParam)->hwndFrom;
  1266. break;
  1267. case WM_PARENTNOTIFY:
  1268. switch(LOWORD(wParam))
  1269. {
  1270. case WM_CREATE:
  1271. case WM_DESTROY:
  1272. hWndChild = (HWND)lParam;
  1273. break;
  1274. default:
  1275. hWndChild = GetDlgItem(HIWORD(wParam));
  1276. break;
  1277. }
  1278. break;
  1279. case WM_DRAWITEM:
  1280. if(wParam) // not from a menu
  1281. hWndChild = ((LPDRAWITEMSTRUCT)lParam)->hwndItem;
  1282. break;
  1283. case WM_MEASUREITEM:
  1284. if(wParam) // not from a menu
  1285. hWndChild = GetDlgItem(((LPMEASUREITEMSTRUCT)lParam)->CtlID);
  1286. break;
  1287. case WM_COMPAREITEM:
  1288. if(wParam) // not from a menu
  1289. hWndChild = GetDlgItem(((LPCOMPAREITEMSTRUCT)lParam)->CtlID);
  1290. break;
  1291. case WM_DELETEITEM:
  1292. if(wParam) // not from a menu
  1293. hWndChild = GetDlgItem(((LPDELETEITEMSTRUCT)lParam)->CtlID);
  1294. break;
  1295. case WM_VKEYTOITEM:
  1296. case WM_CHARTOITEM:
  1297. case WM_HSCROLL:
  1298. case WM_VSCROLL:
  1299. hWndChild = (HWND)lParam;
  1300. break;
  1301. case WM_CTLCOLORBTN:
  1302. case WM_CTLCOLORDLG:
  1303. case WM_CTLCOLOREDIT:
  1304. case WM_CTLCOLORLISTBOX:
  1305. case WM_CTLCOLORMSGBOX:
  1306. case WM_CTLCOLORSCROLLBAR:
  1307. case WM_CTLCOLORSTATIC:
  1308. hWndChild = (HWND)lParam;
  1309. break;
  1310. default:
  1311. break;
  1312. }/* end of switch statement */
  1313. if(hWndChild == NULL){
  1314. bHandled = FALSE;
  1315. return 1;
  1316. }/* end of if statememnt */
  1317. ATLASSERT(::IsWindow(hWndChild));
  1318. return ::SendMessage(hWndChild, OCM__BASE + uMsg, wParam, lParam);
  1319. }/* end of function ReflectNotifications */
  1320. /*************************************************************************/
  1321. /* Function: put_Caption */
  1322. /* Description: Sets the caption to the window if present and handles */
  1323. /* the ambient property implementation. */
  1324. /*************************************************************************/
  1325. STDMETHODIMP CMFBar::put_Caption(BSTR bstrCaption){
  1326. ATLTRACE2(atlTraceControls,2,_T("CStockPropImpl::put_Caption\n"));
  1327. if (FireOnRequestEdit(DISPID_CAPTION) == S_FALSE){
  1328. return S_FALSE;
  1329. }/* end of if statement */
  1330. m_bstrCaption.Empty();
  1331. m_bstrCaption.Attach(::SysAllocString(bstrCaption));
  1332. m_bRequiresSave = TRUE;
  1333. FireOnChanged(DISPID_CAPTION);
  1334. FireViewChange();
  1335. SendOnDataChange(NULL);
  1336. if(::IsWindow(m_hWnd)){
  1337. #ifdef _UNICODE
  1338. ::SetWindowText(m_hWnd, bstrCaption);
  1339. #else
  1340. USES_CONVERSION;
  1341. ::SetWindowText(m_hWnd, OLE2T(bstrCaption));
  1342. #endif
  1343. }/* end of if statement */
  1344. return S_OK;
  1345. }/* end of function put_Caption */
  1346. // ##### BEGIN ACTIVEX SCRIPTING SUPPORT #####
  1347. /*************************************************************************/
  1348. /* IActiveScriptSite Interface Implementation */
  1349. /*************************************************************************/
  1350. /*************************************************************************/
  1351. /* Function: get_CmdLine */
  1352. /*************************************************************************/
  1353. STDMETHODIMP CMFBar::get_CmdLine(BSTR *pVal){
  1354. if(NULL == pVal){
  1355. return(E_POINTER);
  1356. }/* end of if statement */
  1357. *pVal = m_strCmdLine.Copy();
  1358. return S_OK;
  1359. }/* end of function get_CmdLine */
  1360. /*************************************************************************/
  1361. /* Function: put_CmdLine */
  1362. /*************************************************************************/
  1363. STDMETHODIMP CMFBar::put_CmdLine(BSTR newVal){
  1364. m_strCmdLine = newVal;
  1365. return S_OK;
  1366. }/* end of function put_CmdLine */
  1367. /*************************************************************************/
  1368. /* Function: GetUserLCID */
  1369. /* Description: Gets the user default LCID */
  1370. /*************************************************************************/
  1371. STDMETHODIMP CMFBar::GetUserLCID(long *plcid){
  1372. *plcid = ::GetUserDefaultLCID();
  1373. return (S_OK);
  1374. }/* end of function GetUserLCID */
  1375. /*************************************************************************/
  1376. /* Function: GetLCID */
  1377. /* Description: Gets the user default LCID */
  1378. /*************************************************************************/
  1379. STDMETHODIMP CMFBar::GetLCID(LCID *plcid){
  1380. *plcid = ::GetUserDefaultLCID();
  1381. return (S_OK);
  1382. }/* end of function GetLCID */
  1383. /*************************************************************************/
  1384. /* Function: GetItemInfo */
  1385. /* Description: Returns IUnknown or TypeInfo of the contained (embedded) */
  1386. /* objects in the active script, in this case we return also a container,*/
  1387. /* since we can script it as well (but the script container is inserted */
  1388. /* in the list as well, so no special case for it. */
  1389. /* TODO: Might want to optimize and use hash table for faster compares. */
  1390. /* on the other hand it seems like a script engine calls this just once */
  1391. /* for an object an then reuses its internal reference. */
  1392. /*************************************************************************/
  1393. STDMETHODIMP CMFBar::GetItemInfo(LPCOLESTR strObjectID, DWORD dwReturnMask,
  1394. IUnknown** ppunkItemOut, ITypeInfo** pptinfoOut){
  1395. HRESULT hr = S_OK;
  1396. if (dwReturnMask & SCRIPTINFO_ITYPEINFO){
  1397. if (!pptinfoOut){
  1398. return E_INVALIDARG;
  1399. }/* end of if statement */
  1400. *pptinfoOut = NULL;
  1401. }/* end of if statement */
  1402. if (dwReturnMask & SCRIPTINFO_IUNKNOWN){
  1403. if (!ppunkItemOut){
  1404. return E_INVALIDARG;
  1405. }/* end of if statement */
  1406. *ppunkItemOut = NULL;
  1407. }/* end of if statement */
  1408. CHostedObject* pObj;
  1409. if(SUCCEEDED(FindObject(const_cast<BSTR>(strObjectID), &pObj))){
  1410. if (dwReturnMask & SCRIPTINFO_ITYPEINFO){
  1411. hr = pObj->GetTypeInfo(0, ::GetUserDefaultLCID(), pptinfoOut);
  1412. if(FAILED(hr)){
  1413. return(hr);
  1414. }/* end of if statement */
  1415. }/* end of if statement */
  1416. if (dwReturnMask & SCRIPTINFO_IUNKNOWN){
  1417. *ppunkItemOut = pObj->GetUnknown(); // does AddRef under the hood
  1418. }/* end of if statement */
  1419. return(hr); // found out item no need to dig around longer
  1420. }/* end of for loop */
  1421. return TYPE_E_ELEMENTNOTFOUND;
  1422. }/* end of function GetItemInfo */
  1423. /*************************************************************************/
  1424. /* Function: GetDocVersionString */
  1425. /*************************************************************************/
  1426. STDMETHODIMP CMFBar::GetDocVersionString(BSTR *pbstrVersion ){
  1427. return (E_NOTIMPL);
  1428. }/* end of function GetDocVersionString */
  1429. /*************************************************************************/
  1430. /* Function: OnScriptTerminate */
  1431. /*************************************************************************/
  1432. STDMETHODIMP CMFBar::OnScriptTerminate(const VARIANT *pvarResult,
  1433. const EXCEPINFO *pexcepinfo){
  1434. return (E_NOTIMPL);
  1435. }/* end of function OnScriptTerminate */
  1436. /*************************************************************************/
  1437. /* Function: OnStateChange */
  1438. /*************************************************************************/
  1439. STDMETHODIMP CMFBar::OnStateChange(SCRIPTSTATE ssScriptState){
  1440. return (E_NOTIMPL);
  1441. }/* end of function OnStateChange */
  1442. /*************************************************************************/
  1443. /* Function: OnScriptError */
  1444. /* Description: Display the script error in debug mode, skip it in */
  1445. /* release mode for now. */
  1446. /*************************************************************************/
  1447. STDMETHODIMP CMFBar::OnScriptError(IActiveScriptError *pse){
  1448. HRESULT hr = S_OK;
  1449. #ifdef _DEBUG
  1450. WCHAR szError[1024];
  1451. EXCEPINFO ei;
  1452. DWORD dwSrcContext;
  1453. ULONG ulLine;
  1454. LONG ichError;
  1455. BSTR bstrLine = NULL;
  1456. hr = pse->GetExceptionInfo(&ei);
  1457. if(FAILED(hr)){
  1458. return(hr);
  1459. }/* end of if statement */
  1460. hr = pse->GetSourcePosition(&dwSrcContext, &ulLine, &ichError);
  1461. if(FAILED(hr)){
  1462. return(hr);
  1463. }/* end of if statement */
  1464. hr = pse->GetSourceLineText(&bstrLine);
  1465. if (hr){
  1466. hr = S_OK; // Ignore this error, there may not be source available
  1467. }/* end of if statement */
  1468. if (!hr){
  1469. wsprintfW(szError, L"Source:'%s'\n Line:%d Description:%s\n",
  1470. ei.bstrSource, ulLine, ei.bstrDescription);
  1471. #ifdef _DEBUG
  1472. USES_CONVERSION;
  1473. ATLTRACE(W2T(szError));
  1474. ::MessageBeep((UINT)-1);
  1475. ::MessageBoxW(::GetFocus(), szError, L"Error", MB_OK);
  1476. #endif
  1477. // TODO: Add real error handling for released version
  1478. }/* end of if statment */
  1479. if (bstrLine){
  1480. ::SysFreeString(bstrLine);
  1481. }/* end of if statement */
  1482. #endif
  1483. return hr;
  1484. }/* end of function OnScriptError */
  1485. //---------------------------------------------------------------------------
  1486. //
  1487. //---------------------------------------------------------------------------
  1488. STDMETHODIMP CMFBar::OnEnterScript
  1489. (
  1490. void
  1491. )
  1492. {
  1493. // No need to do anything
  1494. return S_OK;
  1495. }
  1496. //---------------------------------------------------------------------------
  1497. //
  1498. //---------------------------------------------------------------------------
  1499. STDMETHODIMP CMFBar::OnLeaveScript
  1500. (
  1501. void
  1502. )
  1503. {
  1504. // No need to do anything
  1505. return S_OK;
  1506. }
  1507. // ##### END ACTIVEX SCRIPTING SUPPORT #####
  1508. /*************************************************************************/
  1509. /* Function: About */
  1510. /* Description: Displayes about box. */
  1511. /*************************************************************************/
  1512. STDMETHODIMP CMFBar::About(){
  1513. HRESULT hr = S_OK;
  1514. const INT ciMaxBuffSize = MAX_PATH; // enough for the text
  1515. TCHAR strBuffer[ciMaxBuffSize];
  1516. TCHAR strBufferAbout[ciMaxBuffSize];
  1517. if(!::LoadString(m_hRes, IDS_BAR_ABOUT, strBuffer, ciMaxBuffSize)){
  1518. hr = E_UNEXPECTED;
  1519. return(hr);
  1520. }/* end of if statement */
  1521. if(!::LoadString(m_hRes, IDS_ABOUT, strBufferAbout, ciMaxBuffSize)){
  1522. hr = E_UNEXPECTED;
  1523. return(hr);
  1524. }/* end of if statement */
  1525. ::MessageBox(::GetFocus(), strBuffer, strBufferAbout, MB_OK);
  1526. return (hr);
  1527. }/* end of function About */
  1528. /*************************************************************************/
  1529. /* Function: GetObjectUnknown */
  1530. /* Description: Iterates throught the object collection, finds the */
  1531. /* object that has the specific ID then returns it IUnknown. */
  1532. /*************************************************************************/
  1533. STDMETHODIMP CMFBar::GetObjectUnknown(BSTR strObjectID, IUnknown **ppUnk){
  1534. HRESULT hr = E_FAIL;
  1535. if(NULL == strObjectID){
  1536. return E_POINTER;
  1537. }/* end of if statement */
  1538. if(NULL == ppUnk){
  1539. return E_POINTER;
  1540. }/* end of if statement */
  1541. *ppUnk = NULL;
  1542. CHostedObject* pObj;
  1543. hr = FindObject(strObjectID, &pObj);
  1544. if(FAILED(hr)){
  1545. return(hr);
  1546. }/* end of if statement */
  1547. *ppUnk = pObj->GetUnknown();
  1548. hr = S_OK;
  1549. if(*ppUnk == NULL){
  1550. hr = E_UNEXPECTED;
  1551. return(hr);
  1552. }/* end of if statement */
  1553. (*ppUnk)->AddRef(); // adds the reference, since we are giving out
  1554. return (hr);
  1555. }/* end of function GetObjectUnknown */
  1556. /*************************************************************************/
  1557. /* Function: EnableObject */
  1558. /* Description: Goes trough the objects and enables or disables it */
  1559. /* depending on the flag. Invalidates the objects rect as well. */
  1560. /*************************************************************************/
  1561. STDMETHODIMP CMFBar::EnableObject(BSTR strObjectID, VARIANT_BOOL fEnable){
  1562. HRESULT hr = E_FAIL;
  1563. if(NULL == strObjectID){
  1564. return E_POINTER;
  1565. }/* end of if sattement */
  1566. CHostedObject* pObj;
  1567. hr = FindObject(strObjectID, &pObj);
  1568. if(FAILED(hr)){
  1569. return(hr);
  1570. }/* end of if statement */
  1571. bool fTmpEnable = VARIANT_FALSE == fEnable ? false: true;
  1572. CContainerObject* pCnt;
  1573. hr = pObj->GetContainerObject(&pCnt);
  1574. if(FAILED(hr)){
  1575. if(pObj->GetUnknown() == GetUnknown()){
  1576. // special case when we are invalidating our self/ the self hosted container
  1577. if(fTmpEnable){
  1578. InvalidateRect(NULL, false);
  1579. }/* end of if statement */
  1580. pObj->SetActive(fTmpEnable);
  1581. hr = S_OK;
  1582. return(hr);
  1583. }/* end of if statement */
  1584. }/* end of if statemenet */
  1585. if (pObj->IsActive() == fTmpEnable)
  1586. return S_OK;
  1587. pObj->SetActive(fTmpEnable);
  1588. if(false == fTmpEnable){
  1589. LONG lRes = 0;
  1590. SetClosestFocus(lRes);
  1591. //MoveFocus(true, lRes);
  1592. //SetObjectFocus(pObj, FALSE, lRes);
  1593. if(pObj->HasCapture()){
  1594. pCnt->SetCapture(FALSE);
  1595. }/* end of if statement */
  1596. }/* end of if statement */
  1597. // invalidate area where the object lives
  1598. if(pObj->IsWindowless()){
  1599. // invalidate the rect only if we are windowless control
  1600. // the windowed control shopuld be able
  1601. // to update itself depending on the SW_SHOW, HIDE messagess
  1602. hr = pCnt->InvalidateObjectRect();
  1603. }/* end of if statement */
  1604. return (hr);
  1605. }/* end of function EnableObject */
  1606. /*************************************************************************/
  1607. /* Function: ObjectEnabled */
  1608. /* Description: Goes trough the objects and checks if the particular */
  1609. /* object is enabled or disabled. */
  1610. /*************************************************************************/
  1611. STDMETHODIMP CMFBar::ObjectEnabled(BSTR strObjectID, VARIANT_BOOL *pfEnabled){
  1612. HRESULT hr = E_FAIL;
  1613. if(NULL == pfEnabled){
  1614. hr = E_POINTER;
  1615. return(hr);
  1616. }/* end of if statement */
  1617. if(NULL == strObjectID){
  1618. hr = E_POINTER;
  1619. return(hr);
  1620. }/* end of if sattement */
  1621. bool bFirstElement = true;
  1622. CNTOBJ::iterator i;
  1623. for(i = m_cntObj.begin(); i!= m_cntObj.end(); i++){
  1624. if(!_wcsicmp((*i)->GetID(), strObjectID)){
  1625. CHostedObject* pObj = (*i);
  1626. *pfEnabled = pObj->IsActive()? VARIANT_TRUE : VARIANT_FALSE;
  1627. hr = S_OK; // might have to turn it on
  1628. return(hr); // already have set the state and invalidated and bail out
  1629. }/* end of if statement */
  1630. }/* end of for loop */
  1631. return (hr);
  1632. }/* end of function ObjectEnabled */
  1633. /*************************************************************************/
  1634. /* Function: ForceKey */
  1635. /* Description: Forces the in the eventa handling code. */
  1636. /* The fEat disables or enables default key handler. */
  1637. /*************************************************************************/
  1638. STDMETHODIMP CMFBar::ForceKey(LONG lVirtKey, LONG lKeyData, VARIANT_BOOL fEat){
  1639. m_fForceKey = true; // set the flag for key handler routine
  1640. m_fEat = (fEat == VARIANT_FALSE ? VARIANT_FALSE : VARIANT_TRUE); // disable or enable this call
  1641. m_lVirtKey = lVirtKey; // put in data
  1642. m_lKeyData = lKeyData; // put in data
  1643. return S_OK;
  1644. }/* end of function ForceKey */
  1645. /*************************************************************************/
  1646. /* Function: get_ScriptLanguage */
  1647. /* Description: Gets current script language such as JScript, VBScript */
  1648. /*************************************************************************/
  1649. STDMETHODIMP CMFBar::get_ScriptLanguage(BSTR *pstrScriptLanguage){
  1650. if(NULL == pstrScriptLanguage){
  1651. return(E_POINTER);
  1652. }/* end of if statement */
  1653. *pstrScriptLanguage = m_strScriptLanguage.Copy();
  1654. return S_OK;
  1655. }/* end of function get_ScriptLanguage */
  1656. /*************************************************************************/
  1657. /* Function: put_ScriptLanguage */
  1658. /* Description: Gets current script language such as JScript, VBScript */
  1659. /*************************************************************************/
  1660. STDMETHODIMP CMFBar::put_ScriptLanguage(BSTR strScriptLanguage){
  1661. HRESULT hr = S_OK;
  1662. if (m_ps){
  1663. hr = E_FAIL; // Already created the script engine, so it
  1664. // will not take an effect untill we unload it
  1665. return(hr);
  1666. }/* end of if statement */
  1667. m_strScriptLanguage = strScriptLanguage;
  1668. return (hr);
  1669. }/* end of function put_ScriptLanguage */
  1670. /*************************************************************************/
  1671. /* Function: get_ScriptFile */
  1672. /* Description: Gets the current script file. */
  1673. /* By default we have empty string which means loading from Windows */
  1674. /* resources, which is not really a file. */
  1675. /*************************************************************************/
  1676. STDMETHODIMP CMFBar::get_ScriptFile(BSTR *pstrScriptFile){
  1677. if(NULL == pstrScriptFile){
  1678. return(E_POINTER);
  1679. }/* end of if statement */
  1680. *pstrScriptFile = m_strScriptFile.Copy();
  1681. return S_OK;
  1682. }/* end of function get_ScriptFile */
  1683. /*************************************************************************/
  1684. /* Function: put_ScriptFile */
  1685. /* Description: Sets the script file. Only valid before the load and */
  1686. /* unload. */
  1687. /*************************************************************************/
  1688. STDMETHODIMP CMFBar::put_ScriptFile(BSTR strScriptFile){
  1689. HRESULT hr = S_OK;
  1690. try {
  1691. if(VARIANT_TRUE == m_fAutoLoad){
  1692. hr = DestroyScriptEngine();
  1693. if(FAILED(hr)){
  1694. throw(hr);
  1695. }/* end of if statement */
  1696. m_strScriptFile = strScriptFile;
  1697. hr = Load();
  1698. if(FAILED(hr)){
  1699. throw(hr);
  1700. }/* end of if statement */
  1701. const INT ciMaxBuffSize = MAX_PATH; // enough for the text
  1702. TCHAR strBuffer[ciMaxBuffSize];
  1703. if(!::LoadString(m_hRes, IDS_MAIN_ENTRY, strBuffer, ciMaxBuffSize)){
  1704. hr = E_UNEXPECTED;
  1705. return(hr);
  1706. }/* end of if statement */
  1707. USES_CONVERSION;
  1708. hr = Run(T2OLE(strBuffer));
  1709. }
  1710. else {
  1711. // case when we are loading manually
  1712. if (m_ps){
  1713. hr = E_FAIL; // Already created the script engine, so it
  1714. // will not take an effect untill we unload it
  1715. throw(hr);
  1716. }/* end of if statement */
  1717. m_strScriptFile = strScriptFile;
  1718. }/* end of if statement */
  1719. }/* end of try statement */
  1720. catch(HRESULT hrTmp){
  1721. hr = hrTmp;
  1722. }
  1723. catch(...){
  1724. hr = E_UNEXPECTED;
  1725. }/* end of catch statement */
  1726. return (hr);
  1727. }/* end of function put_ScriptFile */
  1728. /*************************************************************************/
  1729. /* IActiveScriptSiteWindow Interface Implementation */
  1730. /*************************************************************************/
  1731. /*************************************************************************/
  1732. /* Function: GetWindow */
  1733. /* Description: Gets the window. If we are windowless we do not pass */
  1734. /* down the parent window, since that seems to confuse the control */
  1735. /*************************************************************************/
  1736. STDMETHODIMP CMFBar::GetWindow(HWND *phwndOut){
  1737. HRESULT hr = S_OK;
  1738. if (!phwndOut){
  1739. hr = E_INVALIDARG;
  1740. return (hr);
  1741. }/* end of if statement */
  1742. if(m_bWndLess){
  1743. if(!::IsWindow(m_hWnd)){
  1744. return(GetParentHWND(phwndOut));
  1745. }/* end of if statement */
  1746. }
  1747. else {
  1748. if(!::IsWindow(m_hWnd)){
  1749. *phwndOut = NULL;
  1750. hr = E_FAIL;
  1751. return(hr);
  1752. }/* end of if statement */
  1753. }/* end of if statement */
  1754. *phwndOut = m_hWnd;
  1755. return(hr);
  1756. }/* end of function GetWindow */
  1757. /*************************************************************************/
  1758. /* Function: EnableModeless */
  1759. /* Description: Sets the window from which the UI elemnt can come out */
  1760. /*************************************************************************/
  1761. STDMETHODIMP CMFBar::EnableModeless(BOOL fModeless){
  1762. HRESULT hr = S_OK;
  1763. if(m_hWnd == NULL){
  1764. hr = E_NOTIMPL;
  1765. return (hr);
  1766. }/* end of if statement */
  1767. ::EnableWindow(m_hWnd, fModeless);
  1768. return(hr);
  1769. }/* end of function EnableModeless */
  1770. /*************************************************************************/
  1771. /* Function: get_MinWidth */
  1772. /* Description: Gets the minimum width beyond which we do not resize. */
  1773. /*************************************************************************/
  1774. STDMETHODIMP CMFBar::get_MinWidth(long *pVal){
  1775. if(NULL == pVal){
  1776. return(E_POINTER);
  1777. }/* end of if statement */
  1778. *pVal = m_lMinWidth;
  1779. return S_OK;
  1780. }/* end of function get_MinWidth */
  1781. /*************************************************************************/
  1782. /* Function: put_MinWidth */
  1783. /* Description: Puts the minimum width beyond which we do not resize. */
  1784. /*************************************************************************/
  1785. STDMETHODIMP CMFBar::put_MinWidth(long newVal){
  1786. m_lMinWidth = newVal;
  1787. return S_OK;
  1788. }/* end of function put_MinWidth */
  1789. /*************************************************************************/
  1790. /* Function: get_MinWidth */
  1791. /* Description: Gets the minimum height beyond which we do not resize. */
  1792. /*************************************************************************/
  1793. STDMETHODIMP CMFBar::get_MinHeight(long *pVal){
  1794. if(NULL == pVal){
  1795. return(E_POINTER);
  1796. }/* end of if statement */
  1797. *pVal = m_lMinHeight;
  1798. return S_OK;
  1799. }/* end of function get_MinHeight */
  1800. /*************************************************************************/
  1801. /* Function: put_MinHeight */
  1802. /* Description: Sets the minimum height beyond which we do not resize. */
  1803. /*************************************************************************/
  1804. STDMETHODIMP CMFBar::put_MinHeight(long newVal){
  1805. m_lMinHeight = newVal;
  1806. return S_OK;
  1807. }/* end of function put_MinHeight */
  1808. // ##### BEGIN ACTIVEX SCRIPTING SUPPORT #####
  1809. /*************************************************************************/
  1810. /* Function: CreateScriptEngine */
  1811. /* Description: Initializes the script engine. */
  1812. /*************************************************************************/
  1813. HRESULT CMFBar::CreateScriptEngine(){
  1814. HRESULT hr = S_OK;
  1815. #ifndef _UNICODE
  1816. USES_CONVERSION;
  1817. #endif
  1818. if (m_ps){
  1819. hr = S_FALSE; // Already created the script engine
  1820. return(hr); // so get out
  1821. }/* end of if statement */
  1822. /*************************************************************************/
  1823. /* add (this) the container as a scriptable object as well */
  1824. /* this is special case so we can call script on our self as well */
  1825. /*************************************************************************/
  1826. const INT ciMaxBuffSize = MAX_PATH; // should be enough for tlbr ID, keep ID small if can
  1827. TCHAR strBuffer[ciMaxBuffSize];
  1828. if(!::LoadString(m_hRes, IDS_ROOT_OBJECT, strBuffer, ciMaxBuffSize)){
  1829. hr = E_UNEXPECTED;
  1830. return(hr);
  1831. }/* end of if statement */
  1832. CComPtr<IUnknown> pUnk = GetUnknown();
  1833. CComQIPtr<IDispatch> pDisp (pUnk);
  1834. if(!pDisp){
  1835. return(hr);
  1836. }/* end of if statement */
  1837. #ifdef _UNICODE
  1838. BSTR strObjectID = ::SysAllocString(strBuffer); // gets freed in the destructor of the holding object
  1839. #else
  1840. BSTR strObjectID = ::SysAllocString(T2OLE(strBuffer));
  1841. #endif
  1842. hr = AddObject(strObjectID, pDisp); // this one adds the object to the list as well
  1843. ::SysFreeString(strObjectID); // free up the sys string, since we allocate it in the contructor for the object
  1844. if(FAILED(hr)){
  1845. return(hr);
  1846. }/* end of if statement */
  1847. if(!m_strScriptLanguage){
  1848. // load what script language we decided to support if not set explicitly by user
  1849. if(!::LoadString(m_hRes, IDS_SCRIPT_LANGUAGE, strBuffer, ciMaxBuffSize)){
  1850. hr = E_UNEXPECTED;
  1851. return(hr);
  1852. }/* end of if statement */
  1853. m_strScriptLanguage = strBuffer;
  1854. }/* end of if statement */
  1855. CLSID clsid;
  1856. hr = ::CLSIDFromProgID(m_strScriptLanguage, &clsid); // get the language
  1857. if(FAILED(hr)){
  1858. return hr;
  1859. }/* end of if statement */
  1860. hr = m_ps.CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER);
  1861. // Create the ActiveX Scripting Engine
  1862. //hr = ::CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, IID_IActiveScript, (void **)&m_ps);
  1863. if (FAILED(hr)){
  1864. //s_pszError = "Creating the ActiveX Scripting engine failed. Scripting engine is probably not correctly registered or CLSID incorrect.";
  1865. return (hr);
  1866. }/* end of if statement */
  1867. // Script Engine must support IActiveScriptParse for us to use it
  1868. hr = m_ps->QueryInterface(IID_IActiveScriptParse, (void**) &m_psp);
  1869. if (FAILED(hr)){
  1870. //s_pszError = "ActiveX Scripting engine does not support IActiveScriptParse";
  1871. return (hr);
  1872. }/* end of if statement */
  1873. hr = m_ps->SetScriptSite(this);
  1874. if(FAILED(hr)){
  1875. return hr;
  1876. }/* end of if statement */
  1877. // InitNew the object:
  1878. hr = m_psp->InitNew();
  1879. if(FAILED(hr)){
  1880. return hr;
  1881. }/* end of if statement */
  1882. // Adding dynamically added items so they can be recognized by name
  1883. // and scripted via script language such as VBScript or JScript
  1884. for(CNTOBJ::iterator i = m_cntObj.begin(); i!= m_cntObj.end(); i++){
  1885. // iterate throw the array and see if we find matching ID
  1886. CHostedObject* pObj = (*i);
  1887. hr = m_ps->AddNamedItem((pObj)->GetID(), SCRIPTITEM_ISVISIBLE | SCRIPTITEM_ISSOURCE);
  1888. if(FAILED(hr)){
  1889. return(hr); // might want to modify this later to not exit if we get one bad object
  1890. }/* end of if statement */
  1891. }/* end of for loop */
  1892. // Special case adding the root object
  1893. if(!::LoadString(m_hRes, IDS_ROOT_OBJECT, strBuffer, ciMaxBuffSize)){
  1894. hr = E_UNEXPECTED;
  1895. return(hr);
  1896. }/* end of if statement */
  1897. #ifdef _UNICODE
  1898. hr = m_ps->AddNamedItem(strBuffer, SCRIPTITEM_ISVISIBLE | SCRIPTITEM_ISSOURCE);
  1899. #else
  1900. hr = m_ps->AddNamedItem(A2W(strBuffer), SCRIPTITEM_ISVISIBLE | SCRIPTITEM_ISSOURCE);
  1901. #endif
  1902. // Add up the events that we have saved in the event array
  1903. for(CNTEVNT::iterator j = m_cntEvnt.begin(); j!= m_cntEvnt.end(); j++){
  1904. EXCEPINFO ei;
  1905. ::ZeroMemory(&ei, sizeof(EXCEPINFO));
  1906. BSTR strName;
  1907. CEventObject* pObj = (*j);
  1908. hr = m_psp->AddScriptlet(NULL, pObj->m_strEventCode, pObj->m_strObjectID, NULL, pObj->m_strEvent, NULL, 0, 0, 0, &strName, &ei);
  1909. if(FAILED(hr)){
  1910. ATLTRACE(TEXT("Failed to add an event, might be using a different language or the object does not exists. \n"));
  1911. ATLASSERT(FALSE);
  1912. return(hr);
  1913. }/* end of if statement */
  1914. }/* end of for loop */
  1915. return (hr);
  1916. }/* end of function CreateScriptEngine */
  1917. /*************************************************************************/
  1918. /* Function: DestroyScriptEngine */
  1919. /* Description: Destroys the engine. Might be usefull when using one */
  1920. /* script to initialize the objects and the other script to run the */
  1921. /* objects. */
  1922. /*************************************************************************/
  1923. STDMETHODIMP CMFBar::DestroyScriptEngine(){
  1924. HRESULT hr = S_OK;
  1925. // Release the language engine, since it may hold on to us
  1926. if (m_psp){
  1927. m_psp.Release();
  1928. }/* end of if statement */
  1929. if (m_ps){
  1930. //HRESULT hrTmp = m_ps->InterruptScriptThread(SCRIPTTHREADID_CURRENT, NULL, SCRIPTINTERRUPT_DEBUG);
  1931. //ATLASSERT(SUCCEEDED(hrTmp));
  1932. hr = m_ps->Close();
  1933. if(FAILED(hr)){
  1934. return(hr);
  1935. }/* end of if statement */
  1936. m_ps.Release();
  1937. }/* end of if statement */
  1938. return (hr);
  1939. }/* end of function DestroyScriptEngine */
  1940. /*************************************************************************/
  1941. /* Function: Load */
  1942. /* Description: Loads the script. */
  1943. /*************************************************************************/
  1944. STDMETHODIMP CMFBar::Load(){
  1945. #ifndef _UNICODE_SCRIPT_FILE
  1946. USES_CONVERSION;
  1947. #endif
  1948. HRESULT hr = CreateScriptEngine();
  1949. if(FAILED(hr)){
  1950. ATLTRACE(TEXT("Failed to create a script engine.\n"));
  1951. ATLASSERT(FALSE);
  1952. return(hr);
  1953. }/* end of if statement */
  1954. // see if we can find this resource DLL in the script
  1955. // TCHAR* strType = TEXT("SCRIPT");
  1956. HRSRC hrscScript = ::FindResource(m_hRes, OLE2T(m_strScriptFile), MAKEINTRESOURCE(23));
  1957. if(NULL != hrscScript){
  1958. /**********************************************************************/
  1959. /* load up the script from a resource */
  1960. /**********************************************************************/
  1961. if(NULL == hrscScript){
  1962. hr = HRESULT_FROM_WIN32(::GetLastError());
  1963. return(hr);
  1964. }/* end of if statement */
  1965. HGLOBAL hScript = ::LoadResource(m_hRes, hrscScript);
  1966. if(NULL == hScript){
  1967. hr = HRESULT_FROM_WIN32(::GetLastError());
  1968. return(hr);
  1969. }/* end of if statement */
  1970. DWORD dwSize = SizeofResource((HMODULE)m_hRes, hrscScript);
  1971. if(dwSize == 0){
  1972. hr = E_UNEXPECTED;
  1973. return(hr);
  1974. }/* end of if statement */
  1975. /*****************************************************************/
  1976. /* change this depending if the file was saved as Unicode or not */
  1977. /*****************************************************************/
  1978. #ifndef _UNICODE_SCRIPT_FILE
  1979. WCHAR* strCode = A2W((CHAR*)hScript);
  1980. #else
  1981. WCHAR* strCode = (WCHAR*)hScript;
  1982. #endif
  1983. const INT ciMaxBuffSize = MAX_PATH;
  1984. TCHAR strEOFMarker[ciMaxBuffSize]; // the end of file marker
  1985. // Load up the end of file delimiter
  1986. if(!::LoadString(m_hRes, IDS_END_FILE, strEOFMarker, ciMaxBuffSize)){
  1987. hr = E_UNEXPECTED;
  1988. return(hr);
  1989. }/* end of if statement */
  1990. EXCEPINFO ei;
  1991. ::ZeroMemory(&ei, sizeof(EXCEPINFO));
  1992. #ifdef _UNICODE
  1993. hr = m_psp->ParseScriptText(strCode, NULL, NULL, strEOFMarker, 0, 0, SCRIPTTEXT_ISEXPRESSION|SCRIPTTEXT_ISVISIBLE, NULL, &ei);
  1994. #else
  1995. hr = m_psp->ParseScriptText(strCode, NULL, NULL, A2W(strEOFMarker), 0, 0, SCRIPTTEXT_ISEXPRESSION|SCRIPTTEXT_ISVISIBLE, NULL, &ei);
  1996. #endif
  1997. }
  1998. else {
  1999. /**********************************************************************/
  2000. /* load up the script from a file */
  2001. /**********************************************************************/
  2002. // Create File m_strScriptFile
  2003. HANDLE hFile = ::CreateFile(
  2004. OLE2T(m_strScriptFile), // pointer to name of the file
  2005. GENERIC_READ, // access (read-write) mode
  2006. FILE_SHARE_READ, // share mode
  2007. NULL, // pointer to security descriptor
  2008. OPEN_EXISTING, // how to create
  2009. FILE_ATTRIBUTE_NORMAL, // file attributes
  2010. NULL // handle to file with attributes to copy
  2011. );
  2012. if(hFile == INVALID_HANDLE_VALUE){
  2013. hr = HRESULT_FROM_WIN32(::GetLastError());
  2014. #if _DEBUG
  2015. TCHAR strBuffer[MAX_PATH + 25];
  2016. wsprintf(strBuffer, TEXT("Failed to open script file %s"), OLE2T(m_strScriptFile));
  2017. ::MessageBox(::GetFocus(), strBuffer, TEXT("Error"), MB_OK);
  2018. #endif
  2019. return(hr);
  2020. }/* end of if statement */
  2021. DWORD dwBitsSize = GetFileSize(hFile,NULL);
  2022. if(0 == dwBitsSize){
  2023. hr = E_UNEXPECTED;
  2024. return(hr); // the file size should be definetly more then 0
  2025. }/* end of if statement */
  2026. BYTE* pbBuffer = new BYTE[dwBitsSize + sizeof(WCHAR)];
  2027. ::ZeroMemory(pbBuffer, dwBitsSize + sizeof(WCHAR));
  2028. // load it up convert the text to UNICODE
  2029. DWORD dwBytesRead = 0;
  2030. if(!ReadFile(hFile, pbBuffer, dwBitsSize, &dwBytesRead, NULL)){
  2031. hr = HRESULT_FROM_WIN32(::GetLastError());
  2032. delete[] pbBuffer;
  2033. ::CloseHandle(hFile); // close the file
  2034. return (hr);
  2035. }/* end of function ReadFile */
  2036. if(dwBitsSize != dwBytesRead){
  2037. ATLTRACE(TEXT("Implement reading loop"));
  2038. delete[] pbBuffer; // free up the temp buffer
  2039. ::CloseHandle(hFile); // close the file
  2040. hr = E_UNEXPECTED;
  2041. return(hr);
  2042. }/* end of if statement */
  2043. /*****************************************************************/
  2044. /* change this depending if the file was saved as Unicode or not */
  2045. /*****************************************************************/
  2046. #ifndef _UNICODE_SCRIPT_FILE
  2047. WCHAR* strCode = A2W((CHAR*)pbBuffer);
  2048. #else
  2049. WCHAR* strCode = (WCHAR*)pbBuffer;
  2050. #endif
  2051. delete[] pbBuffer; // free up the temp buffer
  2052. ::CloseHandle(hFile); // close the file
  2053. EXCEPINFO ei;
  2054. ::ZeroMemory(&ei, sizeof(EXCEPINFO));
  2055. #ifdef _UNICODE
  2056. hr = m_psp->ParseScriptText(strCode, NULL, NULL, NULL, 0, 0, SCRIPTTEXT_ISEXPRESSION|SCRIPTTEXT_ISVISIBLE, NULL, &ei);
  2057. #else
  2058. hr = m_psp->ParseScriptText(strCode, NULL, NULL, NULL, 0, 0, SCRIPTTEXT_ISEXPRESSION|SCRIPTTEXT_ISVISIBLE, NULL, &ei);
  2059. #endif
  2060. }/* end of if statement */
  2061. // take out the extra character at the begining of the unicode file just in case it is garbled by editor
  2062. if(FAILED(hr)){
  2063. return(hr);
  2064. }/* end of if statement */
  2065. hr = m_ps->SetScriptState(/* SCRIPTSTATE_STARTED */ SCRIPTSTATE_CONNECTED);
  2066. return hr;
  2067. }/* end of function Load */
  2068. /*************************************************************************/
  2069. /* Function: AddScriptlet */
  2070. /* Description: Using this method you can add events for JScript and */
  2071. /* other languages that do not support event handlers internally. This */
  2072. /* method just add these to the array which does get initializied on load*/
  2073. /*************************************************************************/
  2074. STDMETHODIMP CMFBar::AddScriptlet(BSTR strObjectID, BSTR strEvent, BSTR strEventCode){
  2075. HRESULT hr = S_OK;
  2076. CEventObject* pObj = new CEventObject(strObjectID, strEvent, strEventCode);
  2077. if(NULL == pObj){
  2078. hr = E_OUTOFMEMORY;
  2079. return(hr);
  2080. }/* end of if statement */
  2081. m_cntEvnt.insert(m_cntEvnt.end(), pObj);
  2082. return(hr);
  2083. }/* end of function AddScriptlet */
  2084. /*************************************************************************/
  2085. /* Function: HookScriptlet */
  2086. /* Description: Hooks the scrtiptlet for immidiate use, unlike the */
  2087. /* Add scriptlet which adds it, so it takes effect in the next Load. */
  2088. /* However, it also adds the callback to the array, so if needs to be */
  2089. /* loaded on the next load. */
  2090. /*************************************************************************/
  2091. STDMETHODIMP CMFBar::HookScriptlet(BSTR strObjectID, BSTR strEvent, BSTR strEventCode){
  2092. HRESULT hr = S_OK;
  2093. try {
  2094. hr = AddScriptlet(strObjectID, strEvent, strEventCode);
  2095. if(!m_ps){
  2096. ATLTRACE(TEXT("No Script Engine!! No Run!!\n"));
  2097. ATLASSERT(FALSE);
  2098. throw(S_FALSE);
  2099. }/* end of if statement */
  2100. EXCEPINFO ei;
  2101. ::ZeroMemory(&ei, sizeof(EXCEPINFO));
  2102. BSTR strName;
  2103. hr = m_ps->SetScriptState(SCRIPTSTATE_STARTED);
  2104. if(FAILED(hr)){
  2105. throw(hr);
  2106. }/* end of if statement */
  2107. hr = m_psp->AddScriptlet(NULL, strEventCode, strObjectID, NULL, strEvent, NULL, 0, 0, 0, &strName, &ei);
  2108. if(FAILED(hr)){
  2109. throw(hr);
  2110. }/* end of if statement */
  2111. hr = m_ps->SetScriptState(SCRIPTSTATE_CONNECTED);
  2112. }/* end of try statement */
  2113. catch(HRESULT hrTmp){
  2114. hr = hrTmp;
  2115. }
  2116. catch(...){
  2117. hr = E_UNEXPECTED;
  2118. }/* end of catch statement */
  2119. return (hr);
  2120. }/* end of function HookScriptlet */
  2121. /*************************************************************************/
  2122. /* Function: Run */
  2123. /* Description: Runs the Script function. Right now I do not support */
  2124. /* TODO: parameters, but they can be added, by handling VARIANT. */
  2125. /*************************************************************************/
  2126. STDMETHODIMP CMFBar::Run(BSTR strStatement){
  2127. HRESULT hr = E_FAIL;
  2128. if(!m_ps){
  2129. ATLTRACE(TEXT("No Script Engine!! No Run!!\n"));
  2130. ATLASSERT(FALSE);
  2131. return(hr);
  2132. }/* end of if statement */
  2133. CComPtr<IDispatch> pDispatch;
  2134. hr = m_ps->GetScriptDispatch(NULL, &pDispatch);
  2135. if (FAILED(hr)){
  2136. return(hr);
  2137. }/* end of if statement */
  2138. DISPID dispidMain;
  2139. LCID lcid = ::GetUserDefaultLCID();
  2140. hr = pDispatch->GetIDsOfNames(IID_NULL, &strStatement, 1, lcid, &dispidMain);
  2141. if (hr == ResultFromScode(DISP_E_UNKNOWNNAME))
  2142. hr = NOERROR;
  2143. else if (FAILED(hr))
  2144. hr = E_UNEXPECTED;
  2145. else{
  2146. UINT uArgErr;
  2147. DISPPARAMS params;
  2148. EXCEPINFO ei;
  2149. params.cArgs = 0;
  2150. params.cNamedArgs = 0;
  2151. params.rgvarg = NULL;
  2152. params.rgdispidNamedArgs = NULL;
  2153. hr = pDispatch->Invoke(dispidMain, IID_NULL, lcid, DISPATCH_METHOD,
  2154. &params,NULL, &ei, &uArgErr);
  2155. if (FAILED(hr)){
  2156. return(hr);
  2157. }/* end of if statement */
  2158. }/* end of if statement */
  2159. #ifdef _DEBUG
  2160. ULONG ulcstmt;
  2161. if(FAILED(hr)){
  2162. return(hr);
  2163. }/* end of if statement */
  2164. CComQIPtr<IActiveScriptStats> pstat(m_ps);
  2165. if (pstat){
  2166. ULONG luT;
  2167. if (FAILED(pstat->GetStat(SCRIPTSTAT_STATEMENT_COUNT, &luT, &ulcstmt)))
  2168. ulcstmt = 0;
  2169. }/* end of if statement */
  2170. ATLTRACE("Statments executed %d\n", ulcstmt);
  2171. #endif
  2172. return(hr);
  2173. }/* end of function Run */
  2174. /*************************************************************************/
  2175. /* Function: CreateObject */
  2176. /* Description: Creates a new ActiveX object that can be scripted. */
  2177. /* Puts the newly created object into container and activates it. */
  2178. /*************************************************************************/
  2179. STDMETHODIMP CMFBar::CreateObject(BSTR strID, BSTR strProgID,
  2180. long lx, long ly, long lWidth, long lHeight,
  2181. BSTR strPropBag, VARIANT_BOOL fDisabled,
  2182. BSTR strScriptHook){
  2183. HRESULT hr;
  2184. CHostedObject *pObj = NULL; // an ActiveX object
  2185. try {
  2186. hr = FindObject(strID, &pObj);
  2187. if(SUCCEEDED(hr)){
  2188. ATLTRACE(TEXT("Duplicate Object \n!"));
  2189. throw(E_FAIL);
  2190. }/* end of if statement */
  2191. // create the object
  2192. hr = CHostedObject::CreateObject(strID, strProgID, strPropBag, &pObj);
  2193. if(FAILED(hr)){
  2194. ATLTRACE2(atlTraceHosting, 2, TEXT("Failed to Create Object %ls \n"), strID);
  2195. throw(hr);
  2196. }/* end of if statement */
  2197. // initialize inPlaceObject
  2198. CComPtr<IUnknown> pObjectUnknown;
  2199. pObjectUnknown = pObj->GetUnknown();
  2200. // Get this container unknown
  2201. CComPtr<IUnknown> pContainerUnknown;
  2202. pContainerUnknown = GetUnknown();
  2203. if(!pContainerUnknown){
  2204. throw(hr);
  2205. }/* end of if statement */
  2206. // this is just a container that delegates pretty
  2207. // much all the methods to this container
  2208. // only purpose for its being is that we need to connection
  2209. // between the container and a specific object
  2210. // for SetCapture and SetFocus calls
  2211. CContainerObject* pContainerObj = new CContainerObject(pContainerUnknown, pObj);
  2212. pContainerUnknown.Release();
  2213. if(NULL == pContainerObj){
  2214. throw(E_OUTOFMEMORY);
  2215. }/* end of if statement */
  2216. pObj->SetContainerObject(pContainerObj);
  2217. CComPtr<IUnknown> pUnkContainerObj;
  2218. hr = pContainerObj->QueryInterface(IID_IUnknown, (void**)&pUnkContainerObj);
  2219. if(FAILED(hr)){
  2220. hr = E_FAIL;
  2221. throw(hr);
  2222. }/* end of if statement */
  2223. // insert it at the end of the list
  2224. // TODO: eventually check for duplicate IDs
  2225. m_cntObj.insert(m_cntObj.end(), pObj);
  2226. // add our self to the script engine, so we can hook up the events
  2227. HRESULT hrTmp = m_ps->AddNamedItem((pObj)->GetID(), SCRIPTITEM_ISVISIBLE | SCRIPTITEM_ISSOURCE);
  2228. if(FAILED(hrTmp)){
  2229. ATLTRACE(TEXT("Engine is not initilized yet, but that is what I guess we intended\n"));
  2230. ATLASSERT(FALSE);
  2231. }/* end of if statement */
  2232. CComPtr<IOleObject> pOleObject;
  2233. HRESULT hrOle = pObj->GetOleObject(&pOleObject);
  2234. if(SUCCEEDED(hrOle)){
  2235. DWORD dwMiscStatus;
  2236. pOleObject->GetMiscStatus(DVASPECT_CONTENT, &dwMiscStatus);
  2237. // set the OLE site
  2238. CComPtr<IOleClientSite> spClientSite;
  2239. hr = pUnkContainerObj->QueryInterface(&spClientSite);
  2240. if(FAILED(hr)){
  2241. throw(hr);
  2242. }/* end of if statement */
  2243. if(dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST){
  2244. pOleObject->SetClientSite(spClientSite); // set the client site
  2245. }/* end of if statement */
  2246. // no property bag so try to initialze from stream
  2247. CComQIPtr<IPersistStreamInit, &IID_IPersistStreamInit> spPSI(pOleObject);
  2248. // TODO: Eventaully load up stream via CreateStreamOnHGlobal
  2249. if (spPSI)
  2250. spPSI->InitNew(); // create new stream
  2251. // see if want to use the IPropertyBag to initialize our properties
  2252. CComQIPtr<IPersistPropertyBag, &IID_IPersistPropertyBag> pBag(pObjectUnknown);
  2253. if (pBag) {
  2254. CComQIPtr<IPropertyBag, &IID_IPropertyBag> pSBag(pUnkContainerObj);
  2255. if(!pSBag){
  2256. ATLTRACE2(atlTraceHosting, 0, _T("Could not get IPropertyBag.\r\n"));
  2257. ATLASSERT(FALSE);
  2258. throw(E_UNEXPECTED);
  2259. }/* end of if statement */
  2260. HRESULT hrTmp = pBag->Load(pSBag, NULL);
  2261. if(SUCCEEDED(hrTmp)){
  2262. pBag->Save(pSBag, FALSE, TRUE);
  2263. }/* end of if statement */
  2264. }/* end of if statement */
  2265. if(0 == (dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST)){
  2266. pOleObject->SetClientSite(spClientSite); // set the client site
  2267. }/* end of if statement */
  2268. pObj->InitViewObject(); // cache view object
  2269. // hook up sink/notify for events
  2270. // via this call in which we have chance to hook them up
  2271. if(NULL != *strScriptHook){
  2272. HRESULT hrTmp = Run(strScriptHook);
  2273. if(FAILED(hrTmp)){
  2274. ATLTRACE(TEXT("Engine is not initilized yet, but that is what I guess we intended\n"));
  2275. ATLASSERT(FALSE);
  2276. }/* end of if statement */
  2277. }/* end of if statement */
  2278. // Get the extents adjust them etc...
  2279. // TODO enhance this to handle generic size
  2280. RECT rcPos;
  2281. SIZEL sSize, shmSize;
  2282. sSize.cx = lWidth;
  2283. sSize.cy = lHeight;
  2284. AtlPixelToHiMetric(&sSize, &shmSize);
  2285. pOleObject->SetExtent(DVASPECT_CONTENT, &shmSize);
  2286. pOleObject->GetExtent(DVASPECT_CONTENT, &shmSize);
  2287. AtlHiMetricToPixel(&shmSize, &sSize);
  2288. // TODO: handle the moves on SetObjectRects
  2289. // right now we set offset once but this needs to be eventaully done
  2290. rcPos.left = lx; // use m_rcPos for the offsets these any time we get SetObjectRects call
  2291. rcPos.top = ly;
  2292. rcPos.right = rcPos.left + sSize.cx;
  2293. rcPos.bottom = rcPos.top + sSize.cy;
  2294. // TODO: we might want to wait till our rect is set
  2295. // and then let the script to go at it, that way we reduce the moves
  2296. // and possible flashes
  2297. pObj->SetRawPos(&rcPos); // remember our new position raw position
  2298. //pObj->SetOffset(&m_rcPos.left, &m_rcPos.top); // sets the pointers to the offset
  2299. //pObj->GetPos(&rcPos); // get the position back with adjusted rect
  2300. if(VARIANT_FALSE != fDisabled){
  2301. pObj->SetActive(false);
  2302. }/* end of if statement */
  2303. // IN_PLACE ACTIVATE
  2304. hrOle = pOleObject->DoVerb(OLEIVERB_INPLACEACTIVATE, NULL, spClientSite, 0, m_hWnd, &rcPos);
  2305. }
  2306. else {
  2307. // use the liter interface when IOleObject is not available
  2308. CComQIPtr<IObjectWithSite> spSite(pObjectUnknown);
  2309. if(spSite){
  2310. spSite->SetSite(pUnkContainerObj);
  2311. }/* end of if statement */
  2312. }/* end of if statement */
  2313. }/* end of try statement */
  2314. catch(HRESULT hrTmp){
  2315. hr = hrTmp;
  2316. // cleanup our variables just in case
  2317. if(NULL != pObj){
  2318. delete pObj;
  2319. }/* end of if statement */
  2320. }
  2321. catch(...){
  2322. hr = E_UNEXPECTED;
  2323. }/* end of catch statement */
  2324. return (hr);
  2325. }/* end of function CreateObject */
  2326. /*************************************************************************/
  2327. /* Function: ShowSelfSite */
  2328. /* Description: Show itself as an site for itself. */
  2329. /*************************************************************************/
  2330. STDMETHODIMP CMFBar::ShowSelfSite(long nCmd)
  2331. {
  2332. if (::IsWindow(m_hWnd)) {
  2333. m_pBackBitmap->DeleteMemDC();
  2334. ::ShowWindow(m_hWnd, nCmd);
  2335. InvalidateRgn();
  2336. }
  2337. return S_OK;
  2338. }
  2339. /*************************************************************************/
  2340. /* Function: SetupSelfSite */
  2341. /* Description: Sets itself as an site for itself. */
  2342. /*************************************************************************/
  2343. STDMETHODIMP CMFBar::SetupSelfSite(long lx, long ly, long lWidth,
  2344. long lHeight, BSTR strPropBag,
  2345. VARIANT_BOOL fDisabled,
  2346. VARIANT_BOOL fHelpDisabled,
  2347. VARIANT_BOOL fWindowDisabled){
  2348. HRESULT hr;
  2349. CHostedObject *pObj = NULL; // an ActiveX object
  2350. try {
  2351. if(true == m_fSelfHosted){
  2352. // we are already hosting our self so do not try to do so again
  2353. throw(S_FALSE);
  2354. }/* end of if statement */
  2355. if(m_nReadyState == READYSTATE_COMPLETE){
  2356. throw(S_FALSE); //we are already hosted (most likely IE)
  2357. }/* end of if statement */
  2358. m_bWindowOnly = TRUE; // create self as a window
  2359. m_fSelfHosted = true; // we are trying to self host so send a QUIT message
  2360. CComPtr<IDispatch> pDisp;
  2361. hr = GetUnknown()->QueryInterface(&pDisp);
  2362. if(FAILED(hr)){
  2363. throw(hr);
  2364. }/* end of if statement */
  2365. const INT ciMaxBuffSize = MAX_PATH; // should be enough for tlbr ID, keep ID small if can
  2366. TCHAR strBuffer[ciMaxBuffSize];
  2367. if(!::LoadString(m_hRes, IDS_ROOT_OBJECT, strBuffer, ciMaxBuffSize)){
  2368. hr = E_UNEXPECTED;
  2369. return(hr);
  2370. }/* end of if statement */
  2371. #ifndef _UNICODE
  2372. USES_CONVERSION;
  2373. BSTR strObjectID = ::SysAllocString(T2W(strBuffer));
  2374. #else
  2375. BSTR strObjectID = ::SysAllocString(strBuffer);
  2376. #endif
  2377. hr = CHostedObject::AddObject(strObjectID, strPropBag, pDisp, &pObj);
  2378. // strPropBag gets allocated as well
  2379. ::SysFreeString(strObjectID);
  2380. if(FAILED(hr)){
  2381. throw(hr);
  2382. }/* end of if statement */
  2383. // initialize inPlaceObject
  2384. CComPtr<IUnknown> pObjectUnknown;
  2385. pObjectUnknown = pObj->GetUnknown();
  2386. // Get this container unknown
  2387. CComPtr<IUnknown> pContainerUnknown;
  2388. pContainerUnknown = GetUnknown();
  2389. if(!pContainerUnknown){
  2390. throw(hr);
  2391. }/* end of if statement */
  2392. // this is just a container that delegates pretty
  2393. // much all the methods to this container
  2394. // only purpose for its being is that we need to connection
  2395. // between the container and a specific object
  2396. // for SetCapture and SetFocus calls
  2397. CContainerObject* pContainerObj = new CContainerObject(pContainerUnknown, pObj);
  2398. pContainerUnknown.Release();
  2399. if(NULL == pContainerObj){
  2400. throw(E_OUTOFMEMORY);
  2401. }/* end of if statement */
  2402. pObj->SetContainerObject(pContainerObj);
  2403. CComPtr<IUnknown> pUnkContainerObj;
  2404. hr = pContainerObj->QueryInterface(IID_IUnknown, (void**)&pUnkContainerObj);
  2405. if(FAILED(hr)){
  2406. throw(hr);
  2407. }/* end of if statement */
  2408. // DO NOT INSERT THIS OBJECT, SINCE IT IS OUR CONTAINER
  2409. // m_cntObj.insert(m_cntObj.end(), pObj);
  2410. CComPtr<IOleObject> pOleObject;
  2411. HRESULT hrOle = pObj->GetOleObject(&pOleObject);
  2412. if(FAILED(hrOle)){
  2413. throw(hrOle);
  2414. }/* end of if statement */
  2415. DWORD dwMiscStatus;
  2416. pOleObject->GetMiscStatus(DVASPECT_CONTENT, &dwMiscStatus);
  2417. // set the OLE site
  2418. CComPtr<IOleClientSite> spClientSite;
  2419. hr = pUnkContainerObj->QueryInterface(&spClientSite);
  2420. if(FAILED(hr)){
  2421. throw(hr);
  2422. }/* end of if statement */
  2423. if(dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST){
  2424. pOleObject->SetClientSite(spClientSite); // set the client site
  2425. }/* end of if statement */
  2426. // no property bag so try to initialze from stream
  2427. CComQIPtr<IPersistStreamInit, &IID_IPersistStreamInit> spPSI(pOleObject);
  2428. // TODO: Eventaully load up stream via CreateStreamOnHGlobal
  2429. if (spPSI)
  2430. spPSI->InitNew(); // create new stream
  2431. // see if want to use the IPropertyBag to initialize our properties
  2432. CComQIPtr<IPersistPropertyBag, &IID_IPersistPropertyBag> pBag(pObjectUnknown);
  2433. if (pBag) {
  2434. CComQIPtr<IPropertyBag, &IID_IPropertyBag> pSBag(pUnkContainerObj);
  2435. if(!pSBag){
  2436. ATLTRACE2(atlTraceHosting, 0, _T("Could not get IPropertyBag.\r\n"));
  2437. ATLASSERT(FALSE);
  2438. throw(E_UNEXPECTED);
  2439. }/* end of if statement */
  2440. HRESULT hrTmp = pBag->Load(pSBag, NULL);
  2441. if(SUCCEEDED(hrTmp)){
  2442. pBag->Save(pSBag, FALSE, TRUE);
  2443. }/* end of if statement */
  2444. }/* end of if statement */
  2445. if(0 == (dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST)){
  2446. pOleObject->SetClientSite(spClientSite); // set the client site
  2447. }/* end of if statement */
  2448. pObj->InitViewObject(); // cache view object
  2449. // TODO: hook up sink/notify for events
  2450. // Get the extents adjust them etc...
  2451. // TODO enhance this to handle generic size
  2452. RECT rcPos;
  2453. SIZEL sSize, shmSize;
  2454. sSize.cx = lWidth;
  2455. sSize.cy = lHeight;
  2456. AtlPixelToHiMetric(&sSize, &shmSize);
  2457. pOleObject->SetExtent(DVASPECT_CONTENT, &shmSize);
  2458. pOleObject->GetExtent(DVASPECT_CONTENT, &shmSize);
  2459. AtlHiMetricToPixel(&shmSize, &sSize);
  2460. // TODO: handle the moves on SetObjectRects
  2461. // right now we set offset once but this needs to be eventaully done
  2462. rcPos.left = lx; // use m_rcPos for the offsets these any time we get SetObjectRects call
  2463. rcPos.top = ly;
  2464. rcPos.right = rcPos.left + sSize.cx;
  2465. rcPos.bottom = rcPos.top + sSize.cy;
  2466. RECT rcClientRect;
  2467. rcClientRect.left = 0; // use m_rcPos for the offsets these any time we get SetObjectRects call
  2468. rcClientRect.top = 0;
  2469. rcClientRect.right = sSize.cx;
  2470. rcClientRect.bottom = sSize.cy;
  2471. // TODO: we might want to wait till our rect is set
  2472. // and then let the script to go at it, that way we reduce the moves
  2473. // and possible flashes
  2474. pObj->SetRawPos(&rcPos); // remember our new position raw position
  2475. // adjust rects
  2476. // IN_PLACE ACTIVATE OUR SELF ACTIVATION VERSION
  2477. if (m_spClientSite == NULL)
  2478. return S_OK;
  2479. CComPtr<IOleInPlaceObject> pIPO;
  2480. ControlQueryInterface(IID_IOleInPlaceObject, (void**)&pIPO);
  2481. ATLASSERT(pIPO != NULL);
  2482. m_spClientSite->QueryInterface(IID_IOleInPlaceSiteEx, (void**)&m_spInPlaceSite);
  2483. if (m_spInPlaceSite)
  2484. m_bInPlaceSiteEx = TRUE;
  2485. else
  2486. hr = m_spClientSite->QueryInterface(IID_IOleInPlaceSite, (void**) &m_spInPlaceSite);
  2487. ATLASSERT(m_spInPlaceSite);
  2488. if (!m_spInPlaceSite)
  2489. throw(E_FAIL);
  2490. m_bNegotiatedWnd = TRUE;
  2491. if (!m_bInPlaceActive){
  2492. BOOL bNoRedraw = FALSE;
  2493. if (m_bInPlaceSiteEx)
  2494. m_spInPlaceSite->OnInPlaceActivateEx(&bNoRedraw, 0);
  2495. else
  2496. {
  2497. hr = m_spInPlaceSite->CanInPlaceActivate();
  2498. // CanInPlaceActivate returns S_FALSE or S_OK
  2499. if (FAILED(hr))
  2500. throw(hr);
  2501. if ( hr != S_OK )
  2502. {
  2503. // CanInPlaceActivate returned S_FALSE.
  2504. throw( E_FAIL );
  2505. }
  2506. m_spInPlaceSite->OnInPlaceActivate();
  2507. }
  2508. }/* end of if statement */
  2509. m_bInPlaceActive = TRUE;
  2510. // get location in the parent window,
  2511. // as well as some information about the parent
  2512. //
  2513. OLEINPLACEFRAMEINFO frameInfo;
  2514. CComPtr<IOleInPlaceFrame> spInPlaceFrame;
  2515. CComPtr<IOleInPlaceUIWindow> spInPlaceUIWindow;
  2516. frameInfo.cb = sizeof(OLEINPLACEFRAMEINFO);
  2517. if (!m_bWndLess){
  2518. DWORD dwStyle;
  2519. DWORD dwExStyle;
  2520. HWND hwndPar = NULL;
  2521. if(VARIANT_FALSE == fWindowDisabled){
  2522. // one with the frame
  2523. dwStyle = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
  2524. dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
  2525. }
  2526. else {
  2527. // one without the frame
  2528. dwStyle = WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
  2529. //dwExStyle = WS_EX_TRANSPARENT; //| WS_EX_LTRREADING| WS_EX_WINDOWEDGE;
  2530. //dwExStyle = 0x00080000; //WS_EX_LAYERED = 0x00080000;
  2531. dwExStyle = WS_EX_APPWINDOW;
  2532. //hwndPar = ::GetDesktopWindow();
  2533. }/* end of if statement */
  2534. if(VARIANT_FALSE == fDisabled){
  2535. dwStyle |= WS_VISIBLE;
  2536. }/* end of if statement */
  2537. if(VARIANT_FALSE == fHelpDisabled){
  2538. dwStyle &= ~(WS_MINIMIZEBOX | WS_MAXIMIZEBOX); // take out the min max style
  2539. // help does not work with it
  2540. dwExStyle |= WS_EX_CONTEXTHELP;
  2541. }/* end of if statement */
  2542. #ifdef _UNICODE
  2543. HWND h = Create(hwndPar, rcPos, m_bstrCaption /* window name */, dwStyle, dwExStyle);
  2544. #else
  2545. USES_CONVERSION;
  2546. HWND h = Create(hwndPar, rcPos, OLE2T(m_bstrCaption) /* window name */, dwStyle, dwExStyle);
  2547. #endif
  2548. // used instead of
  2549. // HWND h = CreateControlWindow(hwndParent, rcPos);
  2550. ATLASSERT(h != NULL); // will assert if creation failed
  2551. ATLASSERT(h == m_hWndCD);
  2552. if(NULL == h){
  2553. throw(E_FAIL);
  2554. }/* end of if statement */
  2555. if(VARIANT_TRUE == fWindowDisabled){
  2556. ::SendMessage(h, WM_SETICON, (WPARAM)ICON_SMALL, (LPARAM) m_hIcon);
  2557. ::SendMessage(h, WM_SETICON, (WPARAM)ICON_BIG, (LPARAM) m_hIcon);
  2558. }/* end of if statement */
  2559. }/* end of if statement */
  2560. if(VARIANT_FALSE != fDisabled){
  2561. pObj->SetActive(false);
  2562. }/* end of if statement */
  2563. }/* end of try statement */
  2564. catch(HRESULT hrTmp){
  2565. hr = hrTmp;
  2566. m_fSelfHosted = false;
  2567. // cleanup our variables just in case
  2568. if(NULL != pObj){
  2569. delete pObj;
  2570. }/* end of if statement */
  2571. }
  2572. catch(...){
  2573. m_fSelfHosted = false;
  2574. hr = E_UNEXPECTED;
  2575. }/* end of catch statement */
  2576. return (hr);
  2577. }/* end of function SetupSelfSite */
  2578. /*************************************************************************/
  2579. /* Function: AddObject */
  2580. /* Description: Adds a scriptable only object that was created somewhere */
  2581. /* else into our object container. */
  2582. /*************************************************************************/
  2583. STDMETHODIMP CMFBar::AddObject(BSTR strObjectID, LPDISPATCH pDisp){
  2584. HRESULT hr;
  2585. CHostedObject *pObj = NULL; // an ActiveX object
  2586. try {
  2587. // add an object that was already created
  2588. // this object does not get the Active flag set which
  2589. // means we will not try to draw it and do other
  2590. // activities on it, such as we would do on the objects
  2591. // that are contained and have a site
  2592. hr = CHostedObject::AddObject(strObjectID, NULL, pDisp, &pObj);
  2593. if(FAILED(hr)){
  2594. throw(hr);
  2595. }/* end of if statement */
  2596. // now add the object to the container
  2597. // insert it at the end of the list
  2598. // TODO: eventually check for duplicate IDs
  2599. m_cntObj.insert(m_cntObj.end(), pObj);
  2600. }/* end of try statement */
  2601. catch(HRESULT hrTmp){
  2602. hr = hrTmp;
  2603. // cleanup our variables just in case
  2604. if(NULL != pObj){
  2605. delete pObj;
  2606. }/* end of if statement */
  2607. }
  2608. catch(...){
  2609. hr = E_UNEXPECTED;
  2610. }/* end of catch statement */
  2611. return (hr);
  2612. }/* end of function AddObject */
  2613. // ##### END ACTIVEX SCRIPTING SUPPORT #####
  2614. /*************************************************************************/
  2615. /* Function: GetParentHWND */
  2616. /* Description: Gets the parent window HWND where we are operating. */
  2617. /*************************************************************************/
  2618. HRESULT CMFBar::GetParentHWND(HWND* pWnd){
  2619. HRESULT hr = E_FAIL;
  2620. *pWnd = NULL;
  2621. if(m_bWndLess){
  2622. CComPtr<IOleClientSite> pClientSite;
  2623. hr = GetClientSite(&pClientSite);
  2624. if(FAILED(hr)){
  2625. return(hr);
  2626. }/* end of if statement */
  2627. CComQIPtr<IOleWindow> pOleWindow(pClientSite);
  2628. if(!pOleWindow){
  2629. hr = E_FAIL;
  2630. return(hr);
  2631. }/* end of if statement */
  2632. hr = pOleWindow->GetWindow(pWnd);
  2633. }
  2634. else {
  2635. if(::IsWindow(m_hWnd)){
  2636. *pWnd = ::GetParent(m_hWnd);
  2637. if(::IsWindow(*pWnd)){
  2638. hr = S_OK;
  2639. }/* end of if statement */
  2640. }/* end of if statement */
  2641. }/* end of if statement */
  2642. return(hr);
  2643. }/* end of function GetParentHWND */
  2644. /*************************************************************************/
  2645. /* Function: GetClientRect */
  2646. /* Description: Gets the client rect. If we are windowless we pass down */
  2647. /* the m_rcPos. */
  2648. /*************************************************************************/
  2649. BOOL CMFBar::GetClientRect(LPRECT lpRect) const{
  2650. BOOL bRet = TRUE;
  2651. if (!lpRect){
  2652. bRet = FALSE;
  2653. return (bRet);
  2654. }/* end of if statement */
  2655. if(m_bWndLess){
  2656. *lpRect = m_rcPos;
  2657. return(bRet);
  2658. }/* end of if statement */
  2659. ATLASSERT(::IsWindow(m_hWnd));
  2660. bRet = ::GetClientRect(m_hWnd, lpRect);
  2661. return(bRet);
  2662. }/* end of function GetClientRect */
  2663. /*************************************************************************/
  2664. /* Function: GetParent */
  2665. /* Description: Gets the parent window. If we are windowless we pass */
  2666. /* down the parent container window, which is really in a sense parent. */
  2667. /*************************************************************************/
  2668. HWND CMFBar::GetParent(){
  2669. HWND hwnd = NULL;
  2670. if(m_bWndLess){
  2671. GetParentHWND(&hwnd);
  2672. return(hwnd);
  2673. }/* end of if statement */
  2674. ATLASSERT(::IsWindow(m_hWnd));
  2675. return ::GetParent(m_hWnd);
  2676. }/* end of function GetParent */
  2677. /*************************************************************************/
  2678. /* Function: AdjustRects */
  2679. /* Description: calls all our contained objects and the adjusts their */
  2680. /* rects in the case we have moved, if we do not have any that is OK, */
  2681. /* since the offset is kept in m_rcPos and set whenever the objects */
  2682. /* get created. */
  2683. /*************************************************************************/
  2684. HRESULT CMFBar::AdjustRects(const LPCRECT prcPos){
  2685. HRESULT hr = S_OK;
  2686. //TODO: handle resizing
  2687. ATLTRACE2(atlTraceHosting, 2, TEXT("Resizing control prcPos->left = %d, prcPos.right = %d, prcPos.bottom =%d, prcPos.top = %d\n"),
  2688. prcPos->left, prcPos->right, prcPos->bottom, prcPos->top);
  2689. if(false == m_fSelfHosted){
  2690. Fire_OnResize(RECTWIDTH(prcPos), RECTHEIGHT(prcPos), SIZE_RESTORED);
  2691. }/* end of if statement */
  2692. #if 0
  2693. if(!m_bWndLess){
  2694. return(hr);
  2695. }/* end of if statement */
  2696. if(m_cntObj.empty() == true){
  2697. hr = S_FALSE;
  2698. return(hr);
  2699. }/* end of if statement */
  2700. CNTOBJ::iterator i;
  2701. for(i = m_cntObj.begin(); i!= m_cntObj.end(); i++){
  2702. CHostedObject* pObj = (*i);
  2703. ATLASSERT(pObj);
  2704. if(m_fSelfHosted && (GetUnknown() == pObj->GetUnknown())){
  2705. continue; // that is us we close our self later after the contained objects
  2706. }/* end of if statement */
  2707. pObj->SetObjectRects(); // adjust the current offset if it needs to be so
  2708. }/* end of for loop */
  2709. #endif
  2710. return(hr);
  2711. }/* end of function AdjustRects */
  2712. /*************************************************************************/
  2713. /* IOleInPlaceSiteEx Implementation */
  2714. /*************************************************************************/
  2715. /*************************************************************************/
  2716. /* Function: CanWindowlessActivate */
  2717. /* Description: Return if we can windowless activate or not. */
  2718. /*************************************************************************/
  2719. STDMETHODIMP CMFBar::CanWindowlessActivate(){
  2720. return m_bCanWindowlessActivate ? S_OK : S_FALSE;
  2721. }/* end of function CanWindowlessActivate */
  2722. /*************************************************************************/
  2723. /* Function: GetDC */
  2724. /* Description: Gets a DC to draw with. */
  2725. /*************************************************************************/
  2726. STDMETHODIMP CMFBar::GetDC(LPCRECT pRect, DWORD grfFlags, HDC* phDC){
  2727. HRESULT hr = S_OK;
  2728. if(m_bWndLess){
  2729. hr = m_spInPlaceSite->GetDC(pRect, grfFlags, phDC);
  2730. }
  2731. else {
  2732. if(NULL == m_hWnd){
  2733. hr = E_FAIL;
  2734. return(hr);
  2735. }/* end of if statement */
  2736. if(::IsWindow(m_hWnd)){
  2737. *phDC = ::GetDC(m_hWnd);
  2738. }
  2739. else {
  2740. hr = E_UNEXPECTED;
  2741. }/* end of if statement */
  2742. }/* end of if statement */
  2743. return(hr);
  2744. }/* end of function GetDC */
  2745. /*************************************************************************/
  2746. /* Function: ReleaseDC */
  2747. /* Description: Releases the DC */
  2748. /*************************************************************************/
  2749. STDMETHODIMP CMFBar::ReleaseDC(HDC hDC){
  2750. HRESULT hr = S_OK;
  2751. if(m_bWndLess){
  2752. hr = m_spInPlaceSite->ReleaseDC(hDC);
  2753. }
  2754. else {
  2755. if(NULL == m_hWnd){
  2756. hr = E_FAIL;
  2757. return(hr);
  2758. }/* end of if statement */
  2759. if(::IsWindow(m_hWnd)){
  2760. ::ReleaseDC(m_hWnd, hDC);
  2761. }
  2762. else {
  2763. hr = E_UNEXPECTED;
  2764. }/* end of if statement */
  2765. }/* end of if statement */
  2766. return(hr);
  2767. }/* end of function ReleaseDC */
  2768. /*************************************************************************/
  2769. /* Function: OnDefWindowMessage */
  2770. /* Description: Sends on messages to the default window procedure. */
  2771. /*************************************************************************/
  2772. STDMETHODIMP CMFBar::OnDefWindowMessage(UINT msg, WPARAM wParam,
  2773. LPARAM lParam, LRESULT* plResult){
  2774. *plResult = DefWindowProc(msg, wParam, lParam);
  2775. return S_OK;
  2776. }/* end of function OnDefWindowMessage */
  2777. /*************************************************************************/
  2778. /* Function: InvalidateRgn */
  2779. /* Description: Invalidates the whole rect in case we need to repaint it.*/
  2780. /*************************************************************************/
  2781. STDMETHODIMP CMFBar::InvalidateRgn(HRGN hRGN, BOOL fErase){
  2782. HRESULT hr = S_OK;
  2783. #if 0
  2784. if (!hRGN) {
  2785. RECT rc;
  2786. GetClientRect(&rc);
  2787. hRGN = ::CreateRectRgn( rc.left, rc.top, rc.right, rc.bottom);
  2788. }
  2789. HRGN newRgn = ::CreateRectRgn(0, 0, 10, 10);
  2790. ::CombineRgn(newRgn, hRGN, NULL, RGN_COPY) ;
  2791. CNTOBJ::iterator i;
  2792. for(i = m_cntObj.begin(); i!= m_cntObj.end(); i++){
  2793. CHostedObject* pObj = (*i);
  2794. ATLASSERT(pObj);
  2795. if(m_fSelfHosted && (GetUnknown() == pObj->GetUnknown())){
  2796. continue; // that is us we close our self later after the contained objects
  2797. }/* end of if statement */
  2798. if (!pObj->IsWindowless() && pObj->IsActive()) {
  2799. LONG x1, y1, w, h;
  2800. GetObjectPosition(pObj->GetID(), &x1, &y1, &w, &h);
  2801. HRGN objRgn = ::CreateRectRgn( x1, y1, x1+w, y1+h );
  2802. ::CombineRgn(newRgn, newRgn, objRgn, RGN_DIFF);
  2803. //ATLTRACE(TEXT("Excluding Rgn %d %d %d %d\n"), x1, y1, x1+w, y1+h);
  2804. }
  2805. }/* end of for loop */
  2806. hRGN = newRgn;
  2807. #endif
  2808. if(m_bWndLess){
  2809. hr = m_spInPlaceSite->InvalidateRgn(hRGN ,fErase);
  2810. }
  2811. else {
  2812. if(NULL == m_hWnd){
  2813. hr = E_FAIL;
  2814. return(hr);
  2815. }/* end of if statement */
  2816. if(::IsWindow(m_hWnd)){
  2817. ::InvalidateRgn(m_hWnd, hRGN, fErase); // see if we can get by by not erasing..
  2818. }
  2819. else {
  2820. hr = E_UNEXPECTED;
  2821. }/* end of if statement */
  2822. }/* end of if statement */
  2823. return(hr);
  2824. }/* end of function InvalidateRgn */
  2825. /*************************************************************************/
  2826. /* Function: InvalidateRect */
  2827. /* Description: Invalidates the rect, handles if we are windowless */
  2828. /*************************************************************************/
  2829. STDMETHODIMP CMFBar::InvalidateRect(LPCRECT pRect, BOOL fErase){
  2830. HRESULT hr = S_OK;
  2831. if(m_bWndLess){
  2832. hr = m_spInPlaceSite->InvalidateRect(pRect, fErase);
  2833. }
  2834. else {
  2835. if(NULL == m_hWnd){
  2836. hr = E_FAIL;
  2837. return(hr);
  2838. }/* end of if statement */
  2839. if(::IsWindow(m_hWnd)){
  2840. ::InvalidateRect(m_hWnd, pRect, fErase);
  2841. }
  2842. else {
  2843. hr = E_UNEXPECTED;
  2844. }/* end of if statement */
  2845. }/* end of if statement */
  2846. return(hr);
  2847. }/* end of function InvalidateRect */
  2848. /*************************************************************************/
  2849. /* Function: GetCapture */
  2850. /* Description: Used to determine if we have a cupature or not */
  2851. /*************************************************************************/
  2852. STDMETHODIMP CMFBar::GetCapture(){
  2853. HRESULT hr = S_OK;
  2854. if(m_bWndLess){
  2855. hr = m_spInPlaceSite->GetCapture();
  2856. }
  2857. else {
  2858. if(NULL == m_hWnd){
  2859. hr = E_FAIL;
  2860. return(hr);
  2861. }/* end of if statement */
  2862. if(::IsWindow(m_hWnd)){
  2863. hr = ::GetCapture() == m_hWnd ? S_OK : S_FALSE;
  2864. }/* end of if statement */
  2865. }/* end of if statement */
  2866. return(hr);
  2867. }/* end of function GetCapture */
  2868. /*************************************************************************/
  2869. /* Function: SetCapture */
  2870. /* Description: Used to set the capture for mouse events */
  2871. /* Only one container at the time can have a capture. */
  2872. /*************************************************************************/
  2873. STDMETHODIMP CMFBar::SetCapture(BOOL fCapture){
  2874. HRESULT hr = S_OK;
  2875. // whatever we we are doing we need to reset the capture flags on all the object
  2876. // after this call is finished the specific site will set appropriate flag
  2877. ResetCaptureFlags();
  2878. if(fCapture){
  2879. ATLTRACE2(atlTraceUser, 31, TEXT("Setting Mouse Capture in the container \n"));
  2880. }
  2881. else {
  2882. ATLTRACE2(atlTraceUser, 31, TEXT("Resetting Mouse Capture in the container\n"));
  2883. }/* end of if statement */
  2884. if(m_bWndLess){
  2885. if (fCapture){
  2886. hr = m_spInPlaceSite->SetCapture(TRUE);
  2887. }
  2888. else {
  2889. hr = m_spInPlaceSite->SetCapture(FALSE);
  2890. }/* end of if statement */
  2891. }
  2892. else {
  2893. if(NULL == m_hWnd){
  2894. hr = E_FAIL;
  2895. return(hr);
  2896. }/* end of if statement */
  2897. if(::IsWindow(m_hWnd)){
  2898. if (fCapture){
  2899. // do not have a capture, so set it
  2900. ::SetCapture(m_hWnd);
  2901. }
  2902. else{
  2903. // nobody more has a capture, so let it go
  2904. ::ReleaseCapture();
  2905. }/* end of if statement */
  2906. }
  2907. else {
  2908. hr = E_UNEXPECTED;
  2909. }/* end of if statement */
  2910. }/* end of if statement */
  2911. return(hr);
  2912. }/* end of function SetCapture */
  2913. /*************************************************************************/
  2914. /* Function: ResetCaptureFlags */
  2915. /* Description: Resets the capture on contained objects. */
  2916. /*************************************************************************/
  2917. HRESULT CMFBar::ResetCaptureFlags(){
  2918. for(CNTOBJ::iterator i = m_cntObj.begin(); i!= m_cntObj.end(); i++){
  2919. // iterate through all the contained objects and draw them
  2920. CHostedObject* pObj = (*i);
  2921. pObj->SetCapture(false);
  2922. }/* end of for function */
  2923. return(S_OK);
  2924. }/* end of function ResetCaptureFlags */
  2925. /*************************************************************************/
  2926. /* Function: ResetFocusFlags */
  2927. /* Description: Resets the capture on contained objects. */
  2928. /*************************************************************************/
  2929. HRESULT CMFBar::ResetFocusFlags(){
  2930. for(CNTOBJ::iterator i = m_cntObj.begin(); i!= m_cntObj.end(); i++){
  2931. // iterate through all the contained objects and draw them
  2932. CHostedObject* pObj = (*i);
  2933. if(pObj->HasFocus()){
  2934. LONG lRes;
  2935. SetObjectFocus(pObj, FALSE, lRes);
  2936. }/* end of if statement */
  2937. }/* end of for function */
  2938. return(S_OK);
  2939. }/* end of function ResetFocusFlags */
  2940. /*************************************************************************/
  2941. /* Function: EnumObjects */
  2942. /* Description: Returns IEnumUnknown */
  2943. /*************************************************************************/
  2944. STDMETHODIMP CMFBar::EnumObjects(DWORD /*grfFlags*/, IEnumUnknown** ppenum){
  2945. if (ppenum == NULL)
  2946. return E_POINTER;
  2947. *ppenum = NULL;
  2948. // TODO: handle flags
  2949. if(m_cntObj.empty() == true){
  2950. return E_FAIL;
  2951. }/* end of if statement */
  2952. typedef CComObject<CComEnum<IEnumUnknown, &IID_IEnumUnknown, IUnknown*, _CopyInterface<IUnknown> > > enumunk;
  2953. enumunk* p = NULL;
  2954. ATLTRY(p = new enumunk);
  2955. if(p == NULL)
  2956. return E_OUTOFMEMORY;
  2957. // create an array to which we put our *IUnknowns
  2958. INT iSize = m_cntObj.size();
  2959. IUnknown** pArray = new IUnknown* [iSize];
  2960. if(pArray == NULL)
  2961. return E_OUTOFMEMORY;
  2962. bool bFirstElement = true;
  2963. CNTOBJ::iterator i;
  2964. INT iCount = 0;
  2965. for(i = m_cntObj.begin(); i!= m_cntObj.end(); i++){
  2966. // move the interfaces to the array
  2967. CHostedObject* pObj = (*i);
  2968. pArray[iCount] = pObj->GetUnknown();
  2969. iCount++;
  2970. }/* end of for loop */
  2971. HRESULT hRes = p->Init(pArray, pArray + iSize, GetUnknown(), AtlFlagCopy);
  2972. if (SUCCEEDED(hRes))
  2973. hRes = p->QueryInterface(IID_IEnumUnknown, (void**)ppenum);
  2974. if (FAILED(hRes))
  2975. delete p;
  2976. delete[] pArray;
  2977. return hRes;
  2978. }/* end of function EnumObjects */
  2979. /*************************************************************************/
  2980. /* Function: SendMessageToCtl */
  2981. /* Description: Forwards message to a control */
  2982. /*************************************************************************/
  2983. HRESULT CMFBar::SendMessageToCtl(CHostedObject* pObj,
  2984. UINT uMsg, WPARAM wParam, LPARAM lParam,
  2985. BOOL& bHandled, LONG& lRes, bool fWndwlsOnly){
  2986. HRESULT hr = S_OK;
  2987. if(NULL == pObj){
  2988. hr = E_UNEXPECTED;
  2989. return(hr);
  2990. }/* end of if statement */
  2991. if(fWndwlsOnly && (!pObj->IsWindowless())){
  2992. ATLTRACE2(atlTraceUser, 31, TEXT("NOT SENDING message to control %ls !!!\n"), pObj->GetID());
  2993. hr = E_FAIL;
  2994. return(hr);
  2995. }/* end of if statement */
  2996. if(!pObj->IsActive()){
  2997. ATLTRACE2(atlTraceUser, 31, TEXT("NOT SENDING message to control %ls !!!\n"), pObj->GetID());
  2998. hr = E_FAIL;
  2999. return(hr);
  3000. }/* end of if statement */
  3001. CComPtr<IUnknown> pUnk = pObj->GetUnknown();
  3002. if(!pUnk){
  3003. ATLASSERT(FALSE); // should not be null
  3004. return(E_FAIL);
  3005. }/* end of if statement */
  3006. CComQIPtr<IOleInPlaceObjectWindowless> spInPlaceObjectWindowless(pUnk);
  3007. if(spInPlaceObjectWindowless){
  3008. // more then one control can have have a capture
  3009. LRESULT lRes64;
  3010. spInPlaceObjectWindowless->OnWindowMessage(uMsg, wParam, lParam, &lRes64);
  3011. //BUGBUG: Just to get this compiling for now. Will overhaul all
  3012. //datatypes later for 64-bit compatibility
  3013. lRes = (LONG)lRes64;
  3014. bHandled = TRUE;
  3015. }/* end of if statement */
  3016. return(hr);
  3017. }/* end of function SendMessageToCtl */
  3018. /*************************************************************************/
  3019. /* Function: GetFocus */
  3020. /* Description: Determine if we have a focus or not. */
  3021. /*************************************************************************/
  3022. STDMETHODIMP CMFBar::GetFocus(){
  3023. HRESULT hr = S_OK;
  3024. if(m_bWndLess){
  3025. hr = m_spInPlaceSite->GetFocus();
  3026. }
  3027. else {
  3028. if(NULL == m_hWnd){
  3029. hr = E_FAIL;
  3030. return(hr);
  3031. }/* end of if statement */
  3032. if(::IsWindow(m_hWnd)){
  3033. hr = ::GetFocus() == m_hWnd ? S_OK : S_FALSE;
  3034. }/* end of if statement */
  3035. }/* end of if statement */
  3036. return(hr);
  3037. }/* end of function GetFocus */
  3038. /*************************************************************************/
  3039. /* Function: SetFocus */
  3040. /* Description: Sets focus to the control */
  3041. /*************************************************************************/
  3042. STDMETHODIMP CMFBar::SetFocus(BOOL fFocus){
  3043. HRESULT hr = S_OK;
  3044. // we reset the flags depending on WM_SET and WM_KILL focus messages
  3045. if(fFocus){
  3046. ATLTRACE2(atlTraceUser, 31, TEXT("Setting Mouse Focus in the container \n"));
  3047. }
  3048. else {
  3049. ATLTRACE2(atlTraceUser, 31, TEXT("Resetting Mouse Focus in the container\n"));
  3050. }/* end of if statement */
  3051. if(m_bWndLess){
  3052. if (fFocus){
  3053. hr = m_spInPlaceSite->SetFocus(TRUE);
  3054. }
  3055. else {
  3056. hr = m_spInPlaceSite->SetFocus(FALSE);
  3057. }/* end of if statement */
  3058. }
  3059. else {
  3060. if(NULL == m_hWnd){
  3061. hr = E_FAIL;
  3062. return(hr);
  3063. }/* end of if statement */
  3064. if(::IsWindow(m_hWnd)){
  3065. if (fFocus){
  3066. ::SetFocus(m_hWnd);
  3067. }
  3068. else {
  3069. // else could call ::SetFocus(NULL), but that does not seem like a good solution
  3070. // so instead reset the focus on contained conrols
  3071. // which is risky too, since some control could try to call SetFocus(false)
  3072. // when it does not have the focus, but that is handled in the caller
  3073. //ResetFocusFlags();
  3074. }/* end of if statement */
  3075. }/* end of if statement */
  3076. else {
  3077. hr = E_UNEXPECTED;
  3078. }/* end of if statement */
  3079. }/* end of if statement */
  3080. return(hr);
  3081. }/* end of function SetFocus */
  3082. /*************************************************************************/
  3083. /* Function: get_ActivityTimeOut */
  3084. /* Description: Gets the currrent timout value. */
  3085. /*************************************************************************/
  3086. STDMETHODIMP CMFBar::get_ActivityTimeout(long *plTimeout){
  3087. *plTimeout = m_lTimeout;
  3088. return(S_OK);
  3089. }/* end of function get_ActivityTimeOut */
  3090. /*************************************************************************/
  3091. /* Function: put_ActivityTimeOut */
  3092. /* Description: Creates a new timer if needed. */
  3093. /*************************************************************************/
  3094. STDMETHODIMP CMFBar::put_ActivityTimeout(long lTimeout){
  3095. if(lTimeout < 0){
  3096. return(E_INVALIDARG);
  3097. }/* end of if statement */
  3098. if(!::IsWindow(m_hWnd)){
  3099. return(E_FAIL);
  3100. }/* end of if statement */
  3101. if(m_lTimeout != 0 || 0 == lTimeout ){
  3102. // kill it each time we set a new timer
  3103. ::KillTimer(m_hWnd, ID_EV_TIMER);
  3104. }
  3105. else {
  3106. if(0 == ::SetTimer(m_hWnd, ID_EV_TIMER, lTimeout, NULL)){
  3107. return(E_FAIL);
  3108. }/* end of if statement */
  3109. }/* end of if statement */
  3110. m_lTimeout = lTimeout;
  3111. m_fUserActivity = false;
  3112. m_fWaitingForActivity = false;
  3113. return(S_OK);
  3114. }/* end of function put_ActivityTimeOut */
  3115. /*************************************************************************/
  3116. /* Function: SetObjectExtent */
  3117. /* Description: Sets specific object witdth and height. */
  3118. /*************************************************************************/
  3119. STDMETHODIMP CMFBar::SetObjectExtent(BSTR strObjectID, long lWidth, long lHeight){
  3120. HRESULT hr = E_FAIL;
  3121. if(NULL == strObjectID){
  3122. hr = E_POINTER;
  3123. return(hr);
  3124. }/* end of if sattement */
  3125. bool bFirstElement = true;
  3126. CNTOBJ::iterator i;
  3127. for(i = m_cntObj.begin(); i!= m_cntObj.end(); i++){
  3128. CHostedObject* pObj = (*i);
  3129. if(!_wcsicmp(pObj->GetID(), strObjectID)){
  3130. RECT rcOld;
  3131. hr = pObj->GetPos(&rcOld);
  3132. if(FAILED(hr)){
  3133. return(hr);
  3134. }/* end of if statement */
  3135. RECT rcNew;
  3136. rcNew.left = rcOld.left; rcNew.top = rcOld.top;
  3137. rcNew.right = rcNew.left + lWidth; rcNew.bottom = rcNew.top + lHeight;
  3138. if(::EqualRect(&rcOld, &rcNew)){
  3139. hr = S_FALSE; // no point to monkey around if the rects are the same
  3140. return(hr);
  3141. }/* end of if statement */
  3142. // Set the objects new position
  3143. hr = pObj->SetRawPos(&rcNew);
  3144. if(FAILED(hr)){
  3145. return(hr);
  3146. }/* end of if statement */
  3147. // Set the objects new position
  3148. hr = pObj->SetRawPos(&rcNew);
  3149. if(FAILED(hr)){
  3150. return(hr);
  3151. }/* end of if statement */
  3152. if(pObj->IsWindowless()){
  3153. hr = pObj->SetObjectRects();
  3154. }
  3155. else {
  3156. hr = pObj->SetObjectRects(&rcNew);
  3157. }/* end of if statement */
  3158. if(FAILED(hr)){
  3159. return(hr);
  3160. }/* end of if statement */
  3161. RECT rcUnion;
  3162. ::UnionRect(&rcUnion, &rcOld, &rcNew);
  3163. if (pObj->IsWindowless())
  3164. hr = InvalidateRect(&rcUnion, FALSE);
  3165. break; // already have set the state and invalidated and bail out
  3166. }/* end of if statement */
  3167. }/* end of for loop */
  3168. return (hr);
  3169. }/* end of function SetObjectExtent */
  3170. /*************************************************************************/
  3171. /* Function: SetObjectPosition */
  3172. /* Description: Sets specific object position. Looks up object by object */
  3173. /* ID. Sets also extents. */
  3174. /*************************************************************************/
  3175. STDMETHODIMP CMFBar::SetObjectPosition(BSTR strObjectID, long xPos,
  3176. long yPos, long lWidth, long lHeight){
  3177. HRESULT hr = E_FAIL;
  3178. if(NULL == strObjectID){
  3179. hr = E_POINTER;
  3180. return(hr);
  3181. }/* end of if sattement */
  3182. RECT rcNew;
  3183. rcNew.left = xPos; rcNew.top = yPos;
  3184. rcNew.right = rcNew.left + lWidth; rcNew.bottom = rcNew.top + lHeight;
  3185. bool bFirstElement = true;
  3186. CNTOBJ::iterator i;
  3187. for(i = m_cntObj.begin(); i!= m_cntObj.end(); i++){
  3188. CHostedObject* pObj = (*i);
  3189. if(!_wcsicmp(pObj->GetID(), strObjectID)){
  3190. RECT rcOld;
  3191. hr = pObj->GetPos(&rcOld);
  3192. if(FAILED(hr)){
  3193. return(hr);
  3194. }/* end of if statement */
  3195. if(::EqualRect(&rcOld, &rcNew)){
  3196. hr = S_FALSE; // no point to monkey around if the rects are the same
  3197. return(hr);
  3198. }/* end of if statement */
  3199. // Set the objects new position
  3200. hr = pObj->SetRawPos(&rcNew);
  3201. if(FAILED(hr)){
  3202. return(hr);
  3203. }/* end of if statement */
  3204. if(pObj->IsWindowless()){
  3205. hr = pObj->SetObjectRects();
  3206. }
  3207. else {
  3208. hr = pObj->SetObjectRects(&rcNew);
  3209. }/* end of if statement */
  3210. if(FAILED(hr)){
  3211. return(hr);
  3212. }/* end of if statement */
  3213. RECT rcUnion;
  3214. ::UnionRect(&rcUnion, &rcOld, &rcNew);
  3215. if (pObj->IsWindowless())
  3216. hr = InvalidateRect(&rcUnion, FALSE);
  3217. break; // already have set the state and invalidated and bail out
  3218. }/* end of if statement */
  3219. }/* end of for loop */
  3220. return (hr);
  3221. }/* end of function SetObjectPosition */
  3222. /*************************************************************************/
  3223. /* Function: GetObjectPosition */
  3224. /* Description: SetObjectPosition */
  3225. /*************************************************************************/
  3226. STDMETHODIMP CMFBar::GetObjectPosition(BSTR strObjectID, long* pxPos, long* pyPos, long* plWidth, long* plHeight){
  3227. HRESULT hr = E_FAIL;
  3228. if(NULL == strObjectID){
  3229. hr = E_POINTER;
  3230. return(hr);
  3231. }/* end of if sattement */
  3232. if(NULL == pxPos || NULL == pyPos || NULL == plWidth || NULL == plHeight){
  3233. return(E_POINTER);
  3234. }/* end of if statement */
  3235. *pxPos = *pyPos = *plWidth = *plHeight = 0;
  3236. bool bFirstElement = true;
  3237. CNTOBJ::iterator i;
  3238. for(i = m_cntObj.begin(); i!= m_cntObj.end(); i++){
  3239. if(!_wcsicmp((*i)->GetID(), strObjectID)){
  3240. CHostedObject* pObj = (*i);
  3241. // Set the objects new position
  3242. RECT rc;
  3243. hr = pObj->GetPos(&rc);
  3244. if(SUCCEEDED(hr)){
  3245. *pxPos = rc.left; *pyPos = rc.top; *plWidth = RECTWIDTH(&rc); *plHeight = RECTHEIGHT(&rc);
  3246. }/* end of if statement */
  3247. break; // already have set the state and invalidated and bail out
  3248. }/* end of if statement */
  3249. }/* end of for loop */
  3250. return (hr);
  3251. }/* end function GetObjectPosition */
  3252. /*************************************************************************/
  3253. /* Function: WinHelp */
  3254. /* Description: Called by the script to execute specific help topic. */
  3255. /*************************************************************************/
  3256. STDMETHODIMP CMFBar::WinHelp(long lCommand, long dwData, BSTR strHelpFile){
  3257. HRESULT hr = S_OK;
  3258. try {
  3259. HWND h = NULL;
  3260. hr = GetWindow(&h);
  3261. if(FAILED(hr)){
  3262. throw(hr);
  3263. }/* end of if statement */
  3264. USES_CONVERSION;
  3265. BOOL bResult = ::WinHelp(h, OLE2T(strHelpFile), lCommand, dwData);
  3266. if(!bResult){
  3267. // failed so lets try to get some more meaningful result
  3268. hr = HRESULT_FROM_WIN32(::GetLastError());
  3269. }/* end of if statement */
  3270. }/* end of try statement */
  3271. catch(HRESULT hrTmp){
  3272. hr = hrTmp;
  3273. }
  3274. catch(...){
  3275. hr = E_UNEXPECTED;
  3276. }/* end of catch statement */
  3277. return (hr);
  3278. }/* end of function WinHelp */
  3279. /*************************************************************************/
  3280. /* Function: MessageBox */
  3281. /* Description: Displays the message box using specified parameters. */
  3282. /*************************************************************************/
  3283. STDMETHODIMP CMFBar::MessageBox(BSTR strText, BSTR strCaption, long lType){
  3284. HRESULT hr = S_OK;
  3285. try {
  3286. USES_CONVERSION;
  3287. HWND hWnd = NULL;
  3288. HRESULT hr = GetWindow(&hWnd);
  3289. if(FAILED(hr)){
  3290. ATLASSERT(FALSE);
  3291. throw(hr);
  3292. }/* end of if statement */
  3293. ::MessageBox(hWnd, OLE2T(strText), OLE2T(strCaption), lType);
  3294. }
  3295. catch(HRESULT hrTmp){
  3296. hr = hrTmp;
  3297. }
  3298. catch(...){
  3299. hr = E_UNEXPECTED;
  3300. }
  3301. return S_OK;
  3302. }/* end of function MessageBox */
  3303. /*************************************************************************/
  3304. /* Function: GetToolbarName */
  3305. /* Description: Gets and allocates the toolbar name. */
  3306. /*************************************************************************/
  3307. HRESULT CMFBar::GetToolbarName(BSTR* strToolbarName){
  3308. HRESULT hr = S_OK;
  3309. if(NULL == strToolbarName){
  3310. hr = E_POINTER;
  3311. return(hr);
  3312. }/* end of if statement */
  3313. const INT ciMaxBuffSize = MAX_PATH; // should be enough for tlbr ID, keep ID small if can
  3314. TCHAR strBuffer[ciMaxBuffSize];
  3315. if(!::LoadString(m_hRes, IDS_ROOT_OBJECT, strBuffer, ciMaxBuffSize)){
  3316. hr = E_FAIL;
  3317. return(E_FAIL);
  3318. }/* end of if statement */
  3319. #ifdef _UNICODE
  3320. *strToolbarName = ::SysAllocString(strBuffer);
  3321. #else
  3322. USES_CONVERSION;
  3323. *strToolbarName = ::SysAllocString(T2OLE(strBuffer));
  3324. #endif
  3325. return(hr);
  3326. }/* end of function GetToolbarName */
  3327. /*************************************************************************/
  3328. /* Function: SetPriority */
  3329. /* Description: Sets the thread priority. */
  3330. /*************************************************************************/
  3331. STDMETHODIMP CMFBar::SetPriority(long lPriority){
  3332. HRESULT hr = S_OK;
  3333. try {
  3334. HANDLE hThread = ::GetCurrentThread();
  3335. if(!::SetThreadPriority(hThread, lPriority)){
  3336. hr = HRESULT_FROM_WIN32(::GetLastError());
  3337. throw (hr);
  3338. }/* end of if statement */
  3339. }
  3340. catch(HRESULT hrTmp){
  3341. hr = hrTmp;
  3342. }
  3343. catch(...){
  3344. hr = E_UNEXPECTED;
  3345. }/* end of catch statement */
  3346. return (hr);
  3347. }/* end of function SetPriority */
  3348. /*************************************************************************/
  3349. /* Function: SetPriorityClass */
  3350. /* Description: Sets the thread priority. */
  3351. /*************************************************************************/
  3352. STDMETHODIMP CMFBar::SetPriorityClass(long lPriority){
  3353. HRESULT hr = S_OK;
  3354. try {
  3355. HANDLE hThread = ::GetCurrentThread();
  3356. if(!::SetPriorityClass(hThread, lPriority)){
  3357. hr = HRESULT_FROM_WIN32(::GetLastError());
  3358. throw (hr);
  3359. }/* end of if statement */
  3360. }
  3361. catch(HRESULT hrTmp){
  3362. hr = hrTmp;
  3363. }
  3364. catch(...){
  3365. hr = E_UNEXPECTED;
  3366. }/* end of catch statement */
  3367. return (hr);
  3368. }/* end of function SetPriorityClass */
  3369. /*************************************************************************/
  3370. /* Function: get_BackgroundImage */
  3371. /* Description: Gets the backround image. */
  3372. /*************************************************************************/
  3373. STDMETHODIMP CMFBar::get_BackgroundImage(BSTR *pstrFilename){
  3374. *pstrFilename = m_bstrBackImageFilename.Copy();
  3375. return S_OK;
  3376. }/* end of function get_BackgroundImage */
  3377. /*************************************************************************/
  3378. /* Function: put_BackgroundImage */
  3379. /* Description: Attempts to load the background image. */
  3380. /*************************************************************************/
  3381. STDMETHODIMP CMFBar::put_BackgroundImage(BSTR strFilename){
  3382. USES_CONVERSION;
  3383. HRESULT hr = S_OK;
  3384. if(NULL != m_pBackBitmap){
  3385. delete m_pBackBitmap;
  3386. }/* end of if statement */
  3387. m_pBackBitmap = new CBitmap;
  3388. m_pBackBitmap->LoadPalette(true); // load the palette if available, since this
  3389. // is the palette we use for the rest
  3390. // of the contained objects
  3391. m_bstrBackImageFilename = strFilename;
  3392. TCHAR strBuffer[MAX_PATH] = TEXT("\0");
  3393. bool fGrayOut = false;
  3394. hr = m_pBackBitmap->PutImage(strFilename, m_hRes, GetUnknown(),fGrayOut ,m_blitType);
  3395. if(FAILED(hr)){
  3396. return(hr);
  3397. }/* end of if statement */
  3398. // we are updating image that is being used, refresh it
  3399. ATLTRACE2(atlTraceWindowing, 20, TEXT("Redrawing the image\n"));
  3400. InvalidateRgn(); // our helper function
  3401. return(hr);
  3402. }/* end of function put_BackgroundImage */
  3403. /*************************************************************************/
  3404. /* Function: SetReadyState */
  3405. /* Description: Sets ready state and fires event if it needs to be fired */
  3406. /*************************************************************************/
  3407. HRESULT CMFBar::SetReadyState(LONG lReadyState){
  3408. HRESULT hr = S_OK;
  3409. bool bFireEvent = (lReadyState != m_nReadyState);
  3410. #ifdef _DEBUG
  3411. if(m_nFreezeEvents > 0){
  3412. ::Sleep(10);
  3413. ATLTRACE("Container not expecting events at the moment");
  3414. }/* end of is statement */
  3415. #endif
  3416. if(bFireEvent){
  3417. put_ReadyState(lReadyState);
  3418. Fire_ReadyStateChange(lReadyState);
  3419. }
  3420. else {
  3421. // set the variable
  3422. m_nReadyState = lReadyState;
  3423. }/* end of if statement */
  3424. return(hr);
  3425. }/* end of function SetReadyState */
  3426. /*************************************************************************/
  3427. /* Function: OnPostVerbInPlaceActivate */
  3428. /* Description: Creates the in place active object. */
  3429. /*************************************************************************/
  3430. HRESULT CMFBar::OnPostVerbInPlaceActivate(){
  3431. SetReadyState(READYSTATE_COMPLETE);
  3432. return(S_OK);
  3433. }/* end of function OnPostVerbInPlaceActivate */
  3434. /*************************************************************************/
  3435. /* Function: get_AutoLoad */
  3436. /*************************************************************************/
  3437. STDMETHODIMP CMFBar::get_AutoLoad(VARIANT_BOOL *pVal){
  3438. *pVal = m_fAutoLoad;
  3439. return S_OK;
  3440. }/* end of function get_AutoLoad */
  3441. /*************************************************************************/
  3442. /* Function: put_AutoLoad */
  3443. /* Description: Sets the flag to autolaod the engine after we set a */
  3444. /* script file or not. */
  3445. /*************************************************************************/
  3446. STDMETHODIMP CMFBar::put_AutoLoad(VARIANT_BOOL newVal){
  3447. m_fAutoLoad = (VARIANT_FALSE == newVal ? VARIANT_FALSE : VARIANT_TRUE);
  3448. return S_OK;
  3449. }/* end of function put_AutoLoad */
  3450. /*************************************************************/
  3451. /* Name: SetRectRgn
  3452. /* Description: Set up a rectangular window update region
  3453. /*************************************************************/
  3454. STDMETHODIMP CMFBar::SetRectRgn(long x1, long y1, long x2, long y2)
  3455. {
  3456. HRGN hRgn = ::CreateRectRgn( x1, y1, x2, y2 );
  3457. ::SetWindowRgn(m_hWnd, hRgn, TRUE);
  3458. return S_OK;
  3459. }
  3460. /*************************************************************/
  3461. /* Name: SetRoundRectRgn
  3462. /* Description: Set up a round corner window update region
  3463. /*************************************************************/
  3464. STDMETHODIMP CMFBar::SetRoundRectRgn(long x1, long y1, long x2, long y2, long width, long height){
  3465. HRGN hRgn = ::CreateRoundRectRgn(x1, y1, x2, y2, width, height);
  3466. ::SetWindowRgn(m_hWnd, hRgn, TRUE);
  3467. return S_OK;
  3468. }/* end of function SetRoundRectRgn */
  3469. /*************************************************************/
  3470. /* Function: SetTimeout */
  3471. /* Description: Creates a timer and then calls events when */
  3472. /* timer proc gets called. */
  3473. /*************************************************************/
  3474. STDMETHODIMP CMFBar::SetTimeout(long lTimeout, long lId){
  3475. if(lTimeout < 0){
  3476. return(E_INVALIDARG);
  3477. }/* end of if statement */
  3478. if(!::IsWindow(m_hWnd)){
  3479. return(E_FAIL);
  3480. }/* end of if statement */
  3481. if(ID_EV_TIMER == lId){
  3482. return(E_INVALIDARG);
  3483. }/* end of if statement */
  3484. if(lTimeout == 0){
  3485. ::KillTimer(m_hWnd, lId);
  3486. }
  3487. else{
  3488. if(0 != lTimeout){
  3489. if(0 == ::SetTimer(m_hWnd, lId, lTimeout, NULL)){
  3490. return(E_FAIL);
  3491. }/* end of if statement */
  3492. }/* end of if statement */
  3493. }/* end of if statement */
  3494. return S_OK;
  3495. }/* end of function SetTimeout */
  3496. /*************************************************************/
  3497. /* Function: Sleep */
  3498. /*************************************************************/
  3499. STDMETHODIMP CMFBar::Sleep(long lMiliseconds){
  3500. ::Sleep(lMiliseconds);
  3501. return S_OK;
  3502. }/* end of function Sleep */
  3503. /*************************************************************/
  3504. /* Name: OnButtonDown
  3505. /* Description: Handles WM_MOUSEDOWN
  3506. /*************************************************************/
  3507. LRESULT CMFBar::OnButtonDown(UINT, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  3508. {
  3509. if(::IsWindow(m_hWnd)){
  3510. m_ptMouse.x = GET_X_LPARAM(lParam);
  3511. m_ptMouse.y = GET_Y_LPARAM(lParam);
  3512. ::ClientToScreen(m_hWnd, &m_ptMouse);
  3513. ::SetCapture(m_hWnd);
  3514. SetFocus(TRUE);
  3515. ATLTRACE(TEXT("Button down, starting to track\n"));
  3516. m_bMouseDown = TRUE;
  3517. // Test for resize hit region
  3518. ::GetWindowRect(m_hWnd, &m_rcWnd);
  3519. m_HitRegion = ResizeHitRegion(m_ptMouse);
  3520. UpdateCursor(m_HitRegion);
  3521. }/* end of if statement */
  3522. return 0;
  3523. }
  3524. /*************************************************************/
  3525. /* Name: OnButtonUp
  3526. /* Description: Handles WM_MOUSEUP
  3527. /*************************************************************/
  3528. LRESULT CMFBar::OnButtonUp(UINT, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  3529. {
  3530. if(::IsWindow(m_hWnd)){
  3531. ::ReleaseCapture();
  3532. ATLTRACE(TEXT("Done tracking the window\n"));
  3533. m_bMouseDown = false;
  3534. m_HitRegion = ResizeHitRegion(m_ptMouse);
  3535. UpdateCursor(m_HitRegion);
  3536. }/* end of if statement */
  3537. return 0;
  3538. }
  3539. /*************************************************************/
  3540. /* Name: OnMouseMove
  3541. /* Description: Handles WM_MOUSEMOVE
  3542. /*************************************************************/
  3543. LRESULT CMFBar::OnMouseMove(UINT, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  3544. {
  3545. if(::IsWindow(m_hWnd)){
  3546. ::GetWindowRect(m_hWnd, &m_rcWnd);
  3547. POINT ptMouse;
  3548. ptMouse.x = GET_X_LPARAM(lParam);
  3549. ptMouse.y = GET_Y_LPARAM(lParam);
  3550. ::ClientToScreen(m_hWnd, &ptMouse);
  3551. // Test for resize hit region
  3552. int hitRegion = ResizeHitRegion(ptMouse);
  3553. if (!m_bMouseDown)
  3554. UpdateCursor(hitRegion);
  3555. // No mouse movement, return
  3556. long xAdjustment = m_ptMouse.x - ptMouse.x;
  3557. long yAdjustment = m_ptMouse.y - ptMouse.y;
  3558. if (xAdjustment == 0 && yAdjustment == 0)
  3559. return 0;
  3560. m_ptMouse = ptMouse;
  3561. // ATLTRACE(TEXT("Mouse pos: %d %d\n"), m_ptMouse.x, m_ptMouse.y);
  3562. if (m_HitRegion!=NOHIT && m_bMouseDown) {
  3563. long resizeX = m_rcWnd.left;
  3564. long resizeY = m_rcWnd.top;
  3565. long resizeW = RECTWIDTH(&m_rcWnd);
  3566. long resizeH = RECTHEIGHT(&m_rcWnd);
  3567. if (m_HitRegion & LEFT) {
  3568. if (m_rcWnd.right-ptMouse.x >= m_lMinWidth) {
  3569. resizeW = m_rcWnd.right-ptMouse.x;
  3570. resizeX = ptMouse.x;
  3571. }
  3572. else {
  3573. resizeW = m_lMinWidth;
  3574. resizeX = m_rcWnd.right-m_lMinWidth;
  3575. }
  3576. ATLTRACE(TEXT("m_rcWnd right %d\n"), m_rcWnd.right);
  3577. }
  3578. if (m_HitRegion & RIGHT) {
  3579. if (ptMouse.x-m_rcWnd.left >= m_lMinWidth) {
  3580. resizeW = ptMouse.x-m_rcWnd.left;
  3581. }
  3582. else {
  3583. resizeW = m_lMinWidth;
  3584. }
  3585. }
  3586. if (m_HitRegion & TOP) {
  3587. if (m_rcWnd.bottom-ptMouse.y >= m_lMinHeight) {
  3588. resizeH = m_rcWnd.bottom-ptMouse.y;
  3589. resizeY = ptMouse.y;
  3590. }
  3591. else {
  3592. resizeH = m_lMinHeight;
  3593. resizeY = m_rcWnd.bottom - m_lMinHeight;
  3594. }
  3595. }
  3596. if (m_HitRegion & BOTTOM) {
  3597. if (ptMouse.y-m_rcWnd.top >= m_lMinHeight) {
  3598. resizeH = ptMouse.y-m_rcWnd.top;
  3599. }
  3600. else {
  3601. resizeH = m_lMinHeight;
  3602. }
  3603. }
  3604. if (resizeW >= m_lMinWidth || resizeH >= m_lMinHeight) {
  3605. if(NULL != m_pBackBitmap){
  3606. m_pBackBitmap->DeleteMemDC();
  3607. }/* end of if statement */
  3608. ::MoveWindow(m_hWnd, resizeX, resizeY, resizeW, resizeH, TRUE);
  3609. ATLTRACE(TEXT("Resize window to: %d %d %d %d\n"), resizeX, resizeY, resizeX+resizeW, resizeY+resizeH);
  3610. }
  3611. }/* end of if statement */
  3612. else if(m_bMouseDown){
  3613. long x = m_rcWnd.left;
  3614. long y = m_rcWnd.top;
  3615. long width = RECTWIDTH(&m_rcWnd);
  3616. long height = RECTHEIGHT(&m_rcWnd);
  3617. ::MoveWindow(m_hWnd, x - xAdjustment, y - yAdjustment, width, height, TRUE);
  3618. ATLTRACE2(atlTraceWindowing, 32, TEXT("Moving the window\n"));
  3619. m_ptMouse = ptMouse;
  3620. }/* end of if statement */
  3621. }/* end of if statement */
  3622. return 0;
  3623. }
  3624. /*************************************************************/
  3625. /* Name: ResizeHitRegion */
  3626. /* Description: Test if mouse is in resize hit region */
  3627. /*************************************************************/
  3628. int CMFBar::ResizeHitRegion(POINT p){
  3629. // TODO: DO NOT HARDCODE THE REGION SIZES
  3630. int hitRegion = NOHIT;
  3631. if (abs(p.x-m_rcWnd.left)<=10) {
  3632. hitRegion |= LEFT;
  3633. }
  3634. else if (abs(p.x-m_rcWnd.right)<=10) {
  3635. hitRegion |= RIGHT;
  3636. }/* end of if statement */
  3637. if (abs(p.y-m_rcWnd.top)<=10) {
  3638. hitRegion |= TOP;
  3639. }
  3640. else if (abs(p.y-m_rcWnd.bottom)<=10) {
  3641. hitRegion |= BOTTOM;
  3642. }/* end of if statement */
  3643. return hitRegion;
  3644. }/* end of function ResizeHitRegion */
  3645. /*************************************************************/
  3646. /* Name: UpdateCursor */
  3647. /* Description: Change cursor shape to move arrows */
  3648. /*************************************************************/
  3649. HRESULT CMFBar::UpdateCursor(int hitRegion){
  3650. HCURSOR hCursor;
  3651. switch (hitRegion) {
  3652. case LEFT|NOHIT:
  3653. case RIGHT|NOHIT:
  3654. hCursor = ::LoadCursor(0, IDC_SIZEWE);
  3655. break;
  3656. case TOP|NOHIT:
  3657. case BOTTOM|NOHIT:
  3658. hCursor = ::LoadCursor(0, IDC_SIZENS);
  3659. break;
  3660. case LEFT|TOP|NOHIT:
  3661. case RIGHT|BOTTOM|NOHIT:
  3662. hCursor = ::LoadCursor(0, IDC_SIZENWSE);
  3663. break;
  3664. case RIGHT|TOP|NOHIT:
  3665. case LEFT|BOTTOM|NOHIT:
  3666. hCursor = ::LoadCursor(0, IDC_SIZENESW);
  3667. break;
  3668. default:
  3669. hCursor = ::LoadCursor(0, IDC_ARROW);
  3670. break;
  3671. }/* end of switch statement */
  3672. ::SetCursor(hCursor);
  3673. return S_OK;
  3674. }/* end of function UpdateCursor */
  3675. /*************************************************************************/
  3676. /* Function: SetObjectFocus */
  3677. /* Description: Sets or resets focus to specific object. */
  3678. /*************************************************************************/
  3679. STDMETHODIMP CMFBar::SetObjectFocus(BSTR strObjectID, VARIANT_BOOL fEnable){
  3680. HRESULT hr = S_OK;
  3681. try {
  3682. CHostedObject* pObj;
  3683. hr = FindObject(strObjectID, &pObj);
  3684. if(FAILED(hr)){
  3685. throw(hr);
  3686. }/* end of if statetement */
  3687. LONG lRes = 0;
  3688. hr = SetObjectFocus(pObj, VARIANT_FALSE == fEnable ? FALSE : TRUE, lRes);
  3689. if(FAILED(hr)){
  3690. throw(hr);
  3691. }/* end of if statement */
  3692. if(-1 == lRes){
  3693. throw(E_FAIL); // the control did not take the focus since it is disabled
  3694. }/* end of if statement */
  3695. }/* end of try statement */
  3696. catch(HRESULT hrTmp){
  3697. hr = hrTmp;
  3698. }
  3699. catch(...){
  3700. hr = E_UNEXPECTED;
  3701. }/* end of catch statement */
  3702. return(hr);
  3703. }/* end of function SetObjectFocus */
  3704. /*************************************************************************/
  3705. /* Function: HasObjectFocus */
  3706. /*************************************************************************/
  3707. STDMETHODIMP CMFBar::HasObjectFocus(BSTR strObjectID, VARIANT_BOOL* pfEnable){
  3708. HRESULT hr = S_OK;
  3709. try {
  3710. CHostedObject* pObj;
  3711. hr = FindObject(strObjectID, &pObj);
  3712. if(FAILED(hr)){
  3713. throw(hr);
  3714. }/* end of if statetement */
  3715. *pfEnable = pObj->HasFocus() ? VARIANT_TRUE : VARIANT_FALSE;
  3716. }/* end of try statement */
  3717. catch(HRESULT hrTmp){
  3718. hr = hrTmp;
  3719. }
  3720. catch(...){
  3721. hr = E_UNEXPECTED;
  3722. }/* end of catch statement */
  3723. return(hr);
  3724. }/* end of function HasObjectFocus */
  3725. /*************************************************************************/
  3726. /* Function: SetObjectFocus */
  3727. /* Description: Sets or resets focus to specific object. */
  3728. /*************************************************************************/
  3729. HRESULT CMFBar::SetObjectFocus(CHostedObject* pObj, BOOL fSet, LONG& lRes){
  3730. HRESULT hr = S_OK;
  3731. CContainerObject* pCnt;
  3732. hr = pObj->GetContainerObject(&pCnt);
  3733. if(FAILED(hr)){
  3734. return(hr);
  3735. }/* end of if statement */
  3736. LONG lParam = 0;
  3737. BOOL bHandled = FALSE;
  3738. if(fSet){
  3739. ResetFocusFlags(); // reset old focus on other control
  3740. pCnt->SetFocus(TRUE);
  3741. SendMessageToCtl(pObj, WM_SETFOCUS, (WPARAM) m_hWnd, lParam, bHandled, lRes, false);
  3742. ATLTRACE2(atlTraceUser, 31, TEXT("Sending WM_SETFOCUS to %ls \n"), pObj->GetID());
  3743. }
  3744. else {
  3745. pCnt->SetFocus(FALSE); // disable focus and caputure if we are disabeling the object
  3746. SendMessageToCtl(pObj, WM_KILLFOCUS, (WPARAM) m_hWnd, lParam, bHandled, lRes, false);
  3747. ATLTRACE2(atlTraceUser, 31, TEXT("Sending WM_KILLFOCUS to %ls \n"), pObj->GetID());
  3748. }/* end of if statement */
  3749. return(hr);
  3750. }/* end of function SetObjectFocus */
  3751. /*************************************************************************/
  3752. /* Function: FindObject */
  3753. /* Description: Itterates the objects till it finds the one with matching*/
  3754. /* ID. */
  3755. /*************************************************************************/
  3756. HRESULT CMFBar::FindObject(BSTR strObjectID, CHostedObject** ppObj){
  3757. HRESULT hr = E_FAIL; // did not find the object
  3758. *ppObj = NULL;
  3759. for(CNTOBJ::iterator i = m_cntObj.begin(); i!= m_cntObj.end(); i++){
  3760. CHostedObject* pObj = (*i);
  3761. if(NULL == pObj){
  3762. continue;
  3763. }/* end of if statement */
  3764. if(!_wcsicmp(pObj->GetID(), strObjectID)){
  3765. *ppObj = pObj; // set the pointer and bail out
  3766. hr = S_OK;
  3767. break; // got the unknown get out
  3768. }/* end of if statement */
  3769. }/* end of for loop */
  3770. return(hr);
  3771. }/* end of function FindObject */
  3772. /*************************************************************************/
  3773. /* End of file: MFBar.cpp */
  3774. /*************************************************************************/