Re: using structs like BROWSEINFO and OPENFILENAME (string members)



I dug this up. It hasn't been used in ages, but I believe it is still
valid. Does this look like your code that works?

Private Type BROWSEINFO
hOwner As Long
pidlRoot As Long
pszDisplayName As String
lpszTitle As String
ulFlags As Long
lpfn As Long
lParam As Long
iImage As Long
End Type


Dim BI As BROWSEINFO
Dim pidl As Long
Dim lpSelPath As Long
Dim sPath As String * MAX_PATH

With BI
.hOwner = frmMain.hwnd
.pidlRoot = 0
.lpszTitle = strTitle
.lpfn = FARPROC(AddressOf BrowseCallbackProcStr)
.ulFlags = BIF_USENEWUI Or BIF_RETURNONLYFSDIRS
lpSelPath = LocalAlloc(LPTR, Len(sSelPath) + 1)
CopyMemory ByVal lpSelPath, ByVal sSelPath, Len(sSelPath) + 1
.lParam = lpSelPath
End With

pidl = SHBrowseForFolder(BI)

If pidl Then

If SHGetPathFromIDList(pidl, sPath) Then
BrowseForFolderByPath = Left(sPath, InStr(sPath, vbNullChar) - 1)
End If

Call CoTaskMemFree(pidl)

End If

Call LocalFree(lpSelPath)


"nebbish" <nebbish@xxxxxxxxxxxxxxxxxxxxxxxxx> wrote in message
news:F9610152-553C-4D43-97D1-95A167F2B9BE@xxxxxxxxxxxxxxxx
>I am trying to use BROWSEINFO for SHBrowseForFolder. I would like to have
> *all* my API declarations/definitions to come out of my typelibrary - but
> i'm
> having trouble with the string members of the struct. my typelibrary
> definition is this:
>
> typedef struct BROWSEINFO {
> HWND hwndOwner;
> LPCITEMIDLIST pidlRoot;
> PTR /* LPCTSTR */ lpszTitle; // text to go in the banner over the tree.
> PTR /* LPTSTR */ pszDisplayName;// Return display name of item
> selected.
> UINT ulFlags; // Flags that control the return stuff
> BFFCALLBACK lpfn;
> LONG lParam; // extra info that's passed back in
> callbacks
> int iImage; // output var: where to return the Image
> index.
> } BROWSEINFO, *PBROWSEINFO, *LPBROWSEINFO;
>
> ...notice the data type change for the two string members. my vb code
> that
> uses the title member looks like this: (oTitle is string variable,
> lpTitle
> is long variable)
>
> lpTitle = LocalAlloc(LPTR, Len(oTitle) + 1)
> CopyMemory ByVal lpTitle, ByVal oTitle, Len(oTitle) + 1
> .lpszTitle = lpTitle
>
> (side note: notice the wierdness of "ByVal oTitle". i have inspected the
> memory at lpTitle and the data is ansi, so somehow vb figured out to use
> StrPtr, followed by StrConvert without me having to write it all out)
>
> this technique works great for the '.lParam' member which is used in my
> callback to set the initial selection. (again oStartPath is string, and
> lpPath is long)
>
> lpPath = LocalAlloc(LPTR, Len(oStartPath) + 1)
> CopyMemory ByVal lpRetPath, ByVal oStartPath, Len(oStartPath) +
> 1
> .lParam = lpPath
>
>
> i have no idea why '.lParam' works but '.lpszTitle' does not. the
> '.lParam'
> is returned to me in my callback and the memory address is unchanged, and
> the
> string still resides at that memory location. but i turn around and pass
> the
> pointer right back into the API with a SendMessage using BFFM_SETSELECTION
> and it works!
>
> i even tried some other memory allocation api funcs like GlobalAlloc and
> CoTaskMemAlloc. still no joy. (i think they all use the same heap
> anyway -
> i'm 70% confident about that)
>
> i have also defined the BROWSEINFO struct within the vb module and locally
> (re)declared the SHBrowseForFolder function ('re' because it is still
> defined
> in the typelib) to use the locally defined UDT.......then everything works
> fine. but even using this code i still have to use the LocalAlloc &
> CopyMemory technique for '.lParam' and it works also. *but* this requires
> api declarations which i am trying to eliminate by using the typelibrary.
>
> so does anybody know a way to manually allocate memory, copy in a string
> (in
> ANSI) and pass it in as the title. i am intensly curious about the
> details
> of passing memory pointers back and forth between VB & the API and why the
> two members of the struct seem to behave differently.
>
> thanks for reading this far, i know its a little long-winded, and thanks
> again for any thoughts/ideas/outright-answers.
>
> -nebbish
>


.



Relevant Pages

  • Re: weird problem
    ... Obviously plus a few missing members like prev, ... 'tmp' has for a relation to it - 'tmp' could point to an element ... it fails to obtain as much memory as requested. ... print out a human-readable string for what errno is set to. ...
    (comp.lang.c)
  • Re: GC with lots of small ones
    ... and other objects are members in long existing containers most of my points ... It eats too much memory - log files exceeding 100MB ... and that object (in your case a string) will ...
    (microsoft.public.dotnet.general)
  • Re: Fast string operations
    ... Looping: I thought looping over arrays in managed code was "slow" ... array handling and such. ... The problem with TrimHelper is that it always returns a new string instance. ... The customer perceives this as a memory leak. ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: Discovering variable types...
    ... >- but I suppose MS expect us to use wrappers ... memory allocations for your variables from disk as well. ... >They most certainly are of fixed size, changing the size of a String ... >>me to keep buffer size and current postion right in the memory block. ...
    (comp.lang.pascal.delphi.misc)
  • Re: Optimize
    ... if you use it like me to get 'the next string ptr' in addition. ... | |mov ebx eax;dw aligned strings are faster ... | Would it be enough to touch each 16th bytes in the 64K memory area ... Cache-line size is fixed, my AMD got 64 bytes per line. ...
    (alt.lang.asm)

Quantcast