이전 예제를 보면, picture에 개체를 설정한 것이 아니어서, 이미지 복사후 창이 가려졌다 다시 보여지면 복사한 이미가 창에 보이지 않는다. 이것을 해결하기 위해, 메모리 비트맵을 생성하고 메모리에 이미지를 복사한 후에, 비트맵을 OleCreatePictureIndirect 사용하여 VB에서 사용한 개체로 변환 후에 픽처박스에 Picture 속성에 이미지 개체를 설정한 예이다.

지정된 DC와 호완되는 비트맵을 만든다.

● 선언
Function CreateCompatibleBitmap Lib "gdi32" (ByVal hdc As Long, ByVal nWidth As Long, ByVal nHeight As Long) As Long

● 인수

hDC ━ 호완되는 DC 핸들, 즉 어떤 장치의 DC이냐
nWidth ━ 생성할 비트맵의 폭,픽셀
nHeight ━ 생성할 비트맵의 높이,픽셀

● 반환

성공 ━ 생성한 비트맵의 핸들
실패 ━ Null

다음은 초기 이미지다


이미지 복사 버튼을 누르게 되면, 이미지에 대한 메모리 DC를 생성하고 그 DC를 이미지와 연결하고, 다시 메모리 DC와 메모리 비트맵을 생성하고, DC에 비트맵을 연결하고, 이미지를 DC 메모리 DC에 복사한 후에 메모리의 비트맵을 VB에서 사용가능한 이미지 개체로 변환 후에 그 이미지 개체를 픽처박스의 Picture 속성에 할당한다.



소스이다.

' 이미지 DC를 메모리 DC에 복사 후, 메모리 DC에서 이미지 개체를 얻고, 그 개체를 픽처박스의 이미지로 설정
Option Explicit

Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hdc As Long) As Long
Private Declare Function SelectObject Lib "gdi32" (ByVal hdc As Long, ByVal hObject As Long) As Long
Private Declare Function DeleteDC Lib "gdi32" (ByVal hdc As Long) As Long
Private Declare Function BitBlt Lib "gdi32" (ByVal hDCDest As Long, ByVal XDest As Long, ByVal YDest As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hdcSrc As Long, ByVal XSrc As Long, ByVal YSrc As Long, ByVal dwRop As Long) As Long
Private Declare Function CreateCompatibleBitmap Lib "gdi32" (ByVal hdc As Long, ByVal nWidth As Long, ByVal nHeight As Long) As Long
Private Declare Function OleCreatePictureIndirect Lib "olepro32.dll" (PicDesc As Any, RefIID As GUID, ByVal fPictureOwnsHandle As Long, IPic As IPicture) As Long ' 생성된 비트맵을 VB에서 사용가능하도록, 이미지 개체로 만든다.
Private Declare Function CLSIDFromString Lib "ole32" (ByVal str As Long, id As GUID) As Long
Private Type GUID ' 이미지 개체 클래스 ID를 저장할 구조체
    Data1 As Long
    Data2 As Integer
    Data3 As Integer
    Data4(7) As Byte
End Type

Private Type PicBmp ' VB에서 이미지 개체를 생성하기 위한 정보 구조체
    Size As Long
    Type As Long
    BitmapHwnd As Long
    hPal As Long
    Reserved As Long
End Type

Private Const SRCCOPY = &HCC0020

Public Function CreateImageDC(sPic As StdPicture) As Long ' 이미지에 대한 DC 생성
    Dim hdcPicture As Long ' 메모리 DC

   hdcPicture = CreateCompatibleDC(ByVal 0&)
   SelectObject hdcPicture, sPic.Handle
   CreateImageDC = hdcPicture
End Function

Private Sub cmdImageCopy_Click() ' 이미지 복사
    Dim Sorhdc As Long ' 소스 DC
    Dim Deshdc As Long ' 대상 DC(메모리)
    Dim DesBitmap As Long ' 대상 비트맵(메모리)
    Dim SizeX As Long ' 비트맵 크기 : X축 픽셀수
    Dim SizeY As Long ' 비트맵 크기 : Y축 픽셀수
    Dim Pic As PicBmp ' 비트맵을 OLE 개체로 생성하기 위한 비트맵 정보
    Dim IID_IDispatch As GUID ' VB에서 사용할 이미지 개체의 GUID
    Dim IPic As IPictureDisp ' VB에서 사용할 이미지 개체
   
    SizeX = CLng(Me.ScaleX(Image1.Picture.Width, vbHimetric, vbPixels)) ' 이지미 픽셀 크기
    SizeY = CLng(Me.ScaleY(Image1.Picture.Height, vbHimetric, vbPixels))
    Sorhdc = CreateImageDC(Image1.Picture) ' 이미지에 대한 DC를 생성한다
    Deshdc = CreateCompatibleDC(ByVal 0&)
    DesBitmap = CreateCompatibleBitmap(Sorhdc, SizeX, SizeY)
    SelectObject Deshdc, DesBitmap
    BitBlt Deshdc, 0, 0, SizeX, SizeY, Sorhdc, 0, 0, SRCCOPY ' 이미지 박스 이미지를 메모리 비트맵에 복사
    DeleteDC Sorhdc
    DeleteDC Deshdc
   
    ' 메모리의 비트맵을 VB에서 사용하는 이미지 개체로 변환
    Call CLSIDFromString(StrPtr("{00020400-0000-0000-C000-000000000046}"), IID_IDispatch) ' vb에서 사용되는 GUID를 구조체에 저장한다.
    With Pic
        .Size = Len(Pic)
        .Type = vbPicTypeBitmap
        .BitmapHwnd = DesBitmap
        .hPal = 0&
    End With
    Call OleCreatePictureIndirect(Pic, IID_IDispatch, 1, IPic)
    Set Picture1.Picture = IPic ' 생성된 이미지 개체 반환
End Sub

+ Recent posts