|
Post by BeeTrap on Apr 22, 2022 11:29:17 GMT -5
Hello, I am goofing around with 3 programs to find and store all "functions" found in a range of ".bas" files. This is a modification of Stefan Pendal's "browseForFolder.bas" that Rod presented in his modification of the original Sample Files... then the file output from that prog is called into and use in my modded version of "recursefiles" from Newsletter 102, then... the output file from that modded code is used in "functionfinder20030216a.bas" to find all functions. The problem, more of an irritation, is that the "Browse for Folder" dialog box, created with CallDLL #shell32, "SHBrowseForFolder", BrowseInfo As struct, lpIDList As ulong, I believe, is so low on the screen that I can not see the [OK] or [Cancel] buttons. Or whatever buttons show, not in program right now. I see how to use an API call to Move a "window" that my program has created, but how does one Move a "Window" created by an API call? This is not serious, just bugging the heck out of me. I have seen many programs from other people and places place the window in an inconvenient place before. Can I just use "calldll #user32, "MoveWindow" to do this? And, if so, what is the proper method to get that window's handle? Thanks for entertaining another question from my mind!
|
|
|
Post by Walt Decker on Apr 22, 2022 11:45:53 GMT -5
Make sure that the window has the focus.
CALLDLL #user32, "GetForegroundWindow", WinHndl AS ulong STRUCT tRect, _ X AS LONG, _ Y AS LONG, _ X1 AS LONG, _ Y1 AS LONG CALLDLL #user32, "GetWindowRect", WinHndl AS ULONG, tRect AS STRUCT, RetVal AS VOID BRX = tRect.X1.struct - tRect.X.struct BRY = tRect.Y1.struct - tRect.Y.struct CALLDLL #user32, "MoveWindow", WinHndl AS ULONG, NewPosX AS LONG, NewPosY AS LONG, _ BRX AS LONG, BRY AS LONG, 1 AS LONG, RetVal AS VOID
|
|
|
Post by BeeTrap on Apr 22, 2022 21:36:36 GMT -5
Thank you. I will give that a try in the morning. It would have taken me quite some researching to piece that together. I appreciate your work with API functions.
|
|
|
Post by Rod on Apr 23, 2022 1:38:11 GMT -5
|
|
|
Post by BeeTrap on Apr 24, 2022 7:58:53 GMT -5
Hello, thanks for your answers. I have tried the code that Walt proposed. I have about 40 articles from the LBPE saved, but not that one, thanks Rod. I could not get Walt's code to work by just placing it into my code. If the MainWin was open, then that moved and/or resized according to what I programmed. If I used "NoMainWin", then the Liberty Basic window moved. The "movewindow" code works, just couldn't get it to move the dialog box as soon as it opened. I believe that placing it into the "callback" may be a better choice. Just, my guess! Yesterday I ran NirSoft's "RegistryChangesView" utility before and after running my program. The only changes that I could find were on the BrowseforFolder dialog box's WIDTH and HEIGHT. I never could find any changes on the LOCATION of the dialog box. Today I searched the MS Docs and found: docs.microsoft.com/en-us/windows/win32/api/shlobj_core/nf-shlobj_core-shbrowseforfoldera SHBrowseForFolderA function (shlobj_core.h) Article, 10/13/2021, 6 minutes to read Displays a dialog box that enables the user to select a Shell folder paragraph 1 under "Remarks" For Windows Vista or later, it is recommended that you use IFileDialog with the FOS_PICKFOLDERS option rather than the SHBrowseForFolder function. This uses the Open Files dialog in pick folders mode and is the preferred implementation. and the kicker was...... paragraph 5 under "Remarks"..... If you implement a callback function, specified in the lpfn member of the BROWSEINFO structure, you receive a handle to the dialog box. One use of this window handle is to modify the layout or contents of the dialog box. Because it is not resizable, modifying the older style dialog box is relatively straightforward. Modifying the newer style dialog box is much more difficult, and not recommended. Not only does it have a different size and layout than the old style, but its dimensions and the positions of its controls change every time it is resized by the user. So... I do believe that I am way over my head and will just let this minor problem go away! I do thank you both.
|
|
|
Post by Rod on Apr 24, 2022 8:57:45 GMT -5
On my system the browse for folder dialog opens centre screen, with everything in view.
|
|
|
Post by Walt Decker on Apr 24, 2022 13:29:15 GMT -5
I have not used the browse for folder dialog for 20 years. I use a custom dll that allows me to begin on any drive in any folder and list any file type(s) and return any folder and/or file I select.
The SHbrowseForFolder should open a system modal dialog box that will not let you work in any other window until it is dismissed. However, you should be able to move it around manually so you can see other windows.
Because SHbrowseForFolder is system modal control has not been returned to your app and therefore the code I posted has not been able to function until the dialog has been dismissed.
|
|
|
Post by BeeTrap on Apr 24, 2022 16:29:49 GMT -5
Thanks again guys, as the man said "you can't there from here"! Per Rod, yes, if I manually resized the dialog box by dragging two of the edges, it would shrink and be that same size on next use. Oh well, manually dragging just got old while debugging my horribly written program. But shrink it and be happy!
|
|
|
Post by Walt Decker on Apr 29, 2022 16:47:04 GMT -5
Thought someone might find use for this. The DLL is rather old; worked well for me (integrated into a file find/open dll so no longer used) and not completely tested with LB. The zip contains the following source code plus the DLL.
EDIT: Found an error in the dll code and fixed it. If you have downloaded the zip before: 10:50 am on 30 April 2022 then you should down load it again.
' '################################################################ ' REQUIRED: BrsFF.DLL ' FIRST WRITTEN: JAN, 2001 ' ADAPTED FOR LIBERTY BASIC APRIL, 2022 (NOT THOUROUGHLY TESTED) ' '================================================================ ' OPERATION: ' SELECT FILE TYPES FROM THE TYPES COMBOBOX FOR NEW FILE LIST ' ENTER NEW FILE TYPE IN EDIT CONTROL, CLICK OPEN FOR NEW FILE LIST ' ENTER NEW PATH IN EDIT CONTROL, CLICK OPEN FOR NEW FILE LIST ' ' SELECT FILE FROM LIST, PRESS SUBMIT TO PLACE PATH AND FILE NAME IN BUFFER. ' THE CONTENTS OF THE BUFFER CAN BE RETRIEVED AS SHOWN IN SUB BFF.VALU '################################################################
OPEN "BrsFF.dll" FOR DLL AS #BRS
CHECKBOX #DMO.CKBOPN, "OPEN BFF", BFF, BFF, 5, 5, 70, 15 CHECKBOX #DMO.CKVALU, "BFF VALU", BFF.VALU, BFF.VALU, 160, 5, 70, 15
OPEN "BROWSE" FOR WINDOW AS #DMO PRINT #DMO, "TRAPCLOSE BROWSE"
WAIT
'------------------------------------- '-------------------------------------
SUB BFF OpnHndl$
STRUCT tOut, _ PrntHndl AS ULONG, _ '<--- handle of callwindow or zero BrsHndl AS ULONG, _ '<--- RETURN: handle of browser RetPtr$ AS PTR, _ '<--- RETURN: path and file selected RetLen AS LONG, _ '<--- RETURN: length of RetPtr$ StrtPosX AS LONG, _ '<--- position to place window if PrntHndl <> 0 _ 'position to place window if PrntHndl > 0 StrtPosY AS LONG, _ Always AS LONG '<--- > 0 = keep file browser running 'after selection; 0 (zero) = close file 'browser after selection
FlPath$ = "" '<--- beginning path to start file list or 'Nul ("") to start at root drive
FlMask$ = "" '<--- list of file types in the form '*.bas, *.bak, *.inc | *.txt, *.rtf, *.pdf
WinHndl = HWND(#DMO) tOut.PrntHndl.struct = WinHndl tOut.StrtPosX.struct = 100 tOut.StrtPosY.struct = 100 tOut.Always.struct = 1
FlPath$ = DefaultDir$ FlMask$ = "*._bas, *.bas, *.inc | *.*"
CALLDLL #BRS, "Brs", tOut AS STRUCT, FlMask$ AS PTR, FlPath$ AS PTR, _ RetVal AS ULONG PRINT RetVal END SUB
'-------------------------------------- '--------------------------------------
'-------------------------------------- '--------------------------------------
SUB BFF.VALU BfHndl$
PRINT "BFF.VALUE" IF tOut.Always.struct THEN CALLDLL #BRS, "FN_BrsValue", ValPtr AS ULONG PRINT WINSTRING(ValPtr) EXIT SUB END IF
PRINT WINSTRING(tOut.RetPtr$.struct) END SUB
'-------------------------------------- '--------------------------------------
SUB BROWSE Dmo$ '<----------- required only if browser is in ALWAYS mode ----------> IF tOut.Always.struct THEN CALLDLL #BRS, "BrsClose", 0 AS VOID END IF
CLOSE #BRS CLOSE #Dmo$ END END SUB
FILE_BROWSER.ZIP (42.33 KB)
|
|
|
Post by BeeTrap on May 1, 2022 10:51:46 GMT -5
Both versions are a little buggie, but I do like the look. I use Liberty BASIC only as a hobby so any code is enjoyable to look at. I like and may imitate the way that you name your functions, subs, etc....... Thanks.
|
|
|
Post by Walt Decker on May 1, 2022 11:10:58 GMT -5
Both versions are a little buggie, but I do like the look. I use Liberty BASIC only as a hobby so any code is enjoyable to look at. I like and may imitate the way that you name your functions, subs, etc....... Thanks. Could you give me a little more info than "a little buggie"?
You are welcome to imitate anything you want. The important thing is finding something you are comfortable with and being consistent.
|
|
|
Post by BeeTrap on May 1, 2022 13:15:53 GMT -5
Sorry about that. If used your code and DLL as I believe you intended, then all is well. If one goes "click-crazy" and chooses the wrong "checkbox" first or some combination of wrong choices, or multiple "choices", I get messages such as program closing with a window titled "Please Note: #BRS #DMO These handles closed by Liberty BASIC . Please add the appropriate CLOSE commands." Or, "Warning Runtime Error: system primitive failed (see error.log for more information)". Another was "Warning Runtime Error: undefined struct:tOut (see error log for more information." I have had "lbpro.exe" stop working and was closed by Windows with a report to Microsoft a couple of times. But...... these problems only appeared when I really played around. If I behave, then your program and DLL do.
Later: found other screenshots that I had saved: One error box read "Smalltalk/V a non-continuable protection violation has occured. Check ERROR.LOG file". Another was "lbpro.exe lbpro.exe has stopped working Hang on while Windows reports the problem to Microsoft" which was mentioned earlier. I believe that both of these came from the original code, not the replacement.
As I stated earlier, this only happens when I "play" with the code/DLL!
|
|
|
Post by Walt Decker on May 1, 2022 22:42:48 GMT -5
Ah. The dll is not acting up, it is the LB code. I am not surprised. That was meant to only illustrate how to access the browser and get data from it. There are no safety checks.
Move the struct declaration to the top but leave the equates where they are. Right after SUB BFF OpnHndl$ add this:
IF tOut.BrsHndl.struct THEN EXIT SUB
Change SUB BFF.VALU to this:
SUB BFF.VALU BfHndl$ PRINT "BFF.VALUE" IF tOut.Always.struct THEN CALLDLL #BRS, "FN_BrsValue", ValPtr AS ULONG IF ValPtr = 0 THEN EXIT SUB PRINT WINSTRING(ValPtr) EXIT SUB END IF
IF tOut.RetPtr$.struct = 0 THEN EXIT SUB PRINT WINSTRING(tOut.RetPtr$.struct) END SUB
That should produce a viable base for inclusion into a meaningful application.
By the way, contrary to the name tOut.RetPtr$ has a numeric value, i. e. it is a pointer to a 32-bit memory address. Function WINSTRING() accesses that address and pulls its contents from memory up to the first null character. If a zero value is placed into WINSTRING() it will cause a GPF (system primitive failed?) and crash the application.
|
|
|
Post by BeeTrap on May 2, 2022 10:43:11 GMT -5
Thanks for your time and ability. This works well now. I have yet to break it .. I had not tried using this in any of my programs yet, just ran your sample. I hope you don't mind if I use the code and DLL in the future. Thank you, I've been needing something to inspire me!
|
|
|
Post by Walt Decker on May 2, 2022 13:20:13 GMT -5
Here is one that is a little more comprehensive. I had to make a small change to the dll in order to get it to work properly with a timer, so you may want to down load the dll once more. The zip also has the following code.
EDIT: Use it to your heart's content. That is why I modified the original to work with LB.
' 'BRPWSE_FF_A00._BAS '################################################################ ' REQUIRED: BrsFF.DLL ' FIRST WRITTEN: JAN, 2001 ' ADAPTED FOR LIBERTY BASIC APRIL, 2022 (NOT THOUROUGHLY TESTED) ' '================================================================ ' OPERATION: ' SELECT FILE TYPES FROM THE TYPES COMBOBOX FOR NEW FILE LIST ' ENTER NEW FILE TYPE IN EDIT CONTROL, CLICK OPEN FOR NEW FILE LIST ' ENTER NEW PATH IN EDIT CONTROL, CLICK OPEN FOR NEW FILE LIST ' ' SELECT FILE FROM LIST, PRESS SUBMIT TO PLACE PATH AND FILE NAME IN BUFFER. ' THE CONTENTS OF THE BUFFER CAN BE RETRIEVED AS SHOWN IN SUB BFF.VALU '################################################################
ES.MULTILINE = HEXDEC("&H0004") ES.AUTOVSCROLL = HEXDEC("&H0040") ES.AUTOHSCROLL = HEXDEC("&H0080") WS.VSCROLL = HEXDEC("&H00200000")
'################################################################## ' DOES NOT MATTER WHAT THE STRUCTURE AND ITS ELEMENTS ARE NAMED ' AS LONG AS THE ELEMENTS ARE OF THE SAME TYPE AND SAME ORDER '##################################################################
STRUCT tBff, _ PrntHndl AS ULONG, _ '<--- handle of callwindow or zero BrsHndl AS ULONG, _ '<--- RETURN: handle of browser PathPtr$ AS PTR, _ '<--- RETURN: path and file selected PathLen AS LONG, _ '<--- RETURN: length of PathPtr$ StrtPosX AS LONG, _ '<--- position to place window if PrntHndl = 0 _ 'position to place window if PrntHndl > 0 StrtPosY AS LONG, _ Always AS LONG '<--- > 0 = keep file browser running 'after selection; 0 (zero) = close file 'browser after selection
OPEN "BrsFF.dll" FOR DLL AS #BRS
GLOBAL Bff.Choice GLOBAL Rdo.Low
STYLEBITS #DMO.TXB, ES.AUTOHSCROLL OR ES.VSCROLL, ES.MULTILING OR _ ES.AUTOVSCROLL, 0, 0 TEXTBOX #DMO.TXB, 5, 5, 150, 250 MENU #DMO, "BFF", "LOAD BROWSER", [LOAD.BROWSER] OPEN "BROWSE" FOR WINDOW AS #DMO PRINT #DMO, "TRAPCLOSE BROWSE"
[START.TIMER] IF tBff.Always.struct THEN TIMER 200, [BROWSER.VALUE] WAIT END IF
[END.TIMER] WAIT
'------------------------------------- '-------------------------------------
[LOAD.BROWSER] RetVal = 0 FlPath$ = ""
RetVal = FN.GetChoice()
IF Bff.Choice = 3 THEN GOTO [END.TIMER]
FlPath$ = FN.Browser$(Bff.Choice) IF Bff.Choice = 1 THEN RetVal = FN.DisplayTxt(FlPath$) GOTO [END.TIMER] END IF
GOTO [START.TIMER] [LOAD.BROWSER.END]
'------------------------------------------------------- '-------------------------------------------------------
[BROWSER.VALUE] TIMER 0
FlPath$ = "" PtrVal = 0 RetVal = 0 CALLDLL #BRS, "FN_BrsValue", PtrVal AS ULONG
IF PtrVal < 1 THEN GOTO [START.TIMER]
FlPath$ = WINSTRING(PtrVal) IF FlPath$ = "" THEN GOTO [START.TIMER]
RetVal = FN.DisplayTxt(FlPath$) GOTO [START.TIMER]
[BROWSER.VALUE.END]
'------------------------------------------------------- '-------------------------------------------------------
FUNCTION FN.GetChoice()
Rdo.Low = 0 Bff.Choice = 0
CtlHndl = 0 CtlId = 0
IF tBff.Always.struct THEN CALLDLL #BRS, "BrsClose", 0 AS VOID tBff.Always.struct = 0 tBff.BrsHndl.struct = 0 Bff.Choice = 3 EXIT FUNCTION END IF
RADIOBUTTON #CHS.ONCE, "RUN ONCE", RUN.ONCE, RUN.ONCE, 5, 5, 75, 20 RADIOBUTTON #CHS.ALWYS, "RUN ALWAYS", RUN.ONCE, RUN.ONCE, 5, 30, 95, 20 RADIOBUTTON #CHS.CALCEL, "CANCEL", RUN.ONCE, RUN.ONCE, 5, 55, 75, 20
OPEN "SELECT CHOICE" FOR WINDOW AS #CHS CtlHndl = FN.GetHandle("#CHS.ONCE") CALLDLL #user32, "GetDlgCtrlID", CtlHndl AS ULONG, Rdo.Low AS LONG PRINT Rdo.Low PRINT #CHS, "TRAPCLOSE CLOSE.CHOICE"
[WIN.EVENTS] CALLDLL #kernel32, "Sleep", 1 AS LONG, RetVal AS VOID SCAN
IF Bff.Choice THEN GOTO [EXIT.WIN.EVENTS]
GOTO [WIN.EVENTS] [EXIT.WIN.EVENTS]
END FUNCTION
'------------------------------------------------------ '------------------------------------------------------
SUB RUN.ONCE RdoHndl$
IF Bff.Choice THEN EXIT SUB
Choice = 0 CtlHndl = 0 Value$ = ""
CtlHndl = FN.GetHandle(RdoHndl$)
CALLDLL #user32, "GetDlgCtrlID", CtlHndl AS ULONG, Choice AS LONG
PRINT #RdoHndl$, "Value? Value$"
IF Value$ = "set" THEN Bff.Choice = Choice - Rdo.Low + 1 Value$ = "#CHS" CALL CLOSE.CHOICE Value$ END IF
END SUB
'----------------------------------------------------- '-----------------------------------------------------
SUB CLOSE.CHOICE ChsHndl$ CLOSE #ChsHndl$ END SUB
'----------------------------------------------------- '-----------------------------------------------------
FUNCTION FN.Browser$(Choice)
RetVal = 0 Hndl = 0 WpX = 0 WpY = 0
FlPath$ = "" FlMask$ = ""
Hndl = HWND(#DMO) RetVal = FN.MapPoints(Hndl, 0, WpX, WpY, 0, 0)
FlPath$ = DefaultDir$ FlMask$ = "*._bas, *.bas, *.inc | *.*"
tBff.StrtPosX.struct = WpX tBff.StrtPosY.struct = WpY tBff.PathPtr$.struct = ""
SELECT CASE Choice CASE 1 tBff.Always.struct = 0 CALLDLL #BRS, "Brs", tBff AS STRUCT, FlMask$ AS PTR, FlPath$ AS PTR, _ RetVal AS ULONG FlPath$ = WINSTRING(tBff.PathPtr$.struct) FN.Browser$ = FlPath$
CASE 2 tBff.Always.struct = 1 CALLDLL #BRS, "Brs", tBff AS STRUCT, FlMask$ AS PTR, FlPath$ AS PTR, _ RetVal AS ULONG END SELECT END FUNCTION
'------------------------------------------------------ '------------------------------------------------------
FUNCTION FN.MapPoints(FromHndl, ToHndl, BYREF X, BYREF Y, BYREF X1, BYREF Y1)
STRUCT tRect, _ X AS LONG, _ Y AS LONG, _ X1 AS LONG, _ Y1 AS LONG
RetVal = 0
tRect.X.struct = X tRect.Y.struct = Y tRect.X1.struct = X1 tRect.Y1.struct = Y1
CALLDLL #user32, "MapWindowPoints", FromHndl AS ULONG, ToHndl AS ULONG, _ tRect AS STRUCT, 2 AS LONG, RetVal AS VOID
X = tRect.X.struct Y = tRect.Y.struct X1 = tRect.X1.strcut Y1 = tRect.Y1.struct
END FUNCTION
'-------------------------------------- '--------------------------------------
SUB BROWSE Dmo$ '<----------- required only if browser is in ALWAYS = 1 mode ----------> IF tBff.Always.struct THEN CALLDLL #BRS, "BrsClose", 0 AS VOID END IF
CLOSE #BRS CLOSE #Dmo$ END END SUB
'------------------------------------------ '------------------------------------------
FUNCTION FN.GetHandle(Tag$)
WinHndl = 0 Tag$ = FN.CheckTag$(Tag$)
WinHndl = HWND(#Tag$) FN.GetHandle = WinHndl END FUNCTION
'------------------------------------------ '------------------------------------------
FUNCTION FN.CheckTag$(Tag$)
IF LEFT$(Tag$, 1) <> "#" THEN Tag$ = "#" + Tag$
FN.CheckTag$ = Tag$ END FUNCTION
'------------------------------------------ '------------------------------------------
FUNCTION FN.DisplayTxt(FilePath$)
'load file and display it in edit control or do whatever
PRINT FilePath$ END FUNCTION
'
|
|