home *** CD-ROM | disk | FTP | other *** search
/ BUG 4 / BUGCD1997_05.BIN / aplic / clip4win / clip4win.exe / C4W30E.HUF / SOURCE / WBTDEMO.ZIP / CELLEDIT.PRG < prev    next >
Text File  |  1995-05-30  |  11KB  |  311 lines

  1.  
  2. #define WIN_WANT_ALL
  3. #include "windows.ch"
  4. #include "dialog.ch"
  5. #include "accel.ch"
  6.  
  7. // foo dialog - include it in your applications resource file
  8. // or things are not going to work very well!  Note we have added
  9. // WS_BORDER...
  10.  
  11. // foo DIALOG 38, 108, 84, 15
  12. // STYLE WS_POPUP | WS_BORDER
  13. // BEGIN
  14. //    CONTROL "", 101, "EDIT", ES_LEFT | ES_AUTOHSCROLL | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 0, 0, 84, 15
  15. // END
  16.  
  17.  
  18. FUNCTION CellEdit( oB, nMsg, nwParamb, nlParamb )
  19.        STATIC aRect := {}
  20.        LOCAL xKeyVal
  21.        LOCAL xData
  22.        LOCAL cPicture
  23.        LOCAL nResults
  24.        LOCAL nField
  25.        LOCAL aCellData
  26.        LOCAL hWnd
  27.        LOCAL aARect
  28.        LOCAL nCrec
  29.        LOCAL lMoved
  30.  
  31.        aRect := GetClientRect( oB:hWnd )
  32.  
  33.        // Filter out the keystrokes we don't want
  34.  
  35.        DO CASE
  36.           CASE nMsg == WM_LBUTTONDBLCLK
  37.           CASE nwParamB == 32
  38.           CASE nwParamB == 13
  39.           CASE nwParamB > 111 .OR.;
  40.                nWparamB < 48
  41.                RETURN( .F. )
  42.        ENDCASE
  43.  
  44.        nField    := oB:GetColCargo( oB:colPos )
  45.        IF nField == NIL
  46.           RETURN( .F. )
  47.        ENDIF
  48.        xKeyVal   := IIF( EMPTY( INDEXKEY() ), NIL, &( INDEXKEY() ) )
  49.        nCrec     := ( oB:alias )->( RECNO() )
  50.        lMoved    := .F.
  51.  
  52.        // This might look crazy but there is logic in the madness!
  53.        // When a modal dialog is active Windows disables it's parent
  54.        // window but leaves other windows active.  To allow us
  55.        // to double click in another cell within the browse window
  56.        // we give the modal dialog used for editing another parent
  57.        // window which we don't care if it becomes inactive since
  58.        // the user can't see it anyway!
  59.  
  60.        hWnd := CreateWindow("DEMO","",WS_EX_TRANSPARENT,0,0,0,0,0,0, _GetInstance() )
  61.        aCellData := oB:GetCellData()
  62.        xData     := FIELDGET( nField )
  63.        cPicture  := aCellData[ 2 ]
  64.  
  65.        // Turn off CTL3D  - if you are not using CTL3D.DLL then you can
  66.        // comment out the following line
  67.  
  68.        Ctl3DUnRegister( _GetInstance() )
  69.        nResults  := DialogBox(_GetInstance() , "foo", hWnd, ;
  70.                     {|hDlg, nMsg, nWparam, nLparam|;
  71.                     MFoo( hDlg, nMsg, nWparam, nLparam, oB, @xData, cPicture, nwParamb, nlParamb, xKeyVal, nField ) })
  72.  
  73.        // Turn 3D effects back on - comment out the next two lines
  74.        // if you are not using CTL3D.DLL
  75.  
  76.        Ctl3DRegister( _GetInstance() )
  77.        Ctl3DAutoSubClass( _GetInstance() )
  78.  
  79.        // This part is important.  Windows is going to send a WM_PAINT message
  80.        // if we click outside the currently active get/edit cell ( don't ask
  81.        // why - it just does!).  To prevent unsightly re-draws we tell Windows
  82.        // that the client area of the WBrowse() window is ok!
  83.  
  84.        // Just in case the user re-sized the browse window while celledit was
  85.        // active we DON'T want to validate the client area...
  86.  
  87.        aARect := GetClientRect( oB:hWnd )
  88.        IF ( aRect[ 3 ] + aRect[ 4 ] == aARect[ 3 ] + aARect[ 4 ] )
  89.           ValidateRect( oB:hWnd )
  90.        ENDIF
  91.  
  92.        lMoved := ( ( oB:alias )->( RECNO() ) != nCrec )
  93.        SetFocus( oB:hWnd )
  94.        ( oB:alias )->( DBGOTO( nCrec ) )
  95.        FIELDPUT( nField, xData )
  96.        COMMIT
  97.        IF EMPTY( INDEXKEY() ) .OR. ( xKeyVal == &( INDEXKEY() ) ) ;
  98.           .AND. !lMoved
  99.           // make sure browse is correctly updated
  100.           oB:refreshCol( oB:colPos)
  101.        ELSE
  102.           // record may have moved relative to other records
  103.           oB:refreshAll()
  104.        ENDIF
  105.        IF nResults == WM_USER+2
  106.           oB:up()
  107.        ENDIF
  108.        IF nResults == WM_USER+1
  109.           oB:down()
  110.        ENDIF
  111.  
  112.        // Get rid of our hidden window
  113.  
  114.        DestroyWindow( hWnd )
  115. RETURN( .T. )
  116.  
  117. // BCellEdit() - Used for BListBox()'s - NOTE the additional param hDlgWnd
  118. // Please note that we don't use a "hidden" window for this one.  The
  119. // way things work in dialogs is a bit different than in "normal" windows.
  120. //
  121. FUNCTION BCellEdit( oB, nMsg, nwParamb, nlParamb, hDlgWnd )
  122.        LOCAL xKeyVal
  123.        LOCAL xData
  124.        LOCAL cPicture
  125.        LOCAL nResults
  126.        LOCAL nField
  127.        LOCAL aCellData
  128.  
  129.        // Filter out the keystrokes we don't want
  130.  
  131.        DO CASE
  132.           CASE nMsg == WM_LBUTTONDBLCLK
  133.           CASE nwParamB == 32
  134.           CASE nwParamB == 13
  135.           CASE nwParamB > 111 .OR.;
  136.                nWparamB < 48
  137.                RETURN( .F. )
  138.        ENDCASE
  139.  
  140.        nField    := oB:GetColCargo( oB:colPos )
  141.        IF nField == NIL
  142.           RETURN( .F. )
  143.        ENDIF
  144.        xKeyVal   := IIF( EMPTY( INDEXKEY() ), NIL, &( INDEXKEY() ) )
  145.        aCellData := oB:GetCellData()
  146.        xData     := FIELDGET( nField )
  147.        cPicture  := aCellData[ 2 ]
  148.        Ctl3DUnRegister( _GetInstance() )
  149.        nResults  := DialogBox(_GetInstance() , "foo", , ;
  150.                     {|hDlg, nMsg, nWparam, nLparam|;
  151.                     MFoo( hDlg, nMsg, nWparam, nLparam, oB, @xData, cPicture, nwParamb, nlParamb, xKeyVal, nField ) })
  152.        Ctl3DRegister( _GetInstance() )
  153.        Ctl3DAutoSubClass( _GetInstance() )
  154.  
  155.        // In this case we tell Windows that the client area of the hidden listbox
  156.        // control/window is ok so we don't get a WM_PAINT message we don't want
  157.  
  158.        // Just in case the user re-sized the browse window while celledit was
  159.        // active we DON'T want to validate the client area...
  160.  
  161.        ValidateRect( GetDlgItem( hDlgWnd, 999 ), GetClientRect( GetDlgItem( hDlgWnd, 999 ) ) )
  162.  
  163.        // This is of special importance! To keep keystrokes going to our BListBox()
  164.        // you HAVE to keep the focus on the hidden listbox control/window since
  165.        // BListBox() has subclassed it internally and gets the keystrokes that way.
  166.        // Setting focus to oB:hWnd is not going to get the job done!  In your dialog
  167.        // procedure you should also set focus back to the hidden edit control/window
  168.        // each time the user switches focus to another control ( after you process
  169.        // it of course!).
  170.  
  171.        SetFocus( GetDlgItem( hDlgWnd, 999 ) )
  172.  
  173.        FIELDPUT( nField, xData )
  174.        COMMIT
  175.        IF EMPTY( INDEXKEY() ) .OR. ( xKeyVal == &( INDEXKEY() ) )
  176.           // make sure browse is correctly updated
  177.           oB:refreshCol( oB:colPos)
  178.        ELSE
  179.           // record may have moved relative to other records
  180.           oB:refreshAll()
  181.        ENDIF
  182.        IF nResults == WM_USER+2
  183.           oB:up()
  184.        ENDIF
  185.        IF nResults == WM_USER+1
  186.           oB:down()
  187.        ENDIF
  188. RETURN( .T. )
  189.  
  190. // MFoo() - Used by both CellEdit() and BCellEdit()
  191. //
  192. STATIC FUNCTION MFoo( hDlgWnd, nMsg, nWparam, nLparam, oB, xData, cPicture, nwParamb, nlParamb, xKeyVal, nField )
  193.        STATIC GetList := {}
  194.        LOCAL hFont
  195.  
  196.        DO CASE
  197.           CASE nMsg == WM_INITDIALOG
  198.                GetList := {}
  199.                PosEditWin( oB, hDlgWnd )
  200.                DoSubClEC( GetDlgItem( hDlgWnd, 101 ), hDlgWnd )
  201.                hFont := oB:colFont
  202.                IF hFont == NIL
  203.                   @ DIALOG hDlgWnd ID 101 GET xData PICTURE IIF(cPicture != NIL,cPicture,"")
  204.                ELSE
  205.                   @ DIALOG hDlgWnd ID 101 GET xData PICTURE IIF(cPicture != NIL,cPicture,"") FONT hFont
  206.                ENDIF
  207.                IF nwParamB != VK_RETURN
  208.                   PostMessage( GetDlgItem( hDlgWnd, 101 ), WM_KEYDOWN, nwParamb, nlParamb )
  209.                ENDIF
  210.                RETURN(1)
  211.  
  212.  
  213.           CASE nMsg == WM_USER+1 .OR.; // down
  214.                nMsg == WM_USER+2 .OR.; // up
  215.                nMsg == WM_USER+3       // click on another cell
  216.  
  217.                IsDialogOk( hDlgWnd, 101 )
  218.                xData:= GetList[1]:VarGet()
  219.                EndDialog( hDlgWnd, nMsg )
  220.                RETURN(1)
  221.  
  222.           CASE nMsg == WM_COMMAND
  223.                DO CASE
  224.                   CASE nWparam == IDOK
  225.                        PostMessage( hDlgWnd, WM_USER+3, 0, 0 )
  226.                        RETURN(1)
  227.  
  228.                   CASE nWparam == IDCANCEL
  229.                        CANCEL DIALOG hDlgWnd
  230.                        EndDialog( hDlgWnd, IDCANCEL )
  231.                        RETURN(1)
  232.               ENDCASE
  233.         ENDCASE
  234. RETURN(0)
  235.  
  236. // Please not the addition of the WM_KILLFOCUS message.
  237. // It tells us when the user clicks in another cell..
  238. //
  239. FUNCTION DoSubClEC(hWnd, hDlgWnd)
  240.        LOCAL nProc
  241.  
  242.  
  243.        nProc := SubClassWindow(hWnd,                               ;
  244.                    {|hWnd, nMsg, nWparam, nLparam|                 ;
  245.                    WndProcEC(nProc, hWnd, nMsg, nWparam, nLparam, hDlgWnd)},;
  246.                    {WM_KEYDOWN, WM_KEYUP, WM_KILLFOCUS})
  247. RETURN(NIL)
  248.  
  249. STATIC FUNCTION WndProcEC(nProc, hWnd, nMsg, nWparam, nLparam, hDlgWnd)
  250.  
  251.        DO CASE
  252.           CASE nMsg == WM_KEYDOWN
  253.                IF nWparam == VK_UP
  254.                   SendMessage( hDlgWnd, WM_USER+2, 0, 0 )
  255.                ELSE
  256.                   IF nWparam == VK_DOWN
  257.                      SendMessage( hDlgWnd, WM_USER+1,0,0 )
  258.                   ENDIF
  259.                ENDIF
  260.           CASE nMsg == WM_KILLFOCUS
  261.                PostMessage( hDlgWnd, WM_USER+3,0,0 )
  262.        ENDCASE
  263. RETURN(CallWindowProc(nProc, hWnd, nMsg, nWparam, nLparam))
  264.  
  265. // No changes here - we still need to keep our window title/border, etc.
  266. // from being re-drawn in the inactive mode..
  267. //
  268. FUNCTION DoSubClBWA(hWnd)
  269.        LOCAL nProc
  270.  
  271.        nProc := SubClassWindow(hWnd,                               ;
  272.                    {|hWnd, nMsg, nWparam, nLparam|                 ;
  273.                    WndProcBWA(nProc, hWnd, nMsg, nWparam, nLparam)},;
  274.                    {WM_NCACTIVATE})
  275. RETURN(NIL)
  276.  
  277. STATIC FUNCTION WndProcBWA(nProc, hWnd, nMsg, nWparam, nLparam)
  278.  
  279.        // IF nWparam is 0 then Windows is telling the window
  280.        // it needs to re-draw things in the inactive mode. If
  281.        // we don't pass the message along things will get messed
  282.        // up so we change the message param to 1 and the window
  283.        // proc will be fooled!
  284.  
  285.        DO CASE
  286.           CASE nMsg == WM_NCACTIVATE
  287.                IF nWparam < 1
  288.                   nWparam := 1
  289.                ENDIF
  290.        ENDCASE
  291. RETURN(CallWindowProc(nProc, hWnd, nMsg, nWparam, nLparam))
  292.  
  293. // Modified Again!
  294. // This one keeps the thick border around the active cell
  295. // You can fiddle around with it if you like but be sure
  296. // to save this one <g>...
  297. //
  298. STATIC FUNCTION PosEditWin( oB, hDlgWnd )
  299.        LOCAL aCell := oB:GetCellRect()
  300.        LOCAL aPoint[2]
  301.        LOCAL nWidth, nHeight
  302.  
  303.        nWidth    := aCell[3]
  304.        nHeight   := aCell[4]
  305.        aPoint[1] := aCell[1]
  306.        aPoint[2] := aCell[2]
  307.        ClienttoScreen(oB:hWnd,aPoint)
  308.        MoveWindow(hDlgWnd,aPoint[1],aPoint[2]-1,nWidth,nHeight+1,.F.)
  309.        MoveWindow(GetDlgItem(hDlgWnd,101),3,1,nWidth-4,nHeight+1,.F.)
  310. RETURN(NIL)
  311.