Pull to refresh

Неработающий сенсор закрытия крышки ноутбука и что из этого вышло

Какое-то время назад мой рабочий ноутбук отказался включаться. Просто не реагировал ни на какие попытки, включая отключение батареи. У технической поддержки ушло несколько месяцев на то, чтобы замененить практически все компоненты от матрицы до материнской платы и выяснить, что проблема была в перетертом шлейфе матрицы. Шлейф заменили, машина ожила и вернулась ко мне. Но в первый же день выяснилась интересная особенность — видимо, в пылу борьбы со шлейфом ремонтеры поломали или отключили датчик закрытия крышки. Теперь ноутбук не засыпает при закрытии крышки. Какое-то время я пытался найти способ устранить это самостоятельно, но в этот раз действенных советов Гугл и форумы комании Lenovo, к сожалению, не дали. Второй раз отдавать машину в ремонт просто страшно.

Ок, я не могу решить проблему механически, но может быть можно придумать, какой-то простой workaround. Например, я привык, уходя блокировать компьютер нажатием Win+L, почему бы не сделать shortcut для перевод машины в спящий режим? Выяснилось, что отправить машину в sleep несложно, но вот привязать это к нажатию на Ctrl+Q, например, уже не так тривиально. Можно найти софт, который будет управлять для вас этими функциями. Ну или написать свой. И так вышло, что как раз сегодня есть пара часов времени и стойкое желание попрактиковаться в программировании.

Так как программист я посредственный, то писать решил на C# в Visual Studio Community Edition. Чтобы не усложнять создал пустой проект в формате Windows Form Application с одной формой, в которую добавил контрол notifyIcon. Форму сделал невидимой сразу после старта, а в обработчк MouseDoubleClick добавил код включения и выключения видимости, чтобы форму можно было штатным образом закрыть. Эта мысль пришла не сразу, а после того, как стало понятно, что приложение должно уметь отменить регистрацию глобальных shortcut-ов после своей терминации.

Приложение добавлено в автозапуск и по нажатию на Ctrl+Q уверенно переводит машину в sleep. Не идеальное решение, но позволяет мириться с неработающим сенсором и несовершенством мира.
Может быть и вам эта поделка почему-то окажется полезной :)

Собственно код приложения тут:

using System;

namespace Sleep
{
    public partial class Form1 : Form
    {
        [System.Runtime.InteropServices.DllImport("user32.dll")]
        private static extern bool RegisterHotKey(IntPtr hWnd, int id, int fsModifiers, int vk);
        [System.Runtime.InteropServices.DllImport("user32.dll")]
        private static extern bool UnregisterHotKey(IntPtr hWnd, int id);

        enum KeyModifier
        {
            None = 0,
            Alt = 1,
            Control = 2,
            Shift = 4,
            WinKey = 8
        }

        protected override void WndProc(ref Message m)
        {
            base.WndProc(ref m);
            if (m.Msg == 0x0312)
            {
                // The key of the hotkey that was pressed.
                Keys key = (Keys)(((int)m.LParam >> 16) & 0xFFFF);
                // The modifier of the hotkey that was pressed.
                KeyModifier modifier = (KeyModifier)((int)m.LParam & 0xFFFF);
                // The id of the hotkey that was pressed.
                int id = m.WParam.ToInt32();
                Application.SetSuspendState(PowerState.Suspend, true, true);
            }
        }

        public Form1()
        {
            InitializeComponent();
            int id = 0;
            RegisterHotKey(this.Handle, id, (int)KeyModifier.Control, Keys.Q.GetHashCode());
        }

        private void Form1_Shown(object sender, EventArgs e)
        {
            this.Visible = false;
        }

        private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (this.Visible)
                this.Visible = false;
            else this.Visible = true;
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            UnregisterHotKey(this.Handle, 0);
        }
    }
}
Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.