개발

Windows API - ShellExecute에 대해서

Swimming_Kim 2019. 2. 5. 01:21

선량한(?) 나는 예제를 돌리고 있었다. (윈도우 10 && Visual studio 2017)


1
ShellExecute(GetDesktopWindow(), "open", ptr_snode->song->path, NULLNULL, SW_SHOW);
cs


 이 예제는 내 컴퓨터에서 mp3파일의 절대 경로를 알려주면 찾아서 틀어주는 그런 코드였는데...


 "open", ptr_snode->song->path


 이 두 부분에서 막히는 것이었다. 그래서 수많은 구글링과 생활코딩에 문의한 결과에 대한 리포팅을 남긴다. 


1. LPCSTR(멀티 바이트) && LPCWSTR(유니코드)


구글링한 결과 아주 친절하신 분의 포스트를 읽게 되었는데 (http://egloos.zum.com/pelican7/v/1768951) 결과적으로는 


LPCSTR = long pointer constant string = const char * 

LPCWSTR = long pointer constant wide string = const w_char * 


이렇게 이해할 수 있다고 하신다. 인코딩 방식에 대해서는 다른 포스트로 따로 정리를 해 보려 한다. 


어쨌거나, 단순히 오류가 뜨지 않게 하기 위함에 중점을 두고, ShellExecute의 선언부로 가 보면 다음과 같은 것을 볼 수가 있다. 


1
2
3
4
5
#ifdef UNICODE
#define ShellExecute  ShellExecuteW
#else
#define ShellExecute  ShellExecuteA
#endif // !UNICODE
cs


그렇다. ShellExecute의 매개변수가 유니코드를 사용하는 타입이면 ShellExecuteW를 사용하고, 유니코드가 아니라면 ShellExecuteA를 사용하는 것이다. 아~~주 간단히 말해서


ShellExecuteW ~ 유니코드

ShellExecuteA ~ 유니코드 아닌 것


그런데, 기본적으로 ShellExecuteA를 해도 어차피 내부적으로 다시 유니코드로 변환한다고 한다. 


그냥 문자열 상수 앞에 L 붙이거나, _T() 매크로로 감싸세요. A붙은 윈도우 API는 내부적으로 문자열을 유니코드로 변환한 다음 W붙은 API로 변환한 다음 호출되기 때문에(요즘 보편적으로 사용하는 윈도우는 다 이래요) 성능이 떨어질 수밖에 없습니다 from Facebook 생활코딩


그래서 사실, 나의 경우 ShellExecuteA로 그냥 해준다면 


1
ShellExecuteA(GetDesktopWindow(), "open", ptr_snode->song->path, NULLNULL, SW_SHOW);
cs


문제는 없었지만, ShellExecuteW(결국, ShellExecute)가 쓰이게 하고 싶어졌다!!!


방법 1. A2W 


멀티바이트 문자열을 유니코드 문자열로 바꾸어주는 함수이다!! 사용법은 다음과 같다.


1
2
3
4
5
6
7
8
9
10
#include <Windows.h>
#include <atlbase.h>
 
하고
 
USES_CONVERSION; // 이걸 꼭 써줘야 한다!! 컨버팅에 필요한 임시변수들이 선언되어 있다.
 
ShellExecute(GetDesktopWindow(), TEXT("open"), A2W(ptr_snode->song->path), NULLNULL, SW_SHOW);
 
이런 식으로 쓴다.
cs


참고로 W2A는 유니코드 문자열을 멀티바이트 문자열로 바꾸어 주는 함수이다.


방법 2. CA2W 


ATL 7.0 의 기능으로, Visual Studio .Net 이후 버전부터 사용 가능하다고 한다. 


USES_CONVERSION; 이런걸 안써줘도 된다!!



1
2
3
4
5
6
7
8
9
#include <Windows.h>
#include <atlbase.h>
 
하고
 
ShellExecute(GetDesktopWindow(), TEXT("open"), CA2W(ptr_snode->song->path), NULLNULL, SW_SHOW);
 
 
이런 식으로 쓴다.
cs


굳굳~ 다음에는 문자열 인코딩에 대해서 공부를 해보려고 한다. (TCHAR라던지... )





참고 : https://sonbosun.tistory.com/6 && https://nerve.tistory.com/138 && http://egloos.zum.com/pelican7/v/1768951 &&

https://norux.me/31 && https://sciphy.tistory.com/868