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.

6869 lines
216 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. #include "HtmlHelp.h"
  14. /*************************************************************************/
  15. /* Local defines */
  16. /* Could not find these under windows headers, so if there is a conflict */
  17. /* it is good idea to ifdef these out. */
  18. /*************************************************************************/
  19. #define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp))
  20. #define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp))
  21. #define RECTWIDTH(lpRect) ((lpRect)->right - (lpRect)->left)
  22. #define RECTHEIGHT(lpRect) ((lpRect)->bottom - (lpRect)->top)
  23. #define ID_EV_TIMER 0xff
  24. #define VK_LEFT 0x25
  25. #define VK_UP 0x26
  26. #define VK_RIGHT 0x27
  27. #define VK_DOWN 0x28
  28. #define VK_SELECT 0x29
  29. #define VK_SPACE 0x20
  30. #define VK_RETURN 0x0D
  31. #define SYS_MOVE_SIZE 8
  32. #define SYS_TITLEBAR_WIDTH 25
  33. /*************************************************************************/
  34. /* Windows defines not present, remove when doing the real BUILD. */
  35. /*************************************************************************/
  36. typedef WINUSERAPI BOOL ( WINAPI * SETLAYEREDWINDATR)(
  37. HWND hwnd,
  38. COLORREF crKey,
  39. BYTE bAlpha,
  40. DWORD dwFlags);
  41. #if 0
  42. #define LWA_COLORKEY 0x00000001
  43. #endif
  44. /*************************************************************************/
  45. /* Local functions */
  46. /*************************************************************************/
  47. inline long MAX(long l1, long l2){return(l1 > l2 ? l1 : l2);}
  48. inline long MIN(long l1, long l2){return(l1 < l2 ? l1 : l2);}
  49. /*************************************************************************/
  50. /* Statics for window class info */
  51. /*************************************************************************/
  52. HICON CMFBar::m_hIcon = NULL;
  53. #if 0
  54. HICON CMFBar::m_hIconSmall = NULL;
  55. #endif
  56. /*****************************************************************/
  57. /* change this depending if the file was saved as Unicode or not */
  58. /*****************************************************************/
  59. #define _UNICODE_SCRIPT_FILE
  60. //#define _UNICODE_TEST_SCRIPT_FILE
  61. #if WINVER < 0x0500
  62. #define MNS_NOCHECK 0x80000000
  63. #define MNS_MODELESS 0x40000000
  64. #define MNS_DRAGDROP 0x20000000
  65. #define MNS_AUTODISMISS 0x10000000
  66. #define MNS_NOTIFYBYPOS 0x08000000
  67. #define MNS_CHECKORBMP 0x04000000
  68. #define MIM_MAXHEIGHT 0x00000001
  69. #define MIM_BACKGROUND 0x00000002
  70. #define MIM_HELPID 0x00000004
  71. #define MIM_MENUDATA 0x00000008
  72. #define MIM_STYLE 0x00000010
  73. #define MIM_APPLYTOSUBMENUS 0x80000000
  74. typedef struct tagMENUINFO
  75. {
  76. DWORD cbSize;
  77. DWORD fMask;
  78. DWORD dwStyle;
  79. UINT cyMax;
  80. HBRUSH hbrBack;
  81. DWORD dwContextHelpID;
  82. ULONG_PTR dwMenuData;
  83. } MENUINFO, FAR *LPMENUINFO;
  84. typedef MENUINFO CONST FAR *LPCMENUINFO;
  85. static BOOL (WINAPI *pfnGetMenuInfo)(HMENU, LPMENUINFO);
  86. static BOOL (WINAPI *pfnSetMenuInfo)(HMENU, LPCMENUINFO);
  87. typedef BOOL (WINAPI *PFNGETMENUINFOHANDLE)(HMENU, LPMENUINFO);
  88. typedef BOOL (WINAPI *PFNSETMENUINFOHANDLE)(HMENU, LPCMENUINFO);
  89. HRESULT CallGetMenuInfo(HMENU hMenu, LPMENUINFO pmInfo)
  90. {
  91. HRESULT hr = E_FAIL;
  92. HINSTANCE hinstDll = ::LoadLibrary(TEXT("USER32.DLL"));
  93. if (hinstDll)
  94. {
  95. pfnGetMenuInfo = (PFNGETMENUINFOHANDLE)GetProcAddress(hinstDll, "GetMenuInfo");
  96. if (pfnGetMenuInfo)
  97. {
  98. hr = pfnGetMenuInfo(hMenu, pmInfo);
  99. }
  100. FreeLibrary(hinstDll);
  101. }
  102. return hr;
  103. }
  104. HRESULT CallSetMenuInfo(HMENU hMenu, LPCMENUINFO pmInfo)
  105. {
  106. HRESULT hr = E_FAIL;
  107. HINSTANCE hinstDll = ::LoadLibrary(TEXT("USER32.DLL"));
  108. if (hinstDll)
  109. {
  110. pfnSetMenuInfo = (PFNSETMENUINFOHANDLE)GetProcAddress(hinstDll, "SetMenuInfo");
  111. if (pfnSetMenuInfo)
  112. {
  113. hr = pfnSetMenuInfo(hMenu, pmInfo);
  114. }
  115. FreeLibrary(hinstDll);
  116. }
  117. return hr;
  118. }
  119. #define MIIM_STRING 0x00000040
  120. #define MIIM_BITMAP 0x00000080
  121. #define MIIM_FTYPE 0x00000100
  122. #define HBMMENU_POPUP_CLOSE ((HBITMAP) 8)
  123. #define HBMMENU_POPUP_RESTORE ((HBITMAP) 9)
  124. #define HBMMENU_POPUP_MAXIMIZE ((HBITMAP) 10)
  125. #define HBMMENU_POPUP_MINIMIZE ((HBITMAP) 11)
  126. typedef struct tagMENUITEMINFOAInternal
  127. {
  128. UINT cbSize;
  129. UINT fMask;
  130. UINT fType; // used if MIIM_TYPE (4.0) or MIIM_FTYPE (>4.0)
  131. UINT fState; // used if MIIM_STATE
  132. UINT wID; // used if MIIM_ID
  133. HMENU hSubMenu; // used if MIIM_SUBMENU
  134. HBITMAP hbmpChecked; // used if MIIM_CHECKMARKS
  135. HBITMAP hbmpUnchecked; // used if MIIM_CHECKMARKS
  136. ULONG_PTR dwItemData; // used if MIIM_DATA
  137. LPSTR dwTypeData; // used if MIIM_TYPE (4.0) or MIIM_STRING (>4.0)
  138. UINT cch; // used if MIIM_TYPE (4.0) or MIIM_STRING (>4.0)
  139. HBITMAP hbmpItem; // used if MIIM_BITMAP
  140. } MENUITEMINFOAInternal, FAR *LPMENUITEMINFOAInternal;
  141. typedef struct tagMENUITEMINFOWInternal
  142. {
  143. UINT cbSize;
  144. UINT fMask;
  145. UINT fType; // used if MIIM_TYPE (4.0) or MIIM_FTYPE (>4.0)
  146. UINT fState; // used if MIIM_STATE
  147. UINT wID; // used if MIIM_ID
  148. HMENU hSubMenu; // used if MIIM_SUBMENU
  149. HBITMAP hbmpChecked; // used if MIIM_CHECKMARKS
  150. HBITMAP hbmpUnchecked; // used if MIIM_CHECKMARKS
  151. ULONG_PTR dwItemData; // used if MIIM_DATA
  152. LPWSTR dwTypeData; // used if MIIM_TYPE (4.0) or MIIM_STRING (>4.0)
  153. UINT cch; // used if MIIM_TYPE (4.0) or MIIM_STRING (>4.0)
  154. HBITMAP hbmpItem; // used if MIIM_BITMAP
  155. } MENUITEMINFOWInternal, FAR *LPMENUITEMINFOWInternal;
  156. #ifdef UNICODE
  157. typedef MENUITEMINFOWInternal MENUITEMINFOInternal;
  158. typedef LPMENUITEMINFOWInternal LPMENUITEMINFOInternal;
  159. #else
  160. typedef MENUITEMINFOAInternal MENUITEMINFOInternal;
  161. typedef LPMENUITEMINFOAInternal LPMENUITEMINFOInternal;
  162. #endif // UNICODE
  163. typedef MENUITEMINFOAInternal CONST FAR *LPCMENUITEMINFOAInternal;
  164. typedef MENUITEMINFOWInternal CONST FAR *LPCMENUITEMINFOWInternal;
  165. #ifdef UNICODE
  166. typedef LPCMENUITEMINFOWInternal LPCMENUITEMINFOInternal;
  167. #else
  168. typedef LPCMENUITEMINFOAInternal LPCMENUITEMINFOInternal;
  169. #endif // UNICODE
  170. #endif /* WINVER < 0x0500 */
  171. /*************************************************************************/
  172. /* CMFBar Implementation */
  173. /*************************************************************************/
  174. /*************************************************************************/
  175. /* Function: Init */
  176. /* Description: Initializes memeber variables. */
  177. /*************************************************************************/
  178. HRESULT CMFBar::Init(){
  179. HRESULT hr = S_OK;
  180. // #### BEGIN CONTAINER SUPPORT ####
  181. m_bCanWindowlessActivate = true;
  182. // #### END CONTAINER SUPPORT ####
  183. #if 1 // used for getting the windowed case working DJ
  184. m_bWindowOnly = TRUE;
  185. #endif
  186. m_fSelfHosted = false;
  187. // TODO: Investigate if it works in pallete mode
  188. m_clrBackColor = ::GetSysColor(COLOR_BTNFACE);
  189. m_lMinWidth = -1; // disable it
  190. m_lMinHeight = -1; // disable it by default
  191. m_fHandleHelp = false;
  192. m_blitType = DISABLE;
  193. m_bMouseDown = false;
  194. m_nReadyState = READYSTATE_LOADING;
  195. m_fAutoLoad = VARIANT_TRUE;
  196. m_pBackBitmap = NULL;
  197. m_fForceKey = false;
  198. m_lTimeout = 0;
  199. m_fUserActivity = false;
  200. m_fWaitingForActivity = false;
  201. // setup the default resource DLL to be this binary
  202. m_hRes = _Module.m_hInstResource; // set the resource DLL Name
  203. TCHAR szModule[_MAX_PATH+10];
  204. ::GetModuleFileName(m_hRes, szModule, _MAX_PATH);
  205. USES_CONVERSION;
  206. m_strResDLL = T2OLE(szModule);
  207. if(NULL == m_hIcon){
  208. m_hIcon = ::LoadIcon(m_hRes, MAKEINTRESOURCE(IDI_ICON1));
  209. }/* end of if statement */
  210. #if 0
  211. if(NULL == m_hIconSmall){
  212. m_hIconSmall = (HICON)::LoadImage(m_hRes, MAKEINTRESOURCE(IDI_ICON1), IMAGE_ICON,
  213. ::GetSystemMetrics(SM_CXSMICON), ::GetSystemMetrics(SM_CYSMICON), LR_DEFAULTCOLOR);
  214. }/* end of if statement */
  215. #endif
  216. m_HitRegion = NOHIT; // Initialize the hit region
  217. m_hMenu = NULL;
  218. m_bSysMenuOn = FALSE;
  219. m_bHandleEnter = FALSE;
  220. m_hCursor = NULL;
  221. m_hinstHelpDll = NULL;
  222. ::ZeroMemory(&m_rcWnd, sizeof(RECT));
  223. ::ZeroMemory(&m_rcWndOld, sizeof(RECT));
  224. ::ZeroMemory(&m_ptMouse, sizeof(POINT));
  225. ::ZeroMemory(&m_ptMouseOld, sizeof(POINT));
  226. m_bHandleUserFocus = TRUE;
  227. return(hr);
  228. }/* end of function Init */
  229. /*************************************************************************/
  230. /* Function: Cleanup */
  231. /* Description: Makes sure the script engine is released. Also cleans */
  232. /* up the contained objects in the containers. */
  233. /*************************************************************************/
  234. HRESULT CMFBar::Cleanup(){
  235. // Release the language engine, since it may hold on to us
  236. HRESULT hr = S_OK;
  237. try {
  238. if (m_psp){
  239. m_psp.Release();
  240. }/* end of if statement */
  241. if (m_ps){
  242. m_ps->Close();
  243. m_ps.Release();
  244. }/* end of if statement */
  245. // Reset the Active Object
  246. m_spActiveObject.Release();
  247. // cleanup the event list
  248. for(CNTEVNT::iterator i = m_cntEvnt.begin(); false == m_cntEvnt.empty(); ){
  249. CEventObject* pObj = (*i);
  250. delete pObj;
  251. i = m_cntEvnt.erase(i);
  252. }/* end of if statement */
  253. CHostedObject* pSelfObj = NULL;
  254. CContainerObject* pSelfContainer = NULL;
  255. // cleanup the object list
  256. for(CNTOBJ::iterator j = m_cntObj.begin(); false == m_cntObj.empty(); ){
  257. CHostedObject* pObj = (*j);
  258. CContainerObject* pContainerObj;
  259. HRESULT hrCont = pObj->GetContainerObject(&pContainerObj);
  260. #ifdef _DEBUG
  261. CComBSTR strOBJID = pObj->GetID();
  262. #endif
  263. #if 1
  264. if(pObj->GetUnknown() != GetUnknown()){
  265. try {
  266. delete pObj; // do not delete our self at the moment
  267. }
  268. catch(...){
  269. #if _DEBUG
  270. USES_CONVERSION;
  271. ATLTRACE(TEXT(" Failed to destroy %s "), OLE2T(strOBJID));
  272. #endif
  273. }/* end of catch statement */
  274. }
  275. else {
  276. pSelfObj = pObj;
  277. }/* end of if statement */
  278. #endif
  279. #if 1
  280. if(pObj->GetUnknown() != GetUnknown()){
  281. try {
  282. delete pContainerObj; // do not delete our self at the moment
  283. }
  284. catch(...){
  285. #if _DEBUG
  286. USES_CONVERSION;
  287. ATLTRACE(TEXT(" Failed to destroy wrapper for %s "), OLE2T(strOBJID));
  288. #endif
  289. }/* end of catch statement */
  290. }
  291. else {
  292. pSelfContainer = pContainerObj;
  293. }/* end of if statement */
  294. #endif
  295. j = m_cntObj.erase(j);
  296. }/* end of if statement */
  297. ResetFocusArray();
  298. try {
  299. delete pSelfObj;
  300. delete pSelfContainer;
  301. }
  302. catch(...){
  303. ATLTRACE(TEXT(" The container failed to destroy it self properly"));
  304. }/* end of if statemnent */
  305. if(m_pBackBitmap){
  306. delete m_pBackBitmap;
  307. m_pBackBitmap = NULL;
  308. }/* end of if statement */
  309. CBitmap::FinalRelease(); // cleanup the mosaic if present
  310. if (m_hMenu) {
  311. ::DestroyMenu(m_hMenu);
  312. m_hMenu = NULL;
  313. }
  314. if (m_hCursor) {
  315. ::DestroyCursor(m_hCursor);
  316. m_hCursor = NULL;
  317. }
  318. hr = Init();
  319. if (m_hIcon) {
  320. ::DestroyIcon(m_hIcon);
  321. m_hIcon = NULL;
  322. }/* end of if statement */
  323. #if 0
  324. if (m_hIconSmall) {
  325. ::DestroyIcon(m_hIconSmall);
  326. m_hIconSmall = NULL;
  327. }/* end of if statement */
  328. #endif
  329. if(m_hinstHelpDll){
  330. ::FreeLibrary(m_hinstHelpDll);
  331. }/* end of if statement */
  332. }
  333. catch(...){
  334. hr = E_UNEXPECTED;
  335. }
  336. return (hr);
  337. }/* end of function Cleanup */
  338. /*************************************************************************/
  339. /* Function: ~CMFBar */
  340. /*************************************************************************/
  341. CMFBar::~CMFBar(){
  342. Cleanup();
  343. ATLTRACE(TEXT("Exiting CMFBar destructor! \n"));
  344. }/* end of function ~CMFBar */
  345. /*************************************************************************/
  346. /* Message handling. */
  347. /*************************************************************************/
  348. /*************************************************************************/
  349. /* Function: OnPaint */
  350. /* Description: Had to overwrite the the deafult OnPaint so I could */
  351. /* somehow get the real update rects. */
  352. /*************************************************************************/
  353. LRESULT CMFBar::OnPaint(UINT /* uMsg */, WPARAM wParam,
  354. LPARAM /* lParam */, BOOL& /* lResult */){
  355. RECT rc;
  356. PAINTSTRUCT ps;
  357. HDC hdc = (wParam != NULL) ? (HDC)wParam : ::BeginPaint(m_hWndCD, &ps);
  358. if (hdc == NULL)
  359. return 0;
  360. ::GetClientRect(m_hWndCD, &rc);
  361. ATL_DRAWINFO di;
  362. memset(&di, 0, sizeof(di));
  363. di.cbSize = sizeof(di);
  364. di.dwDrawAspect = DVASPECT_CONTENT;
  365. di.lindex = -1;
  366. di.hdcDraw = hdc;
  367. // DJ change here, keep the real update rect from the PAINTSTRUCT
  368. // Set the window size to the size of the window
  369. di.prcWBounds = (LPCRECTL)&rc;
  370. di.prcBounds = (LPCRECTL)&ps.rcPaint;
  371. OnDrawAdvanced(di); // Eventually propagates to OnDraw
  372. if (wParam == NULL)
  373. ::EndPaint(m_hWndCD, &ps);
  374. return 0;
  375. }/* end of function OnPaint */
  376. /*************************************************************************/
  377. /* Function: OnDraw */
  378. /* Description: Just Draws the rectangular background and contained */
  379. /* windowless controls. */
  380. /*************************************************************************/
  381. HRESULT CMFBar::OnDraw(ATL_DRAWINFO& di){
  382. try {
  383. HDC hdc = di.hdcDraw;
  384. RECT rcClient = *(RECT*)di.prcBounds;
  385. RECT rcWClient = *(RECT*)di.prcWBounds;
  386. // this might not work if you overlapp the controls
  387. // controls like to be painted as a whole so if
  388. // we need to update the are that contains the control
  389. // we need to find all the controls that intersect it, combine the
  390. // rectangle and then repaint the whole region
  391. if(::IsWindow(m_hWnd)){
  392. if(!::EqualRect(&rcClient, &rcWClient)){
  393. RECT rcNewClient = rcClient; // the original update are which we are enlarging
  394. for(CNTOBJ::iterator i = m_cntObj.begin(); i!= m_cntObj.end(); i++){
  395. // iterate through all the contained objects and draw them
  396. CHostedObject* pObj = (*i);
  397. if((NULL != pObj) && (pObj->IsActive())){
  398. if(pObj->IsWindowless()){
  399. RECT rcCntrl;
  400. pObj->GetPos(&rcCntrl); // get the position of the object
  401. RECT rcInt;
  402. if(!::IntersectRect(&rcInt, &rcCntrl, &rcClient)){
  403. continue;
  404. }
  405. else {
  406. // OK we need to add this control rect to our rect union
  407. ::UnionRect(&rcNewClient, &rcClient, &rcCntrl);
  408. }/* end of if statement */
  409. }/* end of if statement */
  410. }/* end of if statement */
  411. }/* end of for loop */
  412. rcClient = rcNewClient; // update our are with enlarged client
  413. }/* end of if statement */
  414. // else if the rects are the same we are updating the whole
  415. // window so there is no point to do the calculations
  416. }/* end of if statement */
  417. COLORREF clr;
  418. HPALETTE hPal = NULL;
  419. if(m_pBackBitmap){
  420. hPal = CBitmap::GetSuperPal();
  421. m_pBackBitmap->SelectRelizePalette(hdc, hPal);
  422. }/* end of if statement */
  423. ::OleTranslateColor (m_clrBackColor, hPal, &clr);
  424. // fill in the background and get ready to fill in the objects
  425. LONG lBmpWidth = RECTWIDTH(&rcWClient);
  426. LONG lBmpHeight = RECTHEIGHT(&rcWClient);
  427. HBITMAP hBitmap = ::CreateCompatibleBitmap(hdc, lBmpWidth, lBmpHeight);
  428. if(NULL == hBitmap){
  429. ATLASSERT(FALSE);
  430. return(0);
  431. }/* end of if statement */
  432. HDC hdcCompatible = ::CreateCompatibleDC(hdc);
  433. if(NULL == hdcCompatible){
  434. ATLASSERT(FALSE);
  435. ::DeleteObject(hBitmap);
  436. return(0);
  437. }/* end of if statement */
  438. // Draw background on the faceplate bitmap
  439. ::SelectObject(hdcCompatible, hBitmap);
  440. if (!m_pBackBitmap){
  441. // fill background of specific color
  442. HBRUSH hbrBack = ::CreateSolidBrush(clr);
  443. if(NULL == hbrBack){
  444. ATLASSERT(FALSE);
  445. ::DeleteObject(hBitmap);
  446. return(0);
  447. }/* end of if statement */
  448. //::FillRect(hdc, &rcClient, hbrBack);
  449. ::FillRect(hdcCompatible, &rcClient, hbrBack);
  450. ::DeleteObject(hbrBack);
  451. }
  452. else {
  453. m_pBackBitmap->SelectRelizePalette(hdcCompatible, hPal);
  454. //BOOL bRet = m_pBackBitmap->PaintTransparentDIB(hdc, &rcWClient, &rcClient, m_blitType, true);
  455. BOOL bRet = m_pBackBitmap->PaintTransparentDIB(hdcCompatible, &rcWClient, &rcClient);
  456. if(!bRet){
  457. ATLTRACE(TEXT(" The transparent Blit did not work!"));
  458. }/* end of if statement */
  459. }/* end of if statement */
  460. for(CNTOBJ::iterator i = m_cntObj.begin(); i!= m_cntObj.end(); i++){
  461. // iterate through all the contained objects and draw them
  462. CHostedObject* pObj = (*i);
  463. CComPtr<IViewObjectEx> pViewObject = NULL;
  464. if((NULL != pObj) && (pObj->IsActive()) && (SUCCEEDED(pObj->GetViewObject(&pViewObject)))){
  465. if(pObj->IsWindowless()){
  466. if(pViewObject){
  467. if(GetUnknown() == pObj->GetUnknown()){
  468. // in case we are windowless and we are trying to draw our self again
  469. continue;
  470. }/* end of if statement */
  471. RECT rcCntrl;
  472. pObj->GetPos(&rcCntrl);
  473. RECT rcInt;
  474. if(!::IntersectRect(&rcInt, &rcCntrl, &rcClient)){
  475. continue;
  476. }/* end of if statement */
  477. LONG lBmpWidth = RECTWIDTH(&rcCntrl);
  478. LONG lBmpHeight = RECTHEIGHT(&rcCntrl);
  479. RECT rcCntrlBitmap = {0, 0, lBmpWidth, lBmpHeight};
  480. POINT ptNewOffset = {rcCntrl.left, rcCntrl.top};
  481. POINT ptOldOffset;
  482. ::GetViewportOrgEx(hdcCompatible, &ptOldOffset);
  483. LPtoDP(hdcCompatible, &ptNewOffset, 1);
  484. // offset the rect we are catually going to draw
  485. //::OffsetRect(&rcInt, -ptNewOffset.x, -ptNewOffset.y);
  486. // offset the DC
  487. ::OffsetViewportOrgEx(hdcCompatible, ptNewOffset.x, ptNewOffset.y, &ptOldOffset);
  488. // draw
  489. 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);
  490. #if 1 // used to redraw the whole control, now we are just doinf part of it
  491. //HRGN hrgnOld = NULL;
  492. //HRGN hrgnNew = NULL;
  493. //if(::IsWindow(m_hWnd)){
  494. //
  495. // hrgnNew = ::CreateRectRgnIndirect(&rcInt);
  496. // hrgnOld = (HRGN)::SelectObject(hdc, hrgnNew);
  497. //}/* end of if statement */
  498. pViewObject->Draw(DVASPECT_CONTENT, -1, NULL, NULL, NULL, hdcCompatible, (RECTL*)&rcCntrlBitmap, (RECTL*)&rcCntrlBitmap, NULL, NULL);
  499. #else
  500. pViewObject->Draw(DVASPECT_CONTENT, -1, NULL, NULL, NULL, hdcCompatible, (RECTL*)&rcInt, (RECTL*)&rcCntrlBitmap, NULL, NULL);
  501. #endif
  502. ::SetViewportOrgEx(hdcCompatible, ptOldOffset.x, ptOldOffset.y, NULL);
  503. }
  504. #ifdef _DEBUG
  505. else {
  506. ATLTRACE2(atlTraceWindowing, 30,TEXT("FAILED Drawing the object since pView is NULL\n"));
  507. }/* end of if statement */
  508. #endif
  509. }/* end of if statement */
  510. }/* end of if statement */
  511. }/* end of for loop */
  512. ::BitBlt(hdc, rcClient.left, rcClient.top, lBmpWidth, lBmpHeight, hdcCompatible, rcClient.left, rcClient.top, SRCCOPY);
  513. // cleanup
  514. ::DeleteDC(hdcCompatible);
  515. ::DeleteObject(hBitmap);
  516. return(1);
  517. }/* end of try statement */
  518. catch(...){
  519. return(0);
  520. }/* end of catch statement */
  521. }/* end of function OnDraw */
  522. /*************************************************************************/
  523. /* Function: OnErase */
  524. /* Description: Skip the erasing to avoid flickers. */
  525. /*************************************************************************/
  526. LRESULT CMFBar::OnErase(UINT, WPARAM wParam, LPARAM lParam, BOOL& bHandled){
  527. ATLTRACE2(atlTraceWindowing, 32, TEXT("Received WM_ERASE MESSAGE \n"));
  528. #if 0
  529. POINT pt; pt.x =0; pt.y = 0;
  530. ::MapWindowPoints(m_hWnd, hWndPar, &pt, 1);
  531. ::OffsetWindowOrgEx(hdc, pt.x, pt.y, &pt);
  532. ::SendMessage(hWndPar, WM_ERASEBKGND, (WPARAM) hdc, 0);
  533. ::SetWindowOrgEx(hdc, pt.x, pt.y, NULL);
  534. #endif
  535. //InvalidateRect(&m_rcPos, FALSE);
  536. bHandled = TRUE;
  537. return 1;
  538. }/* end of function OnErase */
  539. /*************************************************************************/
  540. /* Function: OnClose */
  541. /* Description: Skip the erasing to avoid flickers. */
  542. /*************************************************************************/
  543. LRESULT CMFBar::OnClose(UINT, WPARAM wParam, LPARAM lParam, BOOL& bHandled){
  544. if(::IsWindow(m_hWnd)){
  545. ::DestroyWindow(m_hWnd);
  546. }/* end of if statement */
  547. HRESULT hr = Close(OLECLOSE_SAVEIFDIRTY);
  548. ATLTRACE(TEXT("Closing \n"));
  549. if(SUCCEEDED(hr)){
  550. bHandled = TRUE;
  551. }/* end of if statement */
  552. return 0;
  553. }/* end of function OnClose */
  554. /*************************************************************/
  555. /* Name:
  556. /* Description:
  557. /*************************************************************/
  558. LRESULT CMFBar::OnActivate(UINT, WPARAM wParam, LPARAM lParam, BOOL& bHandled) {
  559. switch (LOWORD(wParam)) {
  560. case WA_ACTIVE:
  561. case WA_CLICKACTIVE:
  562. Fire_OnActivate(VARIANT_TRUE);
  563. break;
  564. case WA_INACTIVE:
  565. Fire_OnActivate(VARIANT_FALSE);
  566. break;
  567. }
  568. return 0;
  569. }
  570. /*************************************************************************/
  571. /* Function: OnSysCommand */
  572. /* Description: Handles the on syscommand. */
  573. /*************************************************************************/
  574. LRESULT CMFBar::OnSysCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled){
  575. ATLTRACE2(atlTraceWindowing, 20, TEXT("Received WM_SYSCOMMAND MESSAGE \n"));
  576. LRESULT lRet = 0;
  577. switch (wParam) {
  578. case SC_CONTEXTHELP :
  579. m_fHandleHelp = true;
  580. bHandled = FALSE;
  581. lRet = 1;
  582. break;
  583. case SC_RESTORE:
  584. case SC_MOVE:
  585. case SC_SIZE:
  586. case SC_MINIMIZE:
  587. case SC_MAXIMIZE:
  588. case SC_CLOSE:
  589. OnCommand(WM_COMMAND, wParam, lParam, bHandled);
  590. bHandled = TRUE;
  591. lRet = 0;
  592. break;
  593. default:
  594. bHandled = FALSE;
  595. return ::DefWindowProc(m_hWnd, uMsg, wParam, lParam);
  596. }
  597. return(lRet);
  598. }/* end of function OnSysCommand */
  599. /*************************************************************************/
  600. /* Function: OnCommand */
  601. /* Description: Handles the on command. */
  602. /*************************************************************************/
  603. LRESULT CMFBar::OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled){
  604. ATLTRACE2(atlTraceWindowing, 20, TEXT("Received WM_COMMAND MESSAGE \n"));
  605. LRESULT lRet = 0;
  606. if (NULL == m_hMenu)
  607. return lRet;
  608. switch (LOWORD(wParam)) {
  609. case ID_SYSTEMMENU_RESTORE:
  610. case SC_RESTORE:
  611. ShowSelfSite(SW_RESTORE);
  612. break;
  613. case ID_SYSTEMMENU_MOVE:
  614. case SC_MOVE: {
  615. // Save window size and position
  616. ::GetWindowRect(m_hWnd, &m_rcWndOld);
  617. ::GetCursorPos(&m_ptMouseOld);
  618. RECT rc;
  619. ::GetClientRect(m_hWnd, &rc);
  620. POINT point = {(rc.left+rc.right)/2, rc.top + SYS_TITLEBAR_WIDTH/2};
  621. POINT screenPt = point;
  622. ::ClientToScreen(m_hWnd, &screenPt);
  623. RECT rcDeskt;
  624. ::GetWindowRect(::GetDesktopWindow(), &rcDeskt);
  625. LONG lx = LONG((FLOAT)screenPt.x/ RECTWIDTH(&rcDeskt) * 0xFFFF);
  626. LONG ly = LONG((FLOAT)screenPt.y/ RECTHEIGHT(&rcDeskt) * 0xFFFF);
  627. mouse_event(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE, lx, ly, 0, 0);
  628. m_HitRegion = PREMOVE;
  629. UpdateCursor(m_HitRegion);
  630. m_bHandleEnter = TRUE;
  631. break;
  632. }
  633. case ID_SYSTEMMENU_SIZE:
  634. case SC_SIZE: {
  635. // Save window size and position
  636. ::GetWindowRect(m_hWnd, &m_rcWndOld);
  637. ::GetCursorPos(&m_ptMouseOld);
  638. RECT rc;
  639. ::GetClientRect(m_hWnd, &rc);
  640. POINT point = {rc.right/2, rc.bottom/2};
  641. POINT screenPt = point;
  642. ::ClientToScreen(m_hWnd, &screenPt);
  643. RECT rcDeskt;
  644. ::GetWindowRect(::GetDesktopWindow(), &rcDeskt);
  645. LONG lx = LONG((FLOAT)screenPt.x/ RECTWIDTH(&rcDeskt) * 0xFFFF);
  646. LONG ly = LONG((FLOAT)screenPt.y/ RECTHEIGHT(&rcDeskt) * 0xFFFF);
  647. mouse_event(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE, lx, ly, 0, 0);
  648. m_HitRegion = PRESIZE;
  649. UpdateCursor(m_HitRegion);
  650. m_bHandleEnter = TRUE;
  651. break;
  652. }
  653. case ID_SYSTEMMENU_MINIMIZE:
  654. case SC_MINIMIZE:
  655. ShowSelfSite(SW_MINIMIZE);
  656. break;
  657. case ID_SYSTEMMENU_MAXIMIZE:
  658. case SC_MAXIMIZE:
  659. ShowSelfSite(SW_MAXIMIZE);
  660. break;
  661. case ID_SYSTEMMENU_CLOSE:
  662. case SC_CLOSE:
  663. OnClose(WM_CLOSE, wParam, lParam, bHandled);
  664. break;
  665. default:
  666. bHandled = FALSE;
  667. return ::DefWindowProc(m_hWnd, uMsg, wParam, lParam);
  668. }
  669. m_bSysMenuOn = FALSE;
  670. return(lRet);
  671. }/* end of function OnCommand */
  672. /*************************************************************************/
  673. /* Function: OnTimer */
  674. /* Description: Handles the timer message. */
  675. /*************************************************************************/
  676. LRESULT CMFBar::OnTimer(UINT, WPARAM wParam, LPARAM lParam, BOOL& bHandled){
  677. WPARAM wTimerID = wParam;
  678. if(ID_EV_TIMER == wTimerID){
  679. if(false == m_fUserActivity && false == m_fWaitingForActivity){
  680. // If system menu is on, do not time out
  681. if (!m_bSysMenuOn) {
  682. // fire message that there is no activity going on
  683. m_fWaitingForActivity = true;
  684. Fire_ActivityDeclined();
  685. }
  686. }/* end of if statement */
  687. m_fUserActivity = false; // reset the flag
  688. }
  689. else {
  690. if(::IsWindow(m_hWnd)){
  691. ::KillTimer(m_hWnd, wTimerID);
  692. }/* end of if statement */
  693. Fire_Timeout(wTimerID);
  694. }/* end of if statement */
  695. bHandled = TRUE;
  696. return(1);
  697. }/* end of function OnTimer */
  698. /*************************************************************************/
  699. /* Function: OnCaptureChanged */
  700. /* Description: Handles the on syscommand. */
  701. /*************************************************************************/
  702. LRESULT CMFBar::OnCaptureChanged(UINT, WPARAM wParam, LPARAM lParam, BOOL& bHandled){
  703. ATLTRACE2(atlTraceWindowing, 4, TEXT("Received WM_CAPTURECHANGED MESSAGE \n"));
  704. if(m_fHandleHelp){
  705. HWND h;
  706. if(SUCCEEDED(GetWindow(&h))){
  707. POINT pt;
  708. ::GetCursorPos(&pt);
  709. RECT rc;
  710. ::GetWindowRect(h, &rc);
  711. if(!::PtInRect(&rc, pt)){
  712. // we clicked somewhere outiside in our help mode
  713. m_fHandleHelp = false; // otherwise we are going to get lbutton up and we will
  714. // turn it off then
  715. }/* end of if statement */
  716. }
  717. else {
  718. m_fHandleHelp = false; // could not get the window, but better trun off
  719. // the help mode
  720. }/* end of if statement */
  721. return(0);
  722. }/* end of if statement */
  723. if(::IsWindow(m_hWnd)){
  724. HWND hwndNewCapture = (HWND) lParam;
  725. if(m_hWnd != hwndNewCapture){
  726. ResetCaptureFlags();
  727. #if 0 // uncoment this if we get badly behaving controls
  728. if(m_bMouseDown){
  729. // we are not supposed to do that
  730. // but if our child takes a focus away while we
  731. // are resizigng we get in trouble
  732. SetCapture(TRUE);
  733. }/* end of if statement */
  734. #endif
  735. }/* end of if statement */
  736. }/* end of if statement */
  737. return(0);
  738. }/* end of function OnCaptureChanged */
  739. /*************************************************************************/
  740. /* Function: OnSetIcon */
  741. /* Description: Set icon . */
  742. /*************************************************************************/
  743. LRESULT CMFBar::OnSetIcon(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled){
  744. LRESULT lr = ::DefWindowProc(m_hWnd, uMsg, wParam, lParam);
  745. return(lr);
  746. }/* end of function OnSetIcon */
  747. /*************************************************************************/
  748. /* Function: OnInitDialog */
  749. /* Description: Fires the help event. */
  750. /*************************************************************************/
  751. LRESULT CMFBar::OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled){
  752. ATLASSERT(FALSE);
  753. LRESULT lr = ::DefWindowProc(m_hWnd, uMsg, wParam, lParam);
  754. return(lr);
  755. }/* end of function OnInitDialog */
  756. /*************************************************************************/
  757. /* Function: OnHelp */
  758. /* Description: Fires the help event. */
  759. /*************************************************************************/
  760. LRESULT CMFBar::OnHelp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled){
  761. HELPINFO* pHpi = (LPHELPINFO) lParam;
  762. bHandled = TRUE;
  763. if(NULL == pHpi){
  764. return 0;
  765. }/* end of if statement */
  766. // first check if we have fired help on message box
  767. HWND hCntrlWnd = (HWND)pHpi->hItemHandle;
  768. if((::GetWindowLong(hCntrlWnd, GWL_STYLE) & WS_DLGFRAME) == WS_DLGFRAME){
  769. // we have a message box up
  770. HWND hwndText;
  771. hwndText = ::FindWindowEx(hCntrlWnd, NULL, TEXT("Static"), NULL);
  772. if(hwndText){
  773. TCHAR strWindowText[MAX_PATH];
  774. ::GetWindowText(hwndText, strWindowText, MAX_PATH);
  775. //::DestroyWindow(hCntrlWnd);
  776. BSTR strToolbarName;
  777. if(SUCCEEDED(GetToolbarName(&strToolbarName))){
  778. USES_CONVERSION;
  779. Fire_OnHelp(strToolbarName, ::SysAllocString(T2OLE(strWindowText)));
  780. }/* end of if statement */
  781. }
  782. else {
  783. ;//::DestroyWindow(hCntrlWnd);
  784. }/* end of if statement */
  785. return(TRUE);
  786. }/* end of if statement */
  787. // then check if a windowed control has fired help
  788. for(CNTOBJ::iterator i = m_cntObj.begin(); i!= m_cntObj.end(); i++){
  789. // iterate through all the contained controls
  790. CHostedObject* pObj = (*i);
  791. if(NULL == pObj){
  792. ATLASSERT(FALSE); // should not be null
  793. continue;
  794. }/* end of if statement */
  795. if(pObj->IsInputEnabled() && !pObj->IsWindowless()){
  796. HWND hwnd = NULL;
  797. HRESULT hr = pObj->GetWindow(&hwnd);
  798. if(FAILED(hr)){
  799. continue;
  800. }/* end of if statement */
  801. if(hwnd == hCntrlWnd){
  802. Fire_OnHelp(::SysAllocString(pObj->GetID()));
  803. //ResetFocusFlags();
  804. return(TRUE);
  805. }/* end of if statement */
  806. }/* end of if statement */
  807. }/* end of for loop */
  808. // now look into windowless control
  809. POINT ptMouse = pHpi->MousePos;
  810. m_fHandleHelp = false; // get our self out of the help mode in case we clicked
  811. // on windowed control and we did not get notified about this
  812. // convert the point to client coordinates
  813. HWND h = NULL;
  814. HRESULT hr = GetWindow(&h);
  815. if(FAILED(hr)){
  816. ATLASSERT(FALSE);
  817. return(0);
  818. }/* end of if statement */
  819. if(!::ScreenToClient(h, &ptMouse)){
  820. ATLASSERT(FALSE);
  821. return(0);
  822. }/* end of if statement */
  823. for(i = m_cntObj.begin(); i!= m_cntObj.end(); i++){
  824. // iterate through all the contained controls
  825. CHostedObject* pObj = (*i);
  826. if(NULL == pObj){
  827. ATLASSERT(FALSE); // should not be null
  828. continue;
  829. }/* end of if statement */
  830. // send the message to the control over which we are howering or on which we
  831. // have clicked, check if we already are ready to send the message
  832. // in that case do not bother with the rect interstec bussines
  833. if(pObj->IsInputEnabled()){
  834. CComPtr<IViewObjectEx> pViewObject;
  835. HRESULT hr = pObj->GetViewObject(&pViewObject);
  836. if(FAILED(hr)){
  837. ATLASSERT(FALSE); // should have a view
  838. continue;
  839. }/* end of if statement */
  840. DWORD dwHitResult = HITRESULT_OUTSIDE;
  841. RECT rcCntrl;
  842. pObj->GetPos(&rcCntrl);
  843. pViewObject->QueryHitPoint(DVASPECT_CONTENT, &rcCntrl, ptMouse, 0, &dwHitResult);
  844. if(HITRESULT_HIT == dwHitResult){
  845. Fire_OnHelp(::SysAllocString(pObj->GetID()));
  846. return(TRUE);
  847. }/* end of if statement */
  848. }/* end of if statement */
  849. }/* end of for loop */
  850. // Get toolbar name
  851. BSTR strToolbarName;
  852. if(SUCCEEDED(GetToolbarName(&strToolbarName))){
  853. Fire_OnHelp(strToolbarName);
  854. }/* end of if statement */
  855. return(TRUE);
  856. }/* end of function OnHelp */
  857. /*************************************************************************/
  858. /* Function: OnSize */
  859. /* Description: Handles the onsize message if we are self contained. */
  860. /*************************************************************************/
  861. LRESULT CMFBar::OnSize(UINT, WPARAM wParam, LPARAM lParam, BOOL& bHandled){
  862. try {
  863. if(false == m_fSelfHosted){
  864. bHandled = FALSE;
  865. return 0;
  866. }/* end of if statement */
  867. // Update the system menu accordingly
  868. if (m_hMenu) {
  869. HMENU hSubMenu = ::GetSubMenu(m_hMenu, 0);
  870. if(hSubMenu){
  871. MENUITEMINFO mInfo;
  872. mInfo.cbSize = sizeof(MENUITEMINFO);
  873. BOOL bRestored = (wParam == SIZE_RESTORED);
  874. ::GetMenuItemInfo(hSubMenu, ID_SYSTEMMENU_RESTORE, false, &mInfo);
  875. mInfo.fMask = MIIM_STATE;
  876. mInfo.fState = bRestored? MFS_GRAYED:MFS_ENABLED;
  877. ::SetMenuItemInfo(hSubMenu, ID_SYSTEMMENU_RESTORE, false, &mInfo);
  878. BOOL bMaximized = (wParam == SIZE_MAXIMIZED);
  879. ::GetMenuItemInfo(hSubMenu, ID_SYSTEMMENU_MAXIMIZE, false, &mInfo);
  880. mInfo.fMask = MIIM_STATE;
  881. mInfo.fState = bMaximized? MFS_GRAYED:MFS_ENABLED;
  882. ::SetMenuItemInfo(hSubMenu, ID_SYSTEMMENU_MAXIMIZE, false, &mInfo);
  883. BOOL bMinimized = (wParam == SIZE_MINIMIZED);
  884. ::GetMenuItemInfo(hSubMenu, ID_SYSTEMMENU_MINIMIZE, false, &mInfo);
  885. mInfo.fMask = MIIM_STATE;
  886. mInfo.fState = bMinimized? MFS_GRAYED:MFS_ENABLED;
  887. ::SetMenuItemInfo(hSubMenu, ID_SYSTEMMENU_MINIMIZE, false, &mInfo);
  888. BOOL bMovable = !(bMaximized || bMinimized);
  889. ::GetMenuItemInfo(hSubMenu, ID_SYSTEMMENU_SIZE, false, &mInfo);
  890. mInfo.fMask = MIIM_STATE;
  891. mInfo.fState = bMovable? MFS_ENABLED:MFS_GRAYED;
  892. ::SetMenuItemInfo(hSubMenu, ID_SYSTEMMENU_SIZE, false, &mInfo);
  893. ::GetMenuItemInfo(hSubMenu, ID_SYSTEMMENU_MOVE, false, &mInfo);
  894. mInfo.fMask = MIIM_STATE;
  895. mInfo.fState = bMovable? MFS_ENABLED:MFS_GRAYED;
  896. ::SetMenuItemInfo(hSubMenu, ID_SYSTEMMENU_MOVE, false, &mInfo);
  897. }
  898. }
  899. if (wParam == SIZE_MAXIMIZED) {
  900. #ifndef _DEBUG
  901. ::SetWindowPos(m_hWnd, HWND_TOPMOST, 0, 0, 0, 0,
  902. SWP_NOREDRAW|SWP_NOMOVE|SWP_NOSIZE);
  903. #endif
  904. }
  905. else {
  906. ::SetWindowPos(m_hWnd, HWND_NOTOPMOST, 0, 0, 0, 0,
  907. SWP_NOREDRAW|SWP_NOMOVE|SWP_NOSIZE);
  908. }
  909. LONG lWidth = LOWORD(lParam);
  910. LONG lHeight = HIWORD(lParam);
  911. Fire_OnResize(lWidth, lHeight, wParam);
  912. if (m_pBackBitmap) {
  913. InvalidateRgn();
  914. if (::IsWindow(m_hWnd))
  915. ::UpdateWindow(m_hWnd);
  916. }
  917. bHandled = true;
  918. }
  919. catch(...){
  920. }
  921. return 0;
  922. }/* end of function OnSize */
  923. /*************************************************************************/
  924. /* Function: OnSizing */
  925. /* Description: Does not let us scale beyond the minimum size. If it */
  926. /* tries to we fix up the rect on it. */
  927. /*************************************************************************/
  928. LRESULT CMFBar::OnSizing(UINT, WPARAM wParam, LPARAM lParam, BOOL& bHandled){
  929. if(false == m_fSelfHosted){
  930. bHandled = FALSE;
  931. return 0;
  932. }/* end of if statement */
  933. RECT* lpRect = (LPRECT)lParam;
  934. LONG lWidth = RECTWIDTH(lpRect);
  935. LONG lHeight = RECTHEIGHT(lpRect);
  936. // if we are going to be to small fix the rect
  937. if(lWidth < m_lMinWidth){
  938. lpRect->right = lpRect->left + m_lMinWidth;
  939. }/* end of if statement */
  940. if(lHeight < m_lMinHeight){
  941. lpRect->bottom = lpRect->top + m_lMinHeight;
  942. }/* end of if statement */
  943. bHandled = true;
  944. return 0;
  945. }/* end of function OnSizing */
  946. /*************************************************************************/
  947. /* Function: Close */
  948. /* Description: Just exposes the underlaying Close functionality to our */
  949. /* custom interface. */
  950. /*************************************************************************/
  951. STDMETHODIMP CMFBar::Close(){
  952. if(::IsWindow(m_hWnd)){
  953. ::PostMessage(m_hWnd, WM_CLOSE, NULL, NULL);
  954. return(S_OK);
  955. //::DestroyWindow(m_hWnd);
  956. }/* end of if statement */
  957. return(Close(OLECLOSE_SAVEIFDIRTY));
  958. }/* end of function Close */
  959. /*************************************************************************/
  960. /* Function: Close */
  961. /* Description: Calls OLECLOSE the contained objects, then itself. */
  962. /* The cleans up the containers and send WM_QUIT if we are self hosting. */
  963. /*************************************************************************/
  964. STDMETHODIMP CMFBar::Close(DWORD dwSaveOption){
  965. HRESULT hr = DestroyScriptEngine();
  966. ATLASSERT(SUCCEEDED(hr));
  967. for(CNTOBJ::iterator i = m_cntObj.begin(); i!= m_cntObj.end(); i++){
  968. // iterate through all the contained objects and call on the Close
  969. CHostedObject* pObj = (*i);
  970. CComPtr<IOleObject> pIOleObject;
  971. HRESULT hrIOleObj = pObj->GetOleObject(&pIOleObject);
  972. if(FAILED(hr)){
  973. continue;
  974. }/* end of if statement */
  975. if(GetUnknown() == pObj->GetUnknown()){
  976. continue; // that is us we close our self later after the contained objects
  977. }/* end of if statement */
  978. pIOleObject->Close(dwSaveOption);
  979. }/* end of for loop */
  980. hr = IOleObjectImpl<CMFBar>::Close(dwSaveOption);
  981. bool fSelfHosted = m_fSelfHosted; // cache up the variable, since we are going to
  982. // wipe it out
  983. Cleanup(); // delete all the objects
  984. if(fSelfHosted){
  985. ::PostMessage(NULL, WM_QUIT, NULL, NULL); // tell our container to give up
  986. }/* end of if statement */
  987. return(hr);
  988. }/* end of function Close */
  989. /*************************************************************************/
  990. /* Function: ProcessMessages *
  991. /* Description: Process the windows messages. */
  992. /*************************************************************************/
  993. STDMETHODIMP CMFBar::ProcessMessages(){
  994. HRESULT hr = ::WaitMessage() ? S_OK: S_FALSE;
  995. return(hr);
  996. }/* end of function ProcessMessages */
  997. /*************************************************************************/
  998. /* Function: AddFocusObject */
  999. /* Description: Adds an object to the end of the focus array. */
  1000. /*************************************************************************/
  1001. STDMETHODIMP CMFBar::AddFocusObject(BSTR strObjectID){
  1002. HRESULT hr = S_OK;
  1003. try {
  1004. CHostedObject* pObj;
  1005. hr = FindObject(strObjectID, &pObj);
  1006. if(FAILED(hr)){
  1007. throw(hr);
  1008. }/* end of if statement */
  1009. m_cntFocus.insert(m_cntFocus.end(), pObj);
  1010. }
  1011. catch(HRESULT hrTmp){
  1012. hr = hrTmp;
  1013. }
  1014. catch(...){
  1015. hr = E_UNEXPECTED;
  1016. }/* end of try statement */
  1017. return (hr);
  1018. }/* end of function AddFocusObject */
  1019. /*************************************************************************/
  1020. /* Function: ResetFocusArray */
  1021. /* Description: Resets the focus array. */
  1022. /*************************************************************************/
  1023. STDMETHODIMP CMFBar::ResetFocusArray(){
  1024. HRESULT hr = S_OK;
  1025. try {
  1026. ResetFocusFlags();
  1027. // cleanup the focus array
  1028. for(CNTOBJ::iterator k = m_cntFocus.begin(); false == m_cntFocus.empty(); ){
  1029. k = m_cntFocus.erase(k);
  1030. }/* end of for loop */
  1031. }
  1032. catch(HRESULT hrTmp){
  1033. hr = hrTmp;
  1034. }
  1035. catch(...){
  1036. hr = E_UNEXPECTED;
  1037. }/* end of try statement */
  1038. return (hr);
  1039. }/* end of function ResetFocusArray */
  1040. /*************************************************************************/
  1041. /* Function: OnSetFocus */
  1042. /* Description: Iterates through the container and sends the focus */
  1043. /* message to the control that thinks it has the focus. */
  1044. /*************************************************************************/
  1045. LRESULT CMFBar::OnSetFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled){
  1046. bHandled = TRUE;
  1047. LONG lRes = 0;
  1048. if(m_cntObj.empty() == true){
  1049. return 0;
  1050. }/* end of if statement */
  1051. MoveFocus(TRUE, lRes);
  1052. return lRes;
  1053. }/* end of function OnSetFocus */
  1054. /*************************************************************************/
  1055. /* Function: OnHelpEnd */
  1056. /* Description: Resets the help */
  1057. /*************************************************************************/
  1058. LRESULT CMFBar::OnHelpEnd(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled){
  1059. bHandled = TRUE;
  1060. LONG lRes = 0;
  1061. m_fHandleHelp = false;
  1062. return lRes;
  1063. }/* end of function OnHelpEnd */
  1064. /*************************************************************************/
  1065. /* Function: OnUserFocus */
  1066. /* Description: Iterates through the container and sends the focus */
  1067. /* message to the control that thinks it has the focus. In this case */
  1068. /* the control is specified by hwnd and that it is a windowed control. */
  1069. /*************************************************************************/
  1070. LRESULT CMFBar::OnUserFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled){
  1071. bHandled = TRUE;
  1072. LONG lRes = 0;
  1073. if (!m_bHandleUserFocus) {
  1074. m_bHandleUserFocus = TRUE;
  1075. return lRes;
  1076. }
  1077. HRESULT hr = E_FAIL; // did not find the object
  1078. if(m_fHandleHelp){
  1079. ResetFocusFlags();
  1080. return(lRes);
  1081. }/* end of if statement */
  1082. for(CNTOBJ::iterator i = m_cntObj.begin(); i!= m_cntObj.end(); i++){
  1083. CHostedObject* pObj = (*i);
  1084. if(NULL == pObj){
  1085. continue;
  1086. }/* end of if statement */
  1087. HWND hwndCtrl = NULL;
  1088. hr = pObj->GetWindow(&hwndCtrl);
  1089. if(FAILED(hr)){
  1090. continue;
  1091. }/* end of if statement */
  1092. if(hwndCtrl == (HWND) wParam){
  1093. SetClosestFocus(lRes, pObj);
  1094. //SetObjectFocus(pObj, TRUE, lRes);
  1095. return(lRes);
  1096. }/* end of if statement */
  1097. }/* end of for loop */
  1098. return lRes;
  1099. }/* end of function OnUserFocus */
  1100. /*************************************************************************/
  1101. /* Function: OnKillFocus */
  1102. /* Description: Sends the kill focus message to the control that has */
  1103. /* Itterates through the container and removes the focus */
  1104. /* from the contained objects. */
  1105. /*************************************************************************/
  1106. LRESULT CMFBar::OnKillFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled){
  1107. bHandled = TRUE;
  1108. LONG lRes = 0;
  1109. ResetFocusFlags(); // cleanup the focus flags
  1110. return lRes;
  1111. }/* end of function OnKillFocus */
  1112. /*************************************************************************/
  1113. /* Function: OnMouseMessage */
  1114. /* Description: Handles the mouse messages, distrubutes to proper */
  1115. /* controls if needed. */
  1116. /*************************************************************************/
  1117. LRESULT CMFBar::OnMouseMessage(UINT uMsg, WPARAM wParam, LPARAM lParam,
  1118. BOOL& bHandled){
  1119. LONG lRes = 0;
  1120. bHandled = FALSE; // indicated if we dispatched the message
  1121. if(m_lTimeout > 0){
  1122. //WM_MOUSEMOVE messages keep comming over even if we really do not move the mouse
  1123. bool bResetActivity = false;
  1124. if(WM_MOUSEMOVE == uMsg){
  1125. static WPARAM wParTmp = 0;
  1126. static LPARAM lParTmp = 0;
  1127. if(wParam != wParTmp || lParam != lParTmp){
  1128. bResetActivity = true;
  1129. }/* end of if statement */
  1130. if(wParam & MK_CONTROL ||
  1131. wParam & MK_CONTROL ||
  1132. wParam & MK_LBUTTON ||
  1133. wParam & MK_MBUTTON ||
  1134. wParam & MK_RBUTTON ||
  1135. wParam & MK_SHIFT ){
  1136. bResetActivity = true;
  1137. }/* end of if statement */
  1138. lParTmp = lParam;
  1139. wParTmp = wParam;
  1140. }
  1141. else {
  1142. bResetActivity = true;
  1143. }/* end of if statement */
  1144. if(bResetActivity){
  1145. m_fUserActivity = true;
  1146. if(m_fWaitingForActivity){
  1147. Fire_ActivityStarted();
  1148. m_fWaitingForActivity = false;
  1149. }/* end of if statement */
  1150. }/* end of if statement */
  1151. }/* end of if statement */
  1152. ATLTRACE2(atlTraceWindowing, 32, TEXT("R WM_ button message : "));
  1153. if(!m_bMouseDown && m_HitRegion!=PRESIZE && m_HitRegion!=PREMOVE){
  1154. CHostedObject* pMouseCaptureObj = NULL;
  1155. // send the message to the control(s) that have the capture
  1156. if(false == m_fHandleHelp && GetCapture() == S_OK){
  1157. for(CNTOBJ::iterator i = m_cntObj.begin(); i!= m_cntObj.end(); i++){
  1158. // iterate through all the contained controls
  1159. CHostedObject* pObj = (*i);
  1160. if(NULL == pObj){
  1161. ATLASSERT(FALSE); // should not be null
  1162. continue;
  1163. }/* end of if statement */
  1164. // need to be able send message to the button with the capture
  1165. if(pObj->HasCapture()){
  1166. ATLTRACE2(atlTraceUser, 31, TEXT("Sending WM_ buttons message to button %ls \n"), pObj->GetID());
  1167. HRESULT hr = SendMessageToCtl(pObj, uMsg, wParam, lParam, bHandled, lRes);
  1168. if(SUCCEEDED(hr)){
  1169. if (WM_LBUTTONDOWN == uMsg) {
  1170. CComPtr<IViewObjectEx> pViewObject;
  1171. HRESULT hr = pObj->GetViewObject(&pViewObject);
  1172. if(FAILED(hr)){
  1173. ATLASSERT(FALSE); // should have a view
  1174. continue;
  1175. }/* end of if statement */
  1176. DWORD dwHitResult = HITRESULT_OUTSIDE;
  1177. POINT ptMouse = { LOWORD(lParam), HIWORD(lParam) };
  1178. RECT rcCntrl;
  1179. pObj->GetPos(&rcCntrl);
  1180. pViewObject->QueryHitPoint(DVASPECT_CONTENT, &rcCntrl, ptMouse, 0, &dwHitResult);
  1181. if(HITRESULT_HIT == dwHitResult){
  1182. if (WM_LBUTTONDOWN == uMsg) {
  1183. LONG lRes;
  1184. //SetObjectFocus(pObj, TRUE, lRes);
  1185. SetClosestFocus(lRes, pObj);
  1186. }/* end of if statement */
  1187. }/* end of if statement */
  1188. }/* end of if statement */
  1189. pMouseCaptureObj = pObj;
  1190. break; // send mouse message to only the one control that has capture
  1191. // then to the ones we hower over
  1192. }/* end of if statement */
  1193. }/* end of if statement */
  1194. }/* end of for loop */
  1195. }/* end of if statement */
  1196. // send the message to the control(s) that we are over, but not to the one
  1197. // that which had focus and we already send one
  1198. for(CNTOBJ::iterator i = m_cntObj.begin(); i!= m_cntObj.end(); i++){
  1199. // iterate through all the contained controls
  1200. CHostedObject* pObj = (*i);
  1201. if(NULL == pObj){
  1202. ATLASSERT(FALSE); // should not be null
  1203. continue;
  1204. }/* end of if statement */
  1205. // need to be able send message to the button with the capture
  1206. // send the message to the control over which we are howering or on which we
  1207. // have clicked, check if we already are ready to send the message
  1208. // in that case do not bother with the rect interstec bussines
  1209. if(!bHandled && pObj->IsWindowless() && pObj->IsInputEnabled()){
  1210. CComPtr<IViewObjectEx> pViewObject;
  1211. HRESULT hr = pObj->GetViewObject(&pViewObject);
  1212. if(FAILED(hr)){
  1213. ATLASSERT(FALSE); // should have a view
  1214. continue;
  1215. }/* end of if statement */
  1216. DWORD dwHitResult = HITRESULT_OUTSIDE;
  1217. POINT ptMouse = { LOWORD(lParam), HIWORD(lParam) };
  1218. RECT rcCntrl;
  1219. pObj->GetPos(&rcCntrl);
  1220. pViewObject->QueryHitPoint(DVASPECT_CONTENT, &rcCntrl, ptMouse, 0, &dwHitResult);
  1221. if(HITRESULT_HIT == dwHitResult){
  1222. // see if we are handling help, if so do not do anything else, but
  1223. // fire help with the control ID we are howering over
  1224. if(m_fHandleHelp){
  1225. if (WM_LBUTTONUP == uMsg) {
  1226. Fire_OnHelp(::SysAllocString(pObj->GetID()));
  1227. m_fHandleHelp = false;
  1228. }/* end of if statement */
  1229. bHandled = TRUE;
  1230. return(lRes);
  1231. }
  1232. else {
  1233. if(pMouseCaptureObj == pObj){
  1234. continue; // we already have send message to this control
  1235. // do not do it again
  1236. }/* end of if statememt */
  1237. ATLTRACE2(atlTraceUser, 31, TEXT("Sending WM_ buttons message to button %ls \n"), pObj->GetID());
  1238. SendMessageToCtl(pObj, uMsg, wParam, lParam, bHandled, lRes);
  1239. if (WM_LBUTTONDOWN == uMsg) {
  1240. LONG lRes;
  1241. //SetObjectFocus(pObj, TRUE, lRes);
  1242. SetClosestFocus(lRes, pObj);
  1243. }/* end of if statement */
  1244. }/* end of if statement */
  1245. }/* end of if statement */
  1246. }/* end of if statement */
  1247. }/* end of for loop */
  1248. }/* end of if statement */
  1249. if(TRUE == bHandled){
  1250. // we send some messages to a control, so there is no need to handle container now
  1251. return(lRes);
  1252. }/* end of if statement */
  1253. // we are not over any control so we might be over container itself, so handle
  1254. // the mouse message appropriately
  1255. ATLTRACE2(atlTraceWindowing, 32, TEXT("Not forwarding the message to the controls\n"));
  1256. if(WM_LBUTTONDOWN == uMsg) {
  1257. Fire_OnMouseDown();
  1258. }
  1259. if(WM_LBUTTONUP == uMsg || WM_LBUTTONDBLCLK == uMsg){
  1260. // TODO: Fire the click only if we are on our window or bitmap
  1261. if(m_fHandleHelp){
  1262. BSTR strToolbarName;
  1263. if(SUCCEEDED(GetToolbarName(&strToolbarName))){
  1264. Fire_OnHelp(strToolbarName);
  1265. }/* end of if statement */
  1266. m_fHandleHelp = false;
  1267. }
  1268. else {
  1269. if(WM_LBUTTONUP == uMsg){
  1270. Fire_OnClick();
  1271. Fire_OnMouseUp();
  1272. }
  1273. else {
  1274. Fire_OnDblClick();
  1275. }/* end of if statement */
  1276. }/* end of if statement */
  1277. }/* end of if statement */
  1278. // handle the moving of the container window
  1279. if(m_fSelfHosted && !m_fHandleHelp){
  1280. if(WM_LBUTTONDOWN == uMsg){
  1281. OnButtonDown(uMsg, wParam, lParam, bHandled);
  1282. }/* end of if statement */
  1283. if(WM_MOUSEMOVE == uMsg){
  1284. OnMouseMove(uMsg, wParam, lParam, bHandled);
  1285. }/* end of if statement */
  1286. if(WM_LBUTTONUP == uMsg){
  1287. OnButtonUp(uMsg, wParam, lParam, bHandled);
  1288. }/* end of if statement */
  1289. // Right click on the title bar
  1290. if(WM_RBUTTONDOWN == uMsg) {
  1291. POINT ptMouse = {GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)};
  1292. if (ptMouse.y <= SYS_TITLEBAR_WIDTH) {
  1293. ::ClientToScreen(m_hWnd, &ptMouse);
  1294. PopupSystemMenu(ptMouse.x, ptMouse.y);
  1295. }/* end of if statement */
  1296. }/* end of if statement */
  1297. }/* end of if statement */
  1298. return(lRes);
  1299. }/* end of function OnMouseMessage */
  1300. /*************************************************************************/
  1301. /* Function: OnSetCursor */
  1302. /* Description: Handles the WM_SETCURSOR messages, distrubutes to proper */
  1303. /* controls if needed. */
  1304. /*************************************************************************/
  1305. LRESULT CMFBar::OnSetCursor(UINT uMsg, WPARAM wParam, LPARAM lParam,
  1306. BOOL& bHandled){
  1307. LONG lRes = 0;
  1308. if(!::IsWindow(m_hWnd)){
  1309. return lRes;
  1310. }/* end of if statement */
  1311. if (m_HitRegion == PRESIZE || m_HitRegion == PREMOVE) {
  1312. return lRes;
  1313. }
  1314. bHandled = FALSE;
  1315. if(m_cntObj.empty() == true){
  1316. return 0;
  1317. }/* end of if statement */
  1318. CHostedObject* pMouseCaptureObj = NULL;
  1319. // send the message to the control(s) that have the capture
  1320. if(false == m_fHandleHelp && GetCapture() == S_OK){
  1321. for(CNTOBJ::iterator i = m_cntObj.begin(); i!= m_cntObj.end(); i++){
  1322. // iterate through all the contained controls
  1323. CHostedObject* pObj = (*i);
  1324. if(NULL == pObj){
  1325. ATLASSERT(FALSE); // should not be null
  1326. continue;
  1327. }/* end of if statement */
  1328. // need to be able send message to the button with the capture
  1329. if(pObj->HasCapture()){
  1330. ATLTRACE2(atlTraceUser, 31, TEXT("Sending WM_SETCURSOR message to button %ls \n"), pObj->GetID());
  1331. HRESULT hr = SendMessageToCtl(pObj, uMsg, wParam, lParam, bHandled, lRes);
  1332. #if 0
  1333. if(SUCCEEDED(hr)){
  1334. return(lRes);
  1335. }/* end of if statement */
  1336. #endif
  1337. }/* end of if statement */
  1338. }/* end of for loop */
  1339. }/* end of if statement */
  1340. DWORD dwValue = ::GetMessagePos();
  1341. POINT ptMouse = {GET_X_LPARAM(dwValue), GET_Y_LPARAM(dwValue)};
  1342. ::ScreenToClient(m_hWnd, &ptMouse);
  1343. // send the message to the control(s) that we are over, but not to the one
  1344. // that which had focus and we already send one
  1345. for(CNTOBJ::iterator i = m_cntObj.begin(); i!= m_cntObj.end(); i++){
  1346. // iterate through all the contained controls
  1347. CHostedObject* pObj = (*i);
  1348. if(NULL == pObj){
  1349. ATLASSERT(FALSE); // should not be null
  1350. continue;
  1351. }/* end of if statement */
  1352. // need to be able send message to the button with the capture
  1353. // send the message to the control over which we are howering or on which we
  1354. // have clicked, check if we already are ready to send the message
  1355. // in that case do not bother with the rect interstec bussines
  1356. if(pObj->IsWindowless()){
  1357. CComPtr<IViewObjectEx> pViewObject;
  1358. HRESULT hr = pObj->GetViewObject(&pViewObject);
  1359. if(FAILED(hr)){
  1360. ATLASSERT(FALSE); // should have a view
  1361. continue;
  1362. }/* end of if statement */
  1363. DWORD dwHitResult = HITRESULT_OUTSIDE;
  1364. RECT rcCntrl;
  1365. pObj->GetPos(&rcCntrl);
  1366. pViewObject->QueryHitPoint(DVASPECT_CONTENT, &rcCntrl, ptMouse, 0, &dwHitResult);
  1367. if(HITRESULT_HIT == dwHitResult){
  1368. // see if we are handling help, if so do not do anything else, but
  1369. // fire help with the control ID we are howering over
  1370. if(m_fHandleHelp){
  1371. bHandled = FALSE;
  1372. return(lRes);
  1373. }
  1374. else {
  1375. if(pMouseCaptureObj == pObj){
  1376. continue; // we already have send message to this control
  1377. // do not do it again
  1378. }/* end of if statememt */
  1379. ATLTRACE2(atlTraceUser, 31, TEXT("Sending WM_SETCURSOR message to button %ls \n"), pObj->GetID());
  1380. SendMessageToCtl(pObj, uMsg, wParam, lParam, bHandled, lRes);
  1381. if(SUCCEEDED(hr)){
  1382. return(lRes);
  1383. }/* end of if statement */
  1384. }/* end of if statement */
  1385. }/* end of if statement */
  1386. }/* end of if statement */
  1387. }/* end of for loop */
  1388. return lRes;
  1389. }
  1390. /*************************************************************************/
  1391. /* Function: OnKeyMessage */
  1392. /* Description: Distrubutes the keyboard messages properly. */
  1393. /*************************************************************************/
  1394. LRESULT CMFBar::OnKeyMessage(UINT uMsg, WPARAM wParam, LPARAM lParam,
  1395. BOOL& bHandled){
  1396. m_fUserActivity = true;
  1397. static bool fHandleKeyUp = false; // when onther child window closes on top
  1398. // of us we get an UP message without down
  1399. // this should.. eat it up
  1400. if(uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN){
  1401. fHandleKeyUp = true;
  1402. }/* end of if statement */
  1403. if(m_fWaitingForActivity){
  1404. Fire_ActivityStarted();
  1405. m_fWaitingForActivity = false;
  1406. }/* end of if statement */
  1407. if(uMsg == WM_KEYUP || uMsg == WM_SYSKEYUP){
  1408. if(!fHandleKeyUp){
  1409. fHandleKeyUp = false;
  1410. return 0;
  1411. }/* end of if statement */
  1412. fHandleKeyUp = false;
  1413. }/* end of if statement */
  1414. bHandled = FALSE;
  1415. LONG lRes = 0;
  1416. VARIANT_BOOL fEat = VARIANT_FALSE;
  1417. LONG lEnable = 1; // using long since the framework will not handle short
  1418. LONG lVirtKey = (LONG) wParam;
  1419. LONG lKeyData = (LONG) lParam;
  1420. m_fForceKey = false; // reset the flag, the change in the value would indicate
  1421. // that we have received call to force key during the event
  1422. // processing
  1423. // Handle keys for manual move and size
  1424. HandleMoveSizeKey(uMsg, wParam, lParam, bHandled);
  1425. if (bHandled)
  1426. return lRes;
  1427. if (!m_bHandleEnter && !m_bSysMenuOn) {
  1428. if(WM_KEYDOWN == uMsg)
  1429. Fire_OnKeyDown(lVirtKey, lKeyData);
  1430. else if (WM_KEYUP == uMsg)
  1431. Fire_OnKeyUp(lVirtKey, lKeyData);
  1432. ATLTRACE2(atlTraceWindowing, 4, TEXT("OnKeyMessage Fire_OnKey message\n"));
  1433. }/* end of if statement */
  1434. if(WM_SYSKEYDOWN == uMsg){
  1435. Fire_OnSysKeyDown(lVirtKey, lKeyData);
  1436. }/* end of if statement */
  1437. if(WM_SYSKEYUP == uMsg){
  1438. Fire_OnSysKeyUp(lVirtKey, lKeyData);
  1439. }/* end of if statement */
  1440. if(m_fForceKey){
  1441. fEat = m_fEat;
  1442. lVirtKey = m_lVirtKey;
  1443. lKeyData = m_lKeyData;
  1444. }/* end of if statement */
  1445. if(VARIANT_FALSE == fEat){
  1446. if(WM_KEYUP == uMsg ){
  1447. switch(lVirtKey){
  1448. case VK_TAB:
  1449. bool fForward = true;
  1450. if(::GetKeyState(VK_SHIFT) < 0){
  1451. fForward = false;
  1452. }/* end of if statement */
  1453. MoveFocus(fForward, lRes);
  1454. return(lRes);
  1455. }/* end of switch statement */
  1456. }/* end of if statement */
  1457. if (m_bHandleEnter || m_bSysMenuOn)
  1458. return lRes;
  1459. // iterates through the controls and send these key messages to the one
  1460. // with focus
  1461. CNTOBJ::iterator i;
  1462. for(i = m_cntObj.begin(); i!= m_cntObj.end(); i++){
  1463. // iterate through all the contained controls
  1464. CHostedObject* pObj = (*i);
  1465. if(NULL == pObj){
  1466. ATLASSERT(FALSE);
  1467. continue;
  1468. }/* end of if statement */
  1469. if(pObj->HasFocus()){
  1470. // handle help
  1471. if(WM_KEYUP == uMsg && VK_F1 == lVirtKey){
  1472. Fire_OnHelp(::SysAllocString(pObj->GetID()));
  1473. }/* end of if statement */
  1474. HRESULT hr = SendMessageToCtl(pObj, uMsg, lVirtKey, lKeyData, bHandled, lRes, false);
  1475. ATLTRACE2(atlTraceWindowing, 4, TEXT("OnKeyMessage SendMessageToCtl\n"));
  1476. if(SUCCEEDED(hr)){
  1477. return(lRes);
  1478. }/* end of if statement */
  1479. }/* end of if statement */
  1480. }/* end of for loop */
  1481. // handle help
  1482. if(WM_KEYUP == uMsg && VK_F1 == lVirtKey){
  1483. BSTR strToolbarName;
  1484. if(SUCCEEDED(GetToolbarName(&strToolbarName))){
  1485. USES_CONVERSION;
  1486. Fire_OnHelp(strToolbarName, NULL);
  1487. //m_fHandleHelp = false;
  1488. }/* end of if statement */
  1489. }/* end of if statement */
  1490. }/* end of if statement */
  1491. return(lRes);
  1492. }/* end of function OnKeyMessage */
  1493. /*************************************************************/
  1494. /* Name: HandleMoveSizeKey
  1495. /* Description: Handle arrows for manual move and size
  1496. /*************************************************************/
  1497. LRESULT CMFBar::HandleMoveSizeKey(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  1498. {
  1499. LONG lRes = 0;
  1500. bHandled = TRUE;
  1501. LONG lVirtKey = (LONG) wParam;
  1502. LONG lKeyData = (LONG) lParam;
  1503. POINT point = m_ptMouse;
  1504. // Get Window rc
  1505. RECT rc;
  1506. ::GetClientRect(m_hWnd, &rc);
  1507. // Get Desktop rc
  1508. RECT rcDeskt;
  1509. ::GetWindowRect(::GetDesktopWindow(), &rcDeskt);
  1510. ATLTRACE2(atlTraceWindowing, 4, TEXT("OnKeyMessage m_bHandleEnter %d\n"), m_bHandleEnter);
  1511. if (lVirtKey == VK_ESCAPE || lVirtKey == VK_SELECT || lVirtKey == VK_SPACE || lVirtKey == VK_RETURN) {
  1512. if (WM_KEYDOWN == uMsg) {
  1513. if (m_bHandleEnter) {
  1514. if (lVirtKey == VK_ESCAPE) {
  1515. ::MoveWindow(m_hWnd, m_rcWndOld.left, m_rcWndOld.top, RECTWIDTH(&m_rcWndOld), RECTHEIGHT(&m_rcWndOld), TRUE);
  1516. }
  1517. point = m_ptMouseOld;
  1518. LONG lx = LONG((FLOAT)point.x/ RECTWIDTH(&rcDeskt) * 0xFFFF);
  1519. LONG ly = LONG((FLOAT)point.y/ RECTHEIGHT(&rcDeskt) * 0xFFFF);
  1520. mouse_event(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_LEFTUP, lx, ly, 0, 0);
  1521. mouse_event(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE, lx, ly, 0, 0);
  1522. return lRes;
  1523. }
  1524. }
  1525. else if (WM_KEYUP == uMsg) {
  1526. if (m_bHandleEnter && !m_bMouseDown &&
  1527. m_HitRegion!=PRESIZE && m_HitRegion!=PREMOVE) {
  1528. m_bHandleEnter = FALSE;
  1529. return lRes;
  1530. }
  1531. } /* end of if statement */
  1532. } /* end of if statement */
  1533. if (WM_KEYDOWN == uMsg &&
  1534. (lVirtKey == VK_LEFT || lVirtKey == VK_RIGHT||
  1535. lVirtKey == VK_UP || lVirtKey == VK_DOWN)) {
  1536. POINT leftTop = {SYS_MOVE_SIZE, SYS_MOVE_SIZE};
  1537. POINT rightBottom = {rc.right-SYS_MOVE_SIZE, rc.bottom-SYS_MOVE_SIZE};
  1538. POINT scLeftTop = leftTop;
  1539. ::ClientToScreen(m_hWnd, &scLeftTop);
  1540. POINT scRightBottom = rightBottom;
  1541. ::ClientToScreen(m_hWnd, &scRightBottom);
  1542. LONG left = LONG((FLOAT)scLeftTop.x/ RECTWIDTH(&rcDeskt) * 0xFFFF);
  1543. LONG top = LONG((FLOAT)scLeftTop.y/ RECTHEIGHT(&rcDeskt) * 0xFFFF);
  1544. LONG right = LONG((FLOAT)scRightBottom.x/ RECTWIDTH(&rcDeskt) * 0xFFFF);
  1545. LONG bottom = LONG((FLOAT)scRightBottom.y/ RECTHEIGHT(&rcDeskt) * 0xFFFF);
  1546. if (m_HitRegion == PREMOVE) {
  1547. POINT point = {(rc.left+rc.right)/2, rc.top + SYS_TITLEBAR_WIDTH/2};
  1548. POINT screenPt = point;
  1549. ::ClientToScreen(m_hWnd, &screenPt);
  1550. LONG lx = LONG((FLOAT)screenPt.x/ RECTWIDTH(&rcDeskt) * 0xFFFF);
  1551. LONG ly = LONG((FLOAT)screenPt.y/ RECTHEIGHT(&rcDeskt) * 0xFFFF);
  1552. m_HitRegion = NOHIT;
  1553. mouse_event(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE, lx, ly, 0, 0);
  1554. mouse_event(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_LEFTDOWN, lx, ly, 0, 0);
  1555. return lRes;
  1556. }
  1557. else if (m_HitRegion == PRESIZE) {
  1558. m_HitRegion = NOHIT;
  1559. switch (lVirtKey) {
  1560. case VK_LEFT:
  1561. mouse_event(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE, left, (top+bottom)/2, 0, 0);
  1562. mouse_event(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_LEFTDOWN, left, (top+bottom)/2, 0, 0);
  1563. break;
  1564. case VK_RIGHT:
  1565. mouse_event(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE, right, (top+bottom)/2, 0, 0);
  1566. mouse_event(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_LEFTDOWN, right, (top+bottom)/2, 0, 0);
  1567. break;
  1568. case VK_UP:
  1569. mouse_event(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE, (left+right)/2, top, 0, 0);
  1570. mouse_event(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_LEFTDOWN, (left+right)/2, top, 0, 0);
  1571. break;
  1572. case VK_DOWN:
  1573. mouse_event(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE, (left+right)/2, bottom, 0, 0);
  1574. mouse_event(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_LEFTDOWN, (left+right)/2, bottom, 0, 0);
  1575. break;
  1576. } /* end of switch statement */
  1577. return lRes;
  1578. }
  1579. else if (m_bMouseDown) {
  1580. switch (lVirtKey) {
  1581. case VK_LEFT:
  1582. if (!(m_HitRegion&RIGHT || m_HitRegion&LEFT) && m_HitRegion!=NOHIT) {
  1583. m_HitRegion = (HitRegion) (m_HitRegion | LEFT);
  1584. mouse_event(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE, left, m_HitRegion&BOTTOM?bottom:top, 0, 0);
  1585. mouse_event(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_LEFTDOWN, left, m_HitRegion&BOTTOM?bottom:top, 0, 0);
  1586. return lRes;
  1587. }
  1588. if (!(m_HitRegion&RIGHT && RECTWIDTH(&rc)-SYS_MOVE_SIZE<=m_lMinWidth))
  1589. point.x -= SYS_MOVE_SIZE;
  1590. break;
  1591. case VK_RIGHT:
  1592. if (!(m_HitRegion&RIGHT || m_HitRegion&LEFT) && m_HitRegion!=NOHIT) {
  1593. m_HitRegion = (HitRegion) (m_HitRegion | RIGHT);
  1594. mouse_event(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE, right, m_HitRegion&BOTTOM?bottom:top, 0, 0);
  1595. mouse_event(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_LEFTDOWN, right, m_HitRegion&BOTTOM?bottom:top, 0, 0);
  1596. return lRes;
  1597. }
  1598. if (!(m_HitRegion&LEFT && RECTWIDTH(&rc)-SYS_MOVE_SIZE<=m_lMinWidth))
  1599. point.x += SYS_MOVE_SIZE;
  1600. break;
  1601. case VK_UP:
  1602. if (!(m_HitRegion&TOP || m_HitRegion&BOTTOM) && m_HitRegion!=NOHIT) {
  1603. m_HitRegion = (HitRegion) (m_HitRegion | TOP);
  1604. mouse_event(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE, m_HitRegion&RIGHT?right:left, top, 0, 0);
  1605. mouse_event(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_LEFTDOWN, m_HitRegion&RIGHT?right:left, top, 0, 0);
  1606. return lRes;
  1607. }
  1608. if (!(m_HitRegion&BOTTOM && RECTHEIGHT(&rc)-SYS_MOVE_SIZE<=m_lMinHeight))
  1609. point.y -= SYS_MOVE_SIZE;
  1610. break;
  1611. case VK_DOWN:
  1612. if (!(m_HitRegion&TOP || m_HitRegion&BOTTOM) && m_HitRegion!=NOHIT) {
  1613. m_HitRegion = (HitRegion) (m_HitRegion | BOTTOM);
  1614. mouse_event(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE, m_HitRegion&RIGHT?right:left, bottom, 0, 0);
  1615. mouse_event(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_LEFTDOWN, m_HitRegion&RIGHT?right:left, bottom, 0, 0);
  1616. return lRes;
  1617. }
  1618. if (!(m_HitRegion&TOP && RECTHEIGHT(&rc)-SYS_MOVE_SIZE<=m_lMinHeight))
  1619. point.y += SYS_MOVE_SIZE;
  1620. break;
  1621. } /* end of switch statement */
  1622. ::SetCursorPos(point.x, point.y);
  1623. return lRes;
  1624. }/* end of if statement */
  1625. }
  1626. bHandled = FALSE;
  1627. return lRes;
  1628. } /*HandleMoveSizekey*/
  1629. /*************************************************************************/
  1630. /* Function: OnDispChange */
  1631. /* Description: Forwards this message to all the controls. */
  1632. /*************************************************************************/
  1633. LRESULT CMFBar::OnDispChange(UINT uMsg, WPARAM wParam, LPARAM lParam,
  1634. BOOL& bHandled){
  1635. LONG lRes =0;
  1636. long cBitsPerPixel = wParam;
  1637. long cxScreen = LOWORD(lParam);
  1638. long cyScreen = HIWORD(lParam);
  1639. if (NULL != m_pBackBitmap)
  1640. m_pBackBitmap->OnDispChange(cBitsPerPixel, cxScreen, cyScreen);
  1641. for(CNTOBJ::iterator i = m_cntObj.begin(); i!= m_cntObj.end(); i++){
  1642. CHostedObject* pObj = (*i);
  1643. if(NULL == pObj){
  1644. continue;
  1645. }/* end of if statement */
  1646. SendMessageToCtl(pObj, uMsg, wParam, lParam, bHandled, lRes, true, false);
  1647. }/* end of for loop */
  1648. return(lRes);
  1649. }/* end of function OnDispChange */
  1650. /*************************************************************************/
  1651. /* Function: AdvanceIterator */
  1652. /* Description: Helper inline function that helps to keep track which */
  1653. /* direction we are advancing. */
  1654. /*************************************************************************/
  1655. void AdvanceIterator(CNTOBJ::iterator& i, bool fForward){
  1656. if(fForward){
  1657. i++;
  1658. }
  1659. else {
  1660. i--;
  1661. }/* end of if statement */
  1662. }/* end of function AdvanceIterator */
  1663. /*************************************************************************/
  1664. /* Function: MoveFocus */
  1665. /* Descrition: Moves focus through the objects in forward or reverse */
  1666. /* direction. */
  1667. /*************************************************************************/
  1668. HRESULT CMFBar::MoveFocus(bool fForward, LONG& lRes){
  1669. HRESULT hr = S_OK;
  1670. if(true == m_cntFocus.empty()){
  1671. return(S_FALSE);
  1672. }/* end of if statement */
  1673. // first remove the focus and remeber the object
  1674. CHostedObject* pLastFocusObject = NULL;
  1675. CNTOBJ::iterator i, iEnd;
  1676. if(fForward){
  1677. i = m_cntFocus.begin();
  1678. iEnd = m_cntFocus.end();
  1679. iEnd--;
  1680. }
  1681. else {
  1682. i = m_cntFocus.end();
  1683. i--;
  1684. iEnd = m_cntFocus.begin();
  1685. }/* end of if statement */
  1686. BOOL bFirst = TRUE;
  1687. do {
  1688. // do not advance if first time in the loop
  1689. if (!bFirst)
  1690. AdvanceIterator(i, fForward);
  1691. else
  1692. bFirst = FALSE;
  1693. // iterate through all the contained controls
  1694. CHostedObject* pObj = (*i);
  1695. if(NULL == pObj){
  1696. ATLASSERT(FALSE);
  1697. continue;
  1698. }/* end of if statement */
  1699. if(pObj->HasFocus()){
  1700. LONG lRes;
  1701. SetObjectFocus(pObj, FALSE, lRes);
  1702. pLastFocusObject = pObj;
  1703. continue; // get to the next object
  1704. }/* end of if statement */
  1705. // try to set the focus to the next object
  1706. if(NULL != pLastFocusObject){
  1707. if(pObj->IsInputEnabled()){
  1708. LONG lRes = 0;
  1709. HRESULT hr = SetObjectFocus(pObj, TRUE, lRes);
  1710. if(FAILED(hr)){
  1711. continue; // this is the container so skip it
  1712. }/* end of if statement */
  1713. if(-1 == lRes){
  1714. // did not want to handle focus, since the button is disabled
  1715. SetObjectFocus(pObj, FALSE, lRes);
  1716. continue;
  1717. }/* end of if statement */
  1718. return(hr);
  1719. }/* end of if statement */
  1720. }/* end of if statement */
  1721. } while (i != iEnd); /* end of do loop */
  1722. // OK lets try to set focus to somebody before
  1723. //CNTOBJ::iterator i;
  1724. if(fForward){
  1725. i = m_cntFocus.begin();
  1726. iEnd = m_cntFocus.end();
  1727. iEnd--;
  1728. }
  1729. else {
  1730. i = m_cntFocus.end();
  1731. i--;
  1732. iEnd = m_cntFocus.begin();
  1733. }/* end of if statement */
  1734. bFirst = TRUE;
  1735. do {
  1736. // do not advance if first time in the loop
  1737. if (!bFirst)
  1738. AdvanceIterator(i, fForward);
  1739. else
  1740. bFirst = FALSE;
  1741. // iterate through all the contained controls
  1742. CHostedObject* pObj = (*i);
  1743. if(NULL == pObj){
  1744. ATLASSERT(FALSE);
  1745. continue;
  1746. }/* end of if statement */
  1747. if(pObj->IsInputEnabled()){
  1748. LONG lRes = 0;
  1749. HRESULT hr = SetObjectFocus(pObj, TRUE, lRes);
  1750. if(FAILED(hr)){
  1751. continue; // this is the container so skip it
  1752. }/* end of if statement */
  1753. if(-1 == lRes){
  1754. // did not want to handle focus, since the button is disabled
  1755. SetObjectFocus(pObj, FALSE, lRes);
  1756. continue;
  1757. }/* end of if statement */
  1758. return(hr);
  1759. }/* end of if statement */
  1760. } while (i != iEnd); /* end of do loop */
  1761. //ATLASSERT(FALSE); // should not really hapen, to have all the objects disabled
  1762. return(hr);
  1763. }/* end of function MoveFocus */
  1764. /*************************************************************************/
  1765. /* Function: SetClosestFocus */
  1766. /* Descrition: Sets the focus to the closes object to pObj if specified. */
  1767. /*************************************************************************/
  1768. HRESULT CMFBar::SetClosestFocus(LONG& lRes, CHostedObject* pStartObj, bool fForward){
  1769. HRESULT hr = S_OK;
  1770. if(m_cntFocus.empty()){
  1771. hr = S_FALSE;
  1772. return(hr);
  1773. }/* end of if statement */
  1774. ResetFocusFlags();
  1775. // first remove the focus and remeber the object
  1776. bool fStartSettingFocus = false;
  1777. CNTOBJ::iterator i, iEnd;
  1778. if(fForward){
  1779. i = m_cntFocus.begin();
  1780. iEnd = m_cntFocus.end();
  1781. iEnd--;
  1782. }
  1783. else {
  1784. i = m_cntFocus.end();
  1785. i--;
  1786. iEnd = m_cntFocus.begin();
  1787. }/* end of if statement */
  1788. if(NULL == pStartObj){
  1789. pStartObj = (*i); // initialize our start object
  1790. }/* end of if statement */
  1791. BOOL bFirst = TRUE;
  1792. do {
  1793. // do not advance if first time in the loop
  1794. if (!bFirst)
  1795. AdvanceIterator(i, fForward);
  1796. else
  1797. bFirst = FALSE;
  1798. // iterate through all the contained controls
  1799. CHostedObject* pObj = (*i);
  1800. if(NULL == pObj){
  1801. ATLASSERT(FALSE);
  1802. continue;
  1803. }/* end of if statement */
  1804. if(pObj == pStartObj){
  1805. fStartSettingFocus = true;
  1806. }/* end of if statement */
  1807. // try to set the focus to the next object
  1808. if(fStartSettingFocus ){
  1809. if(pObj->IsInputEnabled()){
  1810. LONG lRes = 0;
  1811. HRESULT hr = SetObjectFocus(pObj, TRUE, lRes);
  1812. if(FAILED(hr)){
  1813. continue; // this is the container so skip it
  1814. }/* end of if statement */
  1815. if(-1 == lRes){
  1816. // did not want to handle focus, since the button is disabled
  1817. SetObjectFocus(pObj, FALSE, lRes);
  1818. continue;
  1819. }/* end of if statement */
  1820. return(hr);
  1821. }/* end of if statement */
  1822. }/* end of if statement */
  1823. } while (i != iEnd); /* end of do loop */
  1824. if(!fStartSettingFocus){
  1825. hr = S_FALSE;
  1826. return(hr);
  1827. }/* end of if statement */
  1828. // OK lets try to set focus to somebody before
  1829. //CNTOBJ::iterator i;
  1830. if(fForward){
  1831. i = m_cntFocus.begin();
  1832. iEnd = m_cntFocus.end();
  1833. iEnd--;
  1834. }
  1835. else {
  1836. i = m_cntFocus.end();
  1837. i--;
  1838. iEnd = m_cntFocus.begin();
  1839. }/* end of if statement */
  1840. bFirst = TRUE;
  1841. do {
  1842. // do not advance if first time in the loop
  1843. if (!bFirst)
  1844. AdvanceIterator(i, fForward);
  1845. else
  1846. bFirst = FALSE;
  1847. // iterate through all the contained controls
  1848. CHostedObject* pObj = (*i);
  1849. if(NULL == pObj){
  1850. ATLASSERT(FALSE);
  1851. continue;
  1852. }/* end of if statement */
  1853. if(pObj->IsInputEnabled()){
  1854. LONG lRes = 0;
  1855. HRESULT hr = SetObjectFocus(pObj, TRUE, lRes);
  1856. if(FAILED(hr)){
  1857. continue; // this is the container so skip it
  1858. }/* end of if statement */
  1859. if(-1 == lRes){
  1860. // did not want to handle focus, since the button is disabled
  1861. SetObjectFocus(pObj, FALSE, lRes);
  1862. continue;
  1863. }/* end of if statement */
  1864. return(hr);
  1865. }/* end of if statement */
  1866. } while (i != iEnd); /* end of do loop */
  1867. ATLASSERT(FALSE); // should not really hapen, to have all the objects disabled
  1868. return(hr);
  1869. }/* end of function SetClosestFocus */
  1870. /*************************************************************************/
  1871. /* Function: OnForwardMsg */
  1872. /* Description: Forwards the message to the active object. */
  1873. /*************************************************************************/
  1874. LRESULT CMFBar::OnForwardMsg(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/){
  1875. ATLTRACE2(atlTraceHosting, 2, TEXT("CMFBar::OnForwardMsg\n"));
  1876. ATLASSERT(lParam != 0);
  1877. LPMSG lpMsg = (LPMSG)lParam;
  1878. if(m_spActiveObject){
  1879. if(m_spActiveObject->TranslateAccelerator(lpMsg) == S_OK)
  1880. return 1;
  1881. }/* end of function OnForwardMessage */
  1882. return 0;
  1883. }/* end of function OnForwardMessage */
  1884. /*************************************************************************/
  1885. /* Function: ReflectNotifications */
  1886. /* Description: Reflects the messages to the child windows */
  1887. /*************************************************************************/
  1888. LRESULT CMFBar::ReflectNotifications(UINT uMsg, WPARAM wParam, LPARAM lParam,
  1889. BOOL& bHandled){
  1890. HWND hWndChild = NULL;
  1891. switch(uMsg){
  1892. case WM_COMMAND:
  1893. if(lParam != NULL) // not from a menu
  1894. hWndChild = (HWND)lParam;
  1895. break;
  1896. case WM_NOTIFY:
  1897. hWndChild = ((LPNMHDR)lParam)->hwndFrom;
  1898. break;
  1899. case WM_PARENTNOTIFY:
  1900. switch(LOWORD(wParam))
  1901. {
  1902. case WM_CREATE:
  1903. case WM_DESTROY:
  1904. hWndChild = (HWND)lParam;
  1905. break;
  1906. default:
  1907. hWndChild = GetDlgItem(HIWORD(wParam));
  1908. break;
  1909. }
  1910. break;
  1911. case WM_DRAWITEM:
  1912. if(wParam) // not from a menu
  1913. hWndChild = ((LPDRAWITEMSTRUCT)lParam)->hwndItem;
  1914. break;
  1915. case WM_MEASUREITEM:
  1916. if(wParam) // not from a menu
  1917. hWndChild = GetDlgItem(((LPMEASUREITEMSTRUCT)lParam)->CtlID);
  1918. break;
  1919. case WM_COMPAREITEM:
  1920. if(wParam) // not from a menu
  1921. hWndChild = GetDlgItem(((LPCOMPAREITEMSTRUCT)lParam)->CtlID);
  1922. break;
  1923. case WM_DELETEITEM:
  1924. if(wParam) // not from a menu
  1925. hWndChild = GetDlgItem(((LPDELETEITEMSTRUCT)lParam)->CtlID);
  1926. break;
  1927. case WM_VKEYTOITEM:
  1928. case WM_CHARTOITEM:
  1929. case WM_HSCROLL:
  1930. case WM_VSCROLL:
  1931. hWndChild = (HWND)lParam;
  1932. break;
  1933. case WM_CTLCOLORBTN:
  1934. case WM_CTLCOLORDLG:
  1935. case WM_CTLCOLOREDIT:
  1936. case WM_CTLCOLORLISTBOX:
  1937. case WM_CTLCOLORMSGBOX:
  1938. case WM_CTLCOLORSCROLLBAR:
  1939. case WM_CTLCOLORSTATIC:
  1940. hWndChild = (HWND)lParam;
  1941. break;
  1942. default:
  1943. break;
  1944. }/* end of switch statement */
  1945. if(hWndChild == NULL){
  1946. bHandled = FALSE;
  1947. return 1;
  1948. }/* end of if statememnt */
  1949. ATLASSERT(::IsWindow(hWndChild));
  1950. return ::SendMessage(hWndChild, OCM__BASE + uMsg, wParam, lParam);
  1951. }/* end of function ReflectNotifications */
  1952. /*************************************************************************/
  1953. /* Function: put_Caption */
  1954. /* Description: Sets the caption to the window if present and handles */
  1955. /* the ambient property implementation. */
  1956. /*************************************************************************/
  1957. STDMETHODIMP CMFBar::put_Caption(BSTR bstrCaption){
  1958. ATLTRACE2(atlTraceControls,2,_T("CStockPropImpl::put_Caption\n"));
  1959. HRESULT hr = S_OK;
  1960. if (FireOnRequestEdit(DISPID_CAPTION) == S_FALSE){
  1961. return S_FALSE;
  1962. }/* end of if statement */
  1963. m_bstrCaption = bstrCaption;
  1964. m_bRequiresSave = TRUE;
  1965. FireOnChanged(DISPID_CAPTION);
  1966. FireViewChange();
  1967. SendOnDataChange(NULL);
  1968. if(::IsWindow(m_hWnd)){
  1969. #ifdef _UNICODE
  1970. ::SetWindowText(m_hWnd, bstrCaption);
  1971. #else
  1972. USES_CONVERSION;
  1973. LPTSTR strTemp = OLE2T(bstrCaption);
  1974. if (strTemp != NULL)
  1975. {
  1976. ::SetWindowText(m_hWnd, strTemp);
  1977. }
  1978. else
  1979. {
  1980. hr = E_POINTER;
  1981. }
  1982. #endif
  1983. }/* end of if statement */
  1984. return hr;
  1985. }/* end of function put_Caption */
  1986. /*************************************************************************/
  1987. /* Function: BitsPerPixel */
  1988. /* Description: Gets the number of bits per pixel. */
  1989. /*************************************************************************/
  1990. STDMETHODIMP CMFBar::BitsPerPixel(long *plBits){
  1991. HRESULT hr = S_OK;
  1992. try {
  1993. HWND hwnd = NULL;
  1994. hr = GetWindow(&hwnd);
  1995. if(FAILED(hr)){
  1996. throw(hr);
  1997. }/* end of if statement */
  1998. HDC hdc = ::GetWindowDC(hwnd);
  1999. if(NULL == hdc){
  2000. throw(E_FAIL);
  2001. }/* end of if statement */
  2002. *plBits = ::GetDeviceCaps(hdc, BITSPIXEL);
  2003. ::ReleaseDC(hwnd, hdc);
  2004. }
  2005. catch(HRESULT hrTmp){
  2006. hr = hrTmp;
  2007. }
  2008. catch(...){
  2009. hr = E_UNEXPECTED;
  2010. }/* end of try statement */
  2011. return(hr);
  2012. }/* end of function BitsPerPixel */
  2013. // ##### BEGIN ACTIVEX SCRIPTING SUPPORT #####
  2014. /*************************************************************************/
  2015. /* IActiveScriptSite Interface Implementation */
  2016. /*************************************************************************/
  2017. /*************************************************************************/
  2018. /* Function: get_CmdLine */
  2019. /*************************************************************************/
  2020. STDMETHODIMP CMFBar::get_CmdLine(BSTR *pVal){
  2021. if(NULL == pVal){
  2022. return(E_POINTER);
  2023. }/* end of if statement */
  2024. *pVal = m_strCmdLine.Copy();
  2025. return S_OK;
  2026. }/* end of function get_CmdLine */
  2027. /*************************************************************************/
  2028. /* Function: put_CmdLine */
  2029. /*************************************************************************/
  2030. STDMETHODIMP CMFBar::put_CmdLine(BSTR newVal){
  2031. m_strCmdLine = newVal;
  2032. return S_OK;
  2033. }/* end of function put_CmdLine */
  2034. /*************************************************************************/
  2035. /* Function: GetUserLCID */
  2036. /* Description: Gets the user default LCID */
  2037. /*************************************************************************/
  2038. STDMETHODIMP CMFBar::GetUserLCID(long *plcid){
  2039. *plcid = ::GetUserDefaultLCID();
  2040. return (S_OK);
  2041. }/* end of function GetUserLCID */
  2042. /*************************************************************************/
  2043. /* Function: GetLCID */
  2044. /* Description: Gets the user default LCID */
  2045. /*************************************************************************/
  2046. STDMETHODIMP CMFBar::GetLCID(LCID *plcid){
  2047. *plcid = ::GetUserDefaultLCID();
  2048. return (S_OK);
  2049. }/* end of function GetLCID */
  2050. /*************************************************************************/
  2051. /* Function: GetItemInfo */
  2052. /* Description: Returns IUnknown or TypeInfo of the contained (embedded) */
  2053. /* objects in the active script, in this case we return also a container,*/
  2054. /* since we can script it as well (but the script container is inserted */
  2055. /* in the list as well, so no special case for it. */
  2056. /* TODO: Might want to optimize and use hash table for faster compares. */
  2057. /* on the other hand it seems like a script engine calls this just once */
  2058. /* for an object an then reuses its internal reference. */
  2059. /*************************************************************************/
  2060. STDMETHODIMP CMFBar::GetItemInfo(LPCOLESTR strObjectID, DWORD dwReturnMask,
  2061. IUnknown** ppunkItemOut, ITypeInfo** pptinfoOut){
  2062. HRESULT hr = S_OK;
  2063. if (dwReturnMask & SCRIPTINFO_ITYPEINFO){
  2064. if (!pptinfoOut){
  2065. return E_INVALIDARG;
  2066. }/* end of if statement */
  2067. *pptinfoOut = NULL;
  2068. }/* end of if statement */
  2069. if (dwReturnMask & SCRIPTINFO_IUNKNOWN){
  2070. if (!ppunkItemOut){
  2071. return E_INVALIDARG;
  2072. }/* end of if statement */
  2073. *ppunkItemOut = NULL;
  2074. }/* end of if statement */
  2075. CHostedObject* pObj;
  2076. if(SUCCEEDED(FindObject(const_cast<BSTR>(strObjectID), &pObj))){
  2077. if (dwReturnMask & SCRIPTINFO_ITYPEINFO){
  2078. hr = pObj->GetTypeInfo(0, ::GetUserDefaultLCID(), pptinfoOut);
  2079. if(FAILED(hr)){
  2080. return(hr);
  2081. }/* end of if statement */
  2082. }/* end of if statement */
  2083. if (dwReturnMask & SCRIPTINFO_IUNKNOWN){
  2084. *ppunkItemOut = pObj->GetUnknown(); // does AddRef under the hood
  2085. (*ppunkItemOut)->AddRef();
  2086. }/* end of if statement */
  2087. return(hr); // found out item no need to dig around longer
  2088. }/* end of for loop */
  2089. return TYPE_E_ELEMENTNOTFOUND;
  2090. }/* end of function GetItemInfo */
  2091. /*************************************************************************/
  2092. /* Function: GetDocVersionString */
  2093. /*************************************************************************/
  2094. STDMETHODIMP CMFBar::GetDocVersionString(BSTR *pbstrVersion ){
  2095. return (E_NOTIMPL);
  2096. }/* end of function GetDocVersionString */
  2097. /*************************************************************************/
  2098. /* Function: OnScriptTerminate */
  2099. /*************************************************************************/
  2100. STDMETHODIMP CMFBar::OnScriptTerminate(const VARIANT *pvarResult,
  2101. const EXCEPINFO *pexcepinfo){
  2102. return (E_NOTIMPL);
  2103. }/* end of function OnScriptTerminate */
  2104. /*************************************************************************/
  2105. /* Function: OnStateChange */
  2106. /*************************************************************************/
  2107. STDMETHODIMP CMFBar::OnStateChange(SCRIPTSTATE ssScriptState){
  2108. return (E_NOTIMPL);
  2109. }/* end of function OnStateChange */
  2110. /*************************************************************************/
  2111. /* Function: OnScriptError */
  2112. /* Description: Display the script error in debug mode, skip it in */
  2113. /* release mode for now. */
  2114. /*************************************************************************/
  2115. STDMETHODIMP CMFBar::OnScriptError(IActiveScriptError *pse){
  2116. HRESULT hr = S_OK;
  2117. #ifdef _DEBUG
  2118. WCHAR szError[1024];
  2119. EXCEPINFO ei;
  2120. DWORD dwSrcContext;
  2121. ULONG ulLine;
  2122. LONG ichError;
  2123. BSTR bstrLine = NULL;
  2124. hr = pse->GetExceptionInfo(&ei);
  2125. if(FAILED(hr)){
  2126. return(hr);
  2127. }/* end of if statement */
  2128. hr = pse->GetSourcePosition(&dwSrcContext, &ulLine, &ichError);
  2129. if(FAILED(hr)){
  2130. return(hr);
  2131. }/* end of if statement */
  2132. hr = pse->GetSourceLineText(&bstrLine);
  2133. if (hr){
  2134. hr = S_OK; // Ignore this error, there may not be source available
  2135. }/* end of if statement */
  2136. if (!hr){
  2137. wsprintfW(szError, L"Source:'%s'\n Line:%d Description:%s\n",
  2138. ei.bstrSource, ulLine, ei.bstrDescription);
  2139. #ifdef _DEBUG
  2140. USES_CONVERSION;
  2141. //ATLTRACE(OLE2T(szError));
  2142. ::MessageBeep((UINT)-1);
  2143. ::MessageBoxW(::GetFocus(), szError, L"Error", MB_OK);
  2144. #endif
  2145. // TODO: Add real error handling for released version
  2146. }/* end of if statment */
  2147. if (bstrLine){
  2148. ::SysFreeString(bstrLine);
  2149. }/* end of if statement */
  2150. #endif
  2151. return hr;
  2152. }/* end of function OnScriptError */
  2153. //---------------------------------------------------------------------------
  2154. //
  2155. //---------------------------------------------------------------------------
  2156. STDMETHODIMP CMFBar::OnEnterScript
  2157. (
  2158. void
  2159. )
  2160. {
  2161. // No need to do anything
  2162. return S_OK;
  2163. }
  2164. //---------------------------------------------------------------------------
  2165. //
  2166. //---------------------------------------------------------------------------
  2167. STDMETHODIMP CMFBar::OnLeaveScript
  2168. (
  2169. void
  2170. )
  2171. {
  2172. // No need to do anything
  2173. return S_OK;
  2174. }
  2175. // ##### END ACTIVEX SCRIPTING SUPPORT #####
  2176. /*************************************************************************/
  2177. /* Function: About */
  2178. /* Description: Displayes about box. */
  2179. /*************************************************************************/
  2180. STDMETHODIMP CMFBar::About(){
  2181. HRESULT hr = S_OK;
  2182. const INT ciMaxBuffSize = MAX_PATH; // enough for the text
  2183. TCHAR strBuffer[ciMaxBuffSize];
  2184. TCHAR strBufferAbout[ciMaxBuffSize];
  2185. if(!::LoadString(m_hRes, IDS_BAR_ABOUT, strBuffer, ciMaxBuffSize)){
  2186. hr = E_UNEXPECTED;
  2187. return(hr);
  2188. }/* end of if statement */
  2189. if(!::LoadString(m_hRes, IDS_ABOUT, strBufferAbout, ciMaxBuffSize)){
  2190. hr = E_UNEXPECTED;
  2191. return(hr);
  2192. }/* end of if statement */
  2193. ::MessageBox(::GetFocus(), strBuffer, strBufferAbout, MB_OK);
  2194. return (hr);
  2195. }/* end of function About */
  2196. /*************************************************************************/
  2197. /* Function: GetObjectUnknown */
  2198. /* Description: Iterates throught the object collection, finds the */
  2199. /* object that has the specific ID then returns it IUnknown. */
  2200. /*************************************************************************/
  2201. STDMETHODIMP CMFBar::GetObjectUnknown(BSTR strObjectID, IUnknown **ppUnk){
  2202. HRESULT hr = E_FAIL;
  2203. if(NULL == strObjectID){
  2204. return E_POINTER;
  2205. }/* end of if statement */
  2206. if(NULL == ppUnk){
  2207. return E_POINTER;
  2208. }/* end of if statement */
  2209. *ppUnk = NULL;
  2210. CHostedObject* pObj;
  2211. hr = FindObject(strObjectID, &pObj);
  2212. if(FAILED(hr)){
  2213. return(hr);
  2214. }/* end of if statement */
  2215. *ppUnk = pObj->GetUnknown();
  2216. hr = S_OK;
  2217. if(*ppUnk == NULL){
  2218. hr = E_UNEXPECTED;
  2219. return(hr);
  2220. }/* end of if statement */
  2221. (*ppUnk)->AddRef(); // adds the reference, since we are giving out
  2222. return (hr);
  2223. }/* end of function GetObjectUnknown */
  2224. /*************************************************************************/
  2225. /* Function: InvalidateObjectRect */
  2226. /* Description: Invalidates the object. */
  2227. /*************************************************************************/
  2228. STDMETHODIMP CMFBar::InvalidateObjectRect(BSTR strObjectID){
  2229. HRESULT hr = E_FAIL;
  2230. if(NULL == strObjectID){
  2231. return E_POINTER;
  2232. }/* end of if sattement */
  2233. CHostedObject* pObj;
  2234. hr = FindObject(strObjectID, &pObj);
  2235. if(FAILED(hr)){
  2236. return(hr);
  2237. }/* end of if statement */
  2238. CContainerObject* pCnt;
  2239. hr = pObj->GetContainerObject(&pCnt);
  2240. if(FAILED(hr)){
  2241. return(hr);
  2242. }/* end of if statement */
  2243. hr = pCnt->InvalidateObjectRect();
  2244. return (hr);
  2245. }/* end of function InvalidateObjectRect */
  2246. /*************************************************************************/
  2247. /* Function: Invalidate */
  2248. /* Description: Invalidates the whole container, which in turns repaints */
  2249. /* all the controls. */
  2250. /*************************************************************************/
  2251. STDMETHODIMP CMFBar::Invalidate(){
  2252. HRESULT hr = InvalidateRect(NULL, FALSE);
  2253. return (hr);
  2254. }/* end of function Invalidate */
  2255. /*************************************************************************/
  2256. /* Function: EnableObject */
  2257. /* Description: Goes trough the objects and enables or disables it */
  2258. /* depending on the flag. Invalidates the objects rect as well. */
  2259. /*************************************************************************/
  2260. STDMETHODIMP CMFBar::EnableObject(BSTR strObjectID, VARIANT_BOOL fEnable){
  2261. HRESULT hr = E_FAIL;
  2262. if(NULL == strObjectID){
  2263. return E_POINTER;
  2264. }/* end of if sattement */
  2265. CHostedObject* pObj;
  2266. hr = FindObject(strObjectID, &pObj);
  2267. if(FAILED(hr)){
  2268. return(hr);
  2269. }/* end of if statement */
  2270. bool fTmpEnable = VARIANT_FALSE == fEnable ? false: true;
  2271. CContainerObject* pCnt;
  2272. hr = pObj->GetContainerObject(&pCnt);
  2273. if(FAILED(hr)){
  2274. if(pObj->GetUnknown() == GetUnknown()){
  2275. // special case when we are invalidating our self/ the self hosted container
  2276. if(fTmpEnable){
  2277. InvalidateRect(NULL, false);
  2278. }/* end of if statement */
  2279. pObj->SetActive(fTmpEnable);
  2280. hr = S_OK;
  2281. return(hr);
  2282. }/* end of if statement */
  2283. }/* end of if statemenet */
  2284. if (pObj->IsActive() == fTmpEnable)
  2285. return S_OK;
  2286. pObj->SetActive(fTmpEnable);
  2287. if(false == fTmpEnable){
  2288. LONG lRes = 0;
  2289. if (pObj->HasFocus()) {
  2290. SetClosestFocus(lRes);
  2291. //MoveFocus(true, lRes);
  2292. //SetObjectFocus(pObj, FALSE, lRes);
  2293. }
  2294. if(pObj->HasCapture()){
  2295. pCnt->SetCapture(FALSE);
  2296. }/* end of if statement */
  2297. }/* end of if statement */
  2298. // invalidate area where the object lives
  2299. if(pObj->IsWindowless()){
  2300. // invalidate the rect only if we are windowless control
  2301. // the windowed control shopuld be able
  2302. // to update itself depending on the SW_SHOW, HIDE messagess
  2303. hr = pCnt->InvalidateObjectRect();
  2304. }/* end of if statement */
  2305. return (hr);
  2306. }/* end of function EnableObject */
  2307. /*************************************************************************/
  2308. /* Function: ObjectEnabled */
  2309. /* Description: Goes trough the objects and checks if the particular */
  2310. /* object is enabled or disabled. */
  2311. /*************************************************************************/
  2312. STDMETHODIMP CMFBar::ObjectEnabled(BSTR strObjectID, VARIANT_BOOL *pfEnabled){
  2313. HRESULT hr = E_FAIL;
  2314. if(NULL == pfEnabled){
  2315. hr = E_POINTER;
  2316. return(hr);
  2317. }/* end of if statement */
  2318. if(NULL == strObjectID){
  2319. hr = E_POINTER;
  2320. return(hr);
  2321. }/* end of if sattement */
  2322. CHostedObject* pObj;
  2323. hr = FindObject(strObjectID, &pObj);
  2324. if(FAILED(hr)){
  2325. return(hr);
  2326. }/* end of if statement */
  2327. *pfEnabled = pObj->IsActive()? VARIANT_TRUE : VARIANT_FALSE;
  2328. return (hr);
  2329. }/* end of function ObjectEnabled */
  2330. /*************************************************************************/
  2331. /* Function: EnableObjectInput */
  2332. /*************************************************************************/
  2333. STDMETHODIMP CMFBar::EnableObjectInput(BSTR strObjectID, VARIANT_BOOL fEnable){
  2334. HRESULT hr = E_FAIL;
  2335. if(NULL == strObjectID){
  2336. return E_POINTER;
  2337. }/* end of if sattement */
  2338. CHostedObject* pObj;
  2339. hr = FindObject(strObjectID, &pObj);
  2340. if(FAILED(hr)){
  2341. return(hr);
  2342. }/* end of if statement */
  2343. bool fTmpEnable = VARIANT_FALSE == fEnable ? false: true;
  2344. CContainerObject* pCnt;
  2345. hr = pObj->GetContainerObject(&pCnt);
  2346. if(FAILED(hr)){
  2347. if(pObj->GetUnknown() == GetUnknown()){
  2348. // special case when we are invalidating our self/ the self hosted container
  2349. if(fTmpEnable){
  2350. InvalidateRect(NULL, false);
  2351. }/* end of if statement */
  2352. pObj->SetInputEnabled(fTmpEnable);
  2353. hr = S_OK;
  2354. return(hr);
  2355. }/* end of if statement */
  2356. if(NULL == pCnt){
  2357. return(hr);
  2358. }/* end of if statement */
  2359. }/* end of if statemenet */
  2360. if (pObj->IsInputEnabled() == fTmpEnable)
  2361. return S_OK;
  2362. pObj->SetInputEnabled(fTmpEnable);
  2363. if(false == fTmpEnable){
  2364. LONG lRes = 0;
  2365. SetClosestFocus(lRes);
  2366. //MoveFocus(true, lRes);
  2367. //SetObjectFocus(pObj, FALSE, lRes);
  2368. if(pObj->HasCapture()){
  2369. pCnt->SetCapture(FALSE);
  2370. }/* end of if statement */
  2371. }/* end of if statement */
  2372. // invalidate area where the object lives
  2373. if(pObj->IsWindowless()){
  2374. // invalidate the rect only if we are windowless control
  2375. // the windowed control shopuld be able
  2376. // to update itself depending on the SW_SHOW, HIDE messagess
  2377. hr = pCnt->InvalidateObjectRect();
  2378. }/* end of if statement */
  2379. return (hr);
  2380. }/* end of function EnableObjectInput */
  2381. /*************************************************************************/
  2382. /* Function: ObjectInputEnabled */
  2383. /*************************************************************************/
  2384. STDMETHODIMP CMFBar::ObjectInputEnabled(BSTR strObjectID, VARIANT_BOOL *pfEnabled){
  2385. HRESULT hr = E_FAIL;
  2386. if(NULL == pfEnabled){
  2387. hr = E_POINTER;
  2388. return(hr);
  2389. }/* end of if statement */
  2390. if(NULL == strObjectID){
  2391. hr = E_POINTER;
  2392. return(hr);
  2393. }/* end of if sattement */
  2394. CHostedObject* pObj;
  2395. hr = FindObject(strObjectID, &pObj);
  2396. if(FAILED(hr)){
  2397. return(hr);
  2398. }/* end of if statement */
  2399. *pfEnabled = pObj->IsInputEnabled()? VARIANT_TRUE : VARIANT_FALSE;
  2400. return (hr);
  2401. }/* end of function ObjectInputEnabled */
  2402. /*************************************************************************/
  2403. /* Function: SetCookie */
  2404. /* Description: Sets a cookie to object, so it can be retrived later. */
  2405. /*************************************************************************/
  2406. STDMETHODIMP CMFBar::SetCookie(BSTR strObjectID, VARIANT vCookie){
  2407. HRESULT hr = E_FAIL;
  2408. if(NULL == strObjectID){
  2409. return E_POINTER;
  2410. }/* end of if sattement */
  2411. CHostedObject* pObj;
  2412. hr = FindObject(strObjectID, &pObj);
  2413. if(FAILED(hr)){
  2414. return(hr);
  2415. }/* end of if statement */
  2416. pObj->SetCookie(vCookie);
  2417. return (hr);
  2418. }/* end of function SetCookie */
  2419. /*************************************************************************/
  2420. /* Function: GetCookie */
  2421. /* Description: Gets help ID associated with the object. */
  2422. /*************************************************************************/
  2423. STDMETHODIMP CMFBar::GetCookie(BSTR strObjectID, VARIANT *pvCookie){
  2424. HRESULT hr = E_FAIL;
  2425. if(NULL == pvCookie){
  2426. hr = E_POINTER;
  2427. return(hr);
  2428. }/* end of if statement */
  2429. if(NULL == strObjectID){
  2430. hr = E_POINTER;
  2431. return(hr);
  2432. }/* end of if sattement */
  2433. CHostedObject* pObj;
  2434. hr = FindObject(strObjectID, &pObj);
  2435. if(FAILED(hr)){
  2436. return(hr);
  2437. }/* end of if statement */
  2438. hr = pObj->GetCookie(pvCookie);
  2439. return (hr);
  2440. }/* end of function GetCookie */
  2441. /*************************************************************************/
  2442. /* Function: ForceKey */
  2443. /* Description: Forces the in the eventa handling code. */
  2444. /* The fEat disables or enables default key handler. */
  2445. /*************************************************************************/
  2446. STDMETHODIMP CMFBar::ForceKey(LONG lVirtKey, LONG lKeyData, VARIANT_BOOL fEat){
  2447. m_fForceKey = true; // set the flag for key handler routine
  2448. m_fEat = (fEat == VARIANT_FALSE ? VARIANT_FALSE : VARIANT_TRUE); // disable or enable this call
  2449. m_lVirtKey = lVirtKey; // put in data
  2450. m_lKeyData = lKeyData; // put in data
  2451. return S_OK;
  2452. }/* end of function ForceKey */
  2453. /*************************************************************************/
  2454. /* Function: get_ScriptLanguage */
  2455. /* Description: Gets current script language such as JScript, VBScript */
  2456. /*************************************************************************/
  2457. STDMETHODIMP CMFBar::get_ScriptLanguage(BSTR *pstrScriptLanguage){
  2458. if(NULL == pstrScriptLanguage){
  2459. return(E_POINTER);
  2460. }/* end of if statement */
  2461. *pstrScriptLanguage = m_strScriptLanguage.Copy();
  2462. return S_OK;
  2463. }/* end of function get_ScriptLanguage */
  2464. /*************************************************************************/
  2465. /* Function: put_ScriptLanguage */
  2466. /* Description: Gets current script language such as JScript, VBScript */
  2467. /*************************************************************************/
  2468. STDMETHODIMP CMFBar::put_ScriptLanguage(BSTR strScriptLanguage){
  2469. HRESULT hr = S_OK;
  2470. if (m_ps){
  2471. hr = E_FAIL; // Already created the script engine, so it
  2472. // will not take an effect untill we unload it
  2473. return(hr);
  2474. }/* end of if statement */
  2475. m_strScriptLanguage = strScriptLanguage;
  2476. return (hr);
  2477. }/* end of function put_ScriptLanguage */
  2478. /*************************************************************************/
  2479. /* Function: get_ScriptFile */
  2480. /* Description: Gets the current script file. */
  2481. /* By default we have empty string which means loading from Windows */
  2482. /* resources, which is not really a file. */
  2483. /*************************************************************************/
  2484. STDMETHODIMP CMFBar::get_ScriptFile(BSTR *pstrScriptFile){
  2485. if(NULL == pstrScriptFile){
  2486. return(E_POINTER);
  2487. }/* end of if statement */
  2488. *pstrScriptFile = m_strScriptFile.Copy();
  2489. return S_OK;
  2490. }/* end of function get_ScriptFile */
  2491. /*************************************************************************/
  2492. /* Function: put_ScriptFile */
  2493. /* Description: Sets the script file. Only valid before the load and */
  2494. /* unload. */
  2495. /*************************************************************************/
  2496. STDMETHODIMP CMFBar::put_ScriptFile(BSTR strScriptFile){
  2497. HRESULT hr = S_OK;
  2498. try {
  2499. if(VARIANT_TRUE == m_fAutoLoad){
  2500. hr = DestroyScriptEngine();
  2501. if(FAILED(hr)){
  2502. throw(hr);
  2503. }/* end of if statement */
  2504. m_strScriptFile = strScriptFile;
  2505. hr = Load();
  2506. if(FAILED(hr)){
  2507. throw(hr);
  2508. }/* end of if statement */
  2509. const INT ciMaxBuffSize = MAX_PATH; // enough for the text
  2510. TCHAR strBuffer[ciMaxBuffSize];
  2511. if(!::LoadString(m_hRes, IDS_MAIN_ENTRY, strBuffer, ciMaxBuffSize)){
  2512. hr = E_UNEXPECTED;
  2513. return(hr);
  2514. }/* end of if statement */
  2515. USES_CONVERSION;
  2516. hr = Run(T2OLE(strBuffer));
  2517. }
  2518. else {
  2519. // case when we are loading manually
  2520. if (m_ps){
  2521. hr = E_FAIL; // Already created the script engine, so it
  2522. // will not take an effect untill we unload it
  2523. throw(hr);
  2524. }/* end of if statement */
  2525. m_strScriptFile = strScriptFile;
  2526. }/* end of if statement */
  2527. }/* end of try statement */
  2528. catch(HRESULT hrTmp){
  2529. hr = hrTmp;
  2530. }
  2531. catch(...){
  2532. hr = E_UNEXPECTED;
  2533. }/* end of catch statement */
  2534. return (hr);
  2535. }/* end of function put_ScriptFile */
  2536. /*************************************************************************/
  2537. /* IActiveScriptSiteWindow Interface Implementation */
  2538. /*************************************************************************/
  2539. /*************************************************************************/
  2540. /* Function: GetWindow */
  2541. /* Description: Gets the window. If we are windowless we do not pass */
  2542. /* down the parent window, since that seems to confuse the control */
  2543. /*************************************************************************/
  2544. STDMETHODIMP CMFBar::GetWindow(HWND *phwndOut){
  2545. HRESULT hr = S_OK;
  2546. if (!phwndOut){
  2547. hr = E_INVALIDARG;
  2548. return (hr);
  2549. }/* end of if statement */
  2550. if(m_bWndLess){
  2551. if(!::IsWindow(m_hWnd)){
  2552. return(GetParentHWND(phwndOut));
  2553. }/* end of if statement */
  2554. }
  2555. else {
  2556. if(!::IsWindow(m_hWnd)){
  2557. *phwndOut = NULL;
  2558. hr = E_FAIL;
  2559. return(hr);
  2560. }/* end of if statement */
  2561. }/* end of if statement */
  2562. *phwndOut = m_hWnd;
  2563. return(hr);
  2564. }/* end of function GetWindow */
  2565. /*************************************************************************/
  2566. /* Function: EnableModeless */
  2567. /* Description: Sets the window from which the UI elemnt can come out */
  2568. /*************************************************************************/
  2569. STDMETHODIMP CMFBar::EnableModeless(BOOL fModeless){
  2570. HRESULT hr = S_OK;
  2571. if(m_hWnd == NULL){
  2572. hr = E_NOTIMPL;
  2573. return (hr);
  2574. }/* end of if statement */
  2575. ::EnableWindow(m_hWnd, fModeless);
  2576. return(hr);
  2577. }/* end of function EnableModeless */
  2578. /*************************************************************************/
  2579. /* Function: get_MinWidth */
  2580. /* Description: Gets the minimum width beyond which we do not resize. */
  2581. /*************************************************************************/
  2582. STDMETHODIMP CMFBar::get_MinWidth(long *pVal){
  2583. if(NULL == pVal){
  2584. return(E_POINTER);
  2585. }/* end of if statement */
  2586. *pVal = m_lMinWidth;
  2587. return S_OK;
  2588. }/* end of function get_MinWidth */
  2589. /*************************************************************************/
  2590. /* Function: put_MinWidth */
  2591. /* Description: Puts the minimum width beyond which we do not resize. */
  2592. /*************************************************************************/
  2593. STDMETHODIMP CMFBar::put_MinWidth(long newVal){
  2594. m_lMinWidth = newVal;
  2595. return S_OK;
  2596. }/* end of function put_MinWidth */
  2597. /*************************************************************************/
  2598. /* Function: get_MinWidth */
  2599. /* Description: Gets the minimum height beyond which we do not resize. */
  2600. /*************************************************************************/
  2601. STDMETHODIMP CMFBar::get_MinHeight(long *pVal){
  2602. if(NULL == pVal){
  2603. return(E_POINTER);
  2604. }/* end of if statement */
  2605. *pVal = m_lMinHeight;
  2606. return S_OK;
  2607. }/* end of function get_MinHeight */
  2608. /*************************************************************************/
  2609. /* Function: put_MinHeight */
  2610. /* Description: Sets the minimum height beyond which we do not resize. */
  2611. /*************************************************************************/
  2612. STDMETHODIMP CMFBar::put_MinHeight(long newVal){
  2613. m_lMinHeight = newVal;
  2614. return S_OK;
  2615. }/* end of function put_MinHeight */
  2616. // ##### BEGIN ACTIVEX SCRIPTING SUPPORT #####
  2617. /*************************************************************************/
  2618. /* Function: CreateScriptEngine */
  2619. /* Description: Initializes the script engine. */
  2620. /*************************************************************************/
  2621. HRESULT CMFBar::CreateScriptEngine(){
  2622. HRESULT hr = S_OK;
  2623. #ifndef _UNICODE
  2624. USES_CONVERSION;
  2625. #endif
  2626. if (m_ps){
  2627. hr = S_FALSE; // Already created the script engine
  2628. return(hr); // so get out
  2629. }/* end of if statement */
  2630. /*************************************************************************/
  2631. /* add (this) the container as a scriptable object as well */
  2632. /* this is special case so we can call script on our self as well */
  2633. /*************************************************************************/
  2634. const INT ciMaxBuffSize = MAX_PATH; // should be enough for tlbr ID, keep ID small if can
  2635. TCHAR strBuffer[ciMaxBuffSize];
  2636. if(!::LoadString(m_hRes, IDS_ROOT_OBJECT, strBuffer, ciMaxBuffSize)){
  2637. hr = E_UNEXPECTED;
  2638. return(hr);
  2639. }/* end of if statement */
  2640. CComPtr<IUnknown> pUnk = GetUnknown();
  2641. CComQIPtr<IDispatch> pDisp (pUnk);
  2642. if(!pDisp){
  2643. return(hr);
  2644. }/* end of if statement */
  2645. #ifdef _UNICODE
  2646. BSTR strObjectID = ::SysAllocString(strBuffer); // gets freed in the destructor of the holding object
  2647. #else
  2648. BSTR strObjectID = ::SysAllocString(T2OLE(strBuffer));
  2649. #endif
  2650. hr = AddObject(strObjectID, pDisp); // this one adds the object to the list as well
  2651. ::SysFreeString(strObjectID); // free up the sys string, since we allocate it in the contructor for the object
  2652. if(FAILED(hr)){
  2653. return(hr);
  2654. }/* end of if statement */
  2655. if(!m_strScriptLanguage){
  2656. // load what script language we decided to support if not set explicitly by user
  2657. if(!::LoadString(m_hRes, IDS_SCRIPT_LANGUAGE, strBuffer, ciMaxBuffSize)){
  2658. hr = E_UNEXPECTED;
  2659. return(hr);
  2660. }/* end of if statement */
  2661. m_strScriptLanguage = strBuffer;
  2662. }/* end of if statement */
  2663. CLSID clsid;
  2664. hr = ::CLSIDFromProgID(m_strScriptLanguage, &clsid); // get the language
  2665. if(FAILED(hr)){
  2666. return hr;
  2667. }/* end of if statement */
  2668. hr = m_ps.CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER);
  2669. // Create the ActiveX Scripting Engine
  2670. //hr = ::CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, IID_IActiveScript, (void **)&m_ps);
  2671. if (FAILED(hr)){
  2672. //s_pszError = "Creating the ActiveX Scripting engine failed. Scripting engine is probably not correctly registered or CLSID incorrect.";
  2673. return (hr);
  2674. }/* end of if statement */
  2675. // Script Engine must support IActiveScriptParse for us to use it
  2676. hr = m_ps->QueryInterface(IID_IActiveScriptParse, (void**) &m_psp);
  2677. if (FAILED(hr)){
  2678. //s_pszError = "ActiveX Scripting engine does not support IActiveScriptParse";
  2679. return (hr);
  2680. }/* end of if statement */
  2681. hr = m_ps->SetScriptSite(this);
  2682. if(FAILED(hr)){
  2683. return hr;
  2684. }/* end of if statement */
  2685. // InitNew the object:
  2686. hr = m_psp->InitNew();
  2687. if(FAILED(hr)){
  2688. return hr;
  2689. }/* end of if statement */
  2690. // Adding dynamically added items so they can be recognized by name
  2691. // and scripted via script language such as VBScript or JScript
  2692. for(CNTOBJ::iterator i = m_cntObj.begin(); i!= m_cntObj.end(); i++){
  2693. // iterate throw the array and see if we find matching ID
  2694. CHostedObject* pObj = (*i);
  2695. hr = m_ps->AddNamedItem((pObj)->GetID(), SCRIPTITEM_ISVISIBLE | SCRIPTITEM_ISSOURCE);
  2696. if(FAILED(hr)){
  2697. return(hr); // might want to modify this later to not exit if we get one bad object
  2698. }/* end of if statement */
  2699. }/* end of for loop */
  2700. // Special case adding the root object
  2701. if(!::LoadString(m_hRes, IDS_ROOT_OBJECT, strBuffer, ciMaxBuffSize)){
  2702. hr = E_UNEXPECTED;
  2703. return(hr);
  2704. }/* end of if statement */
  2705. #ifdef _UNICODE
  2706. hr = m_ps->AddNamedItem(strBuffer, SCRIPTITEM_ISVISIBLE | SCRIPTITEM_ISSOURCE);
  2707. #else
  2708. hr = m_ps->AddNamedItem(A2W(strBuffer), SCRIPTITEM_ISVISIBLE | SCRIPTITEM_ISSOURCE);
  2709. #endif
  2710. // Add up the events that we have saved in the event array
  2711. for(CNTEVNT::iterator j = m_cntEvnt.begin(); j!= m_cntEvnt.end(); j++){
  2712. EXCEPINFO ei;
  2713. ::ZeroMemory(&ei, sizeof(EXCEPINFO));
  2714. BSTR strName;
  2715. CEventObject* pObj = (*j);
  2716. hr = m_psp->AddScriptlet(NULL, pObj->m_strEventCode, pObj->m_strObjectID, NULL, pObj->m_strEvent, NULL, 0, 0, 0, &strName, &ei);
  2717. if(FAILED(hr)){
  2718. ATLTRACE(TEXT("Failed to add an event, might be using a different language or the object does not exists. \n"));
  2719. ATLASSERT(FALSE);
  2720. return(hr);
  2721. }/* end of if statement */
  2722. }/* end of for loop */
  2723. return (hr);
  2724. }/* end of function CreateScriptEngine */
  2725. /*************************************************************************/
  2726. /* Function: DestroyScriptEngine */
  2727. /* Description: Destroys the engine. Might be usefull when using one */
  2728. /* script to initialize the objects and the other script to run the */
  2729. /* objects. */
  2730. /*************************************************************************/
  2731. STDMETHODIMP CMFBar::DestroyScriptEngine(){
  2732. HRESULT hr = S_OK;
  2733. if(m_ps){
  2734. hr = m_ps->SetScriptState(SCRIPTSTATE_DISCONNECTED);
  2735. }/* end of if statement */
  2736. // Release the language engine, since it may hold on to us
  2737. if (m_psp){
  2738. m_psp.Release();
  2739. }/* end of if statement */
  2740. if (m_ps){
  2741. //HRESULT hrTmp = m_ps->InterruptScriptThread(SCRIPTTHREADID_CURRENT, NULL, SCRIPTINTERRUPT_DEBUG);
  2742. //ATLASSERT(SUCCEEDED(hrTmp));
  2743. hr = m_ps->Close();
  2744. if(FAILED(hr)){
  2745. return(hr);
  2746. }/* end of if statement */
  2747. m_ps.Release();
  2748. }/* end of if statement */
  2749. return (hr);
  2750. }/* end of function DestroyScriptEngine */
  2751. /*************************************************************************/
  2752. /* Function: Load */
  2753. /* Description: Loads the script. */
  2754. /*************************************************************************/
  2755. STDMETHODIMP CMFBar::Load(){
  2756. //#ifndef _UNICODE_SCRIPT_FILE
  2757. USES_CONVERSION;
  2758. //#endif
  2759. HRESULT hr = CreateScriptEngine();
  2760. if(FAILED(hr)){
  2761. ATLTRACE(TEXT("Failed to create a script engine.\n"));
  2762. ATLASSERT(FALSE);
  2763. return(hr);
  2764. }/* end of if statement */
  2765. // see if we can find this resource DLL in the script
  2766. // TCHAR* strType = TEXT("SCRIPT");
  2767. LPTSTR strTemp = OLE2T(m_strScriptFile);
  2768. if (NULL == strTemp)
  2769. {
  2770. hr = E_POINTER;
  2771. return hr;
  2772. }
  2773. HRSRC hrscScript = ::FindResource(m_hRes, strTemp, MAKEINTRESOURCE(23));
  2774. if(NULL != hrscScript){
  2775. /**********************************************************************/
  2776. /* load up the script from a resource */
  2777. /**********************************************************************/
  2778. if(NULL == hrscScript){
  2779. hr = HRESULT_FROM_WIN32(::GetLastError());
  2780. return(hr);
  2781. }/* end of if statement */
  2782. HGLOBAL hScript = ::LoadResource(m_hRes, hrscScript);
  2783. if(NULL == hScript){
  2784. hr = HRESULT_FROM_WIN32(::GetLastError());
  2785. return(hr);
  2786. }/* end of if statement */
  2787. DWORD dwSize = ::SizeofResource((HMODULE)m_hRes, hrscScript);
  2788. if(dwSize == 0){
  2789. hr = E_UNEXPECTED;
  2790. return(hr);
  2791. }/* end of if statement */
  2792. /*****************************************************************/
  2793. /* change this depending if the file was saved as Unicode or not */
  2794. /*****************************************************************/
  2795. #ifndef _UNICODE_SCRIPT_FILE
  2796. WCHAR* strCode = A2W((CHAR*)hScript);
  2797. //delete[] hScript; // free up the temp buffer
  2798. #else
  2799. // work around script engine bug which does not recognize termination string
  2800. BSTR strCode = ::SysAllocStringLen((WCHAR*)hScript+ 1,dwSize / (sizeof(WCHAR) /sizeof(BYTE)) - 1);
  2801. ATLASSERT(strCode[dwSize / (sizeof(WCHAR) /sizeof(BYTE)) - 1] == 0x0000);
  2802. //strCode ++; // skip the word that indicates the byte order
  2803. #endif
  2804. EXCEPINFO ei;
  2805. ::ZeroMemory(&ei, sizeof(EXCEPINFO));
  2806. hr = m_psp->ParseScriptText(strCode, NULL, NULL, NULL, 0, 0, SCRIPTTEXT_ISEXPRESSION|SCRIPTTEXT_ISVISIBLE, NULL, &ei);
  2807. #ifdef _UNICODE_SCRIPT_FILE
  2808. ::SysFreeString(strCode);
  2809. #endif
  2810. }
  2811. else {
  2812. /**********************************************************************/
  2813. /* load up the script from a file */
  2814. /**********************************************************************/
  2815. // Create File m_strScriptFile
  2816. HANDLE hFile = ::CreateFile(
  2817. OLE2T(m_strScriptFile), // pointer to name of the file
  2818. GENERIC_READ, // access (read-write) mode
  2819. FILE_SHARE_READ, // share mode
  2820. NULL, // pointer to security descriptor
  2821. OPEN_EXISTING, // how to create
  2822. FILE_ATTRIBUTE_NORMAL, // file attributes
  2823. NULL // handle to file with attributes to copy
  2824. );
  2825. if(hFile == INVALID_HANDLE_VALUE){
  2826. hr = HRESULT_FROM_WIN32(::GetLastError());
  2827. #if _DEBUG
  2828. TCHAR strBuffer[MAX_PATH + 25];
  2829. wsprintf(strBuffer, TEXT("Failed to open script file %s"), OLE2T(m_strScriptFile));
  2830. ::MessageBox(::GetFocus(), strBuffer, TEXT("Error"), MB_OK);
  2831. #endif
  2832. return(hr);
  2833. }/* end of if statement */
  2834. DWORD dwBitsSize = GetFileSize(hFile,NULL);
  2835. if(0 == dwBitsSize){
  2836. hr = E_UNEXPECTED;
  2837. return(hr); // the file size should be definetly more then 0
  2838. }/* end of if statement */
  2839. BYTE* pbBuffer = new BYTE[dwBitsSize + sizeof(WCHAR)];
  2840. ::ZeroMemory(pbBuffer, dwBitsSize + sizeof(WCHAR));
  2841. // load it up convert the text to UNICODE
  2842. DWORD dwBytesRead = 0;
  2843. if(!ReadFile(hFile, pbBuffer, dwBitsSize, &dwBytesRead, NULL)){
  2844. hr = HRESULT_FROM_WIN32(::GetLastError());
  2845. delete[] pbBuffer;
  2846. ::CloseHandle(hFile); // close the file
  2847. return (hr);
  2848. }/* end of function ReadFile */
  2849. if(dwBitsSize != dwBytesRead){
  2850. ATLTRACE(TEXT("Implement reading loop"));
  2851. delete[] pbBuffer; // free up the temp buffer
  2852. ::CloseHandle(hFile); // close the file
  2853. hr = E_UNEXPECTED;
  2854. return(hr);
  2855. }/* end of if statement */
  2856. /*****************************************************************/
  2857. /* change this depending if the file was saved as Unicode or not */
  2858. /*****************************************************************/
  2859. #ifndef _UNICODE_TEST_SCRIPT_FILE
  2860. WCHAR* strCode = A2W((CHAR*)pbBuffer);
  2861. delete[] pbBuffer; // free up the temp buffer
  2862. #else
  2863. WCHAR* strCode = (WCHAR*)pbBuffer;
  2864. #endif
  2865. ::CloseHandle(hFile); // close the file
  2866. EXCEPINFO ei;
  2867. ::ZeroMemory(&ei, sizeof(EXCEPINFO));
  2868. #ifdef _UNICODE
  2869. hr = m_psp->ParseScriptText(strCode, NULL, NULL, NULL, 0, 0, SCRIPTTEXT_ISEXPRESSION|SCRIPTTEXT_ISVISIBLE, NULL, &ei);
  2870. #else
  2871. hr = m_psp->ParseScriptText(strCode, NULL, NULL, NULL, 0, 0, SCRIPTTEXT_ISEXPRESSION|SCRIPTTEXT_ISVISIBLE, NULL, &ei);
  2872. #endif
  2873. }/* end of if statement */
  2874. // take out the extra character at the begining of the unicode file just in case it is garbled by editor
  2875. if(FAILED(hr)){
  2876. return(hr);
  2877. }/* end of if statement */
  2878. hr = m_ps->SetScriptState(/* SCRIPTSTATE_STARTED */ SCRIPTSTATE_CONNECTED);
  2879. return hr;
  2880. }/* end of function Load */
  2881. /*************************************************************************/
  2882. /* Function: AddScriptlet */
  2883. /* Description: Using this method you can add events for JScript and */
  2884. /* other languages that do not support event handlers internally. This */
  2885. /* method just add these to the array which does get initializied on load*/
  2886. /*************************************************************************/
  2887. STDMETHODIMP CMFBar::AddScriptlet(BSTR strObjectID, BSTR strEvent, BSTR strEventCode){
  2888. HRESULT hr = S_OK;
  2889. CEventObject* pObj = new CEventObject(strObjectID, strEvent, strEventCode);
  2890. if(NULL == pObj){
  2891. hr = E_OUTOFMEMORY;
  2892. return(hr);
  2893. }/* end of if statement */
  2894. m_cntEvnt.insert(m_cntEvnt.end(), pObj);
  2895. return(hr);
  2896. }/* end of function AddScriptlet */
  2897. /*************************************************************************/
  2898. /* Function: HookScriptlet */
  2899. /* Description: Hooks the scrtiptlet for immidiate use, unlike the */
  2900. /* Add scriptlet which adds it, so it takes effect in the next Load. */
  2901. /* However, it also adds the callback to the array, so if needs to be */
  2902. /* loaded on the next load. */
  2903. /*************************************************************************/
  2904. STDMETHODIMP CMFBar::HookScriptlet(BSTR strObjectID, BSTR strEvent, BSTR strEventCode){
  2905. HRESULT hr = S_OK;
  2906. try {
  2907. hr = AddScriptlet(strObjectID, strEvent, strEventCode);
  2908. if(!m_ps){
  2909. ATLTRACE(TEXT("No Script Engine!! No Run!!\n"));
  2910. ATLASSERT(FALSE);
  2911. throw(S_FALSE);
  2912. }/* end of if statement */
  2913. EXCEPINFO ei;
  2914. ::ZeroMemory(&ei, sizeof(EXCEPINFO));
  2915. BSTR strName;
  2916. hr = m_ps->SetScriptState(SCRIPTSTATE_STARTED);
  2917. if(FAILED(hr)){
  2918. throw(hr);
  2919. }/* end of if statement */
  2920. hr = m_psp->AddScriptlet(NULL, strEventCode, strObjectID, NULL, strEvent, NULL, 0, 0, 0, &strName, &ei);
  2921. if(FAILED(hr)){
  2922. throw(hr);
  2923. }/* end of if statement */
  2924. hr = m_ps->SetScriptState(SCRIPTSTATE_CONNECTED);
  2925. }/* end of try statement */
  2926. catch(HRESULT hrTmp){
  2927. hr = hrTmp;
  2928. }
  2929. catch(...){
  2930. hr = E_UNEXPECTED;
  2931. }/* end of catch statement */
  2932. return (hr);
  2933. }/* end of function HookScriptlet */
  2934. /*************************************************************************/
  2935. /* Function: Run */
  2936. /* Description: Runs the Script function. Right now I do not support */
  2937. /* TODO: parameters, but they can be added, by handling VARIANT. */
  2938. /*************************************************************************/
  2939. STDMETHODIMP CMFBar::Run(BSTR strStatement){
  2940. HRESULT hr = E_FAIL;
  2941. if(!m_ps){
  2942. ATLTRACE(TEXT("No Script Engine!! No Run!!\n"));
  2943. ATLASSERT(FALSE);
  2944. return(hr);
  2945. }/* end of if statement */
  2946. CComPtr<IDispatch> pDispatch;
  2947. hr = m_ps->GetScriptDispatch(NULL, &pDispatch);
  2948. if (FAILED(hr)){
  2949. return(hr);
  2950. }/* end of if statement */
  2951. DISPID dispidMain;
  2952. LCID lcid = ::GetUserDefaultLCID();
  2953. hr = pDispatch->GetIDsOfNames(IID_NULL, &strStatement, 1, lcid, &dispidMain);
  2954. if (hr == ResultFromScode(DISP_E_UNKNOWNNAME))
  2955. hr = NOERROR;
  2956. else if (FAILED(hr))
  2957. hr = E_UNEXPECTED;
  2958. else{
  2959. UINT uArgErr;
  2960. DISPPARAMS params;
  2961. EXCEPINFO ei;
  2962. params.cArgs = 0;
  2963. params.cNamedArgs = 0;
  2964. params.rgvarg = NULL;
  2965. params.rgdispidNamedArgs = NULL;
  2966. hr = pDispatch->Invoke(dispidMain, IID_NULL, lcid, DISPATCH_METHOD,
  2967. &params,NULL, &ei, &uArgErr);
  2968. if (FAILED(hr)){
  2969. return(hr);
  2970. }/* end of if statement */
  2971. }/* end of if statement */
  2972. #ifdef _DEBUG
  2973. ULONG ulcstmt = 0;
  2974. if(FAILED(hr)){
  2975. return(hr);
  2976. }/* end of if statement */
  2977. CComQIPtr<IActiveScriptStats> pstat(m_ps);
  2978. if (pstat){
  2979. ULONG luT;
  2980. if (FAILED(pstat->GetStat(SCRIPTSTAT_STATEMENT_COUNT, &luT, &ulcstmt)))
  2981. ulcstmt = 0;
  2982. }/* end of if statement */
  2983. ATLTRACE("Statments executed %d\n", ulcstmt);
  2984. #endif
  2985. return(hr);
  2986. }/* end of function Run */
  2987. /*************************************************************************/
  2988. /* Function: CreateObject */
  2989. /* Description: Creates a new ActiveX object that can be scripted. */
  2990. /* Puts the newly created object into container and activates it. */
  2991. /*************************************************************************/
  2992. STDMETHODIMP CMFBar::CreateObject(BSTR strID, BSTR strProgID,
  2993. long lx, long ly, long lWidth, long lHeight,
  2994. BSTR strPropBag, VARIANT_BOOL fDisabled,
  2995. BSTR strScriptHook){
  2996. HRESULT hr;
  2997. CHostedObject *pObj = NULL; // an ActiveX object
  2998. try {
  2999. hr = FindObject(strID, &pObj);
  3000. if(SUCCEEDED(hr)){
  3001. ATLTRACE(TEXT("Duplicate Object \n!"));
  3002. throw(E_FAIL);
  3003. }/* end of if statement */
  3004. // create the object
  3005. hr = CHostedObject::CreateObject(strID, strProgID, strPropBag, &pObj);
  3006. if(FAILED(hr)){
  3007. ATLTRACE2(atlTraceHosting, 2, TEXT("Failed to Create Object %ls \n"), strID);
  3008. throw(hr);
  3009. }/* end of if statement */
  3010. // initialize inPlaceObject
  3011. CComPtr<IUnknown> pObjectUnknown;
  3012. pObjectUnknown = pObj->GetUnknown();
  3013. // Get this container unknown
  3014. CComPtr<IUnknown> pContainerUnknown;
  3015. pContainerUnknown = GetUnknown();
  3016. if(!pContainerUnknown){
  3017. throw(hr);
  3018. }/* end of if statement */
  3019. // this is just a container that delegates pretty
  3020. // much all the methods to this container
  3021. // only purpose for its being is that we need to connection
  3022. // between the container and a specific object
  3023. // for SetCapture and SetFocus calls
  3024. CContainerObject* pContainerObj = new CContainerObject(pContainerUnknown, pObj);
  3025. pContainerUnknown.Release();
  3026. if(NULL == pContainerObj){
  3027. throw(E_OUTOFMEMORY);
  3028. }/* end of if statement */
  3029. pObj->SetContainerObject(pContainerObj);
  3030. CComPtr<IUnknown> pUnkContainerObj;
  3031. hr = pContainerObj->QueryInterface(IID_IUnknown, (void**)&pUnkContainerObj);
  3032. if(FAILED(hr)){
  3033. hr = E_FAIL;
  3034. throw(hr);
  3035. }/* end of if statement */
  3036. // insert it at the end of the list
  3037. // TODO: eventually check for duplicate IDs
  3038. m_cntObj.insert(m_cntObj.end(), pObj);
  3039. // add our self to the script engine, so we can hook up the events
  3040. HRESULT hrTmp = m_ps->AddNamedItem((pObj)->GetID(), SCRIPTITEM_ISVISIBLE | SCRIPTITEM_ISSOURCE);
  3041. if(FAILED(hrTmp)){
  3042. ATLTRACE(TEXT("Engine is not initilized yet, but that is what I guess we intended\n"));
  3043. ATLASSERT(FALSE);
  3044. }/* end of if statement */
  3045. CComPtr<IOleObject> pOleObject;
  3046. HRESULT hrOle = pObj->GetOleObject(&pOleObject);
  3047. if(SUCCEEDED(hrOle)){
  3048. DWORD dwMiscStatus;
  3049. pOleObject->GetMiscStatus(DVASPECT_CONTENT, &dwMiscStatus);
  3050. // set the OLE site
  3051. CComPtr<IOleClientSite> spClientSite;
  3052. hr = pUnkContainerObj->QueryInterface(&spClientSite);
  3053. if(FAILED(hr)){
  3054. throw(hr);
  3055. }/* end of if statement */
  3056. if(dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST){
  3057. pOleObject->SetClientSite(spClientSite); // set the client site
  3058. }/* end of if statement */
  3059. // no property bag so try to initialze from stream
  3060. CComQIPtr<IPersistStreamInit, &IID_IPersistStreamInit> spPSI(pOleObject);
  3061. // TODO: Eventaully load up stream via CreateStreamOnHGlobal
  3062. if (spPSI)
  3063. spPSI->InitNew(); // create new stream
  3064. // see if want to use the IPropertyBag to initialize our properties
  3065. CComQIPtr<IPersistPropertyBag, &IID_IPersistPropertyBag> pBag(pObjectUnknown);
  3066. if (pBag) {
  3067. CComQIPtr<IPropertyBag, &IID_IPropertyBag> pSBag(pUnkContainerObj);
  3068. if(!pSBag){
  3069. ATLTRACE2(atlTraceHosting, 0, _T("Could not get IPropertyBag.\r\n"));
  3070. ATLASSERT(FALSE);
  3071. throw(E_UNEXPECTED);
  3072. }/* end of if statement */
  3073. HRESULT hrTmp = pBag->Load(pSBag, NULL);
  3074. if(SUCCEEDED(hrTmp)){
  3075. pBag->Save(pSBag, FALSE, TRUE);
  3076. }/* end of if statement */
  3077. }/* end of if statement */
  3078. if(0 == (dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST)){
  3079. pOleObject->SetClientSite(spClientSite); // set the client site
  3080. }/* end of if statement */
  3081. pObj->InitViewObject(); // cache view object
  3082. // hook up sink/notify for events
  3083. // via this call in which we have chance to hook them up
  3084. if(NULL != *strScriptHook){
  3085. HRESULT hrTmp = Run(strScriptHook);
  3086. if(FAILED(hrTmp)){
  3087. ATLTRACE(TEXT("Engine is not initilized yet, but that is what I guess we intended\n"));
  3088. ATLASSERT(FALSE);
  3089. }/* end of if statement */
  3090. }/* end of if statement */
  3091. // Get the extents adjust them etc...
  3092. // TODO enhance this to handle generic size
  3093. RECT rcPos;
  3094. SIZEL sSize, shmSize;
  3095. sSize.cx = lWidth;
  3096. sSize.cy = lHeight;
  3097. AtlPixelToHiMetric(&sSize, &shmSize);
  3098. pOleObject->SetExtent(DVASPECT_CONTENT, &shmSize);
  3099. pOleObject->GetExtent(DVASPECT_CONTENT, &shmSize);
  3100. AtlHiMetricToPixel(&shmSize, &sSize);
  3101. // TODO: handle the moves on SetObjectRects
  3102. // right now we set offset once but this needs to be eventaully done
  3103. rcPos.left = lx; // use m_rcPos for the offsets these any time we get SetObjectRects call
  3104. rcPos.top = ly;
  3105. rcPos.right = rcPos.left + sSize.cx;
  3106. rcPos.bottom = rcPos.top + sSize.cy;
  3107. // TODO: we might want to wait till our rect is set
  3108. // and then let the script to go at it, that way we reduce the moves
  3109. // and possible flashes
  3110. pObj->SetRawPos(&rcPos); // remember our new position raw position
  3111. //pObj->SetOffset(&m_rcPos.left, &m_rcPos.top); // sets the pointers to the offset
  3112. //pObj->GetPos(&rcPos); // get the position back with adjusted rect
  3113. // IN_PLACE ACTIVATE
  3114. hrOle = pOleObject->DoVerb(OLEIVERB_INPLACEACTIVATE, NULL, spClientSite, 0, m_hWnd, &rcPos);
  3115. if(VARIANT_FALSE != fDisabled){
  3116. pObj->SetActive(false);
  3117. }/* end of if statement */
  3118. }
  3119. else {
  3120. // use the liter interface when IOleObject is not available
  3121. CComQIPtr<IObjectWithSite> spSite(pObjectUnknown);
  3122. if(spSite){
  3123. spSite->SetSite(pUnkContainerObj);
  3124. }/* end of if statement */
  3125. }/* end of if statement */
  3126. }/* end of try statement */
  3127. catch(HRESULT hrTmp){
  3128. hr = hrTmp;
  3129. // cleanup our variables just in case
  3130. if(NULL != pObj){
  3131. delete pObj;
  3132. }/* end of if statement */
  3133. }
  3134. catch(...){
  3135. hr = E_UNEXPECTED;
  3136. }/* end of catch statement */
  3137. return (hr);
  3138. }/* end of function CreateObject */
  3139. /*************************************************************************/
  3140. /* Function: ShowSelfSite */
  3141. /* Description: Show itself as an site for itself. */
  3142. /*************************************************************************/
  3143. STDMETHODIMP CMFBar::ShowSelfSite(long nCmd)
  3144. {
  3145. if (::IsWindow(m_hWnd)) {
  3146. if (NULL != m_pBackBitmap)
  3147. m_pBackBitmap->DeleteMemDC();
  3148. #if 0
  3149. long extStyle = ::GetWindowLong(m_hWnd, GWL_EXSTYLE);
  3150. if (nCmd == SW_MAXIMIZE) {
  3151. extStyle |= WS_EX_TOPMOST;
  3152. }
  3153. else {
  3154. extStyle &= ~WS_EX_TOPMOST;
  3155. }
  3156. ::SetWindowLong(m_hWnd, GWL_EXSTYLE, extStyle);
  3157. #endif
  3158. ::ShowWindow(m_hWnd, nCmd);
  3159. InvalidateRgn();
  3160. }
  3161. return S_OK;
  3162. }
  3163. /*************************************************************************/
  3164. /* Function: SetupSelfSite */
  3165. /* Description: Sets itself as an site for itself. */
  3166. /*************************************************************************/
  3167. STDMETHODIMP CMFBar::SetupSelfSite(long lx, long ly, long lWidth,
  3168. long lHeight, BSTR strPropBag,
  3169. VARIANT_BOOL fDisabled,
  3170. VARIANT_BOOL fHelpDisabled,
  3171. VARIANT_BOOL fWindowDisabled){
  3172. HRESULT hr;
  3173. CHostedObject *pObj = NULL; // an ActiveX object
  3174. try {
  3175. if(true == m_fSelfHosted){
  3176. // we are already hosting our self so do not try to do so again
  3177. throw(S_FALSE);
  3178. }/* end of if statement */
  3179. if(m_nReadyState == READYSTATE_COMPLETE){
  3180. throw(S_FALSE); //we are already hosted (most likely IE)
  3181. }/* end of if statement */
  3182. m_bWindowOnly = TRUE; // create self as a window
  3183. m_fSelfHosted = true; // we are trying to self host so send a QUIT message
  3184. CComPtr<IDispatch> pDisp;
  3185. hr = GetUnknown()->QueryInterface(&pDisp);
  3186. if(FAILED(hr)){
  3187. throw(hr);
  3188. }/* end of if statement */
  3189. const INT ciMaxBuffSize = MAX_PATH; // should be enough for tlbr ID, keep ID small if can
  3190. TCHAR strBuffer[ciMaxBuffSize];
  3191. if(!::LoadString(m_hRes, IDS_ROOT_OBJECT, strBuffer, ciMaxBuffSize)){
  3192. hr = E_UNEXPECTED;
  3193. return(hr);
  3194. }/* end of if statement */
  3195. #ifndef _UNICODE
  3196. USES_CONVERSION;
  3197. BSTR strObjectID = ::SysAllocString(T2W(strBuffer));
  3198. #else
  3199. BSTR strObjectID = ::SysAllocString(strBuffer);
  3200. #endif
  3201. hr = CHostedObject::AddObject(strObjectID, strPropBag, pDisp, &pObj);
  3202. // strPropBag gets allocated as well
  3203. ::SysFreeString(strObjectID);
  3204. if(FAILED(hr)){
  3205. throw(hr);
  3206. }/* end of if statement */
  3207. // initialize inPlaceObject
  3208. CComPtr<IUnknown> pObjectUnknown;
  3209. pObjectUnknown = pObj->GetUnknown();
  3210. // Get this container unknown
  3211. CComPtr<IUnknown> pContainerUnknown;
  3212. pContainerUnknown = GetUnknown();
  3213. if(!pContainerUnknown){
  3214. throw(hr);
  3215. }/* end of if statement */
  3216. // this is just a container that delegates pretty
  3217. // much all the methods to this container
  3218. // only purpose for its being is that we need to connection
  3219. // between the container and a specific object
  3220. // for SetCapture and SetFocus calls
  3221. CContainerObject* pContainerObj = new CContainerObject(pContainerUnknown, pObj);
  3222. pContainerUnknown.Release();
  3223. if(NULL == pContainerObj){
  3224. throw(E_OUTOFMEMORY);
  3225. }/* end of if statement */
  3226. pObj->SetContainerObject(pContainerObj);
  3227. CComPtr<IUnknown> pUnkContainerObj;
  3228. hr = pContainerObj->QueryInterface(IID_IUnknown, (void**)&pUnkContainerObj);
  3229. if(FAILED(hr)){
  3230. throw(hr);
  3231. }/* end of if statement */
  3232. // DO NOT INSERT THIS OBJECT, SINCE IT IS OUR CONTAINER
  3233. // m_cntObj.insert(m_cntObj.end(), pObj);
  3234. CComPtr<IOleObject> pOleObject;
  3235. HRESULT hrOle = pObj->GetOleObject(&pOleObject);
  3236. if(FAILED(hrOle)){
  3237. throw(hrOle);
  3238. }/* end of if statement */
  3239. DWORD dwMiscStatus;
  3240. pOleObject->GetMiscStatus(DVASPECT_CONTENT, &dwMiscStatus);
  3241. // set the OLE site
  3242. CComPtr<IOleClientSite> spClientSite;
  3243. hr = pUnkContainerObj->QueryInterface(&spClientSite);
  3244. if(FAILED(hr)){
  3245. throw(hr);
  3246. }/* end of if statement */
  3247. if(dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST){
  3248. pOleObject->SetClientSite(spClientSite); // set the client site
  3249. }/* end of if statement */
  3250. // no property bag so try to initialze from stream
  3251. CComQIPtr<IPersistStreamInit, &IID_IPersistStreamInit> spPSI(pOleObject);
  3252. // TODO: Eventaully load up stream via CreateStreamOnHGlobal
  3253. if (spPSI)
  3254. spPSI->InitNew(); // create new stream
  3255. // see if want to use the IPropertyBag to initialize our properties
  3256. CComQIPtr<IPersistPropertyBag, &IID_IPersistPropertyBag> pBag(pObjectUnknown);
  3257. if (pBag) {
  3258. CComQIPtr<IPropertyBag, &IID_IPropertyBag> pSBag(pUnkContainerObj);
  3259. if(!pSBag){
  3260. ATLTRACE2(atlTraceHosting, 0, _T("Could not get IPropertyBag.\r\n"));
  3261. ATLASSERT(FALSE);
  3262. throw(E_UNEXPECTED);
  3263. }/* end of if statement */
  3264. HRESULT hrTmp = pBag->Load(pSBag, NULL);
  3265. if(SUCCEEDED(hrTmp)){
  3266. pBag->Save(pSBag, FALSE, TRUE);
  3267. }/* end of if statement */
  3268. }/* end of if statement */
  3269. if(0 == (dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST)){
  3270. pOleObject->SetClientSite(spClientSite); // set the client site
  3271. }/* end of if statement */
  3272. pObj->InitViewObject(); // cache view object
  3273. // TODO: hook up sink/notify for events
  3274. // Get the extents adjust them etc...
  3275. // TODO enhance this to handle generic size
  3276. RECT rcPos;
  3277. SIZEL sSize, shmSize;
  3278. sSize.cx = lWidth;
  3279. sSize.cy = lHeight;
  3280. AtlPixelToHiMetric(&sSize, &shmSize);
  3281. pOleObject->SetExtent(DVASPECT_CONTENT, &shmSize);
  3282. pOleObject->GetExtent(DVASPECT_CONTENT, &shmSize);
  3283. AtlHiMetricToPixel(&shmSize, &sSize);
  3284. // TODO: handle the moves on SetObjectRects
  3285. // right now we set offset once but this needs to be eventaully done
  3286. rcPos.left = lx; // use m_rcPos for the offsets these any time we get SetObjectRects call
  3287. rcPos.top = ly;
  3288. rcPos.right = rcPos.left + sSize.cx;
  3289. rcPos.bottom = rcPos.top + sSize.cy;
  3290. RECT rcClientRect;
  3291. rcClientRect.left = 0; // use m_rcPos for the offsets these any time we get SetObjectRects call
  3292. rcClientRect.top = 0;
  3293. rcClientRect.right = sSize.cx;
  3294. rcClientRect.bottom = sSize.cy;
  3295. // TODO: we might want to wait till our rect is set
  3296. // and then let the script to go at it, that way we reduce the moves
  3297. // and possible flashes
  3298. pObj->SetRawPos(&rcPos); // remember our new position raw position
  3299. // adjust rects
  3300. // IN_PLACE ACTIVATE OUR SELF ACTIVATION VERSION
  3301. if (m_spClientSite == NULL)
  3302. return S_OK;
  3303. CComPtr<IOleInPlaceObject> pIPO;
  3304. ControlQueryInterface(IID_IOleInPlaceObject, (void**)&pIPO);
  3305. ATLASSERT(pIPO != NULL);
  3306. m_spClientSite->QueryInterface(IID_IOleInPlaceSiteEx, (void**)&m_spInPlaceSite);
  3307. if (m_spInPlaceSite)
  3308. m_bInPlaceSiteEx = TRUE;
  3309. else
  3310. hr = m_spClientSite->QueryInterface(IID_IOleInPlaceSite, (void**) &m_spInPlaceSite);
  3311. ATLASSERT(m_spInPlaceSite);
  3312. if (!m_spInPlaceSite)
  3313. throw(E_FAIL);
  3314. m_bNegotiatedWnd = TRUE;
  3315. if (!m_bInPlaceActive){
  3316. BOOL bNoRedraw = FALSE;
  3317. if (m_bInPlaceSiteEx)
  3318. m_spInPlaceSite->OnInPlaceActivateEx(&bNoRedraw, 0);
  3319. else
  3320. {
  3321. hr = m_spInPlaceSite->CanInPlaceActivate();
  3322. // CanInPlaceActivate returns S_FALSE or S_OK
  3323. if (FAILED(hr))
  3324. throw(hr);
  3325. if ( hr != S_OK )
  3326. {
  3327. // CanInPlaceActivate returned S_FALSE.
  3328. throw( E_FAIL );
  3329. }
  3330. m_spInPlaceSite->OnInPlaceActivate();
  3331. }
  3332. }/* end of if statement */
  3333. m_bInPlaceActive = TRUE;
  3334. // get location in the parent window,
  3335. // as well as some information about the parent
  3336. //
  3337. OLEINPLACEFRAMEINFO frameInfo;
  3338. CComPtr<IOleInPlaceFrame> spInPlaceFrame;
  3339. CComPtr<IOleInPlaceUIWindow> spInPlaceUIWindow;
  3340. frameInfo.cb = sizeof(OLEINPLACEFRAMEINFO);
  3341. if (!m_bWndLess){
  3342. DWORD dwStyle;
  3343. DWORD dwExStyle;
  3344. HWND hwndPar = NULL;
  3345. if(VARIANT_FALSE == fWindowDisabled){
  3346. // one with the frame
  3347. dwStyle = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
  3348. dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
  3349. }
  3350. else {
  3351. // one without the frame
  3352. dwStyle = WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS |WS_SYSMENU| WS_MAXIMIZEBOX| WS_MINIMIZEBOX ;
  3353. //dwExStyle = WS_EX_TRANSPARENT; //| WS_EX_LTRREADING| WS_EX_WINDOWEDGE;
  3354. //dwExStyle = 0x00080000; //WS_EX_LAYERED = 0x00080000;
  3355. dwExStyle = WS_EX_APPWINDOW;
  3356. //hwndPar = ::GetDesktopWindow();
  3357. }/* end of if statement */
  3358. if(VARIANT_FALSE == fDisabled){
  3359. dwStyle |= WS_VISIBLE;
  3360. }/* end of if statement */
  3361. if(VARIANT_FALSE == fHelpDisabled){
  3362. dwStyle &= ~(WS_MINIMIZEBOX | WS_MAXIMIZEBOX); // take out the min max style
  3363. // help does not work with it
  3364. dwExStyle |= WS_EX_CONTEXTHELP;
  3365. }/* end of if statement */
  3366. #ifdef _UNICODE
  3367. HWND h = Create(hwndPar, rcPos, m_bstrCaption /* window name */, dwStyle, dwExStyle);
  3368. #else
  3369. USES_CONVERSION;
  3370. HWND h = Create(hwndPar, rcPos, OLE2T(m_bstrCaption) /* window name */, dwStyle, dwExStyle);
  3371. #endif
  3372. // used instead of
  3373. // HWND h = CreateControlWindow(hwndParent, rcPos);
  3374. ATLASSERT(h != NULL); // will assert if creation failed
  3375. ATLASSERT(h == m_hWndCD);
  3376. if(NULL == h){
  3377. throw(E_FAIL);
  3378. }/* end of if statement */
  3379. if(VARIANT_TRUE == fWindowDisabled){
  3380. ::SendMessage(h, WM_SETICON, (WPARAM)ICON_SMALL, (LPARAM) m_hIcon);
  3381. ::SendMessage(h, WM_SETICON, (WPARAM)ICON_BIG, (LPARAM) m_hIcon);
  3382. }/* end of if statement */
  3383. }/* end of if statement */
  3384. if(VARIANT_FALSE != fDisabled){
  3385. pObj->SetActive(false);
  3386. }/* end of if statement */
  3387. if (m_hMenu) {
  3388. ::DestroyMenu(m_hMenu);
  3389. m_hMenu = NULL;
  3390. }
  3391. // Create the system menu
  3392. m_hMenu = ::LoadMenu(_Module.GetModuleInstance(), MAKEINTRESOURCE(IDR_SYSMENU));
  3393. MENUINFO mInfo;
  3394. mInfo.cbSize = sizeof(MENUINFO);
  3395. #if(WINVER >= 0x0500)
  3396. ::GetMenuInfo(::GetSubMenu(m_hMenu, 0), &mInfo);
  3397. #else
  3398. CallGetMenuInfo(::GetSubMenu(m_hMenu, 0), &mInfo);
  3399. #endif
  3400. mInfo.dwStyle = MNS_NOCHECK;
  3401. mInfo.fMask = MIM_STYLE;
  3402. #if(WINVER >= 0x0500)
  3403. ::SetMenuInfo(::GetSubMenu(m_hMenu, 0), &mInfo);
  3404. #else
  3405. CallSetMenuInfo(::GetSubMenu(m_hMenu, 0), &mInfo);
  3406. #endif
  3407. #if(WINVER >= 0x0500)
  3408. MENUITEMINFO iInfo;
  3409. iInfo.cbSize = sizeof(MENUITEMINFO);
  3410. #else
  3411. MENUITEMINFOInternal iInfo;
  3412. iInfo.cbSize = sizeof(MENUITEMINFOInternal);
  3413. #endif
  3414. ::GetMenuItemInfo(::GetSubMenu(m_hMenu, 0), ID_SYSTEMMENU_RESTORE, false, (LPMENUITEMINFO)&iInfo);
  3415. iInfo.hbmpItem = HBMMENU_POPUP_RESTORE;
  3416. iInfo.fMask = MIIM_BITMAP;
  3417. ::SetMenuItemInfo(::GetSubMenu(m_hMenu, 0), ID_SYSTEMMENU_RESTORE, false, (LPCMENUITEMINFO)&iInfo);
  3418. ::GetMenuItemInfo(::GetSubMenu(m_hMenu, 0), ID_SYSTEMMENU_MINIMIZE, false, (LPMENUITEMINFO)&iInfo);
  3419. iInfo.hbmpItem = HBMMENU_POPUP_MINIMIZE;
  3420. iInfo.fMask = MIIM_BITMAP;
  3421. ::SetMenuItemInfo(::GetSubMenu(m_hMenu, 0), ID_SYSTEMMENU_MINIMIZE, false, (LPCMENUITEMINFO)&iInfo);
  3422. ::GetMenuItemInfo(::GetSubMenu(m_hMenu, 0), ID_SYSTEMMENU_MAXIMIZE, false, (LPMENUITEMINFO)&iInfo);
  3423. iInfo.hbmpItem = HBMMENU_POPUP_MAXIMIZE;
  3424. iInfo.fMask = MIIM_BITMAP;
  3425. ::SetMenuItemInfo(::GetSubMenu(m_hMenu, 0), ID_SYSTEMMENU_MAXIMIZE, false, (LPCMENUITEMINFO)&iInfo);
  3426. ::GetMenuItemInfo(::GetSubMenu(m_hMenu, 0), ID_SYSTEMMENU_CLOSE, false, (LPMENUITEMINFO)&iInfo);
  3427. iInfo.hbmpItem = HBMMENU_POPUP_CLOSE;
  3428. iInfo.fMask = MIIM_BITMAP|MIIM_STATE;
  3429. iInfo.fState = MFS_DEFAULT;
  3430. ::SetMenuItemInfo(::GetSubMenu(m_hMenu, 0), ID_SYSTEMMENU_CLOSE, false, (LPCMENUITEMINFO)&iInfo);
  3431. }/* end of try statement */
  3432. catch(HRESULT hrTmp){
  3433. hr = hrTmp;
  3434. m_fSelfHosted = false;
  3435. // cleanup our variables just in case
  3436. if(NULL != pObj){
  3437. delete pObj;
  3438. }/* end of if statement */
  3439. }
  3440. catch(...){
  3441. m_fSelfHosted = false;
  3442. hr = E_UNEXPECTED;
  3443. }/* end of catch statement */
  3444. return (hr);
  3445. }/* end of function SetupSelfSite */
  3446. /*************************************************************************/
  3447. /* Function: AddObject */
  3448. /* Description: Adds a scriptable only object that was created somewhere */
  3449. /* else into our object container. */
  3450. /*************************************************************************/
  3451. STDMETHODIMP CMFBar::AddObject(BSTR strObjectID, LPDISPATCH pDisp){
  3452. HRESULT hr;
  3453. CHostedObject *pObj = NULL; // an ActiveX object
  3454. try {
  3455. // add an object that was already created
  3456. // this object does not get the Active flag set which
  3457. // means we will not try to draw it and do other
  3458. // activities on it, such as we would do on the objects
  3459. // that are contained and have a site
  3460. hr = CHostedObject::AddObject(strObjectID, NULL, pDisp, &pObj);
  3461. if(FAILED(hr)){
  3462. throw(hr);
  3463. }/* end of if statement */
  3464. // now add the object to the container
  3465. // insert it at the end of the list
  3466. // TODO: eventually check for duplicate IDs
  3467. m_cntObj.insert(m_cntObj.end(), pObj);
  3468. }/* end of try statement */
  3469. catch(HRESULT hrTmp){
  3470. hr = hrTmp;
  3471. // cleanup our variables just in case
  3472. if(NULL != pObj){
  3473. delete pObj;
  3474. }/* end of if statement */
  3475. }
  3476. catch(...){
  3477. hr = E_UNEXPECTED;
  3478. }/* end of catch statement */
  3479. return (hr);
  3480. }/* end of function AddObject */
  3481. // ##### END ACTIVEX SCRIPTING SUPPORT #####
  3482. /*************************************************************************/
  3483. /* Function: GetParentHWND */
  3484. /* Description: Gets the parent window HWND where we are operating. */
  3485. /*************************************************************************/
  3486. HRESULT CMFBar::GetParentHWND(HWND* pWnd){
  3487. HRESULT hr = E_FAIL;
  3488. *pWnd = NULL;
  3489. if(m_bWndLess){
  3490. CComPtr<IOleClientSite> pClientSite;
  3491. hr = GetClientSite(&pClientSite);
  3492. if(FAILED(hr)){
  3493. return(hr);
  3494. }/* end of if statement */
  3495. CComQIPtr<IOleWindow> pOleWindow(pClientSite);
  3496. if(!pOleWindow){
  3497. hr = E_FAIL;
  3498. return(hr);
  3499. }/* end of if statement */
  3500. hr = pOleWindow->GetWindow(pWnd);
  3501. }
  3502. else {
  3503. if(::IsWindow(m_hWnd)){
  3504. *pWnd = ::GetParent(m_hWnd);
  3505. if(::IsWindow(*pWnd)){
  3506. hr = S_OK;
  3507. }/* end of if statement */
  3508. }/* end of if statement */
  3509. }/* end of if statement */
  3510. return(hr);
  3511. }/* end of function GetParentHWND */
  3512. /*************************************************************************/
  3513. /* Function: GetClientRect */
  3514. /* Description: Gets the client rect. If we are windowless we pass down */
  3515. /* the m_rcPos. */
  3516. /*************************************************************************/
  3517. BOOL CMFBar::GetClientRect(LPRECT lpRect) const{
  3518. BOOL bRet = TRUE;
  3519. if (!lpRect){
  3520. bRet = FALSE;
  3521. return (bRet);
  3522. }/* end of if statement */
  3523. if(m_bWndLess){
  3524. *lpRect = m_rcPos;
  3525. return(bRet);
  3526. }/* end of if statement */
  3527. ATLASSERT(::IsWindow(m_hWnd));
  3528. bRet = ::GetClientRect(m_hWnd, lpRect);
  3529. return(bRet);
  3530. }/* end of function GetClientRect */
  3531. /*************************************************************************/
  3532. /* Function: GetParent */
  3533. /* Description: Gets the parent window. If we are windowless we pass */
  3534. /* down the parent container window, which is really in a sense parent. */
  3535. /*************************************************************************/
  3536. HWND CMFBar::GetParent(){
  3537. HWND hwnd = NULL;
  3538. if(m_bWndLess){
  3539. GetParentHWND(&hwnd);
  3540. return(hwnd);
  3541. }/* end of if statement */
  3542. ATLASSERT(::IsWindow(m_hWnd));
  3543. return ::GetParent(m_hWnd);
  3544. }/* end of function GetParent */
  3545. /*************************************************************************/
  3546. /* Function: AdjustRects */
  3547. /* Description: calls all our contained objects and the adjusts their */
  3548. /* rects in the case we have moved, if we do not have any that is OK, */
  3549. /* since the offset is kept in m_rcPos and set whenever the objects */
  3550. /* get created. */
  3551. /*************************************************************************/
  3552. HRESULT CMFBar::AdjustRects(const LPCRECT prcPos){
  3553. HRESULT hr = S_OK;
  3554. //TODO: handle resizing
  3555. ATLTRACE2(atlTraceHosting, 2, TEXT("Resizing control prcPos->left = %d, prcPos.right = %d, prcPos.bottom =%d, prcPos.top = %d\n"),
  3556. prcPos->left, prcPos->right, prcPos->bottom, prcPos->top);
  3557. if(false == m_fSelfHosted){
  3558. Fire_OnResize(RECTWIDTH(prcPos), RECTHEIGHT(prcPos), SIZE_RESTORED);
  3559. }/* end of if statement */
  3560. #if 0
  3561. if(!m_bWndLess){
  3562. return(hr);
  3563. }/* end of if statement */
  3564. if(m_cntObj.empty() == true){
  3565. hr = S_FALSE;
  3566. return(hr);
  3567. }/* end of if statement */
  3568. CNTOBJ::iterator i;
  3569. for(i = m_cntObj.begin(); i!= m_cntObj.end(); i++){
  3570. CHostedObject* pObj = (*i);
  3571. ATLASSERT(pObj);
  3572. if(m_fSelfHosted && (GetUnknown() == pObj->GetUnknown())){
  3573. continue; // that is us we close our self later after the contained objects
  3574. }/* end of if statement */
  3575. pObj->SetObjectRects(); // adjust the current offset if it needs to be so
  3576. }/* end of for loop */
  3577. #endif
  3578. return(hr);
  3579. }/* end of function AdjustRects */
  3580. /*************************************************************************/
  3581. /* IOleInPlaceSiteEx Implementation */
  3582. /*************************************************************************/
  3583. /*************************************************************************/
  3584. /* Function: CanWindowlessActivate */
  3585. /* Description: Return if we can windowless activate or not. */
  3586. /*************************************************************************/
  3587. STDMETHODIMP CMFBar::CanWindowlessActivate(){
  3588. return m_bCanWindowlessActivate ? S_OK : S_FALSE;
  3589. }/* end of function CanWindowlessActivate */
  3590. /*************************************************************************/
  3591. /* Function: GetDC */
  3592. /* Description: Gets a DC to draw with. */
  3593. /*************************************************************************/
  3594. STDMETHODIMP CMFBar::GetDC(LPCRECT pRect, DWORD grfFlags, HDC* phDC){
  3595. HRESULT hr = S_OK;
  3596. if(m_bWndLess){
  3597. hr = m_spInPlaceSite->GetDC(pRect, grfFlags, phDC);
  3598. }
  3599. else {
  3600. if(NULL == m_hWnd){
  3601. hr = E_FAIL;
  3602. return(hr);
  3603. }/* end of if statement */
  3604. if(::IsWindow(m_hWnd)){
  3605. *phDC = ::GetDC(m_hWnd);
  3606. }
  3607. else {
  3608. hr = E_UNEXPECTED;
  3609. }/* end of if statement */
  3610. }/* end of if statement */
  3611. return(hr);
  3612. }/* end of function GetDC */
  3613. /*************************************************************************/
  3614. /* Function: ReleaseDC */
  3615. /* Description: Releases the DC */
  3616. /*************************************************************************/
  3617. STDMETHODIMP CMFBar::ReleaseDC(HDC hDC){
  3618. HRESULT hr = S_OK;
  3619. if(m_bWndLess){
  3620. hr = m_spInPlaceSite->ReleaseDC(hDC);
  3621. }
  3622. else {
  3623. if(NULL == m_hWnd){
  3624. hr = E_FAIL;
  3625. return(hr);
  3626. }/* end of if statement */
  3627. if(::IsWindow(m_hWnd)){
  3628. ::ReleaseDC(m_hWnd, hDC);
  3629. }
  3630. else {
  3631. hr = E_UNEXPECTED;
  3632. }/* end of if statement */
  3633. }/* end of if statement */
  3634. return(hr);
  3635. }/* end of function ReleaseDC */
  3636. /*************************************************************************/
  3637. /* Function: OnDefWindowMessage */
  3638. /* Description: Sends on messages to the default window procedure. */
  3639. /*************************************************************************/
  3640. STDMETHODIMP CMFBar::OnDefWindowMessage(UINT msg, WPARAM wParam,
  3641. LPARAM lParam, LRESULT* plResult){
  3642. *plResult = DefWindowProc(msg, wParam, lParam);
  3643. return S_OK;
  3644. }/* end of function OnDefWindowMessage */
  3645. /*************************************************************************/
  3646. /* Function: InvalidateRgn */
  3647. /* Description: Invalidates the whole rect in case we need to repaint it.*/
  3648. /*************************************************************************/
  3649. STDMETHODIMP CMFBar::InvalidateRgn(HRGN hRGN, BOOL fErase){
  3650. HRESULT hr = S_OK;
  3651. #if 0
  3652. if (!hRGN) {
  3653. RECT rc;
  3654. GetClientRect(&rc);
  3655. hRGN = ::CreateRectRgn( rc.left, rc.top, rc.right, rc.bottom);
  3656. }
  3657. HRGN newRgn = ::CreateRectRgn(0, 0, 10, 10);
  3658. ::CombineRgn(newRgn, hRGN, NULL, RGN_COPY) ;
  3659. CNTOBJ::iterator i;
  3660. for(i = m_cntObj.begin(); i!= m_cntObj.end(); i++){
  3661. CHostedObject* pObj = (*i);
  3662. ATLASSERT(pObj);
  3663. if(m_fSelfHosted && (GetUnknown() == pObj->GetUnknown())){
  3664. continue; // that is us we close our self later after the contained objects
  3665. }/* end of if statement */
  3666. if (!pObj->IsWindowless() && pObj->IsActive()) {
  3667. LONG x1, y1, w, h;
  3668. GetObjectPosition(pObj->GetID(), &x1, &y1, &w, &h);
  3669. HRGN objRgn = ::CreateRectRgn( x1, y1, x1+w, y1+h );
  3670. ::CombineRgn(newRgn, newRgn, objRgn, RGN_DIFF);
  3671. //ATLTRACE(TEXT("Excluding Rgn %d %d %d %d\n"), x1, y1, x1+w, y1+h);
  3672. }
  3673. }/* end of for loop */
  3674. hRGN = newRgn;
  3675. #endif
  3676. if(m_bWndLess){
  3677. hr = m_spInPlaceSite->InvalidateRgn(hRGN ,fErase);
  3678. }
  3679. else {
  3680. if(NULL == m_hWnd){
  3681. hr = E_FAIL;
  3682. return(hr);
  3683. }/* end of if statement */
  3684. if(::IsWindow(m_hWnd)){
  3685. ::InvalidateRgn(m_hWnd, hRGN, fErase); // see if we can get by by not erasing..
  3686. }
  3687. else {
  3688. hr = E_UNEXPECTED;
  3689. }/* end of if statement */
  3690. }/* end of if statement */
  3691. return(hr);
  3692. }/* end of function InvalidateRgn */
  3693. /*************************************************************************/
  3694. /* Function: InvalidateRect */
  3695. /* Description: Invalidates the rect, handles if we are windowless */
  3696. /*************************************************************************/
  3697. STDMETHODIMP CMFBar::InvalidateRect(LPCRECT pRect, BOOL fErase){
  3698. HRESULT hr = S_OK;
  3699. if(m_bWndLess){
  3700. hr = m_spInPlaceSite->InvalidateRect(pRect, fErase);
  3701. }
  3702. else {
  3703. if(NULL == m_hWnd){
  3704. hr = E_FAIL;
  3705. return(hr);
  3706. }/* end of if statement */
  3707. if(::IsWindow(m_hWnd)){
  3708. ::InvalidateRect(m_hWnd, pRect, fErase);
  3709. }
  3710. else {
  3711. hr = E_UNEXPECTED;
  3712. }/* end of if statement */
  3713. }/* end of if statement */
  3714. return(hr);
  3715. }/* end of function InvalidateRect */
  3716. /*************************************************************************/
  3717. /* Function: GetCapture */
  3718. /* Description: Used to determine if we have a cupature or not */
  3719. /*************************************************************************/
  3720. STDMETHODIMP CMFBar::GetCapture(){
  3721. HRESULT hr = S_OK;
  3722. if(m_bWndLess){
  3723. hr = m_spInPlaceSite->GetCapture();
  3724. }
  3725. else {
  3726. if(NULL == m_hWnd){
  3727. hr = E_FAIL;
  3728. return(hr);
  3729. }/* end of if statement */
  3730. if(::IsWindow(m_hWnd)){
  3731. hr = ::GetCapture() == m_hWnd ? S_OK : S_FALSE;
  3732. }/* end of if statement */
  3733. }/* end of if statement */
  3734. return(hr);
  3735. }/* end of function GetCapture */
  3736. /*************************************************************************/
  3737. /* Function: SetCapture */
  3738. /* Description: Used to set the capture for mouse events */
  3739. /* Only one container at the time can have a capture. */
  3740. /*************************************************************************/
  3741. STDMETHODIMP CMFBar::SetCapture(BOOL fCapture){
  3742. HRESULT hr = S_OK;
  3743. // whatever we we are doing we need to reset the capture flags on all the object
  3744. // after this call is finished the specific site will set appropriate flag
  3745. ResetCaptureFlags();
  3746. if(fCapture){
  3747. ATLTRACE2(atlTraceUser, 31, TEXT("Setting Mouse Capture in the container \n"));
  3748. }
  3749. else {
  3750. ATLTRACE2(atlTraceUser, 31, TEXT("Resetting Mouse Capture in the container\n"));
  3751. }/* end of if statement */
  3752. if(m_bWndLess){
  3753. if (fCapture){
  3754. hr = m_spInPlaceSite->SetCapture(TRUE);
  3755. }
  3756. else {
  3757. hr = m_spInPlaceSite->SetCapture(FALSE);
  3758. }/* end of if statement */
  3759. }
  3760. else {
  3761. if(NULL == m_hWnd){
  3762. hr = E_FAIL;
  3763. return(hr);
  3764. }/* end of if statement */
  3765. if(::IsWindow(m_hWnd)){
  3766. if (fCapture){
  3767. // do not have a capture, so set it
  3768. ATLTRACE2(atlTraceWindowing, 4, TEXT("Setting caputure to our self (container) \n"));
  3769. ::SetCapture(m_hWnd);
  3770. }
  3771. else{
  3772. // nobody more has a capture, so let it go
  3773. ATLTRACE2(atlTraceWindowing, 4, TEXT("Releasing caputure from our self (container) \n"));
  3774. ::ReleaseCapture();
  3775. }/* end of if statement */
  3776. }
  3777. else {
  3778. hr = E_UNEXPECTED;
  3779. }/* end of if statement */
  3780. }/* end of if statement */
  3781. return(hr);
  3782. }/* end of function SetCapture */
  3783. /*************************************************************************/
  3784. /* Function: ResetCaptureFlags */
  3785. /* Description: Resets the capture on contained objects. */
  3786. /*************************************************************************/
  3787. HRESULT CMFBar::ResetCaptureFlags(){
  3788. for(CNTOBJ::iterator i = m_cntObj.begin(); i!= m_cntObj.end(); i++){
  3789. // iterate through all the contained objects and draw them
  3790. CHostedObject* pObj = (*i);
  3791. pObj->SetCapture(false);
  3792. }/* end of for function */
  3793. return(S_OK);
  3794. }/* end of function ResetCaptureFlags */
  3795. /*************************************************************************/
  3796. /* Function: ResetFocusFlags */
  3797. /* Description: Resets the capture on contained objects. */
  3798. /*************************************************************************/
  3799. HRESULT CMFBar::ResetFocusFlags(){
  3800. for(CNTOBJ::iterator i = m_cntObj.begin(); i!= m_cntObj.end(); i++){
  3801. // iterate through all the contained objects and draw them
  3802. CHostedObject* pObj = (*i);
  3803. if(pObj->HasFocus()){
  3804. LONG lRes;
  3805. SetObjectFocus(pObj, FALSE, lRes);
  3806. }/* end of if statement */
  3807. }/* end of for function */
  3808. return(S_OK);
  3809. }/* end of function ResetFocusFlags */
  3810. /*************************************************************************/
  3811. /* Function: EnumObjects */
  3812. /* Description: Returns IEnumUnknown */
  3813. /*************************************************************************/
  3814. STDMETHODIMP CMFBar::EnumObjects(DWORD /*grfFlags*/, IEnumUnknown** ppenum){
  3815. if (ppenum == NULL)
  3816. return E_POINTER;
  3817. *ppenum = NULL;
  3818. // TODO: handle flags
  3819. ATLASSERT(FALSE);
  3820. if(m_cntObj.empty() == true){
  3821. return E_FAIL;
  3822. }/* end of if statement */
  3823. typedef CComObject<CComEnum<IEnumUnknown, &IID_IEnumUnknown, IUnknown*, _CopyInterface<IUnknown> > > enumunk;
  3824. enumunk* p = NULL;
  3825. ATLTRY(p = new enumunk);
  3826. if(p == NULL)
  3827. return E_OUTOFMEMORY;
  3828. // create an array to which we put our *IUnknowns
  3829. INT iSize = m_cntObj.size();
  3830. IUnknown** pArray = new IUnknown* [iSize];
  3831. if(pArray == NULL)
  3832. return E_OUTOFMEMORY;
  3833. bool bFirstElement = true;
  3834. CNTOBJ::iterator i;
  3835. INT iCount = 0;
  3836. for(i = m_cntObj.begin(); i!= m_cntObj.end(); i++){
  3837. // move the interfaces to the array
  3838. CHostedObject* pObj = (*i);
  3839. pArray[iCount] = pObj->GetUnknown();
  3840. pArray[iCount]->AddRef();
  3841. iCount++;
  3842. }/* end of for loop */
  3843. HRESULT hRes = p->Init(pArray, pArray + iSize, GetUnknown(), AtlFlagCopy);
  3844. if (SUCCEEDED(hRes))
  3845. hRes = p->QueryInterface(IID_IEnumUnknown, (void**)ppenum);
  3846. if (FAILED(hRes))
  3847. delete p;
  3848. delete[] pArray;
  3849. return hRes;
  3850. }/* end of function EnumObjects */
  3851. /*************************************************************************/
  3852. /* Function: SendMessageToCtl */
  3853. /* Description: Forwards message to a control */
  3854. /*************************************************************************/
  3855. HRESULT CMFBar::SendMessageToCtl(CHostedObject* pObj,
  3856. UINT uMsg, WPARAM wParam, LPARAM lParam,
  3857. BOOL& bHandled, LONG& lRes, bool fWndwlsOnly, bool fActiveOnly){
  3858. HRESULT hr = S_OK;
  3859. if(NULL == pObj){
  3860. hr = E_UNEXPECTED;
  3861. return(hr);
  3862. }/* end of if statement */
  3863. if(fWndwlsOnly && (!pObj->IsWindowless())){
  3864. ATLTRACE2(atlTraceUser, 31, TEXT("NOT SENDING message to control %ls !!!\n"), pObj->GetID());
  3865. hr = E_FAIL;
  3866. return(hr);
  3867. }/* end of if statement */
  3868. if(fActiveOnly && (!pObj->IsInputEnabled())){
  3869. ATLTRACE2(atlTraceUser, 31, TEXT("NOT SENDING message to control %ls !!!\n"), pObj->GetID());
  3870. hr = E_FAIL;
  3871. return(hr);
  3872. }/* end of if statement */
  3873. CComPtr<IUnknown> pUnk = pObj->GetUnknown();
  3874. if(!pUnk){
  3875. ATLASSERT(FALSE); // should not be null
  3876. return(E_FAIL);
  3877. }/* end of if statement */
  3878. if(pUnk == GetUnknown()){
  3879. // do not send message to our self since we might endup in the never ending recusion
  3880. return(S_FALSE);
  3881. }/* end of if statement */
  3882. CComQIPtr<IOleInPlaceObjectWindowless> spInPlaceObjectWindowless(pUnk);
  3883. if(spInPlaceObjectWindowless){
  3884. // more then one control can have have a capture
  3885. LRESULT lResTemp;
  3886. spInPlaceObjectWindowless->OnWindowMessage(uMsg, wParam, lParam, &lResTemp);
  3887. lRes = (LONG) lResTemp;
  3888. bHandled = TRUE;
  3889. }/* end of if statement */
  3890. return(hr);
  3891. }/* end of function SendMessageToCtl */
  3892. /*************************************************************************/
  3893. /* Function: GetFocus */
  3894. /* Description: Determine if we have a focus or not. */
  3895. /*************************************************************************/
  3896. STDMETHODIMP CMFBar::GetFocus(){
  3897. HRESULT hr = S_OK;
  3898. if(m_bWndLess){
  3899. hr = m_spInPlaceSite->GetFocus();
  3900. }
  3901. else {
  3902. if(NULL == m_hWnd){
  3903. hr = E_FAIL;
  3904. return(hr);
  3905. }/* end of if statement */
  3906. if(::IsWindow(m_hWnd)){
  3907. hr = ::GetFocus() == m_hWnd ? S_OK : S_FALSE;
  3908. }/* end of if statement */
  3909. }/* end of if statement */
  3910. return(hr);
  3911. }/* end of function GetFocus */
  3912. /*************************************************************************/
  3913. /* Function: SetFocus */
  3914. /* Description: Sets focus to the control */
  3915. /*************************************************************************/
  3916. STDMETHODIMP CMFBar::SetFocus(BOOL fFocus){
  3917. HRESULT hr = S_OK;
  3918. // we reset the flags depending on WM_SET and WM_KILL focus messages
  3919. if(fFocus){
  3920. ATLTRACE2(atlTraceUser, 31, TEXT("Setting Mouse Focus in the container \n"));
  3921. }
  3922. else {
  3923. ATLTRACE2(atlTraceUser, 31, TEXT("Resetting Mouse Focus in the container\n"));
  3924. }/* end of if statement */
  3925. if(m_bWndLess){
  3926. if (fFocus){
  3927. hr = m_spInPlaceSite->SetFocus(TRUE);
  3928. }
  3929. else {
  3930. hr = m_spInPlaceSite->SetFocus(FALSE);
  3931. }/* end of if statement */
  3932. }
  3933. else {
  3934. if(NULL == m_hWnd){
  3935. hr = E_FAIL;
  3936. return(hr);
  3937. }/* end of if statement */
  3938. if(::IsWindow(m_hWnd)){
  3939. if (fFocus){
  3940. ::SetFocus(m_hWnd);
  3941. }
  3942. else {
  3943. // else could call ::SetFocus(NULL), but that does not seem like a good solution
  3944. // so instead reset the focus on contained conrols
  3945. // which is risky too, since some control could try to call SetFocus(false)
  3946. // when it does not have the focus, but that is handled in the caller
  3947. //ResetFocusFlags();
  3948. }/* end of if statement */
  3949. }/* end of if statement */
  3950. else {
  3951. hr = E_UNEXPECTED;
  3952. }/* end of if statement */
  3953. }/* end of if statement */
  3954. return(hr);
  3955. }/* end of function SetFocus */
  3956. /*************************************************************************/
  3957. /* Function: get_ActivityTimeOut */
  3958. /* Description: Gets the currrent timout value. */
  3959. /*************************************************************************/
  3960. STDMETHODIMP CMFBar::get_ActivityTimeout(long *plTimeout){
  3961. *plTimeout = m_lTimeout;
  3962. return(S_OK);
  3963. }/* end of function get_ActivityTimeOut */
  3964. /*************************************************************************/
  3965. /* Function: put_ActivityTimeOut */
  3966. /* Description: Creates a new timer if needed. */
  3967. /*************************************************************************/
  3968. STDMETHODIMP CMFBar::put_ActivityTimeout(long lTimeout){
  3969. if(lTimeout < 0){
  3970. return(E_INVALIDARG);
  3971. }/* end of if statement */
  3972. if(!::IsWindow(m_hWnd)){
  3973. return(E_FAIL);
  3974. }/* end of if statement */
  3975. if(m_lTimeout != 0 || 0 == lTimeout ){
  3976. // kill it each time we set a new timer
  3977. ::KillTimer(m_hWnd, ID_EV_TIMER);
  3978. }
  3979. else {
  3980. if(0 == ::SetTimer(m_hWnd, ID_EV_TIMER, lTimeout, NULL)){
  3981. return(E_FAIL);
  3982. }/* end of if statement */
  3983. }/* end of if statement */
  3984. m_lTimeout = lTimeout;
  3985. m_fUserActivity = false;
  3986. m_fWaitingForActivity = false;
  3987. return(S_OK);
  3988. }/* end of function put_ActivityTimeOut */
  3989. /*************************************************************************/
  3990. /* Function: SetObjectExtent */
  3991. /* Description: Sets specific object witdth and height. */
  3992. /*************************************************************************/
  3993. STDMETHODIMP CMFBar::SetObjectExtent(BSTR strObjectID, long lWidth, long lHeight){
  3994. HRESULT hr = E_FAIL;
  3995. if(NULL == strObjectID){
  3996. hr = E_POINTER;
  3997. return(hr);
  3998. }/* end of if sattement */
  3999. bool bFirstElement = true;
  4000. CNTOBJ::iterator i;
  4001. for(i = m_cntObj.begin(); i!= m_cntObj.end(); i++){
  4002. CHostedObject* pObj = (*i);
  4003. if(!_wcsicmp(pObj->GetID(), strObjectID)){
  4004. RECT rcOld;
  4005. hr = pObj->GetPos(&rcOld);
  4006. if(FAILED(hr)){
  4007. return(hr);
  4008. }/* end of if statement */
  4009. RECT rcNew;
  4010. rcNew.left = rcOld.left; rcNew.top = rcOld.top;
  4011. rcNew.right = rcNew.left + lWidth; rcNew.bottom = rcNew.top + lHeight;
  4012. if(::EqualRect(&rcOld, &rcNew)){
  4013. hr = S_FALSE; // no point to monkey around if the rects are the same
  4014. return(hr);
  4015. }/* end of if statement */
  4016. // Set the objects new position
  4017. hr = pObj->SetRawPos(&rcNew);
  4018. if(FAILED(hr)){
  4019. return(hr);
  4020. }/* end of if statement */
  4021. // Set the objects new position
  4022. hr = pObj->SetRawPos(&rcNew);
  4023. if(FAILED(hr)){
  4024. return(hr);
  4025. }/* end of if statement */
  4026. if(pObj->IsWindowless()){
  4027. hr = pObj->SetObjectRects();
  4028. }
  4029. else {
  4030. hr = pObj->SetObjectRects(&rcNew);
  4031. }/* end of if statement */
  4032. if(FAILED(hr)){
  4033. return(hr);
  4034. }/* end of if statement */
  4035. RECT rcUnion;
  4036. ::UnionRect(&rcUnion, &rcOld, &rcNew);
  4037. if (pObj->IsWindowless())
  4038. hr = InvalidateRect(&rcUnion, FALSE);
  4039. break; // already have set the state and invalidated and bail out
  4040. }/* end of if statement */
  4041. }/* end of for loop */
  4042. return (hr);
  4043. }/* end of function SetObjectExtent */
  4044. /*************************************************************************/
  4045. /* Function: SetObjectPosition */
  4046. /* Description: Sets specific object position. Looks up object by object */
  4047. /* ID. Sets also extents. */
  4048. /*************************************************************************/
  4049. STDMETHODIMP CMFBar::SetObjectPosition(BSTR strObjectID, long xPos,
  4050. long yPos, long lWidth, long lHeight){
  4051. HRESULT hr = E_FAIL;
  4052. if(NULL == strObjectID){
  4053. hr = E_POINTER;
  4054. return(hr);
  4055. }/* end of if sattement */
  4056. RECT rcNew;
  4057. rcNew.left = xPos; rcNew.top = yPos;
  4058. rcNew.right = rcNew.left + lWidth; rcNew.bottom = rcNew.top + lHeight;
  4059. bool bFirstElement = true;
  4060. CNTOBJ::iterator i;
  4061. for(i = m_cntObj.begin(); i!= m_cntObj.end(); i++){
  4062. CHostedObject* pObj = (*i);
  4063. if(!_wcsicmp(pObj->GetID(), strObjectID)){
  4064. RECT rcOld;
  4065. hr = pObj->GetPos(&rcOld);
  4066. if(FAILED(hr)){
  4067. return(hr);
  4068. }/* end of if statement */
  4069. if(::EqualRect(&rcOld, &rcNew)){
  4070. hr = S_FALSE; // no point to monkey around if the rects are the same
  4071. return(hr);
  4072. }/* end of if statement */
  4073. // Set the objects new position
  4074. hr = pObj->SetRawPos(&rcNew);
  4075. if(FAILED(hr)){
  4076. return(hr);
  4077. }/* end of if statement */
  4078. if(pObj->IsWindowless()){
  4079. hr = pObj->SetObjectRects();
  4080. LPARAM lParam = MAKELPARAM(lWidth, lHeight);
  4081. WPARAM wParam = SIZE_RESTORED;
  4082. BOOL bHandled;
  4083. LONG lRes;
  4084. SendMessageToCtl(pObj, WM_SIZE, wParam, lParam, bHandled, lRes);
  4085. }
  4086. else {
  4087. hr = pObj->SetObjectRects(&rcNew);
  4088. }/* end of if statement */
  4089. if(FAILED(hr)){
  4090. return(hr);
  4091. }/* end of if statement */
  4092. RECT rcUnion;
  4093. ::UnionRect(&rcUnion, &rcOld, &rcNew);
  4094. if (pObj->IsWindowless())
  4095. hr = InvalidateRect(&rcUnion, FALSE);
  4096. break; // already have set the state and invalidated and bail out
  4097. }/* end of if statement */
  4098. }/* end of for loop */
  4099. return (hr);
  4100. }/* end of function SetObjectPosition */
  4101. /*************************************************************************/
  4102. /* Function: GetObjectPosition */
  4103. /* Description: SetObjectPosition */
  4104. /*************************************************************************/
  4105. STDMETHODIMP CMFBar::GetObjectPosition(BSTR strObjectID, long* pxPos, long* pyPos, long* plWidth, long* plHeight){
  4106. HRESULT hr = E_FAIL;
  4107. if(NULL == strObjectID){
  4108. hr = E_POINTER;
  4109. return(hr);
  4110. }/* end of if sattement */
  4111. if(NULL == pxPos || NULL == pyPos || NULL == plWidth || NULL == plHeight){
  4112. return(E_POINTER);
  4113. }/* end of if statement */
  4114. *pxPos = *pyPos = *plWidth = *plHeight = 0;
  4115. bool bFirstElement = true;
  4116. CNTOBJ::iterator i;
  4117. for(i = m_cntObj.begin(); i!= m_cntObj.end(); i++){
  4118. if(!_wcsicmp((*i)->GetID(), strObjectID)){
  4119. CHostedObject* pObj = (*i);
  4120. // Set the objects new position
  4121. RECT rc;
  4122. hr = pObj->GetPos(&rc);
  4123. if(SUCCEEDED(hr)){
  4124. *pxPos = rc.left; *pyPos = rc.top; *plWidth = RECTWIDTH(&rc); *plHeight = RECTHEIGHT(&rc);
  4125. }/* end of if statement */
  4126. break; // already have set the state and invalidated and bail out
  4127. }/* end of if statement */
  4128. }/* end of for loop */
  4129. return (hr);
  4130. }/* end function GetObjectPosition */
  4131. /*************************************************************************/
  4132. /* Function: WinHelp */
  4133. /* Description: Called by the script to execute specific help topic. */
  4134. /*************************************************************************/
  4135. STDMETHODIMP CMFBar::WinHelp(BSTR strHelpFile, long lCommand, long dwData){
  4136. HRESULT hr = S_OK;
  4137. try {
  4138. HWND h = NULL;
  4139. hr = GetWindow(&h);
  4140. if(FAILED(hr)){
  4141. throw(hr);
  4142. }/* end of if statement */
  4143. USES_CONVERSION;
  4144. LPTSTR strTemp = OLE2T(strHelpFile);
  4145. if (strTemp != NULL)
  4146. {
  4147. BOOL bResult = ::WinHelp(h, strTemp, lCommand, dwData);
  4148. if(!bResult){
  4149. // failed so lets try to get some more meaningful result
  4150. hr = HRESULT_FROM_WIN32(::GetLastError());
  4151. }/* end of if statement */
  4152. }
  4153. else
  4154. {
  4155. hr = E_POINTER;
  4156. }
  4157. }/* end of try statement */
  4158. catch(HRESULT hrTmp){
  4159. hr = hrTmp;
  4160. }
  4161. catch(...){
  4162. hr = E_UNEXPECTED;
  4163. }/* end of catch statement */
  4164. return (hr);
  4165. }/* end of function WinHelp */
  4166. static HWND (WINAPI *pfnHtmlHelp)(HWND , LPCTSTR , UINT , ULONG_PTR);
  4167. typedef HWND (WINAPI *PFNHTMLHELP)(HWND , LPCTSTR , UINT , ULONG_PTR);
  4168. /*************************************************************************/
  4169. /* Function: CallHtmlHelp */
  4170. /* Description: Dynamically load the HTML help. */
  4171. /*************************************************************************/
  4172. HWND CMFBar::CallHtmlHelp(HWND hwndCaller,LPCTSTR pszFile,UINT uCommand,ULONG_PTR dwData){
  4173. HWND hwnd = NULL; // return value
  4174. if(NULL == m_hinstHelpDll){
  4175. m_hinstHelpDll = ::LoadLibrary(TEXT("HHCTRL.OCX"));
  4176. }/* end of if statement */
  4177. if (m_hinstHelpDll){
  4178. #ifndef _UNICODE
  4179. pfnHtmlHelp = (PFNHTMLHELP)GetProcAddress(m_hinstHelpDll, "HtmlHelpA");
  4180. #else
  4181. pfnHtmlHelp = (PFNHTMLHELP)GetProcAddress(m_hinstHelpDll, "HtmlHelpW");
  4182. #endif
  4183. if (pfnHtmlHelp){
  4184. hwnd = pfnHtmlHelp(hwndCaller, pszFile, uCommand, dwData);
  4185. }/* end of if statement */
  4186. }/* end of if statement */
  4187. return (hwnd);
  4188. }/* end of function CallHtmlHelp */
  4189. /*************************************************************************/
  4190. /* Function: HTMLHelp */
  4191. /* Description: Called by the script to execute specific help topic. */
  4192. /*************************************************************************/
  4193. STDMETHODIMP CMFBar::HTMLHelp(BSTR strHelpFile, long lCommand, VARIANT vData){
  4194. HRESULT hr = S_OK;
  4195. try {
  4196. HWND h = NULL;
  4197. hr = GetWindow(&h);
  4198. if(FAILED(hr)){
  4199. throw(hr);
  4200. }/* end of if statement */
  4201. USES_CONVERSION;
  4202. ULONG_PTR pData = NULL;
  4203. switch(vData.vt){
  4204. case VT_BSTR: { // This might be tricky since we have to convert to ansi if not un Unicode
  4205. #ifndef _UNICODE
  4206. USES_CONVERSION;
  4207. pData = (ULONG_PTR) OLE2T(vData.bstrVal);
  4208. #else
  4209. pData = (ULONG_PTR) vData.bstrVal;
  4210. #endif
  4211. }
  4212. break;
  4213. default: pData = vData.ulVal; // like VT_I4 just cast to the the type
  4214. }/* end of switch statement */
  4215. CComBSTR cstr = TEXT("hcp:");
  4216. if(cstr == strHelpFile){
  4217. // special case when we are creating process for TS
  4218. // per Bradley Serbus we do not build another function for this
  4219. TCHAR lpszCmdLine[MAX_PATH * 3];
  4220. if(MAX_PATH < GetWindowsDirectory(lpszCmdLine, MAX_PATH )){
  4221. // not enough size in max path
  4222. ATLASSERT(TRUE);
  4223. throw(E_UNEXPECTED);
  4224. }/* end of if statement */
  4225. _tcscat(lpszCmdLine, TEXT("\\pchealth\\helpctr\\binaries\\helpctr.exe"));
  4226. _tcscat(lpszCmdLine, TEXT(" -url hcp://help/"));
  4227. if(VT_BSTR != vData.vt){
  4228. throw(E_INVALIDARG);
  4229. }/* end of if statement */
  4230. TCHAR* strTS = OLE2T(vData.bstrVal);
  4231. if(NULL == strTS){
  4232. throw(E_UNEXPECTED);
  4233. }/* end of if statement */
  4234. _tcscat(lpszCmdLine, strTS);
  4235. // take the container out of the top-most mode
  4236. ::SetWindowPos(m_hWnd, HWND_NOTOPMOST, 0, 0, 0, 0,
  4237. SWP_NOREDRAW|SWP_NOMOVE|SWP_NOSIZE);
  4238. #ifndef _UNICODE
  4239. if(WinExec(lpszCmdLine, SW_SHOW) <= 31){
  4240. #else
  4241. long cCharacters = wcslen(lpszCmdLine)+1;
  4242. long cbAnsi = cCharacters*2;
  4243. // Use of the OLE allocator is not required because the resultant
  4244. // ANSI string will never be passed to another COM component. You
  4245. // can use your own allocator.
  4246. LPSTR pszA = (LPSTR) CoTaskMemAlloc(cbAnsi);
  4247. if (NULL == pszA)
  4248. throw(E_OUTOFMEMORY);
  4249. if (0 == WideCharToMultiByte(CP_ACP, 0, lpszCmdLine, cCharacters, pszA, cbAnsi, NULL, NULL)) {
  4250. DWORD dwError = GetLastError();
  4251. CoTaskMemFree(pszA);
  4252. throw HRESULT_FROM_WIN32(dwError);
  4253. }
  4254. if(WinExec(pszA, SW_SHOW) <= 31){
  4255. CoTaskMemFree(pszA);
  4256. #endif
  4257. //if(!::CreateProcess(lpszCmdLine, NULL , NULL, NULL, FALSE, 0, NULL, NULL, NULL, NULL)){
  4258. ATLASSERT(FALSE);
  4259. throw(E_FAIL);
  4260. }/* end of if statement */
  4261. #ifdef _UNICODE
  4262. CoTaskMemFree(pszA);
  4263. #endif
  4264. }
  4265. else {
  4266. // take the container out of the top-most mode
  4267. ::SetWindowPos(m_hWnd, HWND_NOTOPMOST, 0, 0, 0, 0,
  4268. SWP_NOREDRAW|SWP_NOMOVE|SWP_NOSIZE);
  4269. m_bHandleUserFocus = FALSE;
  4270. HWND hWndNew = CallHtmlHelp(h, OLE2T(strHelpFile), lCommand, pData);
  4271. if(!::IsWindow(hWndNew)){
  4272. // failed so lets try to get some more meaningful result
  4273. hr = HRESULT_FROM_WIN32(::GetLastError());
  4274. }/* end of if statement */
  4275. }/* end of if statement */
  4276. }/* end of try statement */
  4277. catch(HRESULT hrTmp){
  4278. hr = hrTmp;
  4279. }
  4280. catch(...){
  4281. hr = E_UNEXPECTED;
  4282. }/* end of catch statement */
  4283. return (hr);
  4284. }/* end of function HTMLHelp */
  4285. /*************************************************************************/
  4286. /* Function: MessageBox */
  4287. /* Description: Displays the message box using specified parameters. */
  4288. /*************************************************************************/
  4289. STDMETHODIMP CMFBar::MessageBox(BSTR strText, BSTR strCaption, long lType){
  4290. HRESULT hr = S_OK;
  4291. try {
  4292. USES_CONVERSION;
  4293. HWND hWnd = NULL;
  4294. HRESULT hr = GetWindow(&hWnd);
  4295. if(FAILED(hr)){
  4296. ATLASSERT(FALSE);
  4297. throw(hr);
  4298. }/* end of if statement */
  4299. LPTSTR strTemp1 = OLE2T(strText);
  4300. LPTSTR strTemp2 = OLE2T(strCaption);
  4301. if (strTemp1 != NULL && strTemp2 != NULL)
  4302. {
  4303. ::MessageBox(hWnd, strTemp1, strTemp2, lType);
  4304. }
  4305. else
  4306. {
  4307. hr = E_POINTER;
  4308. }
  4309. }
  4310. catch(HRESULT hrTmp){
  4311. hr = hrTmp;
  4312. }
  4313. catch(...){
  4314. hr = E_UNEXPECTED;
  4315. }
  4316. return S_OK;
  4317. }/* end of function MessageBox */
  4318. /*************************************************************************/
  4319. /* Function: GetToolbarName */
  4320. /* Description: Gets and allocates the toolbar name. */
  4321. /*************************************************************************/
  4322. HRESULT CMFBar::GetToolbarName(BSTR* strToolbarName){
  4323. HRESULT hr = S_OK;
  4324. if(NULL == strToolbarName){
  4325. hr = E_POINTER;
  4326. return(hr);
  4327. }/* end of if statement */
  4328. const INT ciMaxBuffSize = MAX_PATH; // should be enough for tlbr ID, keep ID small if can
  4329. TCHAR strBuffer[ciMaxBuffSize];
  4330. if(!::LoadString(m_hRes, IDS_ROOT_OBJECT, strBuffer, ciMaxBuffSize)){
  4331. hr = E_FAIL;
  4332. return(E_FAIL);
  4333. }/* end of if statement */
  4334. #ifdef _UNICODE
  4335. *strToolbarName = ::SysAllocString(strBuffer);
  4336. #else
  4337. USES_CONVERSION;
  4338. *strToolbarName = ::SysAllocString(T2OLE(strBuffer));
  4339. #endif
  4340. return(hr);
  4341. }/* end of function GetToolbarName */
  4342. /*************************************************************************/
  4343. /* Function: SetPriority */
  4344. /* Description: Sets the thread priority. */
  4345. /*************************************************************************/
  4346. STDMETHODIMP CMFBar::SetPriority(long lPriority){
  4347. HRESULT hr = S_OK;
  4348. try {
  4349. HANDLE hThread = ::GetCurrentThread();
  4350. if(!::SetThreadPriority(hThread, lPriority)){
  4351. hr = HRESULT_FROM_WIN32(::GetLastError());
  4352. throw (hr);
  4353. }/* end of if statement */
  4354. }
  4355. catch(HRESULT hrTmp){
  4356. hr = hrTmp;
  4357. }
  4358. catch(...){
  4359. hr = E_UNEXPECTED;
  4360. }/* end of catch statement */
  4361. return (hr);
  4362. }/* end of function SetPriority */
  4363. /*************************************************************************/
  4364. /* Function: SetPriorityClass */
  4365. /* Description: Sets the thread priority. */
  4366. /*************************************************************************/
  4367. STDMETHODIMP CMFBar::SetPriorityClass(long lPriority){
  4368. HRESULT hr = S_OK;
  4369. try {
  4370. HANDLE hThread = ::GetCurrentThread();
  4371. if(!::SetPriorityClass(hThread, lPriority)){
  4372. hr = HRESULT_FROM_WIN32(::GetLastError());
  4373. throw (hr);
  4374. }/* end of if statement */
  4375. }
  4376. catch(HRESULT hrTmp){
  4377. hr = hrTmp;
  4378. }
  4379. catch(...){
  4380. hr = E_UNEXPECTED;
  4381. }/* end of catch statement */
  4382. return (hr);
  4383. }/* end of function SetPriorityClass */
  4384. /*************************************************************************/
  4385. /* Function: get_BackgroundImage */
  4386. /* Description: Gets the backround image. */
  4387. /*************************************************************************/
  4388. STDMETHODIMP CMFBar::get_BackgroundImage(BSTR *pstrFilename){
  4389. *pstrFilename = m_bstrBackImageFilename.Copy();
  4390. return S_OK;
  4391. }/* end of function get_BackgroundImage */
  4392. /*************************************************************************/
  4393. /* Function: put_BackgroundImage */
  4394. /* Description: Attempts to load the background image. */
  4395. /*************************************************************************/
  4396. STDMETHODIMP CMFBar::put_BackgroundImage(BSTR strFilename){
  4397. USES_CONVERSION;
  4398. HRESULT hr = S_OK;
  4399. if(NULL != m_pBackBitmap){
  4400. delete m_pBackBitmap;
  4401. }/* end of if statement */
  4402. m_pBackBitmap = new CBitmap;
  4403. //m_pBackBitmap->LoadPalette(true); // load the palette if available, since this
  4404. // is the palette we use for the rest
  4405. // of the contained objects
  4406. m_bstrBackImageFilename = strFilename;
  4407. TCHAR strBuffer[MAX_PATH] = TEXT("\0");
  4408. bool fGrayOut = false;
  4409. hr = m_pBackBitmap->PutImage(strFilename, m_hRes, FALSE, m_blitType, CUSTOM_CONTAINER);
  4410. if(FAILED(hr)){
  4411. return(hr);
  4412. }/* end of if statement */
  4413. // we are updating image that is being used, refresh it
  4414. ATLTRACE2(atlTraceWindowing, 20, TEXT("Redrawing the image\n"));
  4415. InvalidateRgn(); // our helper function
  4416. return(hr);
  4417. }/* end of function put_BackgroundImage */
  4418. /*************************************************************************/
  4419. /* Function: SetReadyState */
  4420. /* Description: Sets ready state and fires event if it needs to be fired */
  4421. /*************************************************************************/
  4422. HRESULT CMFBar::SetReadyState(LONG lReadyState){
  4423. HRESULT hr = S_OK;
  4424. bool bFireEvent = (lReadyState != m_nReadyState);
  4425. #ifdef _DEBUG
  4426. if(m_nFreezeEvents > 0){
  4427. ::Sleep(10);
  4428. ATLTRACE("Container not expecting events at the moment");
  4429. }/* end of is statement */
  4430. #endif
  4431. if(bFireEvent){
  4432. put_ReadyState(lReadyState);
  4433. Fire_ReadyStateChange(lReadyState);
  4434. }
  4435. else {
  4436. // set the variable
  4437. m_nReadyState = lReadyState;
  4438. }/* end of if statement */
  4439. return(hr);
  4440. }/* end of function SetReadyState */
  4441. /*************************************************************************/
  4442. /* Function: OnPostVerbInPlaceActivate */
  4443. /* Description: Creates the in place active object. */
  4444. /*************************************************************************/
  4445. HRESULT CMFBar::OnPostVerbInPlaceActivate(){
  4446. SetReadyState(READYSTATE_COMPLETE);
  4447. return(S_OK);
  4448. }/* end of function OnPostVerbInPlaceActivate */
  4449. /*************************************************************************/
  4450. /* Function: get_AutoLoad */
  4451. /*************************************************************************/
  4452. STDMETHODIMP CMFBar::get_AutoLoad(VARIANT_BOOL *pVal){
  4453. *pVal = m_fAutoLoad;
  4454. return S_OK;
  4455. }/* end of function get_AutoLoad */
  4456. /*************************************************************************/
  4457. /* Function: put_AutoLoad */
  4458. /* Description: Sets the flag to autolaod the engine after we set a */
  4459. /* script file or not. */
  4460. /*************************************************************************/
  4461. STDMETHODIMP CMFBar::put_AutoLoad(VARIANT_BOOL newVal){
  4462. m_fAutoLoad = (VARIANT_FALSE == newVal ? VARIANT_FALSE : VARIANT_TRUE);
  4463. return S_OK;
  4464. }/* end of function put_AutoLoad */
  4465. /*************************************************************/
  4466. /* Name: SetRectRgn
  4467. /* Description: Set up a rectangular window update region
  4468. /*************************************************************/
  4469. STDMETHODIMP CMFBar::SetRectRgn(long x1, long y1, long x2, long y2)
  4470. {
  4471. HRGN hRgn = ::CreateRectRgn( x1, y1, x2, y2 );
  4472. ::SetWindowRgn(m_hWnd, hRgn, TRUE);
  4473. return S_OK;
  4474. }
  4475. /*************************************************************/
  4476. /* Name: SetRoundRectRgn
  4477. /* Description: Set up a round corner window update region
  4478. /*************************************************************/
  4479. STDMETHODIMP CMFBar::SetRoundRectRgn(long x1, long y1, long x2, long y2, long width, long height){
  4480. HRGN hRgn = ::CreateRoundRectRgn(x1, y1, x2, y2, width, height);
  4481. ::SetWindowRgn(m_hWnd, hRgn, TRUE);
  4482. return S_OK;
  4483. }/* end of function SetRoundRectRgn */
  4484. /*************************************************************/
  4485. /* Function: SetTimeout */
  4486. /* Description: Creates a timer and then calls events when */
  4487. /* timer proc gets called. */
  4488. /*************************************************************/
  4489. STDMETHODIMP CMFBar::SetTimeout(long lTimeout, long lId){
  4490. if(lTimeout < 0){
  4491. return(E_INVALIDARG);
  4492. }/* end of if statement */
  4493. if(!::IsWindow(m_hWnd)){
  4494. return(E_FAIL);
  4495. }/* end of if statement */
  4496. if(ID_EV_TIMER == lId){
  4497. return(E_INVALIDARG);
  4498. }/* end of if statement */
  4499. if(lTimeout == 0){
  4500. ::KillTimer(m_hWnd, lId);
  4501. }
  4502. else{
  4503. if(0 != lTimeout){
  4504. if(0 == ::SetTimer(m_hWnd, lId, lTimeout, NULL)){
  4505. return(E_FAIL);
  4506. }/* end of if statement */
  4507. }/* end of if statement */
  4508. }/* end of if statement */
  4509. return S_OK;
  4510. }/* end of function SetTimeout */
  4511. /*************************************************************/
  4512. /* Function: Sleep */
  4513. /*************************************************************/
  4514. STDMETHODIMP CMFBar::Sleep(long lMiliseconds){
  4515. ::Sleep(lMiliseconds);
  4516. return S_OK;
  4517. }/* end of function Sleep */
  4518. /*************************************************************/
  4519. /* Name: OnButtonDown
  4520. /* Description: Handles WM_MOUSEDOWN
  4521. /*************************************************************/
  4522. LRESULT CMFBar::OnButtonDown(UINT, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  4523. {
  4524. if(::IsWindow(m_hWnd)){
  4525. m_ptMouse.x = GET_X_LPARAM(lParam);
  4526. m_ptMouse.y = GET_Y_LPARAM(lParam);
  4527. ::ClientToScreen(m_hWnd, &m_ptMouse);
  4528. SetCapture(TRUE);
  4529. SetFocus(TRUE);
  4530. ATLTRACE(TEXT("Button down, starting to track\n"));
  4531. m_bMouseDown = true;
  4532. // Test for resize hit region
  4533. ::GetWindowRect(m_hWnd, &m_rcWnd);
  4534. m_HitRegion = ResizeHitRegion(m_ptMouse);
  4535. UpdateCursor(m_HitRegion);
  4536. }/* end of if statement */
  4537. return 0;
  4538. }
  4539. /*************************************************************/
  4540. /* Name: OnButtonUp
  4541. /* Description: Handles WM_MOUSEUP
  4542. /*************************************************************/
  4543. LRESULT CMFBar::OnButtonUp(UINT, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  4544. {
  4545. if(::IsWindow(m_hWnd)){
  4546. m_bMouseDown = false;
  4547. SetCapture(FALSE);
  4548. ATLTRACE(TEXT("Done tracking the window\n"));
  4549. m_HitRegion = ResizeHitRegion(m_ptMouse);
  4550. UpdateCursor(m_HitRegion);
  4551. }/* end of if statement */
  4552. return 0;
  4553. }
  4554. /*************************************************************/
  4555. /* Name: OnMouseMove
  4556. /* Description: Handles WM_MOUSEMOVE
  4557. /*************************************************************/
  4558. LRESULT CMFBar::OnMouseMove(UINT, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  4559. {
  4560. if(::IsWindow(m_hWnd)){
  4561. ::GetWindowRect(m_hWnd, &m_rcWnd);
  4562. POINT ptMouse;
  4563. ptMouse.x = GET_X_LPARAM(lParam);
  4564. ptMouse.y = GET_Y_LPARAM(lParam);
  4565. ::ClientToScreen(m_hWnd, &ptMouse);
  4566. // Test for resize hit region
  4567. HitRegion hitRegion = ResizeHitRegion(ptMouse);
  4568. if (!m_bMouseDown && m_HitRegion!=PREMOVE && m_HitRegion!=PRESIZE)
  4569. UpdateCursor(hitRegion);
  4570. // No mouse movement, return
  4571. long xAdjustment = m_ptMouse.x - ptMouse.x;
  4572. long yAdjustment = m_ptMouse.y - ptMouse.y;
  4573. if (xAdjustment == 0 && yAdjustment == 0)
  4574. return 0;
  4575. m_ptMouse = ptMouse;
  4576. // ATLTRACE(TEXT("Mouse pos: %d %d\n"), m_ptMouse.x, m_ptMouse.y);
  4577. if (m_HitRegion!=NOHIT && m_bMouseDown) {
  4578. long resizeX = m_rcWnd.left;
  4579. long resizeY = m_rcWnd.top;
  4580. long resizeW = RECTWIDTH(&m_rcWnd);
  4581. long resizeH = RECTHEIGHT(&m_rcWnd);
  4582. HWND desktopWnd = ::GetDesktopWindow();
  4583. RECT desktopRC;
  4584. ::GetWindowRect(desktopWnd, &desktopRC);
  4585. if (m_HitRegion & LEFT) {
  4586. ptMouse.x -= SYS_MOVE_SIZE;
  4587. resizeW = m_rcWnd.right-ptMouse.x;
  4588. if (resizeW >RECTWIDTH(&desktopRC)) {
  4589. resizeW = RECTWIDTH(&desktopRC);
  4590. }
  4591. else if (resizeW < m_lMinWidth) {
  4592. resizeW = m_lMinWidth;
  4593. }
  4594. resizeX = m_rcWnd.right-resizeW;
  4595. }
  4596. if (m_HitRegion & RIGHT) {
  4597. ptMouse.x += SYS_MOVE_SIZE;
  4598. resizeW = ptMouse.x-m_rcWnd.left;
  4599. if (resizeW >RECTWIDTH(&desktopRC)) {
  4600. resizeW = RECTWIDTH(&desktopRC);
  4601. }
  4602. else if (resizeW < m_lMinWidth) {
  4603. resizeW = m_lMinWidth;
  4604. }
  4605. }
  4606. if (m_HitRegion & TOP) {
  4607. ptMouse.y -= SYS_MOVE_SIZE;
  4608. resizeH = m_rcWnd.bottom-ptMouse.y;
  4609. if (resizeH >RECTHEIGHT(&desktopRC)) {
  4610. resizeH = RECTHEIGHT(&desktopRC);
  4611. }
  4612. else if (resizeH < m_lMinHeight) {
  4613. resizeH = m_lMinHeight;
  4614. }
  4615. resizeY = m_rcWnd.bottom - resizeH;
  4616. }
  4617. if (m_HitRegion & BOTTOM) {
  4618. ptMouse.y += SYS_MOVE_SIZE;
  4619. resizeH = ptMouse.y-m_rcWnd.top;
  4620. if (resizeH >RECTHEIGHT(&desktopRC)) {
  4621. resizeH = RECTHEIGHT(&desktopRC);
  4622. }
  4623. else if (resizeH < m_lMinHeight) {
  4624. resizeH = m_lMinHeight;
  4625. }
  4626. }
  4627. if (resizeW >= m_lMinWidth || resizeH >= m_lMinHeight) {
  4628. if(NULL != m_pBackBitmap){
  4629. m_pBackBitmap->DeleteMemDC();
  4630. }/* end of if statement */
  4631. ::MoveWindow(m_hWnd, resizeX, resizeY, resizeW, resizeH, TRUE);
  4632. ATLTRACE2(atlTraceWindowing, 30, TEXT("Resize window to: %d %d %d %d\n"), resizeX, resizeY, resizeX+resizeW, resizeY+resizeH);
  4633. }
  4634. }/* end of if statement */
  4635. else if(m_bMouseDown){
  4636. long x = m_rcWnd.left;
  4637. long y = m_rcWnd.top;
  4638. long width = RECTWIDTH(&m_rcWnd);
  4639. long height = RECTHEIGHT(&m_rcWnd);
  4640. ::MoveWindow(m_hWnd, x - xAdjustment, y - yAdjustment, width, height, TRUE);
  4641. ATLTRACE2(atlTraceWindowing, 32, TEXT("Moving the window\n"));
  4642. m_ptMouse = ptMouse;
  4643. }/* end of if statement */
  4644. }/* end of if statement */
  4645. return 0;
  4646. }
  4647. /*************************************************************/
  4648. /* Name: ResizeHitRegion */
  4649. /* Description: Test if mouse is in resize hit region */
  4650. /*************************************************************/
  4651. HitRegion CMFBar::ResizeHitRegion(POINT p){
  4652. // TODO: DO NOT HARDCODE THE REGION SIZES
  4653. int hitRegion = NOHIT;
  4654. if (abs(p.x-m_rcWnd.left)<=10) {
  4655. hitRegion |= LEFT;
  4656. }
  4657. else if (abs(p.x-m_rcWnd.right)<=10) {
  4658. hitRegion |= RIGHT;
  4659. }/* end of if statement */
  4660. if (abs(p.y-m_rcWnd.top)<=10) {
  4661. hitRegion |= TOP;
  4662. }
  4663. else if (abs(p.y-m_rcWnd.bottom)<=10) {
  4664. hitRegion |= BOTTOM;
  4665. }/* end of if statement */
  4666. return (HitRegion)hitRegion;
  4667. }/* end of function ResizeHitRegion */
  4668. /*************************************************************/
  4669. /* Name: UpdateCursor */
  4670. /* Description: Change cursor shape to move arrows */
  4671. /*************************************************************/
  4672. HRESULT CMFBar::UpdateCursor(HitRegion hitRegion){
  4673. if (m_hCursor)
  4674. ::DestroyCursor(m_hCursor);
  4675. int iHitRegion = (int) hitRegion;
  4676. switch (iHitRegion) {
  4677. case PREMOVE:
  4678. case PRESIZE:
  4679. m_hCursor = ::LoadCursor(0, IDC_SIZEALL);
  4680. break;
  4681. case LEFT|NOHIT:
  4682. case RIGHT|NOHIT:
  4683. m_hCursor = ::LoadCursor(0, IDC_SIZEWE);
  4684. break;
  4685. case TOP|NOHIT:
  4686. case BOTTOM|NOHIT:
  4687. m_hCursor = ::LoadCursor(0, IDC_SIZENS);
  4688. break;
  4689. case LEFT|TOP|NOHIT:
  4690. case RIGHT|BOTTOM|NOHIT:
  4691. m_hCursor = ::LoadCursor(0, IDC_SIZENWSE);
  4692. break;
  4693. case RIGHT|TOP|NOHIT:
  4694. case LEFT|BOTTOM|NOHIT:
  4695. m_hCursor = ::LoadCursor(0, IDC_SIZENESW);
  4696. break;
  4697. default:
  4698. m_hCursor = ::LoadCursor(0, IDC_ARROW);
  4699. break;
  4700. }/* end of switch statement */
  4701. ::SetCursor(m_hCursor);
  4702. return S_OK;
  4703. }/* end of function UpdateCursor */
  4704. /*************************************************************************/
  4705. /* Function: SetObjectFocus */
  4706. /* Description: Sets or resets focus to specific object. */
  4707. /*************************************************************************/
  4708. STDMETHODIMP CMFBar::SetObjectFocus(BSTR strObjectID, VARIANT_BOOL fEnable){
  4709. HRESULT hr = S_OK;
  4710. try {
  4711. CHostedObject* pObj;
  4712. hr = FindObject(strObjectID, &pObj);
  4713. if(FAILED(hr)){
  4714. throw(hr);
  4715. }/* end of if statetement */
  4716. LONG lRes = 0;
  4717. hr = SetObjectFocus(pObj, VARIANT_FALSE == fEnable ? FALSE : TRUE, lRes);
  4718. if(FAILED(hr)){
  4719. throw(hr);
  4720. }/* end of if statement */
  4721. if(-1 == lRes){
  4722. throw(E_FAIL); // the control did not take the focus since it is disabled
  4723. }/* end of if statement */
  4724. }/* end of try statement */
  4725. catch(HRESULT hrTmp){
  4726. hr = hrTmp;
  4727. }
  4728. catch(...){
  4729. hr = E_UNEXPECTED;
  4730. }/* end of catch statement */
  4731. return(hr);
  4732. }/* end of function SetObjectFocus */
  4733. /*************************************************************************/
  4734. /* Function: HasObjectFocus */
  4735. /*************************************************************************/
  4736. STDMETHODIMP CMFBar::HasObjectFocus(BSTR strObjectID, VARIANT_BOOL* pfEnable){
  4737. HRESULT hr = S_OK;
  4738. try {
  4739. CHostedObject* pObj;
  4740. hr = FindObject(strObjectID, &pObj);
  4741. if(FAILED(hr)){
  4742. throw(hr);
  4743. }/* end of if statetement */
  4744. *pfEnable = pObj->HasFocus() ? VARIANT_TRUE : VARIANT_FALSE;
  4745. }/* end of try statement */
  4746. catch(HRESULT hrTmp){
  4747. hr = hrTmp;
  4748. }
  4749. catch(...){
  4750. hr = E_UNEXPECTED;
  4751. }/* end of catch statement */
  4752. return(hr);
  4753. }/* end of function HasObjectFocus */
  4754. /*************************************************************************/
  4755. /* Function: SetObjectFocus */
  4756. /* Description: Sets or resets focus to specific object. */
  4757. /*************************************************************************/
  4758. HRESULT CMFBar::SetObjectFocus(CHostedObject* pObj, BOOL fSet, LONG& lRes){
  4759. HRESULT hr = S_OK;
  4760. CContainerObject* pCnt;
  4761. hr = pObj->GetContainerObject(&pCnt);
  4762. if(FAILED(hr)){
  4763. return(hr);
  4764. }/* end of if statement */
  4765. LONG lParam = 0;
  4766. BOOL bHandled = FALSE;
  4767. if(fSet){
  4768. ResetFocusFlags(); // reset old focus on other control
  4769. pCnt->SetFocus(TRUE);
  4770. SendMessageToCtl(pObj, WM_SETFOCUS, (WPARAM) m_hWnd, lParam, bHandled, lRes, false);
  4771. ATLTRACE2(atlTraceUser, 31, TEXT("Sending WM_SETFOCUS to %ls \n"), pObj->GetID());
  4772. }
  4773. else {
  4774. pCnt->SetFocus(FALSE); // disable focus and caputure if we are disabeling the object
  4775. SendMessageToCtl(pObj, WM_KILLFOCUS, (WPARAM) m_hWnd, lParam, bHandled, lRes, false);
  4776. ATLTRACE2(atlTraceUser, 31, TEXT("Sending WM_KILLFOCUS to %ls \n"), pObj->GetID());
  4777. }/* end of if statement */
  4778. return(hr);
  4779. }/* end of function SetObjectFocus */
  4780. /*************************************************************************/
  4781. /* Function: FindObject */
  4782. /* Description: Itterates the objects till it finds the one with matching*/
  4783. /* ID. */
  4784. /*************************************************************************/
  4785. HRESULT CMFBar::FindObject(BSTR strObjectID, CHostedObject** ppObj){
  4786. HRESULT hr = E_FAIL; // did not find the object
  4787. *ppObj = NULL;
  4788. for(CNTOBJ::iterator i = m_cntObj.begin(); i!= m_cntObj.end(); i++){
  4789. CHostedObject* pObj = (*i);
  4790. if(NULL == pObj){
  4791. continue;
  4792. }/* end of if statement */
  4793. if(!_wcsicmp(pObj->GetID(), strObjectID)){
  4794. *ppObj = pObj; // set the pointer and bail out
  4795. hr = S_OK;
  4796. break; // got the unknown get out
  4797. }/* end of if statement */
  4798. }/* end of for loop */
  4799. return(hr);
  4800. }/* end of function FindObject */
  4801. /*************************************************************/
  4802. /* Name: HasObjectCapture */
  4803. /* Description: Gives us status of capture on specific object*/
  4804. /*************************************************************/
  4805. STDMETHODIMP CMFBar::HasObjectCapture(BSTR strObjectID, VARIANT_BOOL *pfEnable){
  4806. HRESULT hr = S_OK;
  4807. try {
  4808. CHostedObject* pObj;
  4809. hr = FindObject(strObjectID, &pObj);
  4810. if(FAILED(hr)){
  4811. throw(hr);
  4812. }/* end of if statetement */
  4813. *pfEnable = pObj->HasCapture() ? VARIANT_TRUE : VARIANT_FALSE;
  4814. }/* end of try statement */
  4815. catch(HRESULT hrTmp){
  4816. hr = hrTmp;
  4817. }
  4818. catch(...){
  4819. hr = E_UNEXPECTED;
  4820. }/* end of catch statement */
  4821. return(hr);
  4822. }/* end of function HasObjectCapture */
  4823. /*************************************************************/
  4824. /* Name: PopupSystemMenu
  4825. /* Description:
  4826. /*************************************************************/
  4827. STDMETHODIMP CMFBar::PopupSystemMenu(long x, long y)
  4828. {
  4829. if (m_hMenu == NULL)
  4830. return S_FALSE;
  4831. RECT rc;
  4832. ::GetWindowRect(m_hWnd, &rc);
  4833. m_bSysMenuOn = TRUE;
  4834. m_bHandleEnter = TRUE;
  4835. if (x < 0)
  4836. x = rc.left;
  4837. if (y < 0)
  4838. y = rc.top+SYS_TITLEBAR_WIDTH;
  4839. ::TrackPopupMenu(::GetSubMenu(m_hMenu, 0), TPM_LEFTALIGN, x, y, 0, m_hWnd, 0);
  4840. m_bSysMenuOn = FALSE;
  4841. return S_OK;
  4842. }
  4843. /*************************************************************/
  4844. /* Name: GetRegistryDword
  4845. /* Description:
  4846. /*************************************************************/
  4847. BOOL GetRegistryDword(const TCHAR *pValueName, const TCHAR *pSubKey, DWORD* dwRet, DWORD dwDefault)
  4848. {
  4849. HKEY hKey;
  4850. LONG lRet;
  4851. *dwRet = dwDefault;
  4852. lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, pSubKey, 0, KEY_QUERY_VALUE, &hKey);
  4853. if (lRet == ERROR_SUCCESS) {
  4854. DWORD dwType, dwLen;
  4855. dwLen = sizeof(DWORD);
  4856. lRet = RegQueryValueEx(hKey, pValueName, NULL, &dwType, (LPBYTE)dwRet, &dwLen);
  4857. if (ERROR_SUCCESS != lRet)
  4858. *dwRet = dwDefault;
  4859. RegCloseKey(hKey);
  4860. }
  4861. return (lRet == ERROR_SUCCESS);
  4862. }
  4863. /*************************************************************/
  4864. /* Name: SetRegistryDword
  4865. /* Description:
  4866. /*************************************************************/
  4867. BOOL SetRegistryDword(const TCHAR *pValueName, const TCHAR *pSubKey, DWORD dwRet)
  4868. {
  4869. HKEY hKey;
  4870. LONG lRet;
  4871. lRet = RegCreateKey(HKEY_LOCAL_MACHINE, pSubKey, &hKey);
  4872. if (lRet == ERROR_SUCCESS) {
  4873. lRet = RegSetValueEx(hKey, pValueName, NULL, REG_DWORD, (LPBYTE)&dwRet, sizeof(dwRet));
  4874. RegCloseKey(hKey);
  4875. }
  4876. return (lRet == ERROR_SUCCESS);
  4877. }
  4878. const TCHAR g_szLeft[] = TEXT("Left");
  4879. const TCHAR g_szTop[] = TEXT("Top");
  4880. const TCHAR g_szRight[] = TEXT("Right");
  4881. const TCHAR g_szBottom[] = TEXT("Bottom");
  4882. const TCHAR g_szFullScreen[] = TEXT("FullScreen");
  4883. const TCHAR g_szUserData[] = TEXT("UserData");
  4884. const TCHAR g_szKey[] = TEXT("Software\\Microsoft\\Multimedia\\MSMFCnt\\");
  4885. /*************************************************************/
  4886. /* Name: SaveSelfHostState
  4887. /* Description:
  4888. /*************************************************************/
  4889. STDMETHODIMP CMFBar::SaveSelfHostState(BSTR strAppName)
  4890. {
  4891. USES_CONVERSION;
  4892. TCHAR *szAppName = OLE2T(strAppName);
  4893. TCHAR szSubKey[MAX_PATH];
  4894. _stprintf(szSubKey, TEXT("%s%s"), g_szKey, szAppName);
  4895. if (m_fSelfHosted && ::IsWindow(m_hWnd)) {
  4896. WINDOWPLACEMENT wndPlacement;
  4897. wndPlacement.length = sizeof(WINDOWPLACEMENT);
  4898. ::GetWindowPlacement(m_hWnd, &wndPlacement);
  4899. if (wndPlacement.showCmd == SW_SHOWMAXIMIZED) {
  4900. SetRegistryDword(g_szFullScreen, szSubKey, 1);
  4901. }
  4902. else {
  4903. SetRegistryDword(g_szFullScreen, szSubKey, 0);
  4904. }
  4905. SetRegistryDword(g_szLeft, szSubKey, wndPlacement.rcNormalPosition.left);
  4906. SetRegistryDword(g_szTop, szSubKey, wndPlacement.rcNormalPosition.top);
  4907. SetRegistryDword(g_szRight, szSubKey, wndPlacement.rcNormalPosition.right);
  4908. SetRegistryDword(g_szBottom, szSubKey, wndPlacement.rcNormalPosition.bottom);
  4909. return S_OK;
  4910. }
  4911. return E_FAIL;
  4912. }
  4913. /*************************************************************/
  4914. /* Name: RestoreSelfHostState
  4915. /* Description:
  4916. /*************************************************************/
  4917. STDMETHODIMP CMFBar::RestoreSelfHostState(BSTR strAppName)
  4918. {
  4919. USES_CONVERSION;
  4920. TCHAR *szAppName = OLE2T(strAppName);
  4921. TCHAR szSubKey[MAX_PATH];
  4922. _stprintf(szSubKey, TEXT("%s%s"), g_szKey, szAppName);
  4923. if (m_fSelfHosted && ::IsWindow(m_hWnd)) {
  4924. BOOL bFullScreen;
  4925. GetRegistryDword(g_szFullScreen, szSubKey, (DWORD*)&bFullScreen, 0);
  4926. UINT uFlags = SWP_NOZORDER;
  4927. if (bFullScreen)
  4928. uFlags |= SWP_HIDEWINDOW;
  4929. DWORD left, top, right, bottom;
  4930. if (
  4931. GetRegistryDword(g_szLeft, szSubKey, &left, 0) &&
  4932. GetRegistryDword(g_szTop, szSubKey, &top, 0) &&
  4933. GetRegistryDword(g_szRight, szSubKey, &right, 0) &&
  4934. GetRegistryDword(g_szBottom, szSubKey, &bottom, 0) ) {
  4935. if (0 == ::SetWindowPos(m_hWnd, 0, left, top, right-left, bottom-top, uFlags))
  4936. return E_FAIL;
  4937. }
  4938. else {
  4939. if (!bFullScreen)
  4940. return E_FAIL;
  4941. }
  4942. if (bFullScreen) {
  4943. ShowSelfSite(SW_MAXIMIZE);
  4944. }
  4945. return S_OK;
  4946. }
  4947. return E_FAIL;
  4948. }
  4949. /*************************************************************/
  4950. /* Name:
  4951. /* Description:
  4952. /*************************************************************/
  4953. STDMETHODIMP CMFBar::SaveSelfHostUserData(BSTR strAppName, long lData)
  4954. {
  4955. USES_CONVERSION;
  4956. TCHAR *szAppName = OLE2T(strAppName);
  4957. TCHAR szSubKey[MAX_PATH];
  4958. _stprintf(szSubKey, TEXT("%s%s"), g_szKey, szAppName);
  4959. SetRegistryDword(g_szUserData, szSubKey, lData);
  4960. return S_OK;
  4961. }
  4962. /*************************************************************/
  4963. /* Name:
  4964. /* Description:
  4965. /*************************************************************/
  4966. STDMETHODIMP CMFBar::GetSelfHostUserData(BSTR strAppName, long *lData)
  4967. {
  4968. USES_CONVERSION;
  4969. TCHAR *szAppName = OLE2T(strAppName);
  4970. TCHAR szSubKey[MAX_PATH];
  4971. _stprintf(szSubKey, TEXT("%s%s"), g_szKey, szAppName);
  4972. DWORD dwRet;
  4973. if (GetRegistryDword(g_szUserData, szSubKey, &dwRet, 0)) {
  4974. *lData = dwRet;
  4975. return S_OK;
  4976. }
  4977. return E_FAIL;
  4978. }
  4979. /*************************************************************/
  4980. /* Name: get_DoubleClickTime
  4981. /* Description:
  4982. /*************************************************************/
  4983. STDMETHODIMP CMFBar::get_DoubleClickTime(long *pVal)
  4984. {
  4985. if (pVal == NULL)
  4986. return E_INVALIDARG;
  4987. *pVal = ::GetDoubleClickTime();
  4988. return S_OK;
  4989. }
  4990. /*************************************************************************/
  4991. /* End of file: MFBar.cpp */
  4992. /*************************************************************************/