천객만래 [千客萬來] (It has an interminable succession of visitors)

프로그래밍에서 사용되는 HINSTANCE & HWND의 차이


HINSTANCE 핸들은 보통 실행되고 있는 Win32 프로그램이

메모리 상에 올라가 있는 시작 주소 값을 갖고 있습니다.

보통은 0x00400000 이런식의 값을 가지고 있는데 저 값의

메모리 주소에 실행 모듈이 올라가 잇다는 것을 의미 하겠죠.

보통 리소스들을 로드 하는 함수들에서 이 핸들 값을 많이

참조하게 되는데 이 이유는 메모리 상에 올라가 있는 실행 모듈 들중

(exe, dll 등등.. ) hInstance 가 가르키는 주소에 올라가 있는 실행

모듈에서 그 리소스를 읽어 오라고 지정 해주는 것입니다.

이 외에 GetProcAddress() 같이 다른 DLL 에서 함수 주소를

얻어야 하는 경우에도 HMODULE ( Win32 에선 HINSTANCE 와

동일한 기능을 하고 같은 값이라고 보시면 됩니다.) 와 같이 메모리

상에 올라가 있는 어느 특정 모듈을 가르킬때 사용하게 됩니다.

그리고 그 변수를 글로벌로 잡는 경우가 있는데 그 이유는 그 변수를

여러 함수들에서 자주 사용하기 때문에 Win32의 구현 방식상 여러

함수에서 그 값을 읽어 와야 하고 그 값은 WinMain() 에서 한번 들어

오는 값이기 때문에 글로벌 변수에 넣어 두는것이죠...

물론 C++ 클래스로 MFC 처럼 하여 꼭 글로벌로 두지 않아도 되게 하는

방법도 있습니다만.. 어떤 방식이던 목적은 같습니다. 

참고하세요 ^^


////////////////////////////////////////////////////////////////

 

HINSTANCE는 프로그램의 인스턴스 식별자(핸들)을 의미합니다.

간단히 말씀드리자면 실행파일 형태로 껍데기에 불과한 프로그램이 메모리에 실제로

구현된 실체를 뜻합니다.

따라서 만약에 프로그램을 여러개 실행시켰을 때 이들의 각각을 프로그램 인스턴스라고

 하고 실행되는 프로그램마다 고유한 값을 갖고

실행중인 프로그램들을 구분하기 위한 식별값으로 인스턴스 핸들을 이용합니다.

 

HWND는 프로그램의 윈도우 식별자(핸들)를 의미하는데 해당 프로그램의 윈도우들을

구분하기 위한 식별 값을 말합니다. 여기서 윈도우와 프로그램과는 차이가 있습니다.

윈도우 프로그래밍에서 하나의 프로그램에는 많은 윈도우들을 가질수 있기 때문입니다.

프로그램의 윈도우 핸들 중에서 대표적인 것이 부모 윈도우의 핸들입니다. 따라서 대부분의

윈도우 프로그래밍의 작업과정중 대부분은 이들 HWND 값을 통해 얻은 윈도우 핸들을

이용한다고 이해하시면 빠를꺼 같습니다. 창뿐만 아니라 여러가지 수많은 컨트롤 등도 모두

윈도우로 생성시에 핸들값을 소유하고 있는 존재이기 때문입니다.


------------------------------------------------------------------------------------

 

HINSTANCE는 프로그램의 핸들이 아니라, 프로그램 코드를 담고 있는 모듈에 대한 핸들이다. 즉, 프로그램이 수행되려면 프로그램 코드를 담고 있는 파일을 메모리의 특정 영역에 올려서 명령을 하나식 읽어가면서 수행할 수 있도록 준비해 놓아야 한다.

 

이렇게메모리에 올려진 프로그램 코드 덩어리를 윈도우에서 관리하기 위해서 일종의 고유 식별 번호를 부여하는데, 이것이 인스턴스 핸들, HINSTANCE이다. 기본적으로 프로세스를 실행하는 실행파일의 코드를 메모리에 올려놓은 모듈이 하나 있어야 하므로, 실행 파일의 모듈에 대한 인스턴스 핸들을 OS가 어플리케이션 WindMain의 인자로 넘겨주는 것이다.

 

한 프로세스가 여러개의 모듈을 로딩하여 프로그램을 실행하고 있다면 하나의 프로그램이 여러개의 인스턴스 핸들을 할당받아 쓰고 있을 수 있다.(물론 한 개의 모듈을 여러 프로세스가 공유하고 있을 수도 있다.) 대표적인 예가 바로 IE인데, 간단하게 DLL파일 한 개를 쓸 때마다 이 DLL 모듈에 대한 인스턴스 핸들이 한 개씩 생긴다고 보면 된다. 물론 DLL이 한번 로딩되면 다른 프로그램 사이에서 공유된다.

 

한 개의 프로그램에서 HINSTANCE가 한 개만 있는 것이 아니며, 또한 하나의 인스턴스 핸들이 한 개의 프로그램에만 종속되는 것이 아니므로 어떤 프로그램의 출력 대상을 지정하는 데에는 부적적하다는 점을 알 수 있다. 물론, 인스턴스 핸들은 애초부터 화면 출력을 고려햐여 만들어진 식별자는 아니며 단지 프로그램 코드 덩어리를 관리하기 위해 만들어진 리소스이다.

 

윈도우라는 OS에서 화면 출력을 위해 관리하는 리소스가 바로 HWND이다. MSN 메신저 등을 보면 알겠지만 하나의 프로그램이 하나의 창을 사용한다는 보장은 없다. 오히려 99.99%의 프로그램은 한 개 이상의 윈도우로 구성되어 있다. 한 프로그램의 윈도우가 겉보기에는 단일한 대상 영역으로 보일지라도 실제로는 구성요소별로 분리하여 별개의 윈도우로 만들어 각 윈도우는 자기 자신이 맡은 부분에 대한 화면 출력과 사용자 입력만을 담당한다. 자연히 하나의 프로그램에서 사용하는 HWND 타입의 개체 역시 1개 이상이 될 수 밖에 없으며, 이러한 상황에서 특정 위치에 특정한 동작을 수행하기 위해서는 HWND로 대상 영역을 구분할 수 밖에 없다.

 

------------------------------------------------------------------------------------

HWND와 HINSTANCE의 구조체 내용을 보시면 가지는 속성들이 전혀 다릅니다.

HWND는 윈도우 자체에 대한 정보를 가지는 것이고,
HINSTANCE는 현재 실행중인 인스턴스에 관한 정보를 가지고 있습니다.
인스턴스는 운영체제 전체에서 유일한 번호를 가지므로(실행중인 창들이라고 보면되죠)
HWND를 가지고 인스턴스를 구할순 없지만 HINSTANCE를 가지고 있으면
HWND에 관한 내용들을 구할수 있습니다. 

출처 : 인터넷

Posted by SB패밀리

1. hWnd를 알면, 그걸로 hInstance를 얻어올 수 있습니다. 
GetWindowLong / GetWindowLongPtr에서 GWLP_HINSTANCE

 

2. AfxGetApp() 를 통해서 App 의 포인터를 얻어온 다음에 m_instance 멤버변수

 

3. HINSTANCE hInst= GetModuleHandle(NULL); 콘솔에서 윈도 뛰울때 자주 씁니다.

 

4. HINSTANCE AfxGetInstanceHandle( );

5. dll의 메모리를 이용한 HINSTANCE 구하기

종종 DLL 내부에서 window를 띄워야하시겠다는 분이 있어서 찾던중에

 

Detecting a HMODULE/HINSTANCE Handle Within the Module You're Running In

 

이라는 codeguru 글을 보았습니다.

 

http://www.codeguru.com/Cpp/W-P/dll/tips/article.php/c3635/

 

코드는

 

 

#if _MSC_VER >= 1300    // for VC 7.0

  // from ATL 7.0 sources

  #ifndef _delayimp_h

  extern "C" IMAGE_DOS_HEADER __ImageBase;

  #endif

#endif

 

HMODULE GetCurrentModule()

{

#if _MSC_VER < 1300    // earlier than .NET compiler (VC 6.0)

 

  // Here's a trick that will get you the handle of the module

  // you're running in without any a-priori knowledge:

  // http://www.dotnet247.com/247reference/msgs/13/65259.aspx

 

  MEMORY_BASIC_INFORMATION mbi;

  static int dummy;

  VirtualQuery( &dummy, &mbi, sizeof(mbi) );

 

  return reinterpret_cast<HMODULE>(mbi.AllocationBase);

 

#else    // VC 7.0

 

  // from ATL 7.0 sources

 

  return reinterpret_cast<HMODULE>(&__ImageBase);

#endif

}

 

위와 같은데.

 

간단히 설명하면 메모리에 할당된 dll정보를 읽어와서

 

HMODULE위치를 리턴해줍니다.

 

현재 win 9x 및 nt계열에서는 동작하는데 추후에 할당된 메모리 레이아웃이

 

아주 대폭적으로 바뀌면 돌아가지 않을수도 있겠죠.

 

첨부파일은 dll에서 window 생성하는 코드 입니다.


 

[출처] MFC에서 hInstance 얻기|작성자 에쑤비


Posted by SB패밀리


HINSTANCE & HWND의 차이

HINSTANCE 핸들은 보통 실행되고 있는 Win32 프로그램이

메모리 상에 올라가 있는 시작 주소 값을 갖고 잇습니다.

보통은 0x00400000 이런식의 값을 가지고 있는데 저 값의

메모리 주소에 실행 모듈이 올라가 잇다는 것을 의미 하겠죠.

보통 리소스들을 로드 하는 함수들에서 이 핸들 값을 많이

참조하게 되는데 이 이유는 메모리 상에 올라가 있는 실행 모듈 들중

(exe, dll 등등.. ) hInstance 가 가르키는 주소에 올라가 있는 실행

모듈에서 그 리소스를 읽어 오라고 지정 해주는 것입니다.

이 외에 GetProcAddress() 같이 다른 DLL 에서 함수 주소를

얻어야 하는 경우에도 HMODULE ( Win32 에선 HINSTANCE 와

동일한 기능을 하고 같은 값이라고 보시면 됩니다.) 와 같이 메모리

상에 올라가 있는 어느 특정 모듈을 가르킬때 사용하게 됩니다.

그리고 그 변수를 글로벌로 잡는 경우가 있는데 그 이유는 그 변수를

여러 함수들에서 자주 사용하기 때문에 Win32의 구현 방식상 여러

함수에서 그 값을 읽어 와야 하고 그 값은 WinMain() 에서 한번 들어

오는 값이기 때문에 글로벌 변수에 넣어 두는것이죠...

물론 C++ 클래스로 MFC 처럼 하여 꼭 글로벌로 두지 않아도 되게 하는

방법도 있습니다만.. 어떤 방식이던 목적은 같습니다. 

참고하세요 ^^


////////////////////////////////////////////////////////////////

 

HINSTANCE는 프로그램의 인스턴스 식별자(핸들)을 의미합니다.

간단히 말씀드리자면 실행파일 형태로 껍데기에 불과한 프로그램이 메모리에 실제로

구현된 실체를 뜻합니다.

따라서 만약에 프로그램을 여러개 실행시켰을 때 이들의 각각을 프로그램 인스턴스라고

 하고 실행되는 프로그램마다 고유한 값을 갖고

실행중인 프로그램들을 구분하기 위한 식별값으로 인스턴스 핸들을 이용합니다.

 

HWND는 프로그램의 윈도우 식별자(핸들)를 의미하는데 해당 프로그램의 윈도우들을

구분하기 위한 식별 값을 말합니다. 여기서 윈도우와 프로그램과는 차이가 있습니다.

윈도우 프로그래밍에서 하나의 프로그램에는 많은 윈도우들을 가질수 있기 때문입니다.

프로그램의 윈도우 핸들 중에서 대표적인 것이 부모 윈도우의 핸들입니다. 따라서 대부분의

윈도우 프로그래밍의 작업과정중 대부분은 이들 HWND 값을 통해 얻은 윈도우 핸들을

이용한다고 이해하시면 빠를꺼 같습니다. 창뿐만 아니라 여러가지 수많은 컨트롤 등도 모두

윈도우로 생성시에 핸들값을 소유하고 있는 존재이기 때문입니다.


------------------------------------------------------------------------------------

 

HINSTANCE는 프로그램의 핸들이 아니라, 프로그램 코드를 담고 있는 모듈에 대한 핸들이다. 즉, 프로그램이 수행되려면 프로그램 코드를 담고 있는 파일을 메모리의 특정 영역에 올려서 명령을 하나식 읽어가면서 수행할 수 있도록 준비해 놓아야 한다.

 

이렇게메모리에 올려진 프로그램 코드 덩어리를 윈도우에서 관리하기 위해서 일종의 고유 식별 번호를 부여하는데, 이것이 인스턴스 핸들, HINSTANCE이다. 기본적으로 프로세스를 실행하는 실행파일의 코드를 메모리에 올려놓은 모듈이 하나 있어야 하므로, 실행 파일의 모듈에 대한 인스턴스 핸들을 OS가 어플리케이션 WindMain의 인자로 넘겨주는 것이다.

 

한 프로세스가 여러개의 모듈을 로딩하여 프로그램을 실행하고 있다면 하나의 프로그램이 여러개의 인스턴스 핸들을 할당받아 쓰고 있을 수 있다.(물론 한 개의 모듈을 여러 프로세스가 공유하고 있을 수도 있다.) 대표적인 예가 바로 IE인데, 간단하게 DLL파일 한 개를 쓸 때마다 이 DLL 모듈에 대한 인스턴스 핸들이 한 개씩 생긴다고 보면 된다. 물론 DLL이 한번 로딩되면 다른 프로그램 사이에서 공유된다.

 

한 개의 프로그램에서 HINSTANCE가 한 개만 있는 것이 아니며, 또한 하나의 인스턴스 핸들이 한 개의 프로그램에만 종속되는 것이 아니므로 어떤 프로그램의 출력 대상을 지정하는 데에는 부적적하다는 점을 알 수 있다. 물론, 인스턴스 핸들은 애초부터 화면 출력을 고려햐여 만들어진 식별자는 아니며 단지 프로그램 코드 덩어리를 관리하기 위해 만들어진 리소스이다.

 

윈도우라는 OS에서 화면 출력을 위해 관리하는 리소스가 바로 HWND이다. MSN 메신저 등을 보면 알겠지만 하나의 프로그램이 하나의 창을 사용한다는 보장은 없다. 오히려 99.99%의 프로그램은 한 개 이상의 윈도우로 구성되어 있다. 한 프로그램의 윈도우가 겉보기에는 단일한 대상 영역으로 보일지라도 실제로는 구성요소별로 분리하여 별개의 윈도우로 만들어 각 윈도우는 자기 자신이 맡은 부분에 대한 화면 출력과 사용자 입력만을 담당한다. 자연히 하나의 프로그램에서 사용하는 HWND 타입의 개체 역시 1개 이상이 될 수 밖에 없으며, 이러한 상황에서 특정 위치에 특정한 동작을 수행하기 위해서는 HWND로 대상 영역을 구분할 수 밖에 없다.

 

------------------------------------------------------------------------------------

HWND와 HINSTANCE의 구조체 내용을 보시면 가지는 속성들이 전혀 다릅니다.

HWND는 윈도우 자체에 대한 정보를 가지는 것이고,
HINSTANCE는 현재 실행중인 인스턴스에 관한 정보를 가지고 있습니다.
인스턴스는 운영체제 전체에서 유일한 번호를 가지므로(실행중인 창들이라고 보면되죠)
HWND를 가지고 인스턴스를 구할순 없지만 HINSTANCE를 가지고 있으면
HWND에 관한 내용들을 구할수 있습니다.

출처 : 인터넷

Posted by SB패밀리