|
Post by turtleman on Jul 6, 2024 6:01:31 GMT -5
I appreciate everyone's help, but to ask a semi-embarrassing question (that probably applies to most programs), what's the downside of incorporating one or more additional dll's? My program already calls several.
Chris: I'm confused by some of the code examples that include dll downloads. For example: once downloaded, how are the dll's incorporated so I can run the "test.bas" program? I've added them to my LB folder without success and am obviously doing something wrong. Thanks!
Never mind! I trying installing into the correct folder and the program now runs. DUH! I hope I can figure out how to revert to white upon ENTER.
|
|
|
Post by Walt Decker on Jul 6, 2024 9:51:33 GMT -5
That is a good question and something that all programmers should ask themselves.
There are two downsides to using dlls produced by a second party, this includes the base operating system provider.
1 - Functions within the dll may not be updated to take advantage of the operating system inhancements or functions within the dll may be excluded from current versions of the dll.
2 - With LB even a "Hello world" application is over a megabyte. Adding dlls increases that size somewhat. You have to insure that the calling app knows where the dll(s) reside.
|
|
|
Post by Rod on Jul 7, 2024 11:25:02 GMT -5
Dll’s are often patches to supply some functionality missing in Liberty. There are a lot. Few have ongoing support. So if Windows makes a change you’re pretty much stuffed.
That said dlls soldier on, me… native or systemic dlls, so api on that basis is sound but patches are patches.
|
|
|
Post by Walt Decker on Jul 10, 2024 17:01:12 GMT -5
Here is a way to change the colors of an edit control on the fly. Unpack CLRCONTROL.ZIP in the same place you save the following source code.
' DLL FUNCTIONS '========================== '"FN_InitProperties", WinHndl AS LONG, TextTag$ AS PTR, BkgndTag$ AS PTR, _ ' WinColor AS LONG, BmpTrue AS BOOLEAN, RetVal AS LONG
'WinHndl = HWND(#WINDOW) 'TextTag$ = String, e. g. "FORECOLOR"; may be mixed case 'BkgndTag$ = String, e. g. "BKGCOLOR"; may be mixed case 'WinColor = Long Value defining the rgb color of the window background, ' e. g. 255 'BmpTrue = 0 or 1. If BmpTrue is 1(one) then WinColor must be the handle of a ' DIB memory bitmap 'RetVal = Return Value; 0 = failed, > 0 = success '-------------------------------------- '"SetProperty", CtlHndl AS LONG, TxtTag$ AS PTR, ClrTxt AS LONG, _ ' BkgTag$ AS PTR, ClrBkg AS LONT, RetVal AS VOID 'CtlHndl = HWND(#WINDOW.CONTROL) 'TxtTag$ = TextTag$ passed to function FN_InitProperties() 'ClrTxt = Long value defining text color, e. g. 255 'BkgTag$ = BkgndTag$ passed to function FN_InitProperties() 'CltBkg = Long value defining background color, e. g. 27635 'RetVal = This function does not return a value '------------------------------------------------------ '"FN_CLOSE", WinHndl AS LONG, RetVal AS LONG 'WinHndl = HWND(#WINDOW) passed to FN_InitProperties() 'RetVal = Return value; 0 = failed, > 0 = success ' 'NOTE: The LB IDE does not properly close the DLL so that this function 'must be called for each window initialized. '========================================================= '========================================================= 'Controls this DLL will work with are edit (textbox), listbox and 'static (statictext).
'More than one window can be initialized. The same strings should be used 'for the text and background color tags. '========================================================= '=========================================================
[DEF.GLOBALS] GLOBAL HiliteBkng, _ HiliteText
GLOBAL NormalBkng, _ TextColor
GLOBAL BnClicked, _ Active
GLOBAL WinHndl
GLOBAL ForeClr$, _ BackClr$
DIM Ctrl$(1, 1)
[INIT.GLOBALS] HiliteBkng = HEXDEC("&H00008B") HiliteText = HEXDEC("&HFFFFFF") NormalBkng = HEXDEC("&HFFFFFF") TextColor = 0 BnClicked = 0 Active = 0
ForeClr$ = "TEXTCLR" BackClr$ = "BACKGROUND"
[INIT.VARBS] CtlHndl = 0 RetVal = 0
[DECLARE.DLL] OPEN "CTL_COLOR" FOR DLL AS #CTLCLR
[DEF.CONTROLS] TEXTBOX #DMO.TXB1, 5, 5, 100, 20 TEXTBOX #DMO.TXB2, 110, 5, 100, 20
[DEF.WINDOE] WindowWidth = 230 WindowHeight = 75
OPEN "TEXT DEMO" FOR WINDOW AS #DMO
[RETRIEVE.HANDLES] WinHndl = HWND(#DMO) Ctrl$(0, 0) = STR$(HWND(#DMO.TXB1)) Ctrl$(0, 1) = "#DMO.TXB1" Ctrl$(1, 0) = STR$(HWND(#DMO.TXB2)) Ctrl$(1, 1) = "#DMO.TXB2"
[INITIALIZE.DLL] CALLDLL #CTLCLR, "FN_InitProperties", WinHndl AS LONG, ForeClr$ AS PTR, _ BackClr$ AS PTR, 0 AS LONG, 0 AS LONG, RetVal AS LONG
CtlHndl = VAL(Ctrl$(0, 0)) GOSUB [SET.NORMAL] CtlHndl = VAL(Ctrl$(1, 0)) GOSUB [SET.NORMAL]
#DMO "TRAPCLOSE [END.DEMO]"
[BEGIN.TIMER] TIMER 150, [CHECK.FOCUS]
WAIT
'---------------------------- '----------------------------
[END.DEMO] CALLDLL #CTLCLR, "FN_CLOSE", WinHndl AS LONG, RetVal AS LONG CLOSE #CTLCLR
CLOSE #DMO END
'------------------- '-------------------
[CHECK.FOCUS]
TIMER 0
CtlHndl = 0 I = 0
Ctl$ = ""
CALLDLL #user32, "GetFocus", CtlHndl AS LONG
FOR I = 0 TO 1 IF CtlHndl = VAL(Ctrl$(I, 0)) THEN IF Active = 0 THEN BnClicked = CtlHndl Active = I + 1 Ctl$= Ctrl$(I, 1) #Ctl$, "!HIDE" GOSUB [HILITE.CONTROL] #Ctl$, "!SHOW" #Ctl$, "!SETFOCUS" GOTO [BEGIN.TIMER] END IF
IF BnClicked = CtlHndl THEN GOTO [BEGIN.TIMER]
BnClicked = VAL(Ctrl$(Active - 1, 0)) CtlHndl = BnClicked Ctl$ = Ctrl$(Active - 1, 1) #Ctl$, "!HIDE" GOSUB [SET.NORMAL] #Ctl$, "!SHOW"
CtlHndl = VAL(Ctrl$(I, 0)) BnClicked = CtlHndl Active = I + 1 Ctl$ = Ctrl$(I, 1) #Ctl$, "!HIDE" GOSUB [HILITE.CONTROL] #Ctl$, "!SHOW" #Ctl$, "!SETFOCUS" GOTO [BEGIN.TIMER] END IF NEXT I PRINT "NOT FOUND"; CtlHndl GOTO [BEGIN.TIMER]
'------------------- '-------------------
[SET.NORMAL]
CALLDLL #CTLCLR, "SetProperty", CtlHndl AS LONG, ForeClr$ AS PTR, _ TextColor AS LONG, BackClr$ AS PTR, NormalBkng AS LONG, _ RetVal AS VOID RETURN
'------------------- '-------------------
[HILITE.CONTROL]
CALLDLL #CTLCLR, "SetProperty", CtlHndl AS LONG, ForeClr$ AS PTR, _ HiliteText AS LONG, BackClr$ AS PTR, HiliteBkng AS LONG, _ RetVal AS VOID RETURN
|
|
|
Post by Walt Decker on Jul 10, 2024 18:24:56 GMT -5
Here is the same code with three edit controls. The third (bottom) control is not defined in array Ctrl$() nor are its colors set. When it is clicked the last control that was hilited will be cleared.
'' DLL FUNCTIONS '========================== '"FN_InitProperties", WinHndl AS LONG, TextTag$ AS PTR, BkgndTag$ AS PTR, _ ' WinColor AS LONG, BmpTrue AS BOOLEAN, RetVal AS LONG
'WinHndl = HWND(#WINDOW) 'TextTag$ = String, e. g. "FORECOLOR"; may be mixed case 'BkgndTag$ = String, e. g. "BKGCOLOR"; may be mixed case 'WinColor = Long Value defining the rgb color of the window background, ' e. g. 255 'BmpTrue = 0 or 1. If BmpTrue is 1(one) then WinColor must be the handle of a ' DIB memory bitmap 'RetVal = Return Value; 0 = failed, > 0 = success '-------------------------------------- '"SetProperty", CtlHndl AS LONG, TxtTag$ AS PTR, ClrTxt AS LONG, _ ' BkgTag$ AS PTR, ClrBkg AS LONT, RetVal AS VOID 'CtlHndl = HWND(#WINDOW.CONTROL) 'TxtTag$ = TextTag$ passed to function FN_InitProperties() 'ClrTxt = Long value defining text color, e. g. 255 'BkgTag$ = BkgndTag$ passed to function FN_InitProperties() 'CltBkg = Long value defining background color, e. g. 27635 'RetVal = This function does not return a value '------------------------------------------------------ '"FN_CLOSE", WinHndl AS LONG, RetVal AS LONG 'WinHndl = HWND(#WINDOW) passed to FN_InitProperties() 'RetVal = Return value; 0 = failed, > 0 = success ' 'NOTE: The LB IDE does not properly close the DLL so that this function 'must be called for each window initialized. '========================================================= '========================================================= 'Controls this DLL will work with are edit (textbox), listbox and 'static (statictext).
'More than one window can be initialized. The same strings should be used 'for the text and background color tags. '========================================================= '=========================================================
[DEF.GLOBALS] GLOBAL HiliteBkng, _ HiliteText
GLOBAL NormalBkng, _ TextColor
GLOBAL BnClicked, _ Active
GLOBAL WinHndl
GLOBAL ForeClr$, _ BackClr$
DIM Ctrl$(1, 1)
[INIT.GLOBALS] HiliteBkng = HEXDEC("&H00008B") HiliteText = HEXDEC("&HFFFFFF") NormalBkng = HEXDEC("&HFFFFFF") TextColor = 0 BnClicked = 0 Active = 0
ForeClr$ = "TEXTCLR" BackClr$ = "BACKGROUND"
[INIT.VARBS] CtlHndl = 0 RetVal = 0
[DECLARE.DLL] OPEN "CTL_COLOR" FOR DLL AS #CTLCLR
[DEF.CONTROLS] TEXTBOX #DMO.TXB1, 5, 5, 100, 20 TEXTBOX #DMO.TXB2, 110, 5, 100, 20 TEXTBOX #DMO.TXB3, 50, 30, 100, 20
[DEF.WINDOE] WindowWidth = 230 WindowHeight = 95
OPEN "TEXT DEMO" FOR WINDOW AS #DMO
[RETRIEVE.HANDLES] WinHndl = HWND(#DMO) Ctrl$(0, 0) = STR$(HWND(#DMO.TXB1)) Ctrl$(0, 1) = "#DMO.TXB1" Ctrl$(1, 0) = STR$(HWND(#DMO.TXB2)) Ctrl$(1, 1) = "#DMO.TXB2"
[INITIALIZE.DLL] CALLDLL #CTLCLR, "FN_InitProperties", WinHndl AS LONG, ForeClr$ AS PTR, _ BackClr$ AS PTR, 0 AS LONG, 0 AS LONG, RetVal AS LONG
CtlHndl = VAL(Ctrl$(0, 0)) GOSUB [SET.NORMAL] CtlHndl = VAL(Ctrl$(1, 0)) GOSUB [SET.NORMAL]
#DMO "TRAPCLOSE [END.DEMO]"
[BEGIN.TIMER] TIMER 150, [CHECK.FOCUS]
WAIT
'---------------------------- '----------------------------
[END.DEMO] CALLDLL #CTLCLR, "FN_CLOSE", WinHndl AS LONG, RetVal AS LONG CLOSE #CTLCLR
CLOSE #DMO END
'------------------- '-------------------
[CHECK.FOCUS]
TIMER 0
CtlHndl = 0 I = 0
Ctl$ = ""
CALLDLL #user32, "GetFocus", CtlHndl AS LONG
FOR I = 0 TO 1 IF CtlHndl = VAL(Ctrl$(I, 0)) THEN IF Active = 0 THEN BnClicked = CtlHndl Active = I + 1 Ctl$= Ctrl$(I, 1) #Ctl$, "!HIDE" GOSUB [HILITE.CONTROL] #Ctl$, "!SHOW" #Ctl$, "!SETFOCUS" GOTO [BEGIN.TIMER] END IF
IF BnClicked = CtlHndl THEN GOTO [BEGIN.TIMER]
BnClicked = VAL(Ctrl$(Active - 1, 0)) CtlHndl = BnClicked Ctl$ = Ctrl$(Active - 1, 1) #Ctl$, "!HIDE" GOSUB [SET.NORMAL] #Ctl$, "!SHOW"
CtlHndl = VAL(Ctrl$(I, 0)) BnClicked = CtlHndl Active = I + 1 Ctl$ = Ctrl$(I, 1) #Ctl$, "!HIDE" GOSUB [HILITE.CONTROL] #Ctl$, "!SHOW" #Ctl$, "!SETFOCUS" GOTO [BEGIN.TIMER] END IF NEXT I
IF CtlHndl = WinHndl THEN GOTO [BEGIN.TIMER]
IF Active THEN BnClicked = CtlHndl CtlHndl = VAL(Ctrl$(Active - 1, 0)) Ctl$ = Ctrl$(Active - 1, 1) #Ctl$, "!HIDE" GOSUB [SET.NORMAL] #Ctl$, "!SHOW" CALLDLL #user32, "SetFocus", BnClicked AS LONG, RetVal AS VOID BnClicked = 0 Active = 0 END IF
GOTO [BEGIN.TIMER]
'------------------- '-------------------
[SET.NORMAL]
CALLDLL #CTLCLR, "SetProperty", CtlHndl AS LONG, ForeClr$ AS PTR, _ TextColor AS LONG, BackClr$ AS PTR, NormalBkng AS LONG, _ RetVal AS VOID RETURN
'------------------- '-------------------
[HILITE.CONTROL] 'HiliteBkng = HEXDEC("&H00008B") 'HiliteText = HEXDEC("&HFFFFFF")
CALLDLL #CTLCLR, "SetProperty", CtlHndl AS LONG, ForeClr$ AS PTR, _ HiliteText AS LONG, BackClr$ AS PTR, HiliteBkng AS LONG, _ RetVal AS VOID RETURN
|
|
|
Post by Walt Decker on Jul 12, 2024 9:50:49 GMT -5
Here is another one. This has two windows with different window background colors. One has three edit controls that toggles the background colors of two and clears the control to black text on white when the bottom control or the other window is selected. The second window has a listbox and a static control with custom background colors. ' [DECLARE.GLOBALS] GLOBAL BnClicked, _ Hilited
GLOBAL ForeClr$, _ BackClr$
DIM Ctrl$(1, 1) DIM LbItems$(5)
[INIT.GLOBALS] ForeClr$ = "TEXTCLR" BackClr$ = "BKGND"
BnClicked = 0 Hilited = 0
RetVal = FN.SampleList()
[DECLARE.DLL] OPEN "CTL_COLOR" FOR DLL AS #CLRCTL
[DEF.CONTROLS] TEXTBOX #DMO.TXB1, 5, 5, 100, 20 TEXTBOX #DMO.TXB2, 110, 5, 100, 20 TEXTBOX #DMO.TXB3, 50, 30, 100, 20
LISTBOX #WIN1.LBX, LbItems$(), LBOX, 5, 5, 100, 75 STATICTEXT #WIN1.STA, "THIS IS TEXT", 110, 5, 75, 20 BUTTON #WIN1.BTN, "NOTHING", BTN, UL, 110, 30, 60, 20
[DEF.WINDOWS] WindowWidth = 230 WindowHeight = 95
OPEN "TEXT DEMO" FOR WINDOW AS #DMO
UpperLeftX = 200 UpperLeftY = 200 WindowWidth = 230 WindowHeight = 130
OPEN "DMO WIN 2" FOR WINDOW AS #WIN1
[SAVE.CONTROL.HANDLES] Ctrl$(0, 0) = STR$(HWND(#DMO.TXB1)) Ctrl$(0, 1) = "#DMO.TXB1" Ctrl$(1, 0) = STR$(HWND(#DMO.TXB2)) Ctrl$(1, 1) = "#DMO.TXB2"
[SET.NORMAL.CONTROL.COLORS]
'&H7A96E9 salmon '&HD5EFFF papya '&HB9DAFF peach '&HFAE6E6 LAVENDER
RetVal = FN.SetCtrlClr(VAL(Ctrl$(0, 0)), 0, HEXDEC("&HFFFFFF")) RetVal = FN.SetCtrlClr(VAL(Ctrl$(1, 0)), 0, HEXDEC("&HFFFFFF")) RetVal = FN.SetCtrlClr(HWND(#WIN1.LBX), 0, HEXDEC("&HD5EFFF")) RetVal = FN.SetCtrlClr(HWND(#WIN1.STA), 0, HEXDEC("&HFAE6E6"))
[INITIALIZE.WINDOW] RetVal = FN.InitDll(HWND(#DMO), HEXDEC("&H7A96E9"), 0) RetVal = FN.InitDll(HWND(#WIN1), HEXDEC("&HB9DAFF"), 0) #DMO, "TRAPCLOSE END.DMO" #WIN1, "TRAPCLOSE END.DMO"
RetVal = FN.SetSleep(150)
WAIT
'-------------------------------- '--------------------------------
SUB BTN BtnHndl$
END SUB
'-------------------------------- '--------------------------------
SUB END.DMO Win$
WinHndl = HWND(#DMO) CALLDLL #CLRCTL, "FN_CLOSE", WinHndl AS ULONG, RetVal AS ULONG WinHndl = HWND(#WIN1) CALLDLL #CLRCTL, "FN_CLOSE", WinHndl AS ULONG, RetVal AS ULONG CLOSE #CLRCTL
CLOSE #WIN1 CLOSE #DMO END END SUB
'-------------------------------- '--------------------------------
FUNCTION FN.CheckFocus()
NormalBkg = HEXDEC("&HFFFFFF") NormalTxt = 0 HiliteBkg = HEXDEC("&H00008B") HiliteTxt = HEXDEC("&HFFFFFF")
I = 0
SCAN CtlHndl = 0 RetVal = 0 Ctl$ = ""
CALLDLL #user32, "GetFocus", CtlHndl AS ULONG
FOR I = 0 TO 1 IF CtlHndl = VAL(Ctrl$(I, 0)) THEN IF BnClicked = 0 THEN '<--- SET INITIAL HILITE BnClicked = CtlHndl Hilited = I + 1 Ctl$ = Ctrl$(I, 1) #Ctl$, "!HIDE" RetVal = FN.SetCtrlClr(CtlHndl, HiliteTxt, HiliteBkg) #Ctl$, "!SHOW" #Ctl$, "!SETFOCUS" RetVal = FN.SetSleep(150) EXIT FUNCTION END IF
IF CtlHndl = BnClicked THEN RetVal = FN.SetSleep(150) EXIT FUNCTION END IF
'----- CLEAR HILITE AND SET NEXT HILITE ----- Ctl$ = Ctrl$(Hilited - 1, 1) #Ctl$, "!HIDE" RetVal = FN.SetCtrlClr(VAL(Ctrl$(Hilited - 1, 0)), NormalTxt, NormalBkg) #Ctl$, "!SHOW" BnClicked = CtlHndl Hilited = I + 1 Ctl$ = Ctrl$(I, 1) #Ctl$, "!HIDE" RetVal = FN.SetCtrlClr(CtlHndl, HiliteTxt, HiliteBkg) #Ctl$, "!SHOW" #Ctl$, "!SETFOCUS" RetVal = FN.SetSleep(150) EXIT FUNCTION
END IF NEXT I
IF BnClicked THEN '<--- CLEAR HILITE Ctl$ = Ctrl$(Hilited - 1, 1) #Ctl$, "!HIDE" RetVal = FN.SetCtrlClr(VAL(Ctrl$(Hilited - 1, 0)), NormalTxt, NormalBkg) #Ctl$, "!SHOW" BnClicked = 0 Hilited = 0 END IF
RetVal = FN.SetSleep(150)
END FUNCTION
'-------------------------------- '--------------------------------
FUNCTION FN.InitDll(WinHndl, WinColor, BmpTrue)
CALLDLL #CLRCTL, "FN_InitProperties", WinHndl AS LONG, ForeClr$ AS PTR, _ BackClr$ AS PTR, WinColor AS ULONG, BmpTrue AS LONG, _ RetVal AS LONG FN.InitDll = RetVal END FUNCTION
'-------------------------------- '--------------------------------
FUNCTION FN.SetCtrlClr(CtlHndl, TxtClr, BkgClr)
CALLDLL #CLRCTL, "SetProperty", CtlHndl AS ULONG, ForeClr$ AS PTR, _ TxtClr AS ULONG, BackClr$ AS PTR, BkgClr AS ULONG, _ RetVal AS VOID END FUNCTION
'-------------------------------- '--------------------------------
FUNCTION FN.SetSleep(Ms)
RetVal = 0 CALLDLL #kernel32, "Sleep", Ms AS LONG, RetVal AS LONG
RetVal = FN.CheckFocus()
END FUNCTION
'-------------------------------- '--------------------------------
FUNCTION FN.SampleList() I = 0 FOR I = 0 TO 5 LbItems$(I) = "ITEM " + STR$(I + 1) NEXT I
END FUNCTION '
|
|
|
Post by turtleman on Jul 12, 2024 10:27:03 GMT -5
Thanks Walt, there sure is a lot of "food for thought" in those examples. I'm afraid, however, that I'll never understand all of the code, which is way more than I ever would have anticipated. I tried a couple other solutions, such as trying to identify textbox locations with mouse coordinates, but quickly learned that it doesn't seem to work over textboxes.
Some unrelated issues are getting in the way of tackling all of this right now, but I very much appreciate all your help!
|
|
|
Post by Walt Decker on Jul 12, 2024 11:17:22 GMT -5
You are welcome, turtleman. There is a way to toggle the edit controls using the ENTER key. That entails changing the style of the control to multi-line and enabling the return key. You would then have to use API function GetAsyncKeyState() to determine if the ENTER key was clicked.
That is not quite correct. You can do it by constantly monitoring the mouse position using GetCursorPos(), checking the mouse left button down state using GetAsyncKeyState() and then using API function WindowFromPoint(). Actually more work than it is worth.
I realize that the second one is not in your programming style and therefore may be rather confusing to you. If, when you are ready, you want to use any of the code I posted, I am willing to explain it in detail and give the reason for each step.
|
|
|
Post by turtleman on Jul 12, 2024 11:43:35 GMT -5
I know the x,y locations and size of the textboxes, so I thought a click when the mouse coordinates are within designated areas could be used to identify the textbox selected. Of course, I don't know if mouse clicks over textboxes can be detected either. Anyway, that's what I had in mind.
Thanks for offering to explain; but in my case, that might be like trying to communicate in a foreign language when I've only taken an introductory course.
|
|
|
Post by Walt Decker on Jul 12, 2024 13:13:02 GMT -5
I am quite certain a button click on a text box is recorded, but I will check it out if you want.
|
|
|
Post by turtleman on Jul 12, 2024 13:25:47 GMT -5
I'm not able to test if mouse clicks over a textbox are registered right now, but if it works, what do you think about my simply checking coordinates method? Then hide and show commands for the overlapping textboxes could be used for color selections.
|
|
|
Post by Walt Decker on Jul 12, 2024 13:45:57 GMT -5
It is doable; however, I think it is code you do not need when there is an API function that will return the handle of the control. With that handle all you would have to do is parse an array for the handle rather than parse an array of coordinates then determine which control it is then switch controls. To me that is rather confusing. Simply using API function GetFocus() is simpler.
|
|
|
Post by turtleman on Jul 12, 2024 13:57:22 GMT -5
Thanks for checking - most encouraging. Would you believe I don't understand the API function and parsing that you mentioned? I often write more elaborate (and ridiculous) code than necessary when I don't know how to employ more "elegant" solutions.
I thought you couldn't get an indication when clicking a textbox, which is the reason for the lengthier solutions? Now I'm confused even more!
|
|
|
Post by Walt Decker on Jul 12, 2024 15:54:09 GMT -5
I have not checked to see if the left button key state is recorded when it is pressed in a text box. Logic tell me it is otherwise the text box would not receive the focus when the left button is clicked.
Parsing is just going through a list looking for a match. When you use INSTR(String$, Match$) the function is looking(parsing) through a list of characters for a match. You can create your own INSTR() function by using a DO/WHILE loop and the MID$() function to look(parse) a string for a match.
From the first example I fill an array(list) with data. This list will be parsed later looking a match:
[RETRIEVE.HANDLES] WinHndl = HWND(#DMO) Ctrl$(0, 0) = STR$(HWND(#DMO.TXB1)) <--- this turns the numeric handle to a string Ctrl$(0, 1) = "#DMO.TXB1" <--- this is the LB handle tag Ctrl$(1, 0) = STR$(HWND(#DMO.TXB2)) Ctrl$(1, 1) = "#DMO.TXB2" '
From the first example I begin parsing the list (Ctrl$()) for a match based on the result obtained from API function GetFocus(). Function GetFocus() returns the numeric handl of the window or control that has the focus or is active. When a window is first created the window itself has the focus. When the user does something to change the focus to a control (which is also a window) that control then receives the focus. Using function GetFocus is cheaper, programming wise, than checking if the left mouse button is pressed, getting the cursor position, and then using API function WindowFromPoint to obtain whe control handle and is a lot cheaper than checking a list of coordinates to see if the cursor is within the client area of a control.
' [CHECK.FOCUS]
TIMER 0
CtlHndl = 0 I = 0
Ctl$ = ""
CALLDLL #user32, "GetFocus", CtlHndl AS LONG '<-- which control did the user select?
FOR I = 0 TO 1 IF CtlHndl = VAL(Ctrl$(I, 0)) THEN '<--- parse the list for a match IF Active = 0 THEN '<--- match found; control is not hilited 'so hilite it. BnClicked = CtlHndl '<--- save the focus for later Active = I + 1 '<--- save list position for later Ctl$= Ctrl$(I, 1) #Ctl$, "!HIDE" GOSUB [HILITE.CONTROL] #Ctl$, "!SHOW" #Ctl$, "!SETFOCUS" GOTO [BEGIN.TIMER] END IF
'<--- the focus will remain on this control until it is changed ' so get out of the loop --->
IF BnClicked = CtlHndl THEN GOTO [BEGIN.TIMER]
'<--- the focus changed so have to unhilte the contro and ' hilite the new one --->
BnClicked = VAL(Ctrl$(Active - 1, 0)) <--- hilited control CtlHndl = BnClicked Ctl$ = Ctrl$(Active - 1, 1) <--- hilired LB control name #Ctl$, "!HIDE" GOSUB [SET.NORMAL] #Ctl$, "!SHOW"
CtlHndl = VAL(Ctrl$(I, 0)) '<--- control with focus so hilite it BnClicked = CtlHndl '<--- save for later use Active = I + 1 '<--- save list position Ctl$ = Ctrl$(I, 1) #Ctl$, "!HIDE" GOSUB [HILITE.CONTROL] #Ctl$, "!SHOW" #Ctl$, "!SETFOCUS" GOTO [BEGIN.TIMER] END IF NEXT I
'<--- the above FOR/NEXT loop will only get ' here if the handle returned by GetFocus ' is not found in the list --->
IF CtlHndl = WinHndl THEN GOTO [BEGIN.TIMER] 'window has the focus
IF Active THEN '<--- unhilit the control BnClicked = CtlHndl CtlHndl = VAL(Ctrl$(Active - 1, 0)) Ctl$ = Ctrl$(Active - 1, 1) #Ctl$, "!HIDE" GOSUB [SET.NORMAL] #Ctl$, "!SHOW" CALLDLL #user32, "SetFocus", BnClicked AS LONG, RetVal AS VOID BnClicked = 0 '<--- no control in list has the focus Active = 0 '<--- no control is hilited END IF
GOTO [BEGIN.TIMER] ' PS: You said you have the coordinates of the text boxes. That means you have to parse through the coordinate list to determine if the cursor is in the client area of a text box. That takes time and additional code. If you are using superimposed text boxes you have to determine which is the hilited text box. More time and code. You have to transfer the text in the hilited text box to the unhilited text box. More time and code. All of that produces needless complication.
|
|
|
Post by Walt Decker on Jul 12, 2024 18:28:34 GMT -5
Here is a method to check if the left mouse button was pressed while in the display coordinates of a text box.
' STRUCT Rect, _ X1 AS LONG, _ Y1 AS LONG, _ X2 AS LONG, _ Y2 AS LONG
STRUCT Point, _ X1 AS LONG, _ Y1 AS LONG
VK.LBUTTON = 1
DIM CoordName$(0, 5) TEXTBOX #DD.TXB1, 5, 5, 75, 25 OPEN "D" FOR WINDOW AS #DD
RetVal = FN.GetWindowRect(HWND(#DD.TXB1)) CoordName$(0, 0) = STR$(Rect.X1.struct) CoordName$(0, 1) = STR$(Rect.Y1.struct) CoordName$(0, 2) = STR$(Rect.X2.struct) CoordName$(0, 3) = STR$(Rect.Y2.struct) CoordName$(0, 4) = STR$(HWND(#DD.TXB1)) CoordName$(0, 5) = "#DD.TXB1"
[BEGIN]
RetVal = FN.KeyState(VK.LBUTTON) PRINT RetVal WAIT
'-------------------- '--------------------
FUNCTION FN.KeyState(Vkey)
[SET.KEY.TIMER] TIMER 150, [CHECK.STATE] WAIT
[CHECK.STATE] TIMER 0 CALLDLL #user32, "GetAsyncKeyState", Vkey AS ULONG, KeyState AS SHORT
IF KeyState THEN RetVal = FN.CheckCoords() IF RetVal THEN PRINT CoordName$(0, 4), CoordName$(0, 5) FN.KeyState = 1 EXIT FUNCTION END IF END IF
GOTO [SET.KEY.TIMER] END FUNCTION
'-------------------- '--------------------
FUNCTION FN.GetWindowRect(WinHndl)
RetVal = 0 CALLDLL #user32, "GetWindowRect", WinHndl AS ULONG, Rect AS STRUCT, _ RetVal AS VOID
END FUNCTION
'-------------------- '--------------------
FUNCTION FN.CheckCoords()
CALLDLL #user32, "GetCursorPos", Point AS STRUCT, RetVal AS VOID
IF Point.Y1.struct < VAL(CoordName$(0, 1)) THEN EXIT FUNCTION IF Point.Y1.struct > VAL(CoordName$(0, 3)) THEN EXIT FUNCTION IF Point.X1.struct < VAL(CoordName$(0, 0)) THEN EXIT FUNCTION IF Point.X1.struct > VAL(CoordName$(0, 2)) THEN EXIT FUNCTION
FN.CheckCoords = 1 END FUNCTION '
|
|