반응형

아이들이 컴퓨터로 영상을 보거나 게임할 때 습관적으로 소리를 너무 크게 해 놓는 경우가 많다. 소리를 줄이라고 말해도 그때 뿐, 다시 크게 해 놓곤 한다. 시스템 볼륨에 제한을 두고 일정 수준 이상으로 올라가면 자동으로 내리는 프로그램(Turn It Down)을 만들어 보자.

 

※ 참고

2021.11.21 - [C#] - C# Media Player Mp3

2022.01.06 - [C#] - C# AudioSwitcher System Audio/Sound Volume Control - 시스템 오디오/사운드 볼륨 컨트롤 1

2023.10.28 - [C#] - C# Sound Meter 사운드 미터

 

위 링크의 내용들을 참고해 코드를 작성한다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
using System;
using System.Runtime.InteropServices;
using System.Windows.Media;
 
using AudioSwitcher.AudioApi.CoreAudio;
using NAudio.CoreAudioApi;
 
namespace ConsoleApp1
{
    class Program
    {
        [DllImport("kernel32.dll")]
        static extern IntPtr GetConsoleWindow();
 
        [DllImport("user32.dll")]
        static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
 
        // Usage: filename [maxVol(0~100)] [playTime(sec)]
 
        static void Main(string[] args)
        {
            const int SW_HIDE = 0// 창 숨기기
            IntPtr handle = GetConsoleWindow();
            ShowWindow(handle, SW_HIDE);
            
            MediaPlayer MP = new MediaPlayer();
            MP.Open(new Uri("turndown.mp3", UriKind.Relative));
 
            int maxVol;
            if (args.Length > 0)
                maxVol = int.Parse(args[0]);
            else
                maxVol = 20;
 
            int playTime;
            if (MP.NaturalDuration.HasTimeSpan)
                playTime = MP.NaturalDuration.TimeSpan.Milliseconds;
            else if (args.Length > 1)
                playTime = int.Parse(args[1]) * 1000;
            else
                playTime = 6000;
                // 미디어 파일 시간 정보가 없다면 적당한 값을 넣는다.
 
            MMDeviceEnumerator enumerator = new MMDeviceEnumerator();
            MMDevice device = enumerator.GetDefaultAudioEndpoint(DataFlow.Render, Role.Console);
            // MMDeviceEnumerator를 CoreAudioController 보다 먼저 초기화해야 한다.
 
            CoreAudioDevice defaultPlaybackDevice = new CoreAudioController().DefaultPlaybackDevice;
            
            // defaultPlaybackDevice.Volume: 시스템 볼륨(0~100)
            // device.AudioMeterInformation.MasterPeakValue: 시스템 오디오 값(0~1)
            while (true)
            {
                float masterPeakValue = device.AudioMeterInformation.MasterPeakValue;
 
                if (defaultPlaybackDevice.Volume > maxVol && masterPeakValue > 0.3f)
                    // 볼륨이 maxVol 보다 크고 오디오 값이 0.3보다 크다면..
                {                    
                    MP.Play();
                    System.Threading.Thread.Sleep(playTime); // 메세지 재생 대기
                    MP.Stop();
 
                    defaultPlaybackDevice.Volume = maxVol; // 볼륨 감소
                }
 
                System.Threading.Thread.Sleep(1000); // 1초 마다 확인
            }
        }
    }
}
 

 

 

TurnItDown.zip
1.04MB

위 압축 파일에는 실행에 필요한 모든 파일과 설치 배치파일이 들어 있다.

 

압축을 풀고 install.bat를 실행한다.

 

C드라이브 turnitdown 폴더에 프로그램이 복사된다.

 

Startup 폴더에 run.bat 파일이 복사된다.

 

 

아이들 컴퓨터에 이렇게 세팅해 놓고 재부팅하면 프로그램이 자동으로 시작된다. 물론 어떤 UI도 없기 때문에 아이들은 이 프로그램이 실행되었다는걸 인식할 수 없다. 초기 조건은 시스템 볼륨 20 이상이고 오디오로 출력되는 소리 값이 0.3 이상이면 지정한 MP3 파일이 플레이되고 볼륨이 20으로 줄어든다.

 

ex) 시스템 볼륨을 70으로 해 놓고 유튜브 영상을 보면 볼륨을 줄인다는 MP3 메세지가 플레이되고 볼륨이 20으로 줄어든다.

 

플레이되는 MP3 메세지는 C:\turnitdown 폴더의 turndown.mp3인데, 원하는 메세지를 녹음해서 바꿀 수 있다.

설치시 제공되는 MP3파일에는 내 조카(준석이)를 위한 메세지가 녹음되어 있다.

 

메세지를 바꾸거나 볼륨 제한 조건을 바꾸고 싶다면 run.bat 파일을 수정한다.

예를들어 볼륨 제한을 35로 바꾸고, 메세지가 녹음된 MP3파일이 8초로 바뀌었다면 run.bat 파일에서 위 그림과 같이 20 6으로 된 부분을 35 8로 바꾼다.

 

반응형
Posted by J-sean
:

C# Sound Meter 사운드 미터

C# 2023. 10. 28. 20:10 |
반응형

Sound Meter를 표시해 보자.

 

NAudio 패키지를 설치한다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
using System;
using System.Text;
using NAudio.CoreAudioApi;
 
namespace ConsoleApp1
{    class Program
    {
        static void Main()
        {
            MMDeviceEnumerator enumerator = new MMDeviceEnumerator();
            MMDevice device = enumerator.GetDefaultAudioEndpoint(DataFlow.Render, Role.Console);
            
            while (true)
            {
                //Console.Write("\r{0}", device.AudioMeterInformation.MasterPeakValue);
                //System.Threading.Thread.Sleep(100);
 
                System.Threading.Thread.Sleep(100);
 
                float volume = device.AudioMeterInformation.MasterPeakValue;
                int scale = (int)Math.Floor(volume * 79);
 
                StringBuilder sb = new StringBuilder();
 
                Console.Write("\r");
                sb.Append("Value: " + scale + " ");
 
                if (scale < 1)
                {
                    sb.Append(' '79);
                    Console.Write(sb.ToString());
                    continue;
                }
                
                sb.Append('=', scale);
                sb.Append(' '79 - scale);
                Console.Write(sb.ToString());
            }
        }
    }
}
 

 

 

코드를 작성하고 실행한다.

 

시스템 오디오에서 나는 소리값이 표시된다.

 

※ 참고

Displaying a Volume Meter using NAudio

2023.10.26 - [Python] - Python Core Audio Windows Library 파이썬 코어 오디오 라이브러리

2022.01.06 - [C#] - C# AudioSwitcher System Audio/Sound Volume Control - 시스템 오디오/사운드 볼륨 컨트롤 1

2022.01.07 - [C#] - C# AudioSwitcher System Audio/Sound Volume Control - 시스템 오디오/사운드 볼륨 컨트롤 2

 

반응형
Posted by J-sean
:

C# Type Class 타입 클래스

C# 2022. 7. 20. 00:12 |
반응형

Type 클래스를 사용해 보자.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
using System;
using System.Reflection;
 
namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            //Type t = typeof(String);
            //Type t = Type.GetType("System.String");
            String str = "";
            Type t = str.GetType();
            // Gets a Type object that represents the specified type.
 
            MethodInfo[] methods = t.GetMethods();
            foreach (MethodInfo method in methods)
            {
                // String 클래스의 Substring 함수는 2개의 오버로딩 함수가 있다.
                if (method.Name == "Substring")
                {
                    Console.WriteLine("- Method: " + method.Name);
 
                    ParameterInfo[] parameters = method.GetParameters();
                    foreach (ParameterInfo parameter in parameters)
                    {
                        Console.WriteLine("Parameter: " + parameter.Name);
                    }
                }
            }
 
            Console.WriteLine();
 
            MethodInfo substr = t.GetMethod("Substring"new Type[] { typeof(int), typeof(int) });
            // Searches for the specified method whose parameters match the specified generic
            // parameter count, argument types and modifiers, using the specified binding constraints.
 
            Object result = substr.Invoke("Hello, World!"new Object[] { 75 });
            // Invokes the method or constructor represented by the current instance, using the
            // specified parameters.
 
            Console.WriteLine("{0} returned \"{1}\".", substr, result);
        }
    }
}
 

 

소스를 빌드하고 실행한다.

 

 

반응형
Posted by J-sean
:
반응형

2022.04.05 - [C#] - C# Joystick(Gamepad) Input Check - 조이스틱(게임패드) 입력 확인 1 의 내용을 참고하여 조금 더 간단히 조이스틱(게임패드) 입력을 확인해 보자.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
using System.Threading;
using System.Diagnostics;
 
using HidSharp;
using HidSharp.Utility;
using HidSharp.Reports;
 
namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            HidSharpDiagnostics.EnableTracing = true;
            HidSharpDiagnostics.PerformStrictChecks = true;
 
            DeviceList list = DeviceList.Local;
            list.Changed += (sender, e) => Console.WriteLine("Device list changed.");
 
            HidDevice[] hidDeviceList = list.GetHidDevices().ToArray();
 
            foreach (HidDevice dev in hidDeviceList)
            {
                if (!dev.ToString().Contains("gamepad"))
                {
                    Console.WriteLine(dev.GetProductName() + " is not a gamepad.");
                    continue;
                }
 
                try
                {
                    ReportDescriptor reportDescriptor = dev.GetReportDescriptor();
 
                    Debug.Assert(dev.GetMaxInputReportLength() == reportDescriptor.MaxInputReportLength);
                    Debug.Assert(dev.GetMaxOutputReportLength() == reportDescriptor.MaxOutputReportLength);
                    Debug.Assert(dev.GetMaxFeatureReportLength() == reportDescriptor.MaxFeatureReportLength);
 
                    foreach (DeviceItem deviceItem in reportDescriptor.DeviceItems)
                    {
                        {
                            HidStream hidStream;
                            if (dev.TryOpen(out hidStream))
                            {
                                Console.WriteLine(dev.GetProductName() + " opened.");
                                hidStream.ReadTimeout = Timeout.Infinite;
 
                                using (hidStream)
                                {
                                    byte[] inputReportBuffer = new byte[dev.GetMaxInputReportLength()];
                                    HidSharp.Reports.Input.HidDeviceInputReceiver inputReceiver =
                                        reportDescriptor.CreateHidDeviceInputReceiver();
                                    HidSharp.Reports.Input.DeviceItemInputParser inputParser =
                                        deviceItem.CreateDeviceItemInputParser();
 
                                    inputReceiver.Start(hidStream);
 
                                    while (true)
                                    {
                                        if (inputReceiver.WaitHandle.WaitOne(1000))
                                        {
                                            if (!inputReceiver.IsRunning) { break; } // Disconnected?
 
                                            Report report;
                                            while (inputReceiver.TryRead(inputReportBuffer, 0out report))
                                            {
                                                if (inputParser.TryParseReport(inputReportBuffer, 0, report) && inputParser.HasChanged)
                                                {
                                                    //inputParser.HasChanged는 버튼을 누르거나 놓는 등 상태가 변경되는 경우를 뜻한다.
 
                                                    //Console.WriteLine(BitConverter.ToString(inputReportBuffer));
 
                                                    if (inputReportBuffer[3== 0x00)
                                                    {
                                                        Console.WriteLine("Left");
                                                    }
                                                    else if (inputReportBuffer[3== 0xFF)
                                                    {
                                                        Console.WriteLine("Right");
                                                    }
                                                    else if (inputReportBuffer[4== 0x00)
                                                    {
                                                        Console.WriteLine("Up");
                                                    }
                                                    else if (inputReportBuffer[4== 0xFF)
                                                    {
                                                        Console.WriteLine("Down");
                                                    }
                                                    else if (inputReportBuffer[5== 0x1F)
                                                    {
                                                        Console.WriteLine("X");
                                                    }
                                                    else if (inputReportBuffer[5== 0x2F)
                                                    {
                                                        Console.WriteLine("A");
                                                    }
                                                    else if (inputReportBuffer[5== 0x4F)
                                                    {
                                                        Console.WriteLine("B");
                                                    }
                                                    else if (inputReportBuffer[5== 0x8F)
                                                    {
                                                        Console.WriteLine("Y");
                                                    }
                                                    else if (inputReportBuffer[6== 0x01)
                                                    {
                                                        Console.WriteLine("L Shoulder");
                                                    }
                                                    else if (inputReportBuffer[6== 0x02)
                                                    {
                                                        Console.WriteLine("R Shoulder");
                                                    }
                                                    else if (inputReportBuffer[6== 0x10)
                                                    {
                                                        Console.WriteLine("Select");
                                                    }
                                                    else if (inputReportBuffer[6== 0x20)
                                                    {
                                                        Console.WriteLine("Start");
                                                    }
                                                }
                                            }
                                        }
 
                                        if (Console.KeyAvailable)
                                        {
                                            ConsoleKeyInfo consoleKeyInfo = Console.ReadKey(true);
 
                                            if (consoleKeyInfo.Key == ConsoleKey.Escape)
                                            {
                                                Console.WriteLine("User stopped.");
                                                break;
                                                //hidStream.Close();
                                            }
                                        }
                                    }
                                }
 
                                Console.WriteLine("Gamepad closed.");
                            }
                            else
                            {
                                Console.WriteLine("Failed to open device.");
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                }
            }
        }
    }
}
 

 

소스를 입력하고 빌드한다.

 

 

프로그램을 실행하고 게임패드의 버튼을 누르면 어떤 버튼이 눌리는지 표시된다.

 

반응형
Posted by J-sean
:
반응형

컴퓨터에 연결된 모든 HID(Human Interface Devices)를 확인하고 조이스틱(게임패드)의 입력을 체크해 보자.

 

HidSharp를 설치한다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
using System.Threading;
using System.Diagnostics;
 
using HidSharp;
using HidSharp.Utility;
using HidSharp.Reports;
 
namespace ConsoleApp1
{
    class Program
    {
        static void WriteDeviceItemInputParserResult(HidSharp.Reports.Input.DeviceItemInputParser parser)
        {
            while (parser.HasChanged)
            {
                int changedIndex = parser.GetNextChangedIndex();
                DataValue previousDataValue = parser.GetPreviousValue(changedIndex);
                DataValue dataValue = parser.GetValue(changedIndex);
 
                Console.WriteLine(string.Format("  {0}: {1} -> {2}", (Usage)dataValue.Usages.FirstOrDefault(),
                    previousDataValue.GetPhysicalValue(), dataValue.GetPhysicalValue()));
            }
        }
 
        static void Main(string[] args)
        {
            HidSharpDiagnostics.EnableTracing = true;
            HidSharpDiagnostics.PerformStrictChecks = true;
 
            DeviceList list = DeviceList.Local;
            list.Changed += (sender, e) => Console.WriteLine("Device list changed.");
 
            Device[] allDeviceList = list.GetAllDevices().ToArray();
            Console.WriteLine("■ All device list:");
            foreach (Device dev in allDeviceList)
            {
                Console.WriteLine("- Name: " + dev.ToString() + "\n" + "  Path: " + dev.DevicePath);
            }
 
            Console.WriteLine("-----------------------------------------------");
 
            Stopwatch stopwatch = Stopwatch.StartNew();
            HidDevice[] hidDeviceList = list.GetHidDevices().ToArray();
 
            Console.WriteLine("■ HID device list (took {0} ms to get {1} devices):",
                              stopwatch.ElapsedMilliseconds, hidDeviceList.Length);
 
            foreach (HidDevice dev in hidDeviceList)
            {
                Console.WriteLine("- Name: " + dev);
                Console.WriteLine("  Path: " + dev.DevicePath);
 
                try
                {
                    ReportDescriptor reportDescriptor = dev.GetReportDescriptor();
 
                    // Lengths should match.
                    Debug.Assert(dev.GetMaxInputReportLength() == reportDescriptor.MaxInputReportLength);
                    Debug.Assert(dev.GetMaxOutputReportLength() == reportDescriptor.MaxOutputReportLength);
                    Debug.Assert(dev.GetMaxFeatureReportLength() == reportDescriptor.MaxFeatureReportLength);
 
                    foreach (DeviceItem deviceItem in reportDescriptor.DeviceItems)
                    {
                        foreach (uint usage in deviceItem.Usages.GetAllValues())
                        {
                            Console.WriteLine(string.Format("  Usage: {0:X4} {1}", usage, (Usage)usage));
                        }
 
                        {
                            Console.WriteLine("Opening device for 20 seconds...");
 
                            HidStream hidStream;
                            if (dev.TryOpen(out hidStream))
                            {
                                Console.WriteLine("Opened device.");
                                hidStream.ReadTimeout = Timeout.Infinite;
 
                                using (hidStream)
                                {
                                    byte[] inputReportBuffer = new byte[dev.GetMaxInputReportLength()];
                                    HidSharp.Reports.Input.HidDeviceInputReceiver inputReceiver = 
                                        reportDescriptor.CreateHidDeviceInputReceiver();
                                    HidSharp.Reports.Input.DeviceItemInputParser inputParser = 
                                        deviceItem.CreateDeviceItemInputParser();
 
                                    inputReceiver.Start(hidStream);
 
                                    int startTime = Environment.TickCount;
                                    while (true)
                                    {
                                        if (inputReceiver.WaitHandle.WaitOne(1000))
                                        {
                                            if (!inputReceiver.IsRunning) { break; } // Disconnected?
 
                                            Report report;
                                            while (inputReceiver.TryRead(inputReportBuffer, 0out report))
                                            {
                                                // Parse the report if possible.
                                                // This will return false if (for example) the report applies to a different DeviceItem.
                                                if (inputParser.TryParseReport(inputReportBuffer, 0, report))
                                                {
                                                    WriteDeviceItemInputParserResult(inputParser);
                                                }
                                            }
                                        }
 
                                        uint elapsedTime = (uint)(Environment.TickCount - startTime);
                                        if (elapsedTime >= 20000) { break; } // Stay open for 20 seconds.
                                    }
 
                                }
 
                                Console.WriteLine("Closed device.");
                            }
                            else
                            {
                                Console.WriteLine("Failed to open device.");
                            }
 
                            Console.WriteLine("  ---------------------------------------------");
                        }
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                }
            }
        }
    }
}
 

 

소스를 입력하고 빌드한다.

 

 

프로그램을 실행하면 연결된 모든 디바이스와 HID가 표시되고 open 가능한 디바이스(usb gamepad)는 입력을 받아 표시한다.

포커스가 다른 프로그램에 있어도 디바이스의 입력을 확인 할 수 있다.

 

 

각 버튼이 눌렸을때 inputReportBuffer의 변화되는 내용을 확인해 보면 아래와 같다.

(첫 번째 바이트의 '01'은 Report ID인거 같다)

 

1
Console.WriteLine(BitConverter.ToString(inputReportBuffer));
 

 

01-80-80-7F-7F-0F-00-00
01-80-80-00-7F-0F-00-00
  GenericDesktopX: 127 -> 0

01-80-80-7F-7F-0F-00-00
01-80-80-FF-7F-0F-00-00
  GenericDesktopX: 127 -> 255

01-80-80-7F-7F-0F-00-00
01-80-80-7F-00-0F-00-00
  GenericDesktopY: 127 -> 0
  
01-80-80-7F-7F-0F-00-00
01-80-80-7F-FF-0F-00-00
  GenericDesktopY: 127 -> 255
※게임패드의 방향버튼은 기본이(버튼이 눌리지 않았을때) 127

01-80-80-7F-7F-0F-00-00
01-80-80-7F-7F-1F-00-00
  Button1: 0 -> 1

01-80-80-7F-7F-0F-00-00
01-80-80-7F-7F-2F-00-00
  Button2: 0 -> 1
  
01-80-80-7F-7F-0F-00-00
01-80-80-7F-7F-4F-00-00
  Button3: 0 -> 1

01-80-80-7F-7F-0F-00-00
01-80-80-7F-7F-8F-00-00
  Button4: 0 -> 1
※게임패드의 버튼은 기본이(버튼이 눌리지 않았을때) 0

 

※ HidSharp

 

반응형
Posted by J-sean
:
반응형

콘솔 환경에서 키 입력을 확인해 보자.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.TreatControlCAsInput = true;
            // Prevent example from ending if CTL+C is pressed.
            ConsoleKeyInfo consoleKeyInfo;
 
            for (int i = 0; i < 10; i++)
            {
                while (Console.KeyAvailable)
                {
                    consoleKeyInfo = Console.ReadKey(true);
                    // Obtains the next character or function key pressed by the user.
                    // 'true' to not display the pressed key; otherwise, false.
 
                    if ((consoleKeyInfo.Modifiers & ConsoleModifiers.Control) != 0
                        && consoleKeyInfo.Key == ConsoleKey.C)
                    // if (consoleKeyInfo.Key == ConsoleKey.Escape)
                    {
                        Console.WriteLine("Stopped.");
                        return;
                    }
                }
                // 모든 입력을 바로 처리하기 위해(입력 버퍼 비우기) if()가 아닌 while() 사용.
 
                Console.WriteLine(i + 1);
                System.Threading.Thread.Sleep(1000);
            }
        }
    }
}
 

 

소스를 입력하고 빌드한다.

 

프로그램을 실행하고 Ctrl+C를 누르면 정지된다.

 

반응형
Posted by J-sean
:
반응형

이미지 파일을 Drag & Drop으로 열어보자.

 

WinForm에 PictureBox를 적당히 배치한다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
 
namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
 
            pictureBox1.SizeMode = PictureBoxSizeMode.Zoom;
            pictureBox1.AllowDrop = true;
            // 인텔리센스에는 pictureBox1.AllowDrop가 표시되지 않는다.
            // 하지만 사용은 가능하며 인텔리센스를 사용하고 싶다면 아래처럼
            // Control로 형변환해서 해도 된다.
            // ((Control)pictureBox1).AllowDrop = true;
        }
 
        private void pictureBox1_DragOver(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                e.Effect = DragDropEffects.Copy;
            }
        }
 
        private void pictureBox1_DragDrop(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
                // 드롭된 파일들의 전체 경로명을 반환.
                foreach (string file in files)
                {
                    if (file.EndsWith("jpg"|| file.EndsWith("JPG"))
                    {
                        // JPG 파일만 디스플레이
                        pictureBox1.Image = System.Drawing.Image.FromFile(file);
                    }
                }
            }
        }
    }
}
 

 

소스를 입력하고 빌드한다.

 

프로그램을 실행하고 PictureBox 위로 JPG파일을 드래그 & 드롭한다.

 

이미지가 표시된다.

 

반응형
Posted by J-sean
:
반응형

간단한 Drag & Drop을 구현해 보자.

 

WinForm에 ListBox 두 개를 적당히 배치한다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
 
namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
 
            listBox2.AllowDrop = true;
 
            listBox1.Items.Add("모니터");
            listBox1.Items.Add("키보드");
            listBox1.Items.Add("스피커");
            listBox1.Items.Add("마우스");
            listBox1.Items.Add("카메라");
        }
 
        private void listBox1_MouseDown(object sender, MouseEventArgs e)
        {
            DragDropEffects effect;
 
            int index = listBox1.IndexFromPoint(e.X, e.Y);
            // listBox1.SelectedIndex을 사용하지 않으므로
            // 오른쪽 마우스 버튼의 드래그&드롭도 처리 가능
 
            if (index != ListBox.NoMatches)
            {
                string item = (string)listBox1.Items[index];
                effect = DoDragDrop(item, DragDropEffects.Copy | DragDropEffects.Move);
                if (effect == DragDropEffects.Move)
                {
                    listBox1.Items.RemoveAt(index);
                }
            }
        }
 
        private void listBox1_QueryContinueDrag(object sender, QueryContinueDragEventArgs e)
        {
            if (e.EscapePressed)
            {
                e.Action = DragAction.Cancel;
                // 드래그&드롭 중 ESC키가 눌리면 취소된다.
            }
        }
 
        private void listBox2_DragOver(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.StringFormat))
            {
                // StringFormat 형식을 허용하기 때문에 다른 프로그램(노트패드 등)
                // 의 문자열을 선택하고 드래그&드롭도 가능하다.
 
                if ((e.KeyState & 8!= 0)
                {
                    e.Effect = DragDropEffects.Copy;
                    // 1 (bit 0)   The left mouse button.
                    // 2 (bit 1)   The right mouse button.
                    // 4 (bit 2)   The SHIFT key.
                    // 8 (bit 3)   The CTRL key.
                    // 16 (bit 4)  The middle mouse button.
                    // 32 (bit 5)  The ALT key.
                }
                else
                {
                    e.Effect = DragDropEffects.Move;
                }
            }
        }
 
        private void listBox2_DragDrop(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.StringFormat))
            {
                listBox2.Items.Add(e.Data.GetData(DataFormats.StringFormat));
            }
        }
    }
}
 

 

소스를 입력하고 빌드한다.

 

프로그램을 실행하면 위와 같이 표시된다.

 

드래그 & 드롭으로 복사 및 이동이 가능하다.

 

 

다른 프로그램의 문자열도 복사 및 이동이 가능하다.

 

반응형
Posted by J-sean
: