구멍뚫린 폼을 만들어 볼까 합니다. 

예를들어 캡순이 프로그램 처럼 지정된 영역안에 있는 화면만 캡춰하여 이미지로 저장할 수 있는 기능을 만들고자 할때 가운데가 비어있는 사각틀을 만들어야 되겠죠?  그래서 그 사각틀을 만들어 볼까 합니다.


사각틀을 만드는 다른방법으로 SetLayeredWindowAttributes 를 사용하여 해당 색상을 투명하게 만들어 작업할 수도 있습니다.


폼 투명도 주기



아래 그림과 같이 윈도우 폼은 일반적으로 타이틀이나 테두리 부분이 있는 비클라이언트 영역과 컨트롤 등을 배치하여 작업을

하는 클라이언트 영역으로 나뉩니다.




여기에서는 폼사이즈에 변경에 관계없이 클라이언트 영역만 안보이게 하여 아래 그림과 같이 만들어 보겠습니다.




Private Declare Function GetWindowRect Lib "user32" _

                        (ByVal hwnd As Long, _

                         lpRect As RECT) As Long

                         

Private Declare Function GetClientRect Lib "user32" _

                        (ByVal hwnd As Long, _

                         lpRect As RECT) As Long

                         

Private Declare Function CreateRectRgn Lib "gdi32" _

                        (ByVal X1 As Long, _

                         ByVal Y1 As Long, _

                         ByVal X2 As Long, _

                         ByVal Y2 As Long) As Long

                         

Private Declare Function OffsetRgn Lib "gdi32" _

                        (ByVal hRgn As Long, _

                         ByVal x As Long, _

                         ByVal y As Long) As Long

                         

Private Declare Function CombineRgn Lib "gdi32" _

                        (ByVal hDestRgn As Long, _

                         ByVal hSrcRgn1 As Long, _

                         ByVal hSrcRgn2 As Long, _

                         ByVal nCombineMode As Long) As Long

                         

Private Declare Function SetWindowRgn Lib "user32" _

                        (ByVal hwnd As Long, _

                         ByVal hRgn As Long, _

                         ByVal bRedraw As Boolean) As Long

                         

Private Declare Function DeleteObject Lib "gdi32" _

                        (ByVal hObject As Long) As Long


Private Type RECT

        Left As Long

        Top As Long

        Right As Long

        Bottom As Long

End Type


Private Const RGN_AND = 1

Private Const RGN_OR = 2

Private Const RGN_XOR = 3

Private Const RGN_DIFF = 4

Private Const RGN_COPY = 5


Private Sub Form_Resize()


  Const Degree    As Long = 0


  Dim WindowRect  As RECT

  Dim ClientRect  As RECT

  Dim hRgn1       As Long

  Dim hRgn2       As Long

  Dim lMoveX      As Long

  Dim lMoveY      As Long


  GetWindowRect Me.hwnd, WindowRect


  GetClientRect Me.hwnd, ClientRect


  lMoveX = ((WindowRect.Right - WindowRect.Left) - ClientRect.Right) \ 2

  lMoveY = ((WindowRect.Bottom - WindowRect.Top) - ClientRect.Bottom) - lMoveX


  hRgn1 = CreateRectRgn(0, 0, WindowRect.Right - WindowRect.Left, WindowRect.Bottom - WindowRect.Top)


  hRgn2 = CreateRectRgn(0, 0, ClientRect.Right - Degree * 2, ClientRect.Bottom - Degree * 2)


  OffsetRgn hRgn2, lMoveX + Degree, lMoveY + Degree


  CombineRgn hRgn1, hRgn1, hRgn2, RGN_XOR


  SetWindowRgn Me.hwnd, hRgn1, True


  DeleteObject hRgn1

  DeleteObject hRgn2


End Sub

 

폼의 비 클라이언트 영역을 포함한 크기로 Region을 만들고(hRgn1), 구멍의 크기를 클라이언트 영역으로 잡고(hRgn2),

OffsetRgn을 이용하여 hRgn2의 위치를 타이틀과 테두리의 크기를 뺀 위치만큼 이동시키고 이를 CombineRgn으로 XOR하여 

겹치지 않는 영역만 남게하여 폼에 적용하고 생성한 Region을 지우는 겁니다.


GetWindowRect, GetClientRect의 설명은 아래 링크를 참고하세요. 

폼 크기, 위치 구하기

 

Tip.

Form_Resize 안에 Degree 값을 증가시키면 사각틀 안쪽이 좁아지게 됩니다.





'VB6 > Interface' 카테고리의 다른 글

폼 타이틀바 Show/Hide  (0) 2013.03.28
바탕화면 아이콘 Show/Hide  (0) 2013.03.28
폼 위치, 크기 구하기  (0) 2013.03.27
폼 투명도 주기  (0) 2013.03.27
폼 타이틀바 이동효과  (0) 2013.03.26

오스크 등의 프로그램을 위해 윈도우 타이틀바를 필요치 않으면 Form 속성중 BorderStyle을 0으로 설정하는데

런타임시에 Show/Hide를 하고 싶을때 아래 코드를 참고하자.



Private Declare Function GetWindowLong Lib "user32" _

                  Alias "GetWindowLongA" _

                        (ByVal hwnd As Long, _

                         ByVal nIndex As Long) As Long


Private Declare Function SetWindowLong Lib "user32" _

                  Alias "SetWindowLongA" _

                        (ByVal hwnd As Long, _

                         ByVal nIndex As Long, _

                         ByVal dwNewLong As Long) As Long


Private Declare Function GetWindowRect Lib "user32" _

                        (ByVal hwnd As Long, _

                         lpRect As RECT) 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 Const GWL_STYLE = (-16)


Private Const WS_CAPTION = &HC00000 ' WS_BORDER Or WS_DLGFRAME

Private Const WS_MAXIMIZEBOX = &H10000

Private Const WS_MINIMIZEBOX = &H20000

Private Const WS_THICKFRAME = &H40000

Private Const WS_SYSMENU = &H80000


Private Const SWP_NOSIZE = &H1

Private Const SWP_NOMOVE = &H2

Private Const SWP_NOZORDER = &H4

Private Const SWP_FRAMECHANGED = &H20


Private Type RECT

    Left As Long

    Top As Long

    Right As Long

    Bottom As Long

End Type



Private Sub Command1_Click()

  SetWindowLong Me.hwnd, GWL_STYLE, _

                GetWindowLong(Me.hwnd, GWL_STYLE) And Not (WS_CAPTION)


  SetWindowPos Me.hwnd, 0, 0, 0, 0, 0, _

                SWP_NOSIZE Or SWP_NOMOVE Or SWP_NOZORDER Or SWP_FRAMECHANGED

End Sub


Private Sub Command2_Click()

  SetWindowLong Me.hwnd, GWL_STYLE, _

                GetWindowLong(Me.hwnd, GWL_STYLE) Or (WS_CAPTION)


  SetWindowPos Me.hwnd, 0, 0, 0, 0, 0, _

                SWP_NOSIZE Or SWP_NOMOVE Or SWP_NOZORDER Or SWP_FRAMECHANGED

End Sub


Private Sub Form_Load()

  Command1.Caption = "Hide"

  Command2.Caption = "Show"

End Sub


Tip.
코드를 실행시켜보면 단순히 타이틀만 없어지고 사이즈 조절은 된다.
BorderStyle을 없음(0)으로 설정한 것과 같이 하려면 WS_CAPTION을 WS_CAPTION OR WS_THICKFRAME 로 
변경하면 된다.

'VB6 > Interface' 카테고리의 다른 글

폼에 보여줄 영역 만들기(구멍난 폼)  (0) 2013.03.28
바탕화면 아이콘 Show/Hide  (0) 2013.03.28
폼 위치, 크기 구하기  (0) 2013.03.27
폼 투명도 주기  (0) 2013.03.27
폼 타이틀바 이동효과  (0) 2013.03.26

폼에 Picture박스를 한개 가져다 놓고, 

아래와 같이 Visible속성을 적용하여 객체를 가시적으로 표현할 수 있습니다.


감출땐

Picture1.Visible = False    ' Hide


보이게할땐

Picture1.Visible = True     ' Show



이와 동일한 효과를 주기위해 ShowWindow 를 이용하여 폼이나 컨트롤 등의 핸들값을 가지는 객체를 Show/Hide 할 수 있습니다.


Private Declare Function ShowWindow Lib "user32" _

                        (ByVal hWnd As Long, _

                         ByVal nCmdShow As Long) As Long


Private Const SW_HIDE = 0

Private Const SW_SHOW = 5


감출땐 
ShowWindow Picture1.hWnd, SW_HIDE

보일게할땐
ShowWindow Picture1.hWnd, SW_SHOW



프로젝트 내에서 접근가능한 객체를 위와같이 Show/Hide하진 않지만 대상이 윈도우의 시작버튼이나 다른 프로그램의 경우라면

ShowWindow와 같은 API를 사용해야 합니다.

참고가 될만한 예로 바탕화면에 있는 아이콘을 말끔하게 지워버리는(?) 간단한 코드를 작성해봅니다.

폼에 Command버튼을 2개 만들고 각 버튼의 Caption 값을 Hide 와 Show로 합니다. 



Private Declare Function FindWindowEx Lib "user32" Alias _

                        "FindWindowExA" _

                        (ByVal hWnd1 As Long, _

                         ByVal hWnd2 As Long, _

                         ByVal lpsz1 As String, _

                         ByVal lpsz2 As String) As Long

                         

Private Declare Function ShowWindow Lib "user32" _

                        (ByVal hWnd As Long, _

                         ByVal nCmdShow As Long) As Long


Private Const SW_HIDE = 0

Private Const SW_SHOW = 5


'Hide 하는 버튼

Private Sub Command1_Click()

  Dim lHandle   As Long

  lHandle = FindWindowEx(0&, 0&, "Progman", vbNullString)

  ShowWindow lHandle, SW_HIDE

End Sub


'Show 하는 버튼

Private Sub Command2_Click()

  Dim lHandle As Long

  lHandle = FindWindowEx(0&, 0&, "Progman", vbNullString)

  ShowWindow lHandle, SW_SHOW

End Sub


lHandle 변수에 대상이 되는 객체에 핸들값을 얻어 ShowWindow 함수에 첫번째 인자값으로 넘겨주고 

SW_HIDE 또는 SW_SHOW 를 두번째 인자에 적용하기만 하면 되는 예입니다.


대상 객체의 핸들값을 구할 수 있는 방법은 여러가지 방법이 있겠지만 대체로 FindWindowEx, FindWindow 등을 이용하니 

검색을 통해 더 많은 정보를 찾으시길 바람니다.


Tip.

마우스 포인트가 위치하는 윈도우 핸들 구하기




'VB6 > Interface' 카테고리의 다른 글

폼에 보여줄 영역 만들기(구멍난 폼)  (0) 2013.03.28
폼 타이틀바 Show/Hide  (0) 2013.03.28
폼 위치, 크기 구하기  (0) 2013.03.27
폼 투명도 주기  (0) 2013.03.27
폼 타이틀바 이동효과  (0) 2013.03.26

폼의 위치, 크기 정보를 가져오기 위해 GetWindowRectGetClientRect 를 사용합니다.

이 둘의 차이점은 

GetWindowRect 는 화면좌표를 기준으로 하여 비 클라이언트 영역(Non Client Area)을 포함한 각 면의 위치좌표를 가져오고

GetClientRect 는 컨트롤 등을 디자인하는 클라이언트 영역(Client Area)에 크기 정보만을 취득합니다.

쓰다보니 알아먹기 힘든 소리가 되어버렸는데 아래 이미지를 참고하면 이해가 될 겁니다.


     

 GetWindowRect

 

 GetClientRect



Private Declare Function GetWindowRect Lib "user32" _

                        (ByVal hwnd As Long, _

                         lpRect As RECT) As Long


Private Declare Function GetClientRect Lib "user32" _

                        (ByVal hwnd As Long, _

                         lpRect As RECT) As Long


Private Type RECT

        Left As Long

        Top As Long

        Right As Long

        Bottom As Long

End Type



Private Sub Form_Load()


  Dim WindowRect As RECT

  Dim ClientRect As RECT


  GetWindowRect Me.hwnd, WindowRect


  GetClientRect Me.hwnd, ClientRect


  Debug.Print WindowRect.Left

  Debug.Print WindowRect.Top

  Debug.Print WindowRect.Right

  Debug.Print WindowRect.Bottom


  Debug.Print ClientRect.Left

  Debug.Print ClientRect.Top

  Debug.Print ClientRect.Right

  Debug.Print ClientRect.Bottom


End Sub



약 폼안에 있는 PictureBox를 GetWindowRect 로 위치정보를 가져오면 어디를 기준으로 가져올까요?

화면 좌표 기준이니 화면내 PictureBox의 위치정보를 가져오게됩니다.

 

Tip.

프로젝트 내의 폼 크기나 위치정보를 얻기위해 굳이 API 안써도 된다고 하지만 몰라서 해될건 없으니..^^

RECT 구조체로 얻은 결과를 Form 속성과 비교하여 보면 더 이해가 쉽다.


Me.Left \ 15 = WindowRect.Left

Me.Top \ 15 = WindowRect.Top

Me.Width \ 15 = WindowRect.Right - WindowRect.Left

Me.Height \ 15 = WindowRect.Bottom - WindowRect.Top

Me.ScaleWidth \ 15 = ClientRect.Right

Me.ScaleHeight \ 15 = ClientRect.Bottom




'VB6 > Interface' 카테고리의 다른 글

폼에 보여줄 영역 만들기(구멍난 폼)  (0) 2013.03.28
폼 타이틀바 Show/Hide  (0) 2013.03.28
바탕화면 아이콘 Show/Hide  (0) 2013.03.28
폼 투명도 주기  (0) 2013.03.27
폼 타이틀바 이동효과  (0) 2013.03.26

네이트온에 알림창과 같이 폼에 페이드효과가 필요할 때 아래 코드를 참고하자.

Alpha 와 같이 함수형태로 만들어 놓고 핸들값과 Degree값만 바이트 범위(0~255) 내에서 넘겨주면 된다.


Private Declare Function SetLayeredWindowAttributes Lib "user32" _

                        (ByVal hWnd As Long, _

                         ByVal crKey As Long, _

                         ByVal bAlpha As Byte, _

                         ByVal dwFlags As Long) As Long

                         

Private Declare Function SetWindowLong Lib "user32" _

                  Alias "SetWindowLongA" _

                        (ByVal hWnd As Long, _

                         ByVal nIndex As Long, _

                         ByVal dwNewLong As Long) As Long

                  

Private Declare Function GetWindowLong Lib "user32" _

                  Alias "GetWindowLongA" _

                        (ByVal hWnd As Long, _

                         ByVal nIndex As Long) As Long


Private Const GWL_EXSTYLE = (-20)


Private Const WS_EX_LAYERED = &H80000


Private Const LWA_COLORKEY = &H1

Private Const LWA_ALPHA = &H2



Private Sub Alpha(ByVal hHandle As Long, ByVal byDegree As Byte)

  SetWindowLong hHandle, GWL_EXSTYLE, GetWindowLong(hHandle, GWL_EXSTYLE) Or WS_EX_LAYERED

  SetLayeredWindowAttributes hHandle, 0&, byDegree, LWA_ALPHA

End Sub



아래는 호출하는 형태


Private Sub Form_Activate()

  Dim i         As Long

  For i = 0 To 255

    Alpha Me.hWnd, CByte(i)

    DoEvents

  Next i

End Sub




Tip.

LWA_COLORKEY를 적용하면 지정한 색상만 투명하게 만들 수 있다.

Private Sub Transparent(ByVal hHandle As Long, ByVal lColor As Long)

  SetWindowLong hHandle, GWL_EXSTYLE, GetWindowLong(hHandle, GWL_EXSTYLE) Or WS_EX_LAYERED

  SetLayeredWindowAttributes hHandle, lColor, 0&, LWA_COLORKEY

End Sub


호출하는 형태

Private Sub Form_Load()
  Me.BackColor = vbRed
  Transparent Me.hWnd, vbRed
End Sub


'VB6 > Interface' 카테고리의 다른 글

폼에 보여줄 영역 만들기(구멍난 폼)  (0) 2013.03.28
폼 타이틀바 Show/Hide  (0) 2013.03.28
바탕화면 아이콘 Show/Hide  (0) 2013.03.28
폼 위치, 크기 구하기  (0) 2013.03.27
폼 타이틀바 이동효과  (0) 2013.03.26

폼, 컨트롤의 위치이동이 필요할 때에는 아래 코드를 참고하자.

FormMove 와 같이 함수형태로 만들어 놓고 핸들값만 넘겨주면 되니 편하게 사용할 수 있다.


Private Declare Function SendMessage Lib "user32" _

                  Alias "SendMessageA" _

                        (ByVal hwnd As Long, _

                         ByVal wMsg As Long, _

                         ByVal wParam As Long, _

                         lParam As Any) As Long


Private Declare Function ReleaseCapture Lib "user32" () As Long


Private Const WM_NCLBUTTONDOWN = &HA1

Private Const HTCAPTION = 2



Private Sub FormMove(ByVal hHandle As Long)

  ReleaseCapture

  SendMessage hHandle, WM_NCLBUTTONDOWN, HTCAPTION, 0

End Sub



아래는 호출하는 형태(MouseDown 이벤트에 적용하도록 하자.)


Private Sub Form_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)

  FormMove Me.hwnd

End Sub



'VB6 > Interface' 카테고리의 다른 글

폼에 보여줄 영역 만들기(구멍난 폼)  (0) 2013.03.28
폼 타이틀바 Show/Hide  (0) 2013.03.28
바탕화면 아이콘 Show/Hide  (0) 2013.03.28
폼 위치, 크기 구하기  (0) 2013.03.27
폼 투명도 주기  (0) 2013.03.27

+ Recent posts