Author Topic: Need help with browse for folder dialog  (Read 3969 times)

0 Members and 1 Guest are viewing this topic.

Offline Egil

  • Paid Subscriber
  • Hero Member
  • *****
  • Posts: 877
    • LA2PJ
Re: Need help with browse for folder dialog
« Reply #25 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.

« Last Edit: March 04, 2016, 04:21:07 AM by Egil »
Support Amateur Radio  -  Have a ham  for dinner!

Offline LarryMc

  • Administrator
  • Hero Member
  • *****
  • Posts: 5897
  • 'All I like is finishing'
Re: Need help with browse for folder dialog
« Reply #26 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.
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

Offline StormAce

  • Newbie
  • *
  • Posts: 15
Re: Need help with browse for folder dialog
« Reply #27 on: March 05, 2016, 10:23:03 AM »
Thanks Larry :)

Offline StormAce

  • Newbie
  • *
  • Posts: 15
Re: Need help with browse for folder dialog
« Reply #28 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;
}

Offline StormAce

  • Newbie
  • *
  • Posts: 15
Re: Need help with browse for folder dialog
« Reply #29 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);
}

Offline LarryMc

  • Administrator
  • Hero Member
  • *****
  • Posts: 5897
  • 'All I like is finishing'
Re: Need help with browse for folder dialog
« Reply #30 on: March 16, 2016, 08:39:24 PM »
lpIDList = SHBrowseForFolder(bi);
and not
lpIDList = SHBrowseForFolder(&bi);
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library