Windows NT 4.0 source code leak
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.

517 lines
12 KiB

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