INPUTSET.C
上传用户:guoxiu1214
上传日期:2019-02-27
资源大小:876k
文件大小:40k
源码类别:

多显示器编程

开发平台:

Visual C++

  1. /*******************************************************************************
  2. Copyright Datapath Ltd. 2007.
  3. File:    InputSet.c
  4. Purpose: Implements the Input Settings dialog.
  5. History:
  6.          20 DEC 07    SB   Created.
  7. *******************************************************************************/
  8. #include <windows.h>
  9. #include <commctrl.h>
  10. #include <stdio.h>
  11. #include <tchar.h>
  12. #include <rgb.h>
  13. #include <rgbapi.h>
  14. #include <rgberror.h>
  15. #include "sample2.h"
  16. #include "resource.h"
  17. /******************************************************************************/
  18. static const TCHAR Property[] = TEXT("pWindow");
  19. /******************************************************************************/
  20. #define BLANK_MODE_IMAGE   0
  21. #define CURRENT_MODE_IMAGE 1
  22. #define PROP_SETFOCUS         ( WM_USER + 1 )
  23. #define WM_MODECHANGEUPDATE   ( WM_USER + 2 )
  24. #define WM_NOSIGNALUPDATE     ( WM_USER + 3 )
  25. #define WM_INVALIDSIGUPDATE   ( WM_USER + 4 )
  26. #define WM_VALUECHANGED       ( WM_USER + 5 )
  27. #define WM_RECORDERSTARTED    ( WM_USER + 6 )
  28. #define WM_RECORDERSTOPPED    ( WM_USER + 7 )
  29. typedef enum 
  30. {
  31.    VALIDSIGSTATE     = RGB_STATE_CAPTURING,
  32.    NOSIGNALSTATE     = RGB_STATE_NOSIGNAL,
  33.    INVALIDSIGSTATE   = RGB_STATE_INVALIDSIGNAL,
  34.    CAPTURENOTRUNNING = RGB_STATE_PAUSED,
  35.    ERRORSTATE        = RGB_STATE_ERROR,
  36. }  SIGNALSTATE;
  37. RGBMODECHANGEDFN  ModeChangeFn;
  38. RGBNOSIGNALFN     NoSignalFn;
  39. RGBINVALIDSIGNALFN InvalidSignalFn;
  40. typedef struct
  41. {
  42.    HINSTANCE   HInstance;
  43.    HWND        HWndParent;
  44.    HRGB        HRGB;
  45.    BOOL        BProgram;
  46.    BOOL        HCurrentMode;
  47. }  WINDOW, *PWINDOW;
  48. /******************************************************************************/
  49. BOOL
  50. GetDlgItemIntInRange (
  51.    HWND  hDlg,
  52.    int   iEditId,
  53.    int   iMin,
  54.    int   iMax,
  55.    BOOL  bSigned,
  56.    int   *pValue )
  57. {
  58.    BOOL  bTranslated;
  59.    *pValue = GetDlgItemInt ( hDlg, iEditId, &bTranslated, bSigned );
  60.    if ( bTranslated )
  61.    {
  62.       if ( bSigned )
  63.       {
  64.          if ( ( (int)*pValue < iMin ) || ( (int)*pValue > iMax ) )
  65.          {
  66.             return FALSE;
  67.          }
  68.       }
  69.       else
  70.       {
  71.          if ( ( (unsigned int)*pValue < (unsigned int)iMin ) ||
  72.               ( (unsigned int)*pValue > (unsigned int)iMax ) )
  73.          {
  74.             return FALSE;
  75.          }
  76.       }
  77.       return TRUE;
  78.    }
  79.    return FALSE;
  80. }
  81. /******************************************************************************/
  82. #define USE_SCROLL_BARS 1
  83. void
  84. SetTrackBarRange (
  85.    HWND  hCtl,
  86.    LONG  min,
  87.    LONG  max,
  88.    BOOL  bRedraw )
  89. {
  90. #if USE_SCROLL_BARS
  91.    SetScrollRange ( hCtl, SB_CTL, (int)min, (int)max, bRedraw );
  92. #else
  93.    SendMessage ( hCtl, TBM_SETRANGEMIN, 0, min );
  94.    SendMessage ( hCtl, TBM_SETRANGEMAX, 0, max );
  95. #endif
  96. }
  97. /******************************************************************************/
  98. void
  99. GetTrackBarRange (
  100.    HWND     hCtl,
  101.    LPLONG   min,
  102.    LPLONG   max )
  103. {
  104. #if USE_SCROLL_BARS
  105.    {
  106.       int   iMin, iMax;
  107.       GetScrollRange ( hCtl, SB_CTL, &iMin, &iMax );
  108.       *min = (long)iMin;
  109.       *max = (long)iMax;
  110.    }
  111. #else
  112.    *min = SendMessage( hCtl, TBM_GETRANGEMIN, 0, 0 );
  113.    *max = SendMessage( hCtl, TBM_GETRANGEMAX, 0, 0 );
  114. #endif
  115. }
  116. /******************************************************************************/
  117. void
  118. SetTrackBarPos (
  119.    HWND  hCtl,
  120.    LONG  pos,
  121.    BOOL  bRedraw )
  122. {
  123. #if USE_SCROLL_BARS
  124.    SetScrollPos ( hCtl, SB_CTL, (int)pos, bRedraw );
  125. #else
  126.    SendMessage ( hCtl, TBM_SETPOS, bRedraw, pos );
  127. #endif
  128. }
  129. /******************************************************************************/
  130. LONG
  131. GetTrackBarPos (
  132.    HWND  hCtl )
  133. {
  134. #if USE_SCROLL_BARS
  135.    return GetScrollPos ( hCtl, SB_CTL );
  136. #else
  137.    return SendMessage ( hCtl, TBM_GETPOS, 0, 0 );
  138. #endif
  139. }
  140. /******************************************************************************/
  141. BOOL
  142. Cropping (
  143.    HWND           hDlg,
  144.    PWINDOW        pWindow,
  145.    unsigned long  hCurrentMode,
  146.    BOOL           bMessage )
  147. {
  148.    static const struct
  149.    {
  150.       int   EditId;
  151.       int   SpinId;
  152.       BOOL  BSigned;
  153.    } ctl[] =
  154.    {
  155.       { IDC_TOP,      IDC_TOPSPIN,      TRUE },
  156.       { IDC_LEFT,     IDC_LEFTSPIN,     TRUE },
  157.       { IDC_WIDTH,    IDC_WIDTHSPIN,    FALSE },
  158.       { IDC_HEIGHT,   IDC_HEIGHTSPIN,   FALSE },
  159.    };
  160.    long           top, left;
  161.    unsigned long  width, height;
  162.    int   *cropping[] =
  163.    {
  164.       { &top },
  165.       { &left },
  166.       { &width },
  167.       { &height },
  168.    };
  169.    int            i, iMin, iMax;
  170.    unsigned long  error;
  171.    BOOL           bEnabled;
  172.    for ( i = 0; i < sizeof ( ctl ) / sizeof ( ctl[0] ); i++ )
  173.    {
  174.       iMin = iMax = 0;
  175.       SendMessage ( GetDlgItem ( hDlg, ctl[i].SpinId ), UDM_GETRANGE32, 
  176.             (WPARAM)&iMin, (LPARAM)&iMax );
  177.       if ( GetDlgItemIntInRange ( hDlg, ctl[i].EditId, iMin, iMax,
  178.             ctl[i].BSigned, cropping[i] ) == FALSE )
  179.       {
  180.          if ( bMessage )
  181.          {
  182.             PostMessage ( hDlg, PROP_SETFOCUS, 0, ctl[i].EditId );
  183.          }
  184.          return FALSE;
  185.       }
  186.    }
  187.    bEnabled = IsDlgButtonChecked ( hDlg, IDC_CROPPINGON ) == BST_CHECKED;
  188.       
  189.    /* TODO: Get a more meaningful error number back. */
  190.    error = RGBSetCropping ( pWindow->HRGB, top, left, width, height );
  191.    if ( error == 0 )
  192.    {
  193.       error = RGBEnableCropping ( pWindow->HRGB, bEnabled );
  194.       if ( error )
  195.       {
  196.          return FALSE;
  197.       }
  198.    }
  199.    return TRUE;
  200. }
  201. /******************************************************************************/
  202. unsigned long
  203. IncreaseHorizontalScale (
  204.    HWND           hDlg,
  205.    unsigned long  width )
  206. {
  207.    unsigned long  horScale, horStart;
  208.    BOOL           bTranslated;
  209.    horScale = GetDlgItemInt ( hDlg, IDC_HORSCALEVALUE, &bTranslated, FALSE );
  210.    if ( bTranslated )
  211.    {
  212.       horStart = GetDlgItemInt( hDlg, IDC_HOROFFSETVALUE, &bTranslated, FALSE );
  213.       if ( bTranslated )
  214.       {
  215.          unsigned long scale;
  216.          scale = horStart + width;
  217.          if ( scale > horScale )
  218.          {
  219.             return scale;
  220.          }
  221.       }
  222.    }
  223.    return 0;
  224. }
  225. /******************************************************************************/
  226. BOOL
  227. AddrWidth ( 
  228.    HWND     hDlg,
  229.    PWINDOW  pWindow, 
  230.    BOOL     bMessage )
  231. {
  232.    unsigned long  error, width;
  233.    int            iMin, iMax;
  234.    iMin = iMax = 0;
  235.    SendMessage ( GetDlgItem ( hDlg, IDC_ADDRWIDTHSPIN ), UDM_GETRANGE32, 
  236.          (WPARAM)&iMin, (LPARAM)&iMax );
  237.    if ( GetDlgItemIntInRange ( hDlg, IDC_ADDRWIDTH, iMin, iMax,
  238.          FALSE, &width ) == FALSE )
  239.    {
  240.       return FALSE;
  241.    }
  242.    {
  243.       /* Increase the horizontal scale if needed. */
  244.       unsigned long horizontalScale;
  245.       horizontalScale = IncreaseHorizontalScale ( hDlg, width );
  246.       if ( horizontalScale )
  247.       {
  248.          if ( RGBSetHorScale ( pWindow->HRGB, horizontalScale ) == 0 )
  249.          {
  250.             SetTrackBarPos ( GetDlgItem ( hDlg, IDC_HORSCALE ), 
  251.                   horizontalScale, TRUE );
  252.             SetDlgItemInt ( hDlg, IDC_HORSCALEVALUE, horizontalScale, TRUE );
  253.          }
  254.       }
  255.    }
  256.    error = RGBSetCaptureWidth ( pWindow->HRGB, width );
  257.    if ( error )
  258.    {
  259.       return FALSE;
  260.    }
  261.    return TRUE;
  262. }
  263. /******************************************************************************/
  264. BOOL
  265. AddrHeight ( 
  266.    HWND     hDlg,
  267.    PWINDOW  pWindow,
  268.    BOOL     bMessage )
  269. {
  270.    unsigned long  error, height;
  271.    int            iMin, iMax;
  272.    iMin = iMax = 0;
  273.    SendMessage ( GetDlgItem ( hDlg, IDC_ADDRHEIGHTSPIN ), UDM_GETRANGE32, 
  274.          (WPARAM)&iMin, (LPARAM)&iMax );
  275.    if ( GetDlgItemIntInRange ( hDlg, IDC_ADDRHEIGHT, iMin, iMax,
  276.          FALSE, &height ) == FALSE )
  277.    {
  278.       return FALSE;
  279.    }
  280.    error = RGBSetCaptureHeight ( pWindow->HRGB, height );
  281.    if ( error )
  282.    {
  283.       return FALSE;
  284.    }
  285.    return TRUE;
  286. }
  287. /******************************************************************************/
  288. static void
  289. SetValueFromSlider (
  290.    HWND           hDlg,
  291.    PWINDOW        pWindow,
  292.    int            ctlID,
  293.    unsigned long  position )
  294. {
  295.    int nIDDlgItem;
  296.    switch ( ctlID )
  297.    {
  298.       case IDC_BRIGHTNESS:
  299.       {
  300.          RGBSetBrightness ( pWindow->HRGB, position );
  301.          nIDDlgItem = IDC_BRIGHTNESSVALUE;
  302.          break;
  303.       }
  304.       case IDC_CONTRAST:
  305.       {
  306.          RGBSetContrast ( pWindow->HRGB, position );
  307.          nIDDlgItem = IDC_CONTRASTVALUE;
  308.          break;
  309.       }
  310.       case IDC_BLACKLEVEL:
  311.       {
  312.          RGBSetBlackLevel ( pWindow->HRGB, position );
  313.          nIDDlgItem = IDC_BLACKLEVELVALUE;
  314.          break;
  315.       }
  316.       case IDC_PHASE:
  317.       {
  318.          RGBSetPhase ( pWindow->HRGB, position );
  319.          nIDDlgItem = IDC_PHASEVALUE;
  320.          break;
  321.       }
  322.       case IDC_HOROFFSET:
  323.       {
  324.          RGBSetHorPosition ( pWindow->HRGB, position );
  325.          nIDDlgItem = IDC_HOROFFSETVALUE;
  326.          break;
  327.       }
  328.       case IDC_VEROFFSET:
  329.       {
  330.          RGBSetVerPosition ( pWindow->HRGB, position );
  331.          nIDDlgItem = IDC_VEROFFSETVALUE;
  332.          break;
  333.       }
  334.       case IDC_HORSCALE:
  335.       {
  336.          RGBSetHorScale ( pWindow->HRGB, position );
  337.          nIDDlgItem = IDC_HORSCALEVALUE;
  338.          break;
  339.       }
  340.       default:
  341.          return;
  342.    }
  343.    SetDlgItemInt ( hDlg, nIDDlgItem, position, TRUE );
  344. }
  345. /******************************************************************************/
  346. unsigned long
  347. GetMinimumValueForSlider (
  348.    PWINDOW        pWindow,
  349.    int            ctlID,
  350.    unsigned long  *pValue )
  351. {
  352.    unsigned long  error;
  353.    switch ( ctlID )
  354.    {
  355.       case IDC_BRIGHTNESS:
  356.          error = RGBGetBrightnessMinimum ( pWindow->HRGB, pValue );
  357.          break;
  358.       case IDC_CONTRAST:
  359.          error = RGBGetContrastMinimum ( pWindow->HRGB, pValue );
  360.          break;
  361.       case IDC_BLACKLEVEL:
  362.          error = RGBGetBlackLevelMinimum ( pWindow->HRGB, pValue );
  363.          break;
  364.       case IDC_PHASE:
  365.          error = RGBGetPhaseMinimum ( pWindow->HRGB, pValue );
  366.          break;
  367.       case IDC_HOROFFSET:
  368.          error = RGBGetHorPositionMinimum ( pWindow->HRGB, pValue );
  369.          break;
  370.       case IDC_VEROFFSET:
  371.          error = RGBGetVerPositionMinimum ( pWindow->HRGB, pValue );
  372.          break;
  373.       case IDC_HORSCALE:
  374.          error = RGBGetHorScaleMinimum ( pWindow->HRGB, pValue );
  375.          break;
  376.    }
  377.    return error;
  378. }
  379. /******************************************************************************/
  380. unsigned long
  381. GetCurrentValueForSlider (
  382.    PWINDOW        pWindow,
  383.    int            ctlID,
  384.    unsigned long  *pValue )
  385. {
  386.    unsigned long  error;
  387.    switch ( ctlID )
  388.    {
  389.       case IDC_BRIGHTNESS:
  390.          error = RGBGetBrightness ( pWindow->HRGB, pValue );
  391.          break;
  392.       case IDC_CONTRAST:
  393.          error = RGBGetContrast ( pWindow->HRGB, pValue );
  394.          break;
  395.       case IDC_BLACKLEVEL:
  396.          error = RGBGetBlackLevel ( pWindow->HRGB, pValue );
  397.          break;
  398.       case IDC_PHASE:
  399.          error = RGBGetPhase ( pWindow->HRGB, pValue );
  400.          break;
  401.       case IDC_HOROFFSET:
  402.          error = RGBGetHorPosition ( pWindow->HRGB, pValue );
  403.          break;
  404.       case IDC_VEROFFSET:
  405.          error = RGBGetVerPosition ( pWindow->HRGB, pValue );
  406.          break;
  407.       case IDC_HORSCALE:
  408.          error = RGBGetHorScale ( pWindow->HRGB, pValue );
  409.          break;
  410.    }
  411.    return error;
  412. }
  413. /******************************************************************************/
  414. unsigned long
  415. GetMaximumValueForSlider (
  416.    PWINDOW        pWindow,
  417.    int            ctlID,
  418.    unsigned long  *pValue )
  419. {
  420.    unsigned long  error;
  421.    switch ( ctlID )
  422.    {
  423.       case IDC_BRIGHTNESS:
  424.          error = RGBGetBrightnessMaximum ( pWindow->HRGB, pValue );
  425.          break;
  426.       case IDC_CONTRAST:
  427.          error = RGBGetContrastMaximum ( pWindow->HRGB, pValue );
  428.          break;
  429.       case IDC_BLACKLEVEL:
  430.          error = RGBGetBlackLevelMaximum ( pWindow->HRGB, pValue );
  431.          break;
  432.       case IDC_PHASE:
  433.          error = RGBGetPhaseMaximum ( pWindow->HRGB, pValue );
  434.          break;
  435.       case IDC_HOROFFSET:
  436.          error = RGBGetHorPositionMaximum ( pWindow->HRGB, pValue );
  437.          break;
  438.       case IDC_VEROFFSET:
  439.          error = RGBGetVerPositionMaximum ( pWindow->HRGB, pValue );
  440.          break;
  441.       case IDC_HORSCALE:
  442.          error = RGBGetHorScaleMaximum ( pWindow->HRGB, pValue );
  443.          break;
  444.    }
  445.    return error;
  446. }
  447. /******************************************************************************/
  448. static unsigned long
  449. InintialiseInputSource (
  450.    HWND     hDlg,
  451.    PWINDOW  pWindow )
  452. {
  453.    unsigned long  error, inputs, current;
  454.    HWND           hCtl;
  455.    hCtl = GetDlgItem ( hDlg, IDC_INPUTSOURCE );
  456.    /* Find out how many input sources are available. */
  457.    error = RGBGetNumberOfInputs ( &inputs );
  458.    if ( error == 0 )
  459.    {
  460.       unsigned long i;
  461.       /* Add numeric values to the control. */
  462.       for ( i = 0; i < inputs; i++ )
  463.       {
  464.          TCHAR  text[32];
  465.          wsprintf ( text, TEXT("%d"), i+1 );
  466.          SendMessage ( hCtl, CB_ADDSTRING, (WPARAM)0, (LPARAM)text );
  467.          SendMessage ( hCtl, CB_SETITEMDATA , i, (LPARAM)i );
  468.       }
  469.       error = RGBGetInput ( pWindow->HRGB, &current );
  470.       if ( error == 0 )
  471.       {
  472.          SendMessage ( hCtl, CB_SETCURSEL, (WPARAM)current, (LPARAM)0 );
  473.       }
  474.    }
  475.    return error;
  476. }
  477. /******************************************************************************/
  478. static unsigned long
  479. SetInputSource (
  480.    HWND     hDlg,
  481.    PWINDOW  pWindow )
  482. {
  483.    LRESULT        itemIndex, input;
  484.    unsigned long  error;
  485.    HWND           hCtl;
  486.    hCtl = GetDlgItem ( hDlg, IDC_INPUTSOURCE );
  487.    itemIndex = SendMessage ( hCtl, CB_GETCURSEL, 0, 0 );
  488.    input = SendMessage ( hCtl, CB_GETITEMDATA, (WPARAM)itemIndex, (LPARAM)0 );
  489.    error = RGBSetInput ( pWindow->HRGB, input );
  490.    if ( error )
  491.    {
  492.       PostMessage ( hDlg, PROP_SETFOCUS, 0, IDC_INPUTSOURCE );
  493.    }
  494.    return error;
  495. }
  496. /******************************************************************************/
  497. unsigned long
  498. UpdateAddrWidth (
  499.    HWND     hDlg,
  500.    PWINDOW  pWindow )
  501. {
  502.    unsigned long  error;
  503.    HWND           hCtl;
  504.    unsigned long  maximum, minimum, current;
  505.    if ( error = RGBGetCaptureWidthMaximum ( pWindow->HRGB, &maximum ) )
  506.    {
  507.       return error;
  508.    }
  509.    if ( error = RGBGetCaptureWidth ( pWindow->HRGB, &current ) )
  510.    {
  511.       return error;
  512.    }
  513.    if ( error = RGBGetCaptureWidthMinimum ( pWindow->HRGB, &minimum ) )
  514.    {
  515.       return error;
  516.    }
  517.    SetDlgItemInt ( hDlg, IDC_ADDRWIDTH, current, FALSE );
  518.    hCtl = GetDlgItem ( hDlg, IDC_ADDRWIDTHSPIN );
  519.    if ( hCtl )
  520.    {
  521.       SendMessage ( hCtl, UDM_SETRANGE32, minimum, maximum );
  522.       SendMessage ( hCtl, UDM_SETPOS32, 0, current );
  523.    }
  524.    return error;
  525. }
  526. /******************************************************************************/
  527. unsigned long
  528. UpdateAddrHeight (
  529.    HWND     hDlg,
  530.    PWINDOW  pWindow )
  531. {
  532.    unsigned long  error;
  533.    HWND           hCtl;
  534.    unsigned long  maximum, minimum, current;
  535.    if ( error = RGBGetCaptureHeightMaximum ( pWindow->HRGB, &maximum ) )
  536.    {
  537.       return error;
  538.    }
  539.    if ( error = RGBGetCaptureHeight ( pWindow->HRGB, &current ) )
  540.    {
  541.       return error;
  542.    }
  543.    if ( error = RGBGetCaptureHeightMinimum ( pWindow->HRGB, &minimum ) )
  544.    {
  545.       return error;
  546.    }
  547.    SetDlgItemInt ( hDlg, IDC_ADDRHEIGHT, current, FALSE );
  548.    hCtl = GetDlgItem ( hDlg, IDC_ADDRHEIGHTSPIN );
  549.    if ( hCtl )
  550.    {
  551.       SendMessage ( hCtl, UDM_SETRANGE32, minimum, maximum );
  552.       SendMessage ( hCtl, UDM_SETPOS32, 0, current );
  553.    }
  554.    return error;
  555. }
  556. /******************************************************************************/
  557. unsigned long
  558. UpdateCroppingControls (
  559.    HWND           hDlg,
  560.    PWINDOW        pWindow )
  561. {
  562.    unsigned long  count;
  563.    unsigned long  bEnable;
  564.    struct Control
  565.    {
  566.       DWORD editCtrl;
  567.       DWORD spinCtrl;
  568.       long  minimum;
  569.       long  current;
  570.       long  maximum;
  571.       BOOL  sign;
  572.    }  controls[] = 
  573.       {
  574.          { IDC_TOP,     IDC_TOPSPIN,      0, 0, 0, TRUE },
  575.          { IDC_LEFT,    IDC_LEFTSPIN,     0, 0, 0, TRUE },
  576.          { IDC_WIDTH,   IDC_WIDTHSPIN,    0, 0, 0, FALSE },
  577.          { IDC_HEIGHT,  IDC_HEIGHTSPIN,   0, 0, 0, FALSE },
  578.       };
  579.    /* TODO: error reporting. */
  580.    RGBGetCroppingMaximum ( pWindow->HRGB,
  581.          &controls[0].maximum, &controls[1].maximum, 
  582.          &controls[2].maximum, &controls[3].maximum );
  583.    RGBGetCroppingMinimum ( pWindow->HRGB,
  584.          &controls[0].minimum, &controls[1].minimum, 
  585.          &controls[2].minimum, &controls[3].minimum );
  586.    /* Current comes last because we're interested in the current bEnable value.
  587.     */
  588.    RGBGetCropping (pWindow->HRGB,
  589.          &controls[0].current, &controls[1].current, 
  590.          &controls[2].current, &controls[3].current );
  591.    RGBIsCroppingEnabled ( pWindow->HRGB, &bEnable );
  592.    
  593.    CheckRadioButton ( hDlg, IDC_CROPPINGON, IDC_CROPPINGOFF,
  594.          ( bEnable ) ? IDC_CROPPINGON : IDC_CROPPINGOFF );
  595.    for ( count = 0;
  596.          count < sizeof ( controls ) / sizeof ( struct Control );
  597.          count++ )
  598.    {
  599.       HWND hCtl;
  600.       SetDlgItemInt ( hDlg, controls[count].editCtrl, 
  601.             controls[count].current, 
  602.             controls[count].sign );
  603.       hCtl = GetDlgItem ( hDlg, controls[count].spinCtrl );
  604.       if ( hCtl )
  605.       {
  606.          SendMessage ( hCtl, UDM_SETRANGE32, 
  607.             controls[count].minimum, 
  608.             controls[count].maximum );
  609.       
  610.          SendMessage ( hCtl, UDM_SETPOS32, 
  611.             0, controls[count].current );
  612.       }
  613.    }
  614.    return 0;
  615. }
  616. /******************************************************************************/
  617. void
  618. UpdateControls (
  619.    HWND           hDlg,
  620.    PWINDOW        pWindow )
  621. {
  622.    pWindow->BProgram = FALSE;
  623.    /* Initialise the addressable width and height. */
  624.    UpdateAddrWidth ( hDlg, pWindow );
  625.    UpdateAddrHeight ( hDlg, pWindow );
  626.    /* Initialise cropping controls. */
  627.    UpdateCroppingControls ( hDlg, pWindow );
  628.    /* Initialise the slider bars. */
  629.    {
  630.       struct Control
  631.       {
  632.          int   ScrollID;
  633.          int   ValueID;
  634.          long  Current;
  635.       }  control[] =
  636.       {
  637.          { IDC_HOROFFSET,  IDC_HOROFFSETVALUE,  0 },
  638.          { IDC_HORSCALE,   IDC_HORSCALEVALUE,   0 },
  639.          { IDC_PHASE,      IDC_PHASEVALUE,      0 },
  640.          { IDC_VEROFFSET,  IDC_VEROFFSETVALUE,  0 },
  641.          { IDC_BLACKLEVEL, IDC_BLACKLEVELVALUE, 0 },
  642.          { IDC_BRIGHTNESS, IDC_BRIGHTNESSVALUE, 0 },
  643.          { IDC_CONTRAST,   IDC_CONTRASTVALUE,   0 },
  644.       };
  645.       int i;
  646.       for ( i = 0; i < ( sizeof ( control ) / sizeof ( control[0] )); i++ )
  647.       {
  648.          HWND  hCtl;
  649.          unsigned long  error, minimum, maximum;
  650.          hCtl = GetDlgItem ( hDlg, control[i].ScrollID );
  651.          error = GetMinimumValueForSlider ( pWindow, control[i].ScrollID, &minimum );
  652.          if ( error == 0 )
  653.          {
  654.             GetMaximumValueForSlider ( pWindow, control[i].ScrollID, &maximum );
  655.             GetCurrentValueForSlider ( pWindow, control[i].ScrollID, &control[i].Current );
  656.             SetTrackBarRange ( hCtl, minimum, maximum, TRUE );
  657.             SetTrackBarPos ( hCtl, control[i].Current, TRUE );
  658.             SetDlgItemInt ( hDlg, control[i].ValueID, control[i].Current, 
  659.                   TRUE );
  660.          }
  661.          else
  662.          {
  663.             EnableWindow ( hCtl, FALSE );
  664.          }
  665.       }
  666.    }
  667.    /* Initialise the Capture format. */
  668.    pWindow->BProgram = TRUE;
  669.    return;
  670. }
  671. /******************************************************************************/
  672. unsigned long
  673. UpdateCroppingState (
  674.    HWND     hDlg,
  675.    PWINDOW  pWindow,
  676.    BOOL     bValidMode )
  677. {
  678.    static const struct
  679.    {
  680.       int   ScrollID;
  681.       int   ValueID;
  682.       int   StaticID;
  683.    } control[] =
  684.       {
  685.          { IDC_TOPSPIN,    IDC_TOP,    IDC_TOPSTATIC },
  686.          { IDC_LEFTSPIN,   IDC_LEFT,   IDC_LEFTSTATIC },
  687.          { IDC_WIDTHSPIN,  IDC_WIDTH,  IDC_WIDTHSTATIC },
  688.          { IDC_HEIGHTSPIN, IDC_HEIGHT, IDC_HEIGHTSTATIC },
  689.       };
  690.    HWND  hCtl;
  691.    int   bEnable, i;
  692.    bEnable = bValidMode ? TRUE : FALSE;
  693.    hCtl = GetDlgItem ( hDlg, IDC_CROPPINGON );
  694.    EnableWindow ( hCtl, bEnable );
  695.    hCtl = GetDlgItem ( hDlg, IDC_CROPPINGOFF );
  696.    EnableWindow ( hCtl, bEnable );
  697.    
  698.    bEnable = ( ( IsDlgButtonChecked ( hDlg, IDC_CROPPINGON ) == BST_CHECKED ) &&
  699.          bValidMode );
  700.    for ( i = 0; i < ( sizeof ( control ) / sizeof ( control[0] )); i++ )
  701.    {
  702.       hCtl = GetDlgItem ( hDlg, control[i].ScrollID );
  703.       EnableWindow ( hCtl, bEnable );
  704.       hCtl = GetDlgItem ( hDlg, control[i].ValueID );
  705.       EnableWindow ( hCtl, bEnable );
  706.       hCtl = GetDlgItem ( hDlg, control[i].StaticID );
  707.       EnableWindow ( hCtl, bEnable );
  708.    }
  709.    return 0;
  710. }
  711. /******************************************************************************/
  712. unsigned long
  713. UpdateControlState (
  714.    HWND     hDlg,
  715.    PWINDOW  pWindow,
  716.    BOOL     bValidMode )
  717. {
  718.    static const struct
  719.    {
  720.       int   ScrollID;
  721.       int   ValueID;
  722.       int   StaticID;
  723.       BOOL  BHideValue;
  724.    } control[] =
  725.       {
  726.          { IDC_ADDRWIDTHSPIN, IDC_ADDRWIDTH,       IDC_ADDRWIDTHSTATIC,  FALSE },
  727.          { IDC_ADDRHEIGHTSPIN,IDC_ADDRHEIGHT,      IDC_ADDRHEIGHTSTATIC, FALSE },
  728.          { IDC_HOROFFSET,     IDC_HOROFFSETVALUE,  IDC_HOROFFSETSTATIC,  TRUE },
  729.          { IDC_HORSCALE,      IDC_HORSCALEVALUE,   IDC_HORSCALESTATIC,   TRUE },
  730.          { IDC_PHASE,         IDC_PHASEVALUE,      IDC_PHASESTATIC,      TRUE },
  731.          { IDC_VEROFFSET,     IDC_VEROFFSETVALUE,  IDC_VEROFFSETSTATIC,  TRUE },
  732.          { IDC_BLACKLEVEL,    IDC_BLACKLEVELVALUE, IDC_BLACKLEVELSTATIC, TRUE },
  733.          { IDC_BRIGHTNESS,    IDC_BRIGHTNESSVALUE, IDC_BRIGHTNESSSTATIC, TRUE },
  734.          { IDC_CONTRAST,      IDC_CONTRASTVALUE,   IDC_CONTRASTSTATIC,   TRUE },
  735.       };
  736.    int   i;
  737.    UpdateCroppingState ( hDlg, pWindow, bValidMode );
  738.    for ( i = 0; i < ( sizeof ( control ) / sizeof ( control[0] )); i++ )
  739.    {
  740.       HWND  hCtl;
  741.       hCtl = GetDlgItem ( hDlg, control[i].ScrollID );
  742.       EnableWindow ( hCtl, ( bValidMode ) ? TRUE : FALSE );
  743.       hCtl = GetDlgItem ( hDlg, control[i].StaticID );
  744.       EnableWindow ( hCtl, ( bValidMode ) ? TRUE : FALSE );
  745.       hCtl = GetDlgItem ( hDlg, control[i].ValueID );
  746.       if ( control[i].BHideValue )
  747.          ShowWindow ( hCtl, ( bValidMode ) ? SW_NORMAL : SW_HIDE );
  748.       else
  749.          EnableWindow ( hCtl, ( bValidMode ) ? TRUE : FALSE );
  750.    }
  751.    return 0;
  752. }
  753. /******************************************************************************/
  754. unsigned long
  755. UpdateRedetectState (
  756.    HWND           hDlg,
  757.    unsigned long  signalState )
  758. {
  759.    HWND  hCtl;
  760.    hCtl = GetDlgItem ( hDlg, IDC_RESET );
  761.    switch ( signalState )
  762.    {
  763.       case VALIDSIGSTATE:
  764.       case INVALIDSIGSTATE:
  765.       {
  766.          EnableWindow ( hCtl, TRUE );
  767.          break;
  768.       }
  769.       case NOSIGNALSTATE:
  770.       case CAPTURENOTRUNNING:
  771.       {
  772.          EnableWindow ( hCtl, FALSE );
  773.          break;
  774.       }
  775.       /* TODO : Could we make the redetect try and restart the capture? */      
  776.       case ERRORSTATE:
  777.       {
  778.          EnableWindow ( hCtl, FALSE );
  779.          break;
  780.       }
  781.       default:
  782.       {
  783.          /* It's probably better to enable the window when we get a strange 
  784.           * signal state. */
  785.          EnableWindow ( hCtl, TRUE );
  786.          return ERROR_INVALID_STATE;
  787.       }
  788.    }
  789.    return 0;
  790. }
  791. /******************************************************************************/
  792. unsigned long
  793. UpdateInputState (
  794.    HWND           hDlg,
  795.    unsigned long  signalState )
  796. {
  797.    HWND  hCtl;
  798.    hCtl = GetDlgItem ( hDlg, IDC_INPUTSOURCE );
  799.    switch ( signalState )
  800.    {
  801.       case VALIDSIGSTATE:
  802.       case INVALIDSIGSTATE:
  803.       case NOSIGNALSTATE:
  804.       {
  805.          EnableWindow ( hCtl, TRUE );
  806.          break;
  807.       }
  808.       
  809.       case CAPTURENOTRUNNING:
  810.       case ERRORSTATE:
  811.       {
  812.          EnableWindow ( hCtl, FALSE );
  813.          break;
  814.       }
  815.       default:
  816.       {
  817.          /* It's probably better to enable the window when we get a strange 
  818.           * signal state. */
  819.          EnableWindow ( hCtl, TRUE );
  820.          return ERROR_INVALID_STATE;
  821.       }
  822.    }
  823.    return 0;
  824. }
  825. /******************************************************************************/
  826. void RGBCBKAPI
  827. ModeChangeFn (
  828.    HWND                 hWnd,
  829.    HRGB                 hRGB,
  830.    PRGBMODECHANGEDINFO  pModeChangedInfo,
  831.    unsigned long        userData )
  832. {
  833.    HWND  hDlg = (HWND)userData;
  834.    if ( hDlg )
  835.    {
  836.       SendMessage ( hDlg, WM_MODECHANGEUPDATE, (WPARAM) NULL, (LPARAM) NULL );
  837.    }
  838. }
  839. /******************************************************************************/
  840. void RGBCBKAPI
  841. NoSignalFn (
  842.    HWND           hWnd,
  843.    HRGB           hRGB,
  844.    unsigned long  userData )
  845. {
  846.    HWND  hDlg = (HWND)userData;
  847.    if ( hDlg )
  848.    {
  849.       SendMessage ( hDlg, WM_NOSIGNALUPDATE, (WPARAM) NULL, (LPARAM) NULL );
  850.    }
  851.    RGBNoSignal ( hRGB );
  852. }
  853. /******************************************************************************/
  854. void RGBCBKAPI
  855. InvalidSignalFn (
  856.    HWND           hWnd,
  857.    HRGB           hRGB,
  858.    unsigned long  horClock,
  859.    unsigned long  verClock,
  860.    unsigned long  userData )
  861. {
  862.    HWND  hDlg = (HWND)userData;
  863.    if ( hDlg )
  864.    {
  865.       SendMessage ( hDlg, WM_INVALIDSIGUPDATE, (WPARAM) NULL, (LPARAM) NULL );
  866.    }
  867.    RGBInvalidSignal ( hRGB, horClock, verClock );
  868. }
  869. /******************************************************************************/
  870. BOOL APIENTRY
  871. InputSettingsDlgProc (
  872.    HWND hDlg,
  873.    UINT message,
  874.    UINT wParam,
  875.    LONG lParam )
  876. {
  877.    BOOL  bReturn = FALSE;
  878.    switch ( message )
  879.    {
  880.       case PROP_SETFOCUS:
  881.       {
  882.          HWND hCtrl;
  883.          hCtrl = GetDlgItem ( hDlg, (int)lParam );
  884.          if ( hCtrl )
  885.             SetFocus ( hCtrl );
  886.          break;
  887.       }
  888.       case WM_HSCROLL:
  889.       {
  890.          int   nScrollCode;
  891.          HWND  hCtl;
  892.          long  minimum, maximum, position;
  893.          nScrollCode = LOWORD ( wParam );
  894.          if ( nScrollCode == SB_ENDSCROLL )
  895.          {
  896.             break;
  897.          }
  898.          hCtl = (HWND)lParam;
  899.          GetTrackBarRange ( hCtl, &minimum, &maximum );
  900.          position = GetTrackBarPos ( hCtl );
  901.          switch ( nScrollCode )
  902.          {
  903.             case SB_LINELEFT:
  904.                if ( position > minimum )
  905.                {
  906.                   position--;
  907.                }
  908.                break;
  909.             case SB_LINERIGHT:
  910.                if ( position < maximum )
  911.                {
  912.                   position++;
  913.                }
  914.                break;
  915.             case SB_PAGELEFT:
  916.                position -= 5;
  917.                if ( position < minimum )
  918.                {
  919.                   position = minimum;
  920.                }
  921.                break;
  922.             case SB_PAGERIGHT:
  923.                position += 5;
  924.                if ( position > maximum )
  925.                {
  926.                   position = maximum;
  927.                }
  928.                break;
  929.             case SB_THUMBTRACK:
  930.             case SB_THUMBPOSITION:
  931.                position = (signed short)HIWORD ( wParam );
  932.                break;
  933.             case SB_LEFT:
  934.                position = minimum;
  935.                break;
  936.             case SB_RIGHT:
  937.                position = maximum;
  938.                break;
  939.          }
  940.          {
  941.             PWINDOW  pWindow;
  942.             pWindow = GetProp ( hDlg, Property );
  943.             if ( pWindow )
  944.             {
  945.                int   nScrollId;
  946.                nScrollId = GetDlgCtrlID ( hCtl );
  947.                SetValueFromSlider ( hDlg, pWindow, nScrollId, position );
  948.                if ( ( nScrollId == IDC_HOROFFSET ) ||
  949.                     ( nScrollId == IDC_VEROFFSET ) ||
  950.                     ( nScrollId == IDC_HORSCALE ) )
  951.                {
  952.                   /* The cropping regions are related to the three capture 
  953.                    * parameters above, update the cropping limits. */
  954.                   UpdateCroppingControls ( hDlg, pWindow );
  955.                }
  956.             }
  957.          }
  958.          if ( nScrollCode != SB_THUMBTRACK )
  959.          {
  960.             SetTrackBarPos ( hCtl, position, TRUE );
  961.          }
  962.          bReturn = TRUE;
  963.          break;
  964.       }
  965.       case WM_COMMAND:
  966.       {
  967.          PWINDOW     pWindow;
  968.          /* WM_COMMAND messages are received before we have a chance to set the
  969.           * property in response to the WM_INITDIALOG message. */
  970.          pWindow = GetProp ( hDlg, Property );
  971.          if ( ( pWindow == 0 ) || ( pWindow->BProgram == FALSE ) )
  972.          {
  973.             break;
  974.          }
  975.          switch ( LOWORD ( wParam ))
  976.          {
  977.             case IDC_TOP:
  978.             case IDC_LEFT:
  979.             case IDC_WIDTH:
  980.             case IDC_HEIGHT:
  981.                if ( HIWORD  ( wParam ) == EN_CHANGE )
  982.                {
  983.                   Cropping ( hDlg, pWindow, pWindow->HCurrentMode, FALSE );
  984.                }
  985.                bReturn = TRUE;
  986.                break;
  987.             case IDC_INPUTSOURCE:
  988.             {
  989.                HWND  hCtl;
  990.                hCtl = (HWND)lParam;
  991.                if ( HIWORD ( wParam ) == CBN_SELCHANGE )
  992.                {
  993.                   SetInputSource ( hDlg, pWindow );
  994.                }
  995.                bReturn = TRUE;
  996.                break;
  997.             }
  998.             case IDC_ADDRWIDTH:
  999.                if ( HIWORD  ( wParam ) == EN_CHANGE )
  1000.                {
  1001.                   AddrWidth ( hDlg, pWindow, FALSE );
  1002.                }
  1003.                bReturn = TRUE;
  1004.                break;
  1005.             case IDC_ADDRHEIGHT:
  1006.                if ( HIWORD  ( wParam ) == EN_CHANGE )
  1007.                {
  1008.                   AddrHeight ( hDlg, pWindow, FALSE );
  1009.                }
  1010.                bReturn = TRUE;
  1011.                break;
  1012.             case IDC_CROPPINGON:
  1013.             case IDC_CROPPINGOFF:
  1014.             {
  1015.                unsigned long  bEnable;
  1016.                
  1017.                bEnable = ( IsDlgButtonChecked ( hDlg, IDC_CROPPINGON ) == 
  1018.                      BST_CHECKED );
  1019.                RGBEnableCropping ( pWindow->HRGB, bEnable );
  1020.                
  1021.                UpdateCroppingState ( hDlg, pWindow, 
  1022.                      ( pWindow->HCurrentMode ) ? TRUE : FALSE );
  1023.                bReturn = TRUE;
  1024.                break;
  1025.             }
  1026.             case IDC_RESET:
  1027.             {
  1028.                RGBResetCapture ( pWindow->HRGB );
  1029.                break;
  1030.             }
  1031.          }
  1032.          break;
  1033.       }
  1034.       case WM_NOTIFY:
  1035.       {
  1036.          LPPSHNOTIFY lpPSHNotify = (LPPSHNOTIFY)lParam;
  1037.          switch ( lpPSHNotify->hdr.code )
  1038.          {
  1039.             case PSN_APPLY: /* The OK or Apply button was pressed. */
  1040.             {
  1041.                LONG     result = PSNRET_NOERROR;
  1042.                PWINDOW  pWindow;
  1043.                pWindow = GetProp ( hDlg, Property );
  1044.                if ( !pWindow )
  1045.                {
  1046.                   /* TODO: What should we do in these circumstances? */
  1047.                   break;
  1048.                }
  1049.                /* Check the input is valid. */
  1050.                {
  1051.                   unsigned long  error;
  1052.                   error = SetInputSource ( hDlg, pWindow );
  1053.                   if ( error )
  1054.                   {
  1055.                      PostMessage ( hDlg, PROP_SETFOCUS, 0, IDC_INPUTSOURCE );
  1056.                      result = PSNRET_INVALID;
  1057.                   }
  1058.                }
  1059.                /* These values cannot be set if there is no signal */
  1060.                if ( pWindow->HCurrentMode )
  1061.                {
  1062.                   if ( IsDlgButtonChecked ( hDlg, IDC_CROPPINGON ) == 
  1063.                         BST_CHECKED )
  1064.                   {
  1065.                      if (( result == PSNRET_NOERROR ) && 
  1066.                            !Cropping ( hDlg, pWindow, pWindow->HCurrentMode, 
  1067.                            TRUE ))
  1068.                      {
  1069.                         result = PSNRET_INVALID;
  1070.                      }
  1071.                   }
  1072.                   if (( result == PSNRET_NOERROR ) && 
  1073.                            !AddrWidth ( hDlg, pWindow, TRUE ))
  1074.                   {
  1075.                      result = PSNRET_INVALID;
  1076.                   }
  1077.                   if (( result == PSNRET_NOERROR ) && 
  1078.                            !AddrHeight ( hDlg, pWindow, TRUE ))
  1079.                   {
  1080.                      result = PSNRET_INVALID;
  1081.                   }
  1082.                }
  1083.                
  1084.                /* If no error occurred and the OK button was pressed, free the
  1085.                 * resources allocated for this page. */
  1086.                if (( result == PSNRET_NOERROR ) && ( lpPSHNotify->lParam ))
  1087.                {
  1088.                   RGBSetModeChangedFn ( pWindow->HRGB, NULL, 0 );
  1089.                   RGBSetNoSignalFn ( pWindow->HRGB, NULL, 0 );
  1090.                   RGBSetInvalidSignalFn ( pWindow->HRGB, NULL, 0 );
  1091.                   RemoveProp ( hDlg, Property );
  1092.                }
  1093.                /* Indicate whether or not property sheet can be destroyed. */
  1094.                SetWindowLong ( hDlg, DWL_MSGRESULT, result );
  1095.                return TRUE;
  1096.             }
  1097.             case PSN_QUERYCANCEL: /* The Cancel button was pressed. */
  1098.                /* Tell Windows it can destroy the property sheet. */
  1099.                SetWindowLong ( hDlg, DWL_MSGRESULT, FALSE );
  1100.                return TRUE;
  1101.             case PSN_KILLACTIVE: /* Page is about to lose activation. */
  1102.                /* Set FALSE because want to allow page to lose activation. */
  1103.                SetWindowLong ( hDlg, DWL_MSGRESULT, FALSE );
  1104.                return TRUE;
  1105.          
  1106.             case UDN_DELTAPOS:
  1107.             {
  1108.                LPNMUPDOWN  lpUpDown = ( LPNMUPDOWN ) lParam;
  1109.                PWINDOW     pWindow;
  1110.                pWindow = GetProp ( hDlg, Property );
  1111.                switch ( lpUpDown->hdr.idFrom )
  1112.                {
  1113.                   /* We test the cropping width using the standard 
  1114.                    * TestAddrWidth. If it is successful it will be a legitimate
  1115.                    * cropping width. */
  1116.                   case IDC_ADDRWIDTHSPIN:
  1117.                   case IDC_WIDTHSPIN:
  1118.                   {
  1119.                      unsigned long  value;
  1120.                      unsigned long  result;
  1121.                      value = lpUpDown->iPos;
  1122.                      do
  1123.                      {
  1124.                         value += lpUpDown->iDelta;
  1125.                         result = RGBTestCaptureWidth ( pWindow->HRGB, value );
  1126.                      }
  1127.                      while ( ( result == RGBERROR_HORADDRTIME_NOT_WORD_DIVISIBLE ) ||
  1128.                              ( result == RGBERROR_HORADDRTIME_NOT_DWORD_DIVISIBLE ) ||
  1129.                              ( result == RGBERROR_HORADDRTIME_NOT_QWORD_DIVISIBLE ) );
  1130.                      if ( result == 0 )
  1131.                      {
  1132.                         /* Calculate the legal delta. */
  1133.                         lpUpDown->iDelta = value - lpUpDown->iPos;
  1134.                      }
  1135.                   }
  1136.                   break;
  1137.                }
  1138.                /* TODO : Do we need to do this for any of the other controls? */
  1139.             }
  1140.             default:
  1141.                return FALSE;
  1142.          }
  1143.          break;
  1144.       }  /* End of case WM_NOTIFY. */
  1145.       case WM_INITDIALOG:
  1146.       {
  1147.          LPPROPSHEETPAGE   pPage = (LPPROPSHEETPAGE)lParam;
  1148.          PWINDOW           pWindow = (PWINDOW)pPage->lParam;
  1149.          unsigned long     state;
  1150.          unsigned long     error;
  1151.          
  1152.          /* Save pWindow. */
  1153.          SetProp ( hDlg, Property, pWindow );
  1154.          /* Set our callbacks. */
  1155.          RGBSetModeChangedFn ( pWindow->HRGB, ModeChangeFn, (unsigned long)hDlg );
  1156.          RGBSetNoSignalFn ( pWindow->HRGB, NoSignalFn, (unsigned long)hDlg );
  1157.          RGBSetInvalidSignalFn ( pWindow->HRGB, InvalidSignalFn, (unsigned long)hDlg );
  1158.          InintialiseInputSource ( hDlg, pWindow );
  1159.          error = RGBGetCaptureState ( pWindow->HRGB, &state );
  1160.          if ( error == 0 )
  1161.          {
  1162.             if ( state == RGB_STATE_CAPTURING )
  1163.             {
  1164.                pWindow->HCurrentMode = TRUE;
  1165.                UpdateControls ( hDlg, pWindow );
  1166.                UpdateControlState ( hDlg, pWindow, TRUE );
  1167.             }
  1168.             else
  1169.             {
  1170.                pWindow->HCurrentMode = 0;
  1171.                UpdateControlState ( hDlg, pWindow, FALSE );
  1172.             }
  1173.             UpdateInputState ( hDlg, state );
  1174.             UpdateRedetectState ( hDlg, state );
  1175.          }
  1176.          else
  1177.          {
  1178.             /* TODO : Error... */
  1179.          }
  1180.          break;
  1181.       }  /* End of case WM_INITDIALOG. */
  1182.       case WM_MODECHANGEUPDATE:
  1183.       {
  1184.          PWINDOW pWindow = GetProp ( hDlg, Property );
  1185.          pWindow->HCurrentMode = TRUE;
  1186.          UpdateControls ( hDlg, pWindow );
  1187.          UpdateControlState ( hDlg, pWindow, TRUE );
  1188.          UpdateRedetectState ( hDlg, VALIDSIGSTATE );
  1189.          break;
  1190.       }
  1191.       case WM_NOSIGNALUPDATE:
  1192.       {
  1193.          PWINDOW pWindow = GetProp ( hDlg, Property );
  1194.          pWindow->HCurrentMode = 0;
  1195.          UpdateControlState ( hDlg, pWindow, FALSE );
  1196.          UpdateRedetectState ( hDlg, NOSIGNALSTATE );
  1197.          break;
  1198.       }
  1199.       case WM_INVALIDSIGUPDATE:
  1200.       {
  1201.          PWINDOW pWindow = GetProp ( hDlg, Property );
  1202.          pWindow->HCurrentMode = 0;
  1203.          UpdateControlState ( hDlg, pWindow, FALSE );
  1204.          UpdateRedetectState ( hDlg, INVALIDSIGSTATE );
  1205.          break;
  1206.       }
  1207.       default:
  1208.          break;
  1209.    }
  1210.    return bReturn;
  1211. }
  1212. /******************************************************************************/
  1213. DWORD WINAPI
  1214. CreatePropertiesDialog (
  1215.    LPVOID   lpParam )
  1216. {
  1217.    unsigned long     error = 0;
  1218.    PWINDOW           pWindow = (PWINDOW)lpParam;
  1219.    int               i;
  1220.    PROPSHEETPAGE     psp[1];
  1221.    PROPSHEETHEADER   psh;
  1222.    /* The pages... */   
  1223.    i = 0;
  1224.    memset ( &psp[i], 0, sizeof ( PROPSHEETPAGE ));
  1225.    psp[i].dwSize = sizeof ( PROPSHEETPAGE );
  1226.    psp[i].dwFlags = PSP_DEFAULT | PSP_HASHELP;
  1227.    psp[i].hInstance = pWindow->HInstance;
  1228.    psp[i].pszTemplate = (LPTSTR) IDD_DISPLAY;
  1229.    psp[i].pszIcon = NULL;
  1230.    psp[i].pfnDlgProc = InputSettingsDlgProc;
  1231.    psp[i].pszTitle = NULL;
  1232.    psp[i].lParam = (LPARAM)pWindow;
  1233.    i++;
  1234.    memset ( &psh, 0, sizeof ( PROPSHEETHEADER ));
  1235.    psh.dwSize = sizeof ( PROPSHEETHEADER );
  1236.    psh.dwFlags = PSH_PROPSHEETPAGE | PSH_HASHELP | PSH_NOCONTEXTHELP;
  1237.    psh.hwndParent = pWindow->HWndParent;
  1238.    psh.hInstance = pWindow->HInstance;
  1239.    psh.pszIcon = NULL;
  1240.    psh.pszCaption = TEXT("Input Settings");
  1241.    
  1242.    psh.nPages = i;
  1243.    psh.nStartPage = 0;
  1244.    psh.ppsp = psp;
  1245.    psh.pszbmWatermark = NULL;
  1246.    
  1247.    if ( PropertySheet ( &psh ) == -1 )
  1248.    {
  1249.       error = GetLastError ( );
  1250.    }
  1251.    return error;
  1252. }
  1253. /******************************************************************************/
  1254. unsigned long
  1255. DoProperties (
  1256.    HINSTANCE      hInstance,
  1257.    HWND           hWndParent,
  1258.    HRGB           hRGB,
  1259.    int            nStartPage )
  1260. {
  1261.    unsigned long  error = 0;
  1262.    PWINDOW        pWindow;
  1263.    HANDLE         thread;
  1264.    pWindow = (PWINDOW)malloc ( sizeof (WINDOW ));
  1265.    if ( pWindow )
  1266.    {
  1267.       pWindow->HInstance = hInstance;
  1268.       pWindow->HWndParent = hWndParent;
  1269.       pWindow->HRGB = hRGB;
  1270.       pWindow->BProgram = FALSE;
  1271.       pWindow->HCurrentMode = TRUE;
  1272.       thread = CreateThread ( NULL, 0, CreatePropertiesDialog, pWindow, 0, NULL );
  1273.       if ( thread )
  1274.       {
  1275.          CloseHandle ( thread );
  1276.          return 0;
  1277.       }
  1278.    }
  1279.    return GetLastError();;
  1280. }