1
+ using Microsoft . Win32 ;
2
+ using System ;
3
+ using System . Data ;
4
+ using System . Diagnostics ;
5
+ using System . Drawing ;
6
+ using System . IO ;
7
+ using System . Linq ;
8
+ using System . Runtime . InteropServices ;
9
+ using System . Windows . Forms ;
10
+
11
+ namespace NVStreamer1080
12
+ {
13
+ public partial class NVStreamerMainUI : Form
14
+ {
15
+ public NVStreamerMainUI ( )
16
+ {
17
+ InitializeComponent ( ) ;
18
+ }
19
+
20
+ [ StructLayout ( LayoutKind . Sequential ) ]
21
+ public struct DispSet
22
+ {
23
+ [ MarshalAs ( UnmanagedType . ByValArray , SizeConst = 106 ) ]
24
+ byte [ ] padding0 ;
25
+ public int width , height , dummy , frequency ;
26
+ [ MarshalAs ( UnmanagedType . ByValArray , SizeConst = 32 ) ]
27
+ byte [ ] padding1 ;
28
+ } ;
29
+
30
+
31
+
32
+ [ DllImport ( "user32.dll" ) ]
33
+ public static extern int EnumDisplaySettings ( string a , int b , ref DispSet c ) ;
34
+ [ DllImport ( "user32.dll" ) ]
35
+ public static extern int ChangeDisplaySettings ( ref DispSet a , int b ) ;
36
+
37
+
38
+ private int initialWidth ;
39
+ private int initialHeight ;
40
+ private int initialRefresh ;
41
+ private bool useSecondScreen = false ;
42
+ NotifyIcon trayNotifyIcon ;
43
+ private void NVStreamerMainUI_Load ( object sender , EventArgs e )
44
+ {
45
+ Registry . CurrentUser . OpenSubKey ( "SOFTWARE\\ Microsoft\\ Windows\\ CurrentVersion\\ Run" , true ) . SetValue ( "NVStreamer1080" , Application . ExecutablePath ) ;
46
+
47
+ var disp = new DispSet ( ) ;
48
+ if ( EnumDisplaySettings ( null , - 1 , ref disp ) == 0 )
49
+ {
50
+ Application . Exit ( ) ;
51
+ return ;
52
+ }
53
+
54
+ initialWidth = disp . width ;
55
+ initialHeight = disp . height ;
56
+ initialRefresh = disp . frequency ;
57
+
58
+
59
+ var trayContextMenu = new ContextMenu ( ) ;
60
+ trayNotifyIcon = new NotifyIcon ( ) ;
61
+ IntPtr tryIconPtr = Resource1 . TrayIcon . Handle ;
62
+ Icon trayIcon = Icon . FromHandle ( tryIconPtr ) ;
63
+
64
+ trayContextMenu . MenuItems . Add ( "Show UI" , OnShow ) ;
65
+ trayContextMenu . MenuItems . Add ( "Exit" , OnExit ) ;
66
+ if ( Registry . CurrentUser . OpenSubKey ( "SOFTWARE\\ TapperWare\\ NVStreamer1080" , true ) == null )
67
+ Registry . CurrentUser . CreateSubKey ( "SOFTWARE\\ TapperWare\\ NVStreamer1080" , true ) ;
68
+ useSecondScreen = ( ( string ) Registry . CurrentUser . OpenSubKey ( "SOFTWARE\\ TapperWare\\ NVStreamer1080" , true ) . GetValue ( "UseSecondScreen" , "0" ) ) == "1" ;
69
+ if ( useSecondScreen )
70
+ useSecondScreenCB . Checked = true ;
71
+
72
+ trayNotifyIcon . Icon = trayIcon ;
73
+ trayNotifyIcon . Text = "NV Streamer 1080" ;
74
+ trayNotifyIcon . Click += OnShow ;
75
+
76
+ trayNotifyIcon . ContextMenu = trayContextMenu ;
77
+ trayNotifyIcon . Visible = true ;
78
+ CheckTimer . Enabled = true ;
79
+
80
+ }
81
+
82
+ private bool allowClose = false ;
83
+
84
+ protected override void Dispose ( bool isDisposing )
85
+ {
86
+ if ( ! allowClose )
87
+ {
88
+ ShowInTaskbar = false ;
89
+ Visible = false ;
90
+ return ;
91
+ }
92
+
93
+ if ( ( components != null ) )
94
+ {
95
+ components . Dispose ( ) ;
96
+ }
97
+
98
+ if ( isDisposing )
99
+ {
100
+ trayNotifyIcon . Dispose ( ) ;
101
+ }
102
+
103
+ if ( nv1080Set )
104
+ {
105
+ SetResolution ( initialWidth , initialHeight , initialRefresh ) ;
106
+ nv1080Set = false ;
107
+ }
108
+
109
+ base . Dispose ( isDisposing ) ;
110
+
111
+ }
112
+
113
+ private void OnExit ( object sender , EventArgs e )
114
+ {
115
+ allowClose = true ;
116
+ Application . Exit ( ) ;
117
+ }
118
+
119
+ private void OnShow ( object sender , EventArgs e )
120
+ {
121
+ ShowInTaskbar = true ;
122
+ Visible = true ;
123
+ BringToFront ( ) ;
124
+ CenterToScreen ( ) ;
125
+ }
126
+
127
+ private bool nv1080Set = false ;
128
+
129
+ private void SetResolution ( int w , int h , int r )
130
+ {
131
+
132
+ var disp = new DispSet ( ) ;
133
+ if ( EnumDisplaySettings ( null , - 1 , ref disp ) == 0 )
134
+ return ;
135
+
136
+ disp . width = w ;
137
+ disp . height = h ;
138
+ disp . frequency = r ;
139
+ ChangeDisplaySettings ( ref disp , 1 ) ;
140
+
141
+ }
142
+
143
+ private void CheckTimer_Tick ( object sender , EventArgs e )
144
+ {
145
+ var Switch = Path . Combine ( Environment . SystemDirectory , "DisplaySwitch.exe" ) ;
146
+ var nvRunning = Process . GetProcesses ( ) . Where ( a => a . ProcessName . ToLower ( ) == "nvstreamer" ) . Count ( ) > 0 ;
147
+ if ( nvRunning && ! nv1080Set )
148
+ {
149
+ if ( useSecondScreen )
150
+ {
151
+
152
+ Process . Start ( Switch , "/external" ) ;
153
+ label1 . Text = "NVStreamer active: External" ;
154
+ }
155
+ else
156
+ {
157
+ SetResolution ( 1920 , 1080 , 60 ) ;
158
+ label1 . Text = "NVStreamer active: 1920x1080@60" ;
159
+ }
160
+ nv1080Set = true ;
161
+ useSecondScreenCB . Enabled = false ;
162
+ }
163
+ else if ( ! nvRunning && nv1080Set )
164
+ {
165
+ if ( useSecondScreen )
166
+ {
167
+ Process . Start ( Switch , "/internal" ) ;
168
+ }
169
+ else
170
+ {
171
+ SetResolution ( initialWidth , initialHeight , initialRefresh ) ;
172
+ }
173
+ nv1080Set = false ;
174
+ label1 . Text = "NVStreamer not active" ;
175
+ useSecondScreenCB . Enabled = true ;
176
+ }
177
+ }
178
+
179
+ private void HideTimer_Tick ( object sender , EventArgs e )
180
+ {
181
+ ShowInTaskbar = false ;
182
+ Visible = false ;
183
+ HideTimer . Enabled = false ;
184
+
185
+ }
186
+
187
+ private void OnSecondScreenCheckboxChange ( object sender , EventArgs e )
188
+ {
189
+ Registry . CurrentUser . OpenSubKey ( "SOFTWARE\\ TapperWare\\ NVStreamer1080" , true ) . SetValue ( "UseSecondScreen" , useSecondScreenCB . Checked ? "1" : "0" , RegistryValueKind . String ) ;
190
+ useSecondScreen = useSecondScreenCB . Checked ;
191
+
192
+ }
193
+
194
+ }
195
+ }
0 commit comments