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 / samples4 / ch09 / dibsect.frm (.txt) < prev    next >
Encoding:
Visual Basic Form  |  1997-02-16  |  8.4 KB  |  235 lines

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