반응형
이번 프로젝트 이름은 GudaWinSet

Win32 API를 이용한 프로그램을 처음 작성한 것이다.

딱히 내놓을 만한 것은 아니지만 개인적인 프로젝트로 수정 보완하며 진행할 생각이다.

그리고 자바와는 또다른 매력이 있고 오랫만에 플밍에 오르가즘(?)을 느끼는 것 같기도 하다.

이렇게 말한다고 딱히 거창한 것은 아니다. 내가 사용하고자 진행하는 것이기 때문이다.


일단은 콘솔창 및 윈도우 화면의 설정을 변경할 목적으로 만들생각이다.
업무중 어쩔수 없이 콘솔창을 통해 로그를 보는데 각 콘솔창의 타이틀명을 바꾸기 번거럽고
버퍼라인 설정도 일일히 변경하기 귀찮은 관계로 해당 어플을 만들기로 하였다.
그리고 추가적으로 투명도 설정을 할수 있도록 기능을 추가할 예정이다. ㅎㅎ
메신저중에 네이트온처럼 투명창이 되었으면 하는 바램이 있기에 추가할 생각이다.
허접한 어플이지만 내공이 부족하여 구현하는 도중 찾은 여러가지 자료를 정리하고자 한다.

일단 다이얼로그 창에 한글입력시 깨짐 현상이 발생하였는데 이는 visual studio 설정으로 해결.

Resource View에서 해당 다이얼로그를 클릭하면 프로퍼티 속성에서 Language 항목을 볼수가 있다
여기서 한국어를 선택하면 실행시 한글깨짐 현상을 해결할수 있다.

다음 문제는 해당 윈도우의 핸들을 구하는 과정에서의 삽질 부분이다.

윈도우 간의 상호작용을 위해서는 우선 윈도우의 핸들을 알아야지 윈도우 관련 함수들을 사용할 수 있다.

HWND FindWindow(     

    LPCTSTR lpClassName,      //조사할 윈도우의 클래스 이름
    LPCTSTR lpWindowName      //조사할 윈도우의 캡션
);
조건에 맞는 윈도우를 찾으면 윈도우의 핸들을 리턴해 주고 못찾을경우 NULL을 리턴해준다.
최상위 부모 윈도우의 핸들만 리턴해준다.
 

HWND FindWindowEx(      

    HWND hwndParent,      //hwndParent에 속한 차일드 윈도우를 검색해낸다. NULL이면 데스크탑 윈도우의 차일드를 검색한다.
    HWND hwndChildAfter,  //검색을 시작할 차일드 윈도우를 지정한다. NULL이면 첫번째 차일드부터 검색한다.
    LPCTSTR lpszClass,    //조사할 윈도우의 클래스 이름
    LPCTSTR lpszWindow    //조사할 윈도우의 캡션
); 
부모 윈도우에 속한 차일드 윈도우 핸들을 찾을때 사용한다.

//이번에 사용한 함수이다.
HWND WindowFromPoint(      

    POINT Point
);
화면 좌표로 윈도우를 검색하는 함수로 인수로 화면 좌표를 POINT형으로 넣어주면 된다.
조건에 맞는 윈도우를 찾으면 윈도우의 핸들을 리턴해 주고 못찾을경우 NULL을 리턴해준다.
SPY++ 에서 사용하는 함수 인듯하다..  

*주의사항
위 함수를 이용해 얻은 CWnd * 형식의 값은 임시적으로 생성된 객체의 주소값이기 때문에
전역 변수 또는 멤버 변수에 저장한 후, 계속 사용하면 문제가 발생할수 있다.
해당 작업을 하는 그 순간에만 사용하고 더 이상 사용하면 안된다. 주의 할것!

위와 같은 함수를 이용해 윈도우의 핸들을 구했지만 내가 구하고 싶은것은 최상위 부모 윈도우의 핸들
이와 관련하여 HWND GetParent(HWND hWnd) 을 사용했지만 컨트롤의 경우 다른 컨트롤에 포함된 상태이면
상위 윈도우를 리턴하므로 원하는 결과가 나오지 않았다 그래서 사용한 함수가
GetAncestor(hWndChild,GA_ROOTOWNER); 두번째 인자인 플래그에 따라 GA_PARENT, GA_ROOT, GA_ROOTOWNER

GA_PARENT GetParent()와 비슷한 작업.
GA_ROOT, GA_ROOTOWNER  호출하는 컨트롤을 포함하는 최상위 윈도우 핸들

부모 윈도우의 차일드 윈도우를 조사하는 함수

BOOL EnumChildWindows(
    HWND hWndParent,                         // 부모 윈도우 핸들
    WNDENUMPROC IpEnumFunc,        // Call Back 함수의 포인터
    LPARAM IParam);  

하위 윈도우의 캡션값을 가져오기 위해서는  WM_GETTEXT 를 사용하면 된단다.. ^^;; 자료만 수집

코딩보다 자료정리하는데 더 많은 시간이 걸리는 것 같다. 그래도 정리를 해야 다음에 또 써먹기에.. ㅋ

반응형

어플을 실행할때 중복 실행이 되지 않게 하기 위해 방지 하는 방법에 대해서 알아보자.
그 방법에는 FindWindow()를 이용하거나 EnumWindows()를 이용하는등의 방법이 있지만
Mutex를 이용하여 간단하게 처리 하는 방법에 대해 알아보도록 하자.



함수원형
HANDLE CreateMutex(LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL blnitialOwner, LPCTSTR lpName);

Argument
- lpMutexAttributes : Mutex의 보안속성을 지정, 주로 상속관계를 지정하기 위해 사용, 일반적으로 NULL
- blnitialOwner : 생성시 사용권한을 갖을것인지 여부,
- lpName : Mutex의 이름, Mutex 이름을 아는 다른 프로세스와의 동기화 가능, 유니크한 이름 지정.

CreateMutex는 생성한 Mutex의 핸들을 리턴하고
같은 이름의 Mutex가 생성되어 있을 경우 해당 뮤텍스 핸들을 리턴
GetLastError()로는 ERROR_ALREADY_EXIST값을 얻을수 있고
Mutex에 접근할 수 있는 권한이 없는 경우 (ERROR_ACCESS_DENIED)NULL 을 리턴한다.

이를 통해 위 소스를 이용하여 중복실행 방지를 할수 있는 것이다.
중요한것은 CreateMutex()를 통해 Mutex의 핸들을 리턴 받은 루틴 후에
GetLastError()를 확인했을때 ERROR_ALREADY_EXIST 값과 같다면 이미 실행되어 있다는 것이고
그렇다면 종료 루틴으로 흘러가게 되고 어플은 종료 되는 것이다.
참고로 게임이나 다중 실행 방지 처리가 되어 있는데 이런방식을 사용했다면 리버싱관점에서
이 부분을 뛰어 넘기면 멀티로더를 제작할수도 있을듯 하다.

+ Recent posts