At 05:04 AM 21-05-01 -0700, Helio S. Junior wrote: >I would like to know how to use win32 functions which take structures as >their parameter. >For example, the API 'SHBrowseForFolder' take the following structure: > >typedef struct _browseinfo { > HWND hwndOwner; > LPCITEMIDLIST pidlRoot; > LPTSTR pszDisplayName; > LPCTSTR lpszTitle; > UINT ulFlags; > BFFCALLBACK lpfn; > LPARAM lParam; > int iImage; >}; > >How do i 'translate' this structure and use this function with Win32::API >module? First thing, I'm glad there's someone else out there using Win32::API. 1. decide what type of items you are dealing with and pack() them: >typedef struct _browseinfo { > HWND hwndOwner; > LPCITEMIDLIST pidlRoot; > LPTSTR pszDisplayName; > LPCTSTR lpszTitle; > UINT ulFlags; > BFFCALLBACK lpfn; > LPARAM lParam; > int iImage; >}; You've got the following (L = 32-bit integer (long or int), P = char pointer): LLPPLLLL 2. Get function pointers using WIN32::API->new my $SHBrowseForFolder = new Win32::API("shell32", "SHBrowseForFolder", ["P"], "L"); etc 3. Call the functions. Code is attached Joe Yates
#!perl use strict; use WIN32::API; my $SHBrowseForFolder = new Win32::API("shell32", "SHBrowseForFolder", ["P"], "L"); my $SHGetPathFromIDList = new Win32::API("shell32", "SHGetPathFromIDList", ["LP"], "L"); if($SHBrowseForFolder == 0) { print "Failed to initialise function SHBrowseForFolder().\r\n"; } if($SHGetPathFromIDList == 0) { print "Failed to initialise function SHGetPathFromIDList().\r\n"; } my $sFolder = ChooseFolder(); print "Folder: $sFolder\r\n"; exit 1; =pod typedef struct _browseinfo { HWND hwndOwner; LPCITEMIDLIST pidlRoot; LPTSTR pszDisplayName; LPCTSTR lpszTitle; UINT ulFlags; BFFCALLBACK lpfn; LPARAM lParam; int iImage; } BROWSEINFO; =cut my $BIF_RETURNONLYFSDIRS = 1; my $BIF_DONTGOBELOWDOMAIN = 2; sub ChooseFolder() { my $pszDisplayName = "\0" x 0x200; my $lpszTitle = "Choose the folder\0"; my $ulFlags = $BIF_RETURNONLYFSDIRS | $BIF_DONTGOBELOWDOMAIN; # hw pi DisplayName Title Flags cb lp Im my $pbi = pack("LLPPLLLL", 0, 0, $pszDisplayName, $lpszTitle, $ulFlags, 0, 0, 0); my $lIDList = $SHBrowseForFolder->Call($pbi); if($lIDList == 0) { return ""; } my $sBuffer = "\0" x 0x200; $SHGetPathFromIDList->Call($lIDList, $sBuffer); $sBuffer =~ /\0/o; my $sPath = $`; return "$sPath"; }