home *** CD-ROM | disk | FTP | other *** search
/ Programming Tool Box / SIMS_2.iso / vb_code1 / ole_demo / oleacces.bas < prev    next >
BASIC Source File  |  1994-01-27  |  13KB  |  390 lines

  1. Option Explicit
  2.  
  3. 'Global Constants
  4.  
  5. Global Const LENGTH_FOR_SIZE = 4
  6. Global Const OBJECT_SIGNATURE = &H1C15
  7. Global Const OBJECT_HEADER_SIZE = 20
  8. Global Const CHECKSUM_SIGNITURE = &HFE05AD00
  9. Global Const CHECKSUM_STRING_SIZE = 4
  10.  
  11. 'PT : Window sizing information for object
  12. '     Used in OBJECTHEADER type
  13. Type PT
  14.     Width As Integer
  15.     Height As Integer
  16. End Type
  17.  
  18. 'OBJECTHEADER : Contains relevant information about object
  19. '
  20. Type OBJECTHEADER
  21.     Signature As Integer         'Type signiture (0x1c15)
  22.     HeaderSize As Integer        'Size of header (sizeof(struct OBJECTHEADER) + cchName + cchClass)
  23.     ObjectType As Long           'OLE Object type code (OT_STATIC, OT_LINKED, OT_EMBEDDED)
  24.     NameLen As Integer           'Count of characters in object name (CchSz(szName) + 1)
  25.     ClassLen As Integer          'Count of characters in class name (CchSz(szClass) + 1)
  26.     NameOffset As Integer        'Offset of object name in structure (sizeof(OBJECTHEADER))
  27.     ClassOffset As Integer       'Offset of class name in structure (ibName + cchName)
  28.     ObjectSize As PT             'Original size of object (see code below for value)
  29.     NameAndClass As String * 255 'Name and class of object
  30. End Type
  31.  
  32.  
  33.  
  34. 'Windows kernel function for unique temporary filename
  35. Declare Function GetTempFileName Lib "Kernel" (ByVal cDriveLetter As Integer, ByVal lpPrefixString As String, ByVal wUnique As Integer, ByVal lpTempFileName As String) As Integer
  36.  
  37. 'This DANGEROUS function allows copying data between different variable types
  38. Declare Sub hmemcpy Lib "Kernel" (dest As Any, source As Any, ByVal bytes As Long)
  39.  
  40. 'Checksum function put in DLL for speed
  41. Declare Sub ComputeCheckSum Lib "OLECS.DLL" (CheckSum As Integer, ByVal s As String, ByVal Length As Long)
  42.  
  43. 'Ole declarations
  44. 'Comment out if declared elsewhere
  45. Global Const OLE_SAVE_TO_FILE = 11
  46. Global Const OLE_READ_FROM_FILE = 12
  47. Global Const OLE_SAVE_TO_OLE1FILE = 18
  48.  
  49. Sub CopyAccess1xOleToField (OleObject As Control, FieldObject As Field)
  50.     '
  51.     ' Copies Ole object to Field Control
  52.     ' writing Access 1.x ole storage format.
  53.     ' Useful for cross compatibility with
  54.     ' Access 1.x, but saves object as Ole1.
  55.     '
  56.     ' OleObject   :   Ole2 control to save
  57.     ' FieldObject :   Database field control to write
  58.     '
  59.     Dim FileNumber As Integer
  60.     Dim FileName As String * 255
  61.     Dim OleHeaderString As String
  62.     Dim oh As OBJECTHEADER
  63.     Dim FileBuffer As String
  64.     Dim CheckSum As Integer
  65.     Dim FileLength As Long
  66.     Dim FileOffset As Long
  67.     Dim BufferLength As Integer
  68.     Dim HeaderLength As Integer
  69.     Dim DocumentClass As String
  70.     Dim DocumentName As String
  71.     Dim CheckSumString As String
  72.     Dim CheckSumCompare As String
  73.     Dim Result%
  74.     
  75.     BufferLength = 5128
  76.  
  77.     DocumentClass = OleObject.Class
  78.     DocumentName = OleObject.HostName
  79.     
  80.     'Write ole object to temporary file
  81.     'We do this first in case it fails
  82.     Result% = GetTempFileName(0, "OLE", -1, FileName)
  83.     FileNumber = FreeFile
  84.     Open FileName For Binary As FileNumber
  85.     OleObject.FileNumber = FileNumber
  86.     OleObject.Action = OLE_SAVE_TO_OLE1FILE
  87.     Close FileNumber
  88.     
  89.     'Create object header
  90.     'The extra 2 for Headersize are the null characters
  91.     oh.Signature = OBJECT_SIGNATURE
  92.     oh.HeaderSize = OBJECT_HEADER_SIZE + Len(DocumentName) + Len(DocumentClass) + 2
  93.     oh.ObjectType = OleObject.OLEType
  94.     oh.NameLen = Len(DocumentName) + 1
  95.     oh.ClassLen = Len(DocumentClass) + 1
  96.     oh.NameOffset = OBJECT_HEADER_SIZE
  97.     oh.ClassOffset = OBJECT_HEADER_SIZE + oh.NameLen
  98.     oh.ObjectSize.Width = OleObject.Width
  99.     oh.ObjectSize.Height = OleObject.Height
  100.     oh.NameAndClass = DocumentName + Chr$(0) + DocumentClass + Chr$(0)
  101.     
  102.     'Transfer this to a string
  103.     OleHeaderString = String$(oh.HeaderSize, 0)
  104.     Call hmemcpy(ByVal OleHeaderString, oh, oh.HeaderSize)
  105.  
  106.     'Write this string to Access OLE field
  107.     FieldObject.AppendChunk (OleHeaderString)
  108.  
  109.     'Initialize Checksum byte
  110.     CheckSum = 0
  111.  
  112.     'Write ole object from file to Access, calculating checksum
  113.     FileLength = FileLen(FileName)
  114.     Open FileName For Binary As FileNumber
  115.     Do While FileLength > 0
  116.         
  117.         'Get file buffer
  118.         If BufferLength > FileLength Then
  119.             BufferLength = FileLength
  120.         End If
  121.         FileBuffer = String$(BufferLength, 32)
  122.         Get FileNumber, , FileBuffer
  123.  
  124.         'Calculate checksum
  125.         Call ComputeCheckSum(CheckSum, FileBuffer, Len(FileBuffer))
  126.  
  127.         'Write this chunk to access
  128.         FieldObject.AppendChunk (FileBuffer)
  129.  
  130.         'Decrement file length
  131.         FileLength = FileLength - BufferLength
  132.  
  133.     Loop
  134.  
  135.     'Close and kill file
  136.     Close FileNumber
  137.     Kill FileName
  138.  
  139.     'Write the checksum string:
  140.     CheckSumString = String$(CHECKSUM_STRING_SIZE, 32)
  141.     Call hmemcpy(ByVal CheckSumString, CHECKSUM_SIGNITURE Or CheckSum, CHECKSUM_STRING_SIZE)
  142.     FieldObject.AppendChunk CheckSumString
  143.     
  144. End Sub
  145.  
  146. Sub CopyFieldToAccess1xOle (FieldObject As Field, OleObject As Control)
  147.     '
  148.     ' Copies Field Control to Ole Object
  149.     ' reading Access 1.x ole storage format.
  150.     ' Useful for cross compatibility with
  151.     ' Access 1.x.  You would use this
  152.     ' function to read an Ole object
  153.     ' created by Access (1.x) or CopyAccess1xOleToField.
  154.     '
  155.     ' FieldObject :  Database field control to read
  156.     ' OleObject   :  Ole2 control to load
  157.     '
  158.     Dim FileNumber As Integer
  159.     Dim FileName As String * 255
  160.     Dim OleHeaderString As String
  161.     Dim oh As OBJECTHEADER
  162.     Dim FileBuffer As String
  163.     Dim CheckSum As Integer
  164.     Dim FileLength As Long
  165.     Dim FileOffset As Long
  166.     Dim BufferLength As Integer
  167.     Dim HeaderLength As Integer
  168.     Dim DocumentName As String
  169.     Dim DocumentClass As String
  170.     Dim CheckSumString As String
  171.     Dim CheckSumCompare As String
  172.     Dim Result%
  173.             
  174.     BufferLength = 5128
  175.     
  176.     'Get first four bytes of the object to determine length of header
  177.     OleHeaderString = FieldObject.GetChunk(0, LENGTH_FOR_SIZE)
  178.     
  179.     'Copy this to oh structure
  180.     Call hmemcpy(oh, ByVal OleHeaderString, LENGTH_FOR_SIZE)
  181.     HeaderLength = oh.HeaderSize
  182.     
  183.     'Note: You could test first element of oh for
  184.     '      OBJECT_SIGNATURE here.
  185.  
  186.     'Now get all of the header
  187.     OleHeaderString = FieldObject.GetChunk(0, HeaderLength)
  188.  
  189.     'Translate this to OBJECTHEADER structure
  190.     Call hmemcpy(oh, ByVal OleHeaderString, HeaderLength)
  191.  
  192.     'Note: Now you could check variables in OBJECTHEADER structure.
  193.     '      This is what Access does to display class name without
  194.     '      loading the object into an ole container.
  195.  
  196.     'Now write the rest of the Access OLE object, minus Checksum bytes,
  197.     'to temporary file
  198.     Result% = GetTempFileName(0, "OLE", -1, FileName)
  199.     FileNumber = FreeFile
  200.     Open FileName For Binary As FreeFile
  201.  
  202.     FileLength = FieldObject.FieldSize() - HeaderLength - CHECKSUM_STRING_SIZE
  203.     FileOffset = HeaderLength
  204.  
  205.     'Reset checksum
  206.     CheckSum = 0
  207.     
  208.     'Loop through file
  209.     Do While FileLength > 0
  210.         
  211.         If BufferLength > FileLength Then
  212.             BufferLength = FileLength
  213.         End If
  214.         FileBuffer = FieldObject.GetChunk(FileOffset, BufferLength)
  215.  
  216.         'Calculate checksum
  217.         Call ComputeCheckSum(CheckSum, FileBuffer, Len(FileBuffer))
  218.  
  219.         'Write to temp file
  220.         Put FileNumber, , FileBuffer
  221.  
  222.         'Resize FileLength and FileOffset
  223.         FileLength = FileLength - BufferLength
  224.         FileOffset = FileOffset + BufferLength
  225.     
  226.     Loop
  227.  
  228.     'Get the Checksum string from Access object
  229.     CheckSumString = FieldObject.GetChunk(FileOffset, CHECKSUM_STRING_SIZE)
  230.     
  231.     'Create comparison string and compare to string from Access.
  232.     CheckSumCompare = String$(CHECKSUM_STRING_SIZE, 32)
  233.     Call hmemcpy(ByVal CheckSumCompare, CHECKSUM_SIGNITURE Or CheckSum, CHECKSUM_STRING_SIZE)
  234.     
  235.     'Now compare the strings
  236.     If CheckSumCompare <> CheckSumString Then
  237.         MsgBox ("Checksum failed: " & Asc(Mid$(CheckSumCompare, 1, 1)) & "." & Asc(Mid$(CheckSumCompare, 2, 1)) & "." & Asc(Mid$(CheckSumCompare, 3, 1)) & "." & Asc(Mid$(CheckSumCompare, 4, 1)) & ". vs " & Asc(Mid$(CheckSumString, 1, 1)) & "." & Asc(Mid$(CheckSumCompare, 2, 1)) & "." & Asc(Mid$(CheckSumCompare, 3, 1)) & "." & Asc(Mid$(CheckSumCompare, 4, 1)))
  238.     End If
  239.  
  240.     'Close temp file
  241.     Close FileNumber
  242.  
  243.     'Reopen temp file and load into Ole object
  244.     Open FileName For Binary As FileNumber
  245.     OleObject.FileNumber = FileNumber
  246.     OleObject.Action = OLE_READ_FROM_FILE
  247.  
  248.     'Kill and close the file
  249.     Close FileNumber
  250.     Kill FileName
  251.  
  252. End Sub
  253.  
  254. Sub CopyFieldToOle2 (FieldObject As Field, OleObject As Control)
  255.     '
  256.     ' Copies Field Control to Ole Object
  257.     ' reading Ole2 storage format.
  258.     '
  259.     ' FieldObject :  Database field control to read
  260.     ' OleObject   :  Ole2 control to load
  261.     '
  262.     Dim FileNumber As Integer
  263.     Dim FileName As String * 255
  264.     Dim FileBuffer As String
  265.     Dim FileLength As Long
  266.     Dim FileOffset As Long
  267.     Dim BufferLength As Integer
  268.     Dim Result%
  269.             
  270.     BufferLength = 5128
  271.     
  272.     'Write Ole object from Access field to file
  273.     'to temporary file
  274.     Result% = GetTempFileName(0, "OLE", -1, FileName)
  275.     FileNumber = FreeFile
  276.     Open FileName For Binary As FreeFile
  277.  
  278.     FileLength = FieldObject.FieldSize()
  279.     FileOffset = 0
  280.  
  281.     'Loop through file
  282.     Do While FileLength > 0
  283.         
  284.         'Fill buffer from field
  285.         If BufferLength > FileLength Then
  286.             BufferLength = FileLength
  287.         End If
  288.         FileBuffer = FieldObject.GetChunk(FileOffset, BufferLength)
  289.  
  290.         'Write to temp file
  291.         Put FileNumber, , FileBuffer
  292.  
  293.         'Resize FileLength and FileOffset
  294.         FileLength = FileLength - BufferLength
  295.         FileOffset = FileOffset + BufferLength
  296.     
  297.     Loop
  298.  
  299.     'Close temp file
  300.     Close FileNumber
  301.  
  302.     'Reopen temp file and load into Ole object
  303.     Open FileName For Binary As FileNumber
  304.     OleObject.FileNumber = FileNumber
  305.     OleObject.Action = OLE_READ_FROM_FILE
  306.  
  307.     'Kill and close the file
  308.     Close FileNumber
  309.     Kill FileName
  310.  
  311. End Sub
  312.  
  313. Sub CopyOle2ToField (OleObject As Control, FieldObject As Field)
  314.     '
  315.     ' Copies Ole object to Field Control
  316.     ' writing Ole2 fstorage ormat.  Access would not
  317.     ' be able to activate the object.
  318.     '
  319.     ' OleObject   :   Ole2 control to save
  320.     ' FieldObject :   Database field control to write
  321.     '
  322.     Dim FileNumber As Integer
  323.     Dim FileName As String * 255
  324.     Dim FileBuffer As String
  325.     Dim FileLength As Long
  326.     Dim FileOffset As Long
  327.     Dim BufferLength As Integer
  328.     Dim Result%
  329.     
  330.     BufferLength = 5128
  331.  
  332.     'Write ole object to temporary file
  333.     'We do this first in case it fails
  334.     Result% = GetTempFileName(0, "OLE", -1, FileName)
  335.     FileNumber = FreeFile
  336.     Open FileName For Binary As FileNumber
  337.     OleObject.FileNumber = FileNumber
  338.     OleObject.Action = OLE_SAVE_TO_FILE
  339.     Close FileNumber
  340.     
  341.  
  342.     'Write ole object from file to field object
  343.     FileLength = FileLen(FileName)
  344.     Open FileName For Binary As FileNumber
  345.     Do While FileLength > 0
  346.         
  347.         'Get file buffer
  348.         If BufferLength > FileLength Then
  349.             BufferLength = FileLength
  350.         End If
  351.         FileBuffer = String$(BufferLength, 32)
  352.         Get FileNumber, , FileBuffer
  353.  
  354.         'Write this chunk to field
  355.         FieldObject.AppendChunk (FileBuffer)
  356.  
  357.         'Decrement file length
  358.         FileLength = FileLength - BufferLength
  359.  
  360.     Loop
  361.  
  362.     'Close and kill file
  363.     Close FileNumber
  364.     Kill FileName
  365.  
  366. End Sub
  367.  
  368. Sub VBComputeCheckSum (CheckSum As Integer, ByVal s As String, ByVal Length As Long)
  369.     '
  370.     ' Calculates Checksum of Access Ole Object.
  371.     ' It is highly recommended that the DLL version
  372.     ' of this function (ComputeCheckSum) be used instead.
  373.     ' The difference in execution speed is phenomenal.
  374.     ' Although the last parameter (Length) is redundant,
  375.     ' it's included so that the arguments are identical
  376.     ' to the DLL version.
  377.     '
  378.     ' Checksum :  Stores the passed and calculated checksum
  379.     ' s        :  String used to perform checksum
  380.     ' Length   :  Length of string used to perform checksum
  381.     '
  382.     Dim l As Long
  383.  
  384.     For l = 1 To Length
  385.         CheckSum = CheckSum Xor Asc(Mid$(s, l, 1))
  386.     Next
  387.  
  388. End Sub
  389.  
  390.