Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion. Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules. Domains: forum.doom9.org / forum.doom9.net / forum.doom9.se |
|
|
#21 | Link | ||
|
Avisynth language lover
Join Date: Dec 2007
Location: Spain
Posts: 3,442
|
Quote:
child->GetFrame() is not called via Invoke() - it is called directly by filters. Quote:
|
||
|
|
|
|
|
#22 | Link |
|
Registered User
Join Date: Apr 2013
Location: Vienna, Austria
Posts: 55
|
Thanks Gavino!
That was the breakthough. Avisynthplugininit is used multiple times to look up exported functions of loaded plugins, it may be a bad idea to do something else on the env than exporting functions... The function that actually opens the avs file and kicks off parsing and first executions is this: Code:
//script.cpp
AVSValue Import(AVSValue args, void*, IScriptEnvironment* env) {...
AVSValue eval_args[] = { (char*)buf, script_name };
result = env->Invoke("Eval", AVSValue(eval_args, 2));
..
}
Code:
//avisynth.cpp
//called by Import function above, seems to parse line by line and execute functions in given order (script order)
AVSValue ScriptEnvironment::Invoke(const char* name, const AVSValue args, const char** arg_names) {
|
|
|
|
|
|
#23 | Link | |
|
Avisynth language lover
Join Date: Dec 2007
Location: Spain
Posts: 3,442
|
Quote:
Essentially, it is 'interpreting' the script, evaluating expressions, calling functions and, where appropriate, assigning results to variables. The 'compilation' that takes place refers to the building of the filter graph which is the result of the script (a value of type PClip). This is in contrast to 'runtime', ie the subsequent frame serving phase where frames are requested from the graph by calling its GetFrame() function. EDIT: You might find this useful: http://avisynth.nl/index.php/The_script_execution_model Last edited by Gavino; 26th June 2013 at 01:07. |
|
|
|
|
|
|
#24 | Link |
|
Avisynth Developer
Join Date: Jan 2003
Location: Melbourne, Australia
Posts: 3,167
|
AvisynthPluginInit2/3 is the entry point called when Avisynth loads an external plugin .dll.
It is called on the first occurrence of a LoadPlugin() call of that .dll. If the dll is already known it is not called a second time. For plugins that are auto loaded from the plugin folder at IScriptEnvironment creation time, it is called once as the plugin is prescanned and can be called a second time if the .dll has been released and when a defined function is referenced in the script. Referencing a function from a released auto load plugin causes it to be reloaded. You can actually call any IScriptEnvironment function in your AvisynthPluginInit2/3 routine, but because auto load plugins might be released it is normally accepted that only AddFunction calls should be made. i.e. you should not do anything that latter needs something from the address space of the plugin .dll as it may well not be present at all or at a different memory location. Such activity should be performed in the Apply function registered by the AddFunction call. Whenever the Apply function is called the optional registered user_data value is supplied as the second argument. The user_data is of type void* and may be any constant or pointer value that you wish. E.g you may register varying function names with the same Apply function and each with a different user_data value to tell them apart. Or you could provide the address of a structure that all instances of a function can have access to. |
|
|
|
|
|
#25 | Link |
|
Registered User
Join Date: Jun 2009
Location: UK
Posts: 269
|
Can I just say how delighted I am that my suggestion has triggered all this activity?
I haven't had a chance to try out jordanh's prototype yet, but I've seen a comment in the discussion requesting CTRL-V (paste) to work. I assume jordonh was just doing proof-of-concept of the integration-with-avisynth part of the problem, rather than worrying about details of how the file selector itself would look and function...? But just to be clear on what I had in mind for that, I'd like something that opens up the standard Windows "Explorer"-type file selector, as seen in many, many existing applications (VirtualDub, for example). That supports CTRL-V for inserting pathnames and filenames into the relevant fields, as well as drag-and-drop, the ability to create new folders and do a bit of filesystem tidying before you open your file, and so on... not to mention integrating well with all sorts of third-party add-ons such as Listary (See http://www.listary.com/ ), which provides a really useful set of tools to stop me getting lost in the vast and twisty labyrinth of my ever-growing filesystem... ). I've seen various freeware tools that re-invent the wheel on file selection, with various degees of success, but none of them provide the power - not to mention the consistency of user experience - that you get by just using the standard tool. Of course, the possible downsides of that are that (a) it's inherently Windows-specific (but presumably the folks working on the Linux port of avisynth, VapourSynth, etc. could produce a version that calls whatever the standard/most popular file selection UI is on the platform in question...?), and (b) there may be some licensing implications (?). Anyway, thanks for your efforts. I look forward to seeing how this turns out. ![]() (You might even shame me into getting my own hands dirty with a compiler again... It's been a couple of years at least since my last attempt died, along with the laptop hard drive upon which I'd just spent two weeks setting up my development environment... )
Last edited by pbristow; 27th June 2013 at 06:57. |
|
|
|
|
|
#26 | Link |
|
Registered User
Join Date: Jun 2009
Location: UK
Posts: 269
|
Oh, on the "compilation" wording debate: I would call it "instantiation", i.e. the phase during which an instance of the Avisynth working environment is being created. (N.B. sometimes more than one such instance is created by a script, e.g. if it uses MP_Pipeline.)
|
|
|
|
|
|
#27 | Link | |
|
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 11,406
|
Quote:
I have no real concerns on your submission, perhaps I was a little too wordy (said too much). I have not as yet tried the plugin, dont need it just yet, and busy doing something else at the moment, but I will and thank you very much for taking the time to make your submission, it is much appreciated.
__________________
I sometimes post sober. StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace "Some infinities are bigger than other infinities", but how many of them are infinitely bigger ??? |
|
|
|
|
|
|
#28 | Link |
|
Registered User
Join Date: Jun 2009
Location: UK
Posts: 269
|
Just tried out jordanh's prototype: Yes! That's exactly what I wanted it to do. Thankyou!
Although I do think assigning the name to a variable is better than fixed variable names. One of my intended uses is for a script that analyses the difference between two or more clips, where these have been created by different versions of an AVS script I'm developing. The idea is to be able to run the comparaison script in one instance of VirtualDub (or directly in Daum PotPlayer), and then select the files to be compared. This will be repeated multiple times, as I generate more test clips with new versions of the main script, home in on which version of processing is working best. Obviously for that, I need separate variable names, but for now I can work around that using "Testfile1 = SELECTEDFILE" etc. before calling the pop-up again. Oh, and seeing "Save as" in the title bar for an *input* file selector made me panic for a moment.
|
|
|
|
|
|
#29 | Link |
|
Registered User
Join Date: Apr 2013
Location: Vienna, Austria
Posts: 55
|
Hehe... finally someone tried it :-)
Thank YOU (pbristow) for this nice project idea! Mostly the simple ideas are the best. Maybe you really find the esteam to pull out development tools again and finish the plugin on your own ;-) ...setting a few parameters for filechooser and returning the value from the function should do it. @Stainlesss: As i now understand know how things work in detail, i would have had more understanding for what you wrote too - and be able to interpret your messages right. Basically it was only the wording "compile" in general and especially "compile time plugin" (still don't understand what you mean with that) that made me so much working on this thread. From my understanding, avisynth is a mix of different stuff, especially the directshow/vfw interface, but the avisynth script language is something i'd prefer to call officially an "interpreted script language". Last edited by jordanh; 28th June 2013 at 00:03. |
|
|
|
|
|
#30 | Link |
|
Excessively jovial fellow
Join Date: Jun 2004
Location: rude
Posts: 1,100
|
Avisynth script is neither interpreted nor a scripting language in the traditional senses of those words; if you want to be technical about it, it's more of a graph description language than anything else. The term "Avisynth" generally refers to the entire package of a video filtering library, its public API, the third-party libraries written using that API ("plugins"), the scripting engine that builds filter chains using the video filtering library and the VFW output driver that lets ordinary VFW applications retrieve frames from the filtering library without having to interface with its API.
Last edited by TheFluff; 28th June 2013 at 01:09. |
|
|
|
|
|
#31 | Link | ||
|
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 11,406
|
I finally got around to trying this out (thank you jordanh), had to install vs2010 runtimes (thought I had already installed it),
but am getting an Quote:
In Dependency walker (EDIT: for AVS_FilenameSelector.dll), shows message:- Quote:
Anybody got an idea on what that means ? EDIT: Seems unresolved import due to WNetRestoreConnectionA which is probably not the cause of the access violation.
__________________
I sometimes post sober. StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace "Some infinities are bigger than other infinities", but how many of them are infinitely bigger ??? Last edited by StainlessS; 20th July 2013 at 23:25. Reason: clarify |
||
|
|
|
|
|
#32 | Link |
|
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 11,406
|
Previous post access violation probably down to the function used, available only Vista+, so a no-no on XP.
Here an XP+ WINAPI solution, not terribly well tested, but something for you to play with. FSel.dll, FselOpen function. Code:
/*
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
// Compile for minimum supported system. MUST be defined before includes.
// NEED to use SDK for updated headers, OR TK3 will give error messages/Warnings about Beta versions.
#define WINVER 0x0501 // XP
#define _WIN32_WINNT 0x0501 // XP
#define NTDDI_VERSION 0x05010300 // XP SP3
#define _WIN32_IE 0x0603 // 0x0603=IE 6 SP2, 0x0700=1e7, 0x0800=1e8
//
//
#include <windows.h>
#include <stdio.h>
#include <commdlg.h> // OS Specific WINVER (Mainly)
#include <Shlobj.h> // IE Specific _WIN32_IE
//
#include "avisynth.h"
//
/*
typedef struct tagOFN {
DWORD lStructSize;
HWND hwndOwner; // NULL no owner
HINSTANCE hInstance;
LPCTSTR lpstrFilter; // the filter
LPTSTR lpstrCustomFilter;
DWORD nMaxCustFilter;
DWORD nFilterIndex; // we default ALWAYS 1 (ie first one)
LPTSTR lpstrFile; // initial filename, also for return filename
DWORD nMaxFile; // size of filename buffer
LPTSTR lpstrFileTitle;
DWORD nMaxFileTitle;
LPCTSTR lpstrInitialDir; // the initial directory or current if null
LPCTSTR lpstrTitle; // Title Bar text, eg 'Open file'
DWORD Flags;
WORD nFileOffset;
WORD nFileExtension;
LPCTSTR lpstrDefExt;
LPARAM lCustData;
LPOFNHOOKPROC lpfnHook;
LPCTSTR lpTemplateName;
#if (_WIN32_WINNT >= 0x0500)
void * pvReserved;
DWORD dwReserved;
DWORD FlagsEx;
#endif // (_WIN32_WINNT >= 0x0500)
} OPENFILENAME, *LPOPENFILENAME;
*/
int dprintf(char* fmt, ...) {
char printString[2048];
char *p=printString;
va_list argp;
va_start(argp, fmt);
vsprintf(p, fmt, argp);
va_end(argp);
for(;*p++;);
--p; // @ null term
if(printString == p || p[-1] != '\n') {
p[0]='\n'; // append n/l if not there already
p[1]='\0';
OutputDebugString(printString);
} else {
OutputDebugString(printString);
}
return p-printString; // strlen printString
}
AVSValue __cdecl FSelOpen(AVSValue args, void* user_data, IScriptEnvironment* env) {
char * myName="FSelOpen: ";
const char * myFilter=
"All files (*.*)|*.*|"
"Avi Files (*.avi;*.XVid;*.DivX)|*.avi;*.XVid;*.DivX|"
"Mpg files (*.vob;*.mpg;*.mpeg;*.m1v;*.m2v;*.mpv;*.tp;*.ts;*.trp;*.m2t;*.m2ts;*.pva;*.vro)|*.vob;*.mpg;*.mpeg;*.m1v;"
"*.m2v;*.mpv;*.tp;*.ts;*.trp;*.m2t;*.m2ts;*.pva;*.vro|"
"Other Vid (*.mkv;*.Wmv;*.mp4;*.flv;*.ram;*.rm)|*.mkv;*.Wmv;*.mp4;*.flv;*.ram;*.rm|"
"Audio Files (*.mp3;*.mpa;*mp1;*.mp2;*.wav)|*.mp3;*.mpa;*mp1;*.mp2;*.wav|"
"Avs files (*.avs;*.avsi)|*.avs;*.avsi|"
"Text files (*.txt;*.log;*.asc)|*.txt;*.log;*.asc|"
"Image files (*.bmp;*.jpg;*.jpe;*.jpeg;*.png;*.tga;*.tif;*.gif;*.tiff)|*.bmp;*.jpg;*.jpe;*.jpeg;*.png;*.tga;*.tif;*.gif;*.tiff|"
"Bat files (*.bat)|*.bat|";
"Exe files (*.exe)|*.cmd";
const char * title =args[0].AsString(NULL);
const char * dir =args[1].AsString(NULL); // Default current dir
const char * filt =args[2].AsString(myFilter);
const char * fn =args[3].AsString("");
const bool multi =args[4].AsBool(false);
if(strlen(filt)>4096-3) env->ThrowError("%sFilter too long",myName);
char filt2[4096];
const char *p=filt;
int ix=0;
while(*p) { // convert from PIPE '|' separated to nul separated filter strings
if(*p=='|') {
filt2[ix++]='\0';
++p;
} else {
filt2[ix++]=*p++;
}
}
filt2[ix++]='\0'; filt2[ix]='\0'; // Double nul term
int size = (multi) ? 65536 : (MAX_PATH * 2);
int len=strlen(fn) + 1;
if(len>size) size=len;
char *szFile = new char [size]; // buffer for file name
if(szFile==NULL) env->ThrowError("%sCannot allocate memory",myName);
strcpy(szFile,fn); // set initial filename
int flgs= \
OFN_PATHMUSTEXIST |
OFN_FILEMUSTEXIST |
OFN_HIDEREADONLY | // hide readonly check box
OFN_LONGNAMES |
OFN_NOCHANGEDIR; // restore original current directory if user changed. Does NOT work for GetOpenFileName.
if(multi) flgs |=(OFN_ALLOWMULTISELECT|OFN_EXPLORER) ;
OPENFILENAME ofn; // common dialog box structure
ZeroMemory(&ofn, sizeof(ofn)); // Initialize OPENFILENAME
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = NULL; // owner window, we dont have one
ofn.lpstrFile = szFile; // filename buff
ofn.nMaxFile = size; // size of filename buff
ofn.lpstrFilter = filt2; // Converted filt string
ofn.nFilterIndex = 1;
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = dir;
ofn.lpstrTitle=title; // Title shown in Title Bar
ofn.Flags = flgs;
// Display the Open dialog box.
if (GetOpenFileName(&ofn)!=TRUE) {
delete [] szFile;
DWORD ret = CommDlgExtendedError();
if(ret==0) {
dprintf("%sUser CANCELLED",myName);
return 0;
}
switch(ret) {
case FNERR_BUFFERTOOSMALL: dprintf("%sFilename buffer Too Small",myName); break;
case FNERR_INVALIDFILENAME: dprintf("%sInvalid filename",myName); break;
case FNERR_SUBCLASSFAILURE: dprintf("%sSubClass failure (low memory)",myName); break;
case CDERR_DIALOGFAILURE: dprintf("%sDialog box creation failure",myName); break;
case CDERR_FINDRESFAILURE: dprintf("%sFind resource failure",myName); break;
case CDERR_INITIALIZATION: dprintf("%sDialog box initialization failure (usually memory)",myName); break;
case CDERR_LOADRESFAILURE: dprintf("%sLoad resource failure",myName); break;
case CDERR_LOADSTRFAILURE: dprintf("%sLoad string failure",myName); break;
case CDERR_LOCKRESFAILURE: dprintf("%sLock resource failure",myName); break;
case CDERR_MEMALLOCFAILURE: dprintf("%sUnable to allocate memory structures",myName); break;
case CDERR_MEMLOCKFAILURE: dprintf("%sUnable to lock memory associated with handle",myName); break;
case CDERR_NOHINSTANCE: dprintf("%sNo instance handle",myName); break;
case CDERR_NOHOOK: dprintf("%sNo hook",myName); break;
case CDERR_NOTEMPLATE: dprintf("%sNo template",myName); break;
case CDERR_REGISTERMSGFAIL: dprintf("%sRegisterWindowMessage returned an error",myName); break;
case CDERR_STRUCTSIZE: dprintf("%sInvalid lStructSize member",myName); break;
default: dprintf("%sUnknown error",myName); break;
}
return (int)ret;
}
int off=ofn.nFileOffset;
if(!multi || (off>0 && szFile[off-1]=='\\')) { // single filename selected
// dprintf("%s OK Single file = %s",myName,szFile);
AVSValue retstr = env->SaveString(szFile);
delete [] szFile;
return retstr;
}
p=szFile;
int nstr=0;
while(*p) { // Count gotten strings, 1st is dir, then filenames. Ends in double nul.
while(*p) {
++p;
}
++p;
++nstr;
}
int dirlen=off; // including nul (will convert to '\\').
int fullen = (p - szFile - off) + ((nstr - 1) * dirlen) + 1; // +1 for final nul term.
char *mfiles = new char [fullen]; // buffer for multiple expanded file names, '\n' separated
if(mfiles==NULL) {
delete [] szFile;
env->ThrowError("%sCannot allocate multiselect files buffer",myName);
}
char *d=mfiles; // Dest multiselect files buffer
char *s=&szFile[off]; // point at 1st filename node
for(int i=nstr-1;--i>=0;) { // Convert to filenames with full path
char *r=szFile; // point at path
while(*r)
*d++=*r++; // Copy path
*d++='\\'; // backslash separator
while(*s)
*d++=*s++; // append filename
++s; // skip nul
*d++='\n'; // '\n' multiline separator
}
*d='\0'; // nul term
delete [] szFile;
// dprintf("%sOK = %s",myName,mfiles);
AVSValue retstr = env->SaveString(mfiles);
delete [] mfiles;
return retstr;
}
Code:
########
# FSelOpen() by StainlessS
#
# Function FSelOpen(string "title"="Open",string "dir"="",string "filt",string "fn="",bool "multi"=false)
#
# Function to select EXISTING filename. Would need something similar to select SAVE filename, or Folder Select.
#
# Title = Title bar text.
# Dir = Directory, "" = Current
# Filt = Lots, most of below with a few more mpeg. [Displayed text | wildcard] [| more pairs of Displayed text and wildcard, in pairs ONLY].
# first one is default.
# fn = Initially presented filename (if any).
# multi = Multiply Select filenames. Allows selection of more than one filename. RT_Stats v1.20 Required for MULTI=true
#
# Returns
# int, 0, user CANCELLED.
# int, non zero is error (error sent to DebugView window).
# String, Filename selected, Chr(10) separated multiline string if MULTI==true (and multiple files selected).
#
########
TITLE ="Open a File, if you really really want to"
DIR =""
FILT = "All files (*.*)|*.*|"
\ + "Image files (*.bmp;*.jpg;*.jpe;*.jpeg;*.png;*.tga;*.tif;*.gif;*.tiff)|*.bmp;*.jpg;*.jpe;*.jpeg;*.png;*.tga;*.tif;*.gif;*.tiff|"
\ + "Mpg files (*.vob;*.mpg;*.mpeg etc)|*.vob;*.mpg;*.mpeg;*.m1v;*.m2v;*.mpv;*.tp;*.ts;*.trp;*.m2t;*.m2ts;*.pva;*.vro|"
\ + "Avi Files (*.avi)|*.avi|"
\ + "Avs files (*.avs;*.avsi)|*.avs;*.avsi|"
\ + "Text files (*.txt)|*.txt"
FN ="AnyAnyAnyOldIron.txt"
MULTI = false # True requires RT_Stats
result = FSelOpen(title=TITLE,dir=DIR,Filt=FILT,fn=FN,multi=MULTI)
Assert(result.IsString,"FSelOpen: Error="+String(Result))
colorbars
Lines = (!MULTI) ? 1 : RT_TxtQueryLines(result) # Inquire how many filenames we got,
# Can use eg RT_TxtGetLine(result,Line) Where Line valid from 0 to Lines - 1.
(MULTI) ? RT_Debug(Result) : NOP # to DebugViewWindow
result= (MULTI) ? RT_StrReplace(Result,Chr(10),"\n") : result # Convert For SubTitle
result="We got " + String(Lines) + " Filenames\n\n" + result
return Subtitle(result,lsp=0)
Update to v1.01 TAKE 2, Removed FSelOpen() script RT_Stats requirement unless MULTI = true. Here: Link removed, see post #37. EDIT: see also post #37 and #38 for additional parts
__________________
I sometimes post sober. StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace "Some infinities are bigger than other infinities", but how many of them are infinitely bigger ??? Last edited by StainlessS; 15th December 2018 at 14:43. |
|
|
|
|
|
#33 | Link |
|
Registered User
Join Date: Jun 2009
Location: UK
Posts: 269
|
Ooh, this looks powerful! Thanks StainlessS.
[GIVES IT A TRY] Bwahaha! I love the default filenames. ![]() Alas, the test script fails as I don't have the RT_ functions, but tweaking it to just use "AVISource(result)" works fine for single files. I like the idea of being able to pre-set the filetypes/extensions available (so that you don't mistakenly try to open a non-video file, or open that fuzzy old .mpg with a script that's designed to work with nice clean HiRes .mkv files. ) Thanks again. |
|
|
|
|
|
#34 | Link | |
|
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 11,406
|
@pbristow, hope you saw the EDIT:
Quote:
Also, a number of tools to read in eg text files, count multiline strings (whether or not last line is n/l terminated, sort a multiline pseudo array of int/float strings, write a results text/log file and more. My current favorite is RT_Subtitle, is FAST, if you do decide to treat yourself, try the scrolling end credits type snippet, its quite impressive for a few lines of script (about 5 or 6). ![]() EDIT: If I do any further work on this, it will of course be going into RT_Stats plugin, I'm unlikely to do anything further with FSel.dll, if anyone wants to expand and keep as a separate, they are welcome.
__________________
I sometimes post sober. StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace "Some infinities are bigger than other infinities", but how many of them are infinitely bigger ??? Last edited by StainlessS; 26th July 2013 at 01:14. |
|
|
|
|
|
|
#36 | Link |
|
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 11,406
|
Update to FSel.dll, v1.01.
Added FselSaveAs() and FSelFolder(). FSelSaveAs script Code:
########
# FSelSaveAs() by StainlessS
#
# Function FSelSaveAs(string "title"="Open",string "dir"="",string "filt",string "fn="")
#
# Function to select filename for Save.
#
# Title = Title bar text.
# Dir = Directory, "" = Current
# Filt = Lots, most of below with a few more mpeg. [Displayed text | wildcard] [| more pairs of Displayed text and wildcard, in pairs ONLY].
# first one is default.
# fn = Initially presented filename (if any).
#
# Returns
# int, 0, user CANCELLED.
# int, non zero is error (error sent to DebugView window).
# String, Filename selected.
########
TITLE ="Save a File, if you think you know what you are doing"
DIR =""
FILT = "All files (*.*)|*.*|"
\ + "Image files (*.bmp;*.jpg;*.jpe;*.jpeg;*.png;*.tga;*.tif;*.gif;*.tiff)|*.bmp;*.jpg;*.jpe;*.jpeg;*.png;*.tga;*.tif;*.gif;*.tiff|"
\ + "Mpg files (*.vob;*.mpg;*.mpeg etc)|*.vob;*.mpg;*.mpeg;*.m1v;*.m2v;*.mpv;*.tp;*.ts;*.trp;*.m2t;*.m2ts;*.pva;*.vro|"
\ + "Avi Files (*.avi)|*.avi|"
\ + "Avs files (*.avs;*.avsi)|*.avs;*.avsi|"
\ + "Text files (*.txt)|*.txt"
FN ="AnyAnyAnyOldIron.txt"
result = FSelSaveAs(title=TITLE,dir=DIR,Filt=FILT,fn=FN)
Assert(result.IsString,"FSelSaveAs: Error="+String(Result))
return colorbars.Subtitle(Result)
Code:
######## # FSelFolder() by StainlessS # # Function FSelFolder(string "title"="",string "dir"=".") # # Function to select Folder. # # Title = UNDERNEATH the title bar text, for instructions. # Dir = Directory, Default "." = Current, ""=Root. # # Returns # int, 0, user CANCELLED. # int, non zero is error (ie -1, error sent to DebugView window, usually selecting non Folder object eg 'My Computer'). # String, Folder selected (minus trailing BackSlash). ######## TITLE ="USE THIS TO SELECT A FOLDER" DIR="." # Current Dir (Default) #DIR="" # Root, My Computer #DIR="D:\avs\" # Something Else result = FSelFolder(title=TITLE,dir=DIR) Assert(result.IsString,"FSelFolder: Error="+String(Result)) return colorbars.Subtitle(result) EDIT: For those that like to watch a movie and read scrolling text at the same time. Requires RT_Stats v1.20. Code:
avi = FSelOpen("Select an AVI",Filt="*.AVI|*.AVI")
Assert(avi.IsString,"FSelOpen: Error="+String(avi))
AVISource(AVI)
txt = FSelOpen("Select a Text file",Filt="*.txt|*.txt")
Assert(txt.IsString,"FSelOpen: Error="+String(txt))
Txt=RT_ReadTxtFromFile(txt)
Return ScriptClip("""RT_Subtitle("%s",Txt,align=2,y=height+100-current_frame,expy=true)""") # Requires RT_Stats v1.20
EDIT: FSelOpen, will only allow selecting existing files. FSelSaveAs, prompts for Overwrite if existing selected. Update to v1.01 TAKE 2, Removed FSelOpen() script RT_Stats requirement unless MULTI = true. Here: Link removed, see post #37.
__________________
I sometimes post sober. StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace "Some infinities are bigger than other infinities", but how many of them are infinitely bigger ??? Last edited by StainlessS; 27th July 2013 at 19:03. |
|
|
|
|
|
#37 | Link |
|
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 11,406
|
Update to FSelOpen, FSelSaveas and FSelFolder functs, FSel.dll v1.02
Fixed bug in filter scanning, update FSelFolder to resizable dialog box with Makefolder button. Here: http://www.mediafire.com/download/82...28TAKE3%29.zip Very last Fsel.dll version, have added to RT_stats. EDIT: May not be online longer than a month or so.
__________________
I sometimes post sober. StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace "Some infinities are bigger than other infinities", but how many of them are infinitely bigger ??? Last edited by StainlessS; 27th July 2013 at 19:25. |
|
|
|
|
|
#38 | Link |
|
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 11,406
|
Post update, added the FSelSaveAs() and FSelFolder() source (with filter parse bug fixed) , see also posts #32 and #37 for other parts of source.
Link to zip in previous post. Code:
AVSValue __cdecl FSelSaveAs(AVSValue args, void* user_data, IScriptEnvironment* env) {
char * myName="FSelSaveAs: ";
const char * myFilter=
"All files (*.*)|*.*|"
"Avi Files (*.avi;*.XVid;*.DivX)|*.avi;*.XVid;*.DivX|"
"Mpg files (*.vob;*.mpg;*.mpeg;*.m1v;*.m2v;*.mpv;*.tp;*.ts;*.trp;*.m2t;*.m2ts;*.pva;*.vro)|*.vob;*.mpg;*.mpeg;*.m1v;"
"*.m2v;*.mpv;*.tp;*.ts;*.trp;*.m2t;*.m2ts;*.pva;*.vro|"
"Other Vid (*.mkv;*.Wmv;*.mp4;*.flv;*.ram;*.rm)|*.mkv;*.Wmv;*.mp4;*.flv;*.ram;*.rm|"
"Audio Files (*.mp3;*.mpa;*mp1;*.mp2;*.wav)|*.mp3;*.mpa;*mp1;*.mp2;*.wav|"
"Avs files (*.avs;*.avsi)|*.avs;*.avsi|"
"Text files (*.txt;*.log;*.asc)|*.txt;*.log;*.asc|"
"Image files (*.bmp;*.jpg;*.jpe;*.jpeg;*.png;*.tga;*.tif;*.gif;*.tiff)|*.bmp;*.jpg;*.jpe;*.jpeg;*.png;*.tga;*.tif;*.gif;*.tiff|"
"Bat files (*.bat)|*.bat";
const char * title =args[0].AsString(NULL);
const char * dir =args[1].AsString(NULL); // Default current dir
const char * filt =args[2].AsString(myFilter);
const char * fn =args[3].AsString("");
if(strlen(filt)>4096-3) env->ThrowError("%sFilter too long",myName);
char filt2[4096];
const char *p=filt;
int ix=0;
while(*p) { // convert from PIPE '|' separated to nul separated filter strings
if(*p=='|') {
filt2[ix++]='\0';
++p;
} else {
filt2[ix++]=*p++;
}
}
filt2[ix++]='\0'; filt2[ix]='\0'; // Double nul term
int size = MAX_PATH * 2;
int len=strlen(fn) + 1;
if(len>size) size=len;
char *szFile = new char [size]; // buffer for file name
if(szFile==NULL) env->ThrowError("%sCannot allocate memory",myName);
strcpy(szFile,fn); // set initial filename
int flgs= \
OFN_OVERWRITEPROMPT |
OFN_LONGNAMES |
OFN_NOCHANGEDIR; // restore original current directory if user changed. Does NOT work for GetOpenFileName.
OPENFILENAME ofn; // common dialog box structure
ZeroMemory(&ofn, sizeof(ofn)); // Initialize OPENFILENAME
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = NULL; // owner window, we dont have one
ofn.lpstrFile = szFile; // filename buff
ofn.nMaxFile = size; // size of filename buff
ofn.lpstrFilter = filt2; // Converted filt string
ofn.nFilterIndex = 1;
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = dir;
ofn.lpstrTitle=title; // Title shown in Title Bar
ofn.Flags = flgs;
// Display the Open dialog box.
if (GetSaveFileName(&ofn)!=TRUE) {
delete [] szFile;
DWORD ret = CommDlgExtendedError();
if(ret==0) {
dprintf("%sUser CANCELLED",myName);
return 0;
}
switch(ret) {
case FNERR_BUFFERTOOSMALL: dprintf("%sFilename buffer Too Small",myName); break;
case FNERR_INVALIDFILENAME: dprintf("%sInvalid filename",myName); break;
case FNERR_SUBCLASSFAILURE: dprintf("%sSubClass failure (low memory)",myName); break;
case CDERR_DIALOGFAILURE: dprintf("%sDialog box creation failure",myName); break;
case CDERR_FINDRESFAILURE: dprintf("%sFind resource failure",myName); break;
case CDERR_INITIALIZATION: dprintf("%sDialog box initialization failure (usually memory)",myName); break;
case CDERR_LOADRESFAILURE: dprintf("%sLoad resource failure",myName); break;
case CDERR_LOADSTRFAILURE: dprintf("%sLoad string failure",myName); break;
case CDERR_LOCKRESFAILURE: dprintf("%sLock resource failure",myName); break;
case CDERR_MEMALLOCFAILURE: dprintf("%sUnable to allocate memory structures",myName); break;
case CDERR_MEMLOCKFAILURE: dprintf("%sUnable to lock memory associated with handle",myName); break;
case CDERR_NOHINSTANCE: dprintf("%sNo instance handle",myName); break;
case CDERR_NOHOOK: dprintf("%sNo hook",myName); break;
case CDERR_NOTEMPLATE: dprintf("%sNo template",myName); break;
case CDERR_REGISTERMSGFAIL: dprintf("%sRegisterWindowMessage returned an error",myName); break;
case CDERR_STRUCTSIZE: dprintf("%sInvalid lStructSize member",myName); break;
default: dprintf("%sUnknown error",myName); break;
}
return (int)ret;
}
// dprintf("%s OK Single file = %s",myName,szFile);
AVSValue retstr = env->SaveString(szFile);
delete [] szFile;
return retstr;
}
/*
typedef struct _browseinfo {
HWND hwndOwner; // A handle to the owner window for the dialog box.
PCIDLIST_ABSOLUTE pidlRoot; // Root folder to browse from PIDL (NULL = DeskTop)
LPTSTR pszDisplayName; // returned name, Presumed MAX_PATH characters
LPCTSTR lpszTitle; // Title Bar String
UINT ulFlags;
BFFCALLBACK lpfn; // Calback functionm, Can be NULL.
LPARAM lParam;
int iImage;
} BROWSEINFO, *PBROWSEINFO, *LPBROWSEINFO;
*/
int CALLBACK FSelFolderCallback(HWND hwnd,UINT uMsg,LPARAM lp, LPARAM pData) {
// The callback function required to init desired path to folder, rather than root (Desktop)
// meaning of lp depends on uMsg type
// pData is application defined data for the callback function.
char szPath[MAX_PATH*2];
switch(uMsg) {
case BFFM_INITIALIZED: // Selects the specified folder Path
szPath[0]='\0';
{ // Need Brace to init below s without error.
char*s=(char*)pData;
if(s!=NULL) {
if(s[0]=='.'&&s[1]=='\0') {
if(!GetCurrentDirectory(sizeof(szPath), szPath))
szPath[0]='\0';
} else {
strcpy(szPath,s);
}
}
}
SendMessage(hwnd, BFFM_SETSELECTION, TRUE,(LPARAM) szPath);
break;
case BFFM_SELCHANGED: // Indicates the selection has changed.
if (SHGetPathFromIDList((LPITEMIDLIST) lp ,szPath)) { // convert pidl to path
SendMessage(hwnd, BFFM_SETSTATUSTEXT,0,(LPARAM)szPath); // Send path
}
break;
}
return 0; // Always returns 0
}
AVSValue __cdecl FSelFolder(AVSValue args, void* user_data, IScriptEnvironment* env) {
char * myName="FSelDir: ";
const char * title =args[0].AsString("");
const char * dir =args[1].AsString("."); // Default to '.' = current directory
LPMALLOC pMalloc; // Shell allocator
if (!SUCCEEDED(SHGetMalloc(&pMalloc))) { // Did we successfully get the shell mem alloc interaface
env->ThrowError("%sCannot get Shell Alloc Interface",myName);
}
char szFold[MAX_PATH * 2];
strcpy(szFold,dir);
int flgs= \
BIF_STATUSTEXT |
BIF_RETURNFSANCESTORS |
BIF_RETURNONLYFSDIRS | // File system objects only (selectable), DONT SEEM TO WORK PROPER.
BIF_EDITBOX | // EDITBOX (ie 4.0 + Only)
BIF_NEWDIALOGSTYLE; // 6.0 + only (xp+)
BROWSEINFO bi; // Browse structure
ZeroMemory(&bi,sizeof(bi)); // clr
bi.hwndOwner = NULL; // No owner window
bi.pidlRoot = NULL; // Desktop
bi.pszDisplayName = NULL; // We are gonna get path ourselves
bi.lpszTitle = title;
bi.ulFlags = flgs;
bi.lpfn = FSelFolderCallback; // Browse callback function
bi.lParam = (LPARAM)szFold;
//
LPITEMIDLIST pidl = SHBrowseForFolder(&bi); // return NULL on user CANCEL, else pidl, user must free using shell allocator
if (pidl==NULL) {
dprintf("%sUser CANCELLED",myName);
pMalloc->Release(); // done with shell allocator
return 0;
}
bool b = (SHGetPathFromIDList(pidl,szFold)!=0); // Converts an item identifier list to a file system path (MUST be filesystem)
pMalloc->Free(pidl); // free the pidl
pMalloc->Release(); // done with shell allocator
if(!b) {
dprintf("%sNot a Filesystem Object",myName);
return -1;
}
// dprintf("%s OK Single file = %s",myName,szFold);
return env->SaveString(szFold);
}
extern "C" __declspec(dllexport) const char* __stdcall AvisynthPluginInit2(IScriptEnvironment* env) {
env->AddFunction("FSelOpen" ,"[title]s[dir]s[filt]s[fn]s[multi]b",FSelOpen,0);
env->AddFunction("FSelSaveAs","[title]s[dir]s[filt]s[fn]s",FSelSaveAs,0);
env->AddFunction("FSelFolder","[title]s[dir]s",FSelFolder,0);
return 0;
}
comment seems untrue, seems that the file selector has it's own version of current directory which it keeps as user selected for a certain amount of time and then reverts to current directory when that time expires. Current working directory is not changed by the functions.
__________________
I sometimes post sober. StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace "Some infinities are bigger than other infinities", but how many of them are infinitely bigger ??? Last edited by StainlessS; 15th December 2018 at 14:48. |
|
|
|
![]() |
| Thread Tools | Search this Thread |
| Display Modes | |
|
|