Subject Re: PasswordMaskEF.cc bug?
From Bernd Hohenester <newsletter@hobe.de>
Date Tue, 27 Feb 2024 05:17:07 -0500
Newsgroups dbase.getting-started

> Peter Hegelbach Wrote:
>
> > Where I got stuck: Support for Ctrl-C, pasting the password from the
> > clipboard.
>
> i added support for inserting a password. You need to add the following lines:
>
> At the beginning where the "defines" are:
> #define CTRLV_KEY         22    // -- ASCII value of Ctrl+V
>
> And in the function key:
>
> > *-------------------------------------------------------------------------------
> >    procedure Key(nChar, nPosition)
> >                 // Handles keys entered in the password entryfield
> >       private enteredChar, returnValue
> >
> >       // Get the character positions of the selected text (if any)
> >       local SelectStartPos, SelectEndPos
> >       SelectStartPos = 0
> >       SelectEndPos = 0
> >       CheckSelect(this.hwnd,0xB0,SelectStartPos,SelectEndPos)
> >       enteredChar = chr(nChar)
> >       returnValue = true                // By default output whatever key was typed
> >       do case                           // Check for keys that modify the value
> >          case nChar = BACKSPACE_KEY
> >             // if the text is not selected, delete the previous character,
> >             // if the text is selected, delete the characters corresponding
> >             // to the selection range
> >             if SelectStartPos == 0 AND SelectEndPos == 0
> >                this.enteredPassword = ;
> >                   stuff(this.enteredPassword, nPosition - 1, 1, \"\")
> >             else
> >                this.enteredPassword = ;
> >                   stuff(this.enteredPassword, SelectStartPos + 1, ;
> >                   SelectEndPos - SelectStartPos, \"\")
> >             endif
> >          case nChar = DELETE_KEY
> >             // if the text is not selected, delete the current character,
> >             // if the text is selected, delete the characters corresponding
> >             // to the selection range
> >             if SelectStartPos == 0 AND SelectEndPos == 0
> >                this.enteredPassword = ;
> >                   stuff(this.enteredPassword, nPosition, 1, \"\")
> >             else
> >                this.enteredPassword = ;
> >                   stuff(this.enteredPassword, SelectStartPos + 1, ;
> >                   SelectEndPos - SelectStartPos, \"\")
> >             endif
> >          case nChar = ENTER_KEY
> >             if this.captureEnter AND this.enteredPassword.length = 0
> >                          msgbox( \"Kein Passwort eingegeben!\",\"Warnung!\", 48 )
> >                          this.setFocus()
> >                       endif

// again new code! Now this works ;-)

         case nChar = CTRLV_KEY
           // cause key has no access to "this.value", we have to get
           // the content of the clipboard in another way
           local ed, i
           ed = new editor(form)
           ed.visible := false
           ed.enabled := true
           ed.paste()
           if not empty(ed.value)
             // password was inserted with Strg+V
             // all chars must be validated
             for i = 1 to ed.value.length
               if not class::IsValidChar(ed.value.substring(i-1, i))
                 msgbox( "Password contains invalid chars!", "ALERT!", 48)
                 this.value := ""
                 this.setFocus()
                 this.enteredPasswort = ""
                 release object ed
                 ed = null
                 return false
               endif
             endfor
             // if we are here, all is well
             this.enteredPassword = ed.value
             this.value := replicate(this.maskChar, this.enteredPassword.length)
           endif
           release object ed
           ed = null
           returnValue = false


> >          otherwise
> >             if class::IsValidChar(enteredChar)    // Check if alphanumeric
> >                // if the text is not selected, insert the character entered,
> >                // if the text is selected, overwrite the characters
> >                // corresponding to the selection range with the character
> >                // entered
> >                if SelectStartPos == 0 AND SelectEndPos == 0
> >                   this.enteredPassword = ;
> >                      stuff(this.enteredPassword, nPosition, 1, enteredChar)
> >                else
> >                   this.enteredPassword = ;
> >                      stuff(this.enteredPassword, SelectStartPos + 1, ;
> >                      SelectEndPos - SelectStartPos, enteredChar)
> >                endif
> >                if this.camouflageOn
> >                                                 returnValue = asc( this.maskChar ) // Output camouflage character
> >                                         else
> >                                                 returnValue = nChar
> >                                         endif
> >                                 else
> >                                         returnValue = false
> >                                         ? chr(7)    // Beep
> >             endif
> >       endcase
> >    return returnValue


WHAT A PITA!

Because the function key has no access to "this.value", we can't check the clipboard's content. So i changed it to "onKey" and it worked. BUT now all entered chars are shown with the font of the entryfield and not changed to the maskChar.

Ok, back to "function key" and another trick to get the clibboard's content. Now we use an editor-control and paste the clipboard's content. Then check the valid chars and when all is well, set the values. If not, tell the user and reject the insert.

Bernd