Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

790 lines
23 KiB

  1. /*++
  2. * File name:
  3. * clputil.c
  4. * Contents:
  5. * Clipboard functions
  6. *
  7. * Copyright (C) 1998-1999 Microsoft Corp.
  8. --*/
  9. #include <windows.h>
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <io.h>
  13. #include <fcntl.h>
  14. #include <sys/stat.h>
  15. #pragma warning(disable:4706) // assignment within conditional expression
  16. #ifdef _CLPUTIL
  17. enum {ERROR_MESSAGE = 0, WARNING_MESSAGE, INFO_MESSAGE, ALIVE_MESSAGE};
  18. #define TRACE(_x_) LocalPrintMessage _x_
  19. #else // !_CLPUTIL
  20. #include "protocol.h"
  21. /*
  22. * Externals
  23. */
  24. extern void (__cdecl *g_pfnPrintMessage) (MESSAGETYPE, LPCSTR, ...);
  25. #define TRACE(_x_) if (g_pfnPrintMessage) {\
  26. g_pfnPrintMessage(INFO_MESSAGE, "Worker:%d ", GetCurrentThreadId());\
  27. g_pfnPrintMessage _x_; }
  28. #endif // !_CLPUTIL
  29. typedef struct _CLIPBOARDFORMATS {
  30. UINT uiFormat;
  31. LPCSTR szFormat;
  32. } CLIPBOARDFORMATS, *PCLIPBOARDFORMATS;
  33. const CLIPBOARDFORMATS KnownFormats[] =
  34. {
  35. {CF_TEXT, "Text"},
  36. {CF_BITMAP, "Bitmap"},
  37. {CF_METAFILEPICT, "MetaFile"},
  38. {CF_SYLK, "Sylk"},
  39. {CF_DIF, "DIF"},
  40. {CF_TIFF, "TIFF"},
  41. {CF_OEMTEXT, "OEMText"},
  42. {CF_DIB, "DIB"},
  43. {CF_PALETTE, "Palette"},
  44. {CF_PENDATA, "PenData"},
  45. {CF_RIFF, "Riff"},
  46. {CF_WAVE, "Wave"},
  47. {CF_UNICODETEXT,"Unicode"},
  48. {CF_ENHMETAFILE,"ENHMetafile"},
  49. {CF_HDROP, "HDROP"},
  50. {CF_LOCALE, "Locale"},
  51. {CF_DIBV5, "DIBV5"}
  52. };
  53. typedef struct {
  54. UINT32 mm;
  55. UINT32 xExt;
  56. UINT32 yExt;
  57. } CLIPBOARD_MFPICT, *PCLIPBOARD_MFPICT;
  58. /*
  59. * Clipboard functions definitions
  60. */
  61. VOID
  62. Clp_ListAllFormats(VOID);
  63. //VOID
  64. //Clp_ListAllAvailableFormats(VOID);
  65. UINT
  66. Clp_GetClipboardFormat(LPCSTR szFormatLookup);
  67. VOID
  68. Clp_PutIntoClipboard(CHAR *g_szFileName);
  69. VOID
  70. Clp_GetClipboardData(
  71. UINT format,
  72. HGLOBAL hClipData,
  73. INT *pnClipDataSize,
  74. HGLOBAL *phNewData);
  75. BOOL
  76. Clp_SetClipboardData(
  77. UINT formatID,
  78. HGLOBAL hClipData,
  79. INT nClipDataSize,
  80. BOOL *pbFreeHandle);
  81. HGLOBAL
  82. Clp_GetMFData(HANDLE hData,
  83. PUINT pDataLen);
  84. HGLOBAL
  85. Clp_SetMFData(UINT dataLen,
  86. PVOID pData);
  87. VOID
  88. _cdecl LocalPrintMessage(INT errlevel, CHAR *format, ...);
  89. VOID
  90. Clp_ListAllFormats(VOID)
  91. {
  92. UINT format = 0;
  93. CHAR szFormatName[_MAX_PATH];
  94. while ((format = EnumClipboardFormats(format)))
  95. {
  96. *szFormatName = 0;
  97. GetClipboardFormatNameA(format, szFormatName, _MAX_PATH);
  98. if (!(*szFormatName))
  99. // No format, check for known format
  100. {
  101. INT fmti, fmtnum;
  102. fmtnum = sizeof(KnownFormats)/sizeof(KnownFormats[0]);
  103. for (fmti = 0;
  104. KnownFormats[fmti].uiFormat != format
  105. &&
  106. fmti < fmtnum;
  107. fmti ++);
  108. if (fmti < fmtnum)
  109. strcpy(szFormatName, KnownFormats[fmti].szFormat);
  110. }
  111. if (*szFormatName)
  112. {
  113. TRACE((INFO_MESSAGE, "%s[%d(0x%X)]\n", szFormatName, format, format));
  114. } else {
  115. TRACE((ERROR_MESSAGE, "Can't find format name for: 0x%x\n", format));
  116. }
  117. }
  118. }
  119. /*
  120. VOID
  121. Clp_ListAllAvailableFormats(VOID)
  122. {
  123. UINT format = 0;
  124. CHAR szFormatName[_MAX_PATH];
  125. while ((format = EnumClipboardFormats(format)))
  126. {
  127. if (!IsClipboardFormatAvailable(format))
  128. // Skip the unavalable formats
  129. continue;
  130. *szFormatName = 0;
  131. GetClipboardFormatName(format, szFormatName, _MAX_PATH);
  132. if (!(*szFormatName))
  133. // No format, check for known format
  134. {
  135. INT fmti, fmtnum;
  136. fmtnum = sizeof(KnownFormats)/sizeof(KnownFormats[0]);
  137. for (fmti = 0;
  138. KnownFormats[fmti].uiFormat != format
  139. &&
  140. fmti < fmtnum;
  141. fmti ++);
  142. if (fmti < fmtnum)
  143. strcpy(szFormatName, KnownFormats[fmti].szFormat);
  144. }
  145. if (*szFormatName)
  146. TRACE((INFO_MESSAGE, "%s\n", szFormatName));
  147. else
  148. TRACE((ERROR_MESSAGE, "Can't find format name for: 0x%x\n", format));
  149. }
  150. }
  151. */
  152. UINT
  153. Clp_GetClipboardFormat(LPCSTR szFormatLookup)
  154. // Returns the clipboard ID
  155. {
  156. UINT format = 0;
  157. CHAR szFormatName[_MAX_PATH];
  158. BOOL bFound = FALSE;
  159. *szFormatName = 0;
  160. while (!bFound && (format = EnumClipboardFormats(format)))
  161. {
  162. if (!IsClipboardFormatAvailable(format))
  163. // Skip the unavalable formats
  164. continue;
  165. *szFormatName = 0;
  166. GetClipboardFormatNameA(format, szFormatName, _MAX_PATH);
  167. if (!(*szFormatName))
  168. // No format, check for known format
  169. {
  170. INT fmti, fmtnum;
  171. fmtnum = sizeof(KnownFormats)/sizeof(KnownFormats[0]);
  172. for (fmti = 0;
  173. KnownFormats[fmti].uiFormat != format
  174. &&
  175. fmti < fmtnum;
  176. fmti ++);
  177. if (fmti < fmtnum)
  178. strcpy(szFormatName, KnownFormats[fmti].szFormat);
  179. }
  180. bFound = (_stricmp(szFormatName, szFormatLookup) == 0);
  181. }
  182. return format;
  183. }
  184. VOID
  185. Clp_PutIntoClipboard(CHAR *szFileName)
  186. {
  187. INT hFile = -1;
  188. LONG clplength = 0;
  189. UINT uiFormat = 0;
  190. HGLOBAL ghClipData = NULL;
  191. PBYTE pClipData = NULL;
  192. BOOL bClipboardOpen = FALSE;
  193. BOOL bFreeClipHandle = TRUE;
  194. hFile = _open(szFileName, _O_RDONLY|_O_BINARY);
  195. if (hFile == -1)
  196. {
  197. TRACE((ERROR_MESSAGE, "Error opening file: %s. errno=%d\n", szFileName, errno));
  198. goto exitpt;
  199. }
  200. clplength = _filelength(hFile) - sizeof(uiFormat);
  201. if (_read(hFile, &uiFormat, sizeof(uiFormat)) != sizeof(uiFormat))
  202. {
  203. TRACE((ERROR_MESSAGE, "Error reading from file. errno=%d\n", errno));
  204. goto exitpt;
  205. }
  206. ghClipData = GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE, clplength);
  207. if (!ghClipData)
  208. {
  209. TRACE((ERROR_MESSAGE, "Can't allocate %d bytes\n", clplength));
  210. goto exitpt;
  211. }
  212. pClipData = (PBYTE) GlobalLock(ghClipData);
  213. if (!pClipData)
  214. {
  215. TRACE((ERROR_MESSAGE, "Can't lock handle 0x%x\n", ghClipData));
  216. goto exitpt;
  217. }
  218. if (_read(hFile, pClipData, clplength) != clplength)
  219. {
  220. TRACE((ERROR_MESSAGE, "Error reading from file. errno=%d\n", errno));
  221. goto exitpt;
  222. }
  223. GlobalUnlock(ghClipData);
  224. if (!OpenClipboard(NULL))
  225. {
  226. TRACE((ERROR_MESSAGE, "Can't open the clipboard. GetLastError=%d\n",
  227. GetLastError()));
  228. goto exitpt;
  229. }
  230. bClipboardOpen = TRUE;
  231. // Empty the clipboard, so we'll have only one entry
  232. EmptyClipboard();
  233. if (!Clp_SetClipboardData(uiFormat, ghClipData, clplength, &bFreeClipHandle))
  234. {
  235. TRACE((ERROR_MESSAGE, "SetClipboardData failed.\n"));
  236. } else {
  237. TRACE((INFO_MESSAGE, "Clipboard is loaded successfuly. File: %s, %d bytes\n",
  238. szFileName,
  239. clplength));
  240. }
  241. exitpt:
  242. // Do the cleanup
  243. // Close the clipboard
  244. if (bClipboardOpen)
  245. CloseClipboard();
  246. // Release the clipboard handle
  247. if (pClipData)
  248. GlobalUnlock(ghClipData);
  249. if (ghClipData && bFreeClipHandle)
  250. GlobalFree(ghClipData);
  251. // Close the file
  252. if (hFile != -1)
  253. _close(hFile);
  254. }
  255. VOID
  256. Clp_GetClipboardData(
  257. UINT format,
  258. HGLOBAL hClipData,
  259. INT *pnClipDataSize,
  260. HGLOBAL *phNewData)
  261. {
  262. HGLOBAL hData = hClipData;
  263. UINT dataLen = 0;
  264. WORD numEntries;
  265. DWORD dwEntries;
  266. PVOID pData;
  267. *phNewData = NULL;
  268. *pnClipDataSize = 0;
  269. if (format == CF_PALETTE)
  270. {
  271. /****************************************************************/
  272. /* Find out how many entries there are in the palette and */
  273. /* allocate enough memory to hold them all. */
  274. /****************************************************************/
  275. if (GetObjectA(hData, sizeof(numEntries), (LPSTR)&numEntries) == 0)
  276. {
  277. numEntries = 256;
  278. }
  279. dataLen = sizeof(LOGPALETTE) +
  280. ((numEntries - 1) * sizeof(PALETTEENTRY));
  281. *phNewData = GlobalAlloc(GHND, dataLen);
  282. if (*phNewData == 0)
  283. {
  284. TRACE((ERROR_MESSAGE, "Failed to get %d bytes for palette", dataLen));
  285. goto exitpt;
  286. }
  287. else
  288. {
  289. /************************************************************/
  290. /* now get the palette entries into the new buffer */
  291. /************************************************************/
  292. pData = GlobalLock(*phNewData);
  293. dwEntries = (WORD)GetPaletteEntries((HPALETTE)hData,
  294. 0,
  295. numEntries,
  296. (PALETTEENTRY*)pData);
  297. GlobalUnlock(*phNewData);
  298. if (dwEntries == 0)
  299. {
  300. TRACE((ERROR_MESSAGE, "Failed to get any palette entries"));
  301. goto exitpt;
  302. }
  303. dataLen = dwEntries * sizeof(PALETTEENTRY);
  304. }
  305. } else if (format == CF_METAFILEPICT)
  306. {
  307. *phNewData = Clp_GetMFData(hData, &dataLen);
  308. if (!*phNewData)
  309. {
  310. TRACE((ERROR_MESSAGE, "Failed to set MF data"));
  311. goto exitpt;
  312. }
  313. } else {
  314. if (format == CF_DIB)
  315. {
  316. // Get the exact DIB size
  317. BITMAPINFOHEADER *pBMI = (BITMAPINFOHEADER *) GlobalLock(hData);
  318. if (pBMI)
  319. {
  320. if (pBMI->biSizeImage)
  321. dataLen = pBMI->biSize + pBMI->biSizeImage;
  322. GlobalUnlock(hData);
  323. }
  324. }
  325. /****************************************************************/
  326. /* just get the length of the block */
  327. /****************************************************************/
  328. if (!dataLen)
  329. dataLen = (DWORD)GlobalSize(hData);
  330. }
  331. *pnClipDataSize = dataLen;
  332. exitpt:
  333. ;
  334. }
  335. BOOL
  336. Clp_SetClipboardData(
  337. UINT formatID,
  338. HGLOBAL hClipData,
  339. INT nClipDataSize,
  340. BOOL *pbFreeHandle)
  341. {
  342. BOOL rv = FALSE;
  343. PVOID pData = NULL;
  344. HGLOBAL hData = NULL;
  345. LOGPALETTE *pLogPalette = NULL;
  346. UINT numEntries, memLen;
  347. if (!pbFreeHandle)
  348. goto exitpt;
  349. *pbFreeHandle = TRUE;
  350. if (formatID == CF_METAFILEPICT)
  351. {
  352. /********************************************************************/
  353. /* We have to put a handle to the metafile on the clipboard - which */
  354. /* means creating a metafile from the received data first */
  355. /********************************************************************/
  356. pData = GlobalLock(hClipData);
  357. if (!pData)
  358. {
  359. TRACE((ERROR_MESSAGE, "Failed to lock buffer\n"));
  360. goto exitpt;
  361. }
  362. hData = Clp_SetMFData(nClipDataSize, pData);
  363. if (!hData)
  364. {
  365. TRACE((ERROR_MESSAGE, "Failed to set MF data\n"));
  366. }
  367. else if (SetClipboardData(formatID, hData) != hData)
  368. {
  369. TRACE((ERROR_MESSAGE, "SetClipboardData. GetLastError=%d\n", GetLastError()));
  370. }
  371. GlobalUnlock(hClipData);
  372. } else if (formatID == CF_PALETTE)
  373. {
  374. /********************************************************************/
  375. /* We have to put a handle to the palette on the clipboard - again */
  376. /* this means creating one from the received data first */
  377. /* */
  378. /* Allocate memory for a LOGPALETTE structure large enough to hold */
  379. /* all the PALETTE ENTRY structures, and fill it in. */
  380. /********************************************************************/
  381. numEntries = (nClipDataSize / sizeof(PALETTEENTRY));
  382. memLen = (sizeof(LOGPALETTE) +
  383. ((numEntries - 1) * sizeof(PALETTEENTRY)));
  384. pLogPalette = (LOGPALETTE *) malloc(memLen);
  385. if (!pLogPalette)
  386. {
  387. TRACE((ERROR_MESSAGE, "Failed to get %d bytes", memLen));
  388. goto exitpt;
  389. }
  390. pLogPalette->palVersion = 0x300;
  391. pLogPalette->palNumEntries = (WORD)numEntries;
  392. /********************************************************************/
  393. /* get a pointer to the data and copy it to the palette */
  394. /********************************************************************/
  395. pData = GlobalLock(hClipData);
  396. if (pData == NULL)
  397. {
  398. TRACE((ERROR_MESSAGE, "Failed to lock buffer"));
  399. goto exitpt;
  400. }
  401. memcpy(pLogPalette->palPalEntry, pData, nClipDataSize);
  402. /********************************************************************/
  403. /* unlock the buffer */
  404. /********************************************************************/
  405. GlobalUnlock(hClipData);
  406. /********************************************************************/
  407. /* now create a palette */
  408. /********************************************************************/
  409. hData = CreatePalette(pLogPalette);
  410. if (!hData)
  411. {
  412. TRACE((ERROR_MESSAGE, "CreatePalette failed\n"));
  413. goto exitpt;
  414. }
  415. /********************************************************************/
  416. /* and set the palette handle to the Clipboard */
  417. /********************************************************************/
  418. if (SetClipboardData(formatID, hData) != hData)
  419. {
  420. TRACE((ERROR_MESSAGE, "SetClipboardData. GetLastError=%d\n", GetLastError()));
  421. }
  422. } else {
  423. /****************************************************************/
  424. /* Just set it onto the clipboard */
  425. /****************************************************************/
  426. if (SetClipboardData(formatID, hClipData) != hClipData)
  427. {
  428. TRACE((ERROR_MESSAGE, "SetClipboardData. GetLastError=%d, hClipData=0x%x\n", GetLastError(), hClipData));
  429. goto exitpt;
  430. }
  431. // Only in this case we don't need to free the handle
  432. *pbFreeHandle = FALSE;
  433. }
  434. rv = TRUE;
  435. exitpt:
  436. if (!pLogPalette)
  437. {
  438. free(pLogPalette);
  439. }
  440. return rv;
  441. }
  442. HGLOBAL Clp_GetMFData(HANDLE hData,
  443. PUINT pDataLen)
  444. {
  445. UINT lenMFBits = 0;
  446. BOOL rc = FALSE;
  447. LPMETAFILEPICT pMFP = NULL;
  448. HDC hMFDC = NULL;
  449. HMETAFILE hMF = NULL;
  450. // HGLOBAL hMFBits = NULL;
  451. HANDLE hNewData = NULL;
  452. CHAR *pNewData = NULL;
  453. // PVOID pBits = NULL;
  454. /************************************************************************/
  455. /* Lock the memory to get a pointer to a METAFILEPICT header structure */
  456. /* and create a METAFILEPICT DC. */
  457. /************************************************************************/
  458. pMFP = (LPMETAFILEPICT)GlobalLock(hData);
  459. if (pMFP == NULL)
  460. goto exitpt;
  461. hMFDC = CreateMetaFileA(NULL);
  462. if (hMFDC == NULL)
  463. goto exitpt;
  464. /************************************************************************/
  465. /* Copy the MFP by playing it into the DC and closing it. */
  466. /************************************************************************/
  467. if (!PlayMetaFile(hMFDC, pMFP->hMF))
  468. {
  469. CloseMetaFile(hMFDC);
  470. goto exitpt;
  471. }
  472. hMF = CloseMetaFile(hMFDC);
  473. if (hMF == NULL)
  474. goto exitpt;
  475. /************************************************************************/
  476. /* Get the MF bits and determine how long they are. */
  477. /************************************************************************/
  478. #ifdef OS_WIN16
  479. hMFBits = GetMetaFileBitsA(hMF);
  480. lenMFBits = GlobalSize(hMFBits);
  481. #else
  482. lenMFBits = GetMetaFileBitsEx(hMF, 0, NULL);
  483. #endif
  484. if (lenMFBits == 0)
  485. goto exitpt;
  486. /************************************************************************/
  487. /* Work out how much memory we need and get a buffer */
  488. /************************************************************************/
  489. *pDataLen = sizeof(CLIPBOARD_MFPICT) + lenMFBits;
  490. hNewData = GlobalAlloc(GHND, *pDataLen);
  491. if (hNewData == NULL)
  492. goto exitpt;
  493. pNewData = (char *) GlobalLock(hNewData);
  494. /************************************************************************/
  495. /* Copy the MF header and bits into the buffer. */
  496. /************************************************************************/
  497. ((PCLIPBOARD_MFPICT)pNewData)->mm = pMFP->mm;
  498. ((PCLIPBOARD_MFPICT)pNewData)->xExt = pMFP->xExt;
  499. ((PCLIPBOARD_MFPICT)pNewData)->yExt = pMFP->yExt;
  500. #ifdef OS_WIN16
  501. pBits = GlobalLock(hMFBits);
  502. memcpy((pNewData + sizeof(CLIPBOARD_MFPICT)),
  503. pBits,
  504. lenMFBits);
  505. GlobalUnlock(hMFBits);
  506. #else
  507. lenMFBits = GetMetaFileBitsEx(hMF, lenMFBits,
  508. (pNewData + sizeof(CLIPBOARD_MFPICT)));
  509. if (lenMFBits == 0)
  510. goto exitpt;
  511. #endif
  512. /************************************************************************/
  513. /* all OK */
  514. /************************************************************************/
  515. rc = TRUE;
  516. exitpt:
  517. /************************************************************************/
  518. /* Unlock any global mem. */
  519. /************************************************************************/
  520. if (pMFP)
  521. {
  522. GlobalUnlock(hData);
  523. }
  524. if (pNewData)
  525. {
  526. GlobalUnlock(hNewData);
  527. }
  528. /************************************************************************/
  529. /* if things went wrong, then free the new data */
  530. /************************************************************************/
  531. if ((rc == FALSE) && (hNewData != NULL))
  532. {
  533. GlobalFree(hNewData);
  534. hNewData = NULL;
  535. }
  536. return(hNewData);
  537. }
  538. HGLOBAL Clp_SetMFData(UINT dataLen,
  539. PVOID pData)
  540. {
  541. BOOL rc = FALSE;
  542. HGLOBAL hMFBits = NULL;
  543. PVOID pMFMem = NULL;
  544. HMETAFILE hMF = NULL;
  545. HGLOBAL hMFPict = NULL;
  546. LPMETAFILEPICT pMFPict = NULL;
  547. /************************************************************************/
  548. /* Allocate memory to hold the MF bits (we need the handle to pass to */
  549. /* SetMetaFileBits). */
  550. /************************************************************************/
  551. hMFBits = GlobalAlloc(GHND, dataLen - sizeof(CLIPBOARD_MFPICT));
  552. if (hMFBits == NULL)
  553. goto exitpt;
  554. /************************************************************************/
  555. /* Lock the handle and copy in the MF header. */
  556. /************************************************************************/
  557. pMFMem = GlobalLock(hMFBits);
  558. if (pMFMem == NULL)
  559. goto exitpt;
  560. memcpy(pMFMem,
  561. (PVOID)((CHAR *)pData + sizeof(CLIPBOARD_MFPICT)),
  562. dataLen - sizeof(CLIPBOARD_MFPICT) );
  563. GlobalUnlock(hMFBits);
  564. /************************************************************************/
  565. /* Now use the copied MF bits to create the actual MF bits and get a */
  566. /* handle to the MF. */
  567. /************************************************************************/
  568. #ifdef OS_WIN16
  569. hMF = SetMetaFileBits(hMFBits);
  570. #else
  571. hMF = SetMetaFileBitsEx(dataLen - sizeof(CLIPBOARD_MFPICT), (const BYTE *) pMFMem);
  572. #endif
  573. if (hMF == NULL)
  574. goto exitpt;
  575. /************************************************************************/
  576. /* Allocate a new METAFILEPICT structure, and use the data from the */
  577. /* header. */
  578. /************************************************************************/
  579. hMFPict = GlobalAlloc(GHND, sizeof(METAFILEPICT));
  580. pMFPict = (LPMETAFILEPICT)GlobalLock(hMFPict);
  581. if (!pMFPict)
  582. goto exitpt;
  583. pMFPict->mm = (long)((PCLIPBOARD_MFPICT)pData)->mm;
  584. pMFPict->xExt = (long)((PCLIPBOARD_MFPICT)pData)->xExt;
  585. pMFPict->yExt = (long)((PCLIPBOARD_MFPICT)pData)->yExt;
  586. pMFPict->hMF = hMF;
  587. GlobalUnlock(hMFPict);
  588. rc = TRUE;
  589. exitpt:
  590. /************************************************************************/
  591. /* tidy up */
  592. /************************************************************************/
  593. if (!rc)
  594. {
  595. if (hMFPict)
  596. {
  597. GlobalFree(hMFPict);
  598. }
  599. if (hMFBits)
  600. {
  601. GlobalFree(hMFBits);
  602. }
  603. }
  604. return(hMFPict);
  605. }
  606. BOOL
  607. Clp_EmptyClipboard(VOID)
  608. {
  609. BOOL rv = FALSE;
  610. if (OpenClipboard(NULL))
  611. {
  612. EmptyClipboard();
  613. rv = TRUE;
  614. CloseClipboard();
  615. }
  616. return rv;
  617. }
  618. BOOL
  619. Clp_CheckEmptyClipboard(VOID)
  620. {
  621. BOOL rv = TRUE;
  622. if (OpenClipboard(NULL))
  623. {
  624. if (EnumClipboardFormats(0))
  625. // format is available, not empty
  626. rv = FALSE;
  627. CloseClipboard();
  628. }
  629. return rv;
  630. }
  631. // Checks for known format names and returns it's ID
  632. UINT
  633. _GetKnownClipboardFormatIDByName(LPCSTR szFormatName)
  634. {
  635. INT fmti, fmtnum;
  636. UINT rv = 0;
  637. fmtnum = sizeof(KnownFormats)/sizeof(KnownFormats[0]);
  638. for (fmti = 0;
  639. fmti < fmtnum
  640. &&
  641. _stricmp(szFormatName, KnownFormats[fmti].szFormat);
  642. fmti ++)
  643. ;
  644. if (fmti < fmtnum)
  645. rv = KnownFormats[fmti].uiFormat;
  646. return rv;
  647. }
  648. VOID
  649. _cdecl LocalPrintMessage(INT errlevel, CHAR *format, ...)
  650. {
  651. CHAR szBuffer[256];
  652. CHAR *type;
  653. va_list arglist;
  654. INT nchr;
  655. va_start (arglist, format);
  656. nchr = _vsnprintf (szBuffer, sizeof(szBuffer), format, arglist);
  657. szBuffer[SIZEOF_ARRAY(szBuffer) - 1] = 0;
  658. va_end (arglist);
  659. switch(errlevel)
  660. {
  661. case INFO_MESSAGE: type = "INF"; break;
  662. case ALIVE_MESSAGE: type = "ALV"; break;
  663. case WARNING_MESSAGE: type = "WRN"; break;
  664. case ERROR_MESSAGE: type = "ERR"; break;
  665. default: type = "UNKNOWN";
  666. }
  667. printf("%s:%s", type, szBuffer);
  668. }