• Welcome to Powerbasic Museum 2020-B.
 

News:

Forum in repository mode. No new members allowed.

Main Menu

Treeview and localized user's folder.

Started by Olav Bergesen, September 12, 2013, 06:01:17 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Olav Bergesen

Hi,

I have a small routine which populates drives and folders into a Treeview Control.

Even though FindFirstFile(while populating the tree) read the user's folder as C:\Users; the folder
ends up in the treeview control in a localized version. In my case C:\Brukere.

Now, if the user should check this folder(C:\Brukere) in order to search it for files(as the start
folder to search in), FindFirstFile fails to find anything. Works find if C:\Users is used.

Question #1:

Is there a way to prevent localized version of this folder to be added to the treeview?

Question #2:of this folder
Is there a way to detect that C:\Brukere is a special folder and then retrieve it's real name(C:\Users)?

Thanks for your help!
--
Regards,

Olav Bergesen   

Pierre Bellisle

#1
Hi Olav,

If you end up with a localized folder name to your treeview then
the result from FindFirstFile/FindNextFile must have been transformed by
something like the SHGetFileInfo api or similar. To prevent it you must find where it is occuring.

As a demo, here is some code that build a DisplayName
or LocalizedName if you prefer from a regular path name.
Also a routine that do reverse engineering to give a path name from a DisplayName.

Pierre


#COMPILE EXE '#Win 8.04#
#DIM ALL
#INCLUDE "Win32Api.inc"
'______________________________________________________________________________

FUNCTION GetDisplayName(BYVAL sPathName AS STRING) AS STRING 'Get localized DisplayName from a path name
LOCAL FileInfo     AS SHFILEINFO
LOCAL sDisplayName AS STRING
LOCAL sBuildPath   AS STRING
LOCAL SubPathCount AS LONG
LOCAL Looper       AS LONG

IF ASC(sPathName, -1) = 92  THEN 'Is last character is a backslash
   sPathName = LEFT$(sPathName, -1) 'Remove trailing backslash
END IF
SubPathCount = PARSECOUNT(sPathName, "\") 'Count the path parts, Ex: "C:\Folder1\Folder2\Folder3" will be 4

FOR Looper = 1 TO SubPathCount 'For every path name part
   sBuildPath = sBuildPath & PARSE$(sPathName, "\", Looper) & "\" 'Incremental rebuild of sPathName, Ex: "C:\", "C:\User", "C:\User\Olav", "C:\User\Olav\Favorites"
   SHGetFileInfo(BYVAL STRPTR(sBuildPath), 0, FileInfo, LEN(FileInfo), %SHGFI_DISPLAYNAME) 'Get DisplayName for this folder
   sDisplayName = sDisplayName & FileInfo.szDisplayName & "\" 'Build a string for DisplayName
NEXT
FUNCTION = sDisplayName 'Let function return result

END FUNCTION
'______________________________________________________________________________

FUNCTION GetPathName(BYVAL sDisplayName AS STRING) AS STRING 'Get path name from localized DisplayName
LOCAL FolderData    AS WIN32_FIND_DATA
LOCAL FileInfo      AS SHFILEINFO
LOCAL sDriveList    AS STRING
LOCAL sDrive        AS STRING
LOCAL sBuildPath    AS STRING
LOCAL hFile         AS DWORD
LOCAL SubPathCount  AS LONG
LOCAL ReturnedBytes AS LONG
LOCAL Looper        AS LONG

IF ASC(sDisplayName, -1) = 92  THEN 'Is last character is a backslash
   sDisplayName = LEFT$(sDisplayName, -1) 'Remove trailing backslash
END IF
SubPathCount = PARSECOUNT(sDisplayName, "\") 'Count the path parts, Ex: "C:\Folder1\Folder2\Folder3" will be 4

IF LEN(sDisplayName) THEN 'Check if we have something

   'Doing the drive name part
   sDriveList = NUL$(1024) 'Prepare a string big enough to receive drive list
   ReturnedBytes = GetLogicalDriveStrings(LEN(sDriveList), BYVAL STRPTR(sDriveList)) 'Multi-string zero
   FOR Looper = 1 TO ReturnedBytes \ 4 'Each drive returned is 4 bytes like "C:\" & $NUL
     sDrive = PARSE$(sDriveList, $NUL, Looper) 'Like "C:\"
     SHGetFileInfo(BYVAL STRPTR(sDrive), 0, FileInfo, LEN(FileInfo), %SHGFI_DISPLAYNAME) 'Get display name for this drive
     IF LCASE$(PARSE$(sDisplayName, "\", 1)) = LCASE$(FileInfo.szDisplayName) THEN 'Is this part of sDisplayName equal to the DisplayName of the drive?
       sBuildPath = sDrive 'Put drive path name instead of DisplayName, Ex: "C:\" will replace "Windows Seven (C:)"
       EXIT FOR 'No need to continue
     END IF
   NEXT

   'Doing the folder name part
   IF SubPathCount > 1 THEN 'Verify that there is at least one folder name
     FOR Looper = 2 TO SubPathCount 'For every folder
       'sFirstFile = sBuildPath & "*" '
       'hFile = FindFirstFile(BYVAL STRPTR(sFirstFile), FolderData)
       hFile = FindFirstFile(sBuildPath & "*", FolderData) 'Get folder name
       IF hFile <> %INVALID_HANDLE_VALUE THEN 'If valid folder name
          DO 'Start FindNextFile loop
            SHGetFileInfo(sBuildPath & FolderData.cFileName, 0, FileInfo, LEN(FileInfo), %SHGFI_DISPLAYNAME) 'Get DisplayName for this folder
            IF LCASE$(PARSE$(sDisplayName, "\", Looper)) = LCASE$(FileInfo.szDisplayName) THEN 'Is this part of sDisplayName equal to the DisplayName of the folder?
              sBuildPath = sBuildPath & FolderData.cFileName & "\" 'Build a string with folder name
              FindClose(hFile) 'Job is done for this folder
              ITERATE FOR 'Do next folder
            END IF
          LOOP WHILE FindNextFile(hFile, FolderData) 'Get next folder
          FindClose(hFile) 'Clean up
       END IF
     NEXT
   END IF

   FUNCTION = sBuildPath 'Let function return result

END IF

END FUNCTION
'______________________________________________________________________________

FUNCTION PBMAIN() AS LONG
LOCAL sUserName    AS STRING
LOCAL sPath        AS STRING
LOCAL sDisplayName AS STRING
LOCAL UserNameLen  AS LONG

UserNameLen = %UNLEN
sUserName = NUL$(UserNameLen) 'Init the string so it is big enough
GetUserName(BYVAL STRPTR(sUserName), UserNameLen)'Get Windows logged user name
sUserName = LEFT$(sUserName, UserNameLen - 1) 'Remove last $NUL

sPath = "C:\Users\" & sUserName & "\Favorites\" 'Build a folder name

sDisplayName = GetDisplayName(sPath) 'Get display name
MessageBox(%HWND_DESKTOP, sPath & $CRLF  & $CRLF & "Convert path above to DisplayName:" & _
                           $CRLF & $CRLF &  sDisplayName, "PathName to DisplayName", %MB_OK)

sPath = GetPathName(sDisplayName) 'Convert display name to path name
MessageBox(%HWND_DESKTOP, sDisplayName & $CRLF & $CRLF & "Convert DisplayName above to path:" & _
                           $CRLF & $CRLF & sPath, "DisplayName to PathName", %MB_OK)

END FUNCTION
'______________________________________________________________________________
'

[Added comments and did some minors corrections]

Olav Bergesen

Hi,

Very nice. Looks like I can implement your suggestion. Many thanks!

And yes, there is a SHGetFileinfo under the %TVN_GetDispInfo event. I'll have a closer look at that
one.
--
Regards,

Olav Bergesen