기본 이미지입니다. 소스에서 사용한 컨트롤은 Farpoint Spread를 사용했읍니다. 다른 컨트롤을 사용해도 무방합니다.


다음 이미지는 폼을 특정 색을 투명화 시킨 것으로
이전 글의 폼의 특정 색을 투명화 하는 것과 같은 방법입니다.

다음 이미지는 투명화된 뒤에 다른 컨트롤이나 폼을 두어 컨트롤의 배경으로 투시되어 보기게 합니다.
따라서 컨트롤의 배경이 투명으로 되어 폼의 바탕이 투시되어 보이는 것처럼 됩니다.
이 글의 소스에서는 픽처박스를 사용했읍니다.



다음은 소스입니다.

우선 폼 모듈입니다.
' 컨트롤 배경 투명화시킨후, 대신 다른 배경을 보이게 하기
Option Explicit

Private Sub Form_Load()
    With Picture1 ' 픽처박스 크기를 대상 폼의 클라이언트 영역 크기로
        Picture1.Width = Me.ScaleWidth
        Picture1.Height = Me.ScaleHeight
        Picture1.Picture = Me.Picture
    End With
    Call SetParent(Picture1.hWnd, 0) ' 배경이 될 픽처박스를 바탕화면의 하위 폼으로 지정, 폼이 바탕화면의 어느 영역에든 이동 가능하면, 배경이되는 이미지도 바탕화면에서 이동이 가능해야 하므로
    Call SetWindowLong(Me.hWnd, GWL_EXSTYLE, GetWindowLong(Me.hWnd, GWL_EXSTYLE) Or WS_EX_LAYERED) ' 투명폼을 적용하기 위해, 레이어 스타일 윈도우를 적용시킨다
    SetLayeredWindowAttributes Me.hWnd, fpSpread1.BackColor, 0, LWA_COLORKEY
    Hook Me.hWnd ' 서브 클래싱
End Sub

Private Sub Form_Unload(Cancel As Integer)
    SetParent Picture1.hWnd, Me.hWnd ' 원상 복귀
    UnHook Me.hWnd
End Sub

다음은  일반 모듈 소스입니다.

Option Explicit

Public Declare Function SetParent Lib "user32" (ByVal hWndChild As Long, ByVal hWndNewParent As Long) As Long
Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Public Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long) As Long
Public Declare Function SetLayeredWindowAttributes Lib "user32.dll" (ByVal hWnd As Long, ByVal crKey As Long, ByVal bAlpha As Byte, ByVal dwflags As Long) As Long
Private Declare Function ClientToScreen Lib "user32" (ByVal hWnd As Long, lpPoint As POINTAPI) As Long
Private Declare Function SetWindowPos Lib "user32" (ByVal hWnd As Long, ByVal hWndInsertAfter As Long, ByVal x As Long, ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long
Private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal MSG As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Public Const GWL_EXSTYLE = (-20)
Private Const GWL_WNDPROC = (-4)
Public Const WS_EX_LAYERED = &H80000
Public Const LWA_COLORKEY As Long = &H1
Private Const WM_WINDOWPOSCHANGING = &H46
Private Const WM_ACTIVATEAPP = &H1C
Private Const SWP_NOACTIVATE = &H10
Private Const SWP_NOSIZE = &H1

Private Type POINTAPI
    x As Long
    y As Long
End Type

Private GetPicturePoint As POINTAPI
Private preWinProc As Long ' 이전 윈도우 프로시저 주소

Public Sub Hook(WinHwnd As Long)
    preWinProc = SetWindowLong(WinHwnd, GWL_WNDPROC, AddressOf WndProc)
End Sub

Public Sub UnHook(WinHwnd As Long)
    Call SetWindowLong(WinHwnd, GWL_WNDPROC, preWinProc)
End Sub

Public Function WndProc(ByVal hWnd As Long, ByVal MSG As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    Select Case MSG
        Case WM_WINDOWPOSCHANGING, WM_ACTIVATEAPP
            GetPicturePoint.x = 0
            GetPicturePoint.y = 0
            ClientToScreen Form1.hWnd, GetPicturePoint
            SetWindowPos Form1.Picture1.hWnd, Form1.hWnd, GetPicturePoint.x, GetPicturePoint.y, 0, 0, SWP_NOSIZE Or SWP_NOACTIVATE ' 폼과 픽처박스가 위치하게
    End Select
    WndProc = CallWindowProc(preWinProc, hWnd, MSG, wParam, lParam)
End Function

여기서 폼이 움직일때 폼 뒤의 컨트롤이나 폼도 같이 움직일수 있도록 하기 위해서 서브 클래싱을 사용하여
WM_WINDOWPOSCHANGING 윈도우 메세지에 하단의 컨트롤(폼)도 움직이도록 반응하게 하였읍니다.

여러 상황에 대한 처리를 위한 추가적인 코드들이 필요합니다.

+ Recent posts