IonicWind Software

Aurora Compiler => Coding Help - Aurora 101 => Topic started by: StormAce on February 29, 2016, 07:04:34 am

Title: Need help with browse for folder dialog
Post by: StormAce on February 29, 2016, 07:04:34 am
Hi,
I'm trying to translate this piece of c or c++ code to aurora to set the initial select folder in the dialog

Code Select


#include <windows.h>
#include <shlobj.h>

int CALLBACK BrowseForFolderCallback(HWND hwnd,UINT uMsg,LPARAM lp, LPARAM pData)
{
char szPath[MAX_PATH];

switch(uMsg)
{
case BFFM_INITIALIZED:
SendMessage(hwnd, BFFM_SETSELECTION, TRUE, pData);
break;

case BFFM_SELCHANGED:
if (SHGetPathFromIDList((LPITEMIDLIST) lp ,szPath))
{
SendMessage(hwnd, BFFM_SETSTATUSTEXT,0,(LPARAM)szPath);

}
break;
}

return 0;
}

BOOL BrowseFolders(HWND hwnd, LPSTR lpszFolder, LPSTR lpszTitle)
{
BROWSEINFO bi;
char szPath[MAX_PATH + 1];
LPITEMIDLIST pidl;
BOOL bResult = FALSE;

LPMALLOC pMalloc;

    if (SUCCEEDED(SHGetMalloc(&pMalloc)))
{
bi.hwndOwner = hwnd;
bi.pidlRoot = NULL;
bi.pszDisplayName = NULL;
bi.lpszTitle = lpszTitle;
bi.ulFlags = BIF_STATUSTEXT; //BIF_EDITBOX
bi.lpfn = BrowseForFolderCallback;
bi.lParam = (LPARAM)lpszFolder;

pidl = SHBrowseForFolder(&bi);
if (pidl)
{
if (SHGetPathFromIDList(pidl,szPath))
{
bResult = TRUE;
strcpy(lpszFolder, szPath);
}

   pMalloc->Free(pidl);
   pMalloc->Release();
           
}
}

return bResult;

}




Here is mine that crash when i use the callback...

Code Select

//extern string BrowseFolders(CWindow *win, STRING title, opt Pointer lpszFolder, opt INT newfolder , opt STRING root);
#include "windows.inc"
#include "shlwapi.inc"
#include "shlobj.inc"

#DEFINE BIF_RETURNONLYFSDIRS 0x0001
#DEFINE BIF_DONTGOBELOWDOMAIN 0x0002
#DEFINE BIF_STATUSTEXT     0x0004
#DEFINE BIF_RETURNFSANCESTORS 0x0008
#DEFINE BIF_EDITBOX     0x0010
#DEFINE BIF_VALIDATE 0x0020
#DEFINE BIF_NEWDIALOGSTYLE     0x0040
#DEFINE BIF_USENEWUI (BIF_NEWDIALOGSTYLE | BIF_EDITBOX)
#DEFINE BIF_BROWSEINCLUDEURLS 0x0080
#DEFINE BIF_UAHINT              0x0100
#DEFINE BIF_NONEWFOLDERBUTTON 0x0200
#DEFINE BIF_NOTRANSLATETARGETS  0x0400
#DEFINE BIF_BROWSEFORCOMPUTER 0x1000
#DEFINE BIF_BROWSEFORPRINTER 0x2000
#DEFINE BIF_BROWSEINCLUDEFILES  0x4000
#DEFINE BIF_SHAREABLE           0x8000

#DEFINE BFFM_INITIALIZED 1
#DEFINE BFFM_SELCHANGED     2
#DEFINE BFFM_VALIDATEFAILEDA 3
#DEFINE BFFM_VALIDATEFAILEDW 4
#DEFINE BFFM_IUNKNOWN 5

//Open Browse for folder dialog, return folder path
GLOBAL SUB BrowseFolders(CWindow *win, STRING title, opt Pointer lpszFolder, opt INT newfolder , opt STRING root),STRING
{
    DSTRING path[260];
    BROWSEINFO bi;
WORD szPath[MAX_PATH + 1];
    pointer lpIDList;
POINTER pidl;
    STRING Buffer;
    //Make sure COM is active
    CoInitialize(NULL);
//initialize variables
path[0] = 0;
RtlZeroMemory(bi,LEN(bi));

if root <> ""
{
bi.pidlRoot = GetPIDLfromPATH(win, s2w(root));
}
else
{
bi.pidlRoot = null;
}


bi.hwndOwner = win->GetHandle();
bi.pszDisplayName = Buffer;
bi.lpszTitle = Title;

bi.lpfn = /**(BFFCALLBACK)*/&BrowseForFolderCallback;
bi.lParam = *(LPARAM)lpszFolder;

    IF newfolder = true
{
        bi.ulFlags = 0x00000001|BIF_NEWDIALOGSTYLE;
}
    ELSE
{
        if newfolder = false | newfolder = null
    {
          bi.ulFlags = 0x00000001;
        }
    }
//messagebox(0, "", "");

lpIDList = SHBrowseForFolder(&bi);

if (lpIDList)
{
pszPath = SHGetPathFromIDList(lpIDList,path);
if (pszPath)
{
strcpy(*(string)lpszFolder, path);
}
    CoTaskMemFree(lpIDList);
        CoUninitialize();
}

RETURN path;
}

SUB BrowseForFolderCallback(HWND hwnd,UINT uMsg,LPARAM lp, LPARAM pData), LPARAM
{
WORD szPath[MAX_PATH];

switch(uMsg)
{
case BFFM_INITIALIZED:
SendMessage(hwnd, BFFM_SETSELECTION, TRUE, pData);
return;

case BFFM_SELCHANGED:
if (SHGetPathFromIDList( lp ,szPath))
{
SendMessage(hwnd, BFFM_SETSTATUSTEXT,0,szPath);
}
return;
}

return 0;
}

// Use by BrowseForFolder
Global SUB GetPIDLfromPATH(Cwindow *win, POINTER *path),ITEMIDLIST*
{
return SHSimpleIDListFromPath(*(wstring)Path);
}




Anyone can see the problem?


Title: Re: Need help with browse for folder dialog
Post by: LarryMc on February 29, 2016, 07:22:11 am
does it compile?
If not, what error messages do you get?
Title: Re: Need help with browse for folder dialog
Post by: StormAce on March 01, 2016, 10:50:44 am
Yes it compile but the app crash when calling it...
Title: Re: Need help with browse for folder dialog
Post by: Egil on March 01, 2016, 03:15:52 pm
I have never used Aurora myself, but in my version there is an example called folder_browser.src that compiles just fine and does not crash. The source also contains suggestions for modifications.
What is wrong with it?

Title: Re: Need help with browse for folder dialog
Post by: StormAce on March 02, 2016, 01:20:56 am
Hi,
I don’t have check in my examples folder before seeing your post, but what i want to do is use the UINT lpfn; in BrowseInfo
This parameter is used to select the folder specified... and it use CallBack...
That’s where it crashes... you can isolate the call with the messagebox commented to see
I have done a lot of pirouettes with the code, can't find a way.

to run, just put the extern call at the top in an src file in a project and add the src file to your project
Title: Re: Need help with browse for folder dialog
Post by: Egil on March 02, 2016, 03:13:09 am
As I mentioned before, I do not have any experience with Aurora.

To use the value of lpfn you have to  return it in some way for use outside the particular suboutine where  it is retreived.
But when inspecting your code with my IWB eyes, the only value returned from your code is path, defined as string.

The folder_browser.src also use the BrowseInfo structure, so suggest you inspect that code closely to see what element(s) that differs from your code,
and see to that a variable holding the value of lpfn is returned.

Sorry for not being able to give you a more more specific answer. But hopefully some of the other forum users, with Aurora experience, will see this and guide you into the right path...


Good Luck!

Title: Re: Need help with browse for folder dialog
Post by: StormAce on March 02, 2016, 03:31:59 am
QuoteTo use the value of lpfn you have to  return it in some way for use outside the particular suboutine where  it is retreived.
But when inspecting your code with my IWB eyes, the only value returned from your code is path, defined as string.


yep browse for folder dialog return a path  ;)
the callback is retreived by sub "BrowseForFolderCallback" which must return 0 as the example in c or c++ above

QuoteThe folder_browser.src also use the BrowseInfo structure, so suggest you inspect that code closely to see what element(s) that differs from your code,
and see to that a variable holding the value of lpfn is returned.


BrowseInfo structure is declare in the one of the #define .inc file at the top of the code...  :)

Thanks anyway sir
Title: Re: Need help with browse for folder dialog
Post by: Brian on March 02, 2016, 04:28:33 am
Well, this was written by the man who wrote the Aurora compiler, so give it a go:

SUB main()
{
   string folder = GetFolder(null,"Select a folder");
   print(folder);
   While GetKey() == "";
}

/* subroutine to open the system folder browser */
struct BROWSEINFO
{
     UINT hOwner;
     UINT pidlRoot;
     POINTER pszDisplayName;
     POINTER lpszTitle;
     UINT ulFlags;
     UINT lpfn;
     INT lParam;
     INT iImage;
}

DECLARE IMPORT,SHGetPathFromIDList(int pidl,string pszPath),INT;
DECLARE IMPORT,SHBrowseForFolder(BROWSEINFO lpbi),INT;
DECLARE IMPORT,CoTaskMemFree(int pidl);   
DECLARE IMPORT,ZeroMemory ALIAS RtlZeroMemory(pData as POINTER,length as INT);
declare import,SHParseDisplayName(WSTRING pszName,UINT *pbc,UINT *ppidl,UINT sfgaoIn,UINT *psfgaoOut),INT;
declare import,SHGetSpecialFolderLocation(UINT hwnd,int nFoloder,UINT *ppidl),int;
SUB GetFolder(UINT hwnd,string title),STRING
{
DSTRING path[260];
BROWSEINFO bi;
UINT lpIDList;
UINT pRoot,pTemp;
   //initialize variables
   path[0] = 0;
   ZeroMemory(bi,LEN(bi));
   //for Windows XP and above we can use SHParseDisplayName which can take a file path
   //such as "c:\\progs" or a CLSID. The CLSID being used is for the My Computer folder.
   SHParseDisplayName(s2w("::{20d04fe0-3aea-1069-a2d8-08002b30309d}"),NULL,pRoot,0,pTemp);
   //for all Windows version this gets the pidl of the My Computer folder.
   //So if you are targeting Windows 9x and above use this instead
   //SHGetSpecialFolderLocation(null,0x0011,pRoot);
   bi.pidlRoot = pRoot;
   bi.hOwner = hwnd;
   bi.pszDisplayName = path;
   bi.lpszTitle = title;
   bi.ulFlags = 0x00000041;
   lpIDList = SHBrowseForFolder(bi);
   if lpIDList <> 0
   {
      SHGetPathFromIDList(lpIDList,path);
      CoTaskMemFree(lpIDList);
   }   
   RETURN path;
}

/* other common CLSID's for use with SHParseDisplayName:
My Documents ::{450d8fba-ad25-11d0-98a8-0800361b1103}
Programs Folder ::{7be9d83c-a729-4d97-b5a7-1b7313c39e0a}
Start Menu Folder ::{48e7caab-b918-4e58-a94d-505519c795dc}
Temporary Internet Files ::{7bd29e00-76c1-11cf-9dd0-00a0c9034933}
My Network Places ::{208d2c60-3aea-1069-a2d7-08002b30309d}
*/

Brian
Title: Re: Need help with browse for folder dialog
Post by: Egil on March 02, 2016, 07:44:44 am
That is the same example I tried to direct his attention to, Brian.
It is found in the examples folder that came with Aurora, and the filename is folder_browser.src .
He stated himself he had not checked it before starting converting from C.

Bought Aurora just to support the site, and never used it. Had to install it last night to find that example.

The problem is that the subroutines he calls only return string values, and he want to use a structure member called lpfn which is defined as an UINT.
So  whatever programming language he uses, he somehow has to retreive and return the value of lpfn before he can use it.
Title: Re: Need help with browse for folder dialog
Post by: Brian on March 02, 2016, 08:32:37 am
Egil,

Well, I'm not doing anything much at the moment, so I might load my Aurora up and have a go!

Brian

Update: Well, loaded up Aurora. Didn't bother with the extra headers, and compiled

Got it - compile as a Console exe and not a Windows exe

It then displays the folder selected. "print (folder);" is the line that does that
Title: Re: Need help with browse for folder dialog
Post by: Egil on March 02, 2016, 09:15:19 am
Thats good Brian!
You have way more experience with Windows than me, so let's hope you are able to help him.

Title: Re: Need help with browse for folder dialog
Post by: Brian on March 02, 2016, 11:01:50 am
Compile folder_browser.src as a Console exe, not a Windows exe

Brian
Title: Re: Need help with browse for folder dialog
Post by: Egil on March 02, 2016, 01:01:22 pm
Here it does not matter if I choose Console.exe or windows.exe. Both compile fine.
Guess the browse for folder dialog is the same for both methods.
Title: Re: Need help with browse for folder dialog
Post by: aurelCB on March 02, 2016, 01:57:02 pm
well
interesting ...when i try to compile Ebasic(old freeware v1.62) program i receive
message from win7 that i don't have permission to do that and linker cannot link exe to
program files , but when i move eba example to folder  C\user then
compile file and exe work. :)
also i dont get it why he need to return
longPointer...
   lpIDList = SHBrowseForFolder(bi)
Title: Re: Need help with browse for folder dialog
Post by: StormAce on March 02, 2016, 02:19:13 pm
Hi guys,
Like i said the folder_browser.src example work well as my code if you remove the bi.lpfn call, just comment it and it works...
My problem is the Callback that don't work... i need it so the last selected folder should be selected in the dialog when you open it ;)
Title: Re: Need help with browse for folder dialog
Post by: fasecero on March 02, 2016, 02:24:45 pm
Hi. You are using lpszFolder as optional inside your BrowseFolders function, I think you should check its value before using it as a pointer

Code Select


if lpszFolder { bi.lParam = *(LPARAM)lpszFolder; }

.....

if lpszFolder { strcpy(*(string)lpszFolder, path); }



And the SHGetPathFromIDList method from your BrowseForFolderCallback function should require a structure, not a pointer, in the first parameter

Code Select

if (SHGetPathFromIDList( *(ITEMIDLIST) lp , szPath) )
Title: Re: Need help with browse for folder dialog
Post by: StormAce on March 02, 2016, 02:38:25 pm
Thanks fasecero,
I have done lots of pirouettes with the code and i think i had tryed that... but i will give it another go with your suggestions later today
thank you :)
Title: Re: Need help with browse for folder dialog
Post by: aurelCB on March 02, 2016, 02:44:21 pm
look this Ebasic program work properly and return last open folder:
Code Select
/*
EBASIC example program
Shows how to use the system directory browser
Compile as a WINDOWS target
*/

DEF mywin:WINDOW
DEF result:INT
DEF Buffer:STRING
DEF sf:INT

OPENWINDOW mywin,0,0,400,300,@MINBOX,0,"Browse for Folder",&mysub

print mywin,GetFolder()

run = 1
WAITUNTIL run = 0
CLOSEWINDOW mywin
END

SUB mysub
SELECT @CLASS
CASE @IDCLOSEWINDOW
run = 0
CASE @IDCREATE
CENTERWINDOW mywin
ENDSELECT
RETURN
ENDSUB

/* subroutine to open the system folder browser */
TYPE BROWSEINFO
     DEF hOwner:UINT
     DEF pidlRoot:UINT
     DEF pszDisplayName:POINTER
     DEF lpszTitle:POINTER
     DEF ulFlags:UINT
     DEF lpfn:UINT
     DEF lParam:INT
     DEF iImage:INT
ENDTYPE

DECLARE IMPORT,SHGetPathFromIDList(pidl:INT,pszPath:STRING),INT
DECLARE IMPORT,SHBrowseForFolder(lpbi:BROWSEINFO),INT
DECLARE IMPORT,CoTaskMemFree(pidl:int)   
DECLARE IMPORT,ZeroMemory ALIAS RtlZeroMemory(pData as POINTER,length as INT)

SUB GetFolder(),STRING
DEF path[260] as ISTRING
DEF bi:BROWSEINFO
DEF lpIDList:INT
'initialize variables
path[0] = 0
ZeroMemory(bi,LEN(bi))
bi.hOwner = mywin.hwnd
bi.pszDisplayName = Buffer
bi.lpszTitle = "Select Directory:"
bi.ulFlags = 0x00000001
lpIDList = SHBrowseForFolder(bi)
if lpIDList <> 0
pszPath = SHGetPathFromIDList(lpIDList,path)
CoTaskMemFree(lpIDList)
ENDIF
RETURN path
ENDSUB
Title: Re: Need help with browse for folder dialog
Post by: StormAce on March 02, 2016, 03:06:48 pm
Thanks Aurel
but its the same as folder_browser.src that was shown in a post above... yes it return the path but dont select the last folder selected ;)
Title: Re: Need help with browse for folder dialog
Post by: aurelCB on March 02, 2016, 03:56:54 pm
Quoteyes it return the path but dont select the last folder selected

::)
well i dont get it what you mean exactly but if you mean
that browser dialog is not visible after path is presented in output window
then you need different type of program with lot more code
or maybe you can force dialog to be always on top
Title: Re: Need help with browse for folder dialog
Post by: StormAce on March 02, 2016, 04:09:00 pm
hehe .. lol
Aurel what i want to do is when you open the browsefolder dialog, i want the last folder that the user use to be selected in the dialog...
So he can know the folder he selected before...

in vb.net its just a question of pass a string...
in wn32 you have to use a callback function ;)
Title: Re: Need help with browse for folder dialog
Post by: Egil on March 02, 2016, 04:17:56 pm
Quote from: StormAce on March 02, 2016, 04:09:00 pm

... i want the last folder that the user use to be selected in the dialog...
So he can know the folder he selected before...


Hi StormAce,

Below is the code needed for MiniBASIC to do exactly that.
It contains all the defines you need for such a function, and should not be too difficult to convert to Aurora.

The included zip archive also contains an exe file made by compiling the code shown.
(The code is part of a program for bulk renaming mp3 files)


Code Select
'
' folder_browse.mba
'
##NOCONSOLE

const BIF_RETURNONLYFSDIRS = 1
const BIF_NEWDIALOGSTYLE = 0x00000040
const BIF_UAHINT = 0x00000100

@API SHBrowseForFolderA(lpbi As pointer),int
@API SHGetPathFromIDList(pidList As int,lpBuffer As String),int
@API CoTaskMemFree(hMem As int)

Type BrowseInfo
   int hWndOwner
   int pIDLRoot
   pointer pszDisplayName
   pointer lpszTitle
   int ulFlags
   int lpfnCallback
   int lParam
   int iImage
End Type

WINDOW win
win.Open(0,0,800,480,WS_SYSMENU|WS_VISIBLE|BUFFERED|CENTERED,0," Mp3Rename",NULL,&handler)

' Select directory to convert
BrowseInfo bi
int ret
string Path,name

bi.lpszTitle = "Choose Folder"
bi.ulFlags = BIF_RETURNONLYFSDIRS|BIF_NEWDIALOGSTYLE|BIF_UAHINT
bi.pszDisplayName = name
ret = SHBrowseForFolderA(bi)
SHGetPathFromIDList(ret,Path)
CoTaskMemFree(ret)
win.WriteText(10,20,"Selected Directory: "+Path)


DO:ProcessMessages():UNTIL win.GetHandle()=NULL:END



' Main loop
FUNC handler(WINDOW wnd),int

  SELECT wnd.Message
  CASE ID_CLOSE
wnd.Close()
  ENDSELECT

RETURN 0
ENDF


Title: Re: Need help with browse for folder dialog
Post by: StormAce on March 02, 2016, 04:25:09 pm
thanks Egil,
Ill tryed it later today :)
Title: Re: Need help with browse for folder dialog
Post by: aurelCB on March 02, 2016, 11:58:12 pm
Quotei want the last folder that the user use to be selected in the dialog...
So he can know the folder he selected before...


Well i get it now ,but you dont say that first time.
So you need something like listbox to store each selected folder name
but this require more coding....
Title: Re: Need help with browse for folder dialog
Post by: StormAce on March 03, 2016, 12:05:40 am
yes, well, its already coded ;)
I take it from registry in fact
Title: Re: Need help with browse for folder dialog
Post by: Egil on March 03, 2016, 10:22:55 am
Was much easier to convert MiniBASIC code to Aurora than I first thought. Here is the code needed to print selected browser to a console screen:

Code Select
// folder_browse.src
// Compile as console


SUB main()
{
dstring folder = GetFolder(null,"Select a folder");
print ("Selected directory:");
print(folder);

int run = 1;
do
{
wait();
}
until run = 0;
}


struct BROWSEINFO
{
    UINT hOwner;
    UINT pidlRoot;
    POINTER pszDisplayName;
    POINTER lpszTitle;
    UINT ulFlags;
    UINT lpfn;
    INT lParam;
    INT iImage;
}

DECLARE IMPORT,SHGetPathFromIDList(int pidl,string pszPath),INT;
DECLARE IMPORT,SHBrowseForFolder(BROWSEINFO lpbi),INT;
DECLARE IMPORT,CoTaskMemFree(int pidl);  
DECLARE IMPORT,ZeroMemory ALIAS RtlZeroMemory(pData as POINTER,length as INT);
declare import,SHParseDisplayName(WSTRING pszName,UINT *pbc,UINT *ppidl,UINT sfgaoIn,UINT *psfgaoOut),INT;
declare import,SHGetSpecialFolderLocation(UINT hwnd,int nFoloder,UINT *ppidl),int;


/* subroutine to open the system folder browser */
SUB GetFolder(UINT hwnd,string title),STRING
{
DSTRING path[260];
BROWSEINFO bi;
UINT lpIDList;
UINT pRoot,pTemp;
//initialize variables
path[0] = 0;
ZeroMemory(bi,LEN(bi));
//for Windows XP and above we can use SHParseDisplayName which can take a file path
//such as "c:\\progs" or a CLSID. The CLSID being used is for the My Computer folder.
SHParseDisplayName(s2w("::{20d04fe0-3aea-1069-a2d8-08002b30309d}"),NULL,pRoot,0,pTemp);
//for all Windows version this gets the pidl of the My Computer folder.
//So if you are targeting Windows 9x and above use this instead
//SHGetSpecialFolderLocation(null,0x0011,pRoot);
bi.pidlRoot = pRoot;
bi.hOwner = hwnd;
bi.pszDisplayName = path;
bi.lpszTitle = title;
bi.ulFlags = 0x00000041;
lpIDList = SHBrowseForFolder(bi);
if lpIDList <> 0
{
SHGetPathFromIDList(lpIDList,path);
CoTaskMemFree(lpIDList);
}
RETURN path;
}

/* other common CLSID's for use with SHParseDisplayName:
My Documents ::{450d8fba-ad25-11d0-98a8-0800361b1103}
Programs Folder ::{7be9d83c-a729-4d97-b5a7-1b7313c39e0a}
Start Menu Folder ::{48e7caab-b918-4e58-a94d-505519c795dc}
Temporary Internet Files ::{7bd29e00-76c1-11cf-9dd0-00a0c9034933}
My Network Places ::{208d2c60-3aea-1069-a2d7-08002b30309d}
*/



EDIT: Code updated to make the program terminate properly when compiled in Aurora.

Title: Re: Need help with browse for folder dialog
Post by: LarryMc on March 03, 2016, 11:10:05 am
The attached zip contains a source file in iwbasic and an exe file.
The exe demonstrates what I think he he is wanting to do.
It opens the folder browser
if you select a folder it closes the browser
(as part of demo) it immediately reopens browser with the last selected folder
you can keep repeating the process as long as desired
select CANCEL to exit demo loop.

demonstrates that all you have to do is save selection and reload it to make it work.
Title: Re: Need help with browse for folder dialog
Post by: StormAce on March 05, 2016, 10:23:03 am
Thanks Larry :)
Title: Re: Need help with browse for folder dialog
Post by: StormAce on March 16, 2016, 04:21:52 am
Hi,
still stuck on this one... i'm trying to translate larry's example but i want to return the string from the sub
i got invalid assigment for the line "lpIDList = SHBrowseForFolder(&bi);"
anyone see it ?

Code Select

//Open Browse for folder dialog, return folder path
GLOBAL SUB BrowseFolders(CWindow *win, Pointer title, opt Pointer lpszFolder, opt INT newfolder , opt STRING root),STRING
{
    BROWSEINFO bi;
//Make sure COM is active
    CoInitialize(NULL);
RtlZeroMemory(&bi,LEN(bi));
//initialize variables
string returndir;
Unsigned int lpIDList;

//set the root folder
if root <> ""
{
bi.pidlRoot = GetPIDLfromPATH(win, s2w(root));
}
else
{
bi.pidlRoot = null;
}

bi.hwndOwner = win->GetHandle();
bi.lpszTitle = Title;
bi.lpfn = /**(BFFCALLBACK)*/&BrowseForFolderCallback;
bi.lParam = *(unsigned int)lpszFolder;

//newfolder button
    IF (newfolder)
{
        bi.ulFlags = 0x00000001|BIF_NEWDIALOGSTYLE;
}
    ELSE
{
        if !newfolder | newfolder = null
    {
          bi.ulFlags = 0x00000001;
        }
    }


lpIDList = SHBrowseForFolder(&bi);
if (lpIDList)
{
if (SHGetPathFromIDList(lpIDList,&returndir))
{

RETURN returndir + "\\";
}
    CoTaskMemFree(lpIDList);
}

    returndir = "";
    RETURN returndir;
}

SUB BrowseForFolderCallback(HWND hwnd,UINT uMsg,LPARAM lp, LPARAM pData), LPARAM
{
Unsigned Int dwStyle;
string szPath;

Select(uMsg)
{
case BFFM_INITIALIZED:
SendMessage(hwnd, BFFM_SETSELECTION, TRUE, pData);
//Remove the ? from the caption - optional
            dwStyle = GetWindowLongA(hWnd, GWL_EXSTYLE);
            IF (dwStyle & WS_EX_CONTEXTHELP)
{
                SetWindowLongA(hWnd, GWL_EXSTYLE, dwStyle || WS_EX_CONTEXTHELP);
        }
case BFFM_SELCHANGED:
if (SHGetPathFromIDList( lp ,szPath))
{
//Set the window text to the path
                szPath= "\x0";
SendMessage(hwnd, BFFM_SETSTATUSTEXT,0,szPath);
SetWindowTextA(hWnd, szPath);
}
Case BFFM_VALIDATEFAILED:
            Return 1;
}

return 0;
}
Title: Re: Need help with browse for folder dialog
Post by: StormAce on March 16, 2016, 04:35:12 am
here's is the file i use for my software...
if it can help... good sub in it too ;)
you have to add the file to your project and declare the extern at the top in the file you need the function
you have also to install windows headers that i found somewhere on the forum for aurora

Code Select

//////////////////////////////////////////////////////////////
//  subroutine to play with files
//////////////////////////////////////////////////////////////

//extern string BrowseFolders(CWindow *win, STRING title, opt Pointer lpszFolder, opt INT newfolder , opt STRING root);
//extern void StartApp(String AppPath,String Command, INT ShowConsole, INT Wait);
//extern string ParseFile(string pfull);
//extern string ExtractExtension(string Filepath);
//extern string GetFolderLocation(Cwindow *win,INT nFolder);
#ifndef FileAPI
#define FileAPI
#include "windows.inc"
#include "shlwapi.inc"
#include "shlobj.inc"


struct SHELLEXECUTEINFO,1
{
INT cbSize;
INT fMask;
INT hwnd;
Pointer  lpVerb;
Pointer  lpFile;
Pointer  lpParameters;
Pointer  lpDirectory;
int nShow;
INT hInstApp;
// Optional fields
INT lpIDList;
Pointer  lpClass;
INT hkeyClass;
INT dwHotKey;
union {
INT hIcon;
    INT hMonitor;
}
INT hProcess;
}

#define SEE_MASK_NOCLOSEPROCESS 0x40
#define WAIT_TIMEOUT 258
/*
struct BROWSEINFO
{
     Unsigned INT hOwner;
     Unsigned INT pidlRoot;
     POINTER pszDisplayName;
     POINTER lpszTitle;
     Unsigned INT ulFlags;
     Unsigned INT lpfn;
     Unsigned INT lParam;
     Unsigned INT iImage;
}
*/

#DEFINE BIF_RETURNONLYFSDIRS 0x0001
#DEFINE BIF_DONTGOBELOWDOMAIN 0x0002
#DEFINE BIF_STATUSTEXT     0x0004
#DEFINE BIF_RETURNFSANCESTORS 0x0008
#DEFINE BIF_EDITBOX     0x0010
#DEFINE BIF_VALIDATE 0x0020
#DEFINE BIF_NEWDIALOGSTYLE     0x0040
#DEFINE BIF_USENEWUI (BIF_NEWDIALOGSTYLE | BIF_EDITBOX)
#DEFINE BIF_BROWSEINCLUDEURLS 0x0080
#DEFINE BIF_UAHINT              0x0100
#DEFINE BIF_NONEWFOLDERBUTTON 0x0200
#DEFINE BIF_NOTRANSLATETARGETS  0x0400
#DEFINE BIF_BROWSEFORCOMPUTER 0x1000
#DEFINE BIF_BROWSEFORPRINTER 0x2000
#DEFINE BIF_BROWSEINCLUDEFILES  0x4000
#DEFINE BIF_SHAREABLE           0x8000

#DEFINE BFFM_INITIALIZED 1
#DEFINE BFFM_SELCHANGED     2
#DEFINE BFFM_VALIDATEFAILEDA 3
#DEFINE BFFM_VALIDATEFAILEDW 4
#DEFINE BFFM_IUNKNOWN 5

#DEFINE WM_USER                0x400
#DEFINE BFFM_SETSTATUSTEXTA    (WM_USER + 100)
#DEFINE BFFM_ENABLEOK    (WM_USER + 101)
#DEFINE BFFM_SETSELECTIONA    (WM_USER + 102)
#DEFINE BFFM_SETSELECTIONW    (WM_USER + 103)
#DEFINE BFFM_SETSTATUSTEXTW    (WM_USER + 104)
#DEFINE BFFM_SETOKTEXT    (WM_USER + 105)
#DEFINE BFFM_SETEXPANDED    (WM_USER + 106)

DECLARE IMPORT,RtlZeroMemory(POINTER pData, unsigned INT length);
DECLARE IMPORT,GetPathFromIDList alias SHGetPathFromIDList(int pidl,string pszPath),INT;

#ENDIF

//Open Browse for folder dialog, return folder path
GLOBAL SUB BrowseFolders(CWindow *win, Pointer title, opt Pointer lpszFolder, opt INT newfolder , opt STRING root),STRING
{
    BROWSEINFO bi;
//Make sure COM is active
    CoInitialize(NULL);
RtlZeroMemory(&bi,LEN(bi));
//initialize variables
string returndir;
Unsigned int lpIDList;

//set the root folder
if root <> ""
{
bi.pidlRoot = GetPIDLfromPATH(win, s2w(root));
}
else
{
bi.pidlRoot = null;
}

bi.hwndOwner = win->GetHandle();
bi.lpszTitle = Title;
bi.lpfn = /**(BFFCALLBACK)*/&BrowseForFolderCallback;
bi.lParam = *(unsigned int)lpszFolder;

//newfolder button
    IF (newfolder)
{
        bi.ulFlags = 0x00000001|BIF_NEWDIALOGSTYLE;
}
    ELSE
{
        if !newfolder | newfolder = null
    {
          bi.ulFlags = 0x00000001;
        }
    }


lpIDList = SHBrowseForFolder(&bi);
if (lpIDList)
{
if (SHGetPathFromIDList(lpIDList,&returndir))
{
CoTaskMemFree(lpIDList);
RETURN returndir + "\\";
}
    CoTaskMemFree(lpIDList);
}

    returndir = "";
    RETURN returndir;
}

SUB BrowseForFolderCallback(HWND hwnd,UINT uMsg,LPARAM lp, LPARAM pData), LPARAM
{
Unsigned Int dwStyle;
string szPath;

Select(uMsg)
{
case BFFM_INITIALIZED:
SendMessage(hwnd, BFFM_SETSELECTION, TRUE, pData);
//Remove the ? from the caption - optional
            dwStyle = GetWindowLongA(hWnd, GWL_EXSTYLE);
            IF (dwStyle & WS_EX_CONTEXTHELP)
{
                SetWindowLongA(hWnd, GWL_EXSTYLE, dwStyle || WS_EX_CONTEXTHELP);
        }
case BFFM_SELCHANGED:
if (SHGetPathFromIDList( lp ,szPath))
{
//Set the window text to the path
                szPath= "\x0";
//SendMessage(hwnd, BFFM_SETSTATUSTEXT,0,szPath);
SetWindowTextA(hWnd, szPath);
}
Case BFFM_VALIDATEFAILED:
            Return 1;
}

return 0;
}


//get filename from full path
GLOBAL SUB ParseFile(string pfull),string
{
    INT done = 0;
    string ppath = pfull ;
    IF (STRFIND(ppath,"\\")) | (STRFIND(ppath,"/"))
{
        WHILE done = 0 
{
         IF(RIGHT$(ppath,1) <> "\\") & (RIGHT$(ppath,1) <> "/")
{
            ppath = LEFT$(ppath,LEN(ppath)-1);
}
         ELSE 
{
            done = 1 ;

        } 
        string pfile = MID$(pfull,LEN(ppath)+1);
    } 
RETURN  pfile;
}

//Start a Commandline Application
GLOBAL SUB StartApp(String AppPath,String Command, INT ShowConsole, INT Wait)
{
SHELLEXECUTEINFO info;
info.cbSize = 15 * 4;
    info.fMask = SEE_MASK_NOCLOSEPROCESS;
    info.hwnd = 0;
    info.lpVerb = "Open";
    info.lpFile = AppPath;
    info.lpParameters = Command;
info.lpDirectory = "";

If (ShowConsole)
{
    info.nShow = SWRestore;
}
Else
{
info.nShow = SWHide;
}

    info.hInstApp = 0;

ShellExecuteExA(info);

if (wait)
{
do
    {
    Int ret = WaitForSingleObject(info.hprocess,0);
    wait(1);
    }until(ret <> WAIT_TIMEOUT);
}

return;
}

//return the extension from a path or filename (bypass multiple dot in string)
GLOBAL SUB ExtractExtension(string Filepath),string
{
string extension = "";
int pos = 0;
do
{
    unsigned int Dotpos = STRFIND(Filepath, ".", pos+1);
    pos = dotpos;
    if dotpos <> 0
    {
    extension = STRRIGHT(Filepath, len(filepath)-DotPos);
    }
}
until DotPos < 1;
return extension;
}

////////////////////////////////////////////////////////////////////////////////
// return the path to special folders
Global SUB GetFolderLocation(Cwindow *win,INT nFolder),STRING
{
   STRING path;
   INT pidl;
   POINTER ppidl;
   ppidl = pidl;
   SHGetSpecialFolderLocation(win->m_hwnd,nFolder,ppidl);
   GetPathFromIDList(pidl,path);
   CoTaskMemFree(pidl);
RETURN path;
}

// Use by BrowseForFolder
Global SUB GetPIDLfromPATH(Cwindow *win, POINTER path),ITEMIDLIST*
{
return SHSimpleIDListFromPath(Path);
}
Title: Re: Need help with browse for folder dialog
Post by: LarryMc on March 16, 2016, 08:39:24 pm
lpIDList = SHBrowseForFolder(bi);
and not
lpIDList = SHBrowseForFolder(&bi);