엑셀VBA 익스플로러(윈도우) 포커싱하는 법
VBA로 뭔가 만들려고 할 때 엑셀만 제어해서 될 일이 아니라 다른 창이나 폴더를 제어해야 하는 경우가 많다. 지난 번 썼던 <엑셀VBA 오토마우스 만들기>를 참고하여 단순히 Alt+tab 을 누르도록 키보드 후킹해도 좋지만, 이번 내용이 좀 더 고급기술이다.
먼저 캡션과 클래스에 대해 간단히 알아보고 시작한다.
1. 띄우고 싶은 윈도우(창)에 대해 이해하기
프로그램에는 클래스명(Class)과 캡션(Caption)이라는 개념이 있다. 둘 중 하나만 알아내면 윈도우를 찾을 수 있는데, 우리는 캡션을 쓸 것이다.
첫번째로 클래스명은 변하지 않는 프로그램 고유의 것이다. 알아내는 법은 spy++같은 프로그램으로 ctrl+f 하여 해당 프로그램을 드래그하면 된다. 그러나 우리는 클래스명보다는 캡션을 쓸 것이니 자세히는 몰라도 된다. (Spy++는 보통 C++같은 언어를 설치할 때 동봉된다)
두번째로 캡션은, 해당 프로그램 윈도우 제목 부분에 쓰여있는 글이다. 이건 경우에 따라 변화하므로 주의해야 한다. 아래부터는 예를 통해 쉽게 이해해보자.
1-1. 폴더로 이해하기

“수당”이라는 폴더를 켠 상황이다. 보시다시피 윈도우 상단부에 “수당”이라고 적혀있다. 이게 캡션이다.
1-2. 메모장으로 이해하기

메모장을 켠 상황이다. 메모장의 클래스네임은 항상 “Notepad”이지만, 캡션은 어떻게 저장하냐에 따라 바뀔 수도 있다. 여기서의 캡션은 윈도우 최상단부에 쓰여있듯 “ㅇ.txt – 메모장”이다. 여기서 띄어쓰기라거나 대소문자만 바뀌어도 VBA는 인식을 못한다. 주의하자.
지금 이 파일을 ㅅ.txt로 바꿔 저장한다면 캡션도 바뀐다. 이렇듯 파일 이름에 따라 캡션은 바뀔 수 있다. 엑셀도 마찬가지다. 다시 말해 캡션으로 포커스하는 소스를 만들어두면, 캡션이 바뀜에 따라 포커스가 안될 수 있으므로 주의해야 한다.
(참고) 윈도우 핸들시 유용한 클래스 네임
참고삼아 유용한 클래스 네임은 다음과 같다. 파워포인트2007 “PP12FrameClass”, 파워포인트2003 “PP11FrameClass”, 파워포인트2002 (PPT XP버젼) “PP10FrameClass”, 파워포인트2000 “PP9FrameClass”, 파워포인트97 “PP97FrameClass”, 엑셀 “XLMAIN”, 워드 “OpusApp”, 메모장 “Notepad”
1-3. 익스플로러로 이해하기

마지막으로 익스플로러를 통해 이해해보자. 캡션은 “네이버 :: 나의 경쟁력, 네이버 – Windows Internet Explorer” 가 되겠다. 여기서 한 글자만 틀리거나 빠져도 인식하지 못한다.
2. VBA소스
2-1. 각종 선언들
‘//원하는 윈도우 핸들을 찾기 위한 선언
Private Declare Function FindWindow Lib “user32” Alias “FindWindowA” (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
‘//원하는 윈도우를 포커스하기 위한 선언
Public Declare Function SetForegroundWindow Lib “user32” (ByVal hwnd As Long) As Long
2-2. 윈도우 포커싱 소스(폴더나 익스플로러)
‘//ihwnd = FindWindow(클래스명, 캡션) 으로 핸들값을 받아올 수 있다. 이 때 클래스명과 캡션 둘 중 하나만 써넣고 나머지는 Null 처리해도 된다. 창을 못 찾았을 경우 0 을 돌려준다.
Dim ihwnd As Long
ihwnd = FindWindow(vbNullString, “수당”)
If ihwnd = 0 Then
MsgBox “현재 해당 윈도우를 찾을 수 없습니다”
Else
Call SetForegroundWindow(ihwnd)
End If
‘//수당이라는 폴더가 켜져있지 않으면 메세지를 나타내고, 켜져있으면 해당 윈도우를 포커싱한다. 익스플로러나 메모장도 똑같은 원리로 응용하면 되겠다.
2-3. 메모장 포커싱 소스
Dim ihWnd As Long
ihWnd = FindWindow(“Notepad”, vbNullString)
If ihWnd = 0 Then
Shell “C:\Windows\Notepad.exe”
Else
MsgBox “메모장이 켜져있습니다”
Call SetForegroundWindow(ihWnd)
End If
‘//메모장이 켜져있지 않으면 메모장을 실행, 그렇지 않으면 메모장을 포커싱하는 소스다.
2-4. 현재 작업중인 엑셀로 포커싱
‘//다른 창에서 작업하다가 다시 엑셀로 돌아갈 때 유용하다.
Dim ihwnd As Long
ihwnd = FindWindow(vbNullString, Application.Caption)
If ihwnd = 0 Then
MsgBox “현재 엑셀을 찾을 수 없습니다”
Else
Call SetForegroundWindow(ihwnd)
End If
‘//특히 엑셀의 클래스명 XLMAIN을 쓰기보단 위의 소스를 쓰는 게 개인적으로 더 좋았다.
2-5. 윈도우 제어하기
원래는 클래스명을 이용하여 자식클래스 뭐시기 하면서 제어하는 게 정석. 그러나 오토마우스 혹은 오토키보드를 이용하는게 접근하기 쉽다. 지난 번 썼던 <엑셀VBA 오토마우스 만들기>를 참고하여 제어해보자.