|
Post by Rod on Jul 15, 2021 14:19:30 GMT -5
|
|
curly
Full Member
Posts: 161
|
Post by curly on Jul 15, 2021 14:53:53 GMT -5
Rod, I have your example working in my window fine except, in your example, the top left of the keypad is at the spot the curser is when clicked. In my window, it appears at the top left corner of the window? Kind regards, David
|
|
curly
Full Member
Posts: 161
|
Post by curly on Jul 15, 2021 14:56:28 GMT -5
I will create that in the morning and post it, thank you all very much
|
|
|
Post by Walt Decker on Jul 15, 2021 15:11:25 GMT -5
Here is the code I previously posted with a pseudo callback. It catches "touches" on the edit controls only and the buttons know where to put the data.
' WS.OVERLAPPED = HEXDEC("&H00000000") WS.VISIBLE = HEXDEC("&H10000000") WS.CLIPSIBLINGS = HEXDEC("&H04000000") WS.CLIPCHILDREN = HEXDEC("&H02000000") WS.CAPTION = HEXDEC("&H00C00000") WS.SYSMENU = HEXDEC("&H00080000") WS.THICKFRAME = HEXDEC("&H00040000") WS.GROUP = HEXDEC("&H00020000") WS.TABSTOP = HEXDEC("&H00010000")
WS.MINIMIZEBOX = HEXDEC("&H00020000") WS.MAXIMIZEBOX = HEXDEC("&H00010000")
WS.OVERLAPPEDWINDOW = (WS.OVERLAPPED _ OR WS.CAPTION _ OR WS.SYSMENU _ OR WS.THICKFRAME _ OR WS.MINIMIZEBOX _ OR WS.MAXIMIZEBOX)
WS.EX.DLGMODALFRAME = HEXDEC("&H00000001") WS.EX.STATICEDGE = HEXDEC("&H00020000") WS.EX.TOPMOST = HEXDEC("&H00000008") WS.EX.TOOLWINDOW = HEXDEC("&H00000080")
GWL.WNDPROC = -4 GWL.ID = -12 GWL.USERDATA = -21
OPEN "User32.dll" FOR DLL AS #USER
GLOBAL PadHndl, _ LstFocus
GLOBAL VOLTS, _ AMPS, _ REST, _ PAD GLOBAL Ubnd
Ubnd = 2
DIM CtlNames$(2)
STYLEBITS #ELEC.VOLTS, WS.TABSTOP OR WS.GROUP, 0, WS.EX.STATICEDGE OR WS.EX.DLGMODALFRAME, 0 TEXTBOX #ELEC.VOLTS, 5, 5, 50, 25
STYLEBITS #ELEC.AMPS, WS.TABSTOP, 0, WS.EX.STATICEDGE OR WS.EX.DLGMODALFRAME, 0 TEXTBOX #ELEC.AMPS, 60, 5, 50, 25
STYLEBITS #ELEC.REST, WS.TABSTOP, 0, WS.EX.STATICEDGE OR WS.EX.DLGMODALFRAME, 0 TEXTBOX #ELEC.REST, 115, 5, 50, 25
STYLEBITS #ELEC.PAD, WS.TABSTOP OR WS.GROUP, 0, WS.EX.DLGMODALFRAME, 0 BUTTON #ELEC.PAD, "NUM PAD", OPEN.PAD, UL, 5, 35, 68, 25
STYLEBITS #ELEC.OK, WS.TABSTOP, 0, WS.EX.DLGMODALFRAME, 0 BUTTON #ELEC.OK, "APPLY", ADD.VAL, UL, 115, 35, 68, 25
OPEN "ELEC" FOR WINDOW AS #ELEC 'PRINT #ELEC.VOLTS, "!setfocus" PRINT #ELEC, "TRAPCLOSE DEMO.DONE"
CtlHndl = HWND(#ELEC.VOLTS) LstFocus = CtlHndl
CALLDLL #USER, "GetDlgCtrlID", CtlHndl AS ULONG, VOLTS AS LONG CtlHndl = HWND(#ELEC.AMPS) CALLDLL #USER, "GetDlgCtrlID", CtlHndl AS ULONG, AMPS AS LONG CtlHndl = HWND(#ELEC.REST) CALLDLL #USER, "GetDlgCtrlID", CtlHndl AS ULONG, REST AS LONG
CtlNames$(0) = "#ELEC.VOLTS" CtlNames$(1) = "#ELEC.AMPS" CtlNames$(2) = "#ELEC.REST" TRACE 2 A = FocusCB() WAIT
'---------------------------------------------------------- '----------------------------------------------------------
SUB DEMO.DONE ElecHndl$
IF PadHndl THEN CLOSE #PAD END IF
CLOSE #USER CLOSE #ELEC END
END SUB
'---------------------------------------------------------- '----------------------------------------------------------
SUB ADD.VAL BtnHndl$
AryPos = 0 CtlId = 0
CtlStr$ = "" Tmp$ = ""
CALLDLL #USER, "GetDlgCtrlID", LstFocus AS ULONG, CtlId AS LONG AryPos = CtlId - VOLTS + 1
IF AryPos > Ubnd THEN EXIT SUB CtlStr$ = CtlNames$(AryPos) LstFocus = HWND(#CtlStr$)
END SUB
'---------------------------------------------------------- '----------------------------------------------------------
SUB OPEN.PAD BtnHndl$
IF PadHndl THEN EXIT SUB
WS.OVERLAPPED = HEXDEC("&H00000000") WS.VISIBLE = HEXDEC("&H10000000") WS.CLIPSIBLINGS = HEXDEC("&H04000000") WS.CLIPCHILDREN = HEXDEC("&H02000000") WS.CAPTION = HEXDEC("&H00C00000") WS.SYSMENU = HEXDEC("&H00080000") WS.THICKFRAME = HEXDEC("&H00040000") WS.GROUP = HEXDEC("&H00020000") WS.TABSTOP = HEXDEC("&H00010000")
WS.MINIMIZEBOX = HEXDEC("&H00020000") WS.MAXIMIZEBOX = HEXDEC("&H00010000")
WS.OVERLAPPEDWINDOW = (WS.OVERLAPPED _ OR WS.CAPTION _ OR WS.SYSMENU _ OR WS.THICKFRAME _ OR WS.MINIMIZEBOX _ OR WS.MAXIMIZEBOX)
WS.EX.DLGMODALFRAME = HEXDEC("&H00000001") WS.EX.STATICEDGE = HEXDEC("&H00020000") WS.EX.TOPMOST = HEXDEC("&H00000008") WS.EX.TOOLWINDOW = HEXDEC("&H00000080")
GWL.STYLE = -16 GWL.EXSTYLE = -20
STRUCT tRect, _ X AS LONG, _ Y AS LONG, _ X1 AS LONG, _ Y1 AS LONG
CtlHndl = 0
STYLEBITS #PAD.0, 0, 0, WS.EX.DLGMODALFRAME, 0 STYLEBITS #PAD.1, 0, 0, WS.EX.DLGMODALFRAME, 0 STYLEBITS #PAD.P, 0, 0, WS.EX.DLGMODALFRAME, 0 STYLEBITS #PAD.2, 0, 0, WS.EX.DLGMODALFRAME, 0 STYLEBITS #PAD.3, 0, 0, WS.EX.DLGMODALFRAME, 0 STYLEBITS #PAD.NV, 0, 0, WS.EX.DLGMODALFRAME, 0 STYLEBITS #PAD.4, 0, 0, WS.EX.DLGMODALFRAME, 0 STYLEBITS #PAD.5, 0, 0, WS.EX.DLGMODALFRAME, 0 STYLEBITS #PAD.NA, 0, 0, WS.EX.DLGMODALFRAME, 0 STYLEBITS #PAD.6, 0, 0, WS.EX.DLGMODALFRAME, 0 STYLEBITS #PAD.7, 0, 0, WS.EX.DLGMODALFRAME, 0 STYLEBITS #PAD.8, 0, 0, WS.EX.DLGMODALFRAME, 0 STYLEBITS #PAD.9, 0, 0, WS.EX.DLGMODALFRAME, 0
BUTTON #PAD.0, "0", SET.TXT, UL, 5, 5, 20, 25 BUTTON #PAD.1, "1", SET.TXT, UL, 30, 5, 20, 25 BUTTON #PAD.P, ".", SET.TXT, UL, 55, 5, 30, 25 BUTTON #PAD.2, "2", SET.TXT, UL, 5, 35, 20, 25 BUTTON #PAD.3, "3", SET.TXT, UL, 30, 35, 20, 25 BUTTON #PAD.NV, "NV", SET.TXT, UL, 55, 35, 30, 25 BUTTON #PAD.4, "4", SET.TXT, UL, 5, 65, 20, 25 BUTTON #PAD.5, "5", SET.TXT, UL, 30, 65, 20, 25 BUTTON #PAD.NA, "NA", SET.TXT, UL, 55, 65, 30, 25 BUTTON #PAD.6, "6", SET.TXT, UL, 5, 95, 20, 25 BUTTON #PAD.7, "7", SET.TXT, UL, 30, 95, 20, 25 BUTTON #PAD.8, "8", SET.TXT, UL, 5, 125, 20, 25 BUTTON #PAD.9, "9", SET.TXT, UL, 30, 125, 20, 25
CtlHndl = HWND(#ELEC.PAD) CALLDLL #USER, "GetWindowRect", CtlHndl AS ULONG, tRect AS STRUCT, RetVal AS VOID
UpperLeftX = tRect.X1.struct - 5 UpperLeftY = tRect.Y.struct + tRect.Y1.struct - tRect.Y.struct + 5 WindowWidth = 100 WindowHeight = 190
STYLEBITS #PAD, WS.CAPTION OR WS.CLIPCHILDREN OR WS.SYSMENU, _ WS.OVERLAPPEDWINDOW, WS.EX.TOOLWINDOW OR WS.EX.TOPMOST, 0 OPEN "NUM PAD" FOR WINDOW AS #PAD PRINT #PAD, "TRAPCLOSE [CLOSE.PAD]" PadHndl = 1 WAIT
[CLOSE.PAD] CLOSE #PAD
PadHndl = 0 END SUB
'--------------------------------------------------------------------- '---------------------------------------------------------------------
SUB SET.TXT BtnHndl$
BtnHndl = 0 CtlId = 0 AryPos = 0
TxtIn$ = "" TxtOut$ = "" Nam$ = ""
BtnHndl = HWND(#BtnHndl$)
CALLDLL #USER, "GetDlgCtrlID", LstFocus AS ULONG, CtlId AS LONG
FOR I = VOLTS TO REST IF CtlId = I THEN CALLDLL #USER, "GetWindowTextLengthA", BtnHndl AS ULONG, TxtLen AS LONG, TxtIn$ = SPACE$(TxtLen) TxtLen = TxtLen + 1 CALLDLL #USER, "GetWindowTextA", BtnHndl AS ULONG, TxtIn$ AS PTR, TxtLen AS LONG, TxtLen AS LONG AryPos = CtlId - VOLTS Nam$ = CtlNames$(AryPos) PRINT #Nam$, "!contents? TxtOut$" TxtOut$ = TxtOut$ + TxtIn$ PRINT #Nam$, TxtOut$ END IF NEXT I
END SUB
'------------------------------------------------------------------------- '-------------------------------------------------------------------------
FUNCTION FocusCB()
FocusHndl = 0 CtlHndl = 0 FuncPtr = 0
'WinHndl = HWND(#ELEC)
[DO.SCAN] SCAN 'CALLBACK FuncPtr, FN.ChildWin(Hndl), LONG 'CALLDLL #USER, "EnumChildWindows", WinHndl AS ULONG, FuncPtr AS ULONG, 0 AS LONG, RetVal AS VOID CALLDLL #USER, "GetFocus", CtlHndl AS ULONG CALLDLL #USER, "GetDlgCtrlID", CtlHndl AS ULONG, CtlId AS LONG
IF CtlId < VOLTS THEN GOTO [DO.SCAN]
FOR I = VOLTS TO REST IF I = CtlId THEN IF LstFocus = WinHndl THEN EXIT FOR END IF LstFocus = CtlHndl END IF NEXT I
GOTO [DO.SCAN]
END FUNCTION
After more testing I found the LB apparently begins button IDs at 101. Therefore; just below "IF CtlId < VOLTS THEN GOTO [DO.SCAN]" add this bit of code:
F = -1 FOR I = 0 TO Ubnd T$ = CtlNames$(I) IF HWND(#T$) = CtlHndl THEN F = I EXIT FOR END IF NEXT I
IF F < 0 THEN GOTO [DO.SCAN]
|
|
curly
Full Member
Posts: 161
|
Post by curly on Jul 16, 2021 6:38:14 GMT -5
Hi again, I've cobbled together bits of my code and managed to make it run. I've no idea of the terminology in the USA but where the electrical supply enters a dwelling there is normally a cut-out of some sort that will isolate the supply, followed by an electricity meter that records whats been used, and then a fuseboard of some kind that creates separate circuits for lighting, power etc. Inside the fuseboard, there will be a row of devices, normally a switch to isolate the fuseboard, maybe an RCD that detects faults to earth, and then circuit breakers or fuses that protect each individual circuit. I made the decision to work in WAYs, i.e. each device represents one WAY, and the WAYs simply count WAY1, WAY2 etc. There are three other important variables used, POS is a numeric that records the total number of WAYs that exist in the system. pos (lowercase) represents the way currently on the screen. Circuits also need to be numbered, but do not include WAYs used for main switches and RCDs, but do include spare ways. The data for the job is saved intwo main arrays, system$(200) that stores all the one off items, and CCU$(500,34) that stores WAY data. I save in the format of a CSV but use a normally unused character in place of a comma so I can include commas in strings of text. I have a switch to switch encryption on or off that changes every character other than the separator.
I haven't included Rod's keypad in this little sample. Textboxes are turned on and off as required. I really appreciate all the code being created, but my limited knowledge means I have to print it to paper, and then use the LB help files to see what the commands are doing, and although I love learning, it takes me quite a while to work things out, so please don't think I'm discounting anyone's efforts because I haven't raved about it. It took me three daya to properly get to grips with Rod's keypad and then to modify it to work in my application. Purely for the record, I have 413 GUI objects in total including labels. I don't know if that is a lot?
So are you all in a sunshine state somewhere?
nomainwin
WindowWidth = 1100 WindowHeight = 900 UpperLeftX= int((DisplayWidth-WindowWidth)/2) UpperLeftY= int((DisplayHeight-WindowHeight)/2) [StartUp] DIM row(30) 'this simplifies laying out rows of textboxes for i = 1 to 29 row(i) = i * 30 next i
Dim system$(200): Dim JOBS$(50): Dim jobs$(15): Dim Jobs$(50,15): Dim ClipBoard$(100): Dim CLIENT$(50): Dim client$(10): Dim Premises$(15) Dim Encrypt$(260,2): Dim CCU$(500,34): Dim User$(100,15): Dim Client$(50,10): Dim Observation$(99) Dim ExtentS(10): Dim ExtentShort$(10): Dim AgreedL$(10): Dim AgreedLShort$(10): Dim OperationalL$(10): Dim OperationalLShort$(10) Dim cap$(20): Dim IntLoc$(10) user$ = "": ccu = 1: way = 1: way$ = "1": pos = 1: POS = 1: TPN$ = "0": validate$ = "": ZsPC$ = "80%" system$(41) = TPN$: system$(39) = ZsPC$: Records$ = "NO": cct = 1: cct$ = "1" 'End of startup
[CircuitSchedules] 'Collect system and circuit data
if CSWindow = 1 then 'this checks if the CircuitSchedules window is open but hidden and brings it into view. ' print #home.tb104R, "!hide" ' print #home.tb104O, "!show" print #DataIn.Textbox1,"!setfocus" goto [CircuitSchedulesWait] wait 'just in case end if
WindowWidth = 1100 WindowHeight = 900
' gosub [DimArraysAndDefineValues] gosub [DataInGuiObjects]
UpperLeftX=int((DisplayWidth-WindowWidth)/2) UpperLeftY=int((DisplayHeight-WindowHeight)/2)
open "Circuits" for window as #DataIn ' gosub [HideYellowSystemBoxes] ' gosub [HideCircuitBoxes] ' gosub [HideYellowCircuitBoxes] CSWindow = 1 print #DataIn, "trapclose [quit.DataIn]" ' print #DataIn, "font ms_sans_serif 8" ' print #DataIn.Textbox105, "!disable" ' print #DataIn.Textbox105, way$ goto [CircuitSchedulesWait]
[quit.DataIn] Close #DataIn End
[CircuitSchedulesWait] 'this decides which buttons should remain active -I decided to hide them 'to avoid people asking why the button didn't work ' print #DataIn.button1, "!hide" 'if POS > pos then print #DataIn.button1, "!show" 'end if 'print #DataIn.button3, "!hide" 'if pos > 1 then print #DataIn.button3, "!show" 'end if ' print #DataIn.button4, "!hide" 'if pos > 1 then ' if pos = POS then print #DataIn.button4, "!show" ' end if 'end if ' print #DataIn.button5, "!hide" 'if CCU$(pos,7) > "" then print #DataIn.button5, "!show" 'end if wait
[DataInGuiObjects] 'this is just one row of textboxes - comboboxes have been left out statictext #DataIn.statictext120, "Ring circuit r1", 50, row(21), 40, 30 statictext #DataIn.statictext121, "Ring circuit rn", 111, row(21), 40, 30 statictext #DataIn.statictext122, "Ring circuit r2", 172, row(21), 40, 30 statictext #DataIn.statictext123, "R1+R2", 233, row(21), 40, 30 statictext #DataIn.statictext124, "R2", 294, row(21), 40, 30 statictext #DataIn.statictext125, "Insul Test Volts", 355, row(21), 60, 30 statictext #DataIn.statictext126, "L - L", 436, row(21), 30, 30 statictext #DataIn.statictext127, "L - N", 497, row(21), 30, 30 statictext #DataIn.statictext128, "L - E", 558, row(21), 30, 30 statictext #DataIn.statictext129, "N - E", 614, row(21), 30, 30 statictext #DataIn.statictext130, "Polarity", 680, row(21), 40, 30 statictext #DataIn.statictext131, "Max Zs measured", 760, row(21), 50, 30 statictext #DataIn.statictext132, "RCD Dis time (ms)", 830, row(21), 50, 30 statictext #DataIn.statictext133, "RCD test button", 900, row(21), 60, 30 statictext #DataIn.statictext134, "Manual AFDD test button", 985, row(21), 80, 30 button #DataIn.button1, "Next Way", [NextWay], UL, 50, row(24), 100,50 button #DataIn.button2, "Pre-Fill", [PreFill], UL, 200, row(24), 100,50 button #DataIn.button3, "Previous Way", [LastWay], UL, 350, row(24), 100,50 button #DataIn.button4, "New CCU", [NextCCU], UL, 500, row(24), 100,50 button #DataIn.button5, "Save Way", [SaveButton], UL, 650, row(24), 100, 50 button #DataIn.button6, "Pause", [GoHome], UL, 800,row(24),100,50 button #DataIn.button7, "Finished", [ValidateCircuit], UL, 950, row(24), 100,50 Textbox #DataIn.Textbox120, 50, row(22), 40, 23 'r1 Textbox #DataIn.Textbox121, 111, row(22), 40, 23 'rn Textbox #DataIn.Textbox122, 172, row(22), 40, 23 'r2 Textbox #DataIn.Textbox123, 233, row(22), 40, 23 'R1R2 Textbox #DataIn.Textbox124, 294, row(22), 40, 23 'R2 Textbox #DataIn.Textbox126, 436, row(22), 40, 23 'L-L Textbox #DataIn.Textbox127, 497, row(22), 40, 23 'L-N Textbox #DataIn.Textbox128, 558, row(22), 40, 23 'L-E Textbox #DataIn.Textbox129, 614, row(22), 40, 23 'N-E Textbox #DataIn.Textbox131, 760, row(22), 50, 23 'Max measured Zs Textbox #DataIn.Textbox132, 830, row(22), 50, 23 'RCD disconnection time ms return
[NextWay] 'if the next way in the fuseboard exists, this restores it to the screen goto [CircuitSchedulesWait]
[PreFill] ' this allows regular circuits to be selected and prefilled goto [CircuitSchedulesWait]
[LastWay] 'this allows the last circuit created or viewed to be restored and edited if necessary goto [CircuitSchedulesWait]
[NextCCU] 'this creates another fuseboard goto [CircuitSchedulesWait]
[SaveButton] 'this checks the data that has been entered and saves all data for the job goto [CircuitSchedulesWait]
[GoHome] 'this switches focus to the home window goto [CircuitSchedulesWait]
[ValidateCircuit] 'this will validate the whole system when completed before saving goto [CircuitSchedulesWait]
|
|
curly
Full Member
Posts: 161
|
Post by curly on Jul 21, 2021 4:20:39 GMT -5
Hi Walt, I have studied your code for two days, but it goes way over my head. However, I have run it, with the extra code added, and with the extra code relacing the section following that has the same format, but in both cases, I cannot get a keypad to appear? I see three textboxes and two buttons, but neither of the buttons appear to do anything?
Kind regards, David
ps as I haven't seen a response to my last post, have I offended anyone or broken any rules?
|
|
|
Post by Brandon Parker on Jul 21, 2021 9:18:56 GMT -5
You have not broken any rules. I am not certain everyone can ascertain exactly what your example code needs to do
Also, people tend to get busy with normal life activities at times, so there might be a few days here or there where people are off doing other things.
{:0)
Brandon Parker
|
|
|
Post by Walt Decker on Jul 21, 2021 10:19:52 GMT -5
I could not. Plus, I could not follow your code. I do not have a tablet so I cannot test my code on one. There should be three edit controls with nothing in them, and two buttons below the edit controls. One button should be labeled "NUM PAD" and the other should be labeled "APPLY". By pressing "NUM PAD" a window should pop up below and to the right of the "NUM PAD" button. This window should have a small kill button in the caption and 13 buttons. This window is called a "toolbox window". By clicking on the buttons in the toolbox window data should appear in the appropriate edit control. You should be able to set the focus to any of the edit controls in any order and the data defined by the toolbox buttons should appear in that edit control.
The "APPLY" button just increments the edit control focus.
The below code is revised to take advantage of certain control properties and, I think, sufficiently commented so you can follow it and understand what it does. ' WS.OVERLAPPED = HEXDEC("&H00000000") WS.VISIBLE = HEXDEC("&H10000000") WS.CLIPSIBLINGS = HEXDEC("&H04000000") WS.CLIPCHILDREN = HEXDEC("&H02000000") WS.CAPTION = HEXDEC("&H00C00000") WS.SYSMENU = HEXDEC("&H00080000") WS.THICKFRAME = HEXDEC("&H00040000") WS.GROUP = HEXDEC("&H00020000") WS.TABSTOP = HEXDEC("&H00010000")
WS.MINIMIZEBOX = HEXDEC("&H00020000") WS.MAXIMIZEBOX = HEXDEC("&H00010000")
WS.OVERLAPPEDWINDOW = (WS.OVERLAPPED _ OR WS.CAPTION _ OR WS.SYSMENU _ OR WS.THICKFRAME _ OR WS.MINIMIZEBOX _ OR WS.MAXIMIZEBOX)
WS.EX.DLGMODALFRAME = HEXDEC("&H00000001") WS.EX.STATICEDGE = HEXDEC("&H00020000") WS.EX.TOPMOST = HEXDEC("&H00000008") WS.EX.TOOLWINDOW = HEXDEC("&H00000080")
GWL.WNDPROC = -4 GWL.ID = -12 GWL.USERDATA = -21
OPEN "User32.dll" FOR DLL AS #USER
GLOBAL PadHndl, _ LstFocus '<--- text box with focus
[TEXTBOX.CTLIDS] GLOBAL VOLTS, _ AMPS, _ REST, _ PAD
GLOBAL Ubnd '<--- number of text boxes
[INITIALIZE.GLOBALS] Ubnd = 2
VOLTS = 1000 AMPS = 1001 REST = 1002 PAD = 1003
DIM CtlNames$(2)
STYLEBITS #ELEC.VOLTS, WS.TABSTOP OR WS.GROUP, 0, WS.EX.STATICEDGE OR WS.EX.DLGMODALFRAME, 0 TEXTBOX #ELEC.VOLTS, 5, 5, 50, 25
STYLEBITS #ELEC.AMPS, WS.TABSTOP, 0, WS.EX.STATICEDGE OR WS.EX.DLGMODALFRAME, 0 TEXTBOX #ELEC.AMPS, 60, 5, 50, 25
STYLEBITS #ELEC.REST, WS.TABSTOP, 0, WS.EX.STATICEDGE OR WS.EX.DLGMODALFRAME, 0 TEXTBOX #ELEC.REST, 115, 5, 50, 25
STYLEBITS #ELEC.PAD, WS.TABSTOP OR WS.GROUP, 0, WS.EX.DLGMODALFRAME, 0 BUTTON #ELEC.PAD, "NUM PAD", OPEN.PAD, UL, 5, 35, 68, 25
STYLEBITS #ELEC.OK, WS.TABSTOP, 0, WS.EX.DLGMODALFRAME, 0 BUTTON #ELEC.OK, "APPLY", ADD.VAL, UL, 115, 35, 68, 25
OPEN "ELEC" FOR WINDOW AS #ELEC
PRINT #ELEC, "TRAPCLOSE DEMO.DONE"
'############################################################################################# ' get the handle of the first text box and set "LstFocus" to that handle '############################################################################################# CtlHndl = HWND(#ELEC.VOLTS) LstFocus = CtlHndl
'############################################################################################ ' Evry control has at least on programmer definable data area. The below code sets that ' data area of the text boxes to the values VOLTS, AMPS, REST for later use. '############################################################################################ CALLDLL #USER, "SetWindowLongA", CtlHndl AS ULONG, GWL.USERDATA AS LONG, VOLTS AS LONG, RetVal AS VOID CtlHndl = HWND(#ELEC.AMPS) CALLDLL #USER, "SetWindowLongA", CtlHndl AS ULONG, GWL.USERDATA AS LONG, AMPS AS LONG, RetVal AS VOID CtlHndl = HWND(#ELEC.REST) CALLDLL #USER, "SetWindowLongA", CtlHndl AS ULONG, GWL.USERDATA AS LONG, REST AS LONG, RetVal AS VOID
'############################################################################ ' Retain the names of the text boxes for later use '############################################################################ CtlNames$(0) = "#ELEC.VOLTS" CtlNames$(1) = "#ELEC.AMPS" CtlNames$(2) = "#ELEC.REST"
A = FocusCB() WAIT
'---------------------------------------------------------- '----------------------------------------------------------
SUB DEMO.DONE ElecHndl$
IF PadHndl THEN CLOSE #PAD END IF
CLOSE #USER CLOSE #ELEC END
END SUB
'---------------------------------------------------------- '----------------------------------------------------------
SUB ADD.VAL BtnHndl$ '######################################################################## ' This module incrementally sets the focus to the next text box '######################################################################## GWL.USERDATA = -21
AryPos = 0 CtlId = 0
CtlStr$ = "" Tmp$ = ""
'########################################################################## ' Get the value set in the body of the app '########################################################################## CALLDLL #USER, "GetWindowLongA", LstFocus AS ULONG, GWL.USERDATA AS LONG, CtlId AS LONG
'########################################################################## ' Subtract the lowest defined value VOLTS from the obtained value '########################################################################## AryPos = CtlId - VOLTS + 1
IF (AryPos > Ubnd) OR (AryPos < 0) THEN EXIT SUB '<--- if there is an error continue
'############################################################################ ' Get the name of the text box at element AryPos of array CtlNames$() ' assigned in the body of the app and set the focus to that text box '############################################################################# CtlStr$ = CtlNames$(AryPos) LstFocus = HWND(#CtlStr$)
END SUB
'---------------------------------------------------------- '----------------------------------------------------------
SUB OPEN.PAD BtnHndl$
'####################################################################### ' This module creates the number pad tool window and sets up the ' code for placing data in the correct text box '#######################################################################
IF PadHndl THEN EXIT SUB '<--- if set do not create another
[WINDOW.STYLES] WS.OVERLAPPED = HEXDEC("&H00000000") WS.VISIBLE = HEXDEC("&H10000000") WS.CLIPSIBLINGS = HEXDEC("&H04000000") WS.CLIPCHILDREN = HEXDEC("&H02000000") WS.CAPTION = HEXDEC("&H00C00000") WS.SYSMENU = HEXDEC("&H00080000") WS.THICKFRAME = HEXDEC("&H00040000") WS.GROUP = HEXDEC("&H00020000") WS.TABSTOP = HEXDEC("&H00010000")
WS.MINIMIZEBOX = HEXDEC("&H00020000") WS.MAXIMIZEBOX = HEXDEC("&H00010000")
WS.OVERLAPPEDWINDOW = (WS.OVERLAPPED _ OR WS.CAPTION _ OR WS.SYSMENU _ OR WS.THICKFRAME _ OR WS.MINIMIZEBOX _ OR WS.MAXIMIZEBOX)
[WINDOW.EXTENDED.STYLES] WS.EX.DLGMODALFRAME = HEXDEC("&H00000001") WS.EX.STATICEDGE = HEXDEC("&H00020000") WS.EX.TOPMOST = HEXDEC("&H00000008") WS.EX.TOOLWINDOW = HEXDEC("&H00000080")
GWL.STYLE = -16 GWL.EXSTYLE = -20
STRUCT tRect, _ X AS LONG, _ Y AS LONG, _ X1 AS LONG, _ Y1 AS LONG
CtlHndl = 0
'################################################################### ' Set the styles for the buttons on the tool window '################################################################### [BUTTON.STYLES] STYLEBITS #PAD.0, 0, 0, WS.EX.DLGMODALFRAME, 0 STYLEBITS #PAD.1, 0, 0, WS.EX.DLGMODALFRAME, 0 STYLEBITS #PAD.P, 0, 0, WS.EX.DLGMODALFRAME, 0 STYLEBITS #PAD.2, 0, 0, WS.EX.DLGMODALFRAME, 0 STYLEBITS #PAD.3, 0, 0, WS.EX.DLGMODALFRAME, 0 STYLEBITS #PAD.NV, 0, 0, WS.EX.DLGMODALFRAME, 0 STYLEBITS #PAD.4, 0, 0, WS.EX.DLGMODALFRAME, 0 STYLEBITS #PAD.5, 0, 0, WS.EX.DLGMODALFRAME, 0 STYLEBITS #PAD.NA, 0, 0, WS.EX.DLGMODALFRAME, 0 STYLEBITS #PAD.6, 0, 0, WS.EX.DLGMODALFRAME, 0 STYLEBITS #PAD.7, 0, 0, WS.EX.DLGMODALFRAME, 0 STYLEBITS #PAD.8, 0, 0, WS.EX.DLGMODALFRAME, 0 STYLEBITS #PAD.9, 0, 0, WS.EX.DLGMODALFRAME, 0
[DEFINE.BUTTONS] '################################################################ ' All of the buttons use the same event handler [SET.TEXT] '################################################################ BUTTON #PAD.0, "0", SET.TXT, UL, 5, 5, 20, 25 BUTTON #PAD.1, "1", SET.TXT, UL, 30, 5, 20, 25 BUTTON #PAD.P, ".", SET.TXT, UL, 55, 5, 30, 25 BUTTON #PAD.2, "2", SET.TXT, UL, 5, 35, 20, 25 BUTTON #PAD.3, "3", SET.TXT, UL, 30, 35, 20, 25 BUTTON #PAD.NV, "NV", SET.TXT, UL, 55, 35, 30, 25 BUTTON #PAD.4, "4", SET.TXT, UL, 5, 65, 20, 25 BUTTON #PAD.5, "5", SET.TXT, UL, 30, 65, 20, 25 BUTTON #PAD.NA, "NA", SET.TXT, UL, 55, 65, 30, 25 BUTTON #PAD.6, "6", SET.TXT, UL, 5, 95, 20, 25 BUTTON #PAD.7, "7", SET.TXT, UL, 30, 95, 20, 25 BUTTON #PAD.8, "8", SET.TXT, UL, 5, 125, 20, 25 BUTTON #PAD.9, "9", SET.TXT, UL, 30, 125, 20, 25
'############################################################################### ' Get the location of the NUM PAD button on the main window so we can set ' the number pad tool window below it ' The return values from GetWindowRect() are in monitor coordinates. Since ' the tools window is an independant window it can be placed at monitor ' coordinates. '###############################################################################
CtlHndl = HWND(#ELEC.PAD) CALLDLL #USER, "GetWindowRect", CtlHndl AS ULONG, tRect AS STRUCT, RetVal AS VOID
UpperLeftX = tRect.X1.struct - 5 UpperLeftY = tRect.Y.struct + tRect.Y1.struct - tRect.Y.struct + 5 WindowWidth = 100 WindowHeight = 190
'########################################################################## ' Define the style of the window and show it '########################################################################## STYLEBITS #PAD, WS.CAPTION OR WS.CLIPCHILDREN OR WS.SYSMENU, _ WS.OVERLAPPEDWINDOW, WS.EX.TOOLWINDOW OR WS.EX.TOPMOST, 0 OPEN "NUM PAD" FOR WINDOW AS #PAD PRINT #PAD, "TRAPCLOSE CLOSE.PAD"
PadHndl = 1 '<--- make it so another window will not appear until ' this one is closed
END SUB
'--------------------------------------------------------------------- '---------------------------------------------------------------------
SUB CLOSE.PAD BtnHndl$
'<------------ close the number pad ---------> CLOSE #PAD PadHndl = 0 '<--- allow another to be created END SUB
'--------------------------------------------------------------------- '---------------------------------------------------------------------
SUB SET.TXT BtnHndl$ '###################################################################### ' This module is the event handler for the number padd tool window ' It determies which button was pressed on the tool window and ' which text box is to receive the data '#######################################################################
GWL.USERDATA = -21
BtnHndl = 0 CtlId = 0 AryPos = 0
TxtIn$ = "" TxtOut$ = "" Nam$ = ""
BtnHndl = HWND(#BtnHndl$) '<--- button pressed on the number pad
'###################################################################################### ' Determine which text box is to receive data by retrieving its number that was set ' in the app body '######################################################################################
CALLDLL #USER, "GetWindowLongA", LstFocus AS ULONG, GWL.USERDATA AS LONG, CtlId AS LONG
'<---------- get the length of the button caption ---------------> CALLDLL #USER, "GetWindowTextLengthA", BtnHndl AS ULONG, TxtLen AS LONG, TxtIn$ = SPACE$(TxtLen)
'<---------- get the button caption ---------------------> TxtLen = TxtLen + 1 CALLDLL #USER, "GetWindowTextA", BtnHndl AS ULONG, TxtIn$ AS PTR, TxtLen AS LONG, TxtLen AS LONG
'<---------- get the name of the text box -------------------> AryPos = CtlId - VOLTS Nam$ = CtlNames$(AryPos)
'<----------- get the contents of the text box --------------> PRINT #Nam$, "!contents? TxtOut$"
'<-- concatenate the caption of the button to the contents of the text box --> TxtOut$ = TxtOut$ + TxtIn$
'<--------- set the new contents of the text box -----------> PRINT #Nam$, TxtOut$
END SUB
'------------------------------------------------------------------------- '-------------------------------------------------------------------------
FUNCTION FocusCB()
'########################################################################## ' This is a pseudo-callback funciton. It run continuously to monitor ' which control, if any, has the focus. '##########################################################################
GWL.USERDATA = -21
FocusHndl = 0 CtlHndl = 0 FuncPtr = 0
[DO.SCAN] SCAN '<--- interrupt execution to perform other tasks
CALLDLL #USER, "GetFocus", CtlHndl AS ULONG '<--- get the control with the focus
'########################################################################## ' Get the programmer data, if any, from the control that has the focus '##########################################################################
CALLDLL #USER, "GetWindowLongA", CtlHndl AS ULONG, GWL.USERDATA AS LONG, CtlId AS LONG
'########################################################################## ' If the programmer data is less than the lowest value defined in the ' body of the app, i. e., VOLTS, do another scan '##########################################################################
IF CtlId < VOLTS THEN GOTO [DO.SCAN]
'########################################################################## ' If the control with the focus is equal to the current text box with the ' focus then do another scan '##########################################################################
IF LstFocus = CtlHndl THEN GOTO [DO.SCAN] END IF
'<---- set the focus to the text box that now has the focus -----> LstFocus = CtlHndl AryPos = CtlId - VOLTS
GOTO [DO.SCAN]
END FUNCTION '
|
|
|
Post by Rod on Jul 21, 2021 11:12:36 GMT -5
I can't code right now I have no operational PC. Curly wants to display more than one text box on screen, a form. Either the program or the user can select a text box on the form. Whatever text box is selected should be highlighted for input and a popup keypad should allow numeric and a few character input. When the input is complete, as signalled by the popup keypad closing or some other event the input is validated and if passed we move on if fail we stay highlighted.
So the tools we need are get focus() knowing what each handle represents, So we need to record the handle of each text box as it is created. We need to highlight the text box in some way. I like the surrounding graphic box but there are countless solutions. We need to set how the box will be edited, I favour capturing the current contents, redisplaying and moving the cursor to the end but there are countless solutions. We need to know how the edit completion is signalled. Attempting to move to another text box is one, closing the popup is another.
When the edit is signalled complete it will be validated and if it fails the edit is not complete and we continue the highlight. Failed Textboxes will be highlighted as such , passed as such and incomplete as such. a method to abandon or force fail a text box may be necessary.
Now we get an understanding of why no reply. It is a lot more complex than Curly realises, but very doable. If only I had a PC!
|
|
|
Post by Rod on Jul 21, 2021 11:15:56 GMT -5
Oh and don't get hung up on touch. Touch uses legacy events so just think leftButtonUp, the focus may need a timer to know where we are but touch is just mouse input.
|
|
curly
Full Member
Posts: 161
|
Post by curly on Jul 21, 2021 16:17:21 GMT -5
Hi All, I understand you all have other lives, but I suddenly noticed that I was now labelled as a full member?? just as things appeared to go quiet, and I wondered if I had been moved to a different section or something? I really am still very much a novice!
I gave a short presentation to my guys today. They loved Rod's button by a textbox that called up the number pad, and they think I'm a genius (HeeHee!)creating the number pad with the other options of LIM, N/A etc. It looks like the current issue that Rod says is 'doable'may not be neede after all. It's really important I give them what they want, not what I want them to want?
Walt, I don't have a tablet yet, and am running on my PC. When I tried to run your original code, the window appeared with the three textboxes and with the two buttons. I couldn't get the buttons to do anything? The code Rod created requires a button for each textbox where I want to use the number pad. Does your option use a total of two buttons, one to to call the number pad, and the other to put the data into the textbox of my choice? This would obviously reduce the amount to code I need to write? It's past my bedtime now, so I will try running your code again in the morning. Thank you.
The guys also prefer the comboboxes to be altered with stylebits to prevent typing directly into the combobox and having the contents ignored. Chris Iverson gave me the code for that, so thank you Chris, they think I'm really clever to do that as well! So I'm going to be busy for a few days creating all the stylebits, and maybe lots of Rod's buttons.
Thank you all very much, stay safe, David
|
|
|
Post by Walt Decker on Jul 21, 2021 16:44:44 GMT -5
No. You could get by with only the num pad button. Then the user would have to either click (touch) an edit control so it would gain the focus or add a button to the num pad control to change the focus to the NEXT text box. If you wanted to do instant error checking the APPLY button could easily be modified to check for the errors you define. If a NEXT or SET button is added to the num pad, instant checking could be accomplished there also. In the pseudo-callback, instant checking could be accomplished there as well. Doing things in an encapsulated modular way makes it easy to modify parts without breaking other parts.
Try to remember a couple of things.
1: The fewer operations the end user has to perform and/or remember, the easier the app is to use. The best app is one that is used the most.
2: Make the app easy to maintain. Three months from now you will have forgotten at least 50% of how the code works. One year from now you will have a very difficult time unless you lend an eye to maintenance.
|
|
|
Post by Brandon Parker on Jul 22, 2021 14:24:42 GMT -5
I understand you all have other lives, but I suddenly noticed that I was now labelled as a full member?? just as things appeared to go quiet, and I wondered if I had been moved to a different section or something? I really am still very much a novice! This is nothing more than an automated change based on post counts. It is pretty common and based on the assumption that people learn more about the subject at hand as they post and discuss it; in this case, the subject is Liberty BASIC. That being known, people should not post superfluous things just to get their post counts up as this will draw negative action from Moderators/Administrators. Walt, this statement is arguable for sure... My wife and I have a baby monitor that has its own app. The camera works Ok, but the application, although we use it more than pretty much any other app on our phones, is also a piece of junk. It is the most force-stopped application and is a disgrace when it comes to reliability. If the Android Play store could/would track the number of force-stops, this application would be miles ahead of every other app. Just my two cents there, but I think the best app is one that gets the job done efficiently and reliably for all users. {:0) Brandon Parker
|
|
|
Post by Walt Decker on Jul 22, 2021 14:37:36 GMT -5
Mr. Parker:
Do you have a choice?
Perhaps I should have said, "Given a choice, the best app is the one used the most."
|
|
|
Post by Brandon Parker on Jul 22, 2021 15:34:06 GMT -5
Not at all... It is a camera and app combo; both are proprietary to the company. The app used to be good but has been plagued by issues over the last couple of years. Now, back to the regularly scheduled topic of Liberty BASIC... {:0) Brandon Parker
|
|