=====Using OPENIN (etc.) with wildcards===== //by Richard Russell, June 2010//\\ \\ The BBC BASIC [[http://www.bbcbasic.co.uk/bbcwin/manual/bbcwin6.html#openin|OPENIN]], [[http://www.bbcbasic.co.uk/bbcwin/manual/bbcwin6.html#openout|OPENOUT]] and [[http://www.bbcbasic.co.uk/bbcwin/manual/bbcwin6.html#openup|OPENUP]] functions generally take an **unambiguous** filename as their parameter. In //BBC BASIC for Windows// you can instead supply an **ambiguous** filename, that is a filename containing one or more **wildcard** characters: **?** (standing for a single character) or * (standing for any number of characters).\\ \\ In that case, since the supplied parameter doesn't specify a unique file, a **file selector** (Open File dialogue) is displayed, allowing the user to select a file. The files listed are filtered according to the supplied parameter, so in the case of the following code:\\ file% = OPENIN("*.ABC") only files with the extension **ABC** are (initially) displayed for the user to select from.\\ \\ If the user chooses to cancel the operation (by clicking the **Cancel** button in the dialogue box) an **Escape** error is triggered. This happens even if the Escape key has been disabled using ***ESC OFF** (see [[http://www.bbcbasic.co.uk/bbcwin/manual/bbcwini.html#hint1|here]] for a workaround).\\ \\ When a file has been selected by the user the OPENIN (or OPENOUT, OPENUP) function returns a channel number in the usual way, or zero if the file cannot be opened. There is no official way (in **Windows XP** and earlier) for the user's program to discover which file the user selected, but the following code can be used to do so:\\ file% = OPENIN("*.*") filename$ = $$!420 Assuming **file%** is non-zero, the path and filename of the selected file is placed in the variable **filename$**.\\ \\ //addition by Michael Hutton, edited by Richard Russell, June 2012//\\ The easiest way of discovering the filename is the above method, but it can also be achieved using the code below, which does not require accessing the interpreter's internal variables. However the API function used is available only on **Windows Vista** or later, therefore its use will result in your program being incompatible with Windows XP, which is still used in very large numbers:\\ \\ file% = OPENIN(file$) REM Get the file name if was chosen in dialog IF file$="" OR INSTR(file$,"*") OR INSTR(file$,"?") THEN file$ = FN_GetFileNameFromChannel(file%) PRINT file$ END DEF FN_GetFileNameFromChannel(file%) MAX_PATH = 260 LOCAL path%, R% DIM path% LOCAL MAX_PATH+1 : REM +1 Ensures null termination SYS "GetFinalPathNameByHandle", @hfile%(file%), path%, MAX_PATH, 0 TO R% IF R%=0 THEN ERROR 100, "Error : GetFinalPathNameByHandle" = $$(path%+4) : REM excludes the leading //?/