Adding a real time character count to a memo field dialog bx

Adding a real time character count to a memo field dialog bx

Postby Rick Lipkin » Mon Jul 20, 2020 2:38 pm

To All

I would like to be able to show a "real time" character count when you start typing a memo field .. I have some long string text fields that I have to make sure the character count does not exceed the maximum table field length .. The reason I want to enforce a strict field limit is the text will eventually fit into an program generated e-mail. I do not want someone writing a 1000 char message that I have to format in a limited space to fit into an e-mail .. hence why I use a fixed length char() field.

Here is my code .. the Table field is a Sql char(200) or char(400) text field ( nlen parameter ) .. again, I do not want an unlimited Sql "Text" field ..

Code: Select all  Expand view

DEFINE DIALOG oUSERS RESOURCE "MEMO" ;
       TITLE cTITLE              ;

cSay1 := "Maximum "+alltrim(str(nLen))+" Charactors"
REDEFINE SAY oSay1 var cSay1 ID 195 of oUsers UPDATE
oSay1:SetColor(nRgb(7,7,224))

IF cMODE = "E" .or. cMode = "P"

   REDEFINE GET oMEMO      VAR cMEMO MEMO ID 130 of oUSERS UPDATE

ELSE     // view

   REDEFINE GET oMEMO      VAR cMEMO MEMO ID 130 of oUSERS COLOR CLR_BLACK, 16053492 READONLY

ENDIF


          oMemo:bGotFocus = { || oMemo:SetSel( 0, 0 ),;
                         oMemo:Goto( oMemo:GetLineCount() ),;
                         __Keyboard( Chr( VK_HOME ) ) }
   
REDEFINE BTNBMP oButt1 ID 111 ;     // ok
         RESOURCE "Ok" ;
         PROMPT "Save" LEFT 2007;
         ACTION (lOK := _Doit1(oRsTrav, @cMEMO, nLEN, oMEMO, cMODE, cButton ), ;
                 IF( lOK = .T., ( oUSERS:END(), oBtn1:Enable() ) ,)  );      
         GRADIENT GreyButtonGrad()

REDEFINE BTNBMP oButt2 ID 112 ;     // cancel
         RESOURCE "CANCEL" ;
         PROMPT "Cancel" LEFT 2007;
         ACTION oUSERS:END();
         GRADIENT GreyButtonGrad()

ACTIVATE DIALOG oUSERS ;
         ON INIT (If( cMode = "V", oButt1:Disable(), )) ;
         VALID (!GETKEYSTATE( 27 ))  // do not allow esc key here

If cMode = "V"
Else

   oBtn1:Enable()
   cDesignation := cMemo

   SysReFresh()

Endif


oBtn2:Enable()
oBtn3:Enable()

RETURN( NIL )

//-----------------------------
// this function counts the number of characters in the memo string and warns if the length is >= to nLen

Static FUNC _Doit1( oRs, cMEMO, nLEN, oMEMO, cMODE, cButton )

LOCAL SAYING, nLENGTH, nSel

IF cMODE = 'V'
   RETURN(.T.)
ENDIF

cMEMO    := ALLTRIM( cMEMO )
nLENGTH  := LEN( cMEMO )

IF xWRITE = "Y" .or. xSUPER = "Y" .or. xADMIN = 'Y'

   IF nLENGTH > nLEN

      StandardGrad()

      SAYING := "WARNING .. your text is "+alltrim(STR(nLENGTH))+" charactors"+CRLF
      SAYING += "and the Database Table will only hold "+alltrim(str(nLen))+" charactors"+CRLF

      nSel := Alert( Saying ,;
                    { "Return and Make Changes", "Truncate Text to "+alltrim(STR(nLEN))+" Charactors" })

      Do Case
      Case nSel = 1
         oMemo:Setfocus()
         SysReFresh()

         Return(.f.)
      Case nSel = 2
         cMEMO := SUBSTR( cMEMO,1,nLEN )
         oMemo:ReFresh()
         oMemo:SetFocus()
         SysReFresh()
         Return(.f.)
      OtherWIse
         cMEMO := SUBSTR( cMEMO,1,nLEN )
         oMemo:ReFresh()
         oMemo:SetFocus()
         SysReFresh()
         Return(.f.)
      ENdCase

   ENDIF

ENDIF

RETURN(.T.)

 


What I would like to do is add a counter field to the diablg box to show the number of characters being typed in real time ??

Thanks
Rick Lipkin
User avatar
Rick Lipkin
 
Posts: 2633
Joined: Fri Oct 07, 2005 1:50 pm
Location: Columbia, South Carolina USA

Re: Adding a real time character count to a memo field dialog bx

Postby Enrico Maria Giordano » Mon Jul 20, 2020 3:21 pm

This is a sample with counter and limited text to 100 chars:

Code: Select all  Expand view
#include "Fivewin.ch"


#define EM_LIMITTEXT 197


FUNCTION MAIN()

    LOCAL oDlg

    LOCAL oGet, cVar := ""

    LOCAL oSay

    DEFINE DIALOG oDlg

    @ 1, 1 GET oGet VAR cVar MEMO;
           SIZE 100, 30

    oGet:bKeyDown = { || SysRefresh(), oSay:Refresh( .F. ) }

    @ 3, 1 BUTTON "&Close" ACTION oDlg:End()

    @ 3, 10 SAY oSay PROMPT STR( LEN( cVar ) )

    ACTIVATE DIALOG oDlg;
             ON INIT oGet:SendMsg( EM_LIMITTEXT, 100, 0 );
             CENTER

    RETURN NIL


EMG
User avatar
Enrico Maria Giordano
 
Posts: 8356
Joined: Thu Oct 06, 2005 8:17 pm
Location: Roma - Italia

Re: Adding a real time character count to a memo field dialog bx

Postby Horizon » Mon Jul 20, 2020 4:59 pm

Maybe like this.

Code: Select all  Expand view
    @ 50,10 SAY oSay PROMPT "Mesaj" OF oDlg PIXEL
    @ 48,40 GET oGovde VAR Govde OF oDlg PIXEL SIZE 110,10 UPDATE MEMO ;
            ON CHANGE (oSayac:VarPut("("+NTRIM(LEN(oGovde:GetText()))+")"),;
                oSayac:Refresh())
   
    @ 62,10 SAY oSayac PROMPT "(Boş)" OF oDlg PIXEL SIZE 30,10
   
Regards,

Hakan ONEMLI

Harbour & MSVC 2022 & FWH 23.04
Horizon
 
Posts: 1288
Joined: Fri May 23, 2008 1:33 pm

Re: Adding a real time character count to a memo field dialog bx

Postby Rick Lipkin » Mon Jul 20, 2020 6:31 pm

Enrico

Thank you for your responce .. been a while since we had a chance to chat ... I am having difficulty translating your code into using resources ..

this is my current code .. I can get it to initially come up but when I click on the get field .. the code blows up ..

Code: Select all  Expand view

//------------------------------------
Static FUNC _ViewMemo4( cMODE, oRsTrav, cTABLENAME, oBtn1,oBtn2,oBtn3,oBtn4,oBtn5,cButton,cBenefits,nLen,cPrevAppr )       // benefits button

#define EM_LIMITTEXT 197

LOCAL SAYING, oUSERS, cTITLE, oMEMO, cMEMO
LOCAL lOK, oButt1,oButt2

Local oSay1,cSay1
Local oSay

IF EMPTY( cMODE )
   cMODE := "V"
ENDIF

IF xWRITE = "Y" .or. xSUPER = "Y" .or. xADMIN = 'Y'
ELSE
   cMODE := "V"
ENDIF

IF oRsTrav:eof
   SAYING := "SORRY ... Before you can Write a Memo "
   SAYING += "a Record must Already Exist"
   MsgInfo( SAYING )
   RETURN( .F. )
ENDIF

oBtn1:Disable()
oBtn2:Disable()
oBtn3:Disable()

LightGreyGrad()

DO CASE
CASE cMODE = "A"
   cTitle := cTABLENAME+" Table Memo for     'Purpose or Benefits Text'     ADD"
   cMEMO := space(nlen)    // 200

CASE cMODE = "E"
   cTitle := cTABLENAME+" Table Memo for     'Purpose or Benefits Text'     EDIT"
   cMemo := cBenefits

CASE cMODE = "V"
   cTitle := cTABLENAME+" Table Memo for     'Purpose or Benefits Text'     VIEW"
   cMEMO := oRsTrav:Fields("Benefits"):Value

CASE cMODE = "P"
   cTITLE := cTABLENAME+" Table Memo     Approval Info VIEW"
   cMEMO := oRsTrav:Fields("Benefits"):Value

ENDCASE

DEFINE DIALOG oUSERS RESOURCE "MEMO" ;
       TITLE cTITLE              ;

     cSay1 := "Maximum "+alltrim(str(nLen))+" Charactors"
     REDEFINE SAY oSay1 var cSay1 ID 195 of oUsers UPDATE
     oSay1:SetColor(nRgb(7,7,224))

     REDEFINE SAY oSay PROMPT Str(len(cMemo)) ID 196 of oUsers //UPDATE

     IF cMODE = "E" .or. cMode = "P"

        REDEFINE GET oMEMO      VAR cMEMO MEMO ID 130 of oUSERS UPDATE

     ELSE     // view

        REDEFINE GET oMEMO      VAR cMEMO MEMO ID 130 of oUSERS COLOR CLR_BLACK, 16053492 READONLY

    ENDIF

  *  oMemo:bGotFocus = { || oMemo:SetSel( 0, 0 ),;                           // blows up had to rem'd out
  *                        oMemo:Goto( oMemo:GetLineCount() ),;
  *                       __Keyboard( Chr( VK_HOME ) ) }

    oMemo:bKeyDown = { SysReFresh(), oSay:ReFresh() } // .f. ) }


    REDEFINE BTNBMP oButt1 ID 111 ;     // ok
         RESOURCE "Ok" ;
         PROMPT "Save" LEFT 2007;
         ACTION (lOK := _Doit1(oRsTrav, @cMEMO, nLEN, oMEMO, cMODE, cButton ), ;
                 IF( lOK = .T., ( oUSERS:END(), oBtn1:Enable() ) ,)  );
         GRADIENT GreyButtonGrad()

    REDEFINE BTNBMP oButt2 ID 112 ;     // cancel
         RESOURCE "CANCEL" ;
         PROMPT "Cancel" LEFT 2007;
         ACTION oUSERS:END();
         GRADIENT GreyButtonGrad()

ACTIVATE DIALOG oUSERS ;
         ON INIT (oMemo:SendMsg( EM_LIMITTEXT,100,0 ),If( cMode = "V", oButt1:Disable(), )) ;
         VALID (!GETKEYSTATE( 27 ))  // do not allow esc key here

If cMode = "V"
Else

   oBtn1:Enable()
   cBenefits := cMemo

   SysReFresh()

Endif


oBtn2:Enable()
oBtn3:Enable()

RETURN( NIL )

 


Here is Memo.rc

Code: Select all  Expand view

// Generated by ResEdit 1.6.6
// Copyright (C) 2006-2015
// http://www.resedit.net

#include <windows.h>
#include <commctrl.h>
//#include "resource.h"

#ifndef WC_STATIC
#define WC_STATIC L"Static"
#endif

#ifndef MONTHCAL_CLASS
#define MONTHCAL_CLASS "SysMonthCal32"
#endif

#ifndef DATETIMEPICK_CLASS
#define DATETIMEPICK_CLASS "SysDateTimePick32"
#endif

//
// Dialog resources
//
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
MEMO DIALOG 150, 47, 353, 135
STYLE DS_MODALFRAME | DS_SETFONT | WS_CAPTION | WS_POPUP
FONT 6, "MS Sans Serif"
{
    EDITTEXT        196, 107, 102, 25, 12, WS_DISABLED, WS_EX_LEFT
    LTEXT           "Max 400 char", 195, 4, 103, 95, 9, SS_LEFT | SS_NOPREFIX, WS_EX_LEFT
    EDITTEXT        130, 40, 8, 307, 80, WS_VSCROLL | ES_MULTILINE | ES_WANTRETURN, WS_EX_LEFT
    CONTROL         "Ok", 111, "TBtnBmp", 0x50010020, 247, 100, 45, 24, 0x00000000
    LTEXT           "Memo", 194, 3, 11, 35, 9, SS_LEFT | SS_NOPREFIX, WS_EX_LEFT
    CONTROL         "Cancel", 112, "TBtnBmp", 0x50010020, 300, 100, 45, 24, 0x00000000
}

 


Passing the variable cBenefits which I initializes cMemo .. from there I have tried to interpret your code and failed ..

Code: Select all  Expand view

Application
===========
   Path and name: C:\Fox\DOI\LeavTrav\LeaveW32.Exe (32 bits)
   Size: 6,641,664 bytes
   Compiler version: xHarbour 1.2.3 Intl. (SimpLex) (Build 20200311)
   FiveWin  version: FWH 20.06
   C compiler version: Borland/Embarcadero C++ 7.4 (32-bit)
   Windows version: 6.2, Build 9200

   Time from start: 0 hours 0 mins 14 secs
   Error occurred at: 07/20/2020, 14:09:54
   Error description: Error BASE/1004  Class: 'ARRAY' has no exported method: EVAL
   Args:
     [   1] = A   { ... } length: 2
     [   2] = N   75
     [   3] = N   2424833
     [   4] = O   TMULTIGET

Stack Calls
===========
   Called from:  => EVAL( 0 )
   Called from: .\source\classes\WINDOW.PRG => TWINDOW:KEYDOWN( 2867 )
   Called from: .\source\classes\CONTROL.PRG => TCONTROL:KEYDOWN( 1114 )
   Called from: .\source\classes\MGET.PRG => TMULTIGET:KEYDOWN( 661 )
   Called from:  => TWINDOW:HANDLEEVENT( 0 )
   Called from: .\source\classes\CONTROL.PRG => TMULTIGET:HANDLEEVENT( 1827 )
   Called from: .\source\classes\WINDOW.PRG => _FWH( 3559 )
   Called from:  => DIALOGBOX( 0 )
   Called from: .\source\classes\DIALOG.PRG => TDIALOG:ACTIVATE( 304 )
   Called from: REQUEST.PRG => _VIEWMEMO4( 4035 )
   Called from: REQUEST.PRG => (b)_REQUEST( 1447 )
 


Appreciate any suggestions ...

Thanks
Rick Lipkin
User avatar
Rick Lipkin
 
Posts: 2633
Joined: Fri Oct 07, 2005 1:50 pm
Location: Columbia, South Carolina USA

Re: Adding a real time character count to a memo field dialog bx

Postby Enrico Maria Giordano » Mon Jul 20, 2020 7:26 pm

Sorry, I can't help you without a sample that I can compile and run here.

EMG
User avatar
Enrico Maria Giordano
 
Posts: 8356
Joined: Thu Oct 06, 2005 8:17 pm
Location: Roma - Italia

Re: Adding a real time character count to a memo field dialog bx

Postby Rick Lipkin » Mon Jul 20, 2020 9:40 pm

Enrico

Try this code ... I get an initial value .. of 179 .. but the len of cMemo is not updated as you type in more charactors ..

Thanks
Rick

Code: Select all  Expand view

#include "Fivewin.ch"
#define EM_LIMITTEXT 197


FUNCTION MAIN()

LOCAL oDlg
LOCAL cMemo, oMemo, cTitle
LOCAL oSay,cSay



cMemo := "Many years experience with and a good understanding of IP networking, IP printing, SMTP "
cMemo += "routing for multi-function printers, scanners, copiers and general configurations of Cisco "

cTITLE := "Request Table Memo for     'Travel Rejection Text'    EDIT"
cSay   := "Number of Charactors Typed"


DEFINE DIALOG oDlg RESOURCE "MEMO" ;
       TITLE cTITLE

       REDEFINE GET oMemo VAR cMEMO MEMO ID 130 of oDlg UPDATE

       oMemo:bGotFocus = { || oMemo:SetSel( 0, 0 ),;
                         oMemo:Goto( oMemo:GetLineCount() ),;
                         __Keyboard( Chr( VK_HOME ) ) }

       REDEFINE SAY oSay VAR str(len(cMemo)) ID 196 of oDlg UPDATE

       REDEFINE BTNBMP oButt1 ID 111 ;     // ok
         RESOURCE "Ok" ;
         PROMPT "Save" LEFT 2007;
         ACTION ( oDlg:End() )

       REDEFINE BTNBMP oButt2 ID 112 ;     // cancel
         RESOURCE "CANCEL" ;
         PROMPT "Cancel" LEFT 2007;
         ACTION oDLg:ENd()


ACTIVATE DIALOG oDlg ;
         ON INIT oMemo:SendMsg( EM_LIMITTEXT,500,0);
         VALID (!GETKEYSTATE( 27 ))  // do not allow esc key here

Return(nil)
 


Here is the Memo.rc

Code: Select all  Expand view

// Generated by ResEdit 1.6.6
// Copyright (C) 2006-2015
// http://www.resedit.net

#include <windows.h>
#include <commctrl.h>
//#include "resource.h"

#ifndef WC_STATIC
#define WC_STATIC L"Static"
#endif

#ifndef MONTHCAL_CLASS
#define MONTHCAL_CLASS "SysMonthCal32"
#endif

#ifndef DATETIMEPICK_CLASS
#define DATETIMEPICK_CLASS "SysDateTimePick32"
#endif

//
// Dialog resources
//
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
MEMO DIALOG 150, 47, 353, 135
STYLE DS_MODALFRAME | DS_SETFONT | WS_CAPTION | WS_POPUP
FONT 6, "MS Sans Serif"
{
    EDITTEXT        196, 107, 102, 45, 12, WS_DISABLED | NOT WS_TABSTOP, WS_EX_LEFT
    LTEXT           "Max 400 char", 195, 4, 103, 95, 9, SS_LEFT | SS_NOPREFIX, WS_EX_LEFT
    EDITTEXT        130, 40, 8, 307, 80, WS_VSCROLL | ES_MULTILINE | ES_WANTRETURN, WS_EX_LEFT
    CONTROL         "Ok", 111, "TBtnBmp", 0x50010020, 247, 100, 45, 24, 0x00000000
    LTEXT           "Memo", 194, 3, 11, 35, 9, SS_LEFT | SS_NOPREFIX, WS_EX_LEFT
    CONTROL         "Cancel", 112, "TBtnBmp", 0x50010020, 300, 100, 45, 24, 0x00000000
}
 
User avatar
Rick Lipkin
 
Posts: 2633
Joined: Fri Oct 07, 2005 1:50 pm
Location: Columbia, South Carolina USA

Re: Adding a real time character count to a memo field dialog bx

Postby Horizon » Tue Jul 21, 2020 6:41 am

Rick,

Change this.
Code: Select all  Expand view
      REDEFINE GET oMemo VAR cMEMO MEMO ID 130 of oDlg UPDATE ;
                    ON CHANGE (oSay:VarPut(ALLTRIM(str(LEN(oMemo:GetText())))),;
                oSay:Refresh())
Regards,

Hakan ONEMLI

Harbour & MSVC 2022 & FWH 23.04
Horizon
 
Posts: 1288
Joined: Fri May 23, 2008 1:33 pm

Re: Adding a real time character count to a memo field dialog bx

Postby Rick Lipkin » Tue Jul 21, 2020 12:54 pm

Hakan

Thank you VERY much for your input and nicely done.. works perfectly .. Enrico .. again that you very much for your help!!

Rick Lipkin
User avatar
Rick Lipkin
 
Posts: 2633
Joined: Fri Oct 07, 2005 1:50 pm
Location: Columbia, South Carolina USA


Return to FiveWin for Harbour/xHarbour

Who is online

Users browsing this forum: Google [Bot] and 38 guests