home *** CD-ROM | disk | FTP | other *** search
/ Dan Appleman's Visual Bas…s Guide to the Win32 API / Dan.Applmans.Visual.Basic.5.0.Programmers.Guide.To.The.Win32.API.1997.Ziff-Davis.Press.CD / VB5PG32.mdf / vbpg32 / samples5 / ch09 / dibsect.frm (.txt) < prev    next >
Encoding:
Visual Basic Form  |  1997-02-16  |  8.4 KB  |  234 lines

  1. VERSION 5.00
  2. Begin VB.Form frmDIBSection 
  3.    Caption         =   "DIBSection Demo"
  4.    ClientHeight    =   4515
  5.    ClientLeft      =   1095
  6.    ClientTop       =   1515
  7.    ClientWidth     =   5580
  8.    LinkTopic       =   "Form1"
  9.    PaletteMode     =   1  'UseZOrder
  10.    ScaleHeight     =   4515
  11.    ScaleWidth      =   5580
  12.    Begin VB.CommandButton cmdWhiteRect 
  13.       Caption         =   "Draw Rect"
  14.       Height          =   435
  15.       Left            =   1980
  16.       TabIndex        =   6
  17.       Top             =   2880
  18.       Width           =   1335
  19.    End
  20.    Begin VB.CommandButton cmdStrip 
  21.       Caption         =   "Strip Blue"
  22.       Height          =   495
  23.       Index           =   2
  24.       Left            =   480
  25.       TabIndex        =   5
  26.       Top             =   2820
  27.       Width           =   1035
  28.    End
  29.    Begin VB.CommandButton cmdStrip 
  30.       Caption         =   "Strip Green"
  31.       Height          =   495
  32.       Index           =   1
  33.       Left            =   480
  34.       TabIndex        =   4
  35.       Top             =   2220
  36.       Width           =   1035
  37.    End
  38.    Begin VB.CommandButton cmdStrip 
  39.       Caption         =   "Strip Red"
  40.       Height          =   495
  41.       Index           =   0
  42.       Left            =   480
  43.       TabIndex        =   3
  44.       Top             =   1620
  45.       Width           =   1035
  46.    End
  47.    Begin VB.CommandButton cmdRandom 
  48.       Caption         =   "Randomize"
  49.       Height          =   495
  50.       Left            =   480
  51.       TabIndex        =   2
  52.       Top             =   900
  53.       Width           =   1035
  54.    End
  55.    Begin VB.CommandButton cmdUpdate 
  56.       Caption         =   "Update"
  57.       Height          =   495
  58.       Left            =   480
  59.       TabIndex        =   1
  60.       Top             =   240
  61.       Width           =   1035
  62.    End
  63.    Begin VB.PictureBox picDisplay 
  64.       Height          =   2355
  65.       Left            =   1980
  66.       ScaleHeight     =   155
  67.       ScaleMode       =   3  'Pixel
  68.       ScaleWidth      =   207
  69.       TabIndex        =   0
  70.       Top             =   240
  71.       Width           =   3135
  72.    End
  73. Attribute VB_Name = "frmDIBSection"
  74. Attribute VB_GlobalNameSpace = False
  75. Attribute VB_Creatable = False
  76. Attribute VB_PredeclaredId = True
  77. Attribute VB_Exposed = False
  78. Option Explicit
  79. ' Copyright 
  80.  1997 by Desaware Inc. All Rights Reserved
  81. Private Type BITMAPINFOHEADER '40 bytes
  82.         biSize As Long
  83.         biWidth As Long
  84.         biHeight As Long
  85.         biPlanes As Integer
  86.         biBitCount As Integer
  87.         biCompression As Long
  88.         biSizeImage As Long
  89.         biXPelsPerMeter As Long
  90.         biYPelsPerMeter As Long
  91.         biClrUsed As Long
  92.         biClrImportant As Long
  93. End Type
  94. Private Type RGBQUAD
  95.         rgbBlue As Byte
  96.         rgbGreen As Byte
  97.         rgbRed As Byte
  98.         rgbReserved As Byte
  99. End Type
  100. Private Type BITMAPINFO
  101.         bmiHeader As BITMAPINFOHEADER
  102.         bmiColors As RGBQUAD    ' RGB, so length here doesn't matter
  103. End Type
  104. Dim binfo As BITMAPINFO
  105. Dim CompDC As Long  ' Compatible DC to hold the bitmap
  106. Dim addr As Long    ' Pointer to memory block containing bitmap data
  107. Dim DIBSectionHandle As Long    ' Handle to DIBSection
  108. Dim OldCompDCBM As Long         ' Original bitmap for CompDC
  109. Dim BytesPerScanLine As Long   ' Hold this value to improve performance
  110. Private Const BI_RGB = 0&
  111. Private Const BI_RLE8 = 1&
  112. Private Const BI_RLE4 = 2&
  113. Private Const DIB_RGB_COLORS = 0 '  color table in RGBs
  114. Private Const DIB_PAL_COLORS = 1 '  color table in palette indices
  115. Private Const SRCCOPY = &HCC0020 ' (DWORD) dest = source
  116. Private Declare Function CreateDIBSection Lib "gdi32" (ByVal hdc As Long, pBitmapInfo As BITMAPINFO, ByVal un As Long, lplpVoid As Long, ByVal handle As Long, ByVal dw As Long) As Long
  117. Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hdc As Long) As Long
  118. Private Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long
  119. Private Declare Function SelectObject Lib "gdi32" (ByVal hdc As Long, ByVal hObject As Long) As Long
  120. Private Declare Function DeleteDC Lib "gdi32" (ByVal hdc As Long) As Long
  121. Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
  122. Private Declare Function GetLastError Lib "kernel32" () As Long
  123. Private Declare Function GetStockObject Lib "gdi32" (ByVal nIndex As Long) As Long
  124. Private Declare Function Rectangle Lib "gdi32" (ByVal hdc As Long, ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long
  125. Private Sub cmdWhiteRect_Click()
  126.     Dim di&
  127.     di = SelectObject(CompDC, GetStockObject(0))
  128.     di = Rectangle(CompDC, 0, 0, 50, 50)
  129.     cmdUpdate_Click
  130. End Sub
  131. Private Sub cmdRandom_Click()
  132.     Dim x&
  133.     Dim usex&, usey&
  134.     Dim di&
  135.     With binfo.bmiHeader
  136.         ' Faster to access width & height in structure than pic properties
  137.         For x& = 1 To 1000
  138.             usex& = Int(Rnd() * .biWidth)
  139.             ' Height can be negative for top down DIB
  140.             usey& = Abs(Int(Rnd() * .biHeight))
  141.             SetSectionPixel usex&, usey&, RGB(Rnd() * 256, Rnd() * 256, Rnd() * 256)
  142.         Next x&
  143.     End With
  144.     cmdUpdate_Click
  145. End Sub
  146. Private Sub cmdStrip_Click(Index As Integer)
  147.     StripColor Index
  148.     cmdUpdate_Click
  149. End Sub
  150. Private Sub cmdUpdate_Click()
  151.     Dim di&
  152.     di& = BitBlt(picDisplay.hdc, 0, 0, picDisplay.ScaleWidth, picDisplay.ScaleHeight, CompDC, 0, 0, SRCCOPY)
  153. End Sub
  154. Private Sub Form_Load()
  155.     Randomize
  156.     ' Create a compatible DC to use
  157.     CompDC = CreateCompatibleDC(0)
  158.     ' Initialize the DIBSection header
  159.     With binfo.bmiHeader
  160.         .biSize = 40
  161.         .biWidth = picDisplay.ScaleWidth
  162.         .biHeight = -picDisplay.ScaleHeight
  163.         .biPlanes = 1
  164.         .biBitCount = 24 ' True RGB
  165.         .biCompression = BI_RGB
  166.         ' How many bytes per scan line?
  167.         ' For 256 colors: ScanAlign(.biWidth)
  168.         ' For 16 colors: ScanAlign((.biWidth+1) \ 2)
  169.         ' For monochrome: ScanAlign((.biWidth+7) \ 8)
  170.         ' For 24 bit color, as follows:
  171.         BytesPerScanLine = ScanAlign(.biWidth * 3)
  172.         .biSizeImage = BytesPerScanLine * .biHeight
  173.     End With
  174.     DIBSectionHandle = CreateDIBSection(CompDC, binfo, DIB_RGB_COLORS, addr, 0, 0)
  175.     OldCompDCBM = SelectObject(CompDC, DIBSectionHandle)
  176. End Sub
  177. ' Clean up afterwards
  178. Private Sub Form_Unload(Cancel As Integer)
  179.     Dim di
  180.     di = SelectObject(CompDC, OldCompDCBM)
  181.     di = DeleteDC(CompDC)
  182.     di = DeleteObject(DIBSectionHandle)
  183. End Sub
  184. ' Scans must align on 32 bit boundary
  185. Public Function ScanAlign(pwidth&) As Long
  186.     ScanAlign = (pwidth + 3) And &HFFFFFFFC
  187. End Function
  188. ' Calculates the location of a pixel in a DIBSection and sets it
  189. Public Sub SetSectionPixel(ByVal x&, ByVal y&, ByVal color&)
  190.     Dim ByteOffset&
  191.     ' How would you modify this code for a 16 color, 256 color and monochrome DIB?
  192.     ByteOffset = y * BytesPerScanLine + x * 3
  193.     agCopyData color, ByVal (addr + ByteOffset), 3
  194. End Sub
  195. ' This strips the Red, Green or Blue component from the image
  196. ' Could you do this in other color modes?
  197. Public Sub StripColor(ByVal colorindex%)
  198.     Dim ByteOffset&
  199.     Dim cury&
  200.     Dim curx&
  201.     Dim ScanOffset&
  202.     Dim CurrentAddr&
  203.     Dim ByteToStrip%
  204.     ' Reorder to match organization of bytes in DIB
  205.     Select Case colorindex
  206.         Case 0  ' Red
  207.                 ByteToStrip = 2
  208.         Case 1  ' Green
  209.                 ByteToStrip = 1
  210.         Case 2  ' Blue
  211.                 ByteToStrip = 0
  212.     End Select
  213.     Dim zerobyte As Byte
  214.     ' We need to scan each line
  215.     ' Note how we hand optimize the code to reduce calculations
  216.     ScanOffset = addr   ' First scan line
  217.     With binfo.bmiHeader
  218.         For cury& = 0 To Abs(.biHeight) - 1
  219.             ' Take into account which byte we are clearing here
  220.             CurrentAddr& = ScanOffset& + ByteToStrip
  221.             For curx& = 0 To .biWidth - 1
  222.                 ' Clear one byte
  223.                 agCopyData zerobyte, ByVal CurrentAddr&, 1
  224.                 CurrentAddr = CurrentAddr + 3
  225.             Next curx&
  226.         ScanOffset& = ScanOffset& + BytesPerScanLine
  227.         Next cury&
  228.     End With
  229.                         
  230. End Sub
  231. Private Sub picDisplay_Paint()
  232.     cmdUpdate_Click
  233. End Sub
  234.