Languages/C#2010. 7. 19. 17:51

최근에 프로그래밍을 하면서 기본 Sound Device를 상황에 맞게 선택한 Device로 설정해야 하는 상황이 발생하였습니다.

이리저리 알아보고 이것저것 시도를 해보았지만 구글신에게 버림받고 COM, Multimedia, System Programming등 에 대한

이해와 실력이 부족하기에 좌절을 맛봐야 했습니다. ㅠㅠ

이번 포스팅은 저와 같이 모자란 실력에 고민하는 분들에게 "모로 가도 서울만 가면 된다" 는 말이 있듯이

약간의 어이 없는 방법을 소개하고자 합니다. -_- ;;

 

기본적으로 다음 그림과 같이 제어판의 소리 메뉴를 선택하여 장치 목록 중에서 기본 장치로 설정하기 위해

해당 목록을 선택하여 마우스 오른쪽 버튼을 눌러 팝업창을 띄운 후 기본 장치로 설정을 클릭하게 되면

기본 사운드 장치로 설정이 되어집니다.

 

 

제가 생각해 낸 방법은

바로 이 과정을 프로그래밍으로 동작할 수 있게 구현한 것입니다. ;;

 

이를 구현하기 위해서 오랫만에 API 함수를 사용하게 되었습니다.

두 가지의 메뉴를 선택할 수 있게 하였는데요. 사용 여부 메뉴와 기본 장치로 설정입니다.

 

부끄럽지만 저 과정을 코드로 옮긴 소스는 다음과 같습니다.

public SoundDeviceChange()

{

    // 사운드 설정 창 실행 ( 바로가기 파일 실행 )

    Process.Start("Sound.lnk");

 

    // 창이 열리기 위한 잠시 대기 시간

    Thread.Sleep(500);

 

    SetHandle();

 

    // 현재 윈도우를 최상위로 설정

    BringWindowToTop(new WindowInteropHelper(Application.Current.MainWindow).Handle);

 

    int moveX = (int)SystemParameters.FullPrimaryScreenWidth;

    int moveY = (int)SystemParameters.FullPrimaryScreenHeight;

 

    // 사운드 설정창의 위치를 오른쪽 하단으로 이동

    MoveWindow(soundHandle, moveX, moveY, 0, 0, false);

}

 

// 핸들 얻어오기

private void SetHandle()

{

    // 바탕화면 핸들

    deskTopHandle = GetDesktopWindow();

 

    // 사운드 설정 창 핸들

    soundHandle = FindWindow(null, "소리");

 

    // 사운드 설정 창의 재생 탭 핸들

    playHandle = GetWindow(soundHandle, GW_CHILD);

 

    // 사운드 설정 창의 라벨 핸들 ( 설정을 수정할 재생 장치 선택: )

    lableHandle = GetWindow(playHandle, GW_CHILD);

 

    // 사운드 설정 창의 목록(ListView) 핸들

    listViewHandle = GetWindow(lableHandle, GW_HWNDNEXT);

 

    // 사운드 설정 창이 늦게 뜰 경우를 대비

    if (listViewHandle == IntPtr.Zero)

    {

        SetHandle();

    }

}

 

// 해당 목록에서 마우스 오른 쪽 버튼 클릭 동작하는 함수

private void ShowPopupWindow(int soundDeviceIndex)

{

    // 선택 목록 인덱스가 이전 인덱스보다 위라면

    if (previousSoundDeviceIndex > soundDeviceIndex)

    {

        // 해당 인덱스 만큼 위로 이동

        for (int j = 0; j <= previousSoundDeviceIndex; j++)

        {

            PostMessage(listViewHandle, WM_KEYDOWN, VK_UP, 0);

        }

    }

    // 선택 목록 인덱스가 이전 인덱스보다 아래라면

    else

    {

        // 해당 인덱스 만큼 아래로 이동

        for (int j = 0; j <= soundDeviceIndex; j++)

        {

            PostMessage(listViewHandle, WM_KEYDOWN, VK_DOWN, 0);

        }

    }

 

    // 현재 지점에서 마우스 오른쪽 이벤트 발생

    PostMessage(listViewHandle, WM_RBUTTONUP, 0, 0);

 

    // 목록에 대한 설정 팝업 창 핸들 찾기

    while (true)

    {

        // 바탕화면 핸들의 첫번 째 자식( 팝업창은 첫 번째 자식 윈도우로 등록 됨 )

        popupHandle = GetWindow(deskTopHandle, GW_CHILD);

 

        // 윈도우의 클래스 이름 얻어오기

        GetClassName(popupHandle, className, 256);

 

        // 팝업창의 클래스 이름은 #32768

        if (className.ToString() == "#32768")

        {

            // 팝업창의 스타일을 WS_DISABLED로 설정하여 사라지게 만듬.

            SetWindowLong(popupHandle, GWL_STYLE, WS_DISABLED);

            break;

        }

    }

}

 

// 현재 인덱스의 디바이스를 기본 장치로 설정

public void ChangeDevice(int soundDeviceIndex)

{

    // 이전 디바이스 인덱스와 같으면 리턴

    if (previousSoundDeviceIndex == soundDeviceIndex)

    {

        return;

    }

 

    // 현재 목록에 대한 설정 팝업 창 실행

    ShowPopupWindow(soundDeviceIndex);

 

    // 기본 장치로 설정 메뉴 단축키는 D

    PostMessage(popupHandle, WM_KEYDOWN, VK_D, 0);

 

    // 이전 디바이스 인덱스 갱신

    previousSoundDeviceIndex = soundDeviceIndex;

}

 

// 현재 인덱스의 디바이스의 사용 여부를 변경

public void ChangeDevice(int soundDeviceIndex, bool disable)

{

    // 현재 목록에 대한 설정 팝업 창 실행

    ShowPopupWindow(soundDeviceIndex);

 

    // 사용은 2 칸 아래

    int keyDown = 2;

 

    // 사용 안함은 3칸 아래

    if (disable)

    {

        keyDown = 3;

    }

 

    // 해당 메뉴 만큼 아래로 이동

    for (int k = 0; k < keyDown; k++)

    {

        PostMessage(popupHandle, WM_KEYDOWN, VK_DOWN, 0);

    }

 

    // Enter 이벤트 발생

    PostMessage(popupHandle, WM_KEYDOWN, VK_RETURN, 0);

 

    // 이전 디바이스 인덱스 갱신

    previousSoundDeviceIndex = soundDeviceIndex;

}

 

실행화면과 같이 목록의 디바이스 중에서 선택한 선택한 디바이스를 선택하고

SoundChange 버튼을 누르게 되면 기본장치로 설정이 되어집니다.

Sound On 버튼을 누르면 사용 상태로 변경하게 되고 Sound Off 버튼을 누르면 사용 안함 상태로 변경되어 집니다.

 

제대로 된 방법이 아니기 때문에 몇 가지 제약사항이 있습니다.

 

1. 윈도우 7을 바탕으로 만들었기 때문에 다른 버전에서도 위와 같은 절차인지 모르겠습니다.

 

2. 팝업창을 DISABLE 시키긴 하지만 잠깐의 깜빡일 정도로 보일 수가 있습니다.

    컴퓨터 사양에 틀린 것 같습니다. 보이는 컴퓨터와 안 보이는 컴퓨터가 있더군요.

 

3. 스피커와 오디오의 팝업창 메뉴가 다르기 때문에 오디오를 선택 후 사용과 사용안함의 기능을

    사용하면 제대로 동작하지 않습니다. 오디오 목록들은 사운드 설정 창에서 사용안함으로 변경 후

    마우스 오른쪽 버튼을 눌러 사용 할 수 없는 장치 표시메뉴를 UnCheck 하시는게 좋습니다.

 

전체 코드는 첨부파일을 받으시면 됩니다.

 

혹시 진짜로 코드로 디바이스를 제어하는 법을 아시는 분께선 꼭 알려주시길 바랍니다. ㅠㅠ

'Languages > C#' 카테고리의 다른 글

[ C# ] Win32 API MouseEvent  (8) 2010.12.07
[ C# ] C# FTP Download  (3) 2010.07.21
[ C# ] XML 쓰고 읽기  (0) 2010.05.21
[ C# ] Network 연결 확인  (0) 2010.05.21
소수점 자릿수 출력하기  (0) 2009.04.11
Posted by 열ㅇl