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.

541 lines
11 KiB

  1. /*****************************************************************************
  2. V I R T U A L C L I P B O A R D
  3. Name: vclpbrd.c
  4. Date: 21-Jan-1994
  5. Creator: Unknown
  6. Description:
  7. This file contains the virtual clipboard routines.
  8. History:
  9. 21-Jan-1994 John Fu Reformat and cleanup
  10. 19-Apr-1994 John Fu Add code for DIB to BITMAP conversion.
  11. 13-Mar-1995 John Fu Fix code to delete clipboard formats.
  12. *****************************************************************************/
  13. #define WIN31
  14. #include <windows.h>
  15. #include "common.h"
  16. #include "clipbook.h"
  17. #include "clipbrd.h"
  18. #include "vclpbrd.h"
  19. #include "clipdsp.h"
  20. #include "ddeml.h"
  21. #include "debugout.h"
  22. #include "cvutil.h"
  23. /*
  24. * CreateVClipboard
  25. */
  26. PVCLPBRD CreateVClipboard (
  27. HWND hwnd)
  28. {
  29. PVCLPBRD p;
  30. if ( !( p = (PVCLPBRD)GlobalAlloc ( GPTR, sizeof(VCLPBRD) )))
  31. {
  32. PERROR(TEXT("CreateVClipboard returning 0\n\r"));
  33. return NULL;
  34. }
  35. p->NumFormats = 0;
  36. p->Head = (PVCLPENTRY)NULL;
  37. p->Tail = (PVCLPENTRY)NULL;
  38. p->fOpen = FALSE;
  39. p->Hwnd = hwnd;
  40. // PINFO(TEXT("CreateVClipboard OK\n\r"));
  41. return p;
  42. }
  43. /*
  44. * DestroyVClipboard
  45. */
  46. BOOL DestroyVClipboard (
  47. PVCLPBRD p)
  48. {
  49. if (!p)
  50. {
  51. PERROR(TEXT("DestroyVClipboard on NULL Vclipboard\n\r"));
  52. return FALSE;
  53. }
  54. if (VEmptyClipboard ( p ) == FALSE)
  55. {
  56. PERROR(TEXT("DestroyVClipboard: couldn't empty Vclipboard\n\r"));
  57. return FALSE;
  58. }
  59. if (GlobalFree ( (HGLOBAL)p ))
  60. {
  61. PERROR(TEXT("DestroyVClipboard: GlobalFree failure\n\r"));
  62. return FALSE;
  63. }
  64. // PINFO(TEXT("DestroyVClipboard OK\n\r"));
  65. return TRUE;
  66. }
  67. /*
  68. * VCountClipboardFormats
  69. */
  70. int VCountClipboardFormats (
  71. PVCLPBRD p)
  72. {
  73. if ( !p )
  74. return CountClipboardFormats();
  75. return p->NumFormats;
  76. }
  77. /*
  78. * VEmptyClipboard
  79. */
  80. BOOL VEmptyClipboard (
  81. PVCLPBRD p)
  82. {
  83. PVCLPENTRY q, tmp;
  84. if ( !p )
  85. return EmptyClipboard();
  86. for ( q = p->Head; q; )
  87. {
  88. tmp = q->Next;
  89. if ( q->Data )
  90. switch ( q->Fmt )
  91. {
  92. case CF_BITMAP:
  93. case CF_DIB:
  94. case CF_PALETTE:
  95. DeleteObject ( q->Data );
  96. break;
  97. case CF_METAFILEPICT:
  98. case CF_ENHMETAFILE:
  99. DeleteEnhMetaFile (q->Data);
  100. break;
  101. default:
  102. GlobalFree ( q->Data );
  103. }
  104. GlobalFree ( (HGLOBAL)q );
  105. q = tmp;
  106. }
  107. p->NumFormats = 0;
  108. return TRUE;
  109. }
  110. /*
  111. * VEnumClipboardFormats
  112. */
  113. UINT VEnumClipboardFormats(
  114. PVCLPBRD p,
  115. UINT Fmt)
  116. {
  117. PVCLPENTRY q;
  118. if ( !p )
  119. return EnumClipboardFormats ( Fmt );
  120. if ( !p->fOpen )
  121. return 0;
  122. if ( Fmt == 0 )
  123. return (p->Head)->Fmt;
  124. for (q = p->Head; q; q = q->Next)
  125. if ( q->Fmt == Fmt )
  126. {
  127. if ( q->Next )
  128. return q->Next->Fmt;
  129. else
  130. return 0;
  131. }
  132. return 0;
  133. }
  134. /*
  135. * VGetClipboardData
  136. */
  137. HANDLE VGetClipboardData (
  138. PVCLPBRD pvclp,
  139. UINT Fmt )
  140. {
  141. PVCLPENTRY pEntry;
  142. HSZ hszFmt;
  143. TCHAR szFmt[CCHMAXCLPFORMAT];
  144. HDDEDATA hFmtData;
  145. HANDLE hClipData;
  146. DWORD dwR;
  147. PINFO(TEXT("VGetClpData: %ld %d, "), pvclp, Fmt);
  148. if ( !pvclp )
  149. {
  150. if (IsClipboardFormatAvailable( Fmt ))
  151. {
  152. hClipData = GetClipboardData ( Fmt );
  153. if (!hClipData)
  154. dwR = GetLastError();
  155. return hClipData;
  156. }
  157. else
  158. {
  159. PINFO(TEXT("No data on clp\r\n"));
  160. return NULL;
  161. }
  162. }
  163. if ( !pvclp->fOpen )
  164. {
  165. PERROR(TEXT("!pvclp->fOpen\r\n"));
  166. return NULL;
  167. }
  168. for ( pEntry = pvclp->Head; pEntry; pEntry = pEntry->Next )
  169. {
  170. if ( pEntry->Fmt == Fmt )
  171. {
  172. if ( pEntry->Data )
  173. {
  174. // PINFO(TEXT("pEntry->Data\r\n"));
  175. }
  176. else
  177. {
  178. // if (LockApp(TRUE, szGettingData ))
  179. // {
  180. // this is the biggie...
  181. GetClipboardName (Fmt, szFmt, sizeof (szFmt));
  182. PINFO(TEXT("Asking for %s.\r\n"),szFmt);
  183. if (hszFmt = DdeCreateStringHandle(idInst, szFmt, 0))
  184. {
  185. hFmtData = MySyncXact (NULL,
  186. 0L,
  187. GETMDIINFO(pvclp->Hwnd)->hVClpConv,
  188. hszFmt,
  189. MyGetFormat (szFmt, GETFORMAT_LIE),
  190. XTYP_REQUEST,
  191. LONG_SYNC_TIMEOUT,
  192. NULL);
  193. if ( hFmtData )
  194. {
  195. PINFO(TEXT("Got it\r\n"));
  196. SetClipboardFormatFromDDE(pvclp->Hwnd, Fmt, hFmtData);
  197. }
  198. else
  199. {
  200. PERROR(TEXT("REQUEST for %s failed %x\n\r"),
  201. szFmt, DdeGetLastError(idInst));
  202. VSetClipboardData(pvclp, Fmt, INVALID_HANDLE_VALUE);
  203. // LockApp ( FALSE, szNull );
  204. // MessageBoxID ( hInst, hwndApp, IDS_DATAUNAVAIL,
  205. // IDS_APPNAME, MB_OK | MB_ICONEXCLAMATION );
  206. }
  207. DdeFreeStringHandle(idInst, hszFmt);
  208. // can't find bitmap, see if we can get it from dib
  209. if (!hFmtData && Fmt == CF_BITMAP)
  210. {
  211. GetClipboardName (CF_DIB, szFmt, sizeof(szFmt));
  212. if (hszFmt = DdeCreateStringHandle (idInst, szFmt, 0))
  213. {
  214. hFmtData = MySyncXact (NULL,
  215. 0L,
  216. GETMDIINFO(pvclp->Hwnd)->hVClpConv,
  217. hszFmt,
  218. MyGetFormat (szFmt, GETFORMAT_LIE),
  219. XTYP_REQUEST,
  220. LONG_SYNC_TIMEOUT,
  221. NULL);
  222. if (hFmtData)
  223. SetClipboardFormatFromDDE(pvclp->Hwnd, DDE_DIB2BITMAP, hFmtData);
  224. DdeFreeStringHandle(idInst, hszFmt);
  225. }
  226. }
  227. // }
  228. // LockApp ( FALSE, szNull );
  229. }
  230. else
  231. {
  232. PERROR(TEXT("app locked in vgetclipboarddata\n\r"));
  233. }
  234. }
  235. break;
  236. }
  237. }
  238. return (pEntry ?
  239. (INVALID_HANDLE_VALUE == pEntry->Data? NULL: pEntry->Data):
  240. NULL);
  241. }
  242. /*
  243. * VIsClipboardFormatAvailable
  244. */
  245. BOOL VIsClipboardFormatAvailable (
  246. PVCLPBRD p,
  247. UINT Fmt )
  248. {
  249. PVCLPENTRY q;
  250. if ( !p )
  251. {
  252. return IsClipboardFormatAvailable ( Fmt );
  253. }
  254. else
  255. {
  256. for ( q = p->Head; q; q = q->Next )
  257. {
  258. if ( q->Fmt == Fmt )
  259. {
  260. return TRUE;
  261. }
  262. }
  263. }
  264. return FALSE;
  265. }
  266. /*
  267. * VSetClipboardData
  268. */
  269. HANDLE VSetClipboardData(
  270. PVCLPBRD p,
  271. UINT Fmt,
  272. HANDLE Data)
  273. {
  274. PVCLPENTRY q;
  275. if ( !p )
  276. {
  277. PINFO(TEXT("Setting real clipboard data \r\n"));
  278. return SetClipboardData ( Fmt, Data );
  279. }
  280. if ( !p->fOpen )
  281. {
  282. PERROR(TEXT("VSetClipboardData on non-open Vclipboard\n\r"));
  283. return NULL;
  284. }
  285. // existing format?
  286. for ( q = p->Head; q; q = q->Next )
  287. {
  288. if (q->Fmt == Fmt)
  289. {
  290. if (q->Data)
  291. {
  292. switch (Fmt)
  293. {
  294. case CF_BITMAP:
  295. case CF_DIB:
  296. case CF_PALETTE:
  297. DeleteObject ( q->Data );
  298. break;
  299. case CF_METAFILEPICT:
  300. case CF_ENHMETAFILE:
  301. DeleteEnhMetaFile (q->Data);
  302. break;
  303. default:
  304. GlobalFree ( q->Data );
  305. }
  306. }
  307. q->Data = Data;
  308. PINFO(TEXT("VSetClipboardData: set same as existing format\n\r"));
  309. return Data;
  310. }
  311. }
  312. if (!(q = (PVCLPENTRY)GlobalAlloc (GPTR, sizeof (VCLPENTRY))))
  313. {
  314. PERROR(TEXT("VSetClipboardData: GlobalAlloc failed\n\r"));
  315. return NULL;
  316. }
  317. q->Next = NULL;
  318. q->Data = Data;
  319. q->Fmt = Fmt;
  320. if ( p->Tail )
  321. {
  322. p->Tail->Next = q;
  323. }
  324. p->Tail = q;
  325. if ( !p->Head )
  326. p->Head = q;
  327. p->NumFormats++;
  328. PINFO(TEXT("VSetClipboardData: set new format w/%ldn\r"), Data);
  329. return Data;
  330. }
  331. /*
  332. * VOpenClipboard
  333. */
  334. BOOL VOpenClipboard(
  335. PVCLPBRD p,
  336. HWND hwnd)
  337. {
  338. if ( !p )
  339. {
  340. return SyncOpenClipboard ( hwnd );
  341. }
  342. else if ( p->fOpen )
  343. {
  344. return FALSE;
  345. }
  346. else
  347. {
  348. p->fOpen = TRUE;
  349. p->Hwnd = hwnd;
  350. return TRUE;
  351. }
  352. }
  353. /*
  354. * VCloseClipboard
  355. */
  356. BOOL VCloseClipboard(
  357. PVCLPBRD p)
  358. {
  359. if ( !p )
  360. return SyncCloseClipboard();
  361. if ( !p->fOpen )
  362. return FALSE;
  363. p->fOpen = FALSE;
  364. p->Hwnd = (HWND)0;
  365. return TRUE;
  366. }