Не зря предостерегают от SendKeys: мало того, что во время работы клавиатуру не тронь, так еще и мусорит, и "соседние кнопки" умудряется задеть.
Результат проверки GetKeyboardState и GetKeyState - это, насколько я понял: считается ли клавиша НАЖАТОЙ или ОТПУЩЕННОЙ!!! Именно эти состояния автор темы именовал "стабильным" и "изменчивым" (только в каком сочетании - не разобрался я)
А SENDKEYS, как я понял, передает за один раз не целое переключение: кнопка нажата и отпущена, а только его половину. Такие переключатели, как NUMLOCK совершают цикл за два целых переключения, стало быть, за 4 SENDKEYS. Вот и объяснение 4-х состояний для NUMLOCK.
Мне, кстати, не удалось добиться от GetKeyboardState и GetKeyState ничего, кроме 0 или 1, свидетельствующих (как уважаемые форумчане точно подметили) нажата клавиша или отпущена.
В одном из этих состояний (честно, не стал досконально разбираться в каком: при нажатой, но не отпущенной или при ненажатой клавише) SENDKEYS "^©" своего соседа NUMLOCK "задевает и переключает", а в другом - не трогает! Но переключая значения, не изменяет нажатость!!!
ЕЩЁ!!!! Я проверил эффект SENDKEYS "^©" для состояния клавиши Ctrl - у нее тоже меняется состояние нажатости и однократное нажатие "мусорит" и здесь! Как-то потом техника справляется, а, может, и не справляется. В общем, мусор от SendKeys остается и там!
Время от времени обращал внимание: слетал режим INSERT, но реже и с ним разбираться не стал.
Предложенный костыль через "WScript.Shell" соседей не задевает, но мусор неотжатой кнопки Ctrl оставляет все равно.
Как обойти? Можно, конечно, проверять для NUMLOCKа GetKeyState и если он 1, то после SendKeys "^©" дважды SENDKEYS "{NUMLOCK}
Самый чистый, на мой взгляд - двукратный посыл SendKeys "^©"! Но если в коде их сделать подряд, то система не успевает реагировать и эффект получается как от одного, поэтому нужно поставить между ними ожидание (на моем компе хватило и 0,01 секунды). Это, кстати, касается и двукратного SENDKEYS "{NUMLOCK}.
Итак. на мой взгляд решение может быть таким:
Код |
---|
SendKeys "^(c)", True tim = Date * 24 * 3600 + Timer + 0.01 Do DoEvents Loop While tim > (Date * 24 * 3600 + Timer) SendKeys "^(c)", True |
P.S.: еще ложечка деготка: эффект SendKeys "^©" зависит от раскладки клавиатуры!!!!!
При русской раскладке он мне вводил "c" вместо копирования выделенного!
Поэтому перед всеми SendKeys лучше запомнить текущую раскладку, сменить раскладку на латиницу, а потом вернуть ту, что была.
Прикладываю для пытливых умов файл с результатами экспериментов. Поскольку не обнаружил: как проверять "лампочку NUMLOCKа", то заносил ручками да/нет
"Даже если ясность изложения исключает неверное толкование, все равно найдется кто-то, кто поймет Вас неправильно."