VIDFRAME.C
上传用户:carrie980
上传日期:2013-03-28
资源大小:1143k
文件大小:14k
源码类别:

视频捕捉/采集

开发平台:

Visual C++

  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 - 1996 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.         SetClassLong(hwnd, GCL_HBRBACKGROUND, (LONG) 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. LONG 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. }