233 Form design: How to create password fields
VERSIONS: All ? - written for Paradox 5

SUBJECT: How to create password fields
BY: Mark Pauker

Since I posted a message about creating a password field that echos asterisks, I have received numerous requests for the code. Thus I thought I'd post the steps to create the clip object:
  1. Place 2 fields on a form.

  2. Set each field's display type to Unlabeled.

  3. Change the font for each field to some monospace (fixed pitch) font. I use Fixedsys, not bold.

  4. Make sure that the frame style and thickness settings are identical for both fields.

  5. Drag one of the fields over the other so they _partially_ overlap, in order to determine which one is on top.

  6. Turn off the Runtime|Tabstop property of the bottom field.

  7. This step is optional. The following code will size the field(s) such that an integral number of characters will fit within it. That is, the last asterisk in the field will fit exactly, without being cut off. (This is possible because "Fixedsys" is a monospace font.) You should put this in the open method of one (or both) of the fields, and run the form. After the form has run once, the code will have done its job and can be removed (although it won't hurt to leave it). Note that you should replace NUMCHARS with the number of asterisks you want to be able to display:
                   var
                      siFrameStyle smallInt
                      ptCharSize, pt point
                   endVar
                   siFrameStyle = self'frame.style
                   self'frame.style = NoFrame
                   ptCharSize = self'avgCharSize
                   pt = self'position
                   self'position = pixelsToTwips(twipsToPixels(pt))
                   pt = self'size - self'fullSize
                   self'size = point(ptCharSize.x() * NUMCHARS + pt.x(),
                                     ptCharSize.y() + pt.y())
                   self'frame.style = siFrameStyle
    
    (Yes, I know some of this code looks like it doesn't do anything, but it's all necessary depending on the size and location of the fields you place.)

  8. If you skipped step 7, or if you only placed step 7's code in one of the fields, you should use the Design|AdjustSize tools to make both fields identical sizes. (Don't modify the size of any field whose size was set in step 7.)

  9. Use the Design|Align tools to align the fields exactly on top of one another.

  10. Change the color of the top field to Transparent (White + Translucent).

  11. Turn the top field's Runtime|NoEcho property to True.

  12. Place the following code in the top field's var window:
                   var
                      uiDisplay uiObject
                   endVar
    
  13. Place the following code in the top field's open method:
                  uiDisplay.attach(self'prev)
    
  14. Add the custom method uSyncDisplay!() to the top field as follows:
                   method uSyncDisplay!()
                      if size(uiDisplay'value) <> size(self'value) then
                         uiDisplay'value = fill("*", size(self'value))
                      endIf
                   endMethod
    
  15. Place the following code in the top field's action AND keyPhysical methods:
                   doDefault
                   uSyncDisplay!()
    
  16. Place the following code in the top field's arrive method: (It is needed to work around a minor Paradox display bug.)
                   self.action(EditEnterFieldView)
                   self.action(EditExitFieldView)
    
  17. Select both fields and group them (using Design|Group). (Note that when you select the fields, their selection handles won't appear because the fields are identical in size and position.) This step is necessary in order for the "self'prev" in the open method to refer to the correct object. I chose this approach because it encapsulates the clip object, and allows it to be independent of any uiObject naming conventions. (Notice that I didn't have to name either of the fields.)
That's it! Granted, a bit more work than I'd have liked, but since it's a clip object, I only had to do it once and can now copy it from form to form.

Hope you find this useful...

To index