The ZIP file contains PowerBASIC source code for the DLL and the
demonstration program, sample icons to compile the function in the DLL and
to view the included html Help file.
Enter_PIN.zip download.
Will compile in either PBWin 10 or PBCC 6. Some changes may be needed for older versions. The compiled DLL should work in any version, and callable in other languages.
#compile dll
#dim all
'================================================================
enum PIN_IDs singular
'%en_update group
ID_PINA1Txtbx = &h3000&
ID_PINA2Txtbx
ID_PINA3Txtbx
ID_PINA4Txtbx
ID_PINA5Txtbx
ID_PINA6Txtbx
ID_PINA7Txtbx
ID_PINA8Txtbx
ID_PINA9Txtbx
ID_PINB1Txtbx = &h3010
ID_PINB2Txtbx
ID_PINB3Txtbx
ID_PINB4Txtbx
ID_PINB5Txtbx
ID_PINB6Txtbx
ID_PINB7Txtbx
ID_PINB8Txtbx
ID_PINB9Txtbx
'%bn_clicked group
ID_PINAExposeBtn
ID_PINBExposeBtn
ID_PINSubmitSnglBtn
ID_PINSubmitDuplBtn
ID_PINHelp
ID_PINCanx
'not selected in callback
ID_PINInstruLbl
ID_PINALbl
ID_PINBLbl 'type rect '
end enum 'number up to &h3FF reserved
'
%EM_SETPASSWORDCHAR = &h00CC
%wm_syscommand = &h0112 '(not built into PBWin)
%DT_CalcRect = &h00000400
#resource icon, PIN16, ".\PIN16.ico"
#resource icon, ShowPWon24, ".\ShowPWon24.ico"
#resource icon, ShowPWoff24, ".\ShowPWoff24.ico"
#resource icon, PINSubmit, ".\PINSubmit48.ico"
#resource icon, PINHelp, ".\HelpQuesBtn48.ico"
#resource icon, PINCanx, ".\CancelPIN32.ico"
global gIsVariableDigits, gNumOfDigits as long '(is in PIN_Enter and callback)
global gEntryErrTitle as wstring
declare function ShellExecute lib "Shell32.dll" alias "ShellExecuteW" ( _
byval hwnd as dword, lpOperation as wstringz, lpFile as wstringz, _
lpParameters as wstringz, lpDirectory as wstringz, byval nShowCmd as long) _
as dword
'############################################################# the function ####
function PIN_Enter alias "PIN_Enter" (byval hParent as dword, _
byval DualPIN as long, _
byval NumOfDigits as long) export as dword
'- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
static Not1stCall, nFontMono14B as long
static gEntryErrTitle as wstring
static RatioX, RatioY as single
local hPIN_Dlg, PIN as dword
local TBY, TBX, ID_Dig, PosX as long
local InstruStr, DigCnt as wstring
'========================================================= initialization ====
'····························································· persistent ····
if Not1stCall = 0 then 'so it is first call
Not1stCall = -1
font new "Lucida Console", 14, 1, 1, 0, 0 to nFontMono14B
dialog default font "Segoe UI", 12, 0, 1
gEntryErrTitle = "PIN Entry Error"$$
end if
'······························································ each call ····
if (NumOfDigits < 0) or (NumOfDigits > 9) then 'check range
msgbox "The number of PIN digits can only be optionally"$$ + $$crlf + _
"not used, or 0 to 9 digits long."$$ + $$crlf + _
"Not used or 0 is for a variable length PIN of"$$ + $$crlf + _
"1 to 9 digigits. Otherwise the number of digits is"$$ + $$crlf + _
"fixed by the using program."$$, _
%mb_ok or %mb_iconerror or %mb_taskmodal, gEntryErrTitle
exit function
end if
if NumOfDigits = 0 then 'variable number
gIsVariableDigits = -1
gNumOfDigits = 9
else
gNumOfDigits = NumOfDigits
end if
'================================================================= dialog ====
dialog new hParent, "Enter PIN."$$, _
0, 10, 200, 120, _
%ds_3dlook or %ds_modalframe or %ds_nofailcreate or %ds_setfont or _
%ws_caption or %ws_clipsiblings or %ws_dlgframe or %ws_popup or _
%ws_sysmenu, %ws_ex_left or %ws_ex_ltrreading to hPIN_Dlg
dialog set icon hPIN_Dlg, "PIN16"
'------------------------------------------------------- unit/pixel ratio ----
#if %pb_revision = &h1004
dialog units hPIN_Dlg, 1000, 1000 to pixels TBY, TBX 'precycle longs
#else
dialog units hPIN_Dlg, 1000, 1000 to pixels TBX, TBY
#endif
RatioX = 1000 /TBX : RatioY = 1000 / TBY 'mult img px for button units
'------------------------------------------------------------- PIN instru ----
if DualPIN then
InstruStr = "The application requires dual entry for the requested "$$ + _
"task. "$$
end if
if NumOfDigits then
InstruStr +="Enter the "$$ + dec$(gNumOfDigits) + " digit PIN. "$$
else
InstruStr += "The number of digits is not fixed. The PIN may be 4 "$$ + _
"to 9 digits. Leave unused digits at right empty. "$$
end if
InstruStr += "The only characters allowed are ""0"" to ""9""."$$
control add label, hPIN_Dlg, %ID_PINInstruLbl, InstruStr, _
5, 4, 185, 34, %ss_left, %ws_ex_left
control set color hPIN_Dlg, %ID_PINInstruLbl, -1, &hFAFAFA
'---------------------------------------------------- "A" digit textboxes ----
control add label, hPIN_Dlg, %ID_PINALbl, "Enter PIN:"$$, _
4, 45, 42, 10, %ss_right, %ws_ex_left ''55
'
PosX = 49
for ID_Dig = %ID_PINA1Txtbx to %ID_PINA1Txtbx + gNumOfDigits - 1
control add textbox, hPIN_Dlg, ID_Dig, ""$$, _
PosX, 44, 12, 10, %es_center or %es_number or %ws_border or _
%ws_tabstop or %es_password, %ws_ex_clientedge or %ws_ex_left
control set font hPIN_Dlg, ID_Dig, nFontMono14B
PosX += 15
next
'
control add imgbutton, hPIN_Dlg, %ID_PINAExposeBtn, "ShowPWon24", _
181, 43, 28 * RatioX, 28 * RatioY
if DualPIN = 0 then
control add imgbutton, hPIN_Dlg, %ID_PINSubmitSnglBtn, "PINSubmit", _
49 - (52 * RatioX), 59, 52 * RatioX, 52 * RatioY
' dialog set size hPIN_Dlg, 200, 75 + (52 * RatioY)
else
'---------------------------------------------------- "B" digit textboxes ----
PosX = 49
control add label, hPIN_Dlg, %ID_PINBLbl, "Reenter PIN:"$$, _
4, 60, 42, 10, %ss_right, %ws_ex_left ''55
for ID_Dig = %ID_PINB1Txtbx to %ID_PINB1Txtbx + gNumOfDigits - 1
control add textbox, hPIN_Dlg, ID_Dig, ""$$, _
PosX, 60, 12, 10, %es_center or %es_number or %ws_border or _
%ws_tabstop or %es_password, %ws_ex_clientedge or %ws_ex_left
control set font hPIN_Dlg, ID_Dig, nFontMono14B
PosX += 15
next
'
control add imgbutton, hPIN_Dlg, %ID_PINBExposeBtn, "ShowPWon24", _
181, 59, 28 * RatioX, 28 * RatioY
control add imgbutton, hPIN_Dlg, %ID_PINSubmitDuplBtn, "PINSubmit", _
49 - (52 * RatioX), 75, 52 * RatioX, 52 * RatioY
end if
'----------------------------------------------------- "A" and "B" common ----
if DualPIN = 0 then
control add imgbutton, hPIN_Dlg, %ID_PINHelp, "PINHelp", _
191 - (99 * RatioX), 59, 52 * RatioX, 52 * RatioY
control add imgbutton, hPIN_Dlg, %ID_PINCanx, "PINCanx", _
191 - (36 * RatioX), 59 + (16 * RatioY), (36 * RatioX), (36 * RatioY)
dialog set size hPIN_Dlg, 200, 76 + (52 * RatioY)
else
control add imgbutton, hPIN_Dlg, %ID_PINHelp, "PINHelp", _
191 - (99 * RatioX), 75, 52 * RatioX, 52 * RatioY
dialog set size hPIN_Dlg, 200, 92 + (52 * RatioY)
control add imgbutton, hPIN_Dlg, %ID_PINCanx, "PINCanx", _
191 - (36 * RatioX), 75 + (16 * RatioY), (36 * RatioX), (36 * RatioY)
end if
'
dialog show modal hPIN_Dlg call PINDlgCB to PIN
function = PIN
end function
'================================================================= callback ====
callback function PINDlgCB() as long
static A_IsExposed, B_IsExposed as long
static PINStr as wstring
local TmpL as long
local TmpS as wstring
if cb.msg = %wm_command then
if cb.ctlmsg = %en_update then
if (cb.ctl >= %ID_PINA1Txtbx) and (cb.ctl <= %ID_PINB9Txtbx) then
if (gNumOfDigits - 1) > (&h00000F and cb.ctl) then
control set focus cb.hndl, cb.ctl + 1
else
control set focus cb.hndl, %ID_PINB1Txtbx
end if
end if
elseif cb.ctlmsg = %bn_clicked then
select case as const cb.ctl
case %ID_PINAExposeBtn
if A_IsExposed then 'unexpose
for TmpL = %ID_PINA1Txtbx to %ID_PINA9Txtbx
control send cb.hndl, TmpL, %EM_SETPASSWORDCHAR,_
&h2A, 0
next
control set imgbutton cb.hndl, %ID_PINAExposeBtn, "ShowPWon24"
A_IsExposed = 0
else 'expose
for TmpL = %ID_PINA1Txtbx to %ID_PINA9Txtbx
control send cb.hndl, TmpL, %EM_SETPASSWORDCHAR, 0, 0
next
control set imgbutton cb.hndl, %ID_PINAExposeBtn, "ShowPWoff24"
A_IsExposed = -1
end if
for TmpL = %ID_PINA1Txtbx to %ID_PINA9Txtbx
control redraw cb.hndl, TmpL
next
case %ID_PINBExposeBtn
if B_IsExposed then
for TmpL = %ID_PINB1Txtbx to %ID_PINB9Txtbx
control send cb.hndl, TmpL, %EM_SETPASSWORDCHAR,_
&h2A, 0
next
control set imgbutton cb.hndl, %ID_PINBExposeBtn, "ShowPWon24"
B_IsExposed = 0
else 'expose
for TmpL = %ID_PINB1Txtbx to %ID_PINB9Txtbx
control send cb.hndl, TmpL, %EM_SETPASSWORDCHAR, 0, 0
next
control set imgbutton cb.hndl, %ID_PINBExposeBtn, "ShowPWoff24"
B_IsExposed = -1
end if
for TmpL = %ID_PINB1Txtbx to %ID_PINB9Txtbx
control redraw cb.hndl, TmpL
next
'············································· submit single button ····
case %ID_PINSubmitSnglBtn, %ID_PINSubmitDuplBtn
control get text cb.hndl, %ID_PINA1Txtbx to TmpS
PINStr = TmpS
for TmpL = 1 to 8
control get text cb.hndl, %ID_PINA1Txtbx + TmpL to TmpS
PINStr += TmpS
next
TmpL = len(PINStr)
if gIsVariableDigits then
if Tmpl < 4 then
msgbox "Varible length PINs must be 4 to 9 digits "$$ + _
"and exactly the same as when it was created."$$, _
%mb_ok or %mb_iconerror or %mb_taskmodal, gEntryErrTitle
exit function
end if
else
if TmpL < gNumOfDigits then
msgbox "The program using this PIN requires "$$ + _
dec$(gNumOfDigits) + " digits."$$, _
%mb_ok or %mb_iconerror or %mb_taskmodal, gEntryErrTitle
exit function
end if
end if
if cb.ctl = %ID_PINSubmitDuplBtn then
for TmpL = 0 to 8
control get text cb.hndl, %ID_PINB1Txtbx + TmpL to TmpS
if TmpS = mid$(PINStr, TmpL + 1, 1) then
iterate for
else
msgbox "The and the repeat do not match."$$, _
%mb_ok or %mb_iconerror or %mb_taskmodal, _
gEntryErrTitle
exit function
end if
next
end if
if gIsVariableDigits then
TmpL = 9 - len(PINStr)
PINStr += string$$(TmpL, "0"$$)
end if
dialog end cb.hndl, val(PINStr)
case %ID_PINHelp
'' ShellExecute
ShellExecute (0, "open"$$, "PIN_Enter_Help.html", ""$$, ""$$, %sw_shownormal)
case %ID_PINCanx
goto NoPIN
end select
end if
elseif (lo(word, cb.wparam) = %sc_close) and (cb.msg = %wm_syscommand) then
goto NoPIN
end if
exit function
NoPIN:
TmpL = msgbox("""Yes"", to quit PIN entry."$$ + $$crlf + _
"""No"", to stay and enter a PIN."$$, _
%mb_yesno or %mb_iconquestion or %mb_defbutton2 or %mb_taskmodal, _
"Verify Quitting PIN Entry"$$)
if TmpL = %idno then
function = -1
else
dialog end cb.hndl
end if
end function
'File PIN_SLL_demo.bas
#compile exe
#dim all
#if %def(%pb_cc32)
#console off
#endif
declare function PIN_Enter lib "EnterPIN.dll" alias "PIN_Enter" _
(byval hParent as dword, _
byval DuplPIN as long, _
byval NumOfDigits as long) as dword
function pbmain () as long
local hTWin, PIN as dword
local Rspnc as wstring
txt.window("PIN Enter Popup Demonstration"$$, 400, 70, 20, 75) to hTWin
txt.color = %rgb_green
txt.print "At any wait use any key to continue. (like now :) )"$$
txt.waitkey$
'
txt.color = %rgb_blue
txt.print "A dual PIN entry with number of digits set to 4. "$$;
txt.color = %rgb_black
txt.print "Returned PIN is: "$$ + dec$(PIN_Enter(hTWin, 1, 4), 4)"."$$
txt.color = %rgb_green
txt.print
txt.print "Any key to continue."
txt.waitkey$
'
txt.color = %rgb_blue
txt.print "A single PIN entry with number of digits set to 4. "$$;
txt.color = %rgb_black
txt.print "Returned PIN is: "$$ + dec$(PIN_Enter(hTWin, 0, 4), 4)"."$$
txt.print
txt.color = %rgb_green
txt.print """ESC"" to end demo, any other key to continue with next."
Rspnc = txt.waitkey$
if Rspnc = $$esc then exit function
'
txt.color = %rgb_blue
txt.print "Number of PIN digits set to 9. "$$;
txt.color = %rgb_black
txt.print "Returned PIN is: "$$ + dec$(PIN_Enter(hTWin, 0, 9), 9)"."$$
txt.color = %rgb_blue
txt.print "You had to enter 9 digits, or ""Cancel PIN"" to get here."$$
txt.print
txt.color = %rgb_green
txt.print """ESC"" to end demo, any other key to continue with next."
Rspnc = txt.waitkey$
if Rspnc = $$esc then exit function
txt.color = %rgb_blue
txt.print "Number of PIN digits set to 0 (user preference). "$$
txt.print "Looks like previous, but 4 to 9 digits allowed."$$;
txt.print "Returned PIN is: "$$ + dec$(PIN_Enter(hTWin, 0, 0), 9)"."$$
'
'---------------------------------------------------------------------
txt.color = %rgb_green
txt.print
txt.print "Any key will close."$$
txt.waitkey$
end function
Source and compiled code partial copyleft (ↄ), the limitation is you
may not claim creation and attempt to copyright it.
This page is copyright © 2026, all rights reserved Dale Yarker.
Created on 26 April 2026.
To Dale's Notebook
| To Programs
|