- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Here is the missing Interface:
Code:
interface
subroutine CoTaskMemFree (pvoid)
!DEC$ IF DEFINED(_X86_)
!DEC$ ATTRIBUTES STDCALL, ALIAS:'_CoTaskMemFree@4' :: CoTaskMemFree
!DEC$ ELSE
!DEC$ ATTRIBUTES STDCALL, ALIAS: 'CoTaskMemFree' :: CoTaskMemFree
!DEC$ ENDIF
integer :: pvoid
end subroutine CoTaskMemFree
end interface
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You probably gave it an invalid or NULL parent window handle.
XeffortLite sample contains module XFTFile which contains XBrowse wrapper routine for ShBrowseForFolder. It also allows you to specify the initial directory for the dialog (and I find the software which always lets you start browsing from "My Computer" very annoying).
Jugoslav
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Code:
module BrowseFolder interface integer(4) function SHBrowseForFolder (pBI) use mod_dialog !DEC$ IF DEFINED(_X86_) !DEC$ ATTRIBUTES STDCALL, ALIAS:'_SHBrowseForFolderA@4' :: SHBrowseForFolder !DEC$ ELSE !DEC$ ATTRIBUTES STDCALL, ALIAS: 'SHBrowseForFolderA' :: SHBrowseForFolder !DEC$ ENDIF !DEC$ ATTRIBUTES REFERENCE :: pBI TYPE(T_BROWSEINFO) :: pBI end function SHBrowseForFolder end interface interface logical(4) function SHGetPathFromIDList (pidl, pszPath) !DEC$ IF DEFINED(_X86_) !DEC$ ATTRIBUTES STDCALL, ALIAS:'_SHGetPathFromIDListA@8' :: SHGetPathFromIDList !DEC$ ELSE !DEC$ ATTRIBUTES STDCALL, ALIAS: 'SHGetPathFromIDListA' :: SHGetPathFromIDList !DEC$ ENDIF !DEC$ ATTRIBUTES VALUE :: pidl !DEC$ ATTRIBUTES REFERENCE :: pszPath integer :: pidl character*(*) :: pszPath end function SHGetPathFromIDList end interface end module LOGICAL Function BrowseForFolder(dir) use browsefolder implicit none
TYPE T_BROWSEINFO
INTEGER hwndOwner
INTEGER pidlRoot
INTEGER pszDisplayName ! Return display name of item selected.
INTEGER lpszTitle ! text to go in the banner over the tree.
INTEGER ulFlags ! Flags that control the return stuff
INTEGER lpfn
INTEGER lParam ! extra info that's passed back in callbacks
INTEGER iImage ! output var: where to return the Image index.
END TYPE T_BROWSEINFO character*(*) dir integer lpIDList TYPE(T_BROWSEINFO) BI bi.hwndOwner = 0 bi.pidlRoot = NULL !Starts with Workspace bi.pszDisplayName = LOC(Dir) bi.lpszTitle = LOC("Please select directory:"C) bi.ulFlags = 1 !For selecting only directories and hard drives and not network enviroment and so on bi.lpfn = 0 bi.lParam = 0 bi.iImage = 0 lpIDList = SHBrowseForFolder(bi) IF (lpIDList.ne.0) THEN BrowseForFolder = SHGetPathFromIDList (lpIDList, dir) else BrowseForFolder = .false. END IF return end function
I use the following module for browsing folders.
Note that dir has a char(0) at the end of the string.
Markus
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Is it possible to obtain these?
Sorry, XFLOGM.f90 was indeed missing from the zip; I updated it now. (You don't need it for your project though -- only XFTFile and XFTStrings).
Either make sure that first !DEC$DEFINE XLITE line is uncommented, or specify XLITE in Project/Settings/Fortran/Preprocessor/Symbols. In this way, you "cut off" dependencies from other XFT* modules. (All library sources are in full Xeffort installation).
Jugoslav
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I finally solved the problem in which my BrowseForFolder dialog was being displayed behind all other windows: I was responding to the WM_PAINT message in order to automatically display some graphical output, and this was interfering with all popup windows including message boxes. ObviouslyI was not doing it correctly. Anyway it all works now. Many thanks to all who replied to my questions and helped me along the way.
Lynn
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
integer, parameter :: BIF_DONTGOBELOWDOMAIN =Z'0002' ! For starting the Find Computer
integer, parameter :: BIF_STATUSTEXT =Z'0004' ! Top of the dialog has 2 lines of text for BROWSEINFO.lpszTitle and one line if
! this flag is set. Passing the message BFFM_SETSTATUSTEXTA to the hwnd can set the
! rest of the text. This is not used with BIF_USENEWUI and BROWSEINFO.lpszTitle gets
! all three lines of text.
integer, parameter :: BIF_RETURNFSANCESTORS =Z'0008'
integer, parameter :: BIF_EDITBOX =Z'0010' ! Add an editbox to the dialog
integer, parameter :: BIF_VALIDATE =Z'0020' ! insist on valid result (or CANCEL)
integer, parameter :: BIF_NEWDIALOGSTYLE =Z'0040' ! Use the new dialog layout with the ability to resize
! Caller needs to call OleInitialize() before using this API
integer, parameter :: BIF_USENEWUI = IOR(BIF_NEWDIALOGSTYLE , BIF_EDITBOX)
integer, parameter :: BIF_BROWSEINCLUDEURLS =Z'0080' ! Allow URLs to be displayed or entered. (Requires BIF_USENEWUI)
integer, parameter :: BIF_UAHINT =Z'0100' ! Add a UA hint to the dialog, in place of the edit box. May not be combined with BIF_EDITBOX
integer, parameter :: BIF_NONEWFOLDERBUTTON =Z'0200' ! Do not add the "New Folder" button to the dialog. Only applicable with BIF_NEWDIALOGSTYLE.
integer, parameter :: BIF_NOTRANSLATETARGETS=Z'0400' ! don't traverse target as shortcut
integer, parameter :: BIF_BROWSEFORCOMPUTER =Z'1000' ! Browsing for Computers.
integer, parameter :: BIF_BROWSEFORPRINTER =Z'2000' ! Browsing for Printers
integer, parameter :: BIF_BROWSEINCLUDEFILES=Z'4000' ! Browsing for Everything
integer, parameter :: BIF_SHAREABLE =Z'8000' ! sharable resources displayed (remote shares, requires BIF_USENEWUI)
integer, parameter :: BFFM_INITIALIZED = 1
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
[bash]! Shows a folder chooser shell window. The path to the chosen
! folder is placed in folderPath, which is a character array of
! the specified length. Returns true if the user chose a folder,
! or false if the operation was cancelled. The title caption
! is specified as a string table resource ID in the optional
! argument title.
!
LOGICAL FUNCTION CmnDlgChooseFolder (hwndParent, folderPath, title)
USE ExtraWinTy
USE ifcom, only: COMInitialize, COMUnInitialize
IMPLICIT NONE
INTEGER(HANDLE), INTENT(IN) :: hwndParent
CHARACTER(LEN=*), INTENT(INOUT) :: folderPath
INTEGER, INTENT(IN), OPTIONAL :: title ! stringtable id value
TYPE(T_BROWSEINFO) :: bi
CHARACTER(LEN=MAX_PATH) :: buffer
INTEGER :: pidl ! pointer to id list
INTEGER :: status, rval2
CHARACTER(LEN=200) :: titleBuffer
INTEGER :: titleId
TYPE(T_STRRET) :: rstring
INTEGER :: IShellFolder_desktop
CmnDlgChooseFolder = .FALSE.
IF (PRESENT(title)) THEN
titleId = title
ELSE
titleId = IDS_DEFAULT_CHOOSEFOLDER_TITLE
END IF
titleBuffer = STGet(titleId, 200)
CALL COMInitialize (status)
buffer = folderPath
! TYPE T_BROWSEINFO
! SEQUENCE
! INTEGER :: hwndOwner
! INTEGER :: pidlRoot
! INTEGER :: pszDisplayName
! INTEGER :: lpszTitle
! INTEGER :: ulFlags
! INTEGER :: lpfn
! INTEGER :: lParam
! INTEGER :: iImage
! END TYPE T_BROWSEINFO
bi%hwndOwner = hwndParent
bi%pidlRoot = NULL
bi%pszDisplayName = LOC(buffer)
bi%lpszTitle = LOC(titleBuffer)
bi%ulFlags = BIF_RETURNONLYFSDIRS
bi%lpfn = NULL
bi%lParam = 0
bi%iImage = 0
! SHBrowseForFolder returns an item identifier list.
pidl = SHBrowseForFolder (bi)
IF (pidl /= 0) THEN
SELECT CASE (windows_version)
! Win95 and Win98
CASE (VER_PLATFORM_WIN32_WINDOWS)
! We need to ask the shell to decode the item identifier
! list into a parseable name. First, retrieve an IShellFolder
! COM interface handle to the desktop folder.
rval2 = SHGetDesktopFolder(LOC(IShellFolder_desktop))
IF (rval2 == NOERROR) THEN
! Use the GetDisplayNameOf method to convert the item
! identifier list into a string. The SHGDN_FORPARSING flag
! indicates we want the parseable path, not the general-
! purpose display label.
rstring%uType = STRRET_CSTR
rval2 = IShellFolder_GetDisplayNameOf (IShellFolder_desktop,&
pidl, &
SHGDN_FORPARSING, &
LOC(rstring) )
IF (rval2 == NOERROR) THEN
folderPath = rstring%cStr
CmnDlgChooseFolder = .TRUE.
END IF
END IF
! WinNT, Win2K, WinXP
CASE (VER_PLATFORM_WIN32_NT)
CmnDlgChooseFolder = SHGetPathFromIDList (pidl, folderPath)
END SELECT
CALL CoTaskMemFree (pidl)
END IF
CALL COMUnInitialize ()
END FUNCTION CmnDlgChooseFolder
[/bash]
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
itemidlistptr = SHSimpleIDListFromPath (initdirptr)
fails because initdirptr must point to a WIDE character string, that is a string consisting of 2 bytes-per-character.
try this:
CHARACTER(256) STARTPATH1
INTEGER(2) UCPATH1(256)
INTEGER IACP, IBYTESNEED, IBYTESWRITTEN,IWIDE
INTEGER ITEMIDLISTPTR
....
....
STARTPATH1="C:\PROGRAM FILES"//CHAR(0) ! Must be a null-terminated string
UCPATH1=0
IACP=GetACP() ! get the code page in use
IWIDE=0
! find out how many bytes are needed...
IBYTESNEED=MultiByteToWideChar(IACP, 0, STARTPATH1,-1,UCPATH1, IWIDE)
!..then write them to UCPATH1..
IBYTESWRITTEN=MultiByteToWideChar(IACP, 0, STARTPATH1,-1,UCPATH1, IBYTESNEED)
UCPATH1(IBYTESWRITTEN+1)=0 ! terminate with an added zero
ITEMIDLISTPTR=SHSimpleIDListFromPath (LOC(UCPATH1))
and you should get a meaningful pointer value for ITEMIDLISTPTR
By the way, "C:\program files" has its own PIDL value = CSIDL_PROGRAM_FILES
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
error #6404: This name does not have a type, and must have an explicit type. [STGET]
error #6404: This name does not have a type, and must have an explicit type. [SHBROWSEFORFOLDER]
error #6404: This name does not have a type, and must have an explicit type. [WINDOWS_VERSION]
error #6404: This name does not have a type, and must have an explicit type. [SHGETDESKTOPFOLDER]
error #6404: This name does not have a type, and must have an explicit type. [STRRET_CSTR]
error #6404: This name does not have a type, and must have an explicit type. [SHGDN_FORPARSING]
error #6404: This name does not have a type, and must have an explicit type. [ISHELLFOLDER_GETDISPLAYNAMEOF]
error #6404: This name does not have a type, and must have an explicit type. [SHGETPATHFROMIDLIST]
I could not find definitions for these names in the IVF include files. May be they are somewhere else?
String 52:
bi%pidlRoot=NULL
It looks like it starts from the Decktop, not from the supplied path.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
After I added your code to my and added 'USE kernel32' stringcompiler built application without error reports. But when I run my program and called this function it showed wrong behavior. I tried to use as a starting folder E:\Data. First, a mesage appeared:
The folder E:\Data cannot be used. Please choose another folder.
After I pressed OK, browse for folder dialog appeared, but in wrong kind. It did not contain any folders except E:\Data, but it had improper view and had no subfolders. Screenshots attached. After I pressed Cancel and closed my application it crashed: An unhandled win32 exception occurred in Myprogram.exe [4576].

.

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
And a screen shot of Windows explorer opened at E:\data?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Try setting the flags to zero so the defaults are used.
I have tried your code on an XP Pro system and it works fine, except I do not have an e:\data disk so have to use different folder name.
Is there anything special about your E:\data disk?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
NoteIf COM is initialized using CoInitializeEx with the COINIT_MULTITHREADED flag, SHBrowseForFolder fails if the calling application uses the BIF_USENEWUI or BIF_NEWDIALOGSTYLE flag in the BROWSEINFO structure.
It is the responsibility of the calling application to call CoTaskMemFree to free the IDList returned by SHBrowseForFolder when it is no longer needed.
Perhaps remove the BIF_NEWDIALOGSTYLE flag?...
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page