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.

555 lines
14 KiB

  1. /**************************************************************************
  2. *
  3. * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  4. * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  5. * IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
  6. * PURPOSE.
  7. *
  8. * Copyright (c) 1992 - 1995 Microsoft Corporation. All Rights Reserved.
  9. *
  10. **************************************************************************/
  11. /****************************************************************************
  12. *
  13. * vidframe.c: Frame for the capture window
  14. *
  15. * Vidcap32 Source code
  16. *
  17. ***************************************************************************/
  18. /*
  19. * Window class that provides a frame for the AVICAP window in the
  20. * VidCap capture tool. Responsible for positioning within the
  21. * parent window, handling scrolling and painting a size border if
  22. * there is room.
  23. */
  24. #include <windows.h>
  25. #include <windowsx.h>
  26. #include <mmsystem.h>
  27. #include <mmreg.h>
  28. #include <vfw.h>
  29. #include "vidcap.h"
  30. #include "vidframe.h"
  31. /*
  32. * pixels to move when asked to scroll one line or page
  33. */
  34. #define LINE_SCROLL 10
  35. #define PAGE_SCROLL 50
  36. // class name
  37. #define VIDFRAMECLASSNAME "vidframeClass"
  38. /*
  39. * standard brushes
  40. */
  41. static HBRUSH ghbrBackground = NULL, ghbrFace, ghbrHighlight, ghbrShadow;
  42. static BOOL fhbrBackgroundIsSysObj;
  43. /*
  44. * create brushes to be used in painting
  45. */
  46. void
  47. vidframeCreateTools(HWND hwnd)
  48. {
  49. vidframeSetBrush(hwnd, gBackColour);
  50. ghbrHighlight = CreateSolidBrush(GetSysColor(COLOR_BTNHIGHLIGHT));
  51. ghbrShadow = CreateSolidBrush(GetSysColor(COLOR_BTNSHADOW));
  52. ghbrFace = CreateSolidBrush(GetSysColor(COLOR_BTNFACE));
  53. }
  54. void
  55. vidframeDeleteTools(void)
  56. {
  57. if (ghbrBackground) {
  58. if (!fhbrBackgroundIsSysObj) {
  59. DeleteObject(ghbrBackground);
  60. ghbrBackground = NULL;
  61. }
  62. }
  63. if (ghbrHighlight) {
  64. DeleteObject(ghbrHighlight);
  65. ghbrHighlight = NULL;
  66. }
  67. if (ghbrShadow) {
  68. DeleteObject(ghbrShadow);
  69. ghbrShadow = NULL;
  70. }
  71. if (ghbrFace) {
  72. DeleteObject(ghbrFace);
  73. ghbrFace = NULL;
  74. }
  75. }
  76. /*
  77. * change the background fill brush to be one of-
  78. * IDD_PrefsDefBackground - windows default background colour
  79. * IDD_PrefsLtGrey - light grey
  80. * IDD_PrefsDkGrey - dark grey
  81. * IDD_PrefsBlack - black
  82. */
  83. void
  84. vidframeSetBrush(HWND hwnd, int iPref)
  85. {
  86. if (ghbrBackground != NULL) {
  87. if (!fhbrBackgroundIsSysObj) {
  88. DeleteObject(ghbrBackground);
  89. ghbrBackground = NULL;
  90. }
  91. }
  92. switch(iPref) {
  93. case IDD_PrefsDefBackground:
  94. ghbrBackground = CreateSolidBrush(GetSysColor(COLOR_WINDOW));
  95. fhbrBackgroundIsSysObj = FALSE;
  96. break;
  97. case IDD_PrefsLtGrey:
  98. ghbrBackground = GetStockObject(LTGRAY_BRUSH);
  99. fhbrBackgroundIsSysObj = TRUE;
  100. break;
  101. case IDD_PrefsDkGrey:
  102. ghbrBackground = GetStockObject(DKGRAY_BRUSH);
  103. fhbrBackgroundIsSysObj = TRUE;
  104. break;
  105. case IDD_PrefsBlack:
  106. ghbrBackground = GetStockObject(BLACK_BRUSH);
  107. fhbrBackgroundIsSysObj = TRUE;
  108. break;
  109. default:
  110. return;
  111. }
  112. if (hwnd != NULL) {
  113. #ifdef _WIN32
  114. SetClassLongPtr(hwnd, GCLP_HBRBACKGROUND, (LONG_PTR) ghbrBackground);
  115. #else
  116. SetClassWord(hwnd, GCW_HBRBACKGROUND, (WORD) ghbrBackground);
  117. #endif
  118. InvalidateRect(hwnd, NULL, TRUE);
  119. }
  120. }
  121. /*
  122. * layout the window - decide if we need scrollbars or
  123. * not, and position the avicap window correctly
  124. */
  125. void
  126. vidframeLayout(HWND hwnd, HWND hwndCap)
  127. {
  128. RECT rc;
  129. RECT rcCap;
  130. CAPSTATUS cs;
  131. int cx, cy;
  132. POINT ptScroll;
  133. // get the x and y scroll pos so we can reset them
  134. ptScroll.y = GetScrollPos(hwnd, SB_VERT);
  135. ptScroll.x = GetScrollPos(hwnd, SB_HORZ);
  136. GetClientRect(hwnd, &rc);
  137. if (!capGetStatus(hwndCap, &cs, sizeof(cs))) {
  138. // no current window? - make it 0 size
  139. cs.uiImageWidth = 0;
  140. cs.uiImageHeight = 0;
  141. }
  142. SetRect(&rcCap, 0, 0, cs.uiImageWidth, cs.uiImageHeight);
  143. /*
  144. * check which scrollbars we need - note that adding and removing
  145. * scrollbars affects the other dimension - so recheck client rect
  146. */
  147. if (RECTWIDTH(rcCap) < RECTWIDTH(rc)) {
  148. // fits horz.
  149. SetScrollRange(hwnd, SB_HORZ, 0, 0, TRUE);
  150. } else {
  151. // need horz scrollbar
  152. SetScrollRange(hwnd, SB_HORZ, 0, RECTWIDTH(rcCap) - RECTWIDTH(rc), FALSE);
  153. }
  154. // get client size in case shrunk/expanded
  155. GetClientRect(hwnd, &rc);
  156. // check vert scrollbar
  157. if (RECTHEIGHT(rcCap) < RECTHEIGHT(rc)) {
  158. SetScrollRange(hwnd, SB_VERT, 0, 0, TRUE);
  159. } else {
  160. SetScrollRange(hwnd, SB_VERT, 0, RECTHEIGHT(rcCap) - RECTHEIGHT(rc), FALSE);
  161. // this may have caused the horz scrollbar to be unneeded
  162. GetClientRect(hwnd, &rc);
  163. if (RECTWIDTH(rcCap) < RECTWIDTH(rc)) {
  164. // fits horz.
  165. SetScrollRange(hwnd, SB_HORZ, 0, 0, TRUE);
  166. } else {
  167. // need horz scrollbar
  168. SetScrollRange(hwnd, SB_HORZ, 0, RECTWIDTH(rcCap) - RECTWIDTH(rc), FALSE);
  169. }
  170. }
  171. /*
  172. * be sure we don't leave any underwear showing if we have scrolled
  173. * back or removed the scrollbars
  174. */
  175. {
  176. int cmax, cmin;
  177. GetScrollRange(hwnd, SB_HORZ, &cmin, &cmax);
  178. if (ptScroll.x > cmax) {
  179. ptScroll.x = cmax;
  180. }
  181. GetScrollRange(hwnd, SB_VERT, &cmin, &cmax);
  182. if (ptScroll.y > cmax) {
  183. ptScroll.y = cmax;
  184. }
  185. SetScrollPos(hwnd, SB_HORZ, ptScroll.x, TRUE);
  186. SetScrollPos(hwnd, SB_VERT, ptScroll.y, TRUE);
  187. capSetScrollPos(hwndCap, &ptScroll);
  188. }
  189. // centre the window if requested and if room
  190. if(gbCentre) {
  191. GetClientRect(hwnd, &rc);
  192. cx = max(0, (RECTWIDTH(rc) - (int) cs.uiImageWidth)/2);
  193. cy = max(0, (RECTHEIGHT(rc) - (int) cs.uiImageHeight)/2);
  194. OffsetRect(&rcCap, cx, cy);
  195. }
  196. // DWORD align the capture window for optimal codec speed
  197. // during preview.
  198. rc = rcCap;
  199. MapWindowPoints (hwnd, NULL, (LPPOINT)&rc, 1);
  200. cx = rc.left - (rc.left & ~3);
  201. OffsetRect(&rcCap, -cx, 0);
  202. MoveWindow(hwndCap,
  203. rcCap.left, rcCap.top,
  204. RECTWIDTH(rcCap), RECTHEIGHT(rcCap),
  205. TRUE);
  206. InvalidateRect(hwnd, NULL, TRUE);
  207. }
  208. /*
  209. * paint the vidframe window. The fill colour is always selected as the
  210. * background brush, so all we need to do here is paint the
  211. * fancy border around the inner window if room.
  212. */
  213. void
  214. vidframePaint(HWND hwnd, HWND hwndCap)
  215. {
  216. POINT ptInner;
  217. RECT rcCap;
  218. PAINTSTRUCT ps;
  219. HDC hdc;
  220. HBRUSH hbr;
  221. int cx, cy;
  222. hdc = BeginPaint(hwnd, &ps);
  223. /*
  224. * first calculate the location of the upper left corner
  225. * of the avicap window in vidframe-window client co-ordinates
  226. */
  227. ptInner.x = 0;
  228. ptInner.y = 0;
  229. MapWindowPoints(hwndCap, hwnd, &ptInner, 1);
  230. // width and height of cap window
  231. GetWindowRect(hwndCap, &rcCap);
  232. cx = RECTWIDTH(rcCap);
  233. cy = RECTHEIGHT(rcCap);
  234. // shadow lines
  235. hbr = SelectObject(hdc, ghbrShadow);
  236. PatBlt(hdc, ptInner.x-1, ptInner.y-1, cx + 1, 1, PATCOPY);
  237. PatBlt(hdc, ptInner.x-1, ptInner.y-1, 1, cy + 1, PATCOPY);
  238. PatBlt(hdc, ptInner.x + cx + 4, ptInner.y-5, 1, cy+10, PATCOPY);
  239. PatBlt(hdc, ptInner.x -5, ptInner.y+cy+4, cx+10, 1, PATCOPY);
  240. // hi-light lines
  241. SelectObject(hdc, ghbrHighlight);
  242. PatBlt(hdc, ptInner.x - 5, ptInner.y - 5, 1, cy+9, PATCOPY);
  243. PatBlt(hdc, ptInner.x - 5, ptInner.y - 5, cx+9, 1, PATCOPY);
  244. PatBlt(hdc, ptInner.x+cx, ptInner.y-1, 1, cy+2, PATCOPY);
  245. PatBlt(hdc, ptInner.x-1, ptInner.y+cy, cx, 1, PATCOPY);
  246. // fill bordered area with button face colour
  247. SelectObject(hdc, ghbrFace);
  248. PatBlt(hdc, ptInner.x-4, ptInner.y-4, cx+8, 3, PATCOPY);
  249. PatBlt(hdc, ptInner.x-4, ptInner.y+cy+1, cx+8, 3, PATCOPY);
  250. PatBlt(hdc, ptInner.x-4, ptInner.y-1, 3, cy+2, PATCOPY);
  251. PatBlt(hdc, ptInner.x+cx+1, ptInner.y-1, 3, cy+2, PATCOPY);
  252. SelectObject(hdc, hbr);
  253. EndPaint(hwnd, &ps);
  254. }
  255. /*
  256. * respond to a scrollbar message by moving the current scroll
  257. * position horizontally
  258. */
  259. void
  260. vidframeHScroll(HWND hwnd, HWND hwndCap, int code, int pos)
  261. {
  262. POINT pt;
  263. int cmax, cmin;
  264. pt.x = GetScrollPos(hwnd, SB_HORZ);
  265. pt.y = GetScrollPos(hwnd, SB_VERT);
  266. GetScrollRange(hwnd, SB_HORZ, &cmin, &cmax);
  267. switch(code) {
  268. case SB_LINEUP:
  269. pt.x -= LINE_SCROLL;
  270. break;
  271. case SB_LINEDOWN:
  272. pt.x += LINE_SCROLL;
  273. break;
  274. case SB_PAGEUP:
  275. pt.x -= PAGE_SCROLL;
  276. break;
  277. case SB_PAGEDOWN:
  278. pt.x += PAGE_SCROLL;
  279. break;
  280. case SB_THUMBTRACK:
  281. case SB_THUMBPOSITION:
  282. pt.x = pos;
  283. break;
  284. }
  285. if (pt.x < cmin) {
  286. pt.x = cmin;
  287. } else if (pt.x > cmax) {
  288. pt.x = cmax;
  289. }
  290. SetScrollPos(hwnd, SB_HORZ, pt.x, TRUE);
  291. capSetScrollPos(hwndCap, &pt);
  292. }
  293. /*
  294. * respond to a scrollbar message by moving the current scroll
  295. * position vertically
  296. */
  297. void
  298. vidframeVScroll(HWND hwnd, HWND hwndCap, int code, int pos)
  299. {
  300. POINT pt;
  301. int cmax, cmin;
  302. pt.x = GetScrollPos(hwnd, SB_HORZ);
  303. pt.y = GetScrollPos(hwnd, SB_VERT);
  304. GetScrollRange(hwnd, SB_VERT, &cmin, &cmax);
  305. switch(code) {
  306. case SB_LINEUP:
  307. pt.y -= LINE_SCROLL;
  308. break;
  309. case SB_LINEDOWN:
  310. pt.y += LINE_SCROLL;
  311. break;
  312. case SB_PAGEUP:
  313. pt.y -= PAGE_SCROLL;
  314. break;
  315. case SB_PAGEDOWN:
  316. pt.y += PAGE_SCROLL;
  317. break;
  318. case SB_THUMBTRACK:
  319. case SB_THUMBPOSITION:
  320. pt.y = pos;
  321. break;
  322. }
  323. if (pt.y < cmin) {
  324. pt.y = cmin;
  325. } else if (pt.y > cmax) {
  326. pt.y = cmax;
  327. }
  328. SetScrollPos(hwnd, SB_VERT, pt.y, TRUE);
  329. capSetScrollPos(hwndCap, &pt);
  330. }
  331. LRESULT FAR PASCAL
  332. vidframeProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  333. {
  334. switch(message) {
  335. case WM_MOVE:
  336. case WM_SIZE:
  337. if (ghWndCap) {
  338. vidframeLayout(hwnd, ghWndCap);
  339. }
  340. break;
  341. case WM_SYSCOLORCHANGE:
  342. // re-get brushes - we will be sent a paint message
  343. vidframeDeleteTools();
  344. vidframeCreateTools(hwnd);
  345. return(TRUE);
  346. case WM_PALETTECHANGED:
  347. case WM_QUERYNEWPALETTE:
  348. // allow the avicap window to handle this
  349. if (ghWndCap) {
  350. return SendMessage(ghWndCap, message, wParam, lParam) ;
  351. }
  352. case WM_PAINT:
  353. if (ghWndCap) {
  354. vidframePaint(hwnd, ghWndCap);
  355. }
  356. break;
  357. case WM_HSCROLL:
  358. if (ghWndCap) {
  359. vidframeHScroll(hwnd, ghWndCap,
  360. GET_WM_HSCROLL_CODE(wParam, lParam),
  361. GET_WM_HSCROLL_POS(wParam, lParam)
  362. );
  363. }
  364. break;
  365. case WM_VSCROLL:
  366. if (ghWndCap) {
  367. vidframeVScroll(hwnd, ghWndCap,
  368. GET_WM_VSCROLL_CODE(wParam, lParam),
  369. GET_WM_VSCROLL_POS(wParam, lParam)
  370. );
  371. }
  372. break;
  373. case WM_DESTROY:
  374. vidframeDeleteTools();
  375. break;
  376. default:
  377. return(DefWindowProc(hwnd, message, wParam, lParam));
  378. }
  379. return(0);
  380. }
  381. /*
  382. * create a frame window and child capture window at the
  383. * given location. Initialise the class if this is the
  384. * first time through.
  385. *
  386. * returns the window handle of the frame window
  387. * (or NULL if failure). returns the window handle of the AVICAP window
  388. * via phwndCap.
  389. */
  390. HWND
  391. vidframeCreate(
  392. HWND hwndParent,
  393. HINSTANCE hInstance,
  394. HINSTANCE hPrevInstance,
  395. int x,
  396. int y,
  397. int cx,
  398. int cy,
  399. HWND FAR * phwndCap
  400. )
  401. {
  402. HWND hwnd, hwndCap;
  403. static BOOL bInitDone = FALSE;
  404. if (!bInitDone) {
  405. WNDCLASS wc;
  406. vidframeCreateTools(NULL);
  407. if (!hPrevInstance) {
  408. // If it's the first instance, register the window class
  409. wc.lpszClassName = VIDFRAMECLASSNAME;
  410. wc.hInstance = hInstance;
  411. wc.lpfnWndProc = vidframeProc;
  412. wc.hCursor = LoadCursor(NULL, IDC_ARROW) ;
  413. wc.hIcon = NULL;
  414. wc.lpszMenuName = NULL;
  415. wc.hbrBackground = ghbrBackground;
  416. wc.style = CS_HREDRAW | CS_VREDRAW ;
  417. wc.cbClsExtra = 0 ;
  418. wc.cbWndExtra = 0 ;
  419. if(!RegisterClass(&wc)) {
  420. return(NULL);
  421. }
  422. }
  423. bInitDone = TRUE;
  424. }
  425. hwnd = CreateWindowEx(
  426. gfIsRTL ? WS_EX_LEFTSCROLLBAR | WS_EX_RIGHT | WS_EX_RTLREADING : 0,
  427. VIDFRAMECLASSNAME,
  428. NULL,
  429. WS_CHILD|WS_VISIBLE|WS_HSCROLL|WS_VSCROLL|WS_CLIPCHILDREN,
  430. x, y, cx, cy,
  431. hwndParent,
  432. (HMENU) 0,
  433. hInstance,
  434. NULL);
  435. if (hwnd == NULL) {
  436. return(NULL);
  437. }
  438. /*
  439. * create an AVICAP window within this window. Leave vidframeLayout
  440. * to do the layout
  441. */
  442. hwndCap = capCreateCaptureWindow(
  443. NULL,
  444. WS_CHILD | WS_VISIBLE,
  445. 0, 0, 160, 120,
  446. hwnd, // parent window
  447. 1 // child window id
  448. );
  449. if (hwndCap == NULL) {
  450. return(NULL);
  451. }
  452. *phwndCap = hwndCap;
  453. return(hwnd);
  454. }