웹 사용자 정의 컨트롤(*.ascx)파일을 동적으로 참조하기...

 

System.Web.UI.Control uc;

 private void Page_Load(object sender, System.EventArgs e)
{

   uc = LoadControl("list.ascx"); // 참조하고자 하는 웹 사용자 정의 컨트롤 경로를 할당해준다.

   uc.ID = "list";   //컨트롤의 ID 할당

   Controls.Add(uc);

}

  • switch case문을 이용하여 상황에 맞는 컨트롤을 참조할 수 있다.

by 이상한돌 | 2006/06/07 15:22 | 트랙백 | 덧글(0)

 

DB 연결하기

참조 네임스페이스
* System.Data
* System.Data.Common
* System.Data.SqlClient
* System.Data.OleDb
* System.Data.Odbc
* System.Data.SqlTypes



연결 문자열선언
string strConn = "data source=서버;initial catalog=데이터베이스;user id=계정;password=비밀번호";

연결 생성
SqlConnection conn = new SqlConnection();
conn.ConnectionString = strConn;
conn.Open();

or

SqlConnection conn = new SqlConnection(strConn);
conn.Open();

by 이상한돌 | 2006/06/05 08:32 | 트랙백 | 덧글(0)

 

Visual Studio .NET Framework BootStrapper Plug-in을 사용한 .NET Framework 재배포


Visual Studio .NET Framework BootStrapper Plug-in을 사용한 .NET Framework 재배포


Microsoft Visual Studio .NET 2003 Bootstrapper Plug-in 다운로드


Visual Studio .NET 2003의 설치 프로젝트는 응용 프로그램과 함께 .NET Framework를 설치하는 데 사용할 수 있지만, 개발 컴퓨터에 Visual Studio .NET Framework BootStrapper Plug-in 옵션을 설치한 경우에만 가능합니다.

Visual Studio .NET Framework BootStrapper Plug-in은 .NET Framework 부트스트래퍼뿐만 아니라 Windows Installer 부트스트래퍼를 포함하도록 설치 프로젝트의 부트스트래퍼 속성 기능을 수정합니다. 그런 다음 .NET Framework의 재배포 가능 요소는 사용자의 응용 프로그램과 함께 패키지화됩니다. 사용자가 부트스트래퍼 setup.exe를 실행할 경우 이 실행 프로그램은 설치 시에 .NET Framework의 버전이 올바른지 확인하고 필요할 경우 응용 프로그램을 설치하기 전에 이 .NET Framework 버전을 설치합니다.

참고 영어 외의 언어일 경우 해당 언어용 언어 팩이 .NET Framework와 함께 설치됩니다.

참고 Visual Studio .NET Framework BootStrapper Plug-in은 웹 부트스트래퍼를 수정하지 않습니다. 부트스트래퍼 속성을 웹 부트스트래퍼로 설정하면 웹을 통해서만 Windows Installer의 부트스트래핑을 실행할 수 있습니다.

또한 응용 프로그램에서 데이터 액세스가 필요한 경우, 설치할 때 Microsoft Data Access Components(MDAC)를 함께 설치할 수 있습니다.

플러그인이 설치되어 있는지 확인하려면
제어판에서 프로그램 추가/제거를 클릭합니다.
프로그램 추가/제거 대화 상자의 현재 설치된 프로그램 목록에서 Microsoft Visual Studio .NET 2003 BootStrapper Plug-in을 확인합니다.
만약 Microsoft Visual Studio .NET 2003 BootStrapper Plug-in이 설치되어 있지 않으면 Visual Studio .NET Framework BootStrapper Plug-in을 다운로드하여 설치해야 합니다.

참고 Visual Studio .NET Framework BootStrapper Plug-in을 제거하려면 목록에서 선택하여 제거를 클릭하면 됩니다.

설치 프로젝트를 이용해 .NET Framework를 설치하려면
Visual Studio .NET Framework BootStrapper Plug-in이 설치되어 있는지 확인합니다.
솔루션 탐색기에서 설치 프로젝트를 선택합니다. 프로젝트 메뉴에서 속성을 선택합니다.
부트스트래퍼 속성을 Windows Installer 부트스트래퍼로 설정합니다.
.NET Framework 재배포 가능 요소가 완성되면 설치 프로젝트용 Setup.exe와 함께 패키지로 제공됩니다 .

참고 .NET Framework의 시작 조건은 .NET Framework를 참조하는 모든 프로젝트를 위해 기본적으로 사용 가능하도록 설정되어 있어야 합니다. 시작 조건을 확인하려면 보기 메뉴에서 편집기를 가리킨 다음 시작 조건을 선택하고 .Net Framework라고 되어 있는 시작 조건을 찾습니다.

설치 프로젝트를 이용해 MDAC를 설치하려면
Visual Studio .NET Framework BootStrapper Plug-in이 설치되어 있는지 확인합니다.
솔루션 탐색기에서 설치 프로젝트를 선택합니다. 보기 메뉴에서 편집기를 가리키고 시작 조건을 선택합니다.
대상 컴퓨터의 요구 사항 노드를 선택합니다. 작업 메뉴에서 레지스트리 시작 조건 추가를 선택합니다.
RegistryEntry1 검색 노드를 선택합니다. 속성 창에서 RegKey 속성을 선택하고 SoftwareMicrosoftDataAccess를 입력합니다.
Root 속성을 선택한 다음 vsdrrHKLM를 선택합니다.
Value 속성을 선택한 다음 FullInstallVer를 입력합니다.
Property을 선택한 다음 MDACSEARCH를 입력합니다.
시작 조건 편집기에서 Condition1 노드를 선택합니다. 속성 창에서 Condition 속성을 선택한 다음 MDACSEARCH>="2.6"을 선택합니다.
솔루션 탐색기에서 설치 프로젝트를 선택합니다. 프로젝트 메뉴에서 속성을 선택합니다.
부트스트래퍼 속성을 Windows Installer 부트스트래퍼로 설정합니다.
.NET Framework 재배포 가능 요소와 MDAC는 설치 프로젝트를 위한 Setup.exe와 함께 패키지로 제공됩니다.


by 이상한돌 | 2005/08/04 03:39 | * C# | 트랙백 | 덧글(0)

 

스타일가이드작성 개략

스타일 가이드란 뭔가.. (검색추천)

어쨌든 스타일 가이드란 것은 디자이너의 머릿속에 들어차 있는 한 프로젝트의 개별적인 디자인에 관한 세부사항에 대한 정의를 문서화한 정보를 말하는것.. 이라고 생각할 수 있겠다.

스타일가이드는 편집에서부터 웹작업까지 두루 작성되는 것인데..

편집의 경우는 주기적으로 재발간해야 하는 프로젝트의 경우.. 혹은 후임자나 보조자에게 작업을 맡겨야 할 경우를 대비해 작성된다.



웹분야는 그 작성에 있어서 자유롭고 여러명이 작업하게 되는 경우가 많으며 제작자와 관리자가 다른 경우도 다반사이기 때문에 이 스타일 가이드가 필수.. 라곤 하지만 대부분 안만든다 ㅡ,.ㅡ

이유인즉.. 웹이라는 매체는 레이아웃에서부터 각 개별폰트까지 다 지정을 해야 하는 스타일가이드에 있어서 치명적인.. 가변요소를 너무나 많이 안고 있기 때문이다.



웹디자인을 할 때 대부분 정형화된 한가지 스타일만을 작업하는 것이 아니라.. 각 카테고리별, 혹은 성격별로 많은 형태의 페이지가 생성되고, 그 각각의 페이지들은 각기 다른 스타일을 가지게 된다. 게다가 페이지 수는 좀 많은가!! 그런 이유로 웹디자이너에게 스타일 가이드 작업은 실제 작업시간보다 더 많은 시간을 할애하게 만드는 뜨거운 감자가 되어버리고 마는 것이다.



만약 내가 만들고 내가 관리하는 사이트라면 PSD원본만 열어보면 컬러와 폰트 등의 요소들이 모두 한눈에 보여지고 스타일시트 파일을 열어보면 모든 문서의 스타일이 정의되어 있을 것이지만..

어차피 개인작업 개인관리를 할 수 없는 에이젼시 팀 체제에서 스타일가이드는 어쩔 수 없는 선택인거다. (뭐 당연히 만들어야 한다고 주장한다면 나도 할말은 없지만.. 그래도 그거 시간 잡아먹는건 어쩌남..)



이런 이유로 중대형 규모의.. 유지보수 및 추가개발이 이루어지는 사이트를 제작하게 된 본인은..

눈물을 삼키며 스타일 가이드 계획을 짜고 있다.

사이트 완성 후 스타일 가이드를 별도로 만든다는 것은 좀 어리석은 짓인것 같고..

아무래도 처음 디자인을 시작할 때 스타일의 기본적인 부분들을 정의해 두고 가변적인 요소들을 추가해나가면서 작업하면 차후 정리에 의한 스타일가이드가 탄생될 것 같은 생각이 든다.

(일전에 한번 작업 마무리 후 스타일가이드 제작을 몰아서 하다가 실패 본 경험이 있다)



스타일 가이드 작업을 하게 되면 자신이 일관성 있게 컨셉에서 파생된 스타일을 지켜나가고 있는지 정확히 파악 할 수 있는 장점이 있다. 후임자나 작업참여자 혹은 관리자에게만 필요한 스타일 가이드가 아니라 제작자 자신에게도 사실은 스타일 가이드가 필요한 셈이다.

PSD파일에만 의존하기에는 한가지 이미지에서 파생되는 페이지가 너무도 많으며 각각의 페이지에 개별적으로 디자인을 적용하다보면 분명 어디선가 스타일에 어긋나는 것을 만들어 넣어버리는 경우도 생기게 된다(적어도 나는 그렇더라ㅡ,.ㅡ)



그런 여러가지 이유에서 스타일 가이드는 사실 필수라고 말할 수 있는데..

이번 작업에서 그럴 일이 생겨버렸다.

소규모 개발에서 시작해서 차후 추가개발로 이어지는 프로젝트라 스타일 가이드가 필수이긴 한데.. 당췌 이걸 작성해봤어야지.. 스타일가이드 작성법이라든가.. 작성사례같은거 많이 보긴 했어도.. 막상 적용하자면 뭔가 커스터마이징이 되어야 한단 말이거든.



일단 내가 작성하고자 하는 요지는..

1. 컨셉 및 컬러테마.

2. 카테고리별 테마

3. 컨텐츠 종류별 테마.

4. 별도창 테마. 등으로 구성되며



소분류로는

1. 레이아웃컨셉

2. 컬러컨셉

3. 타이포컨셉 등이 있을것이고



그 하위분류로는

1. 각 분류별 레이아웃 정의

2. 분류별 컬러 정의 및 응용방안

3. 분류별 타이포 정의 및 응용방안 등

이 될 것이다.



정리해보니 간단하네 뭐... (라고 말은 해도 아마.. 무시무시하게 많은 분량이 될게 뻔하다. ㅡ,.ㅡ)

한페이지에만도 엄청난 수의 컬러가 사용되고 엄청난 종류의 타이포가 응용된다.

레이아웃이야 크게 바뀌지 않으니까 문제가 없지만..

팝업이나 외부창이 생겨버리면 그에 따른 별도의 스타일 가이드가 작성되어야 하는게다.



아마도.. 올 휴가는 느즈막히로 연기되지 않을까 싶다.



스타일 가이드 작성에 도움이 되는 자료가 있으신 분은 본인에게 연락주기 바람. ^^

더불어 위에 틀린점이 있거나 고칠점이 있다면 알려주기 바랍니다.

(후사하겠음. - 스티치의 손으로 직접붙인 봉투 같은것... - ㅡ,.ㅡ)

by 이상한돌 | 2005/07/29 22:00 | * 잡생각 | 트랙백 | 덧글(0)

 

웹 스타일 가이드

웹 스타일 가이드는 미국 예일 대학의 웹 스타일 가이드로부터 시작된 것으로 파악된다. 예일 대학의 웹 스타일 가이드는 단지 예일 대학을 위한 것일 뿐 아니라 일반적인 웹사이트 개발의 지침이 될 만하다. 예일 대학이 웹 스타일 가이드를 만든 이후 카네기멜론 대학 등 수 많은 대학과 기업들이 쫓아서 웹 스타일 가이드를 만들기 시작했다.





1. 대학의 웹 스타일 가이드


대학의 경우 단과대학과 학과, 교수진, 운영부서 단위로 다양한 필요와 목적에 따라 수많은 운영주체에 의해 웹 페이지가 개발되고 운영된다. 이런 경우 종종 한 대학에 서로 다른 모양과 느낌의 사이트들이 생겨나기 쉽다. 따라서 대학들은 일관된 대학 사이트의 아이덴티티와 브랜드 이미지를 유지하고 사이트 유지관리의 편리성을 위하여 웹 스타일 가이드를 필요로 하게 된다. 국내 대학의 웹사이트들 대부분은 아직 이러한 웹 스타일 가이드를 마련하지 못한 경우가 대부분이며, 따라서 대학과 관련된 웹사이트들의 통일된 이미지를 형성하는 데 실패하고 있다고 볼 수 있다.





2. 기업의 웹 스타일 가이드


삼성이나 한국통신과 같은 대기업과 GE, IBM, Compaq, Citi Bank와 같은 글로벌 기업들 역시 웹 스타일 가이드를 만들고 있다. 이들 기업들은 조직 내 다양한 부서에서 각자의 필요성과 목적에 따라 만들어지는 웹사이트들의 통일성 있는 개발과 웹을 통한 일관된 브랜드 이미지의 구축, 일관된 사용자 경험의 구현, 사이트 유지관리 보수의 편리성을 위해 속속 웹 스타일 가이드를 개발하고 있다. 비록 거대기업이 아닌 단일 기업일 경우에도 인터넷 관련 인력(디자이너, 프로그래머, 기획자)의 잦은 이직과 교체를 고려할 때 이러한 웹 스타일 가이드의 작성은 여전히 필요하다고 할 수 있다.





3. 웹에이전시의 웹 스타일 가이드



웹에이전시들은 고객사를 위해 웹 스타일 가이드를 개발할 수 있어야 한다. Proxicom과 같은 미국의 유수 에이전시는 프로젝트를 마무리하기 전에 필수적으로 고객사에게 웹 스타일 가이드를 작성하여 전달하고 있다. 웹 스타일 가이드는 최소한 프로젝트 개발의 결과물을 체계적으로 정리하여 제출하는 의미가 있을 뿐 아니라, 웹 스타일 가이드를 개발한다는 것 자체가 사실상 효율적이고 체계적으로 웹사이트 개발 작업을 해 왔다는 것을 증명하는 것이기도 하다. 만약 당신이 사이트 개발을 웹에이전시에게 의뢰한 고객사라면 프로젝트의 마무리에 디자인 작업의 결과물로서 그래픽 파일들과 HTML 템플릿과 함께 잘 정리되고 상세한 설명이 덧붙여진 '웹 스타일 가이드'를 받는다면 얼마나 좋겠는가? 웹 스타일 가이드없이 떠나가는 웹에이전시와 좀 더 철저하게 '웹 스타일 가이드'를 작성하여 제출하고 마무리 짓는 웹에이전시 어떤 쪽에 더 신뢰가 가고 후속 프로젝트를 맡기겠는가? 웹 스타일 가이드의 작성 목적을 요약하면 웹사이트의 통일되고 일관된 사용자 경험(User Experience)을 구현하고, 사이트의 추가개발 및 유지보수의 편리성을 높이는 데 있다.



체계적이고 일관된 사용자 경험(User Experience)은 결과적으로 사용자들에게 사이트의 일관되고 통일된 아이덴티티(Identity)와 브랜드(Brand) 이미지를 형성한다. 이러한 목적으로 만들어지는 웹 스타일 가이드는 체계적인 사이트 개발 작업의 결과물인 셈이다.





웹스타일 가이드의 종류



웹사이트 디자인 방법을 설명하는 수많은 가이드가 쏟아져 나오고 있다. 이들 웹 디자인 가이드는 두 가지 유형으로 구분할 수 있다. 하나는 HTML 기법에 대한 내용을 다루고 있는 웹 개발 가이드들이고, 또 다른 한 종류는 디자인 측면을 강조하고 있는 웹 디자인 가이드이다. 여기서 다루고자 하는 것은 후자이다. 후자에 가까운 '웹 스타일 가이드' 역시 일반적인 웹 디자인 방법을 소개하는 경우와 특정기업이나 조직(특히 학교나 종교기관), 단체의 웹사이트를 위한 고유한 웹 스타일 가이드가 있다.



특정 조직을 위한 웹 스타일 가이드의 경우 웹사이트 디자인의 일관성을 유지하므로 단일한 웹사이트에서의 브랜드 이미지를 전달하기 위해 이용된다. 또 하나의 목적은 웹 페이지의 추가 개발과 사이트 유지의 편리성을 위해 웹 스타일 가이드가 사용된다.



Agency.com에서 Compaq의 웹사이트를 위해 개발한 '웹 브랜딩 가이드'는 통일적인 웹 브랜드 이미지를 전달하는 데 초점을 둔 디자인 중심의 웹 스타일 가이드로 분류할 수 있다. 홍익 인터넷이 개발한 '한국통신 웹 스타일 가이드' 역시 웹 디자인의 일관성 및 온라인 오프라인의 브랜드 통일성을 위해 만들어진 스타일 가이드이다. 한국통신의 웹 스타일 가이드는 상세한 사용례와 템플릿이 돋보인다.



동일하게 디자인적인 측면(색상, 로고, 폰트, 레이아웃) 등을 강조한 웹 스타일 가이드이지만 GE의 웹 스타일 가이드는 그래픽 요소들과 함께 HTML 템플릿 소스까지 제공하고 있다는 점에서 그 어떤 웹 스타일 가이드보다 철저하다고 볼 수 있다.



반면 IBM이나 Sun이 자사의 웹사이트를 위해 만든 웹 스타일 가이드들은 단순히 디자인적 측면만을 강조한 것이 아니라 HTML, Java, CGI 등 적용기술과 관련된 가이드를 제시하고 있다. 일종의 총체적인 개발 가이드인 셈이다. 그래픽 템플릿과 프로그래밍 소스 및 적용방식을 자세히 설명하고 있다는 점에서 웹 개발 가이드에 가깝다고 볼 수 있다.





※ 웹사이트에서 사용자의 경험을 이루는 요소들



웹사이트의 구조(Structure),

네비게이션과 정보구조(Navigation & Information Architecture),

웹페이지의 시각적 디자인 요소,

상호작용(Interaction) 디자인,

기능(Function),

컨텐트(Content)





♣ 웹 스타일 가이드의 내용



웹 스타일 가이드는 어떤 내용들을 포함하는가? 물론 웹 스타일 가이드는 위에서 언급했듯이 여러 가지 종류가 있다. 여기서는 기술적 측면보다는 디자인 측면을 강조한 웹 스타일 가이드가 포함해야 하는 내용들에 대해서 살펴보도록 하겠다.



웹 스타일 가이드는 체계적이고 일관된 사이트에서의 사용자 경험(User Experience)을 개발하여 사용자에게 전달하는 것을 목표로 한다. 따라서 웹 스타일 가이드는 사용자 경험을 이루는 대부분의 요소들을 포함해야 한다.



웹사이트에서 사용자의 경험을 이루는 요소들은 웹사이트의 구조(Structure), 네비게이션과 정보구조(Navigation & Information Architecture), 웹페이지의 시각적 디자인 요소, 상호작용(Interaction) 디자인, 기능(Function), 컨텐트(Content) 등과 관련된 내용들을 담아야 한다. 다음은 웹사이트에서 사용자의 경험을 이루는 요소를 설명하고 있다.





웹 사이트의 목표전략과 전술



즉, 웹 스타일 가이드는 웹 사이트의 목표전략을 구체화 하는 전술이다. 한 웹 사이트의 초기 단계에는 규정하기 어려우나, 그 웹 사이트가 목적을 명확히 하고, 목적에 맞는 방문자를 맞이하고, 그 방문자들과 커뮤니케이션을 통해 발전하고 진화한다면, 일관성을 유지하며 장점만을 부각하기 위해선 여러 규칙과 안내가 필요한 것이다. 인쇄물의 형태든, 전자 문서의 형태든, 웹 스타일 가이드는 존재해야 한다.



이러한 웹 스타일 가이드는 아이덴티티 표출이 중요한 단일 서비스나 기업의 홍보 사이트, 여러 개의 회사가 모인 그룹사가 동일한 아이덴티티 사용으로 시너지가 극대화 될 수 있다고 판단되는 경우, 복수의 브랜드를 가졌으며 기업 이미지가 신뢰감 향상에 도움 되는 겅우, 사이트 운영 주체가 여러 조직이나 회사로 나누어 져 있을 경우, 원활한 비즈니스 전개와 커뮤니케이션, 효율적인 작업을 위하여 웹 사이트를 운영하는 기업과 단체에 필요하다.



개인적으로 스타일이 좋아 한가할 때면 종종 들려 보는 사이트가 있다. 이 사이트는 디지털넷진으로 매 달 주제를 바꾸어 가며 컨텐츠와 이벤트를 바꾸어 소개 한다. 이 넷진의 스타일은 주제를 나타내는 시원한 공간감이 돋보이는 플래쉬 인트로덕션. 강한 비쥬얼에 짧은 문단으로 구성된 읽을 거리 컨텐츠 구성. 플래쉬 애니메이션을 통한 스토리텔링으로 전개 되는 각각의 테마들, 인터뷰들. 깜찍하고 앙증맞은 캐릭터가 나오는 게임 등으로 구성된다.



매달 주제는 달라도 표현하는 형식들은 동일한데, 동일한 형식이 지겹지 않고 그 형식이 맞추어진 내용들에 따라 비슷한 듯 색다르게 보이는 장점이 있다. 매 달 다른 모습을 선보이면서도 규칙적인 스타일을 유지하는 것을 보면, 나름대로 탄탄한 스타일 가이드가 있으리라 하고 짐작 할 수 있다.





CI와 웹 스타일 가이드는 분명히 다르다!



그렇다면, 오프라인에서 사용되는 CI와 웹 스타일과의 관계는 어떨까? 이 둘은 규정하는 형태와 목적이 비슷하여 서로 포함 관계를 가질 수도 있겠다. 그러나, 분명한 것은 CI와 웹 스타일 가이드는 다르며, CI의 요소가 웹 스타일 가이드에 그대로 적용 될 수 없다. 웹 스타일 가이드는 컴퓨터 모니터를 기준으로, CI는 오프라인의 인쇄물이나 조형물을 대상으로 전개 되기에, 서로 적용되는 매체의 특성에 따라 구분되어야 한다. 웹 스타일 가이드는 CI에 비해 경험과 체험이 해당 사이트의 가치 증대에 중요하다는 것을 잊지 말자.



특히, 오프라인 CI를 연장하여 온라인에 적용할 경우, 단순히 로고나 심볼을 차용하여 비슷한 색상으로 고정된 위치에 웹 사이트에서 표현 하는 것이 웹 스타일 가이드의 전부라고는 생각하지는 말자. 왜냐면, 오프라인 CI를 연장하여 온라인에 왜 그렇게 적용해야 하는 가, 그 적용 효과가 무엇인가 고민하고 연구하여 답을 얻지 않은 상태에서 오프라인 CI요소를 흉내만 내었다면 그것은 아이덴티티를 구성하는 스타일이 아닌 따라 그린 그림에 불과 하기 때문이다.

by 이상한돌 | 2005/07/29 21:59 | * 잡생각 | 트랙백 | 덧글(0)

 

[펌] C#으로 COM 생성후 asp에서 사용하기...

안녕하세요. 마리입니다. ^^;



제가 또 뉴스그룹 서핑 도중... 질문을 하나 만났습니다.



"C#으로 COM을 생성하고 asp에서 VB나 C++의 COM처럼 사용할 수 있을까요?"



답변은 할 수 있다는 것이였습니다.



"C# 으로 만든 컴포넌트는 CCW( COM Callable Wrapper) 에 의해서 regsvr32.exe 로 COM 개체



를 등록된 것과 같은 효과로 등록되어질 수 있습니다."



저도 궁금하기도 하고 호기심도 생기고 해서... 테스트를 해보려고 맘 먹었습니다.



그런데 COM을 첨 해보는지라... 좀 헤맸습니다. ㅋㅋ



간단하게 테스트 예제와 함께 과정을 살펴보겠습니다.



(아래의 과정은 MS웹 사이트의 기술자료 http://support.microsoft.com/default.aspx?scid=kb;ko;306296 의 방법으로 한 것 입니다.)



먼저 새 프로젝트로 C#프로젝트에서 클래스 라이브러리를 하나 만듭니다.



이름은 ServicedCOM으로 하겠습니다.



자동 생성된 클래스 Class1의 이름을 Com_Test로 변경합니다. 아래... 생성자도 변경 하시는거



아시죠? ^^; 소스를 보여드리겠습니다.



using System;
using System.EnterpriseServices;

namespace ServicedCOM
{

public class Com_Test : ServicedComponent
{
public Com_Test()
{
}
public string DoTrans()
{
return ".NET COM+ Testing";
}
}
}



만약에 System.EnterpriseServices네임스페이스가 자동 완성되지 않으신다면...



솔루션 탐색기에서 참조추가를 합니다. 거기서 .NET 탭중 쭉..내리시면 있습니다.



등록을 해주세요. 소스는 간단한 문자열을 리턴하는 소스입니다.



이제 AssemblyInfo.cs파일에서 추가를 합니다.



System.EnterpriseServices 역시 상단에 using키워드로 명시하시구요.



[assembly: ApplicationActivation(ActivationOption.Library)]
[assembly: ApplicationName("Com_Test")]



이제 컴파일을 합니다. 그럼 dll파일이 하나 생기겠죠?



이제 어셈블리 이름을 강력하게 지정해야 합니다.



시작 메뉴에서 프로그램을 가리키고 Microsoft Visual Studio .NET을 누른 다음 Visual Studio .NET Tools를 눌러 Visual Studio .NET 명령 프롬프트를 엽니다.
명령 프롬프트에서 sn.exe -k ServicedCOM.snk를 입력하여 어셈블리에 강력한 이름을 지정합니다.

강력한 이름으로 어셈블리에 서명하는 방법에 대한 자세한 내용은 .NET Framework SDK 설명서를 참조하십시오.
ServicedCOM.snk를 프로젝트 폴더에 복사합니다.
AssemblyInfo.cs에서 AssemblykeyFile 코드를 다음 코드로 대체합니다.
[assembly: AssemblyKeyFile("..\..\ServicedCOM.snk")]
자... 이제 레지스트리에 등록을 해야 합니다.



시작 메뉴에서 프로그램을 누르고 Microsoft Visual Studio .NET을 누른 다음 Visual Studio .NET Tools를 눌러 .NET 명령 프롬프트를 엽니다.
.NET 명령 프롬프트에서 regsvcs 프로젝트경로inDebugservicedcom.dll을 입력합니다. 그러면 클래스와 같은 이름의 COM+ 라이브러리 응용 프로그램이 만들어집니다.
이제 완료가 되었습니다.



간단한 asp코드로 테스트를 해보세요.



<%
set Com = server.createobject("ServicedCOM.Com_Test")
response.write Com.DoTrans()
%>







서핑 하던 도중 다른 방법도 있군요...





using System;

namespace ServicedCOM
{

public class Com_Test

{
public Com_Test()
{
}
public string DoTrans()
{
return ".NET COM+ Testing";
}
}
}



어셈블리쪽은 건드리지 마세요. 아... 위의 소스가 아니고 첨의 그대로...



regasm 프로젝트경로inDebugServicedCOM.dll /codebase



이렇게 하면 COM에 등록이 됩니다. 사용법은 위와 동일하구요....

by 이상한돌 | 2005/07/26 00:03 | * C# | 트랙백 | 덧글(0)

 

Unmanaged Dll호출관련 정리노트

Using unmanaged dll in C#



Platform Invocation(PInvoke)는 Dll에 구현된 unmanaged function을 managed code에서 호출할 수 있게 하는 서비스이다.(자세한 내용은 "플랫폼 호출"을 참고)



exported dll 함수를 사용하려면
1. Dll의 함수를 식별
최소요구정보 - 함수이름, Dll이름

Dll함수의 ID의 구성요소 - 함수이름 또는 서수, 구현이 있는 Dll파일의 이름, 이 정보를 이용하면 관리되는 정의를 작성하며, 또한 플랫폼 호출에서 함수를 만들고 함수에 대해 데이터를 마샬링하는 방법을 조정할 수 있다.

User32.dll에 있는 MessageBox함수를 지정하면 함수(MessageBox)와 함수의 위치(User32.dll, User32 또는 user32)를 알 수 있다. MS Windows 응용 프로그래밍 인터페이스(Win32 API)는 각 함수에 대해 문자와 문자열을 처리하는 두 개 버전(1바이트 문자 ANSI와 2바이트문자 유니코드 버전)을 포함할 수 있다. 아무것도 지정치 않으면 default는 ANSI이다
MessageBoxA는 MessageBox함수에 대한 ANSI진입점을 나타내고 MessageBoxW는 동일한 함수에 대한 유니코드 버전을 나타낸다.

Unmanaged Dll의 함수이름을 바꿀 수도 있는데, 이 경우에는 함수의 이름을 Dll의 원래 진입점에 매핑해야한다. (플랫폼 호출에서 사용되는 닷넷기반 선언의 생성 방법을 보여 주는 예제는 "플랫폼 호출을 사용하여 데이터 마샬링"을 참조)
진입점은 Dll에서의 함수 위치를 식별한다. managed project에서 대상함수의 원래 이름또는 서수 진입점은 상호 운용 경계 내에서 해당 함수를 식별하는 데 사용된다. 진입점을 다른 이름에 매핑하면 함수의 이름을 바꿀 수도 있다.
다음은 함수 이름을 바꿀 수 있는 경우이다.
- 대/소문자를 구분하는 API함수 이름을 사용하지 않으려는 경우
- 기존 명명 규칙을 따라야 하는 경우
- 동일한 Dll함수의 여러 버전을 선언하여 다른 데이터 형식을 사용하는 함수를 적용하려는 경우
- ANSI 및 Unicode 버전이 들어 있는 API를 간단하게 사용하려는 경우
DllImportAttribute.EntryPoint필드를 사용하여 Dll함수의 이름 또는 서수를 지정할 수 있다. 메서드 정의의 함수 이름이 Dll의 진입점과 동일한 경우에는 EntryPoint필드를 사용하여 함수를 명시적으로 식별하지 않아도 되지만, 함수 이름과 Dll진입점이 다른 경우에는 다음 특성 폼 중 하나를 사용하여 함수의 이름 또는 서수를 지정해야 한다.

[DllImport("dllname", EntryPoint="FunctinName")]
[DllImport("dllname", EntryPoint="#123")]
서수에 파운드 기호(#)를 접두사로 붙여야한다.
예제는 EntryPoint필드를 사용하여 MessageBoxA를 MsgBox로 바꾸는 것을 보여준다.

using System.Runtime.InteropServices;

public class Win32{
[DllImport("user32.dll", EntryPoint="MessageBoxA")]
public static extern int MsgBox(int hWnd, string text, string caption, uint type);



2. Dll함수가 포함된 클래스 만들기 및 Managed Code에서 프로토타입 생성
클래스 내에서 호출할는 각 Dll함수에 대한 정적 메서드를 정의해야 한다. 이 정의에는 문자 집합 또는 메서드 인수를 전달할 때의 호출 규칙과 같은 추가 정보가 포함될 수 있는데, 이 정보를 생략하면 기본 설정이 사용된다.
함수를 래핑하면 다른 정적 함수에 대해 메서드를 호출할 때와 마찬가지로, 래핑된 함수에 대해 메서드를 호출할 수 있다. 플랫폼 호출은 내보낸 내부 함수를 자동으로 처리한다. 선언 옵션 목록 및 해당 옵션의 기본 설정에 대한 내용은 아래와 같다.(PInvoke에서 사용되는 .NET기반 선언의 생성 방법을 보여 주는 예제는 "플랫폼 호출을 사용하여 데이터 마샬링"을 참조)
참고) 문자열을 할당하는 Win32 API함수는 LocalFree와 같은 메서드를 사용하여 문자열을 해제하는데 플랫폼 호출은 이러한 매개 변수를 다르게 처리한다. 플랫폼 호출의 경우에는 매개 변수를 string형식이 아닌 IntPtr형식으로 만들어야 한다. System.Runtime.Interopservices.Marshal클래스를 사용하면 형식을 문자열로 변환하고 해당 형식을 해제하는 작업 을 수동으로 할 수 있다.

예제)
using System.Runtime.InteropServices;

public class Win32 {
[DllImport("user32.dll", CharSet=CharSet.Auto)]
public static extern int MessageBox(int hWnd, String text,
String caption, uint type);
}

public class HelloWorld {
public static void Main() {
Win32.MessageBox(0, "Hello World", "Platform Invoke Sample", 0);
}
}
참고) BestFitMaping, CallingConvention, ExactSpelling, PreserveSig, SetLastError,

ThrowOnUnmappableChar에 대한 자세한 정보는 DllImportAttribute클래스를 참조.



3. Dll함수 호출
Unmanaged Dll함수를 호출하는 작업은 Managed Code를 호출하는 것과 비슷하지만 Dll함수에 대한 혼란을 일으키는 몇 가지 차이점이 있는데 여기서 예외적인 호출 관련 항목에 대해 설명한다.



3.1 구조체 전달
대부분의 Unmanaged 함수의 경우, Managed Code에 정의된 구조체의 멤버 혹은 클래스의 멤버를 함수에 대한 매개변수로 전달해야 한다. 플랫폼 호출을 사용하여 구조체 또는 클래스를 관리되지 않는 코드에 전달하는 경우 원래 레이아웃 및 맞춤을 유지하면서 추가 정보를 제공해야 한다. 서식이 지정된 형식을 정의하는 데 사용되는 StructLayoutAttribute특성에 대해 설명한다.

Managed Struct or Class의 경우, LayoutKind열거형에서 제공하는 몇 가지 예측 가능한 레이아웃 동작에서 선택할 수 있다.
이 항목에서 제시되는 개념의 핵심은 구조체와 클래스 형식 간의 중요한 차이이다. 구조체는 값 형식이고 클래스는 참조 형식이다. 클래스에서는 항상 메모리 간접 참조(값에 대한 포인터) 수준을 하나 이상 제공한다. (자세한 사항은 "구조체 전달"을 참조)

예제1) 구조체 선언 및 전달
관리되는 코드에서 Point 및 Rect 구조체를 정의하고 이들 형식을 User32.dll 파일의 PtInRect 함수에 대한 매개 변수로 전달하는 방법을 보여 줍니다. 함수에는 RECT 형식에 대한 포인터가 필요하므로 Rect 구조체를 참조로 전달해야 합니다.

PtInRect의 관리되지 않는 서명 ==> BOOL PtInRect(const RECT *lprc, POINT pt);



using System.Runtime.InteropServices;

[StructLayout(LayoutKind.Sequential)]
public struct Point {
public int x;
public int y;
}

[StructLayout(LayoutKind.Explicit)]
public struct Rect {
[FieldOffset(0)] public int left;
[FieldOffset(4)] public int top;
[FieldOffset(8)] public int right;
[FieldOffset(12)] public int bottom;
}

class Win32API {
[DllImport("User32.dll")]
public static extern bool PtInRect(ref Rect r, Point p);
}



예제2) 클래스 선언 및 전달
클래스에 고정 멤버 레이아웃이 있으면 클래스의 멤버를 관리되지 않는 DLL 함수에 전달할 수 있다.
MySystemTime 클래스에 순차적으로 정의된 멤버를 User32.dll 파일의 GetSystemTime에 전달하는 방법을 보여 준다. 값 형식과 달리 클래스에는 항상 1 수준 이상의 간접 참조가 있습니다.

GetSystemTime의 관리되지 않는 서명 ===> void GetSystemTime(SYSTEMTIME* SystemTime);



[StructLayout(LayoutKind.Sequential)]
public class MySystemTime {
public ushort wYear;
public ushort wMonth;
public ushort wDayOfWeek;
public ushort wDay;
public ushort wHour;
public ushort wMinute;
public ushort wSecond;
public ushort wMilliseconds;
}

class Win32API {
[DllImport("Kernel32.dll")]
public static extern void GetSystemTime(MySystemTime st);
}


3.2 콜백 함수 구현

by 이상한돌 | 2005/07/26 00:01 | * C# | 트랙백 | 덧글(0)

 

Hooks in C#

http://support.microsoft.com/default.aspx?scid=kb;en-us;318804

이 기사는 폼하나와 버튼 하나를 가지고 작성됐으며 블로그쥔장의 어설픈 영어땜시 잘못번역된 부분도 있다는 것을 감안하셨음 합니다.



스레드에 명시한 후크와 마우스후크 사용에의한 후크프로시져 설정방법.

후크는 이벤트의 정확한 형태을 알아보기위해 사용할 수 있고, 명시된 스레드를 갖는 이벤트 혹은 같은 데스크탑내의 모든 스레드를 갖는 이벤트와 관련시킬 수 있다.



***기본 namespace외에 추가할 namespace

using System.Runtime.InteropServices;



***Form1 class에 들어갈 코드
public delegate int HookProc(int nCode, IntPtr wParam, IntPtr lParam);

//Declare hook handle as int.
static int hHook = 0;

//Declare mouse hook constant.
//For other hook types, you can obtain these values from Winuser.h in Microsoft SDK.
public const int WH_MOUSE = 7;
private System.Windows.Forms.Button button1;

//Declare MouseHookProcedure as HookProc type.
HookProc MouseHookProcedure;

//Declare wrapper managed POINT class.
[StructLayout(LayoutKind.Sequential)]
public class POINT
{
public int x;
public int y;
}

//Declare wrapper managed MouseHookStruct class.
[StructLayout(LayoutKind.Sequential)]
public class MouseHookStruct
{
public POINT pt;
public int hwnd;
public int wHitTestCode;
public int dwExtraInfo;
}

//Import for SetWindowsHookEx function.
//Use this function to install thread-specific hook.
[DllImport("user32.dll",CharSet=CharSet.Auto, CallingConvention=CallingConvention.StdCall)]
public static extern int SetWindowsHookEx(int idHook, HookProc lpfn,
IntPtr hInstance, int threadId);


//설정된 hook를 제거할 때 사용
[DllImport("user32.dll",CharSet=CharSet.Auto,
CallingConvention=CallingConvention.StdCall)]
public static extern bool UnhookWindowsHookEx(int idHook);


//hook정보를 다음 후크프로시져에 넘길 때 사용
[DllImport("user32.dll",CharSet=CharSet.Auto,
CallingConvention=CallingConvention.StdCall)]
public static extern int CallNextHookEx(int idHook, int nCode,
IntPtr wParam, IntPtr lParam);



***추가된 버튼에 들어갈 코드
private void button1_Click(object sender, System.EventArgs e)
{
if(hHook == 0)
{
// HookProc인스턴스 생성.
MouseHookProcedure = new HookProc(Form1.MouseHookProc);

hHook = SetWindowsHookEx(WH_MOUSE,
MouseHookProcedure,
(IntPtr)0,
AppDomain.GetCurrentThreadId());


//SetWindowsHookEx가 후크프로시저 설정에 실패한다면.
if(hHook == 0 )
{
MessageBox.Show("SetWindowsHookEx Failed");
return;
}
button1.Text = "UnHook Windows Hook";
}
else
{
bool ret = UnhookWindowsHookEx(hHook);
//UnhookWindowsHookEx가 후크프로시져 제거에 실패한다면.
if(ret == false )
{
MessageBox.Show("UnhookWindowsHookEx Failed");
return;
}
hHook = 0;
button1.Text = "Set Windows Hook";
this.Text = "Mouse Hook";
}
}

후크된 컨트롤에 대한 핸들러
public static int MouseHookProc(int nCode, IntPtr wParam, IntPtr lParam)
{
//Marshall the data from callback.
MouseHookStruct MyMouseHookStruct = (MouseHookStruct) Marshal.PtrToStructure(lParam, typeof(MouseHookStruct));

if (nCode < 0)
{
return CallNextHookEx(hHook, nCode, wParam, lParam);
}
else
{
//현재 마우스좌표를 보여줄 string변수생성
String strCaption = "x = " +
MyMouseHookStruct.pt.x.ToString("d") +
" y = " +
MyMouseHookStruct.pt.y.ToString("d");
//Need to get the active form because it is a static function.
Form tempForm = Form.ActiveForm;

//폼에 제목을 설정한다.
tempForm.Text = strCaption;
return CallNextHookEx(hHook, nCode, wParam, lParam);
}
}



Global Hook is not supported in .NET Framework
닷넷에선 전역후크를 구현할 수 없다. 전역후크를 설정하려면 후크는 다른 프로세스에 자신을 주입할 노출용 Native Dll을 가져야한다, 후크를 주입할 프로세스는 호출한 함수와 호출된 함수가 형태상으로 정확한 일치를 요구한다. 전역후크는 Dll내의 함수노출을 요구하나 닷넷프레임웍은 이를 지원하지 않는다. Managed Code는 함수포인터에대한 형태가 일치되는 값에 대한 개념이 없다. 이유는 함수포인터는 동적으로 생성되는 proxy이기 때문이다.



위의 부분은 개념이 전혀없는 것을 해석하려고 하다보니 해놓고도 도무지 무슨 의미인지 알 수가 없네요(--). 아시는 분은 조금의 지식을 공유해 주세요.


일반적인 Hooks의 개념
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/windowing/hooks/abouthooks.asp

by 이상한돌 | 2005/07/26 00:01 | * C# | 트랙백 | 덧글(0)

 

Events and Delegates simplified

http://www.codeproject.com/csharp/events.asp

원문입니다. 옮긴 글이 잘못해석됐을 수도 있으니 참조바랍니다. 잘못됐다고 생각되는 부분은 리플을 부탁드려요.



What are delegates?
delegate와 event개념은 완벽하게 두 개가 묶여져있다. delegates는 함수포인터, event도 그렇다, 둘은 함수에대한 참조를 갖는다.
delegate는 클래스다. 여러분들이 delegate의 인스턴스를 생성할 때 여러분은 delegate가 참조할 함수이름을 생성자의 파라미터로 넘겨준다. 모든 delegate는 형식을 갖는다.


예제) "Delegate int SomeDelegate(string s, bool b);"

는 delegate의 정의다. 사용자가 이를 기술할 때 이 delegate는 형식을 갖는다, 이것은 함수의 결과값으로 int형을 돌려주고 두 개의 파라미터 string, bool을 취한다는 것을 의미한다.
여러분들이 delegate를 실증할 때, 여러분들은 delegate가 참조할 함수이름을 생성자 파라미터로 넘겨줘야한다. 중요한 것은 delegate와 같은 형식을 갖는 함수만이 파라미터로 넘겨질 수 있다.
다음 함수를 보라.

private int SomeFunction(string str, bool bln) {...};
SomeFunction함수는 SomeDelegate의 생성자로 넘겨줄 수 있다, 이유는 같은 형식이기 때문이다.



SomeDelegate sd = new SomeDelegate(SomeFunction);
이제, sd는 SomeFunction을 참조한다, 다시말해 SomeFunction은 sd에 등록됐다. 만약 여러분이 sd를 호출하면 SomeFunction이 호출될 것이다.
나중에, 등록된 함수를 참조할 것이다.
sd("somestring", true);



Understanding Events
- Button은 클래스이며, 버튼을 클릭할 때, Click event가 기동한다.
- Timer는 클래스이며, millisecond마다 tick event가 기동한다.
예제를 통해서 어떤 일들이 벌어지는지 알아보자.



scenario : 우리는 Counter라는 클래스를 가지고있다. 이 클래스는 CountTo라는 메소드를 갖는다. 그리고 CountTo메소드에서 특정 숫자에 다다르면 NumberReached로 명명된 event를 발생시킨다. 클래스는 NumberReached라는 이벤트를 갖는다. 여러이벤트는 delegate형의 변수들이다. 이 예제에서는 이벤트를 정의하길 원한다면 단순히 어떤 delegate의 변수를 선언한다.


public event NumberReachedEventhandler NumberReached;
위 정의에서 NumberReachedEventHandler는 단순한 delegate다. 아마도 저렇게 하는 것이 더 나을 것이다. 그러나 알아둘 것은 MS는 MouseEventHandler와 PaintEventHandler를 제공하는 대신 MouseDelegate나 PaintDelegate를 언급하진 않는다. 이것은 NumberReadchedDelegate를 대신해 NumberReadchedEventHandler를 언급하는 약속이다.
우리는 이벤트를 정의하기전에 이벤트 핸들러를 선언할 필요가 있다.

public delegate void NumberReachedEventHandler

(object sender, NumberReadchedEventArgs e);

보는바와같이 delegate의 이름은 NumberReadchedEventHandler이고 형식은 결과값 void형과 두 파라미터 object와 NumberReachedEventArgs로 구성한다. 이 delegate를 실증하려면, 생성자 파라미터로 넘겨질 함수는 delegate와 같은 형식을 가져야한다.

마우스의 위치나 어디서 움직이고 있었는지를 알기위해 코드에서 PaintEventArgs나 MouseEventArgs를 사용해봤는가? 혹은 Paint event가 기동될 object의 Graphics property는 사용해 봤는가? 실제로, 우리는 EventArgs클래스에서 파생된 클래스에 사용자를 위해서 데이터를 제공한다. 아래 예제에서 우리는 도달된 숫자를 제공하고싶다. 그리고 이건 클래스 정의다

public class NumberReachedEventArgs : EventArgs
{
private int _reached;

public NumberReachedEventArgs(int num)
{
this._reached = num;
}

public int ReachedNumber
{
get
{
return _reached;
}
}
}

만약 이용자에게 어떤 정보도 제공할 필요가 없다면 우리 그냥 EventArgs클래스를 사용한다.
이제 우리의 Counter클래스의 내부를 볼 모든 사항이 준비되었다.

namespace Events
{
public delegate void NumberReachedEventHandler(object sender,
NumberReachedEventArgs e);

/// <summary>
/// Summary description for Counter.
/// </summary>
public class Counter
{
public event NumberReachedEventHandler NumberReached;

public Counter()
{
//
// TODO: Add constructor logic here
//
}
public void CountTo(int countTo, int reachableNum)
{
if(countTo < reachableNum)
throw new ArgumentException(
"reachableNum should be less than countTo");
for(int ctr=0;ctr<=countTo;ctr++)
{
if(ctr == reachableNum)
{
NumberReachedEventArgs e = new NumberReachedEventArgs(
reachableNum);
OnNumberReached(e);
return;//don't count any more
}
}
}

protected virtual void OnNumberReached(NumberReachedEventArgs e)
{
if(NumberReached != null)
{
NumberReached(this, e);//Raise the event
}
}
}
위 코드에서, 우리는 원하는 숫자가 나오면 이벤트를 기동한다. 여기엔 많은 고려사항이 있다.
- 이벤트 기동은 우리가 작성한 이벤트를 통해서 성립된다.
NumberReached(this, e);
이 방법은 등록된 모든 함수를 발생시킬 수 있다.

- 우리는 "NumberReachedEventArgs e = new NumberReachedEventArgs(reachableNum)"을 통해서 등록된 함수에 대한 데이터를 준비한다.

- 의문한가지 : 왜 우리는 "NumberReached(this, e)"을 "OnNumberReached(NumberReachedEventArgs e)"를 통해서 간접적으로 호출하는가? 왜 우리는 아래의 코드처럼 하지 않았는가?

if(ctr == reachableNum)
{
NumberReachedEventArgs e = new NumberReachedEventArgs(reachableNum);
//OnNumberReached(e);
if(NumberReached != null)
{
NumberReached(this, e);//Raise the event
}
return;//don't count any more
}



간접적으로 호출한 이유를 알고싶다면 다음의 코드를 참조해보라.
protected virtual void OnNumberReached(NumberReachedEventArgs e)
- protected는 이 클래스를 상속받는 클래스에서도 사용할 수 있게된다.
- virtual는 상속된 클래스에서 override될 수 있다.

이건 아주 유용하다. 여러분이 Counter클래스로부터 상속하는 클래스를 디자인한다고 가정해보자. OnNumberReached method를 override함으로써, 여러분들은 이벤트가 기동되기전에 몇가지 추가적인 작업을 할 수 있게된다.

protected override void OnNumberReached(NumberReachedEventArgs e)
{
//Do additional work
base.OnNumberReached(e);
}
만약 여러분이 base.OnNumberReached(e)를 호출하지 않으면 이벤트는 절대 기동되지 않을것이다. 이것은 여러분이 어떤 클래스에서 상속을 받아 일부 이벤트를 제거하고 싶을 때 아주 유용하다.

event Keyword
많은 사람들이 이런 질문을 해온다. event 키워드를 사용하지 않으면 어떤 일이 일어나냐고, "What happens if we don't use event keyword?".
본질적으로, event키워드를 선언하는 것은 event키워드를 null로 설정해서 딜리게이트 유저들의 어떤 점을 방지한다. 왜 이것이 중요할까? 클라이언트로서 생각해보자. 내가 delegates invocation list에 클래스의 함수중 콜백을 추가하면 그리고 다른 클라이언트라고 가정하면 모든것이 잘 된다. 이제 누군가가 "+="대신 "="을 사용해 delegate에 새로운 콜백함수를 설정하고 있다고 상상해보자. 이것은 기본적으로 이전 delegate를 버리고 delegate의 invocation list도 버려진다. 그리고 invocation list내에서 한 아이템을 가지고 딜리게이트를 새로 만든다. 다른 클라이언트들은 같은 딜리게이트를 호출할 때 그들소유의 딜리게이트를 받지 못할 것이다. 부여된 콜백함수를 가지고 invocation list를 재생성한다. 다른 모든 클라이언트들은 callback함수를 호출할 때 클라이언트에 부여된 callback함수를 받지못할 것이다. event키워드로 해결하려고 하는 것이 그런 상황중의 하나이다. 만약 Counter클래스에서 event키워드를 제거하고 컴파일을 시도한다면 compilation error가 발생할 것이다.
결론적으로, event정의는 delegate인스턴스상에서 보호층을 더한다. 이 보호층은 delegate의 클라이언트를 delegate와 invocation list재설정으로부터 보호하고, 대상을 invocation list로부터 추가 혹은 제거만 허용한다



아래의 event keyword에 대한 원문은 해석이 제대로 안되었기에 좀더 잘 이해하실 수 있도록 놔뒀습니다. 아울러 제게도 좀 알려주세요 ^^;



event keyword에 대한 원문

In essence, declaring the event keyword prevents any of the delegate’s users from setting it to null. Why is this important? Imagine that as a client I would add to the delegates invocation list a callback to one of my class’ functions. So would other clients. All is well and good. Now imagine that someone, instead of using the “+=”, is simply setting the delegate to a new callback by using “=”. This basically just throws the old delegate and its invocation list down the drain and creates a whole new delegate with a single item in its invocation list. All the other clients will not receive their callbacks when the time comes. It is this kind of situation that having the event keyword is aiming to solve. If I remove the event keyword in the Counter class and try to compile the following code in my application, it will cause a compilation error:

In conclusion: an event declaration adds a layer of protection on the delegate instance. This protection prevents clients of the delegate from resetting the delegate and its invocation list, and only allows adding or removing targets from the invocation list

by 이상한돌 | 2005/07/25 23:54 | * C# | 트랙백(1) | 덧글(0)

 

XP 스타일 적용하기

Visual Studio .NET 디자인 모드에서 컨트롤들의 XP 스타일 적용하기

1. 다음과 같은 XML 파일을 만듭니다. 파일명은 devenv.exe.manifest 이어야 합니다. (첨부파일 참조)

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity
     version="1.0.0.0"
     processorArchitecture="X86"
     name="*"
     type="win32"
/>
<dependency>
     <dependentAssembly>
          <assemblyIdentity
          type="win32"
          name="Microsoft.Windows.Common-Controls"
          version="6.0.0.0"
          processorArchitecture="X86"
          publicKeyToken="6595b64144ccf1df"
          language="*"
          />
     </dependentAssembly>
</dependency>
</assembly>


2. devenv.exe.manifest 파일을 아래의 폴더에 복사합니다. 설치위치에 따라 조금씩 다를 수 있습니다.
C:Program FilesMicrosoft Visual Studio .NET 2003Common7IDE (2003 일때)


3. 비주얼 스투디오 .NET 을 실행합니다.
콤보박스, 텍스트박스, 리스트 박스 등 FlatStyle이 없는 컨트롤은 디폴트로 XP 비주얼스타일로 보입니다.
단, 버튼, 라디오버튼, 체크박스 등의 FlatStyle 속성이 있는 컨트롤은 System으로 설정하여야 보입니다.






응용프로그램 실행시 XP스타일 적용하기
static void Main()
{
// 응용프로그램에 대해 XP 비주얼스타일을 적용합니다.
Application.EnableVisualStyles();
Application.Run(new Form1());
}





by 이상한돌 | 2005/07/22 02:44 | * C# | 트랙백 | 덧글(0)

 

◀ 이전 페이지다음 페이지 ▶