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.

1440 lines
45 KiB

  1. /*---------------------------------------------------------------------------
  2. | INPLACE.C
  3. | This file has the InPlace activation related interfaces and functions.
  4. | This file has the function DoInPlaceEdit which initiaites the server side
  5. | operations for InPlace activation.
  6. |
  7. | Created By: Vij Rajarajan (VijR)
  8. +---------------------------------------------------------------------------*/
  9. #define SERVERONLY
  10. #include <windows.h>
  11. #include <windowsx.h>
  12. #include "mpole.h"
  13. #include <mmsystem.h>
  14. #include "mplayer.h"
  15. #include "toolbar.h"
  16. #include "ole2ui.h"
  17. #define DEF_HATCH_SZ 4 //Width of the hatch marks
  18. #define EW_HATCH_HANDLE 10 //GetWindowWord offset to check
  19. //if resize handle needed in hatch window
  20. //#define DUMMY_TOOLBAR_WIDTH 58 //Width of dummy toolbar transferred during play.
  21. #define DUMMY_TOOLBAR_WIDTH 0 //Width of dummy toolbar transferred during play.
  22. HWND ghwndIPHatch = NULL; //Hatch window surrounding object.
  23. HWND ghwndIPToolWindow; //The toolwindow appearing on top
  24. HWND ghwndIPScrollWindow; //Tool window appearing at bottom with tthe scrollbar
  25. //if the container does not give us space on top.
  26. HMENU ghInPlaceMenu;
  27. POINT gHatchOffset;
  28. WNDPROC gfnHatchWndProc = NULL;
  29. BOOL gfOle2Open = FALSE;
  30. BOOL gfOle2IPEditing = FALSE;
  31. BOOL gfOle2IPPlaying = FALSE;
  32. BOOL gfInPlaceResize = FALSE; //TRUE: We have resized when InPlace
  33. BOOL gfTopAndBottomTool = TRUE; // We have toolbars both on top and bottom
  34. RECT gInPlacePosRect; //Our position in the container.
  35. HWND ghwndCntr; //Container
  36. HWND ghwndFrame = NULL; //Frame of the container.
  37. int toolbarwidth;
  38. BOOL gfPosRectChange = FALSE;
  39. RECT gPrevPosRect;
  40. BOOL gfInPPViewer; /* Hack to stop PowerPoint Viewer crashing */
  41. extern TCHAR szToolBarClass[];
  42. extern HMENU ghDeviceMenu; /* handle to the Device menu */
  43. extern UINT gwPlaybarHeight; //tell playbar how tall to make
  44. //itself so it covers the title
  45. void AllocInPlaceDataBlock (LPDOC lpdoc);
  46. void FreeInPlaceDataBlock (LPDOC lpdoc);
  47. void DeactivateTools(LPDOC lpdoc);
  48. HRESULT ActivateTools(LPDOC lpdoc, BOOL fPlayOnly);
  49. void InPlaceCreateControls(BOOL fPlayOnly);
  50. LONG_PTR FAR PASCAL SubClassedHatchWndProc(HWND hwnd, UINT wMsg, WPARAM wParam, LPARAM lParam);
  51. /**************************************************************************
  52. * TransferTools:
  53. * This function changes parents and positions the toolbar buttons
  54. * from the main Mplayer window to the toolbar window/windows we will
  55. * display in the client.
  56. ***************************************************************************/
  57. void TransferTools(HWND hwndToolWindow)
  58. {
  59. SetParent(ghwndToolbar, hwndToolWindow);
  60. MoveWindow(ghwndToolbar, 5,0,7*BUTTONWIDTH+15,TOOL_WIDTH,TRUE);
  61. SetParent(ghwndMark, hwndToolWindow);
  62. MoveWindow(ghwndMark, 7*BUTTONWIDTH+16,0,2*BUTTONWIDTH+15,TOOL_WIDTH,TRUE);
  63. SetParent(ghwndFSArrows, hwndToolWindow);
  64. MoveWindow(ghwndFSArrows, 9*BUTTONWIDTH+16+10+3,0,toolbarwidth-9*BUTTONWIDTH-25,TOOL_WIDTH,TRUE);
  65. if(!ghwndMCI) {
  66. toolbarModifyState(ghwndToolbar, BTN_EJECT, TBINDEX_MAIN, BTNST_GRAYED);
  67. toolbarModifyState(ghwndToolbar, BTN_STOP, TBINDEX_MAIN, BTNST_GRAYED);
  68. toolbarModifyState(ghwndToolbar, BTN_PLAY, TBINDEX_MAIN, BTNST_GRAYED);
  69. toolbarModifyState(ghwndMark, BTN_MARKIN, TBINDEX_MARK, BTNST_GRAYED);
  70. toolbarModifyState(ghwndMark, BTN_MARKOUT, TBINDEX_MARK, BTNST_GRAYED);
  71. toolbarModifyState(ghwndFSArrows, ARROW_PREV, TBINDEX_ARROWS, BTNST_GRAYED);
  72. toolbarModifyState(ghwndFSArrows, ARROW_NEXT, TBINDEX_ARROWS, BTNST_GRAYED);
  73. }
  74. if(hwndToolWindow == ghwndApp)
  75. {
  76. SetParent(ghwndTrackbar,ghwndApp);
  77. SetParent(ghwndMap,ghwndApp);
  78. }
  79. }
  80. /**************************************************************************
  81. * ActivateTools:
  82. * This function negotiates for toolbar space with the client. If possible
  83. * one broad toolbar is placed at the top of the client, if not the
  84. * toolbar is split and one is placed on top and other at bottom. If even
  85. * that is not possible then the function fails. The top toolbar window is
  86. * ghwndIPToolWindow and the bottom one is ghwndIPScrollWindow (because it
  87. * has the scrolling trackbar.
  88. *
  89. * fPlayOnly is TRUE if we are just going to play. In that case a dummy, empty
  90. * tool bar is transferred. No, we don't want anything. But we have to
  91. * negotiate space, even empty space, otherwise Word doesn't think we're
  92. * in-place active.
  93. ***************************************************************************/
  94. HRESULT ActivateTools(LPDOC lpdoc, BOOL fPlayOnly)
  95. {
  96. RECT rect, size;
  97. SCODE sc;
  98. size.left = 0;
  99. size.top = 0;
  100. size.bottom = 0;
  101. size.right = 0;
  102. IOleInPlaceFrame_GetBorder(lpdoc->lpIpData->lpFrame, &rect);
  103. if (fPlayOnly)
  104. size.top = DUMMY_TOOLBAR_WIDTH; /* This is now 0 - no toolbar space needed */
  105. else
  106. size.top = 3*TOOL_WIDTH+1;
  107. size.bottom = 0;
  108. sc = GetScode(IOleInPlaceFrame_RequestBorderSpace(lpdoc->lpIpData->lpFrame,
  109. &size));
  110. if (sc == S_OK)
  111. {
  112. size.bottom = size.left = size.right = 0;
  113. if (fPlayOnly)
  114. size.top = DUMMY_TOOLBAR_WIDTH;
  115. else
  116. size.top = 3*TOOL_WIDTH+1;
  117. sc = GetScode(IOleInPlaceFrame_SetBorderSpace(lpdoc->lpIpData->lpFrame,
  118. &size));
  119. if (sc != S_OK)
  120. goto ToolBottom;
  121. IOleInPlaceFrame_GetBorder(lpdoc->lpIpData->lpFrame, &rect);
  122. IOleInPlaceFrame_GetWindow (lpdoc->lpIpData->lpFrame, &ghwndFrame);
  123. if (GetParent(ghwndIPToolWindow) != ghwndFrame)
  124. SetParent(ghwndIPToolWindow, ghwndFrame);
  125. if (!fPlayOnly)
  126. MoveWindow(ghwndIPToolWindow, rect.left, rect.top,
  127. toolbarwidth, 3*TOOL_WIDTH+1, TRUE);
  128. else
  129. return NOERROR; /* That's all folks, if we're just playing. */
  130. if(ghwndIPToolWindow != GetParent(ghwndTrackbar))
  131. {
  132. SetParent(ghwndTrackbar,ghwndIPToolWindow);
  133. SetWindowPos(ghwndTrackbar, NULL,3,TOOL_WIDTH+2,
  134. 11*BUTTONWIDTH+15,FSTRACK_HEIGHT,SWP_NOZORDER | SWP_NOACTIVATE);
  135. SetParent(ghwndMap,ghwndIPToolWindow);
  136. SetWindowPos(ghwndMap, NULL,3,TOOL_WIDTH+FSTRACK_HEIGHT+2+2,
  137. 11*BUTTONWIDTH+50,MAP_HEIGHT,SWP_NOZORDER | SWP_NOACTIVATE);
  138. }
  139. ShowWindow(ghwndIPToolWindow, SW_SHOW);
  140. ShowWindow(ghwndMark, SW_SHOW);
  141. ShowWindow(ghwndFSArrows, SW_SHOW);
  142. gfTopAndBottomTool = FALSE;
  143. return NOERROR;
  144. }
  145. else
  146. {
  147. ToolBottom:
  148. if (!fPlayOnly)
  149. {
  150. size.top = TOOL_WIDTH+1;
  151. size.bottom = 2*TOOL_WIDTH+1;
  152. }
  153. else
  154. {
  155. ShowWindow(ghwndFSArrows, SW_HIDE);
  156. ShowWindow(ghwndStatic, SW_HIDE);
  157. ShowWindow(ghwndMark, SW_HIDE);
  158. return NOERROR;
  159. }
  160. sc = GetScode(IOleInPlaceFrame_RequestBorderSpace(lpdoc->lpIpData->lpFrame,
  161. &size));
  162. size.left = size.right = 0;
  163. size.top = TOOL_WIDTH+1;
  164. size.bottom = 2*TOOL_WIDTH+1;
  165. if (sc != S_OK)
  166. goto error;
  167. sc = GetScode(IOleInPlaceFrame_SetBorderSpace(lpdoc->lpIpData->lpFrame,
  168. &size));
  169. if (sc != S_OK)
  170. goto error;
  171. IOleInPlaceFrame_GetBorder(lpdoc->lpIpData->lpFrame, &rect);
  172. if (GetParent(ghwndIPToolWindow) != ghwndFrame)
  173. {
  174. SetParent(ghwndIPToolWindow, ghwndFrame);
  175. SetParent(ghwndIPScrollWindow, ghwndFrame);
  176. }
  177. if(ghwndIPScrollWindow != GetParent(ghwndTrackbar))
  178. {
  179. SetParent(ghwndTrackbar,ghwndIPScrollWindow);
  180. SetWindowPos(ghwndTrackbar, NULL,3,4,
  181. 11*BUTTONWIDTH+15,FSTRACK_HEIGHT,SWP_NOZORDER | SWP_NOACTIVATE);
  182. SetParent(ghwndMap,ghwndIPScrollWindow);
  183. SetWindowPos(ghwndMap, NULL,3,FSTRACK_HEIGHT+4+2,
  184. 11*BUTTONWIDTH+50,MAP_HEIGHT,SWP_NOZORDER | SWP_NOACTIVATE);
  185. }
  186. MoveWindow(ghwndIPToolWindow, rect.left, rect.top,
  187. toolbarwidth, TOOL_WIDTH+1, TRUE);
  188. ShowWindow(ghwndIPToolWindow, SW_SHOW);
  189. MoveWindow(ghwndIPScrollWindow, rect.left,rect.bottom-2*TOOL_WIDTH,//-1,
  190. toolbarwidth,2*TOOL_WIDTH+1,TRUE);
  191. ShowWindow(ghwndIPScrollWindow, SW_SHOW);
  192. gfTopAndBottomTool = TRUE;
  193. return NOERROR;
  194. }
  195. error:
  196. RETURN_RESULT(sc);
  197. }
  198. /**************************************************************************
  199. * DeactivateTools:
  200. * Hides the toolbars.
  201. ***************************************************************************/
  202. void DeactivateTools(LPDOC lpdoc)
  203. {
  204. ShowWindow(ghwndIPToolWindow, SW_HIDE);
  205. SetParent(ghwndIPToolWindow, NULL);
  206. if (gfTopAndBottomTool)
  207. {
  208. ShowWindow(ghwndIPScrollWindow, SW_HIDE);
  209. SetParent(ghwndIPScrollWindow, NULL);
  210. }
  211. }
  212. /**************************************************************************
  213. ************ IOleInPlaceObject INTERFACE IMPLEMENTATION.
  214. ***************************************************************************/
  215. //Delegate to the common IUnknown implementation.
  216. STDMETHODIMP IPObjQueryInterface (
  217. LPOLEINPLACEOBJECT lpIPObj, // inplace object ptr
  218. REFIID riidReq, // IID required
  219. LPVOID FAR * lplpUnk // pre for returning the interface
  220. )
  221. {
  222. return UnkQueryInterface((LPUNKNOWN)lpIPObj, riidReq, lplpUnk);
  223. }
  224. STDMETHODIMP_(ULONG) IPObjAddRef(
  225. LPOLEINPLACEOBJECT lpIPObj // inplace object ptr
  226. )
  227. {
  228. return UnkAddRef((LPUNKNOWN) lpIPObj);
  229. }
  230. STDMETHODIMP_(ULONG) IPObjRelease(
  231. LPOLEINPLACEOBJECT lpIPObj // inplace object ptr
  232. )
  233. {
  234. return UnkRelease((LPUNKNOWN) lpIPObj);
  235. }
  236. STDMETHODIMP IPObjGetWindow(
  237. LPOLEINPLACEOBJECT lpIPObj, // inplace object ptr
  238. HWND FAR* lphwnd // window handle of the object
  239. )
  240. {
  241. DPF("IPObjGetWindow\n");
  242. *lphwnd = docMain.hwnd;
  243. return NOERROR;
  244. }
  245. STDMETHODIMP IPObjContextSensitiveHelp(
  246. LPOLEINPLACEOBJECT lpIPObj, // inplace object ptr
  247. BOOL fEnable
  248. )
  249. {
  250. //Not very useful at this time.
  251. LPDOC lpdoc;
  252. lpdoc = ((struct COleInPlaceObjectImpl FAR*)lpIPObj)->lpdoc;
  253. lpdoc->lpIpData->fInContextHelpMode = fEnable;
  254. return NOERROR;
  255. }
  256. STDMETHODIMP IPObjInPlaceDeactivate(
  257. LPOLEINPLACEOBJECT lpIPObj // inplace object ptr
  258. )
  259. {
  260. LPDOC lpdoc;
  261. LPINPLACEDATA lpIpData;
  262. static int EntryCount; /* OLE sometimes calls us recursively. */
  263. DPF("IPObjInPlaceDeactivate\n");
  264. if (EntryCount++ == 0)
  265. {
  266. lpdoc = ((struct COleInPlaceObjectImpl FAR*)lpIPObj)->lpdoc;
  267. lpIpData = lpdoc->lpIpData;
  268. if (lpIpData)
  269. {
  270. // This stops PowerPoint crashing, since it forces UpdateObject
  271. // to send change notification when there's an empty Media Clip.
  272. if (gwDeviceID == 0)
  273. fDocChanged = TRUE;
  274. //Make sure the container has the correct metafile before we are hidden
  275. UpdateObject();
  276. IOleInPlaceObject_UIDeactivate ((LPOLEINPLACEOBJECT)&lpdoc->m_InPlace);
  277. if (lpIpData && lpIpData->lpSite)
  278. {
  279. if (!gfInPPViewer)
  280. IOleInPlaceSite_OnInPlaceDeactivate (lpIpData->lpSite);
  281. IOleInPlaceSite_Release (lpIpData->lpSite);
  282. }
  283. FreeInPlaceDataBlock (lpdoc);
  284. }
  285. }
  286. else
  287. {
  288. /* This sometimes happens during the above OnInPlaceDeactivate call,
  289. * which resulted in an access violation because the data block had
  290. * been freed when the call returned.
  291. * According to the OLE guys, apps should guard against this.
  292. */
  293. DPF("Attempt to re-enter IPObjInPlaceDeactivate\n");
  294. }
  295. --EntryCount;
  296. /* Dontcha just love these global variables!
  297. */
  298. gfOle2IPEditing = FALSE;
  299. gfOle2IPPlaying = FALSE;
  300. gfPlayingInPlace = FALSE;
  301. return NOERROR;
  302. }
  303. //Hide our inplace UI.
  304. STDMETHODIMP IPObjUIDeactivate(
  305. LPOLEINPLACEOBJECT lpIPObj // inplace object ptr
  306. )
  307. {
  308. LPDOC lpdoc;
  309. DPF("IPObjUIDeactivate\n");
  310. lpdoc = ((struct COleInPlaceObjectImpl FAR*)lpIPObj)->lpdoc;
  311. if (!(lpdoc->lpIpData && lpdoc->lpIpData->lpFrame))
  312. return NOERROR;
  313. IOleInPlaceFrame_SetMenu (lpdoc->lpIpData->lpFrame, NULL, NULL, lpdoc->hwnd);
  314. // clear inplace-state
  315. IOleInPlaceFrame_SetActiveObject (lpdoc->lpIpData->lpFrame, NULL, NULL);
  316. if (lpdoc->lpIpData->lpUIWindow)
  317. IOleInPlaceUIWindow_SetActiveObject (lpdoc->lpIpData->lpUIWindow, NULL, NULL);
  318. if(gfOle2IPPlaying)
  319. PostMessage(ghwndApp, WM_COMMAND, ID_STOP, 0L);
  320. /* We could also be playing if we're in-place editing:
  321. */
  322. else if(gfOle2IPEditing && (gwStatus == MCI_MODE_PLAY || gwStatus == MCI_MODE_SEEK))
  323. PostMessage(ghwndApp, WM_COMMAND, ID_STOP, 0L);
  324. ShowWindow(ghwndIPHatch,SW_HIDE);
  325. DeactivateTools(lpdoc);
  326. DisassembleMenus (lpdoc);
  327. if (lpdoc->lpIpData->lpUIWindow) {
  328. IOleInPlaceUIWindow_Release (lpdoc->lpIpData->lpUIWindow);
  329. lpdoc->lpIpData->lpUIWindow = NULL;
  330. }
  331. if (lpdoc->lpIpData->lpFrame) {
  332. IOleInPlaceFrame_Release (lpdoc->lpIpData->lpFrame);
  333. lpdoc->lpIpData->lpFrame = NULL;
  334. }
  335. // Set the parent back to hwndClient window
  336. SetParent(ghwndIPHatch,NULL);
  337. gPrevPosRect.left = gPrevPosRect.top =gPrevPosRect.right = gPrevPosRect.bottom = 0;
  338. lpdoc->hwndParent = NULL;
  339. if (!gfInPPViewer)
  340. IOleInPlaceSite_OnUIDeactivate (lpdoc->lpIpData->lpSite, FALSE);
  341. return NOERROR;
  342. }
  343. /**************************************************************************
  344. * IPObjSetObjectRects:
  345. * The client specifies our window position and size. Move our
  346. * window accordingly. Also size the Hatch window to fit around the
  347. * ghwndApp. If the change is very small compared to the previous
  348. * size ignore and return. This account for slop speeds things up.
  349. ***************************************************************************/
  350. STDMETHODIMP IPObjSetObjectRects(
  351. LPOLEINPLACEOBJECT lpIPObj, // inplace object ptr
  352. LPCRECT lprcPosRect,
  353. LPCRECT lprcVisRect
  354. )
  355. {
  356. LPDOC lpdoc;
  357. RECT rc;
  358. GetWindowRect(ghwndApp, (LPRECT)&rc);
  359. DPFI("\n*IPObjSetObjectRects");
  360. DPFI("\n^^^^^^^^ LPRECPOSRECT: %d, %d, %d, %d ^^^^\n", *lprcPosRect);
  361. DPFI("\n^^^^^^^^ PREVRECT: %d, %d, %d, %d ^^^^\n", gPrevPosRect);
  362. DPFI("\n^^^^^^^^ HWNDRECT: %d, %d, %d, %d ^^^^\n", rc);
  363. lpdoc = ((struct COleInPlaceObjectImpl FAR*)lpIPObj)->lpdoc;
  364. if (!ghwndIPHatch || (ghwndCntr != GetParent(ghwndIPHatch)))
  365. return NOERROR;
  366. if (!(lpdoc->lpIpData))
  367. return NOERROR;
  368. rc = *lprcPosRect;
  369. if (!(gwDeviceID == (UINT)0 || !(gwDeviceType & DTMCI_CANWINDOW)))
  370. SetHatchWindowSize(ghwndIPHatch, (LPRECT)&rc,lprcVisRect, (LPPOINT)&gHatchOffset,TRUE);
  371. else
  372. SetHatchWindowSize(ghwndIPHatch, (LPRECT)&rc,lprcVisRect, (LPPOINT)&gHatchOffset,FALSE);
  373. if(!(gwDeviceType & DTMCI_CANWINDOW) && (gwOptions & OPT_BAR))
  374. rc.top = rc.bottom - gwPlaybarHeight;
  375. if(!(gwDeviceType & DTMCI_CANWINDOW) && !(gwOptions & OPT_BAR))
  376. rc.bottom = rc.top = rc.left = rc.right = 0;
  377. MapWindowPoints(ghwndCntr,ghwndIPHatch,(LPPOINT)&rc, 2);
  378. gfPosRectChange = TRUE;
  379. if (gwDeviceID)
  380. MoveWindow(lpdoc->hwnd, rc.left, rc.top,
  381. rc.right - rc.left,
  382. rc.bottom - rc.top, TRUE);
  383. else
  384. MoveWindow(lpdoc->hwnd, rc.left, rc.top,
  385. rc.right - rc.left,
  386. rc.bottom - rc.top, FALSE);
  387. GetWindowRect(lpdoc->hwnd, &gInPlacePosRect);
  388. gPrevPosRect = *lprcPosRect;
  389. /* I've commented out the below line, because PowerPoint calls
  390. * SetObjectRects after we deactivate, and this was causing the
  391. * MPlayer window to reappear when it was supposed to be hidden.
  392. * This line seems to have been superfluous in any case.
  393. */
  394. // ShowWindow(ghwndIPHatch,SW_SHOW);
  395. return NOERROR;
  396. }
  397. //We don't have an Undo state.
  398. STDMETHODIMP IPObjReactivateAndUndo(
  399. LPOLEINPLACEOBJECT lpIPObj // inplace object ptr
  400. )
  401. {
  402. RETURN_RESULT(INPLACE_E_NOTUNDOABLE);
  403. }
  404. /**************************************************************************
  405. ************** IOleInPlaceActiveObject INTERFACE IMPLEMENTATION.
  406. ***************************************************************************/
  407. //delegate to the common IUnknown implementation.
  408. STDMETHODIMP IPActiveQueryInterface (
  409. LPOLEINPLACEACTIVEOBJECT lpIPActive, // inplace active object ptr
  410. REFIID riidReq, // IID required
  411. LPVOID FAR * lplpUnk // pre for returning the interface
  412. )
  413. {
  414. return UnkQueryInterface((LPUNKNOWN)lpIPActive, riidReq, lplpUnk);
  415. }
  416. STDMETHODIMP_(ULONG) IPActiveAddRef(
  417. LPOLEINPLACEACTIVEOBJECT lpIPActive // inplace active object ptr
  418. )
  419. {
  420. return UnkAddRef((LPUNKNOWN) lpIPActive);
  421. }
  422. STDMETHODIMP_(ULONG) IPActiveRelease (
  423. LPOLEINPLACEACTIVEOBJECT lpIPActive // inplace active object ptr
  424. )
  425. {
  426. return UnkRelease((LPUNKNOWN) lpIPActive);
  427. }
  428. STDMETHODIMP IPActiveGetWindow(
  429. LPOLEINPLACEACTIVEOBJECT lpIPActive, // inplace active object ptr
  430. HWND FAR* lphwnd // window handle of the object
  431. )
  432. {
  433. DPF("IPActiveGetWindow\n");
  434. *lphwnd = ghwndIPHatch;
  435. return NOERROR;
  436. }
  437. //Not very useful at this time.
  438. STDMETHODIMP IPActiveContextSensitiveHelp(
  439. LPOLEINPLACEACTIVEOBJECT lpIPActive, // inplace active object ptr
  440. BOOL fEnable
  441. )
  442. {
  443. LPDOC lpdoc;
  444. lpdoc = ((struct COleInPlaceActiveObjectImpl FAR*)lpIPActive)->lpdoc;
  445. lpdoc->lpIpData->fInContextHelpMode = fEnable;
  446. return NOERROR;
  447. }
  448. STDMETHODIMP IPActiveTranslateAccelerator(
  449. LPOLEINPLACEACTIVEOBJECT lpIPActive, // inplace active object ptr
  450. LPMSG lpmsg
  451. )
  452. {
  453. // This will never be called because this server is implemented as an EXE
  454. RETURN_RESULT(S_FALSE);
  455. }
  456. STDMETHODIMP IPActiveOnFrameWindowActivate(
  457. LPOLEINPLACEACTIVEOBJECT lpIPActive, // inplace active object ptr
  458. BOOL fActivate
  459. )
  460. {
  461. DPF("IPActiveOnFrameWindowActivate = %d **\r\n", (int)fActivate);
  462. if (gwStatus == MCI_MODE_PAUSE)
  463. PostMessage(ghwndApp, WM_COMMAND, ID_STOP, 0L);
  464. return NOERROR;
  465. }
  466. //If activating show the toolbar and menu. If not hide the toolbar and menu.
  467. STDMETHODIMP IPActiveOnDocWindowActivate(
  468. LPOLEINPLACEACTIVEOBJECT lpIPActive, // inplace active object ptr
  469. BOOL fActivate
  470. )
  471. {
  472. LPDOC lpdoc;
  473. RECT rc;
  474. DPF("IPActiveOnDocWindowActivate\n");
  475. lpdoc = ((struct COleInPlaceActiveObjectImpl FAR*)lpIPActive)->lpdoc;
  476. GetWindowRect(lpdoc->hwnd, &rc);
  477. ScreenToClient(lpdoc->hwndParent, (POINT FAR *)&rc);
  478. ScreenToClient(lpdoc->hwndParent, (POINT FAR *)&(rc.right));
  479. if (fActivate) {
  480. if(gfOle2IPEditing)
  481. {
  482. ActivateTools(lpdoc,FALSE);
  483. TransferTools(ghwndIPToolWindow);
  484. }
  485. else
  486. {
  487. ActivateTools(lpdoc,TRUE);
  488. TransferTools(ghwndApp);
  489. }
  490. Layout();
  491. IOleInPlaceFrame_SetMenu (lpdoc->lpIpData->lpFrame,
  492. lpdoc->lpIpData->hmenuShared,
  493. lpdoc->lpIpData->holemenu,
  494. lpdoc->hwnd);
  495. }
  496. else {
  497. DeactivateTools(lpdoc);
  498. if(gfOle2IPPlaying)
  499. PostMessage(ghwndApp, WM_COMMAND, ID_STOP, 0L);
  500. IOleInPlaceFrame_SetMenu (lpdoc->lpIpData->lpFrame,
  501. NULL, NULL, lpdoc->hwnd);
  502. }
  503. return NOERROR;
  504. }
  505. //If we have a toolwindow at the bottom reposition that window to match
  506. //the new frame window size.
  507. STDMETHODIMP IPActiveResizeBorder(
  508. LPOLEINPLACEACTIVEOBJECT lpIPActive, // inplace active object ptr
  509. LPCRECT lprectBorder,
  510. LPOLEINPLACEUIWINDOW lpIPUiWnd,
  511. BOOL fFrameWindow
  512. )
  513. {
  514. DPF("IPActiveResizeBorder\n");
  515. if (fFrameWindow)
  516. {
  517. LPDOC lpdoc;
  518. lpdoc = ((struct COleInPlaceActiveObjectImpl FAR*)lpIPActive)->lpdoc;
  519. if (gfTopAndBottomTool && (GetParent(ghwndIPScrollWindow) != NULL))
  520. MoveWindow(ghwndIPScrollWindow, lprectBorder->left,lprectBorder->bottom-2*TOOL_WIDTH,
  521. toolbarwidth,2*TOOL_WIDTH+1,TRUE);
  522. }
  523. return NOERROR;
  524. }
  525. STDMETHODIMP IPActiveEnableModeless(
  526. LPOLEINPLACEACTIVEOBJECT lpIPActive, // inplace active object ptr
  527. BOOL fEnable
  528. )
  529. {
  530. return NOERROR;
  531. }
  532. /**************************************************************************
  533. * DoInplaceEdit:
  534. * This is the function that initiates the InPlace activation from the
  535. * server side. It sets up the InPlace data structures required by us,
  536. * makes sure that the client supports the required interfaces and
  537. * can provide the space we require. It also prepares the toolbar to be
  538. * displayed and the layout of the Mplayer window.
  539. ***************************************************************************/
  540. STDMETHODIMP DoInPlaceEdit(
  541. LPDOC lpdoc,
  542. LPMSG lpmsg,
  543. LPOLECLIENTSITE lpActiveSite,
  544. LONG verb,
  545. HWND FAR * lphwnd,
  546. LPRECT lprect
  547. )
  548. {
  549. SCODE error = S_OK;
  550. LPOLEINPLACESITE lpIPSite;
  551. RECT rcPos;
  552. RECT rcVis;
  553. RECT hatchrc;
  554. LPWSTR lpObjName;
  555. if (!(lpdoc->lpoleclient))
  556. RETURN_RESULT( E_FAIL);
  557. if (!(lpdoc->lpIpData))
  558. {
  559. if ((error = GetScode(IOleClientSite_QueryInterface(
  560. lpdoc->lpoleclient,
  561. &IID_IOleInPlaceSite,
  562. (void FAR* FAR*) &lpIPSite))) != S_OK)
  563. RETURN_RESULT( error);
  564. if ((error = GetScode(IOleInPlaceSite_CanInPlaceActivate(lpIPSite))) != S_OK)
  565. goto errActivate;
  566. if (!gfInPPViewer)
  567. IOleInPlaceSite_OnInPlaceActivate(lpIPSite);
  568. AllocInPlaceDataBlock (lpdoc);
  569. lpdoc->lpIpData->lpSite = lpIPSite;
  570. }
  571. if ((error = GetScode(IOleInPlaceSite_GetWindow (lpdoc->lpIpData->lpSite, &lpdoc->hwndParent))) != S_OK)
  572. goto errRtn;
  573. if (!(lpdoc->hwndParent))
  574. goto errRtn;
  575. if (!gfInPPViewer)
  576. IOleInPlaceSite_OnUIActivate(lpdoc->lpIpData->lpSite);
  577. if ((error = GetScode(IOleInPlaceSite_GetWindowContext(
  578. lpdoc->lpIpData->lpSite,
  579. &lpdoc->lpIpData->lpFrame,
  580. &lpdoc->lpIpData->lpUIWindow,
  581. &rcPos, &rcVis,
  582. &lpdoc->lpIpData->frameInfo))) != S_OK)
  583. goto errRtn;
  584. #ifdef LATER
  585. if (gscaleInitXY[SCALE_X].denom)
  586. {
  587. gscaleInitXY[SCALE_X].num = (rcPos.right - rcPos.left) * HIMETRIC_PER_INCH / giXppli;
  588. gscaleInitXY[SCALE_Y].num = (rcPos.bottom - rcPos.top) * HIMETRIC_PER_INCH / giYppli;
  589. DPF0("Scale: %d%c X %d%c (%d/%d X %d/%d)\n",
  590. gscaleInitXY[SCALE_X].num * 100 / gscaleInitXY[SCALE_X].denom, '%',
  591. gscaleInitXY[SCALE_Y].num * 100 / gscaleInitXY[SCALE_Y].denom, '%',
  592. gscaleInitXY[SCALE_X].num,
  593. gscaleInitXY[SCALE_X].denom,
  594. gscaleInitXY[SCALE_Y].num,
  595. gscaleInitXY[SCALE_Y].denom);
  596. }
  597. #endif
  598. #ifdef UNICODE
  599. lpObjName = gachClassRoot;
  600. #else
  601. lpObjName = AllocateUnicodeString(gachClassRoot);
  602. if (!lpObjName)
  603. RETURN_RESULT(E_OUTOFMEMORY);
  604. #endif /* UNICODE */
  605. IOleInPlaceFrame_SetActiveObject (lpdoc->lpIpData->lpFrame,
  606. (LPOLEINPLACEACTIVEOBJECT) &lpdoc->m_IPActive,
  607. lpObjName);
  608. if (lpdoc->lpIpData->lpUIWindow) {
  609. IOleInPlaceUIWindow_SetActiveObject (lpdoc->lpIpData->lpUIWindow,
  610. (LPOLEINPLACEACTIVEOBJECT) &lpdoc->m_IPActive,
  611. lpObjName);
  612. }
  613. #ifndef UNICODE
  614. FreeUnicodeString(lpObjName);
  615. #endif
  616. ghwndCntr = lpdoc->hwndParent;
  617. //Create and initialize the hatch window to surround the Mplayer window.
  618. if (!ghwndIPHatch)
  619. {
  620. RegisterHatchWindowClass(ghInst);
  621. if ( !(ghwndIPHatch = CreateHatchWindow(lpdoc->hwndParent,ghInst)))
  622. goto errRtn;
  623. gfnHatchWndProc = (WNDPROC)GetWindowLongPtr(ghwndIPHatch, GWLP_WNDPROC);
  624. SetWindowLongPtr(ghwndIPHatch, GWLP_WNDPROC, (LONG_PTR)SubClassedHatchWndProc);
  625. }
  626. SetParent(ghwndIPHatch, ghwndCntr);
  627. SetFocus(ghwndIPHatch);
  628. CopyRect(&hatchrc, &rcPos);
  629. #define EB_HATCHWIDTH (0 * sizeof(INT))
  630. if (verb == OLEIVERB_PRIMARY)
  631. {
  632. /* I don't want to show the hatch window on play, because it looks
  633. * really bad in PowerPoint. Can't make it invisible, because
  634. * the app window is its child, and it inherits the flag.
  635. * Instead, just make it of zero width.
  636. */
  637. SETWINDOWUINT(ghwndIPHatch, EB_HATCHWIDTH, 0);
  638. }
  639. else
  640. {
  641. SETWINDOWUINT(ghwndIPHatch, EB_HATCHWIDTH, DEF_HATCH_SZ);
  642. InflateRect(&hatchrc, DEF_HATCH_SZ, DEF_HATCH_SZ);
  643. }
  644. SetHatchRect(ghwndIPHatch,(LPRECT)&hatchrc);
  645. *lphwnd = ghwndIPHatch;
  646. //If we are going to Play inplace, do the minimum stuff and return.
  647. if (verb == OLEIVERB_PRIMARY)
  648. {
  649. gfOle2IPPlaying = TRUE;
  650. GetWindowRect(ghwndCntr,(LPRECT)&rcVis);
  651. MapWindowPoints(NULL,ghwndCntr,(LPPOINT)&rcVis, 2);
  652. SetHatchWindowSize(ghwndIPHatch, (LPRECT)&rcPos,(LPRECT)&rcVis, (LPPOINT)&gHatchOffset,FALSE);
  653. MoveWindow(ghwndApp, 0, 0, rcPos.right - rcPos.left, rcPos.bottom - rcPos.top, TRUE);
  654. InPlaceCreateControls(TRUE);
  655. ActivateTools(lpdoc, TRUE);
  656. TransferTools(ghwndApp);
  657. ClientToScreen(lpdoc->hwndParent, (LPPOINT)&rcPos);
  658. ClientToScreen(lpdoc->hwndParent, (LPPOINT)&rcPos+1);
  659. lpdoc->hwndParent = NULL;
  660. /* MENU STUFF */
  661. /* We have to set the menus even if we're only playing, because otherwise
  662. * Word doesn't believe we're in-place active, and doesn't send us any
  663. * deactivation notification when the user clicks outside us.
  664. */
  665. AssembleMenus (lpdoc, TRUE);
  666. if ((error = GetScode(IOleInPlaceFrame_SetMenu (lpdoc->lpIpData->lpFrame,
  667. lpdoc->lpIpData->hmenuShared,
  668. lpdoc->lpIpData->holemenu,
  669. lpdoc->hwnd))) != S_OK)
  670. goto errRtn;
  671. /* END MENU STUFF */
  672. *lprect = rcPos;
  673. ShowWindow(ghwndIPHatch, SW_SHOW);
  674. return NOERROR;
  675. }
  676. //Edit InPlace.
  677. if (!(gwDeviceID == (UINT)0 || !(gwDeviceType & DTMCI_CANWINDOW)))
  678. //No resize handles.
  679. SetHatchWindowSize(ghwndIPHatch, (LPRECT)&rcPos,(LPRECT)&rcVis, (LPPOINT)&gHatchOffset,TRUE);
  680. else
  681. //There will be resize handles.
  682. SetHatchWindowSize(ghwndIPHatch, (LPRECT)&rcPos,(LPRECT)&rcVis, (LPPOINT)&gHatchOffset,FALSE);
  683. gfOle2IPEditing = TRUE;
  684. if (!SkipInPlaceEdit) //don't layout and transfer the tools
  685. { // if we are just reactivating.
  686. DestroyWindow(ghwndStatic);
  687. ghwndStatic = CreateStaticStatusWindow(ghwndApp, FALSE);
  688. SendMessage(ghwndStatic, WM_SETFONT, (UINT_PTR)ghfontMap, 0);
  689. Layout();
  690. InPlaceCreateControls(FALSE);
  691. }
  692. else
  693. SetParent (lpdoc->hwnd, ghwndIPHatch);
  694. TransferTools(ghwndIPToolWindow);
  695. if ((error = GetScode(AssembleMenus (lpdoc, FALSE))) != S_OK)
  696. goto errRtn;
  697. ShowWindow (lpdoc->hwnd, SW_HIDE);
  698. // currently we are not using the pane
  699. // prevent OnDataChange() notification
  700. lpdoc->lpIpData->fNoNotification = FALSE;
  701. if ((error = GetScode(IOleInPlaceFrame_SetMenu (lpdoc->lpIpData->lpFrame,
  702. lpdoc->lpIpData->hmenuShared,
  703. lpdoc->lpIpData->holemenu,
  704. lpdoc->hwnd))) != S_OK)
  705. goto errRtn;
  706. if ((error = GetScode(ActivateTools(lpdoc,FALSE))) != S_OK)
  707. goto errRtn;
  708. ShowWindow(ghwndIPHatch,SW_SHOW);
  709. ShowWindow(ghwndMCI,SW_SHOW);
  710. ClientToScreen(lpdoc->hwndParent, (LPPOINT)&rcPos);
  711. ClientToScreen(lpdoc->hwndParent, (LPPOINT)&rcPos+1);
  712. *lprect = rcPos;
  713. if (SkipInPlaceEdit)
  714. OffsetRect(&gInPlacePosRect,rcPos.left-gInPlacePosRect.left,
  715. rcPos.top-gInPlacePosRect.top);
  716. else
  717. gInPlacePosRect = rcPos;
  718. return NOERROR;
  719. errRtn:
  720. DoInPlaceDeactivate(lpdoc);
  721. TransferTools(ghwndApp);
  722. RETURN_RESULT(error);
  723. errActivate:
  724. IOleInPlaceSite_Release(lpIPSite);
  725. FreeInPlaceDataBlock (lpdoc);
  726. RETURN_RESULT( error);
  727. }
  728. #if 0
  729. HMENU GetInPlaceMenu(void)
  730. {
  731. if (ghInPlaceMenu)
  732. return GetSubMenu(ghInPlaceMenu,0);
  733. else
  734. {
  735. ghInPlaceMenu = LoadMenu(ghInst, TEXT("InPlaceMenu"));
  736. return GetSubMenu(ghInPlaceMenu,0);
  737. }
  738. }
  739. #endif
  740. /**************************************************************************
  741. * AssembleMenus:
  742. * This function merges our menu with that of the client.
  743. ***************************************************************************/
  744. STDMETHODIMP AssembleMenus (LPDOC lpdoc, BOOL fPlayOnly)
  745. {
  746. HMENU hmenuMain = ghMenu;
  747. HMENU hmenuEditPopup = GetSubMenu(hmenuMain, menuposEdit);
  748. HMENU hmenuDevicePopup = GetSubMenu(hmenuMain, menuposDevice);
  749. HMENU hmenuScalePopup = GetSubMenu(hmenuMain, menuposScale);
  750. //HMENU hmenuCommandPopup = GetInPlaceMenu();
  751. HMENU hmenuHelpPopup = GetSubMenu(hmenuMain, menuposHelp);
  752. HMENU hmenuShared;
  753. LONG FAR* lpMenuWidths;
  754. SCODE error = S_OK;
  755. UINT uPos;
  756. UINT uPosStart;
  757. static TCHAR szEdit[40] = TEXT("");
  758. static TCHAR szInsert[40] = TEXT("");
  759. static TCHAR szScale[40] = TEXT("");
  760. //static TCHAR szCommand[40] = TEXT("");
  761. static TCHAR szHelp[40] = TEXT("");
  762. if (szEdit[0] == TEXT('\0'))
  763. {
  764. LOADSTRING(IDS_EDITMENU, szEdit);
  765. LOADSTRING(IDS_INSERTMENU, szInsert);
  766. LOADSTRING(IDS_SCALEMENU, szScale);
  767. //LOADSTRING(IDS_COMMANDMENU, szCommand);
  768. LOADSTRING(IDS_HELPMENU, szHelp);
  769. }
  770. lpMenuWidths = lpdoc->lpIpData->menuWidths.width;
  771. hmenuShared = CreateMenu();
  772. if((error = GetScode(IOleInPlaceFrame_InsertMenus (lpdoc->lpIpData->lpFrame,
  773. hmenuShared, &lpdoc->lpIpData->menuWidths))) !=S_OK)
  774. {
  775. if (hmenuShared)
  776. DestroyMenu(hmenuShared);
  777. RETURN_RESULT( error);
  778. }
  779. if(fPlayOnly)
  780. {
  781. /* No server menu items if we're only playing:
  782. */
  783. lpMenuWidths[1] = lpMenuWidths[3] = lpMenuWidths[5] = 0;
  784. }
  785. else
  786. {
  787. uPos = (UINT)lpMenuWidths[0]; /* # of menus in the FILE group */
  788. uPosStart = uPos;
  789. InsertMenu (hmenuShared, (WORD)uPos,
  790. MF_BYPOSITION | MF_POPUP, (UINT_PTR)hmenuEditPopup, szEdit);
  791. uPos++;
  792. lpMenuWidths[1] = uPos - uPosStart;
  793. /* Insert OBJECT group menus */
  794. uPos += (UINT)lpMenuWidths[2];
  795. uPosStart = uPos;
  796. InsertMenu (hmenuShared, (WORD)uPos,
  797. MF_BYPOSITION | MF_POPUP, (UINT_PTR)hmenuDevicePopup, szInsert);
  798. uPos++;
  799. InsertMenu (hmenuShared, (WORD)uPos,
  800. MF_BYPOSITION | MF_POPUP, (UINT_PTR)hmenuScalePopup, szScale);
  801. uPos++;
  802. //InsertMenu (hmenuShared, (WORD)uPos,
  803. // MF_BYPOSITION | MF_POPUP, (UINT)hmenuCommandPopup, szCommand);
  804. //uPos++;
  805. lpMenuWidths[3] = uPos - uPosStart;
  806. /* Insert HELP group menus */
  807. uPos += (UINT) lpMenuWidths[4]; /* # of menus in WINDOW group */
  808. uPosStart = uPos;
  809. InsertMenu (hmenuShared, (WORD)uPos, MF_BYPOSITION | MF_POPUP, (UINT_PTR)hmenuHelpPopup,
  810. szHelp);
  811. uPos++;
  812. lpMenuWidths[5] = uPos - uPosStart;
  813. }
  814. if(!(lpdoc->lpIpData->holemenu = OleCreateMenuDescriptor (hmenuShared,
  815. &lpdoc->lpIpData->menuWidths)))
  816. RETURN_RESULT( E_OUTOFMEMORY);
  817. lpdoc->lpIpData->hmenuShared = hmenuShared;
  818. RETURN_RESULT( error);
  819. }
  820. //Removes our menu from the shared menu,
  821. STDMETHODIMP DisassembleMenus (LPDOC lpdoc)
  822. {
  823. HMENU hmenuMain = ghMenu;
  824. HMENU hmenuEditPopup = GetSubMenu(hmenuMain, menuposEdit);
  825. HMENU hmenuDevicePopup = GetSubMenu(hmenuMain, menuposDevice);
  826. HMENU hmenuScalePopup = GetSubMenu(hmenuMain, menuposScale);
  827. //HMENU hmenuCommandPopup = GetInPlaceMenu();
  828. HMENU hmenuHelpPopup = GetSubMenu(hmenuMain, menuposHelp);
  829. HMENU hmenuTmp;
  830. HMENU hmenuShared = lpdoc->lpIpData->hmenuShared;
  831. int i, n, cnt;
  832. SCODE error = S_OK;
  833. OleDestroyMenuDescriptor (lpdoc->lpIpData->holemenu);
  834. lpdoc->lpIpData->holemenu = NULL;
  835. if(!(lpdoc->lpIpData->hmenuShared))
  836. RETURN_RESULT( error);
  837. n = GetMenuItemCount(hmenuShared);
  838. cnt = 0;
  839. i = 0;
  840. while (i < n) {
  841. hmenuTmp = GetSubMenu(hmenuShared, i);
  842. if (hmenuTmp == hmenuEditPopup
  843. || hmenuTmp == hmenuDevicePopup
  844. || hmenuTmp == hmenuHelpPopup
  845. //|| hmenuTmp == hmenuCommandPopup
  846. || hmenuTmp == hmenuScalePopup ) {
  847. RemoveMenu (hmenuShared, i, MF_BYPOSITION);
  848. ++cnt;
  849. if (cnt == 4) { // added 3 (4 if command menu included) popup menus.
  850. break;
  851. }
  852. --n;
  853. }
  854. else
  855. ++i;
  856. }
  857. IOleInPlaceFrame_RemoveMenus (lpdoc->lpIpData->lpFrame,
  858. lpdoc->lpIpData->hmenuShared);
  859. DestroyMenu(lpdoc->lpIpData->hmenuShared);
  860. lpdoc->lpIpData->hmenuShared = NULL;
  861. RETURN_RESULT( error);
  862. }
  863. void AllocInPlaceDataBlock (LPDOC lpdoc)
  864. {
  865. // When this app is ready to support mutiple objects (documents), these
  866. // structures should be allocated dynamically one per object.
  867. static INPLACEDATA IpData;
  868. lpdoc->lpIpData = (LPINPLACEDATA) &IpData;
  869. lpdoc->lpIpData->lpFrame = NULL;
  870. lpdoc->lpIpData->lpUIWindow = NULL;
  871. lpdoc->lpIpData->fInContextHelpMode = FALSE;
  872. }
  873. void FreeInPlaceDataBlock (LPDOC lpdoc)
  874. {
  875. lpdoc->lpIpData = NULL;
  876. }
  877. void DoInPlaceDeactivate (LPDOC lpdoc)
  878. {
  879. if (!(lpdoc->lpIpData))
  880. return;
  881. ShowWindow(ghwndApp,SW_HIDE);
  882. IOleInPlaceObject_InPlaceDeactivate ((LPOLEINPLACEOBJECT)&lpdoc->m_InPlace);
  883. }
  884. /**************************************************************************
  885. * ToolWndProc:
  886. * This is the Window proc for the ToolWindow/Windows we will be trasnferring
  887. * to the client window. Some messages are routed to the MPlayer main window
  888. * to ensure proper operation.
  889. ***************************************************************************/
  890. LONG_PTR FAR PASCAL ToolWndProc (HWND hwnd, unsigned message, WPARAM wparam,
  891. LPARAM lparam)
  892. {
  893. switch(message)
  894. {
  895. case WM_COMMAND:
  896. PostMessage(ghwndApp,WM_COMMAND,
  897. wparam,lparam);
  898. break;
  899. case WM_NEXTDLGCTL:
  900. case WM_CTLCOLOR:
  901. case WM_HSCROLL:
  902. return (SendMessage(ghwndApp,message,wparam,lparam));
  903. default:
  904. return DefWindowProc(hwnd,message,wparam,lparam);
  905. }
  906. return 0;
  907. }
  908. /**************************************************************************
  909. * RegisterToolWinClasses:
  910. * Register the WindowClasses for the Toolbar windows we use to display
  911. * in the client document.
  912. ***************************************************************************/
  913. BOOL RegisterToolWinClasses()
  914. {
  915. WNDCLASS wc;
  916. wc.lpszClassName = TEXT("ObjTool");
  917. wc.lpfnWndProc = ToolWndProc;
  918. wc.style = 0;
  919. wc.hInstance = ghInst;
  920. wc.hIcon = NULL;
  921. wc.cbClsExtra = 4;
  922. wc.cbWndExtra = 0;
  923. wc.lpszMenuName = NULL;
  924. wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  925. wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
  926. if (!RegisterClass(&wc))
  927. return FALSE;
  928. return TRUE;
  929. }
  930. /**************************************************************************
  931. * InPlaceCreateControls:
  932. * This function creates the toolbar windows we will display in the client
  933. * and transfers the tool button to these windows by changing parents
  934. * and repositioning them.
  935. * If fPlayOnly is true all we need is a Dummy toolbar to fill space on
  936. * the top of the container. Don't transfer the tools.
  937. ***************************************************************************/
  938. void InPlaceCreateControls(BOOL fPlayOnly)
  939. {
  940. RECT rc;
  941. if(IsWindow(ghwndIPToolWindow))
  942. return;
  943. RegisterToolWinClasses();
  944. GetWindowRect(GetDesktopWindow(),&rc);
  945. toolbarwidth = 2*(rc.right - rc.left);
  946. IOleInPlaceFrame_GetWindow (docMain.lpIpData->lpFrame, &ghwndFrame);
  947. ghwndIPToolWindow = CreateWindowEx(gfdwFlagsEx,
  948. TEXT("ObjTool"),
  949. NULL,
  950. WS_CHILD | WS_BORDER,
  951. 0, 0,
  952. toolbarwidth,
  953. 3*TOOL_WIDTH+1,
  954. ghwndFrame,
  955. NULL,
  956. ghInst,
  957. NULL);
  958. ShowWindow(ghwndIPToolWindow, SW_HIDE);
  959. if (fPlayOnly)
  960. return;
  961. ghwndIPScrollWindow = CreateWindowEx(gfdwFlagsEx,
  962. TEXT("ObjTool"),
  963. NULL,
  964. WS_CHILD | WS_BORDER,
  965. 0, 0,
  966. toolbarwidth,
  967. 3*TOOL_WIDTH+1,
  968. ghwndFrame,
  969. NULL,
  970. ghInst,
  971. NULL);
  972. ShowWindow(ghwndIPScrollWindow, SW_HIDE);
  973. }
  974. /**************************************************************************
  975. * SubClassedHatchWndProc:
  976. * The Hatch Window is created in the OLE2UI.LIB. The window proc
  977. * is also specified there. But in order to do things like resizing
  978. * the Mplayer when the handles in the hatch window are dragged
  979. * we need to subclass the window.
  980. ***************************************************************************/
  981. LONG_PTR FAR PASCAL SubClassedHatchWndProc(HWND hwnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
  982. {
  983. static BOOL fCapture = FALSE;
  984. static RECT hatchRC;
  985. RECT rc;
  986. static POINT ptLast;
  987. POINT pt;
  988. HDC hdcDeskTop;
  989. HPEN hpenOld;
  990. HBRUSH hbrushOld;
  991. int nropOld;
  992. int nBkOld;
  993. HPEN hpen;
  994. static int dL,dR, dT, dB;
  995. static int left, right, top, bottom;
  996. switch(wMsg)
  997. {
  998. case WM_LBUTTONDOWN: //Check to see if the click is on the resize handles.
  999. //If yes then capture the mouse.
  1000. if(!GETWINDOWUINT(ghwndIPHatch,EW_HATCH_HANDLE))
  1001. break;
  1002. if(gfOle2IPPlaying)
  1003. break;
  1004. GetHatchRect(ghwndIPHatch, &hatchRC);
  1005. pt.x = (int)(SHORT)LOWORD(lParam);
  1006. pt.y = (int)(SHORT)HIWORD(lParam);
  1007. left = right = top = bottom = 0;
  1008. rc.left = hatchRC.left;
  1009. rc.top = hatchRC.top;
  1010. rc.right = rc.left + DEF_HATCH_SZ + 1;
  1011. rc.bottom = rc.top + DEF_HATCH_SZ + 1;
  1012. if(PtInRect((LPRECT)&rc,pt))
  1013. left = top = 1;
  1014. rc.top = hatchRC.top+(hatchRC.bottom-hatchRC.top-DEF_HATCH_SZ-1)/2;
  1015. rc.bottom = rc.top + DEF_HATCH_SZ + 1;
  1016. if(PtInRect((LPRECT)&rc,pt))
  1017. left = 1;
  1018. rc.top = hatchRC.bottom-DEF_HATCH_SZ-1;
  1019. rc.bottom = rc.top + DEF_HATCH_SZ + 1;
  1020. if(PtInRect((LPRECT)&rc,pt))
  1021. {
  1022. bottom = 1;
  1023. left = 1;
  1024. }
  1025. rc.left = hatchRC.right - DEF_HATCH_SZ-1;
  1026. rc.right = rc.left + DEF_HATCH_SZ + 1;
  1027. if(PtInRect((LPRECT)&rc,pt))
  1028. {
  1029. bottom = 1;
  1030. right = 1;
  1031. }
  1032. rc.top = hatchRC.top+(hatchRC.bottom-hatchRC.top-DEF_HATCH_SZ-1)/2;
  1033. rc.bottom = rc.top + DEF_HATCH_SZ + 1;
  1034. if(PtInRect((LPRECT)&rc,pt))
  1035. right = 1;
  1036. rc.top = hatchRC.top;
  1037. rc.bottom = rc.top + DEF_HATCH_SZ + 1;
  1038. if(PtInRect((LPRECT)&rc,pt))
  1039. {
  1040. top = 1;
  1041. right = 1;
  1042. }
  1043. rc.left = hatchRC.left + (hatchRC.right - hatchRC.left - DEF_HATCH_SZ-1)/2;
  1044. rc.right = rc.left + DEF_HATCH_SZ + 1;
  1045. if(PtInRect((LPRECT)&rc,pt))
  1046. top = 1;
  1047. rc.top = hatchRC.bottom-DEF_HATCH_SZ-1;
  1048. rc.bottom = rc.top + DEF_HATCH_SZ + 1;
  1049. if(PtInRect((LPRECT)&rc,pt))
  1050. bottom = 1;
  1051. if (!(left || right || top || bottom))
  1052. break;
  1053. fCapture = TRUE;
  1054. SetCapture(hwnd);
  1055. ptLast = pt;
  1056. MapWindowPoints(hwnd,NULL,(LPPOINT)&hatchRC,2);
  1057. dL = dR = dT = dB = 0;
  1058. hpen = CreatePen(PS_DASH, 1, 0x00000000);
  1059. hdcDeskTop = GetDC(NULL);
  1060. hpenOld = SelectObject (hdcDeskTop, hpen);
  1061. hbrushOld = SelectObject (hdcDeskTop,
  1062. GetStockObject(HOLLOW_BRUSH));
  1063. nropOld = GetROP2(hdcDeskTop);
  1064. SetROP2(hdcDeskTop, R2_NOT);
  1065. nBkOld = GetBkMode(hdcDeskTop);
  1066. SetBkMode(hdcDeskTop, TRANSPARENT);
  1067. Rectangle(hdcDeskTop, hatchRC.left+dL, hatchRC.top+dT,
  1068. hatchRC.right+dR, hatchRC.bottom+dB);
  1069. SetBkMode(hdcDeskTop, nBkOld);
  1070. SetROP2(hdcDeskTop, nropOld);
  1071. SelectObject(hdcDeskTop, hbrushOld);
  1072. SelectObject(hdcDeskTop, hpenOld);
  1073. DeleteObject (hpen);
  1074. ReleaseDC(NULL, hdcDeskTop);
  1075. break;
  1076. case WM_MOUSEMOVE: //If we have the capture draw the resize rectangles.
  1077. if (!fCapture)
  1078. break;
  1079. else {
  1080. pt.x = (int)(SHORT)LOWORD(lParam);
  1081. pt.y = (int)(SHORT)HIWORD(lParam);
  1082. hpen = CreatePen(PS_DASH, 1, 0x00000000);
  1083. hdcDeskTop = GetDC(NULL);
  1084. hpenOld = SelectObject (hdcDeskTop, hpen);
  1085. hbrushOld = SelectObject (hdcDeskTop,
  1086. GetStockObject(HOLLOW_BRUSH));
  1087. nropOld = GetROP2(hdcDeskTop);
  1088. SetROP2(hdcDeskTop, R2_NOT);
  1089. nBkOld = GetBkMode(hdcDeskTop);
  1090. SetBkMode(hdcDeskTop, TRANSPARENT);
  1091. Rectangle(hdcDeskTop, hatchRC.left+dL, hatchRC.top+dT,
  1092. hatchRC.right+dR, hatchRC.bottom+dB);
  1093. dL = dR = pt.x - ptLast.x;
  1094. dT = dB = pt.y - ptLast.y;
  1095. dL *= left;
  1096. dR *= right;
  1097. dT *= top;
  1098. dB *= bottom;
  1099. Rectangle(hdcDeskTop, hatchRC.left+dL, hatchRC.top+dT,
  1100. hatchRC.right+dR, hatchRC.bottom+dB);
  1101. SetBkMode(hdcDeskTop, nBkOld);
  1102. SetROP2(hdcDeskTop, nropOld);
  1103. SelectObject(hdcDeskTop, hbrushOld);
  1104. SelectObject(hdcDeskTop, hpenOld);
  1105. if (hpen)
  1106. DeleteObject (hpen);
  1107. ReleaseDC(NULL, hdcDeskTop);
  1108. }
  1109. break;
  1110. case WM_LBUTTONUP: //release capture and resize.
  1111. if (!fCapture)
  1112. break;
  1113. else {
  1114. hpen = CreatePen(PS_DASH, 1, 0x00000000);
  1115. hdcDeskTop = GetDC(NULL);
  1116. hpenOld = SelectObject (hdcDeskTop, hpen);
  1117. hbrushOld = SelectObject (hdcDeskTop,
  1118. GetStockObject(HOLLOW_BRUSH));
  1119. nropOld = GetROP2(hdcDeskTop);
  1120. SetROP2(hdcDeskTop, R2_NOT);
  1121. nBkOld = GetBkMode(hdcDeskTop);
  1122. SetBkMode(hdcDeskTop, TRANSPARENT);
  1123. Rectangle(hdcDeskTop, hatchRC.left+dL, hatchRC.top+dT,
  1124. hatchRC.right+dR, hatchRC.bottom+dB);
  1125. SetBkMode(hdcDeskTop, nBkOld);
  1126. SetROP2(hdcDeskTop, nropOld);
  1127. SelectObject(hdcDeskTop, hbrushOld);
  1128. SelectObject(hdcDeskTop, hpenOld);
  1129. DeleteObject (hpen);
  1130. ReleaseDC(NULL, hdcDeskTop);
  1131. ReleaseCapture();
  1132. }
  1133. fCapture = FALSE;
  1134. GetWindowRect(ghwndApp,&hatchRC);
  1135. hatchRC.left += dL;
  1136. hatchRC.right += dR;
  1137. hatchRC.top += dT;
  1138. hatchRC.bottom += dB;
  1139. MapWindowPoints(NULL,ghwndCntr,(LPPOINT)&hatchRC, 2);
  1140. if (gwStatus != MCI_MODE_STOP)
  1141. PostMessage(ghwndApp, WM_COMMAND, ID_STOP, 0L);
  1142. // Negotiate with client for space. We accept the size specified by client.
  1143. DPFI("Hatch Resize: Before OnPosRectChange: %d, %d, %d, %d\r\n", hatchRC);
  1144. if (!gfInPPViewer)
  1145. IOleInPlaceSite_OnPosRectChange(docMain.lpIpData->lpSite, &hatchRC);
  1146. SendDocMsg((LPDOC)&docMain, OLE_CHANGED);
  1147. break;
  1148. case WM_PAINT:
  1149. {
  1150. HDC hdc;
  1151. HDC hdcmem;
  1152. RECT rcH;
  1153. HBITMAP hbm;
  1154. BITMAP bm;
  1155. if(ghwndMCI)
  1156. break;
  1157. CallWindowProc(gfnHatchWndProc, hwnd, wMsg, wParam, lParam);
  1158. hdc = GetDC(hwnd);
  1159. GetHatchRect(hwnd, (LPRECT)&rcH);
  1160. InflateRect((LPRECT)&rcH,-DEF_HATCH_SZ,-DEF_HATCH_SZ);
  1161. hbm = BitmapMCI();
  1162. hdcmem = CreateCompatibleDC(hdc);
  1163. if(!hdcmem)
  1164. return(E_FAIL);
  1165. SelectObject(hdcmem,hbm);
  1166. GetObject(hbm,sizeof(bm),(LPVOID)&bm);
  1167. StretchBlt(hdc,rcH.left,rcH.top,rcH.right-rcH.left,rcH.bottom-rcH.top,hdcmem,
  1168. 0,0,bm.bmWidth,bm.bmHeight,SRCCOPY);
  1169. DeleteDC(hdcmem);
  1170. ReleaseDC(ghwndIPHatch,hdc);
  1171. return 0L;
  1172. }
  1173. }
  1174. return CallWindowProc(gfnHatchWndProc, hwnd, wMsg, wParam, lParam);
  1175. }
  1176.