CODE: Help in controls, now, so easy.

Post Reply
Rochinha
Posts: 309
Joined: Sun Jan 08, 2006 10:09 pm
Location: Brasil - Sao Paulo
Contact:

CODE: Help in controls, now, so easy.

Post by Rochinha »

Friends,

Compile the code below, run application, press F2 in a GET, CHECKBOX or COMBOBOX, put the help text for control and confirm.

Press F2 again in control and, Huaalaaaaaá!

Anota.PRG

Code: Select all

#include "FiveWin.ch"
#include "btnget.ch"

#include "anota.ch"

#command OPEN <(db)>                                                    ;
             [VIA <rdd>]                                                ;
             [ALIAS <a>]                                                ;
             [<new: NEW>]                                               ;
             [<ex: EXCLUSIVE>]                                          ;
             [<sh: SHARED>]                                             ;
             [<ro: READONLY>]                                           ;
             [INDEX <(index1)> [, <(indexn)>]]                          ;
       => if Select( <(db)> )==0                                        ;
         ;   dbUseArea( <.new.>, <rdd>, <(db)>, <(a)>, if(<.sh.> .or. <.ex.>, !<.ex.>, NIL), <.ro.>, 0 )[; dbSetIndex( <(db)> )];
         ; else                                                         ;
         ;   dbSelectArea( <(db)> )                                     ;
         ; end

//----------------------------------------------------------------------------//
function Main()

   local oDlg
   local cCtrl9000 := SPACE(45)  ,;
         nCtrl9001 := 1          ,;
         lCtrl9007 := .F.        ,;
         cCtrl9008 := "CADASTRO" ,;
         nCtrl9009 := 3          ,;
         nCtrl9012 := 1          ,;
         nCtrl9013 := 1          ,;
         dCtrl9014 := DATE()     ,;
         dCtrl9015 := DATE()
   aCtrl9008 := { "CADASTRO", "ANIVERSARIO", "ULTIMA COMPRA" }

   // ************************************************
   Request DBFCDX
   RddRegister('DBFCDX',1)
   RddSetDefault('DBFCDX')
   Request OrdKeyNo
   Request OrdKeyCount
   // ************************************************

   // ************************************************
   idTheHelp := "SHOWPAINEL"
   SetKey( VK_F2, nil )
   // ************************************************

   SET _3DLOOK ON
   DEFINE DIALOG oDlgPainel RESOURCE "dlgPainel"

   REDEFINE GET      oCtrl9000 VAR cCtrl9000 ID 9000 PICTURE "@!" OF oDlgPainel
   REDEFINE RADIO    oCtrl9001 VAR nCtrl9001 ID 9001,9002 ON CHANGE oCtrl9101:Enable() OF oDlgPainel
   REDEFINE CHECKBOX oCtrl9007 VAR lCtrl9007 ID 9007 ON CHANGE oCtrl9008:Enable() OF oDlgPainel
   REDEFINE COMBOBOX oCtrl9008 VAR cCtrl9008 ID 9008 ITEMS aCtrl9008 OF oDlgPainel WHEN lCtrl9007
   REDEFINE RADIO    oCtrl9009 VAR nCtrl9009 ID 9009,9010,9011 ON CHANGE oCtrl9012:Enable() OF oDlgPainel
   REDEFINE GET      oCtrl9012 VAR nCtrl9012 ID 9012 PICTURE "999" WHEN lCtrl9007 .AND. nCtrl9009 = 1 OF oDlgPainel ;
            VALID nCtrl9012 >= 0 ;
            SPINNER ;
            ON UP   (++nCtrl9012,oCtrl9012:Refresh(),nCtrl9009:=1,oCtrl9009:Refresh(),oCtrl9101:Enable()) ;
            ON DOWN (--nCtrl9012,oCtrl9012:Refresh(),nCtrl9009:=1,oCtrl9009:Refresh(),oCtrl9101:Enable()) MIN 1
   REDEFINE GET      oCtrl9013 VAR nCtrl9013 ID 9013 PICTURE "999" WHEN lCtrl9007 .AND. nCtrl9009 = 2 OF oDlgPainel ;
            VALID nCtrl9013 >= 0 ;
            SPINNER ; 
            ON UP   (++nCtrl9013,oCtrl9013:Refresh(),nCtrl9009:=2,oCtrl9009:Refresh(),oCtrl9101:Enable()) ;
            ON DOWN (--nCtrl9013,oCtrl9013:Refresh(),nCtrl9009:=2,oCtrl9009:Refresh(),oCtrl9101:Enable()) MIN 1
   REDEFINE BTNGET   oCtrl9014 VAR dCtrl9014 ID 9014 WHEN lCtrl9007 .AND. nCtrl9009 = 3 ;
            RESOURCE "calen" OF oDlgPainel SPINNER ;
            ON UP   (++dCtrl9014,oCtrl9014:Refresh(),nCtrl9009:=3,oCtrl9009:Refresh(),oCtrl9101:Enable()) ;
            ON DOWN (--dCtrl9014,oCtrl9014:Refresh(),nCtrl9009:=3,oCtrl9009:Refresh(),oCtrl9101:Enable()) ;
            ACTION (aRect       := GetCoors(oCtrl9014:hWnd),;
                    dCtrl9014   := FwCalendar(dCtrl9014,aRect[1],aRect[4],oDlgPainel),;
                    oCtrl9014:Refresh())
   REDEFINE BTNGET   oCtrl9015 VAR dCtrl9015 ID 9015 WHEN lCtrl9007 .AND. nCtrl9009 = 3 ;
            RESOURCE "calen" OF oDlgPainel SPINNER ;
            ON UP   (++dCtrl9015,oCtrl9015:Refresh(),nCtrl9009:=3,oCtrl9009:Refresh(),oCtrl9101:Enable()) ;
            ON DOWN (--dCtrl9015,oCtrl9015:Refresh(),nCtrl9009:=3,oCtrl9009:Refresh(),oCtrl9101:Enable()) ;
            ACTION (aRect       := GetCoors(oCtrl9015:hWnd),;
                    dCtrl9015  := FwCalendar(dCtrl9015,aRect[1],aRect[4],oDlgPainel),;
                    oCtrl9015:Refresh())
   REDEFINE BUTTON   oCtrl9101 ID 9101 OF oDlgPainel ACTION .t.
   oCtrl9008:Disable()
   oCtrl9013:Disable()
   oCtrl9014:Disable()
   oCtrl9015:Disable()

   ACTIVATE DIALOG oDlgPainel CENTERED

   // ************************************************
   SetKey( VK_F2, fun() )
   // ************************************************

   return

function fun()
   return .t.
/*
 ***********************************
 * FUNCAO: Help on-line
 *
 * MODO DE USO:
 *
 * SetKey( VK_F2, nil )
 * DEFINE DIALOG oDlgm RESOURCE "dlgPDVMedVL"
 *        ...
 *        REDEFINE GET oGet123 ...
 *        ...
 *        oGet123:bKeyDown := {|nKey,bFlags| iif( nKey==VK_F2, TheHelp( CtrlSearch(oDlgm) ), .t.) }
 *        ...
 * endif
 * ACTIVATE DIALOG oDlgm CENTERED
 * SetKey( VK_F2, { || RemitePedido() } )
 ***********************************
 */
function TheHelp( idCtrl )
   local cProcName := Padr(ProcName( 1 ),20)
   local nProcLine := 0 // ProcLine( 0 )
   local cProcCtrl := StrZero( idCtrl, 4 )
   local cTexto    := Space( 200 )
   local oldArea   := Select()
   local aStru
   if ValType( idTheHelp ) = "U"
      MsgHelpFancy( "Desculpe, a variavel de controle idThehelp nao foi configurada neste modulo...", "" ) 
      return nil
   endif
   cProcName := Padr( idTheHelp, 20 )
   if !file( "HELP.DBF" )
      aStru  := { { "PROG"    ,"C" , 20, 0 } , ; 
                  { "LINHA"   ,"C" ,  6, 0 } , ; 
                  { "VARIAVEL","C" ,  4, 0 } , ; 
                  { "TEXTO"   ,"C" ,255, 0 } } 
      dbCreate( "HELP.DBF", aStru ) 
   endif
   if !file( "HELP.CDX" ) 
      use help exclusive
      index on prog+linha+variavel to help
      use
   endif
   open help shared new 
   set index to help
   dbGotop()
   dbSeek( cProcName+StrZero(nProcLine,6)+cProcCtrl )
   if !found()
      MsgGet( "Digite uma ajuda", "Conteudo:", @cTexto )
      if .not. empty(cTexto)
         dbAppend()
         help->PROG     := cProcName
         help->LINHA    := STRZERO(nProcLine,6)
         help->VARIAVEL := cProcCtrl
         help->TEXTO    := cTexto
      endif
   else
      cTexto         := TEXTO 
      MsgHelpFancy( If( Empty( cTexto ), "Desculpe, nenhuma ajuda foi configurada...", Alltrim( cTexto ) ) )
   endif
   Select( oldArea )
   return nil

STATIC Function HelpIndex()
   Keyboard( VK_F1 )
   return nil

/*
 * SOURCE: NewHelp.prg
 */
function MsgHelpFancy( cMsg )
   PUBLIC lNoPaint := .f.
   DEFINE BRUSH oHBrush STYLE NULL
   DEFINE FONT oFont NAME "Arial" SIZE 0, -9
   DEFINE DIALOG oWndHelp TITLE "Ajuda" SIZE 400,150 BRUSH oHBrush STYLE WS_POPUP
          @ 20,50 SAY oSay VAR cMsg SIZE 110,20 OF oWndHelp COLOR nRGB(000,000,000),nRGB(255,250,141) PIXEL FONT oFont
   ACTIVATE DIALOG oWndHelp CENTERED ;
            ON PAINT ShowHelpBmp( oWndHelp, "genie1", "genie2" ) 

function ShowHelpBmp( oWndHelp, cBmp1, cBmp2 )
   local hDC  := oWndHelp:hDC
   local oBmp1, oBmp2
   DEFINE BITMAP oBmp1 RESOURCE cBmp1
   DEFINE BITMAP oBmp2 RESOURCE cBmp2
   DrawBitmap( hDC, oBmp2:hBitmap, 0, 0, 0, 0, 15597702 )
   DrawBitmap( hDC, oBmp1:hBitmap, 0, 0, 0, 0, 8913094 )
   oBmp1:End()
   oBmp2:End()
   return nil
Anota.RC

Code: Select all

dlgPainel DIALOG 19, 22, 126, 156
STYLE DS_MODALFRAME | 0x4L | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Painel de Filtragem"
FONT 8, "Helv"
{
 EDITTEXT 9000, 4, 12, 118, 12
 CONTROL "Iniciando", 9001, "BUTTON", BS_AUTORADIOBUTTON, 4, 27, 42, 12
 CONTROL "Contendo", 9002, "BUTTON", BS_AUTORADIOBUTTON, 60, 27, 54, 12
 CHECKBOX " Data", 9007, 5, 41, 60, 12, BS_AUTOCHECKBOX | WS_TABSTOP
 COMBOBOX 9008, 17, 56, 105, 50, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
 CONTROL "nos ultimos", 9009, "BUTTON", BS_AUTORADIOBUTTON, 16, 72, 47, 12
 EDITTEXT 9012, 64, 72, 25, 12, WS_BORDER | WS_VSCROLL | WS_TABSTOP
 CONTROL "nos ultimos", 9010, "BUTTON", BS_AUTORADIOBUTTON, 16, 88, 46, 12
 EDITTEXT 9013, 64, 88, 25, 12, WS_BORDER | WS_VSCROLL | WS_TABSTOP
 CONTROL "entre", 9011, "BUTTON", BS_AUTORADIOBUTTON, 16, 104, 34, 12
 EDITTEXT 9014, 54, 105, 66, 12, WS_BORDER | WS_VSCROLL | WS_TABSTOP
 EDITTEXT 9015, 54, 121, 66, 12, WS_BORDER | WS_VSCROLL | WS_TABSTOP
 LTEXT "Procurar por nomes", 99, 4, 2, 70, 8
 LTEXT "meses", 98, 93, 74, 23, 8
 LTEXT "dias", 97, 93, 90, 18, 8
 PUSHBUTTON "Executar pesquisa", 9101, 4, 138, 118, 14
}

genie1 BITMAP "c:/fivewin/bitmaps/genie1.bmp"
genie2 BITMAP "c:/fivewin/bitmaps/genie2.bmp"
Anota.CH

Code: Select all

#xcommand REDEFINE GET [ <oGet> VAR ] <uVar> ;
             [ <memo: MULTILINE, MEMO, TEXT> ] ;
             [ ID <nId> ] ;
             [ <dlg: OF, WINDOW, DIALOG> <oDlg> ] ;
             [ <help:HELPID, HELP ID> <nHelpId> ] ;
             [ <color: COLOR,COLORS> <nClrFore> [,<nClrBack>] ] ;
             [ FONT <oFont> ] ;
             [ CURSOR <oCursor> ] ;
             [ MESSAGE <cMsg> ] ;
             [ <update: UPDATE> ] ;
             [ WHEN <uWhen> ] ;
             [ <readonly: READONLY, NO MODIFY> ] ;
             [ VALID <uValid> ] ;
             [ ON CHANGE <uChange> ] ;
       => ;
          [ <oGet> := ] TMultiGet():ReDefine( <nId>, bSETGET(<uVar>),;
             <oDlg>, <nHelpId>, <nClrFore>, <nClrBack>, <oFont>, <oCursor>,;
             <cMsg>, .t., <{uWhen}>, <.readonly.>, <{uValid}>,;
             [\{|nKey, nFlags, Self| <uChange>\}] ) ;;
          <oGet>:bKeyDown := {|nKey,bFlags| iif( nKey==VK_F2, TheHelp( <nId> ), .t.) }

#xcommand REDEFINE GET [ <oGet> VAR ] <uVar> ;
             [ ID <nId> ] ;
             [ <dlg: OF, WINDOW, DIALOG> <oDlg> ] ;
             [ <help:HELPID, HELP ID> <nHelpId> ] ;
             [ VALID   <ValidFunc> ]       ;
             [ <pict: PICT, PICTURE> <cPict> ] ;
             [ <color:COLOR,COLORS> <nClrFore> [,<nClrBack>] ] ;
             [ FONT <oFont> ] ;
             [ CURSOR <oCursor> ] ;
             [ MESSAGE <cMsg> ] ;
             [ <update: UPDATE> ] ;
             [ WHEN <uWhen> ] ;
             [ ON CHANGE <uChange> ] ;
             [ <readonly: READONLY, NO MODIFY> ] ;
             [ <spin: SPINNER> [ON UP <SpnUp>] [ON DOWN <SpnDn>] [MIN <Min>] [MAX <Max>] ] ;
       => ;
          [ <oGet> := ] TGet():ReDefine( <nId>, bSETGET(<uVar>), <oDlg>,;
             <nHelpId>, <cPict>, <{ValidFunc}>, <nClrFore>, <nClrBack>,;
             <oFont>, <oCursor>, <cMsg>, .t., <{uWhen}>,;
             [ \{|nKey,nFlags,Self| <uChange> \}], <.readonly.>,;
             <.spin.>, <{SpnUp}>, <{SpnDn}>, <{Min}>, <{Max}>) ;;
          <oGet>:bKeyDown := {|nKey,bFlags| iif( nKey==VK_F2, TheHelp( <nId> ), .t.) }

#define TBTNGET_CH
#define CGET TBTNGET
#define TBTNGET BTNGET

#xcommand REDEFINE BTNGET [ <oGet> VAR ] <uVar> ;
             [ ID <nId> ] ;
             [ <dlg: OF, WINDOW, DIALOG> <oDlg> ] ;
             [ <help:HELPID, HELP ID> <nHelpId> ] ;
             [ VALID   <ValidFunc> ]       ;
             [ PICTURE <cPict> ] ;
             [ <color:COLOR,COLORS> <nClrFore> [,<nClrBack>] ] ;
             [ FONT <oFont> ] ;
             [ CURSOR <oCursor> ] ;
             [ MESSAGE <cMsg> ] ;
             [ <update: UPDATE> ] ;
             [ WHEN <uWhen> ] ;
             [ ON CHANGE <uChange> ] ;
             [ <readonly: READONLY, NO MODIFY> ] ;
             [ <spin: SPINNER> [ON UP <SpnUp>] [ON DOWN <SpnDn>] [MIN <Min>] [MAX <Max>] ] ;
             [ <resource: BUTTON NAME, RESNAME, RESOURCE> <cResName> ];
             [ <bact: BUTTON ACTION, ACTION> <uAction> ] ;
       => ;
          [ <oGet> := ] TBtnGet():ReDefine( <nId>, bSETGET(<uVar>), <oDlg>,;
             <nHelpId>, <cPict>, <{ValidFunc}>, <nClrFore>, <nClrBack>,;
             <oFont>, <oCursor>, <cMsg>, .t., <{uWhen}>,;
             [ \{|nKey,nFlags,Self| <uChange> \}], <.readonly.>,;
             <.spin.>, <{SpnUp}>, <{SpnDn}>, <{Min}>, <{Max}>, [<cResName>], ;
            [<{uAction}>]) ;;
          <oGet>:bKeyDown := {|nKey,bFlags| iif( nKey==VK_F2, TheHelp( <nId> ), .t.) }

#xcommand REDEFINE COMBOBOX [ <oCbx> VAR ] <cVar> ;
             [ <items: PROMPTS, ITEMS> <aItems> ] ;
             [ ID <nId> ] ;
             [ <dlg:OF,WINDOW,DIALOG> <oWnd> ] ;
             [ <help:HELPID, HELP ID> <nHelpId> ] ;
             [ ON CHANGE <uChange> ] ;
             [ VALID   <uValid> ] ;
             [ <color: COLOR,COLORS> <nClrText> [,<nClrBack>] ] ;
             [ <update: UPDATE> ] ;
             [ MESSAGE <cMsg> ] ;
             [ WHEN <uWhen> ] ;
             [ BITMAPS <acBitmaps> ] ;
             [ ON DRAWITEM <uBmpSelect> ] ;
             [ STYLE <nStyle> ] ;
             [ <pict: PICT, PICTURE> <cPicture> ];
             [ ON EDIT CHANGE <uEChange> ] ;
       => ;
          [ <oCbx> := ] TComboBox():ReDefine( <nId>, bSETGET(<cVar>),;
             <aItems>, <oWnd>, <nHelpId>, <{uValid}>, [{|Self|<uChange>}],;
             <nClrText>, <nClrBack>, <cMsg>, <.update.>, <{uWhen}>,;
             <acBitmaps>, [{|nItem|<uBmpSelect>}], <nStyle>, <cPicture>,;
             [<{uEChange}>] ) ;;
          <oCbx>:bKeyDown := {|nKey,bFlags| iif( nKey==VK_F2, TheHelp( <nId> ), .t.) }

#xcommand REDEFINE CHECKBOX [ <oCbx> VAR ] <lVar> ;
             [ ID <nId> ] ;
             [ <of:OF, WINDOW, DIALOG> <oWnd> ] ;
             [ <help:HELPID, HELP ID> <nHelpId> ] ;
             [ <click:ON CLICK, ON CHANGE> <uClick> ];
             [ VALID <uValid> ] ;
             [ <color: COLOR, COLORS> <nClrFore> [,<nClrBack>] ] ;
             [ MESSAGE <cMsg> ] ;
             [ <update: UPDATE> ] ;
             [ WHEN <uWhen> ] ;
       => ;
          [ <oCbx> := ] TCheckBox():ReDefine( <nId>, bSETGET(<lVar>),;
             <oWnd>, <nHelpId>, [<{uClick}>], <{uValid}>, <nClrFore>,;
             <nClrBack>, <cMsg>, <.update.>, <{uWhen}> ) ;;
          <oCbx>:bKeyDown := {|nKey,bFlags| iif( nKey==VK_F2, TheHelp( <nId> ), .t.) }
demont frank
Posts: 167
Joined: Thu Mar 22, 2007 11:24 am

Post by demont frank »

Nice and very usefull job .

1)
The indexexpression from help.dbf contains the line number.

I suppose that the textfile will not be found when the program has changed.

Maybe better is to use only progmodule + IDnumber

2)
I will try this technique to make also tooltips (i.e. F3)

Frank
demont frank
Posts: 167
Joined: Thu Mar 22, 2007 11:24 am

Post by demont frank »

Instead from using a ch file to change the defines from GET , BTNGET and CHECKBOx , we can also :

Code: Select all

FOR EACH el IN oDlgPainel:aControls
  IF __ObjHasData(el,"bKeyDown")
    el:bKeyDown := {|nKey,bFlags| iif( nKey==VK_F2, TheHelp( el:nId ), .t.)}
  END
NEXT
ACTIVATE DIALOG oDlgPainel CENTERED
Also the radio buttons have a help text.
We can also avoid public memvars , and use a local parameter as

TheHelp(el:nId ,"SHOWPAINEL" )

Using a procedure or function to fill bKeydown , it should be possible to test that bKeydown is not empty and to execute first this code

Frank
Rochinha
Posts: 309
Joined: Sun Jan 08, 2006 10:09 pm
Location: Brasil - Sao Paulo
Contact:

Post by Rochinha »

demont frank wrote:1)
The indexexpression from help.dbf contains the line number.

I suppose that the textfile will not be found when the program has changed.
See the line with a nProcline var:

Code: Select all

function TheHelp( idCtrl ) 
   local cProcName := Padr(ProcName( 1 ),20) 
   local nProcLine := 0 // ProcLine( 0 ) 
...
nProcline := 0 prevents the problem.
demont frank wrote:Instead from using a ch file to change the defines from GET , BTNGET and CHECKBOx , we can also :

FOR EACH el IN oDlgPainel:aControls
IF __ObjHasData(el,"bKeyDown")
el:bKeyDown := {|nKey,bFlags| iif( nKey==VK_F2, TheHelp( el:nId ), .t.)}
END
NEXT
ACTIVATE DIALOG oDlgPainel CENTERED
I will try your code.
Post Reply