convert structure to IntPtr
-
Hi, I want to use SHGetFileInfo from shell32.dll u can pass string or pidl(ITEMIDLIST structure) for first param the problem is: u can't convert string (file path) to pidl or vice versa. so I use IntPtr for first param. but the problem is I can't convert pidl to IntPtr. (the problem is the code below doesn't work I can't find out why)
public class FileFolder { [DllImport("Shell32.dll", CharSet = CharSet.Unicode)] public static extern UInt32 SHGetFileInfo(IntPtr pszPath, UInt32 dwFileAttributes, ref SHFILEINFO psfi, UInt32 cbFileInfo, UInt32 uFlags); [DllImport("Shell32.dll", CharSet = CharSet.Unicode)] public static extern Int32 SHGetSpecialFolderLocation(IntPtr hwndOwner, int nFolder, ref ITEMIDLIST ppidl); [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct SHITEMID { public UInt16 cb; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]public SByte[] abID; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct ITEMIDLIST { public SHITEMID mkid; } } uint flag = FileFolder.C_GetFileInfoFlagt.SHGFI_PIDL| FileFolder.C_GetFileInfoFlagt.SHGFI_ICON | FileFolder.C_GetFileInfoFlagt.SHGFI_SHELLICONSIZE | FileFolder.C_GetFileInfoFlagt.SHGFI_ATTRIBUTES | FileFolder.C_GetFileInfoFlagt.SHGFI_TYPENAME; FileFolder.ITEMIDLIST pidl = new FileFolder.ITEMIDLIST(); if (FileFolder.SHGetSpecialFolderLocation(IntPtr.Zero, (int)0x0003, ref pidl) == 0) { MessageBox.Show("true"); } IntPtr pnt = Marshal.AllocHGlobal(Marshal.SizeOf(pidl)); Marshal.StructureToPtr(pidl, pnt, true); if (FileFolder.SHGetFileInfo(pnt, 256, ref info, (uint)Marshal.SizeOf(info), flag) > 0) { MessageBox.Show("Successfull"); }
-
Hi, I want to use SHGetFileInfo from shell32.dll u can pass string or pidl(ITEMIDLIST structure) for first param the problem is: u can't convert string (file path) to pidl or vice versa. so I use IntPtr for first param. but the problem is I can't convert pidl to IntPtr. (the problem is the code below doesn't work I can't find out why)
public class FileFolder { [DllImport("Shell32.dll", CharSet = CharSet.Unicode)] public static extern UInt32 SHGetFileInfo(IntPtr pszPath, UInt32 dwFileAttributes, ref SHFILEINFO psfi, UInt32 cbFileInfo, UInt32 uFlags); [DllImport("Shell32.dll", CharSet = CharSet.Unicode)] public static extern Int32 SHGetSpecialFolderLocation(IntPtr hwndOwner, int nFolder, ref ITEMIDLIST ppidl); [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct SHITEMID { public UInt16 cb; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]public SByte[] abID; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct ITEMIDLIST { public SHITEMID mkid; } } uint flag = FileFolder.C_GetFileInfoFlagt.SHGFI_PIDL| FileFolder.C_GetFileInfoFlagt.SHGFI_ICON | FileFolder.C_GetFileInfoFlagt.SHGFI_SHELLICONSIZE | FileFolder.C_GetFileInfoFlagt.SHGFI_ATTRIBUTES | FileFolder.C_GetFileInfoFlagt.SHGFI_TYPENAME; FileFolder.ITEMIDLIST pidl = new FileFolder.ITEMIDLIST(); if (FileFolder.SHGetSpecialFolderLocation(IntPtr.Zero, (int)0x0003, ref pidl) == 0) { MessageBox.Show("true"); } IntPtr pnt = Marshal.AllocHGlobal(Marshal.SizeOf(pidl)); Marshal.StructureToPtr(pidl, pnt, true); if (FileFolder.SHGetFileInfo(pnt, 256, ref info, (uint)Marshal.SizeOf(info), flag) > 0) { MessageBox.Show("Successfull"); }
Wow! it sometimes works ! a few times it is failed. I can not find out why! plz help!
-
Hi, I want to use SHGetFileInfo from shell32.dll u can pass string or pidl(ITEMIDLIST structure) for first param the problem is: u can't convert string (file path) to pidl or vice versa. so I use IntPtr for first param. but the problem is I can't convert pidl to IntPtr. (the problem is the code below doesn't work I can't find out why)
public class FileFolder { [DllImport("Shell32.dll", CharSet = CharSet.Unicode)] public static extern UInt32 SHGetFileInfo(IntPtr pszPath, UInt32 dwFileAttributes, ref SHFILEINFO psfi, UInt32 cbFileInfo, UInt32 uFlags); [DllImport("Shell32.dll", CharSet = CharSet.Unicode)] public static extern Int32 SHGetSpecialFolderLocation(IntPtr hwndOwner, int nFolder, ref ITEMIDLIST ppidl); [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct SHITEMID { public UInt16 cb; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]public SByte[] abID; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct ITEMIDLIST { public SHITEMID mkid; } } uint flag = FileFolder.C_GetFileInfoFlagt.SHGFI_PIDL| FileFolder.C_GetFileInfoFlagt.SHGFI_ICON | FileFolder.C_GetFileInfoFlagt.SHGFI_SHELLICONSIZE | FileFolder.C_GetFileInfoFlagt.SHGFI_ATTRIBUTES | FileFolder.C_GetFileInfoFlagt.SHGFI_TYPENAME; FileFolder.ITEMIDLIST pidl = new FileFolder.ITEMIDLIST(); if (FileFolder.SHGetSpecialFolderLocation(IntPtr.Zero, (int)0x0003, ref pidl) == 0) { MessageBox.Show("true"); } IntPtr pnt = Marshal.AllocHGlobal(Marshal.SizeOf(pidl)); Marshal.StructureToPtr(pidl, pnt, true); if (FileFolder.SHGetFileInfo(pnt, 256, ref info, (uint)Marshal.SizeOf(info), flag) > 0) { MessageBox.Show("Successfull"); }
-
No, It doesn't help. because it assumes just file system paths not pidl!. you can not convert every pidl to string.
-
No, It doesn't help. because it assumes just file system paths not pidl!. you can not convert every pidl to string.
-
thanks, I see the code but I can't find out why my code doesn't work properly. my code is like the code in the page that you mention. (the caller is not presented in the page just callee is presented)
modified on Friday, March 7, 2008 5:01 AM
-
thanks, I see the code but I can't find out why my code doesn't work properly. my code is like the code in the page that you mention. (the caller is not presented in the page just callee is presented)
modified on Friday, March 7, 2008 5:01 AM
Hello Amirreza_nl, I wrote the code that was alluded to earlier in this thread (from CodeGator.com). You are correct that your code is similar to mine, however I am calling a slightly different method to get the path from the PIDL. In my case I am using the SHGetPathFromIDList function. Also, my code doesn't convert from the InPtr to a ITEMIDLIST structure. I am able to deal with PIDL's as IntPtr objects instead of converting them to ITEMIDLIST structures. (See my code here) You don't say which call is failing in your code, is it SHGetSpecialFolderLocation or SHGetFileInfo? My suggestion would be to try omiting the conversion of the PIDL to a struct if possible. I hope I have helped, Martin
Martin Cook Jesus answered, "I am the way and the truth and the life. No one comes to the Father except through me." John 14:6
-
Hello Amirreza_nl, I wrote the code that was alluded to earlier in this thread (from CodeGator.com). You are correct that your code is similar to mine, however I am calling a slightly different method to get the path from the PIDL. In my case I am using the SHGetPathFromIDList function. Also, my code doesn't convert from the InPtr to a ITEMIDLIST structure. I am able to deal with PIDL's as IntPtr objects instead of converting them to ITEMIDLIST structures. (See my code here) You don't say which call is failing in your code, is it SHGetSpecialFolderLocation or SHGetFileInfo? My suggestion would be to try omiting the conversion of the PIDL to a struct if possible. I hope I have helped, Martin
Martin Cook Jesus answered, "I am the way and the truth and the life. No one comes to the Father except through me." John 14:6
Hi, first of all, thanks for ur reply. I think SHGetFileInfo doesn't work well. because the first call's return value is ok. but SHGetFileInfo's return value sometimes is not ok. I run the code 2 or 3 times then it works well and show control panel's (or something else) attributes correctly! I don't know why! SHGetPathFromIDList doesn't work at all with something like control panel (I think). we can use it when pidl is controled by file system(file or folder that is stored physically in a hard disk). so I can not use it for my app.
typedef struct _SHITEMID { USHORT cb; BYTE abID[1]; } SHITEMID;
I wrote this in C#:[StructLayout(LayoutKind.Sequential, Pack = 1)] public struct SHITEMID { public UInt16 cb; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]public SByte[] abID; }
thentypedef struct _ITEMIDLIST { SHITEMID mkid; } ITEMIDLIST;
in C#:[StructLayout(LayoutKind.Sequential, Pack = 1)] public struct ITEMIDLIST { public SHITEMID mkid; }
-
Hi, I want to use SHGetFileInfo from shell32.dll u can pass string or pidl(ITEMIDLIST structure) for first param the problem is: u can't convert string (file path) to pidl or vice versa. so I use IntPtr for first param. but the problem is I can't convert pidl to IntPtr. (the problem is the code below doesn't work I can't find out why)
public class FileFolder { [DllImport("Shell32.dll", CharSet = CharSet.Unicode)] public static extern UInt32 SHGetFileInfo(IntPtr pszPath, UInt32 dwFileAttributes, ref SHFILEINFO psfi, UInt32 cbFileInfo, UInt32 uFlags); [DllImport("Shell32.dll", CharSet = CharSet.Unicode)] public static extern Int32 SHGetSpecialFolderLocation(IntPtr hwndOwner, int nFolder, ref ITEMIDLIST ppidl); [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct SHITEMID { public UInt16 cb; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]public SByte[] abID; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct ITEMIDLIST { public SHITEMID mkid; } } uint flag = FileFolder.C_GetFileInfoFlagt.SHGFI_PIDL| FileFolder.C_GetFileInfoFlagt.SHGFI_ICON | FileFolder.C_GetFileInfoFlagt.SHGFI_SHELLICONSIZE | FileFolder.C_GetFileInfoFlagt.SHGFI_ATTRIBUTES | FileFolder.C_GetFileInfoFlagt.SHGFI_TYPENAME; FileFolder.ITEMIDLIST pidl = new FileFolder.ITEMIDLIST(); if (FileFolder.SHGetSpecialFolderLocation(IntPtr.Zero, (int)0x0003, ref pidl) == 0) { MessageBox.Show("true"); } IntPtr pnt = Marshal.AllocHGlobal(Marshal.SizeOf(pidl)); Marshal.StructureToPtr(pidl, pnt, true); if (FileFolder.SHGetFileInfo(pnt, 256, ref info, (uint)Marshal.SizeOf(info), flag) > 0) { MessageBox.Show("Successfull"); }
oh, I think I find the bug in my code! I write: [StructLayout(LayoutKind.Sequential, Pack = 1)] but I must write: [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Pack = 1)] instead. I use unicode charset for my all methode definitions. But I wonder why this makes a problem! we have two types of pidl!? on for ansi one for unicode!? why? in pidl address we have string!??