그 중 3가지를 소개하고 제가 사용하는 방법을 알려드리려 합니다.
1. FindWindow() API를 이용하는 방법
- 이 API는 RegisterClass() 또는 RegisterClassEx() API를 이용하여 등록된 클래스명이나 프로그램명(Title)을 이용하여 특정 윈도우를 찾는 함수입니다.
- 가장 간단한 코드로 구현할 수 있습니다. 그러나 문제점을 갖고 있어 사용을 권장하진 않습니다.
- 문제점1: 클래스명이나 프로그램명은 중복될 확률이 높아 우리가 원하는 프로그램을 찾아내지 못합니다. (예를들면 탐색기의 프로그램명은 폴더명에 따라 바뀌기 때문에 혼동되기 쉽습니다.)
- 문제점2: 프로그램을 아주 빠른 속도로 두번 연속 실행시킬 경우 정상적으로 동작을 안할 수 있습니다.
- 문제점3: 레이스 컨디션(Race Condition: 두 개의 쓰레드가 실행될 때 어떤 스레드가 먼저 처리되느냐에 따라 결과가 달라지는 것)이 존재합니다.
// MyApp.cpp : Defines the class behaviors for the application. BOOL CMyApp::InitInstance() hwndClone = ::FindWindow(NULL, _T("프로그램 이름 (My App. Title)")); ... |
2. 뮤텍스(Mutex)를 이용하는 방법
- 커널 객체인 뮤텍스는 단 하나의 쓰레드만이 소유할 수 있다는 성질을 이용합니다. (뮤텍스에 대한 자세한 설명은 'Windows API 정복, 가남사' 또는 'TCP/IP 소켓 프로그래밍, 프리렉'을 참조하세요.)
- 뮤텍스를 생성하기 위해서는 CreateMutext() API를 이용합니다. 이 API의 세번째 인자에 뮤텍스 이름을 넘기게 되어 있는데, 그 이름이 중복될 경우 원치않는 동작을 할 수 있습니다. 이를 해결하기 위해서 뮤텍스 이름으로 GUID 값을 넘기면 해결할 수 있습니다.
// MyApp.h : main header file for the MyApp application class CMyApp : public CWinApp |
// MyApp.cpp : Defines the class behaviors for the application. BOOL CMyApp::CMyApp() ... BOOL CMyApp::InitInstance() BOOL CMyApp::ExitInstance() ... |
3. 공유 메모리를 이용하는 방법
- 특정 데이터 세그먼트 영역에 공유할 변수를 만들어 그 변수 값에 따라 처리하는 방법입니다.
// MyApp.cpp : Defines the class behaviors for the application. #pragma data_seg(".Shared") // 'Shared'란 이름으로 'Data Segment'를 만든다. #pragma comment(linker, "/SECTION:.Shared,rws") ... BOOL CMyApp::InitInstance() g_lInstanceCount ++; ... BOOL CMyApp::ExitInstance() ... |
위 3가지 방법 중에서 FindWindow() API를 이용하는 방법을 제외하면 기존 인스턴스에 대한 정보를 얻지 못해 기존 인스턴스를 윈도우즈에서 최상단(z-order)에 위치하도록 하지 못하고 있습니다. 이를 해결하기 위해 전 뮤텍스와 공유 메모리를 이용한 방법을 혼용하였습니다.
공유 메모리 영역에 최초로 실행된 인스턴스의 메인 윈도우 핸들 값을 저장하고 그 값을 이용하여 인스턴스를 컨트롤합니다.
// MyApp.h : main header file for the MyApp application class CMyApp : public CWinApp |
// MyApp.cpp : Defines the class behaviors for the application. #pragma data_seg(".Shared") // 'Shared'란 이름으로 'Data Segment'를 만든다. #pragma comment(linker, "/SECTION:.Shared,rws") ... BOOL CMyApp::CMyApp() ... BOOL CMyApp::InitInstance() BOOL CMyApp::ExitInstance() ... |
추신. http://www.flounder.com/nomultiples.htm 에 가보시면 Joseph M. Newcomer 이란 분이 아주 상세하게 설명해 놓으셨습니다.
'Tech & IT > 프로그래밍' 카테고리의 다른 글
소프트웨어 아키텍쳐 강좌 사이트 (0) | 2010.03.31 |
---|---|
소프트웨어 분석 및 설계 (0) | 2010.03.31 |
use case diagram 예시 (0) | 2010.03.22 |
제안서, 제안요청서 작성하기 (0) | 2010.03.15 |
Class Diagram (0) | 2010.03.03 |