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.

512 lines
17 KiB

  1. #include <windows.h>
  2. #include <shellapi.h>
  3. #include "clipbrd.h"
  4. /*--------------------------------------------------------------------------*/
  5. /* */
  6. /* InitOwnerScrollInfo() - */
  7. /* */
  8. /*--------------------------------------------------------------------------*/
  9. void InitOwnerScrollInfo(
  10. void)
  11. {
  12. OwnVerPos = OwnHorPos = OwnVerMin = OwnHorMin = 0;
  13. OwnVerMax = VPOSLAST;
  14. OwnHorMax = HPOSLAST;
  15. }
  16. /*--------------------------------------------------------------------------*/
  17. /* */
  18. /* ClipbrdWndProc() - */
  19. /* */
  20. /*--------------------------------------------------------------------------*/
  21. LONG FAR PASCAL ClipbrdWndProc(register HWND hwnd,
  22. UINT message,register WPARAM wParam,LONG lParam)
  23. {
  24. int i;
  25. HDC hdc;
  26. UINT wNewFormat;
  27. UINT wOldFormat;
  28. HPALETTE hpal;
  29. HPALETTE hpalT;
  30. static INT UpdateCount = 0;
  31. switch (message)
  32. {
  33. case WM_RENDERALLFORMATS:
  34. /* When clipboard is cleared by user using EDIT-CLEAR command
  35. * we (clipboard viewer) become the owner and this results in
  36. * WM_RENDERALLFORMATS message when Clipbrd viewer is closed.
  37. * So, we should check if we have anything to render before
  38. * processing this message. Sankar
  39. */
  40. if (!CountClipboardFormats())
  41. break;
  42. /* Check if the clipbrd viewer has done any File I/O before.
  43. * If it has not, then it has nothing to render! Sankar
  44. */
  45. if (!fAnythingToRender)
  46. break;
  47. /* Empty the clipboard */
  48. if (!MyOpenClipboard(hwnd))
  49. break;
  50. EmptyClipboard();
  51. /*** FALL THRU ***/
  52. case WM_RENDERFORMAT:
  53. {
  54. INT fh;
  55. DWORD HeaderPos;
  56. FILEHEADER FileHeader;
  57. FORMATHEADER FormatHeader;
  58. WORD w;
  59. fh = (INT)CreateFile((LPCTSTR)szFileName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
  60. NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  61. FileHeader.FormatCount = 0; /* If _lread fails, we can detect */
  62. _lread(fh, (LPBYTE)&FileHeader, sizeof(FILEHEADER));
  63. HeaderPos = sizeof(FILEHEADER);
  64. for (w=0; w < FileHeader.FormatCount; w++)
  65. {
  66. _llseek(fh, HeaderPos, 0);
  67. if (fNTReadFileFormat) {
  68. if(_lread(fh, (LPBYTE)&(FormatHeader.FormatID), sizeof(FormatHeader.FormatID)) < sizeof(FormatHeader.FormatID))
  69. break;
  70. } else {
  71. FormatHeader.FormatID = 0; /* initialize the hight WORD */
  72. if(_lread(fh, (LPBYTE)&(FormatHeader.FormatID), sizeof(WORD)) < sizeof(WORD))
  73. break;
  74. }
  75. if(_lread(fh, (LPBYTE)&(FormatHeader.DataLen), sizeof(FormatHeader.DataLen)) < sizeof(FormatHeader.DataLen))
  76. break;
  77. if(_lread(fh, (LPBYTE)&(FormatHeader.DataOffset), sizeof(FormatHeader.DataOffset)) < sizeof(FormatHeader.DataOffset))
  78. break;
  79. if(_lread(fh, (LPBYTE)&(FormatHeader.Name), sizeof(FormatHeader.Name)) < sizeof(FormatHeader.Name))
  80. break;
  81. if (fNTReadFileFormat)
  82. HeaderPos += (sizeof(UINT) + 2*sizeof(DWORD) + CCHFMTNAMEMAX*sizeof(TCHAR));
  83. else
  84. HeaderPos += (sizeof(WORD) + 2*sizeof(DWORD) + CCHFMTNAMEMAX*sizeof(TCHAR));
  85. if (PRIVATE_FORMAT(FormatHeader.FormatID))
  86. FormatHeader.FormatID = (UINT)RegisterClipboardFormat(FormatHeader.Name);
  87. if ((message == WM_RENDERALLFORMATS) || (FormatHeader.FormatID == (UINT)wParam))
  88. RenderFormat(&FormatHeader, fh);
  89. }
  90. if (message == WM_RENDERALLFORMATS)
  91. CloseClipboard();
  92. _lclose(fh);
  93. break;
  94. }
  95. case WM_DESTROYCLIPBOARD:
  96. /* Prevent unnecessary file I/O when getting a WM_RENDERALLFORMATS */
  97. fAnythingToRender = FALSE;
  98. break;
  99. case WM_CREATE:
  100. hMainMenu = GetMenu(hwnd);
  101. /* Get the handle to the Display popup menu */
  102. hDispMenu = GetSubMenu(hMainMenu, 2);
  103. UpdateCBMenu(hwnd);
  104. break;
  105. case WM_COMMAND:
  106. switch (GET_WM_COMMAND_ID(wParam, lParam))
  107. {
  108. case CBM_CLEAR:
  109. ClearClipboard(hwnd);
  110. break;
  111. case CBM_EXIT:
  112. SendMessage(hwnd, WM_SYSCOMMAND, SC_CLOSE, 0L);
  113. break;
  114. case CBM_ABOUT:
  115. if(ShellAbout(hwnd, szCaptionName, (LPTSTR)TEXT(""),
  116. LoadIcon(hInst, MAKEINTRESOURCE(CBICON))) == -1)
  117. MemErrorMessage();
  118. break;
  119. case CBM_OPEN:
  120. OpenClipboardFile(hwnd);
  121. break;
  122. case CBM_SAVEAS:
  123. SaveClipboardToFile(hwnd);
  124. break;
  125. case CBM_AUTO:
  126. case CF_PALETTE:
  127. case CF_TEXT:
  128. case CF_BITMAP:
  129. case CF_METAFILEPICT:
  130. case CF_SYLK:
  131. case CF_DIF:
  132. case CF_TIFF:
  133. case CF_OEMTEXT:
  134. case CF_DIB:
  135. case CF_OWNERDISPLAY:
  136. case CF_DSPTEXT:
  137. case CF_DSPBITMAP:
  138. case CF_DSPMETAFILEPICT:
  139. case CF_PENDATA:
  140. case CF_UNICODETEXT:
  141. case CF_RIFF:
  142. case CF_WAVE:
  143. case CF_ENHMETAFILE:
  144. case CF_DSPENHMETAFILE:
  145. if (CurSelFormat == GET_WM_COMMAND_ID(wParam, lParam))
  146. break;
  147. CheckMenuItem(hDispMenu, CurSelFormat, MF_BYCOMMAND | MF_UNCHECKED);
  148. CheckMenuItem(hDispMenu, GET_WM_COMMAND_ID(wParam, lParam), MF_BYCOMMAND | MF_CHECKED);
  149. DrawMenuBar(hwnd);
  150. wOldFormat = GetBestFormat(CurSelFormat);
  151. wNewFormat = GetBestFormat(GET_WM_COMMAND_ID(wParam, lParam));
  152. if (wOldFormat == wNewFormat)
  153. {
  154. /* An equivalent format is selected; No change */
  155. CurSelFormat = GET_WM_COMMAND_ID(wParam, lParam);
  156. break;
  157. }
  158. /* A different format is selected; So, refresh... */
  159. /* Change the character sizes based on new format. */
  160. ChangeCharDimensions(hwnd, wOldFormat, wNewFormat);
  161. fDisplayFormatChanged = TRUE;
  162. CurSelFormat = GET_WM_COMMAND_ID(wParam, lParam);
  163. if (wOldFormat == CF_OWNERDISPLAY)
  164. {
  165. /* Save the owner Display Scroll info */
  166. SaveOwnerScrollInfo(hwnd);
  167. goto InvalidateScroll1;
  168. }
  169. if (wNewFormat == CF_OWNERDISPLAY)
  170. {
  171. /* Restore the owner display scroll info */
  172. RestoreOwnerScrollInfo(hwnd);
  173. InvalidateRect(hwnd,NULL,TRUE);
  174. }
  175. else
  176. goto InvalidateScroll1;
  177. break;
  178. case CBM_USEHELP:
  179. if(!WinHelp(hwnd, (LPTSTR)NULL, HELP_HELPONHELP, 0L))
  180. MemErrorMessage();
  181. break;
  182. case CBM_HELP:
  183. if(!WinHelp(hwnd, (LPTSTR)szHelpFileName, HELP_INDEX, 0L))
  184. MemErrorMessage();
  185. break;
  186. case CBM_SEARCH:
  187. if(!WinHelp(hwnd, (LPTSTR)szHelpFileName, HELP_PARTIALKEY, (DWORD)(LPTSTR)TEXT(""))) /* Anas May 92 should I? */
  188. MemErrorMessage();
  189. break;
  190. default:
  191. return(DefWindowProc(hwnd, message, wParam, lParam));
  192. }
  193. break;
  194. case WM_CHANGECBCHAIN:
  195. /* Some window is being removed from the clipboard viewer chain. */
  196. if (hwndNextViewer == NULL)
  197. return(FALSE);
  198. if ((HWND)wParam == hwndNextViewer)
  199. {
  200. /* Chain link being removed is our descendant */
  201. hwndNextViewer = GET_WM_CHANGECBCHAIN_HWNDNEXT(wParam, lParam);
  202. return(TRUE);
  203. }
  204. return(SendMessage(hwndNextViewer, WM_CHANGECBCHAIN, wParam, lParam));
  205. case WM_KEYDOWN:
  206. {
  207. WPARAM sb;
  208. switch (wParam)
  209. {
  210. case VK_UP:
  211. sb = SB_LINEUP;
  212. goto VertScroll;
  213. case VK_DOWN:
  214. sb = SB_LINEDOWN;
  215. goto VertScroll;
  216. case VK_PRIOR:
  217. sb = SB_PAGEUP;
  218. goto VertScroll;
  219. case VK_NEXT:
  220. sb = SB_PAGEDOWN;
  221. VertScroll:
  222. SendMessage(hwnd, WM_VSCROLL, sb, 0L);
  223. break;
  224. case VK_LEFT:
  225. sb = SB_LINEUP;
  226. goto HorzScroll;
  227. case VK_RIGHT:
  228. sb = SB_LINEDOWN;
  229. goto HorzScroll;
  230. case VK_TAB:
  231. sb = (GetKeyState( VK_SHIFT ) < 0) ? SB_PAGEUP : SB_PAGEDOWN;
  232. HorzScroll:
  233. SendMessage( hwnd, WM_HSCROLL, sb, 0L);
  234. break;
  235. default:
  236. goto DefaultProc;
  237. }
  238. break;
  239. }
  240. case WM_SIZE:
  241. fDisplayFormatChanged = TRUE;
  242. if (wParam == SIZEICONIC)
  243. {
  244. if (fOwnerDisplay)
  245. SendOwnerSizeMessage(hwnd, 0, 0, 0, 0);
  246. }
  247. else
  248. {
  249. /* Invalidate scroll offsets since they are dependent on
  250. * window size UNLESS it is a Owner display item. Also the
  251. * "object size" of CF_TEXT changes when the window width
  252. * changes.
  253. */
  254. if (fOwnerDisplay)
  255. SendOwnerSizeMessage(hwnd, 0, 0, LOWORD(lParam), HIWORD(lParam));
  256. else
  257. goto InvalidateScroll;
  258. }
  259. break;
  260. case WM_DESTROY:
  261. /* Take us out of the viewer chain */
  262. ChangeClipboardChain(hwnd, hwndNextViewer);
  263. if (fOwnerDisplay)
  264. SendOwnerSizeMessage(hwnd, 0, 0, 0, 0);
  265. DeleteObject(hbrBackground);
  266. WinHelp(hwnd, (LPTSTR)szHelpFileName, HELP_QUIT, 0L);
  267. PostQuitMessage(0);
  268. break;
  269. case WM_DRAWCLIPBOARD:
  270. fDisplayFormatChanged = TRUE;
  271. /* Pass the message on to the next clipboard viewer in the chain. */
  272. if (hwndNextViewer != NULL)
  273. SendMessage(hwndNextViewer, WM_DRAWCLIPBOARD, wParam, lParam);
  274. wOldFormat = GetBestFormat(CurSelFormat);
  275. /* Update the popup menu entries. */
  276. UpdateCBMenu(hwnd);
  277. wNewFormat = GetBestFormat(CurSelFormat);
  278. /* Change the character dimensions based on the format. */
  279. ChangeCharDimensions(hwnd, wOldFormat, wNewFormat);
  280. /* Initialize the owner display scroll info, because the
  281. * contents have changed.
  282. */
  283. InitOwnerScrollInfo();
  284. InvalidateScroll1:
  285. /* Force a total repaint. fOwnerDisplay gets updated during
  286. * a total repaint.
  287. */
  288. InvalidateRect(hwnd,NULL,TRUE);
  289. InvalidateScroll:
  290. /* Invalidate object info; reset scroll position to 0. */
  291. cyScrollLast = cxScrollLast = -1;
  292. /* Range is set in case CF_OWNERDISPLAY owner changed it. */
  293. SetScrollRange(hwnd, SB_VERT, 0, VPOSLAST, FALSE);
  294. SetScrollPos(hwnd, SB_VERT, (INT)(cyScrollNow = 0), TRUE);
  295. SetScrollRange(hwnd, SB_HORZ, 0, HPOSLAST, FALSE);
  296. SetScrollPos(hwnd, SB_HORZ, cxScrollNow = 0, TRUE);
  297. break;
  298. case WM_QUERYNEWPALETTE:
  299. /* If palette realization caused a palette change, do a full redraw. */
  300. if (!MyOpenClipboard(hwnd))
  301. return(FALSE);
  302. if (IsClipboardFormatAvailable(CF_PALETTE))
  303. hpal = GetClipboardData(CF_PALETTE);
  304. else
  305. hpal = NULL;
  306. CloseClipboard();
  307. if (hpal)
  308. {
  309. hdc = GetDC(hwnd);
  310. hpalT = SelectPalette(hdc, hpal, FALSE);
  311. i = RealizePalette(hdc);
  312. SelectPalette (hdc, hpalT, FALSE);
  313. ReleaseDC(hwnd, hdc);
  314. if (i)
  315. {
  316. InvalidateRect(hwnd, NULL, TRUE);
  317. UpdateCount = 0;
  318. return TRUE;
  319. }
  320. }
  321. return(FALSE);
  322. case WM_PALETTECHANGED:
  323. if ((HWND)wParam != hwnd && IsClipboardFormatAvailable(CF_PALETTE))
  324. {
  325. if (!MyOpenClipboard(hwnd))
  326. return(FALSE);
  327. if (IsClipboardFormatAvailable(CF_PALETTE))
  328. hpal = GetClipboardData(CF_PALETTE);
  329. else
  330. hpal = NULL;
  331. CloseClipboard();
  332. if (hpal)
  333. {
  334. hdc = GetDC(hwnd);
  335. hpalT = SelectPalette (hdc, hpal, FALSE);
  336. if (RealizePalette(hdc))
  337. {
  338. #ifdef ORG_CODE
  339. UpdateColors(hdc);
  340. UpdateCount++;
  341. #else
  342. InvalidateRect(hwnd, NULL, TRUE);
  343. UpdateCount = 0;
  344. #endif
  345. }
  346. SelectPalette (hdc, hpalT, 0);
  347. ReleaseDC(hwnd, hdc);
  348. }
  349. }
  350. break;
  351. case WM_PAINT:
  352. {
  353. PAINTSTRUCT ps;
  354. /* If we have updated more than once, the rest of our
  355. * window is not in some level of degradation worse than
  356. * our redraw... We need to redraw the whole area.
  357. */
  358. if (UpdateCount > 1)
  359. {
  360. UpdateCount = 0;
  361. InvalidateRect(hwnd, NULL, TRUE);
  362. }
  363. BeginPaint(hwnd, &ps);
  364. hdc = ps.hdc;
  365. if (MyOpenClipboard(hwnd))
  366. {
  367. SetBkColor(hdc, GetSysColor(COLOR_WINDOW));
  368. SetTextColor(hdc, GetSysColor(COLOR_WINDOWTEXT));
  369. /* Check if a palette is also available in the clipboard.
  370. * If so, select it before drawing data.
  371. */
  372. if (IsClipboardFormatAvailable(CF_PALETTE)) {
  373. if ((hpal = GetClipboardData(CF_PALETTE)) != NULL)
  374. {
  375. hpalT = SelectPalette(hdc, hpal, FALSE);
  376. RealizePalette(hdc);
  377. }
  378. } else
  379. hpal = NULL;
  380. DrawStuff(hwnd, &ps);
  381. if (hpal)
  382. SelectPalette(hdc, hpalT, FALSE);
  383. CloseClipboard();
  384. }
  385. EndPaint(hwnd, &ps);
  386. break;
  387. }
  388. case WM_VSCROLL:
  389. if (GET_WM_VSCROLL_CODE(wParam, lParam) != SB_THUMBTRACK)
  390. {
  391. if (fOwnerDisplay)
  392. SendOwnerMessage(WM_VSCROLLCLIPBOARD, (WPARAM)hwnd,
  393. (LPARAM)MAKELONG(GET_WM_VSCROLL_CODE(wParam, lParam),
  394. GET_WM_VSCROLL_POS(wParam, lParam)));
  395. else
  396. ClipbrdVScroll(hwnd, GET_WM_VSCROLL_CODE(wParam, lParam),
  397. GET_WM_VSCROLL_POS(wParam, lParam));
  398. }
  399. break;
  400. case WM_HSCROLL:
  401. if (GET_WM_HSCROLL_CODE(wParam, lParam) != SB_THUMBTRACK)
  402. {
  403. if (fOwnerDisplay)
  404. SendOwnerMessage(WM_HSCROLLCLIPBOARD, (WPARAM)hwnd,
  405. (LPARAM)MAKELONG(GET_WM_HSCROLL_CODE(wParam, lParam),
  406. GET_WM_HSCROLL_POS(wParam, lParam)));
  407. else
  408. ClipbrdHScroll(hwnd, GET_WM_HSCROLL_CODE(wParam, lParam),
  409. GET_WM_HSCROLL_POS(wParam, lParam));
  410. }
  411. break;
  412. case WM_SYSCOLORCHANGE:
  413. /* Update pen and brush to reflect new color */
  414. DeleteObject(hbrBackground);
  415. hbrBackground = CreateSolidBrush(GetSysColor(COLOR_WINDOW));
  416. break;
  417. default:
  418. DefaultProc:
  419. return(DefWindowProc(hwnd, message, wParam, lParam));
  420. }
  421. return(0L);
  422. }