wade@sdacs.ucsd.EDU (Wade Blomgren) (05/18/88)
What is the best (easiest) way to allow entry of a password on the screen while suppressing the display of the actual characters in the edittext item? Use a dedicated font, like TOPS does? Or intercept all keydown events in a filter and change the key code to that of a meaningless character like a bullet or hash? The latter method seems to be what is happening in, for example, AppleShare, but it seems a bit difficult to keep track of the actual word that gets typed if the person does any editing of the edittext item with the mouse. For example, if the user types "abc" and then clicks between the a and the b, and inserts another letter, you would have a bit of figuring to do if you wanted to figure out what the word entered really was. What am I missing? Or is there yet another way to do this. I suppose one solution is to avoid having an edited field at all and just capture keydown events, but that seems somewhat inelegant. Wade Blomgren wade@sdacs.ucsd.edu
matthews@eleazar.dartmouth.edu (Jim Matthews) (05/19/88)
In article <536@sdacs.ucsd.EDU> wade@sdacs.ucsd.EDU (Wade Blomgren) writes: > >What is the best (easiest) way to allow entry of a password on the screen >while suppressing the display of the actual characters in the >edittext item? It actually isn't very difficult to intercept the key events and keep a hidden copy of the password string. It isn't necessary to remember any context since you have access to the TextEdit record, and it tells you what the current selection is. The following routine is a filter for a name/password dialog box. It displays bullets (ala AppleShare) and stores the real password in a global string, pwStr. It also handles hitting return or enter. { signonFilter -- dialog filter for doSignon, hides password } FUNCTION signonFilter (dp : DialogPtr; VAR theEvent : EventRecord; VAR itemHit : integer) : boolean; CONST nameItem = 3; passwordItem = 4; bs = $08; tab = $09; cr = $0D; enter = $03; larrow = $1C; rarrow = $1D; uparrow = $1E; downarrow = $1F; VAR dpeek : DialogPeek; theChar : char; theStr : Str255; selStart, selEnd : integer; h : Handle; itemType : integer; box : Rect; BEGIN signonFilter := false; dpeek := DialogPeek(dp); IF ((theEvent.what = keydown) OR (theEvent.what = autoKey)) THEN IF (dpeek^.editField = passwordItem - 1) THEN BEGIN theChar := char(BitAnd(theEvent.message, charCodeMask)); selStart := dpeek^.textH^^.selStart; selEnd := dpeek^.textH^^.selEnd; CASE ord(theChar) OF bs : { Backspace } BEGIN IF selEnd = selStart THEN { back over a character } BEGIN IF selStart > 0 THEN pwStr := concat(copy(pwStr,1, selStart - 1), copy(pwStr, selStart + 1, length(pwStr) - selStart)); END ELSE { delete the selection } pwStr := concat(copy(pwStr, 1, selStart), copy(pwStr, selEnd + 1, length(pwStr) - selEnd)); END; cr, enter : { Return or Enter -- treat as "OK } BEGIN itemHit := ok; signonFilter := true; END; { cr, enter } tab, uparrow, downarrow, rarrow, larrow : ; { just pass on tabs & arrows } OTHERWISE { "normal" character } BEGIN { remember character, insert a bullet } pwStr := concat(copy(pwStr, 1, selStart), theChar, copy(pwStr, selEnd + 1, length(pwStr) - selEnd)); theEvent.message := BitAnd(theEvent.message, $FFFFFF00) + ord('*'); END; { normal character } END; { case ord(theChar) of } END { in password field } ELSE { not in password field -- still check for cr, enter } CASE BitAnd(theEvent.message, charCodeMask) OF cr, enter : BEGIN itemHit := ok; signonFilter := true; END; { cr, enter } OTHERWISE ; END; { case BitAnd } END; { signonFilter } The bullet is replaced with an asterisk, since it's an 8-bit character. Hope this helps, Jim Matthews Software Development jim.matthews@dartmouth.edu