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.

832 lines
20 KiB

  1. /****************************** Module Header ******************************\
  2. * Module Name: MAIN.C
  3. *
  4. * PURPOSE: WinMain, WEP and some other misc routines
  5. *
  6. * Created: 1991
  7. *
  8. * Copyright (c) 1990, 1991 Microsoft Corporation
  9. *
  10. * History:
  11. * Srinik (04/01/91) Pulled some routines, into this, from ole.c.
  12. * curts Create portable version for win16/32.
  13. *
  14. \***************************************************************************/
  15. #include <windows.h>
  16. #include "dll.h"
  17. #ifndef WF_WLO
  18. #define WF_WLO 0x8000
  19. #endif
  20. // ordinal number new win31 API IsTask
  21. #define ORD_IsTask 320
  22. #define NUM_DLL 30 /* space for this many DLL_ENTRYs is created on */
  23. /* each alloc/realloc */
  24. OLECLIPFORMAT cfOwnerLink = 0; // global variables for clip frmats
  25. OLECLIPFORMAT cfObjectLink = 0;
  26. OLECLIPFORMAT cfLink = 0;
  27. OLECLIPFORMAT cfNative = 0;
  28. OLECLIPFORMAT cfBinary = 0;
  29. OLECLIPFORMAT cfFileName = 0;
  30. OLECLIPFORMAT cfNetworkName = 0;
  31. ATOM aStdHostNames;
  32. ATOM aStdTargetDevice ;
  33. ATOM aStdDocDimensions;
  34. ATOM aStdDocName;
  35. ATOM aStdColorScheme;
  36. ATOM aNullArg = 0;
  37. ATOM aSave;
  38. ATOM aChange;
  39. ATOM aClose;
  40. ATOM aSystem;
  41. ATOM aOle;
  42. ATOM aClipDoc;
  43. ATOM aPackage;
  44. // Used in work around for MSDraw bug
  45. ATOM aMSDraw;
  46. extern LPCLIENTDOC lpHeadDoc;
  47. extern LPCLIENTDOC lpTailDoc;
  48. extern RENDER_ENTRY stdRender[];
  49. HANDLE hInstDLL;
  50. /* HANDLE hDllTable; !!! Add this when bug in WEP is fixed */
  51. DLL_ENTRY lpDllTable[NUM_DLL]; //!!! change this when WEP bug is fixed
  52. DWORD dllTableSize;
  53. int iLast = 0;
  54. int iMax = NUM_DLL -1;
  55. int iUnloadableDll = 0; // index to handler than can be freed up
  56. char packageClass[] = "Package";
  57. // For QuerySize() API & methods.
  58. extern OLESTREAMVTBL dllStreamVtbl;
  59. extern CLIENTDOC lockDoc;
  60. #ifdef FIREWALLS
  61. BOOL bShowed = FALSE;
  62. char szDebugBuffer[80];
  63. short ole_flags;
  64. void FARINTERNAL ShowVersion (void);
  65. void FARINTERNAL SetOleFlags(void);
  66. #endif
  67. // LOWWORD - BYTE 0 major verision, BYTE1 minor version,
  68. // HIWORD reserved
  69. DWORD dwOleVer = 0x0901L; // change this when we want to update dll version
  70. // number
  71. WORD wReleaseVer = 0x0001; // This is used while object is being saved to
  72. // file. There is no need to change this value
  73. // whenever we change ole dll version number
  74. static BOOL bLibInit = FALSE;
  75. HANDLE hModule;
  76. #define MAX_HIMETRIC 0x7FFF
  77. int maxPixelsX = MAX_HIMETRIC;
  78. int maxPixelsY = MAX_HIMETRIC;
  79. void SetMaxPixel (void);
  80. VOID FAR PASCAL WEP (int);
  81. #ifdef WIN16 // begin WIN16
  82. BOOL bProtMode;
  83. BOOL bWLO = FALSE;
  84. WORD wWinVer;
  85. #pragma alloc_text(WEP_TEXT, WEP)
  86. FARPROC lpfnIsTask = NULL; // the API IsTask() became available from
  87. // win31 onwards, hence we are trying to
  88. // get it's address through GetProcAddress
  89. #endif // end WIN16
  90. //////////////////////////////////////////////////////////////////////////////
  91. //
  92. // int FAR PASCAL LibMain (hInst, wDataSeg, cbHeapSize, lpszCmdLine)
  93. //
  94. // The main library entry point. This routine is called when the library
  95. // is loaded.
  96. //
  97. // Arguments:
  98. //
  99. // hInst - dll's instance handle
  100. // wDataSeg - DS register value
  101. // cbHeapSize - heap size defined def file
  102. // lpszCmdLine - command line info
  103. //
  104. // Returns:
  105. //
  106. // 0 - failure
  107. // 1 - success
  108. //
  109. // Effects:
  110. //
  111. //////////////////////////////////////////////////////////////////////////////
  112. #ifdef WIN16
  113. int APIENTRY LibMain(
  114. HANDLE hInst,
  115. WORD wDataSeg,
  116. WORD cbHeapSize,
  117. LPSTR lpszCmdLine
  118. #endif
  119. #ifdef WIN32
  120. BOOL LibMain(
  121. HANDLE hInst,
  122. ULONG Reason,
  123. PCONTEXT Context
  124. #endif // WIN32
  125. ){
  126. WNDCLASS wc;
  127. int i;
  128. #ifdef WIN32
  129. char szDocClass[] = "OleDocWndClass" ;
  130. char szSrvrClass[] = "OleSrvrWndClass" ;
  131. #endif
  132. Puts("LibMain");
  133. #ifdef FIREWALLS
  134. SetOleFlags();
  135. #endif
  136. #ifdef WIN32 // begin WIN32
  137. UNREFERENCED_PARAMETER(Context);
  138. if (Reason == DLL_PROCESS_DETACH)
  139. {
  140. WEP(0);
  141. UnregisterClass (szDocClass, hInst) ;
  142. UnregisterClass (szSrvrClass, hInst) ;
  143. return TRUE;
  144. }
  145. else if (Reason != DLL_PROCESS_ATTACH)
  146. return TRUE;
  147. #endif // end WIN32
  148. bLibInit = TRUE;
  149. hInstDLL = hInst;
  150. hModule = GetModuleHandle ("OLECLI");
  151. #ifdef WIN16 // begin WIN16
  152. bProtMode = (BOOL) (GetWinFlags() & WF_PMODE);
  153. bWLO = (BOOL) (GetWinFlags() & WF_WLO);
  154. wWinVer = (WORD) GetVersion();
  155. #endif // end WIN16
  156. // REGISTER LINK FORMAT
  157. cfObjectLink = (OLECLIPFORMAT)RegisterClipboardFormat("ObjectLink");
  158. cfLink = (OLECLIPFORMAT)RegisterClipboardFormat("Link");
  159. cfOwnerLink = (OLECLIPFORMAT)RegisterClipboardFormat("OwnerLink");
  160. cfNative = (OLECLIPFORMAT)RegisterClipboardFormat("Native");
  161. cfBinary = (OLECLIPFORMAT)RegisterClipboardFormat("Binary");
  162. cfFileName = (OLECLIPFORMAT)RegisterClipboardFormat("FileName");
  163. cfNetworkName = (OLECLIPFORMAT)RegisterClipboardFormat("NetworkName");
  164. if (!(cfObjectLink && cfOwnerLink && cfNative && cfLink))
  165. return 0;
  166. // SET UP OLEWNDCLASS
  167. wc.style = 0;
  168. wc.lpfnWndProc = DocWndProc;
  169. wc.cbClsExtra = 0;
  170. wc.cbWndExtra = sizeof(LONG_PTR); //we are storing longs
  171. wc.hInstance = hInst;
  172. wc.hIcon = NULL;
  173. wc.hCursor = NULL;
  174. wc.hbrBackground= NULL;
  175. wc.lpszMenuName = NULL;
  176. wc.lpszClassName= szDocClass;
  177. if (!RegisterClass(&wc))
  178. return 0;
  179. wc.lpfnWndProc = (WNDPROC)SrvrWndProc;
  180. wc.lpszClassName = szSrvrClass ;
  181. if (!RegisterClass(&wc))
  182. return 0;
  183. /*
  184. // !!! Add this when bug in WEP is fixed.
  185. // Allocate memory for DLL table
  186. dllTableSize = NUM_DLL * sizeof(DLL_ENTRY);
  187. if (!(hDllTable = GlobalAlloc (GMEM_MOVEABLE | GMEM_ZEROINIT,
  188. dllTableSize)))
  189. return 0;
  190. if (!(lpDllTable = (DLL_ENTRY FAR *) GlobalLock (hDllTable)))
  191. return 0;
  192. */
  193. // !!! remove the following when WEP bug is fixed
  194. for (i = 0; i < NUM_DLL; i++)
  195. lpDllTable[i].aDll = (ATOM)0;
  196. // !!! BEGIN hack for Pbrush.
  197. lpDllTable[0].hDll = NULL;
  198. lpDllTable[0].aDll = GlobalAddAtom ((LPSTR) "ole");
  199. lpDllTable[0].Load = PbLoadFromStream;
  200. lpDllTable[0].Clip = PbCreateFromClip;
  201. lpDllTable[0].Link = PbCreateLinkFromClip;
  202. lpDllTable[0].Create = PbCreate;
  203. lpDllTable[0].CreateFromTemplate = PbCreateFromTemplate;
  204. lpDllTable[0].CreateFromFile = PbCreateFromFile;
  205. lpDllTable[0].CreateLinkFromFile = PbCreateLinkFromFile;
  206. lpDllTable[0].CreateInvisible = PbCreateInvisible;
  207. // !!! END hack for pbrush
  208. // For ObjectSize API
  209. dllStream.lpstbl = (LPOLESTREAMVTBL) &dllStreamVtbl;
  210. dllStream.lpstbl->Put = DllPut;
  211. // add the atoms required.
  212. aStdDocName = GlobalAddAtom ((LPSTR)"StdDocumentName");
  213. aSave = GlobalAddAtom ((LPSTR)"Save");
  214. aChange = GlobalAddAtom ((LPSTR)"Change");
  215. aClose = GlobalAddAtom ((LPSTR)"Close");
  216. aSystem = GlobalAddAtom ((LPSTR)"System");
  217. aOle = GlobalAddAtom ((LPSTR)"OLEsystem");
  218. aPackage = GlobalAddAtom ((LPSTR) packageClass);
  219. // Used in work around for MSDraw bug
  220. aMSDraw = GlobalAddAtom ((LPSTR) "MSDraw");
  221. // clipboard document name atom
  222. aClipDoc = GlobalAddAtom ((LPSTR)"Clipboard");
  223. stdRender[0].aClass = GlobalAddAtom ("METAFILEPICT");
  224. stdRender[1].aClass = GlobalAddAtom ("DIB");
  225. stdRender[2].aClass = GlobalAddAtom ("BITMAP");
  226. stdRender[3].aClass = GlobalAddAtom ("ENHMETAFILE");
  227. SetMaxPixel();
  228. #ifdef WIN16 // begin WIN16
  229. if (wWinVer != 0x0003) {
  230. HANDLE hModule;
  231. if (hModule = GetModuleHandle ("KERNEL"))
  232. lpfnIsTask = GetProcAddress (hModule,
  233. (LPSTR) MAKELONG (ORD_IsTask, 0));
  234. }
  235. if (cbHeapSize != 0)
  236. UnlockData(0);
  237. #endif // end WIN16
  238. return 1;
  239. }
  240. //////////////////////////////////////////////////////////////////////////////
  241. //
  242. // VOID FAR PASCAL WEP (nParameter)
  243. //
  244. // Called just before the library is being unloaded. Delete all the atoms
  245. // added by this dll and also frees up all unloaded handler dlls.
  246. //
  247. // Arguments:
  248. //
  249. // nParameter - Termination code
  250. //
  251. // Returns:
  252. //
  253. // none
  254. //
  255. // Effects:
  256. //
  257. //////////////////////////////////////////////////////////////////////////////
  258. VOID FAR PASCAL WEP (int nParameter)
  259. {
  260. int i;
  261. Puts("LibExit");
  262. #ifdef WIN32 // begin WIN32
  263. UNREFERENCED_PARAMETER(nParameter);
  264. DEBUG_OUT ("---L&E DLL EXIT---\n",0)
  265. #endif // end WIN32
  266. // case when the DLLs are missing
  267. if (!bLibInit)
  268. return;
  269. #ifdef WIN16 // begin WIN16
  270. if (nParameter == WEP_SYSTEM_EXIT)
  271. DEBUG_OUT ("---L&E DLL EXIT on system exit---",0)
  272. else if (nParameter == WEP_FREE_DLL)
  273. DEBUG_OUT ("---L&E DLL EXIT---\n",0)
  274. else
  275. return;
  276. #endif // end WIN16
  277. // Delete atoms added by us
  278. for (i = 0; i < NUM_RENDER; i++) {
  279. if (stdRender[i].aClass)
  280. GlobalDeleteAtom (stdRender[i].aClass);
  281. }
  282. if (aStdDocName)
  283. GlobalDeleteAtom (aStdDocName);
  284. if (aSave)
  285. GlobalDeleteAtom (aSave);
  286. if (aChange)
  287. GlobalDeleteAtom (aChange);
  288. if (aClose)
  289. GlobalDeleteAtom (aClose);
  290. if (aSystem)
  291. GlobalDeleteAtom (aSystem);
  292. if (aOle)
  293. GlobalDeleteAtom (aOle);
  294. if (aPackage)
  295. GlobalDeleteAtom (aPackage);
  296. if (aClipDoc)
  297. GlobalDeleteAtom (aClipDoc);
  298. if (aMSDraw)
  299. GlobalDeleteAtom (aMSDraw);
  300. // Free handler dlls if there are any still loaded. Entry 0 is used for
  301. // Pbrush handler which is part of this dll.
  302. for (i = 0; i <= iLast; i++) {
  303. if (lpDllTable[i].aDll)
  304. GlobalDeleteAtom (lpDllTable[i].aDll);
  305. if (lpDllTable[i].hDll)
  306. FreeLibrary (lpDllTable[i].hDll);
  307. }
  308. #ifdef FIREWALLS
  309. ASSERT(!lpHeadDoc, "Some client doc structures are not deleted");
  310. ASSERT(!lockDoc.lpHeadObj, "Some servers are left in a locked state");
  311. #endif
  312. /* !!! Add this when bug in WEP is fixed
  313. if (lpDllTable)
  314. GlobalUnlock (hDllTable);
  315. if (hDllTable)
  316. GlobalFree (hDllTable);
  317. */
  318. }
  319. //////////////////////////////////////////////////////////////////////////////
  320. //
  321. // void FARINTERNAL SetOleFlags()
  322. //
  323. // Sets the debug level flags for controlling the level of debug information
  324. // on the comm terminal. This will be included only in the debug version.
  325. //
  326. // Arguments:
  327. //
  328. // none
  329. //
  330. // Returns:
  331. //
  332. // none
  333. //
  334. // Effects:
  335. //
  336. //////////////////////////////////////////////////////////////////////////////
  337. #ifdef FIREWALLS
  338. void FARINTERNAL SetOleFlags()
  339. {
  340. char buffer[80];
  341. if(GetProfileString ("OLE",
  342. "Puts","", (LPSTR)buffer, 80))
  343. ole_flags = DEBUG_PUTS;
  344. else
  345. ole_flags = 0;
  346. if(GetProfileString ("OLE",
  347. "DEBUG_OUT","", (LPSTR)buffer, 80))
  348. ole_flags |= DEBUG_DEBUG_OUT;
  349. if(GetProfileString ("OLE",
  350. "MESSAGEBOX","", (LPSTR)buffer, 80))
  351. ole_flags |= DEBUG_MESSAGEBOX;
  352. }
  353. //////////////////////////////////////////////////////////////////////////////
  354. //
  355. // void FARINTERNAL ShowVersion (void)
  356. //
  357. // Displays version, date, time and copyright info in client app's window.
  358. // Called by all the object create functions after checking the flag bShowed.
  359. // This will be included only in the debug version.
  360. //
  361. // Arguments:
  362. //
  363. // none
  364. //
  365. // Returns:
  366. //
  367. // none
  368. //
  369. // Effects:
  370. //
  371. // sets bShowed
  372. //
  373. //////////////////////////////////////////////////////////////////////////////
  374. void FARINTERNAL ShowVersion ()
  375. {
  376. if (!bShowed && (ole_flags & DEBUG_MESSAGEBOX)) {
  377. MessageBox (NULL, "\
  378. VER: 1.09.000\n\
  379. TIME: 00:00:00\n\
  380. DATE: 02/01/1992\n\
  381. Copyright (c) 1990, 1991 Microsoft Corp.\n\
  382. All Rights Reserved.",
  383. "Ole Client Library",
  384. MB_OK | MB_TASKMODAL);
  385. bShowed = TRUE;
  386. }
  387. }
  388. #endif
  389. int FARINTERNAL LoadDll (LPCSTR lpClass)
  390. {
  391. char str[MAX_STR];
  392. char str1[MAX_STR];
  393. ATOM aDll = (ATOM)0;
  394. int index;
  395. int iEmpty;
  396. BOOL found = FALSE;
  397. HANDLE hDll;
  398. #ifdef WIN16
  399. int refcnt;
  400. #endif
  401. LONG cb = MAX_STR;
  402. if (!lstrcmpi (lpClass, "Pbrush"))
  403. return 0;
  404. lstrcpy (str, lpClass);
  405. lstrcat (str, "\\protocol\\StdFileEditing\\handler32");
  406. if (RegQueryValue (HKEY_CLASSES_ROOT, str, str1, &cb))
  407. return INVALID_INDEX;
  408. if (aDll = GlobalFindAtom (str1)) {
  409. for (index = 1; index <= iLast; index++) {
  410. if (lpDllTable[index].aDll == aDll) { // Dll already loaded
  411. lpDllTable[index].cObj ++;
  412. if (index == iUnloadableDll) {
  413. // since the object count is not zero anymore, this
  414. // handler can not be freed up.
  415. iUnloadableDll = 0;
  416. }
  417. return index;
  418. }
  419. }
  420. }
  421. aDll = GlobalAddAtom (str1);
  422. // Look for an empty entry
  423. for (iEmpty = 1; iEmpty <= iLast; iEmpty++) {
  424. if (!lpDllTable[iEmpty].aDll) {
  425. found = TRUE;
  426. break;
  427. }
  428. }
  429. if (iEmpty > iMax)
  430. goto errLoad;
  431. /*
  432. if (!found) {// no empty entry exists create a new one if necessary.
  433. if (iEmpty > iMax) {
  434. dllTableSize += (blockSize = NUM_DLL * sizeof(DLL_ENTRY));
  435. hTable = GlobalReAlloc (hDllTable, dllTableSize,
  436. GMEM_MOVEABLE | GMEM_ZEROINIT);
  437. if (hTable == hDllTable)
  438. iMax += NUM_DLL;
  439. else {
  440. dllTableSize -= blockSize;
  441. iEmpty = INVALID_INDEX;
  442. }
  443. }
  444. }
  445. */
  446. #ifdef WIN16
  447. // !!! reference count of OLECLI is increasing by 2 when the handlers are
  448. // are loaded, looks like windows bug. Following is a temporary fix.
  449. refcnt = GetModuleUsage (hModule);
  450. hDll = LoadLibrary ((LPSTR) str1);
  451. refcnt = (GetModuleUsage (hModule) - refcnt);
  452. while (refcnt > 1) {
  453. FreeModule (hModule);
  454. refcnt--;
  455. }
  456. #endif
  457. #ifdef WIN32
  458. hDll = LoadLibrary ((LPSTR) str1);
  459. #endif
  460. if (MAPVALUE(hDll < 32, !hDll))
  461. goto errLoad;
  462. if (!(lpDllTable[iEmpty].Load = (_LOAD)GetProcAddress(hDll,
  463. "DllLoadFromStream")))
  464. goto errLoad;
  465. if (!(lpDllTable[iEmpty].Clip = (_CLIP)GetProcAddress (hDll,
  466. "DllCreateFromClip")))
  467. goto errLoad;
  468. if (!(lpDllTable[iEmpty].Link = (_LINK)GetProcAddress (hDll,
  469. "DllCreateLinkFromClip")))
  470. goto errLoad;
  471. if (!(lpDllTable[iEmpty].CreateFromTemplate = (_CREATEFROMTEMPLATE)
  472. GetProcAddress (hDll,
  473. "DllCreateFromTemplate")))
  474. goto errLoad;
  475. if (!(lpDllTable[iEmpty].Create = (_CREATE)GetProcAddress (hDll,
  476. "DllCreate")))
  477. goto errLoad;
  478. if (!(lpDllTable[iEmpty].CreateFromFile = (_CREATEFROMFILE)GetProcAddress (hDll,
  479. "DllCreateFromFile")))
  480. goto errLoad;
  481. if (!(lpDllTable[iEmpty].CreateLinkFromFile = (_CREATELINKFROMFILE)GetProcAddress (hDll,
  482. "DllCreateLinkFromFile")))
  483. goto errLoad;
  484. lpDllTable[iEmpty].CreateInvisible = (_CREATEINVISIBLE)GetProcAddress (hDll,
  485. "DllCreateInvisible");
  486. lpDllTable[iEmpty].aDll = aDll;
  487. lpDllTable[iEmpty].cObj = 1;
  488. lpDllTable[iEmpty].hDll = hDll;
  489. if (iEmpty > iLast)
  490. iLast++;
  491. return iEmpty;
  492. errLoad:
  493. if (aDll)
  494. GlobalDeleteAtom (aDll);
  495. if (MAPVALUE(hDll >= 32, !hDll))
  496. FreeLibrary (hDll);
  497. return INVALID_INDEX;
  498. }
  499. // unload the the handler that can be free up (whose object count is NULL)
  500. void FARINTERNAL UnloadDll ()
  501. {
  502. if (!iUnloadableDll)
  503. return;
  504. if (iUnloadableDll == iLast)
  505. iLast--;
  506. if (lpDllTable[iUnloadableDll].aDll)
  507. GlobalDeleteAtom (lpDllTable[iUnloadableDll].aDll);
  508. lpDllTable[iUnloadableDll].aDll = (ATOM)0;
  509. FreeLibrary (lpDllTable[iUnloadableDll].hDll);
  510. lpDllTable[iUnloadableDll].hDll = NULL;
  511. iUnloadableDll = 0;
  512. }
  513. //
  514. // Reduce the object count of the handler, refered to by the index, by one.
  515. // If the object count becomes NULL, free up the handler that is ready to be
  516. // freed (refered to by index iUnloadableDll), and then make this handler the
  517. // freeable one.
  518. //
  519. // As you can see we are trying to implement a simple mechanism of caching.
  520. //
  521. void FARINTERNAL DecreaseHandlerObjCount (int iTable)
  522. {
  523. if (!iTable)
  524. return;
  525. if (iTable != INVALID_INDEX) {
  526. ASSERT (lpDllTable[iTable].cObj, "Handler Obj count is already NULL");
  527. if (!--lpDllTable[iTable].cObj) {
  528. UnloadDll ();
  529. iUnloadableDll = iTable;
  530. }
  531. }
  532. }
  533. /***************************** Public Function ****************************\
  534. *
  535. * OLESTATUS FARINTERNAL CreatePictFromClip (lpclient, lhclientdoc, lpobjname, lplpoleobject, optRender, cfFormat, lpClass, ctype)
  536. *
  537. * CreatePictFromClip: This function creates the LP to an object
  538. * from the clipboard. It will try to create a static picture object if
  539. * it understands any rendering formats on the clipboard. Currently, it
  540. * understands only bitmaps and metafiles.
  541. *
  542. * Effects:
  543. *
  544. * History:
  545. * Wrote it.
  546. \***************************************************************************/
  547. OLESTATUS FARINTERNAL CreatePictFromClip (
  548. LPOLECLIENT lpclient,
  549. LHCLIENTDOC lhclientdoc,
  550. LPSTR lpobjname,
  551. LPOLEOBJECT FAR * lplpobj,
  552. OLEOPT_RENDER optRender,
  553. OLECLIPFORMAT cfFormat,
  554. LPSTR lpClass,
  555. LONG objType
  556. ){
  557. OLESTATUS retVal = OLE_ERROR_OPTION;
  558. *lplpobj = NULL;
  559. if (optRender == olerender_none)
  560. return OLE_OK;
  561. else if (optRender == olerender_format) {
  562. switch (cfFormat) {
  563. case 0:
  564. return OLE_ERROR_FORMAT;
  565. case CF_ENHMETAFILE:
  566. return EmfPaste (lpclient, lhclientdoc, lpobjname,
  567. lplpobj, objType);
  568. case CF_METAFILEPICT:
  569. return MfPaste (lpclient, lhclientdoc, lpobjname,
  570. lplpobj, objType);
  571. case CF_DIB:
  572. return DibPaste (lpclient, lhclientdoc, lpobjname,
  573. lplpobj, objType);
  574. case CF_BITMAP:
  575. return BmPaste (lpclient, lhclientdoc, lpobjname,
  576. lplpobj, objType);
  577. default:
  578. return GenPaste (lpclient, lhclientdoc, lpobjname, lplpobj,
  579. lpClass, cfFormat, objType);
  580. }
  581. }
  582. else if (optRender == olerender_draw) {
  583. cfFormat = (OLECLIPFORMAT)EnumClipboardFormats (0);
  584. while ((cfFormat) && (retVal > OLE_WAIT_FOR_RELEASE)) {
  585. switch (cfFormat) {
  586. case CF_ENHMETAFILE:
  587. retVal = EmfPaste (lpclient, lhclientdoc, lpobjname,
  588. lplpobj, objType);
  589. break;
  590. case CF_METAFILEPICT:
  591. retVal = MfPaste (lpclient, lhclientdoc,
  592. lpobjname, lplpobj, objType);
  593. break;
  594. case CF_DIB:
  595. retVal = DibPaste (lpclient, lhclientdoc,
  596. lpobjname, lplpobj, objType);
  597. break;
  598. case CF_BITMAP:
  599. retVal = BmPaste (lpclient, lhclientdoc,
  600. lpobjname, lplpobj, objType);
  601. break;
  602. }
  603. cfFormat = (OLECLIPFORMAT)EnumClipboardFormats (cfFormat);
  604. }
  605. }
  606. return retVal;
  607. }
  608. OLESTATUS FARINTERNAL CreatePackageFromClip (
  609. LPOLECLIENT lpclient,
  610. LHCLIENTDOC lhclientdoc,
  611. LPSTR lpobjname,
  612. LPOLEOBJECT FAR * lplpobj,
  613. OLEOPT_RENDER optRender,
  614. OLECLIPFORMAT cfFormat,
  615. LONG objType
  616. ){
  617. char file[MAX_STR+6];
  618. HANDLE hData;
  619. LPSTR lpFileName;
  620. if (!(hData = GetClipboardData (cfFileName))
  621. || !(lpFileName = GlobalLock (hData)))
  622. return OLE_ERROR_CLIPBOARD;
  623. if (objType == OT_LINK) {
  624. lstrcpy (file, lpFileName);
  625. lstrcat (file, "/Link");
  626. lpFileName = (LPSTR) file;
  627. }
  628. GlobalUnlock (hData);
  629. return CreateEmbLnkFromFile (lpclient, packageClass, lpFileName,
  630. NULL, lhclientdoc, lpobjname, lplpobj,
  631. optRender, cfFormat, OT_EMBEDDED);
  632. }
  633. void FARINTERNAL RemoveLinkStringFromTopic (
  634. LPOBJECT_LE lpobj
  635. ){
  636. char buf[MAX_STR+6];
  637. int i = 0;
  638. if (GlobalGetAtomName (lpobj->topic, buf, sizeof(buf))) {
  639. // scan the topic for "/Link"
  640. while (buf[i] != '/') {
  641. if (!buf[i])
  642. return;
  643. i++;
  644. }
  645. buf[i] = '\0';
  646. if (lpobj->topic)
  647. GlobalDeleteAtom (lpobj->topic);
  648. lpobj->topic = GlobalAddAtom (buf);
  649. }
  650. }
  651. void SetMaxPixel ()
  652. {
  653. HDC hdc;
  654. // find out the pixel equivalent of MAX_HIMETRIC in X and Y directions
  655. if (hdc = GetDC (NULL)) {
  656. maxPixelsX = MulDiv (MAX_HIMETRIC, GetDeviceCaps(hdc, LOGPIXELSX),
  657. 2540);
  658. maxPixelsY = MulDiv (MAX_HIMETRIC, GetDeviceCaps(hdc, LOGPIXELSY),
  659. 2540);
  660. ReleaseDC (NULL, hdc);
  661. }
  662. }