August 18, 2019, 03:37:48 pm

News:

IonicWind Snippit Manager 2.xx Released!  Install it on a memory stick and take it with you!  With or without IWBasic!


Need help with browse for folder dialog

Started by StormAce, February 29, 2016, 07:04:34 am

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Egil

March 03, 2016, 10:22:55 am #25 Last Edit: March 04, 2016, 04:21:07 am by Egil
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.

Support Amateur Radio  -  Have a ham  for dinner!

LarryMc

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


StormAce

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;
}

StormAce

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);
}

LarryMc

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