/// <summary> /// Функция поворота экрана /// </summary> /// <param name="newOrientation">0 - 0, 1 - 90, 2 - 180, 3 - 270</param> private void vectorOrientation(SafeNativeMethods.DEVMODEW dm, uint newOrientation) { sens_orients.Clear(); // Чистим массив данных для корректного следующего поворота if ( ((newOrientation == (uint)Orientation.LANDSCAPE || newOrientation == (uint)Orientation.UNLANDSCAPE) && (dm.dmDisplayOrientation == (uint)Orientation.L_PORTRAIT || dm.dmDisplayOrientation == (uint)Orientation.R_PORTRAIT)) || ((newOrientation == (uint)Orientation.L_PORTRAIT || newOrientation == (uint)Orientation.R_PORTRAIT) && (dm.dmDisplayOrientation == (uint)Orientation.LANDSCAPE || dm.dmDisplayOrientation == (uint)Orientation.UNLANDSCAPE))) { // Меняем местами высоту и ширину экрана uint temp2 = dm.dmPelsHeight; dm.dmPelsHeight = dm.dmPelsWidth; dm.dmPelsWidth = temp2; } dm.dmDisplayOrientation = newOrientation; switch (SafeNativeMethods.ChangeDisplaySettingsExW(null, ref dm, IntPtr.Zero, (uint)Disp_Settings.CDS_.TEST, IntPtr.Zero)) // Тестим возможность изменения параметров дисплея { case Disp_Settings.DISP_CHANGE_SUCCESSFUL: // 0 SafeNativeMethods.ChangeDisplaySettingsExW(null, ref dm, IntPtr.Zero, reestrwrite, IntPtr.Zero); // Изменяем значения дисплея в динамическом режиме break; case Disp_Settings.DISP_CHANGE_RESTART: // 1 timer1.Stop(); SafeNativeMethods.ChangeDisplaySettingsExW(null, ref dm, IntPtr.Zero, (uint)Disp_Settings.CDS_.UPDATEREGISTRY, IntPtr.Zero); if (MessageBox.Show(Resources.DISP_CHANGE_RESTART_String + Environment.NewLine + Resources.Restart_Now_String, Resources.Attention_String, MessageBoxButtons.YesNo, MessageBoxIcon.Asterisk, MessageBoxDefaultButton.Button2) == DialogResult.Yes) { Process.Start("shutdown", "-r -t 5 -f"); } else { timer1.Start(); } break; case Disp_Settings.DISP_CHANGE_FAILED: // -1 timer1.Stop(); if (MessageBox.Show(Resources.DISP_CHANGE_FAILED_String + Environment.NewLine + Resources.Close_App_String, Resources.Attention_String, MessageBoxButtons.YesNo, MessageBoxIcon.Error, MessageBoxDefaultButton.Button2) == DialogResult.Yes) { gpsportopen = false; Close(); } else { timer1.Start(); } break; case Disp_Settings.DISP_CHANGE_BADMODE: // -2 timer1.Stop(); if (MessageBox.Show(Resources.DISP_CHANGE_BADMODE_String + Environment.NewLine + Resources.Close_App_String, Resources.Attention_String, MessageBoxButtons.YesNo, MessageBoxIcon.Asterisk, MessageBoxDefaultButton.Button2) == DialogResult.Yes) { gpsportopen = false; Close(); } else { timer1.Start(); } break; case Disp_Settings.DISP_CHANGE_BADDUALVIEW: // -6 timer1.Stop(); if (MessageBox.Show(Resources.DISP_CHANGE_BADDUALVIEW_String + Environment.NewLine + Resources.Close_App_String, Resources.Attention_String, MessageBoxButtons.YesNo, MessageBoxIcon.Error, MessageBoxDefaultButton.Button2) == DialogResult.Yes) { gpsportopen = false; Close(); } else { timer1.Start(); } break; case Disp_Settings.DISP_CHANGE_BADFLAGS: // -4 timer1.Stop(); if (MessageBox.Show(Resources.DISP_CHANGE_BADFLAGS_String + Environment.NewLine + Resources.Close_App_String, Resources.Attention_String, MessageBoxButtons.YesNo, MessageBoxIcon.Error, MessageBoxDefaultButton.Button2) == DialogResult.Yes) { gpsportopen = false; Close(); } else { timer1.Start(); } break; case Disp_Settings.DISP_CHANGE_BADPARAM: // -5 timer1.Stop(); if (MessageBox.Show(Resources.DISP_CHANGE_BADPARAM_String + Environment.NewLine + Resources.Close_App_String, Resources.Attention_String, MessageBoxButtons.YesNo, MessageBoxIcon.Error, MessageBoxDefaultButton.Button2) == DialogResult.Yes) { gpsportopen = false; Close(); } else { timer1.Start(); } break; case Disp_Settings.DISP_CHANGE_NOTUPDATED: // -3 timer1.Stop(); if (MessageBox.Show(Resources.DISP_CHANGE_NOTUPDATED_String + Environment.NewLine + Resources.Close_App_String, Resources.Attention_String, MessageBoxButtons.YesNo, MessageBoxIcon.Asterisk, MessageBoxDefaultButton.Button2) == DialogResult.Yes) { gpsportopen = false; Close(); } else { timer1.Start(); } break; default: break; } }
/// <summary> /// Выполняем функции по таймеру /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private unsafe void timer1_Tick(object sender, EventArgs e) { lock (locker) { Monitor.Enter(locker); Sensor_Orientation curr_sens_orient = new Sensor_Orientation(); Average_Coordinates ave_sens = new Average_Coordinates() { X = 0.00, Y = 0.00, Z = 0.00 }; short[] OutBuffer = new short[3]; uint bytesReturned = 0; if (UnsafeNativeMethods.ReadFile( gs.hDriver, OutBuffer, 6u, &bytesReturned, overlapped: null)) { curr_sens_orient.X = OutBuffer[0]; // X curr_sens_orient.Y = OutBuffer[1]; // Y curr_sens_orient.Z = OutBuffer[2]; // Z sens_orients.Add(curr_sens_orient); // Оставляем пару значений элементов массива для расчёта среднего и отслеживания выключателя if (sens_orients.Count >= 3) { sens_orients.RemoveRange(0, sens_orients.Count - 2); } // Теперь проверяем положение переключателя if (sens_orients.Count > 1) { if (sens_orients[sens_orients.Count - 1].X.Equals(sens_orients[sens_orients.Count - 2].X) && sens_orients[sens_orients.Count - 1].Y.Equals(sens_orients[sens_orients.Count - 2].Y) && sens_orients[sens_orients.Count - 1].Z.Equals(sens_orients[sens_orients.Count - 2].Z)) { notifyIcon1.Icon = Resources.Off; Monitor.Exit(locker); return; } } // Тут продолжаем процедуру автоматического поворота экрана (4 положения) // Выводим среднее для сглаживания for (int i = 0; i < sens_orients.Count; i++) { ave_sens.X += sens_orients[i].X; ave_sens.Y += sens_orients[i].Y; ave_sens.Z += sens_orients[i].Z; } if (((ave_sens.X / sens_orients.Count) + corr_orient.X) == 0) { ave_sens.X = 0.01; } else { ave_sens.X = (ave_sens.X / sens_orients.Count) + corr_orient.X; } if (((ave_sens.Y / sens_orients.Count) + corr_orient.Y) == 0) { ave_sens.Y = 0.01; } else { ave_sens.Y = (ave_sens.Y / sens_orients.Count) + corr_orient.Y; } ave_sens.Z = (ave_sens.Z / sens_orients.Count) + corr_orient.Z; // Переводим значения датчика в углы ориентации double Vert_angel = Math.PI * Vert_trackBar.Value / 180; double Hor_angel = Math.PI * Hor_trackBar.Value / 180; double Vert_Y_gip = Math.Sqrt(Math.Pow(ave_sens.Y, 2) + Math.Pow(ave_sens.Z, 2)); double Hor_gip = Math.Sqrt(Math.Pow(ave_sens.X, 2) + Math.Pow(ave_sens.Y, 2)); double Vert_X_gip = Math.Sqrt(Math.Pow(ave_sens.X, 2) + Math.Pow(ave_sens.Z, 2)); // Отрисовываем показатели сенсора if (Curr_Anim_checkBox.Checked) { Average_Coordinates temp = new Average_Coordinates() { X = (int)ave_sens.X + 256, Y = (int)ave_sens.Y + 256, Z = (int)ave_sens.Z + 256 }; if ((int)temp.X < 0) { temp.X = X_progressBar.Minimum; } if ((int)temp.X > 512) { temp.X = X_progressBar.Maximum; } X_progressBar.Value = (int)temp.X; label_X.Text = "X: " + curr_sens_orient.X.ToString("0"); if ((int)temp.Y < 0) { temp.Y = Y_progressBar.Minimum; } if ((int)temp.Y > 512) { temp.Y = Y_progressBar.Maximum; } Y_progressBar.Value = (int)temp.Y; label_Y.Text = "Y: " + curr_sens_orient.Y.ToString("0"); if ((int)temp.Z < 0) { temp.Z = Z_progressBar.Minimum; } if ((int)temp.Z > 512) { temp.Z = Z_progressBar.Maximum; } Z_progressBar.Value = (int)temp.Z; label_Z.Text = "Z: " + curr_sens_orient.Z.ToString("0"); double chl = 0.00; double cvl = 0.00; switch (Current_orientation) { case (uint)Orientation.LANDSCAPE: // 0 Cont_Hor_pictureBox.BackgroundImage = Resources.Hor_0; chl = Math.Acos(ave_sens.Y / Hor_gip) * 180 / Math.PI; cvl = Math.Acos(ave_sens.Y / Vert_Y_gip) * 180 / Math.PI; break; case (uint)Orientation.L_PORTRAIT: // 90 Cont_Hor_pictureBox.BackgroundImage = Resources.Hor_1; chl = 180 - (Math.Acos(ave_sens.X / Hor_gip) * 180 / Math.PI); cvl = 180 - (Math.Acos(ave_sens.X / Vert_X_gip) * 180 / Math.PI); break; case (uint)Orientation.UNLANDSCAPE: // 180 Cont_Hor_pictureBox.BackgroundImage = Resources.Hor_2; chl = 180 - (Math.Acos(ave_sens.Y / Hor_gip) * 180 / Math.PI); cvl = 180 - (Math.Acos(ave_sens.Y / Vert_Y_gip) * 180 / Math.PI); break; case (uint)Orientation.R_PORTRAIT: // 270 Cont_Hor_pictureBox.BackgroundImage = Resources.Hor_3; chl = Math.Acos(ave_sens.X / Hor_gip) * 180 / Math.PI; cvl = Math.Acos(ave_sens.X / Vert_X_gip) * 180 / Math.PI; break; default: break; } Cont_Vert_pictureBox.BackgroundImage = Resources.Vert_0; Control_Hor_label.Text = chl.ToString("0.00") + " \u00B0"; Control_Vert_label.Text = cvl.ToString("0.00") + " \u00B0"; } // При уходе за критические углы наклона просто выходим из цикла и меняем иконку if (Math.Abs(ave_sens.Z / ave_sens.Y) > Math.Tan(Vert_angel) & Math.Abs(ave_sens.Z / ave_sens.X) > Math.Tan(Vert_angel)) { notifyIcon1.Icon = Resources.Pause; Monitor.Exit(locker); return; } // Получаем текущую ориентацию экрана (портрет или ландшафт) notifyIcon1.Icon = Resources.On; SafeNativeMethods.DEVMODEW dm = new SafeNativeMethods.DEVMODEW(); dm.dmSize = (ushort)Marshal.SizeOf(dm); dm.dmFields = (uint)Disp_Settings.DM_.DISPLAYORIENTATION | (uint)Disp_Settings.DM_.PELSHEIGHT | (uint)Disp_Settings.DM_.PELSWIDTH; uint New_orientation = correct_orient(ave_sens.X, ave_sens.Y, Hor_angel); if (SafeNativeMethods.EnumDisplaySettingsExW(null, Disp_Settings.ENUM_CURRENT_SETTINGS, ref dm, Disp_Settings.EDS_ROTATEDMODE)) { Current_orientation = dm.dmDisplayOrientation; if (Current_orientation != New_orientation) { vectorOrientation(dm, New_orientation); } } } Monitor.Exit(locker); } }