With a few extra minutes on my hands, I've looked at a few
examples on this thumbnail shell stuff and found them a bit
overwhelming for what I need. Not wanting to implement
every little nuance of the Shell API, I've somewhat shortened
the code, became brain dead and am left with this ERROR:
Attempted to read or write protected memory. This is often an
indication that other memory is corrupt.
Just wondering if anybody can see the problem???? I don't think
this happened with that VBaccelerator C# code. Here's the VB code
I'm using. Thanks.
======= Windows Form with Button and PictureBox
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim img As Image = ThumOne.CADImage("c:\temp\tryme.dwg")
If Not img Is Nothing Then
PictureBox1.Image = img
End If
End Sub
======= ThumOne Class
Imports System
Imports System.Text
Imports System.Runtime.InteropServices
Public Class ThumOne
Public Structure SIZE
Public wide As Integer
Public tall As Integer
End Structure
<GuidAttribute("BB2E617C-0920-11d1-9A0B-00C04FC2D6C1"), _
InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)> _
Public Interface IExtractImage
Sub GetLocation(ByVal pszPathBuffer As IntPtr, ByVal cch As Integer, ByRef pdwPriority As Integer, ByRef prgSize As SIZE, ByVal dwRecClrDepth As Integer, ByRef pdwFlags As Integer)
Sub Extract(ByRef phBmpThumbnail As IntPtr)
End Interface
<GuidAttribute("000214E6-0000-0000-C000-000000000046"), _
InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)> _
Public Interface IShellFolder
Sub ParseDisplayName(ByVal hWnd As IntPtr, ByVal pbc As IntPtr, ByVal pszDisplayName As String, ByRef pchEaten As Integer, ByRef ppidl As System.IntPtr, ByRef pdwAttributes As Integer)
Sub EnumObjects(ByVal hwndOwner As IntPtr, <MarshalAs(UnmanagedType.U4)> ByVal grfFlags As Integer, <Out()> ByRef ppenumIDList As IntPtr)
Sub BindToObject(ByVal pidl As IntPtr, ByVal pbcReserved As IntPtr, ByRef riid As Guid, ByRef ppvOut As IShellFolder)
Sub BindToStorage(ByVal pidl As IntPtr, ByVal pbcReserved As IntPtr, ByRef riid As Guid, <Out()> ByVal ppvObj As IntPtr)
<PreserveSig()> _
Function CompareIDs(ByVal lParam As IntPtr, ByVal pidl1 As IntPtr, ByVal pidl2 As IntPtr) As Integer
Sub CreateViewObject(ByVal hwndOwner As IntPtr, ByRef riid As Guid, ByVal ppvOut As Object)
Sub GetAttributesOf(ByVal cidl As Integer, ByVal apidl As IntPtr, <MarshalAs(UnmanagedType.U4)> ByRef rgfInOut As Integer)
Sub GetUIObjectOf(ByVal hwndOwner As IntPtr, ByVal cidl As Integer, ByRef apidl As IntPtr, ByRef riid As Guid, <Out()> ByVal prgfInOut As Integer, <Out(), MarshalAs(UnmanagedType.IUnknown)> ByRef ppvOut As Object)
End Interface
<DllImport("shell32.dll", CharSet:=CharSet.Auto)> _
Public Shared Function SHGetDesktopFolder(<Out()> ByRef ppshf As IShellFolder) As Integer
End Function
Public Shared Function CADImage(ByVal cadFileName As String) As Image
Dim DirShell = New Guid("000214E6-0000-0000-C000-000000000046")
Dim FileShell = New Guid("BB2E617C-0920-11d1-9A0B-00C04FC2D6C1")
Dim cadDir As IShellFolder = Nothing
Dim dwgFile As IShellFolder = Nothing
Dim xImg As IExtractImage = Nothing
Dim pidl As IntPtr
Dim filePidl As IntPtr
Dim NameDir = IO.Path.GetDirectoryName(cadFileName)
Dim CADName = IO.Path.GetFileName(cadFileName)
Dim img As IntPtr
Dim imgLoc As IntPtr
Dim size As SIZE
size.wide = 100
size.tall = 75
SHGetDesktopFolder(cadDir)
cadDir.ParseDisplayName(IntPtr.Zero, IntPtr.Zero, NameDir, 0, pidl, 0)
cadDir.BindToObject(pidl, IntPtr.Zero, DirShell, dwgFile)
dwgFile.ParseDisplayName(IntPtr.Zero, IntPtr.Zero, CADName, 0, filePidl, 0)
dwgFile.GetUIObjectOf(IntPtr.Zero, 1, filePidl, FileShell, 0, xImg)
imgLoc = Marshal.AllocHGlobal(0)
xImg.GetLocation(imgLoc, 260, 0, size, 2, 0)
xImg.Extract(img)
Try
CADImage = Image.FromHbitmap(img)
Catch
CADImage = Nothing
Finally
Marshal.FreeHGlobal(imgLoc)
Marshal.FreeCoTaskMem(pidl)
Marshal.FreeCoTaskMem(filePidl)
End Try
End Function
End Class