Author Topic: DWG 2013 thumbnail onto Access form  (Read 8928 times)

0 Members and 1 Guest are viewing this topic.

jerrywilson

  • Guest
DWG 2013 thumbnail onto Access form
« on: October 24, 2013, 10:22:42 AM »
I have an Access database that is used for version control of AutoCad designs. It currently uses an Activex control, DWGThumbnail.ocx, to display the .bmp thumbnail contained in the DWG file.

As the thumbnail file type has changed in the 2013 DWG file to a .png that activex control dosen't work with these files.

I've looked for an updated version of the activex control but it appears that there isn't one that will work with the new format DWG files.

I've seen a couple of posts here and in  .net VB that have some code that may offer a solution but I am having some difficulty integrating the code into my database (bit of a newby when it comes to VBA).

http://www.theswamp.org/index.php?topic=30985.0

http://www.theswamp.org/index.php?topic=39428.msg446925#msg446925

Can anyone help? Has anyone already resolved this issue (or similar).

Many thanks, Jerry Wilson 

Matt__W

  • Seagull
  • Posts: 12955
  • I like my water diluted.
Re: DWG 2013 thumbnail onto Access form
« Reply #1 on: October 24, 2013, 10:42:27 AM »
I have some code that will show a preview without the OCX.  Let me dig it up and I'll post a sample project.
Autodesk Expert Elite
Revit Subject Matter Expert (SME)
Owner/FAA sUAS Pilot @ http://skyviz.io

Matt__W

  • Seagull
  • Posts: 12955
  • I like my water diluted.
Re: DWG 2013 thumbnail onto Access form
« Reply #2 on: October 24, 2013, 10:54:24 AM »
Nevermind.  I thought I tested the old code on a newer drawing.  Turns out it was a 2010 DWG so it doesn't work.  Sorry.
Autodesk Expert Elite
Revit Subject Matter Expert (SME)
Owner/FAA sUAS Pilot @ http://skyviz.io

jerrywilson

  • Guest
Re: DWG 2013 thumbnail onto Access form
« Reply #3 on: October 24, 2013, 11:04:30 AM »
Thanks M@yhem.

It might be a start though.

I still need to be able to view the .bmp thumbnails from older designs. Then I would have to come up with a method of dealing with the newer files.  I've seen some code in .Net Vb that may be able to handle the .png files... perhaps I can use the same method but recode it in VBa 



Matt__W

  • Seagull
  • Posts: 12955
  • I like my water diluted.
Re: DWG 2013 thumbnail onto Access form
« Reply #4 on: October 24, 2013, 11:26:08 AM »
Here's the stripped down code to show a preview without an OCX.
Autodesk Expert Elite
Revit Subject Matter Expert (SME)
Owner/FAA sUAS Pilot @ http://skyviz.io

jerrywilson

  • Guest
Re: DWG 2013 thumbnail onto Access form
« Reply #5 on: October 25, 2013, 04:06:40 AM »
Thanks M@yhem.

I was hoping for the VBa code that I could use in our Access database.

Currently we use the activex control to display the thumbnail on a Access form. The hope is that I can replace this activex control and use some VBa code to display the old DWG thumbnails as well as (hopefully) the new format DWG thumnails.   

The Access database is used outside of AutoCad (other than the Launch Autocad button), so I can't use the .dvb file for this.

Cheers for the help though  :-)

Matt__W

  • Seagull
  • Posts: 12955
  • I like my water diluted.
Re: DWG 2013 thumbnail onto Access form
« Reply #6 on: October 25, 2013, 07:59:45 AM »
Why can't you use the code I posted?  It's not referencing an OCX.  It uses a frame and an image.  And actually, I don't believe the frame is even needed.  I think it's just used for a dropped shadow effect.
Autodesk Expert Elite
Revit Subject Matter Expert (SME)
Owner/FAA sUAS Pilot @ http://skyviz.io

jerrywilson

  • Guest
Re: DWG 2013 thumbnail onto Access form
« Reply #7 on: October 25, 2013, 08:51:19 AM »
I don't know how to use this file. I've unzipped it using 7zip and opened the files in notepad++ but I don't see any code.

Forgive my ignorance, but how do I use this in MS VB for applications?

Matt__W

  • Seagull
  • Posts: 12955
  • I like my water diluted.
Re: DWG 2013 thumbnail onto Access form
« Reply #8 on: October 25, 2013, 08:56:18 AM »
Here's the code and a screen shot of the form.  The form consists of a frame, the image control and a command button.  The DWG preview is painted onto the image control.  I'm able to run this code on Windows 7 from AutoCAD MEP 2011.

Code - Visual Basic: [Select]
  1. Option Explicit
  2.  
  3. Private Declare Function GetDC Lib "user32" (ByVal hwnd As Long) As Long
  4. Private Declare Function SetPixel Lib "gdi32" (ByVal hdc As Long, ByVal X As Long, ByVal Y As Long, ByVal crColor As Long) As Long
  5. Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
  6. Private Declare Function SetRect Lib "user32" (lpRect As RECT, ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long
  7. Private Declare Function DrawEdge Lib "user32" (ByVal hdc As Long, qrc As RECT, ByVal edge As Long, ByVal grfFlags As Long) As Long
  8. Private Declare Function ReleaseDC Lib "user32" (ByVal hwnd As Long, ByVal hdc As Long) As Long
  9.  
  10. Private Type BITMAPINFOHEADER
  11.     biSize As Long
  12.     biWidth As Long
  13.     biHeight As Long
  14.     biPlanes As Integer
  15.     biBitCount As Integer
  16.     biCompression As Long
  17.     biSizeImage As Long
  18.     biXPelsPerMeter As Long
  19.     biYPelsPerMeter As Long
  20.     biClrUsed As Long
  21.     biClrImportant As Long
  22. End Type
  23.  
  24.  
  25. Private Type RGBQUAD
  26.     rgbBlue As Byte
  27.     rgbGreen As Byte
  28.     rgbRed As Byte
  29.     rgbReserved As Byte
  30. End Type
  31.  
  32. Private Type IMGREC
  33.     bytType As Byte
  34.     lngStart As Long
  35.     lngLen As Long
  36. End Type
  37.  
  38. Private Type RECT
  39.     Left As Long
  40.     Top As Long
  41.     Right As Long
  42.     Bottom As Long
  43. End Type
  44.  
  45. Private RC As RECT
  46. Private Const BDR_SUNKENOUTER = &H2
  47. Private Const BF_BOTTOM = &H8
  48. Private Const BF_LEFT = &H1
  49. Private Const BF_RIGHT = &H4
  50. Private Const BF_TOP = &H2
  51. Private Const BF_RECT = (BF_LEFT Or BF_TOP Or BF_RIGHT Or BF_BOTTOM)
  52.  
  53. Public Function PaintPreview(strFile As String) As Integer
  54.     imgPreview.Visible = False
  55.   Dim lngSeeker As Long
  56.   Dim lngImgLoc As Long
  57.   Dim bytCnt As Byte
  58.   Dim lngFile As Long
  59.   Dim lngCurLoc As Long
  60.   Dim intCnt As Integer
  61.   Dim udtRec As IMGREC
  62.   Dim bytBMPBuff() As Byte
  63.   Dim udtColors() As RGBQUAD
  64.   Dim udtColor As RGBQUAD
  65.   Dim lngHwnd As Long
  66.   Dim lngDc As Long
  67.   Dim lngY As Long
  68.   Dim lngX As Long
  69.   Dim intRed As Integer
  70.   Dim intGreen As Integer
  71.   Dim intBlue As Integer
  72.   Dim lngColor As Long
  73.   Dim lngCnt As Long
  74.   Dim udtHeader As BITMAPINFOHEADER
  75.   On Error GoTo Err_Control
  76.   If Len(Dir(strFile)) > 0 Then
  77.     lngFile = FreeFile
  78.     Open strFile For Binary As lngFile
  79.     Seek lngFile, 14
  80.     Get lngFile, , lngImgLoc
  81.     Seek lngFile, lngImgLoc + 17
  82.     lngCurLoc = Seek(lngFile)
  83.     Seek lngFile, lngCurLoc + 4
  84.     Get lngFile, , bytCnt
  85.     If bytCnt > 1 Then
  86.       For intCnt = 1 To bytCnt
  87.         Get lngFile, , udtRec
  88.         If udtRec.bytType = 2 Then
  89.         'All of the code preceding this Line
  90.        'Is identical to the code in Part
  91.        'Two of Byte By Byte.
  92.        'Now we begin the color extraction
  93.        'The start value is the BYTE BEFORE
  94.        'The BMP Header data (The RGBQUAD
  95.        'And BMP Header are contained within
  96.        'Another structure), so move the read/
  97.        'Write marker to the next byte...
  98.          Seek lngFile, udtRec.lngStart + 1
  99.           'Pull out the BMP header data...
  100.          Get lngFile, , udtHeader
  101.           'Resize the Byte buffer to the full
  102.          'Length of the data...
  103.          ReDim bytBMPBuff(udtRec.lngLen)
  104.           'Did you read Randall's article?
  105.          If udtHeader.biBitCount = 8 Then
  106.             'Resize the array of RGBQuads, I
  107.            'Could also have used the biClrUsed
  108.            'Value of the udtHeader...
  109.            ReDim udtColors(256)
  110.             'Grab all of the color values
  111.            Get lngFile, , udtColors
  112.             'Now we grab the full record by
  113.            'Moving the Read/Write marker
  114.            'Back to the start of the data.
  115.            'Don't worry about all of the data
  116.            'We allready grabbed...
  117.            '(If you read Randall's article,
  118.            'Remember that the data is reverse
  119.            'Scan...
  120.            Seek lngFile, udtRec.lngStart
  121.             'Fill the buffer...
  122.            Get lngFile, , bytBMPBuff
  123.             'Now grab the Forms Handle
  124.            lngHwnd = FindWindow(vbNullString, Me.Caption)
  125.             'So we can get its Device Context..
  126.            lngDc = GetDC(lngHwnd)
  127.             'I thought this was a nice touch..
  128. '''            Frame2.Caption = strFile
  129.            'Clean any old paint off..
  130.            Frame1.Repaint
  131.             'Begin Painting
  132.            
  133.             For lngY = 1 To udtHeader.biHeight
  134.               For lngX = udtHeader.biWidth To _
  135.               1 Step -1
  136.                 'See, we are reading the data
  137.                'From THE END of the buffer...
  138.                lngColor = _
  139.                 bytBMPBuff((UBound(bytBMPBuff) - lngCnt))
  140.                 'Get the mapped value
  141.                udtColor = udtColors(lngColor)
  142.                 'Break it into Red
  143.                intRed = CInt(udtColor.rgbRed)
  144.                 'Green
  145.                intGreen = CInt(udtColor.rgbGreen)
  146.                 'And Blue
  147.                intBlue = CInt(udtColor.rgbBlue)
  148.                 'Get a color the API will accept
  149.                lngColor = RGB(intRed, intGreen, intBlue)
  150.                 'Paint this Pixel. The + 5 is to
  151.                'Give a little offset from the edge
  152.                'Of the form.
  153.                'But before we do, would you like
  154.                'To have Black backgrounds? Easy,
  155.                'Swap the map:
  156.                '///BLACK BACKGROUND///
  157.                If lngColor = vbBlack Then
  158.                   lngColor = vbWhite
  159.                 ElseIf lngColor = vbWhite Then
  160.                   lngColor = vbBlack
  161.                 End If
  162.                 '//////////////////////
  163.                'If your prefere White (the true Value) Then just remove that..
  164.                SetPixel lngDc, lngX + 20, lngY + 30, lngColor
  165.                 'Increment the counter...
  166.                lngCnt = lngCnt + 1
  167.               Next lngX
  168.             Next lngY
  169.             'NEW//FRAME
  170.            SetRect RC, 20, 30, udtHeader.biWidth + 20, udtHeader.biHeight + 30
  171.             DrawEdge lngDc, RC, BDR_SUNKENOUTER, BF_RECT
  172.           End If
  173.           Exit For
  174.         ElseIf udtRec.bytType = 3 Then
  175.           'Its a Meta File!
  176.          Exit For
  177.         End If
  178.       Next intCnt
  179.     Else
  180.       'Print Message - No Preview
  181.    End If
  182.     'Close the file
  183.    Close lngFile
  184.     'Return the value
  185.  End If
  186.   ReleaseDC lngHwnd, lngDc
  187.   'General Error control
  188. Exit_Here:
  189.   Exit Function
  190. Err_Control:
  191.   Select Case Err.Number
  192.   'Add your Case selections here
  193.    Case Else
  194.     MsgBox Err.Description
  195.     Resume Exit_Here
  196.   End Select
  197. End Function
  198.  
  199. Private Sub CommandButton1_Click()
  200.     PaintPreview "e:\temp\test.dwg"
  201. End Sub
Autodesk Expert Elite
Revit Subject Matter Expert (SME)
Owner/FAA sUAS Pilot @ http://skyviz.io

jerrywilson

  • Guest
Re: DWG 2013 thumbnail onto Access form
« Reply #9 on: October 25, 2013, 09:18:32 AM »
Cheers M@yhem, that looks interesting.

I'll load it up and see how I get on. Nice one!

Matt__W

  • Seagull
  • Posts: 12955
  • I like my water diluted.
Re: DWG 2013 thumbnail onto Access form
« Reply #10 on: October 25, 2013, 09:23:54 AM »
Let me know if you have any other questions.  I don't know much about Access but I'll help where I can.
Autodesk Expert Elite
Revit Subject Matter Expert (SME)
Owner/FAA sUAS Pilot @ http://skyviz.io

jerrywilson

  • Guest
Re: DWG 2013 thumbnail onto Access form
« Reply #11 on: October 25, 2013, 09:33:20 AM »
Yes, I can't seem to copy the code without loosing the formatting.

Any chance you could put it in a text file and attach it?

Cheers

Matt__W

  • Seagull
  • Posts: 12955
  • I like my water diluted.
Re: DWG 2013 thumbnail onto Access form
« Reply #12 on: October 25, 2013, 09:38:10 AM »
Try this instead.

Quote
Option Explicit

Private Declare Function GetDC Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function SetPixel Lib "gdi32" (ByVal hdc As Long, ByVal X As Long, ByVal Y As Long, ByVal crColor As Long) As Long
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function SetRect Lib "user32" (lpRect As RECT, ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long
Private Declare Function DrawEdge Lib "user32" (ByVal hdc As Long, qrc As RECT, ByVal edge As Long, ByVal grfFlags As Long) As Long
Private Declare Function ReleaseDC Lib "user32" (ByVal hwnd As Long, ByVal hdc As Long) As Long

Private Type BITMAPINFOHEADER
    biSize As Long
    biWidth As Long
    biHeight As Long
    biPlanes As Integer
    biBitCount As Integer
    biCompression As Long
    biSizeImage As Long
    biXPelsPerMeter As Long
    biYPelsPerMeter As Long
    biClrUsed As Long
    biClrImportant As Long
End Type


Private Type RGBQUAD
    rgbBlue As Byte
    rgbGreen As Byte
    rgbRed As Byte
    rgbReserved As Byte
End Type

Private Type IMGREC
    bytType As Byte
    lngStart As Long
    lngLen As Long
End Type

Private Type RECT
    Left As Long
    Top As Long
    Right As Long
    Bottom As Long
End Type

Private RC As RECT
Private Const BDR_SUNKENOUTER = &H2
Private Const BF_BOTTOM = &H8
Private Const BF_LEFT = &H1
Private Const BF_RIGHT = &H4
Private Const BF_TOP = &H2
Private Const BF_RECT = (BF_LEFT Or BF_TOP Or BF_RIGHT Or BF_BOTTOM)

Public Function PaintPreview(strFile As String) As Integer
    imgPreview.Visible = False
  Dim lngSeeker As Long
  Dim lngImgLoc As Long
  Dim bytCnt As Byte
  Dim lngFile As Long
  Dim lngCurLoc As Long
  Dim intCnt As Integer
  Dim udtRec As IMGREC
  Dim bytBMPBuff() As Byte
  Dim udtColors() As RGBQUAD
  Dim udtColor As RGBQUAD
  Dim lngHwnd As Long
  Dim lngDc As Long
  Dim lngY As Long
  Dim lngX As Long
  Dim intRed As Integer
  Dim intGreen As Integer
  Dim intBlue As Integer
  Dim lngColor As Long
  Dim lngCnt As Long
  Dim udtHeader As BITMAPINFOHEADER
  On Error GoTo Err_Control
  If Len(Dir(strFile)) > 0 Then
    lngFile = FreeFile
    Open strFile For Binary As lngFile
    Seek lngFile, 14
    Get lngFile, , lngImgLoc
    Seek lngFile, lngImgLoc + 17
    lngCurLoc = Seek(lngFile)
    Seek lngFile, lngCurLoc + 4
    Get lngFile, , bytCnt
    If bytCnt > 1 Then
      For intCnt = 1 To bytCnt
        Get lngFile, , udtRec
        If udtRec.bytType = 2 Then
        'All of the code preceding this Line
        'Is identical to the code in Part
        'Two of Byte By Byte.
        'Now we begin the color extraction
        'The start value is the BYTE BEFORE
        'The BMP Header data (The RGBQUAD
        'And BMP Header are contained within
        'Another structure), so move the read/
        'Write marker to the next byte...
          Seek lngFile, udtRec.lngStart + 1
          'Pull out the BMP header data...
          Get lngFile, , udtHeader
          'Resize the Byte buffer to the full
          'Length of the data...
          ReDim bytBMPBuff(udtRec.lngLen)
          'Did you read Randall's article?
          If udtHeader.biBitCount = 8 Then
            'Resize the array of RGBQuads, I
            'Could also have used the biClrUsed
            'Value of the udtHeader...
            ReDim udtColors(256)
            'Grab all of the color values
            Get lngFile, , udtColors
            'Now we grab the full record by
            'Moving the Read/Write marker
            'Back to the start of the data.
            'Don't worry about all of the data
            'We allready grabbed...
            '(If you read Randall's article,
            'Remember that the data is reverse
            'Scan...
            Seek lngFile, udtRec.lngStart
            'Fill the buffer...
            Get lngFile, , bytBMPBuff
            'Now grab the Forms Handle
            lngHwnd = FindWindow(vbNullString, Me.Caption)
            'So we can get its Device Context..
            lngDc = GetDC(lngHwnd)
            'I thought this was a nice touch..
'''            Frame2.Caption = strFile
            'Clean any old paint off..
            Frame1.Repaint
            'Begin Painting
           
            For lngY = 1 To udtHeader.biHeight
              For lngX = udtHeader.biWidth To _
              1 Step -1
                'See, we are reading the data
                'From THE END of the buffer...
                lngColor = _
                bytBMPBuff((UBound(bytBMPBuff) - lngCnt))
                'Get the mapped value
                udtColor = udtColors(lngColor)
                'Break it into Red
                intRed = CInt(udtColor.rgbRed)
                'Green
                intGreen = CInt(udtColor.rgbGreen)
                'And Blue
                intBlue = CInt(udtColor.rgbBlue)
                'Get a color the API will accept
                lngColor = RGB(intRed, intGreen, intBlue)
                'Paint this Pixel. The + 5 is to
                'Give a little offset from the edge
                'Of the form.
                'But before we do, would you like
                'To have Black backgrounds? Easy,
                'Swap the map:
                '///BLACK BACKGROUND///
                If lngColor = vbBlack Then
                  lngColor = vbWhite
                ElseIf lngColor = vbWhite Then
                  lngColor = vbBlack
                End If
                '//////////////////////
                'If your prefere White (the true Value) Then just remove that..
                SetPixel lngDc, lngX + 20, lngY + 30, lngColor
                'Increment the counter...
                lngCnt = lngCnt + 1
              Next lngX
            Next lngY
            'NEW//FRAME
            SetRect RC, 20, 30, udtHeader.biWidth + 20, udtHeader.biHeight + 30
            DrawEdge lngDc, RC, BDR_SUNKENOUTER, BF_RECT
          End If
          Exit For
        ElseIf udtRec.bytType = 3 Then
          'Its a Meta File!
          Exit For
        End If
      Next intCnt
    Else
      'Print Message - No Preview
    End If
    'Close the file
    Close lngFile
    'Return the value
  End If
  ReleaseDC lngHwnd, lngDc
  'General Error control
Exit_Here:
  Exit Function
Err_Control:
  Select Case Err.Number
  'Add your Case selections here
    Case Else
    MsgBox Err.Description
    Resume Exit_Here
  End Select
End Function

Private Sub CommandButton1_Click()
    PaintPreview "e:\temp\test.dwg"
End Sub
Autodesk Expert Elite
Revit Subject Matter Expert (SME)
Owner/FAA sUAS Pilot @ http://skyviz.io

jerrywilson

  • Guest
Re: DWG 2013 thumbnail onto Access form
« Reply #13 on: October 25, 2013, 09:43:48 AM »
Brilliant, cheers buddy.

Matt__W

  • Seagull
  • Posts: 12955
  • I like my water diluted.
Re: DWG 2013 thumbnail onto Access form
« Reply #14 on: October 25, 2013, 09:54:49 AM »
Autodesk Expert Elite
Revit Subject Matter Expert (SME)
Owner/FAA sUAS Pilot @ http://skyviz.io