Q&A

  • 투명폼 소스에 대한 설명 부탁드립니다..
var
    frmRegion, tempRegion: HRGN;
    I: Integer;
    aRect: TRect;
begin
    frmRegion := 0;
    for I := 0 to ControlCount - 1 do
    begin
        // create a region for the control
        aRect := Controls[i].BoundsRect;
        
       // coordinates have to be window-relative, not client area relative
        OffsetRect( aRect, clientorigin.x - left, clientorigin.y - top );
        tempRegion := CreateRectRgnIndirect( aRect );

        // merge the region with the "summary" region we are building
        if frmRegion = 0 then
            frmRegion := tempRegion
        else
        begin
            CombineRgn( frmRegion, frmRegion, tempRegion, RGN_OR );
            DeleteObject( tempRegion );
        end;
    end;

    // create a region for the caption and menu bar and add it to the summary
    tempregion :=
    CreateRectRgn( 0, 0, Width,
    GetSystemMetrics( SM_CYCAPTION )+
    GetSystemMetrics( SM_CYSIZEFRAME )+
    GetSystemMetrics( SM_CYMENU ));

    CombineRgn( frmRegion, frmRegion, tempRegion, RGN_OR );
    DeleteObject( tempRegion );
    SetWindowRgn( handle, frmRegion, true );
end;

주석도 영어로 달려있고.. 프로시져랑 함수들에 대한 설명이 없어서..
정확히 어떤 방법으로 폼을 투명하게 만드는지 알 수 가 없거든요?

각 라인에 대한 상세한 설명을 알고 싶은데..
도와주세요~
4  COMMENTS
  • Profile
    하얀까마귀 2004.11.19 21:45
    안녕하세요 하얀까마귀 입니다.

          영역의 핸들입니다. HRGN이라는 게 영역의 핸들이죠
          // 이놈을 가지고 내가 원하는 모양으로 만들수 있는겁니다.
      
         // ControlCount  정확히는 Self.controlcount 또는 Form1.Controlcount겠죠?  현재 폼안에 있는 모든 콘트롤의 갯수죠.. 이걸로 콘트롤들을
      엑세스 할려는거 같군요

              // 역시나 해당 콘트롤의 위치값을 얻습니다..
              // 이 rect값으로 할려는거 같군요.
              
              // 이노은 그냥 rect의 내용을 조금 변화시키는 겁니다.
             이 함수 사용안해도 무방합니다....
              단지 clientorigin <-- 이변수는 전역인듯 하군요.
             현재 폼의 위치에 따라서 rect의 값을 약간 변화시켜 줍니다.

              // 이제 해당 rect로 영역을 만들어 내죠...
             // 이게 제일처음 즉 영역값이 0이면 없는거니까.. 없을때는 그냥주고
              그게 아닐때는 둘다 합치는군요..  
                  // CombineRgn에 두개의 영역을 OR로 합치는 겁니다.
                  // 그럼 두개가 하나의 핸들 즉 frmRegion이 되겠죠?
                  // 당연히 사용한 이전의 템프는 없애 버려야죠
           // 이놈은 이제 타이틀 을 구해서 역시나 똑같은 짓을 하는군요

          // 영역을 만들기만 하면 안되겟죠? 내 폼에다가 적용을 해야지..
          // 마짐막으로 적용시킵니다.




    에구구.. 용일이형 말과 같이 콘트롤의 영역만 존재하는 이상한 폼이 되겟군요.
    콘트롤들이 어떤 위치에 잇느냐에 따라서 상당히 이상한 폼이 될듯 하네요..

    일단 모양을 여러가지로 하는건 핸들이 있는건 다 됩니다. 마지막 함수잇죠?

    SetWindowRgn 저기에서 핸들이 들어갈수 잇는 콘틀롤은 다된다고 보시면 됩니다.. 뭐 동그란 버튼 <-- 이런게 된다는거죠. 물론 동작하는건 이상해서
    콤포넌트를 다시 작업해줘야 겟지만. ㅎㅎ

    중요한건 위에서 보이는 콤비네이션 하구요. Create 부분입니다.
    Create관련하여서는 몇개의 함수가 더있거든요? 도움말을 참조 하시구요..
    보통 원이나 사각형 polygon도 있으니 이런것들을 이용해서 이쁜 윈도우를 만듭니다..

    한가지 부연설명 하자면 이건 투명한것과는 다른겁니다.
    투명한건 내 윈도우 영역에 상위의 윈도우의 그림을 그리는겁니다.
    따라서 실제로 윈도우는 존재하죠 그래서 마우스 클릭이라던지 이런 이벤트들이 먹습니다. 하지만 이건 영역자체가 없는것이기 때문에 위에서도 마찬가지로 콘트롤이 없는 부분은 바탕화면에 클릭이 되는것이죠..

    잘모르시는거 같아서 쉽게 한다고 했는데 이해가 되었는지 모르겟네요.
    그럼.
  • Profile
    이두형 2004.11.20 02:04
    하얀까마귀님 우선 답변 감사드립니다. 꾸벅 (__)(^^)

    폼을 투명하게 하는 것이 아니라,
    콘트롤(콘트롤이 컴포넌트들을 뜻하는 것이겠지요? ^^a)들이 있는 영역의 나머지를
    없애는 것이였구요.. 그래서 빈부분을 클릭하면 바탕화면이 선택되었구나..

    이 소스를 그대로 FormCreate에 붙여서 쓰고 있었거든요..
    그런데 제 폼이 보더스타일이 bsNone이구요,
    그위에 여러 이미지 컴포넌트들을 만들어서 메인 화면을 만들었는데,
    그 이미지 컴포넌트들의 영역( 하얀까마귀님 답변에서처럼 콘트롤의 영역이죠? )의 나머지 영역들이 없어지겠죠..
    헌데, 폼의 윗부분의 영역(Top가 0 에서부터 40 까지 좌우로 끝까지)이 없어지지 않아요..
    그 이유가 무엇인지..
    짧은 제 생각이지만 그 부분이 타이틀바 부분이 것같은 느낌이 들거든요?
    소스에 문제가 있는 것인지.. 잘 모르겠네요..

    아, 죄송.. 밑에 답변이 하나 더 있네요.. 못 보고 다시 글을 올렸네요..
    아마 그 부분이 메뉴바 부분인것 같아요..
    그런데 메뉴바 부분을 제외하고 영역을 없애는데 제외한 부분(메뉴바 부분)은
    그 폼의 바탕색으로 표현이 되나요?
    보더의 색을 하얀색으로 했는데 그 부분이 하얗게 나오네요..
    그럼, 그 메뉴바 부분의 영역도 없애려면 어떻게 해야 하는 것인지.. -_-a
  • Profile
    하얀까마귀 2004.11.23 02:34
    안녕하세요 하얀까마귀 입니다.

    늦게 봤네요..

    먼저 이런 소스를 구하셧으면 한줄 한줄 정말 명령어 하나하나 그 의미를
    완전히 알때까지 보고 또 보세요. ㅠㅠ
    저 높은곳에 있는 내공이 심오한 분들이야 그냥 대충 휙보고 넘어가도 되겠지만 우리같은 초보들이 그래야 되겟습니까...  보고또봐야 겨우 알수 있을텐데요. 님이 올려주신 소스는 말씀하신 타이틀바 부분이 고려가 된거였던걸로 기억합니다. 따라서 폼 스타일을 없애버리셧으니 그부분이 당연히 이상하게
    나타나겠죠.... 소스의 마지막 부분에 보시면 캡션바를 고려한 부분이 있는데
    그러한 부분을 빼버리고요..

    이런 폼은 두가지 문제가 생깁니다.
    첫째는 폼을 이동시킬수 있는 방법이 없습니다. 캡션이 없으니까 당연한거겠죠

    두번째는 크기조절이 안됩니다. ㅠㅠ

    이것또한 마찬가지 문제죠? 알수가 없으니.. ^^

    자 그럼 다른 프로그램들에서 어떻게 하는지 한번 살펴보시죠..

    마우스를 가져다 대면 모양이 이상하지만 끝부분에서는 커서가 변합니다.

    또 콘트롤이 없는곳에서는 캡션처럼 움직이구요..

    이런 동작은 WM_HITTEST라는 마우스 메세지를 이용하시면 가능합니다.

    이걸 이용해서 각종 마우스 관련 메세지가 만들어지는 거니까요..
    팁란에 보시면 아마 이 메세지를 이용한 팁이 올라와 있을껍
  • Profile
    최용일 2004.11.19 21:06
    안녕하세요. 최용일입니다.

    흠... 투명폼이라기보다는 구멍뚫린 폼이라고 할까나... 유리창에 창틀만 있고 유리가 없는...

    주석에 있는 영어가 어렵다면 한영변환 사이트를 찾아보세요. 개발자에게 영어는 필수입니다. 워낙 쉬운 영어로 써져 있어서 약간만 공부하시면... 함수자체도 이해하기 쉽게 명명되어 있는데.. Create, Combine, Delete...

    함수에 대한 설명은 한글판 Visual Studio를 구하셔서 도움말 보세요. 모두 Window API라서 한글판 MSDN에 한글로 다 나와 있습니다.

    일반적으로 윈도우는 네모난 모양을 가지고 있죠? 이 네모난 영역을 Region이라고 부릅니다. 이곳에 윈도우가 표시됩니다. 이 영역을 벗어난 곳에 그리면 뭘 그려도 화면상에 나타나지 않습니다.
    이 Region은 일반적으로 네모난 모양이 기본이지만 둥근모서리사각형, 타원, 다각형등도 있구요... 이것들을 조합해서 여러가지 모양을 만들 수 있습니다.

    스킨에 따라 다양한 모양을 가진 프로그램들이 이 Region을 이용한 겁니다.

    님이 적으신 코드는 폼의 메뉴바영역과 폼안에 있는 컨트롤 영역을 제외하고 모두 없애버려서 그곳에 밑에 있는 윈도우들이 보이도록 만들어진거네요...

    ^^ 항상 즐코하세요...