블로그 이미지
생각처럼

카테고리

전체보기 (209)
TOOL (1)
다이어리 (1)
Bit (200)
HELP? (0)
Total
Today
Yesterday

달력

« » 2025.2
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28

공지사항

태그목록

최근에 올라온 글

그래, 자네가 요즘 슬럼프라고? 나태의 늪에서 좀처럼 헤어나기가 어렵다고?

그런 날들이 하루이틀 계속되면서 이제는 스스로가 미워질만큼, 그런 독한 슬럼프에 빠져있다고?

왜, 나는 슬럼프 없을 것 같아? 이런 편지를 다 했네, 내 얘길 듣고 싶다고.



우선 하나 말해 두지, 나는 슬럼프란 말을 쓰지 않아, 대신 그냥 ‘게으름’이란 말을 쓰지. 슬럼프, 라고 표현하면 왠지 자신을 속이는 것 같아서… 지금부턴 그냥 게으름 또는 나태라고 할께.



나는 늘 그랬어. 한번도 관료제가 견고한 조직생활을 해본 적이 없었지. 하다 못해 군대도 학교(육군제3사관학교)였다니까?

그렇게 거의 25년을 학생으로 살다가, 어느 날 다시 교수로 위치로 바꾼 것이 다라니까? 복 받은 삶이지만, 어려운 점도 있어.

나를 내치는 상사가 없는 대신, 스스로를 관리하지 않으면 안되는 게 내 삶이었거든.

그래서 늘 힘들었어, 자기를 꾸준이 관리해야 된다는 사실이. 평생을 두고 나는 ‘자기관리’라는 화두와 싸워왔어.



사람이 기계는 아니잖아… 감정적인 동요가 있거나, 육체적인 피로가 있거나, 아니면 그냥 어쩌다 보면 좀 게을러지고 싶고, 또 그게 오래 가는 게 인지상정이잖아… 교수라는 직업이 밖에서 점검해 주는 사람이 없기 때문에 슬럼프, 아니 나태에 훨씬 쉽게 그리고 깊게 빠져. 내가 자주 그렇다니깐? 자네들에게 표현을 안해서 그렇지.



난 나태란 관성의 문제라고 생각해. 자전거는 올라타서 첫페달 밟을 때까지가 제일 힘들지. 컴퓨터 켜기도, 자동차 시동걸기도, 사는 것도 마찬가지야. 정지상태를 깨는 첫 힘을 쏟는 모멘텀을 줄 의지가 관성이 치여버리는 현상... 난 그것이 자네가 말하는 ‘슬럼프’의 합당한 정의라고 생각해.



근데, 문제는 말야, 나태한 자신이 싫어진다고 말은 하면서도 그 게으른 일상에 익숙해져서 그걸 즐기고 있단 말이지.

‘슬럼프’에서 벗어나고 싶다고 말하면서도, 실은 그걸 즐기고 있단 말이지.

실은 자네도 슬럼프를, 아니 오랜만의 연속된 나태를, 지금 즐기고 있는 거라면 이 글을 여기까지만 읽어. 딱 여기까지만 읽을 사람을 위해 덕담까지 한 마디 해줄게. “슬럼프란 더 생산적인 내일을 위한 재충전의 기간이다.” 됐지? 잘 가.

         


                  
 
하지만, 위에 쓴 덕담은 거짓말이야. 너무 오래 나태하면 안돼.

자아가 부패하거든, 그러면 네 아름다운 육신과 영혼이 슬퍼지거든, 그러면 너무 아깝거든.

그러니까, ‘정말’ 슬럼프, 아니 나태에서 벗어나겠다고 스스로 각오해. 그리고 이 다음을 읽어.



보통 ‘슬럼프’ 상태에서는 정신이 확 드는 외부적 자극이 자신을 다시 바로 잡아주기를 기다리게 되거든?

어떤 강력한 사건의 발생이나, 친구/선배의 따끔한 한 마디, 혹은 폭음 후 새벽 숙취 속에서 느끼는 어떤 깨달음 같은 것이라도… 그런 걸 느낄 때까지는 자신의 게으름에 대한 자학을 유보하거든? 땍! 정신 차려 이 친구야, 그런 자극은 없어, 아니면 늘 있어.



정말 중요한 것은 결국 자신이란 말야. 그 자극을 자극으로 받아들이고, 그걸 생활의 실천으로 옮기는 스스로의 노력이 없으면 그런 자극이 백번 있어도 아무 소용 없단 말야. 정말 나태에서 벗어날 참이면 코끝에 스치는 바람에도 삶의 의욕을 찾고, 그러지 않을 참이면 옆에 벼락이 떨어져도 늘 같은 상태라니까?



내가 자네만할 때는 말이지, 가을이면 특히 11월이면, 감상적이 되고 우울해지고 많이 그랬거든? "자 11월이다, 감상적일 때다" 하고 자기암시를 주기도 하고… 그래 놓고는 그 감정을 해소한다고 술도 마시고, 음악을 듣고… 그러면 더 감상적이 되고… 지금 생각해 보면 그걸 은근히 즐겼어. 딱지가 막 앉은 생채기를 톡톡 건드리면 따끔따끔 아프지만 재밌잖아? 내 젊은 날의 버거움이란 그런 딱지 같은 거였나봐.



나도 철이 들었나보지? 차츰 해결법을 찾았어. 감정은 육체의 버릇이라는 걸 깨닫게 된거지.

일조량의 부족, 운동량의 부족, 술/담배의 과다… 즐기지 않는 감정적인 문제에 근원이 있다면 그런 거야. 난 정말 감정에서 자유롭고 싶으면 한 4마일 정도를 달려. 오히려 술도 되도록 적게 마시지, 몸이 아니라 마음을 위해서. 그리고 무엇보다 일을 해. 꽤 효과 있어.



더 근원적인 건 '목표'의 문제야. 나태는 목표가 흐려질 때 자주 찾아오거든. 선생님 같은 나이에 무슨 새로운 목표가 있겠니?

내 목표란 '좋은 선생' '좋은 학자' 되는 건데, 그 '좋은' 이라는게 무척 애매하거든. 목표는 원대할수록 좋지만, 너무 멀면 동인이 되기 힘들어. 그래서 나 같은 경우엔 더 작고 구체적인 목표를 세우지. 대개 일주일이나 한달짜리 목표들…



슬럼프에서 벗어나고 싶어? '정말로' 원한다면 해결은 생각보다 쉬워. '오늘' 해결하면 되. 늘 '오늘'이 중요해. "오늘 할 일을 내일로 미루지 말라," 뭐 이런 차원이 아니야. 그냥 오늘 자전거의 첫페달을 밟고 그걸로 만족하면 되. 그런 오늘들이 무섭게 빠른 속도로 모이거든, 나태가 관성인 것처럼 분주함도 관성이 되거든.



사실은 선생님도 먼 나라에 혼자 떨어져서 요즘 감정적으로 무척 힘들어.

그래서 물리적인 생활을 무너뜨리지 않으려고 굉장히 노력해. 육체적인 것이 중요하다고 했잖아? 늦게 자지 않고, 일찍 일어나고, 술 마시지 않고, 햇빛 아래서 많이 움직이고 걷고 뛰고, 꼭 1시간은 색스폰 연습하고, 몇 글자라도 읽고, 3페이지 이상 글쓰고… 나는 잘 알거든, 이런 육체적인 것들이 무너지면 걷잡을 수 없이 나태 속으로 빠지게 되는걸. 여러 번 경험했거든.





힘 내. 얘기가 길어졌지? 내가 늘 그래. 대신 긴 설교를 요약해 줄게. (선생님답지?)



. 나태를 즐기지 마. 은근히 즐기고 있다면 대신 힘들다고 말하지 마.
. 몸을 움직여. 운동하고, 사람을 만나고, 할 일을 해. 술 먹지 말고, 일찍 자.
. 그것이 무엇이든 오늘 해. 지금 하지 않는다면, 그건 네가 아직도 나태를 즐기고 있다는 증거야. 그럴거면 더 이상 칭얼대지 마.
. (마지막이야 잘 들어?) 아무리 독한 슬픔과 슬럼프 속에서라도, 여전히 너는 너야. 조금 구겨졌다고 만원이 천원 되겠어? 자학하지 마, 그 어떤 경우에도, 절,대,로.



그거 알아? 모든 것은 흘러. 지나고 나면 이번 일도 무덤덤해 질거야. 하지만 말야, 그래도 이번 자네의 슬럼프는 좀 짧아지길 바래.


잘 자.
(아니, 아직 자지 마. 오늘 할 일이 있었잖아?)

새임.

(2005. 2.) 서울대학교 김난도 교수


Posted by 생각처럼
, |
Posted by 생각처럼
, |

한글 깨짐 문제

Bit/C# / 2012. 2. 3. 17:04
Posted by 생각처럼
, |
Posted by 생각처럼
, |

PHP란 무엇인가?

Bit / 2012. 2. 3. 17:03
Posted by 생각처럼
, |

I have an MDI application that allows me to open different types of child windows. I can open multiple (but different) instances of the same type of child window. (Example: I can open 3 instances of child window type A and 2 instances of child window type B. All 5 windows are distinct entities and do not share data until unless the user explicitly drags the same data onto multiple windows.) Each child window has a ToolStripContainer with one or more ToolStrips. How do I prevent:

  1. the user from dragging a ToolStrip from a child window of type A to a ToolStripContainer in a child window of type B?
  2. the user from dragging a ToolStrip from one instance of child window A to a ToolStripContainer in another instances of the same type of window?

I'm trying to prevent the user from dragging a ToolStrip from instance 1 of type A to instance 2 of type A, selecting some stuff on instance 2, and then clicking a button on the toolbar only to have something weird happen to some other window. Similarly it doesn't make sense to drag a ToolStrip from a window of type A to a window of type B -- the actions don't apply to that type, but to the user it looks like everything is fine because I let them do the drag.

Is it as simple as adding my own handler for the ControlAdded event or is there a better way to do this? I'm using WinForms in .NET 3.0.

edit: Steps to reproduce

  1. Create a new Windows Application project.
  2. Add a new user control. Give the control a ToolStripContainer that contains one ToolStrip with a single button.
  3. Repeat step 2, giving you a UserControl2 class.
  4. Compile the solution so UserControl1 and UserControl2 show up in your toolbox.
  5. Drag UserControl1 and UserControl2 onto the form. Set the borders so you know where the boundaries are.
  6. Run the app.
  7. It's now possible to drag the ToolStrip from the container in UserControl1 and drop it into the container in UserControl2 (leaving zero ToolStrips in UC1 and two ToolStrips in UC2.)
  8. Now imagine you only have access to the code in UserControl1. How do you prevent the user from dragging the ToolStrip out of that instance of the ToolStripContainer?
link|edit|flag

40% accept rate
I tried to reproduce the problem that you are having but I can't seem to get it to work. Once I create two instances of the same form I can't drag the toolbar from one to the other in the first place – Nathan W Nov 18 '08 at 22:39

This feels like a hack, but it works (kind of) (sorry, vb.net not c#):

Public Class UserControl2

   
Private Sub tsMainMenu_BeginDrag(ByVal sender As Object, ByVal e As System.EventArgs) Handles tsMainMenu.BeginDrag

        tsMainMenu
.Tag = tsMainMenu.Parent

   
End Sub

   
Private Sub ToolStrip1_EndDrag(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tsMainMenu.EndDrag


       
If Not tsMainMenu.Parent.Parent.Equals(CType(tsMainMenu.Tag, ToolStripPanel).Parent) Then

           
CType(ToolStrip1.Tag, ToolStripPanel).Controls.Add(tsMainMenu)
       
End If

   
End Sub

End Class

simply put; when the control is finished being dragged, if its parent ToolStripContainer is not the same as it was when it started dragging, move the toolstrip back to where it was.

im sure this could be rolled into a control so that you dont have to write it for every toolbar.

Edit: You could put all this code into a control that inherits from ToolStripContainer, and have it do all the work for you, meaning a nice encapsulated solution.

Posted by 생각처럼
, |

윈폼에 엑셀 출력

Bit/C# / 2012. 2. 3. 17:02

엑셀의 경우 메크로 기능을 사용하면
거의 모든 프로그램이 가능하다.

아주 대단한 개발툴이 될수 있는것이다.

엑셀은 통계도 좋고, 프린트 하기도 아주 좋고. 뭐 두루두루 뛰어난다는거~^^

그런 엑셀을 엑셀 폼에 뛰우지 않고 윈도어플리케이션안에 띄어서 사용을 할경우 
필요할수 있을것 같다.

방법은 2가지 정도로 압축을 할수 있을것 같다

엑셀 Process를 윈도어플에 넣어주는 방법이 있을것이고
WebBrowser객체 안에 엑셀을 띄워 Browser를 WinApp에 넣어주면 될것이다.

첫번째 방법은
[DllImport("user32.dll")]
static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);

panContents.SuspendLayout();
runProcess = new Process();
ProcessStartInfo info = new ProcessStartInfo();
info.FileName = fileName;
info.WindowStyle = ProcessWindowStyle.Normal;
//info.Arguments = "10492";
runProcess = Process.Start(info);

SetParent(runProcess.MainWindowHandle, panContents.Handle);

panContents.ResumeLayout();

을 사용해서 가능할것이고

두번째 방법은
WebBrowser webBro = new WebBrowser();
 webBro.Dock = DockStyle.Fill;

webBro.Navigate(fileName);
panContents.Controls.Add(webBro);

이런식으로 처리를 하면 될것이다.

물론 더 좋은 방법도 있겠지만 내가 찾아낸 방법은 요정도..ㅎㅎ

Posted by 생각처럼
, |

출처 헝그리 유저 SSuk 마음대로 | Initial H
원문 http://blog.naver.com/gkarltjr/126111585
 

                  쿠아이롬으로 생활중인 모토쿼티 배터리를 너무 빨리 잡아먹어 버립니다.

매일 매일 배터리 갈아주는 것도 귀찮고. 리튬 폴리머는 자주 충전해주는 것이 좋다기에

도킹 스테이션을 만들어보기로 합니다.

과거 3.5인치 하드 도킹을 만들어본 경험이 있는지라..

쉽게 만들수 있을꺼란 생각을 하고 도전했습니다.!

하드보드지 + 목공본드 조합으로 만들었습니다~


3년전에 만들었던 3.5인치 하드 도킹입니다~

(하드보드지 + 목공본드 + 3.5인치 하드 usb변환 젠더)








모토쿼티 자작 도킹 스테이션 

(하드보드지 + 목공본드 + 마이크로 usb 5핀 단자 + 자석 + 글루건 + 부직포 + 가죽시트지)

















시연 동영상

<iframe frameborder="no" width="500" height="408" scrolling="no" name="mplayer" id="254C88CBDAC519FC7271FAC747D9481FF4D6" src="http://blog.naver.com/post/multimediaFLVPlayer.jsp?vid=254C88CBDAC519FC7271FAC747D9481FF4D6&inkey=V1256a09806fc26511142343b1734c0a7d68a568c7699507115817d457c7bf352365c343b1734c0a7d68a&width=500&height=408&ispublic=false">


휴대용 자작 micro usb 




도면 필요하신 분들은 도면 보내 드리겠습니다~

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓



생각보다 도면 찾으시는 분들이 많이 있네요..

도면 첨부파일로 추가합니다~


micro 5핀 단자는

디바이스 마트 : http://www.devicemart.co.kr/mart7/mall.php?cat=013020021&query=view&no=35106 (케이스X)

엔씨 일렉트로닉스 : http://www.nexconn.net/mall2/index.jsp (케이스 O)

구매했습니다~ 저는 케이스 있는 곳에서 구매했는데. 배송비가 500원 더 비쌉니다~


도면 받으실때 예의상 덧글 남겨주시면 감사하겠습니다~


일러로 작업 했습니다~



〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓


도면에 자석 위치 추가했습니다~


그리고 한가지 팁을 더 드리자면

도킹 만드실때 마이크로 5핀에 걸쇠 부분은 제거 하는게

쿼티를 꼽고 뺄때 편하실꺼에요~


〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓

pdf파일로도 첨부해 드립니다~

Posted by 생각처럼
, |

svn 권한 설정

Bit / 2012. 2. 3. 17:01

출처 kimsk99님의 블로그 | 솔라리스
원문 http://kimsk99.blog.me/50096526825

svn(Subversion)이 처음 만들어 졌을 때는 권한 설정에 대한 옵션이 약했으나 점점 강화되어 지금은 많이 강해졌다.

권한 설정, 특히 svn의 각 direcotry별로 다른 권한을 설정하는 방법을 알아보자. 

 

Login

svn에 login하는 방법은 svnserve의 passwd파일을 사용하는 방법과 apache의 자체 로긴을 이용하는 방법이 있다.

여기서 apache의 자체 로긴은 access파일을 이용한 것과 기타 로긴 시스템(윈도우 NT 로긴 시스템)을 이용한 것등을 이용할 수 있다.

 

디렉토리별 권한

directory별 권한 설정은 svnserve와 apache모두 공통적으로 사용한다.  

먼저 인증된 ID를 기준으로  그룹을 설정할 수 있다.

그리고 디렉토리 별로 그룹 또는 ID의 권한을 할당할 수 있다.

참조: http://svnbook.red-bean.com/nightly/en/svn.serverconfig.pathbasedauthz.html

 

독립된 여러 개의 repository 의 운용

apache를 사용하면 독립된 여러 개의 repository를 같이 사용할 수 있다.

회사에서 수행되는 각 프로젝트 마다 하나씩 repository를 할당해 주는 것이 가능한 것이다.

그리고 위에 설명된 '디렉토리별 권한'을 설정해서 사용하면 거의 완벽한 운용이 가능하다.

 

그런데 이런 것을 자동화 해주는 툴은 없을 까?

UI등을 이용해서 손쉽게 각각의 repository를 생성하고 권한을 설정한다.

또한 각 repository에 있는 directory 별로도 권한을 설정한다.

이런 툴이 있다면 좀더 편한 권한 관리가 가능할 텐데..

Posted by 생각처럼
, |

출처 ♡SweetLove♡ LoveHouse | 크라우젠
원문 http://gy801110.blog.me/94607776
 

                  사이트 : src/resources-development

 

다운로드 주소 : http://subversion.tigris.org/servlets/ProjectDocumentList?folderID=91

 

파일 : Setup-Subversion-1.5.6.msi  or svn-win32-1.5.6.zip

 

받을 파일의 압축을 푼다. 필자의 경우 (C:\Python25\svn-win32-1.5.6)에 압축을 풀었다.

 

SVN의 해당 패스를 등록한다. (윈도우7 기준 : 내컴퓨터 > 우측 버튼 속성 > 시스템보호 > 고급 > 환경 변수)

 

시스템 변수 에 svn~~`\bin을 등록한다. 아래 그림을 참조한다.

 

 

콘솔 창을 띄우고(명령 프롬프트 : 윈도우 키 > 실행 > cmd)

 

저장장소로 이동한다. (필자의 경우 C:\Python25\Repository에 디렉토리를 만들었다.)

 

svnadmin create LoveHouse를 입력한다. LoveHouse는 프로젝트 이름이다. ^^

 

실행하게 되면 LoveHouse의 디렉토리에 SVN 설정과 관련된 디렉토리와 파일이 생성된다.

 

 

다음으로는 SVN 프로토콜을 사용하기 위한 서버 설정을 해주어야 한다.

 

해당 프로젝트 SVN 설정으로 이동한다. (필자의 경우 C:\Python25\Repository\LoveHouse\conf)

 

svnserve.conf파일에서 붉은색 부분의 주석(#)을 제거 한다.

 

 [general]
### These options control access to the repository for unauthenticated
### and authenticated users.  Valid values are "write", "read",
### and "none".  The sample settings below are the defaults.
# anon-access = read
# auth-access = write
### The password-db option controls the location of the password
### database file.  Unless you specify a path starting with a /,
### the file's location is relative to the directory containing
### this configuration file.
### If SASL is enabled (see below), this file will NOT be used.
### Uncomment the line below to use the default password file.
 password-db = passwd
### The authz-db option controls the location of the authorization
### rules for path-based access control.  Unless you specify a path
### starting with a /, the file's location is relative to the the
### directory containing this file.  If you don't specify an
### authz-db, no path-based access control is done.
### Uncomment the line below to use the default authorization file.
 authz-db = authz

 

anon-access 항목의 설정은 로그인하지 않는 사용자에게 접근 권한을 설정하는 부분이다.

anon-access 항목은 read, write, none 세 가지 값으로 설정할 수 있다.

read는 읽기 권한, write는 쓰기 권한, none는 읽기와 쓰기 권한을 허용하지 않는 설정이다.

 

auth-access 항목의 설정은 로그인한 사용자에 대한 접근 권한을 설정하는 부분이다.

auth-access 항목도 anon-access 항목과 같이 read, write, none 세 가지 값을 가진다.

 

passwd-db 항목은 저장소에 접근할 사용자 계정과 비밀번호 관리할 파일의 이름을 지정하는 것이다.

기본 파일 이름은 passwd를 사용하며, 다른 이름을 사용할 수도 있다.

 

authz-db 항목은 파일과 디렉토리에 대한 접근 권한을 관리하는 파일의 이름을 지정하는 것이다.

기본 파일 이름은 authz를 사용하며, 다른 이림을 사용할 수 있다.

 

 

다음으로 passwd 설정을 한다.

 

passwd를 메모장이나 워드패드를 통해서 열게 되면 아래와 같이 보이게 된다.

 

새로운 사용자를 추가하려면 사용자 아이디 = 비밀번호로 입력하면 된다.

 

예를 들어 admin이라는 사용자의 패스워드가 admin이라면 admin = admin으로 입력하면 된다.

 

 

 

다음으로는 authz 파일의 설정이다. 같은 디렉토리 (필자의 경우 C:\Python25\Repository\LoveHouse\conf)에 authz라는 파일을 열어보자.

이 파일의 경우 사용자와 그룹별로 각 디렉토리, 파일에 대한 접근 권한을 설정할 수 있다.

 

 

authz 설정 파일에 디렉토리, 저장소별 경로 설정 방법
 
 경로 설명 
 [foo/bar]  /foo/bar 디렉토리에 대한 접근 권한 설정이다. 저장소가 하나일 때 유용하게 사용할 수 있다.
 [/trunk:/pom.xml]  /trunk 디렉토리의 pom.xml 파일에 대한 접근 권한 설정이다.
 [LoveHouse:/bar/fuz]  LoveHouse 저장소의 /bar/fuz 디렉토리에 대한 접근 권한 설정이다. 여러개의 저장소에서 authz 파일을 공유할 때 사용한다.
 [LoveHouse:/trunk/pom.xml]  LoveHouse 저장소의 /trunk 디렉토리 아래에 pom.xml 파일에 대한 접근 권한 설정이다.
 
authz 설정 파일에 사용자, 그룹별 권한 설정 예제
 
 권한 설정 예제  설명
 harry = rw  harry 아이디를 쓰는 사용자에게 읽기(r), 쓰기(w) 권한이 있다.
 &joe = r  joy 그룹에 읽기(r) 권한이 있다. 권한을 설정할 때 그룹 앞에는 &을 사용한다.
 sally =  sally 아이디를 쓰는 사용자는 설정한 경로에 접근할 권한이 없다.
 
해당 설정 파일을 아래와 같이 추가한다.
 

 [groups]
# harry_and_sally = harry,sally
# harry_sally_and_joe = harry,sally,&joe
developergroup = developer1, developer2, developer3

 

[LoveHouse:/]
@developergroup = rw
*=r

 
그룹 developergroup를 만들고 그룹안에 developer1, developer2, developer3를 추가한다.
LoveHouse 저장소에 접근할 때 그룹 developergroup는 읽기, 쓰기 권한을 주어진다.
 
 
자 마지막으로 SVN 서버 시작이다.
 
svnserve -d -r C:\Python25\Repository\LoveHouse 실행을 한다.

Posted by 생각처럼
, |

최근에 달린 댓글

최근에 받은 트랙백

글 보관함