Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 01.02.2013, 22:57   #1
DIgorevich
Погулять вышел
Участник клуба
 
Аватар для DIgorevich
 
Регистрация: 17.05.2010
Сообщений: 1,573
По умолчанию Не срабатывает отсыл сочетаний клавиш

По нажатию горячей клавиши вызывается процедура, которая вставляет в активное поле набора (в основном Word) указанный текст. Перед этим туда же посылается сочетание клавиш, которые форматируют вводимый текст. Но столкнулся с такой проблемой: включение и выключение горячих клавиш срабатывает не всегда и даже не через раз. Зависимости не нашел. А если поставить галочки на все пункты (жирный, курсивом, подчеркнутый), то все сразу сочетания клавиш посылаются только с третьей-четвертой попытки, а не с первой, как вроде по коду должно. Прошу помочь разобраться, код привожу.
Код:
function CtrlDown : Boolean;
var
  State : TKeyboardState;
begin
  GetKeyboardState(State);
  Result := ((State[vk_Control] and 128) <> 0);
end;

function ShiftDown : Boolean;
var
  State : TKeyboardState;
begin
  GetKeyboardState(State);
  Result := ((State[vk_Shift] and 128) <> 0);
end;

function AltDown : Boolean;
var
  State : TKeyboardState;
begin
  GetKeyboardState(State);
  Result := ((State[vk_Menu] and 128) <> 0);
end;



procedure inse(ttk: Boolean; text:string);
Var
  vGuiInfo:TGUIThreadInfo;
  i:Integer;
  al, sh, ct: Boolean;
begin
  vGuiInfo.cbSize:=SizeOf(TGUIThreadInfo);
  GetGUIThreadInfo(GetWindowThreadProcessId(GetForegroundWindow),vGuiInfo);
  sh:=False;
  al:=False;
  ct:=False;
  //Проверяем и запоминаем состояние управляющих клавиш
  if ShiftDown then   sh:= True;
  if AltDown then   al:= True;
  if CtrlDown then   ct:= True;
  //Принудительно отжимаем управляющие клавиши
    keybd_event(VK_CONTROL, MapVirtualKey(VK_CONTROL,0), KEYEVENTF_KEYUP, 0);
    keybd_event(VK_MENU, MapVirtualKey(VK_MENU,0), KEYEVENTF_KEYUP, 0);
    keybd_event(VK_SHIFT, MapVirtualKey(VK_SHIFT,0), KEYEVENTF_KEYUP, 0);
  if ttk then
    begin
     if Form3.TKB.Checked then   //Если стоит птичка, то посылаем Ctrl+B, делаем жирным
      begin
        keybd_event(VK_CONTROL, MapVirtualKey(VK_CONTROL, 0), 0, 0);
        keybd_event(Ord('B'), MapVirtualKey(Ord('B'), 0), 0, 0);
        keybd_event(Ord('B'), 0, KEYEVENTF_KEYUP, 0);
        keybd_event(VK_CONTROL, MapVirtualKey(VK_CONTROL,0), KEYEVENTF_KEYUP, 0);
      end;
     if Form3.TKI.Checked then //Если стоит птичка, то посылаем Ctrl+I, делаем курсивом
      begin
        keybd_event(VK_CONTROL, MapVirtualKey(VK_CONTROL, 0), 0, 0);
        keybd_event(Ord('I'), MapVirtualKey(Ord('I'), 0), 0, 0);
        keybd_event(Ord('I'), 0, KEYEVENTF_KEYUP, 0);
        keybd_event(VK_CONTROL, MapVirtualKey(VK_CONTROL,0), KEYEVENTF_KEYUP, 0);
      end;
     if Form3.TKU.Checked then //Если стоит птичка, то посылаем Ctrl+U, делаем подчеркнутым
      begin
        keybd_event(VK_CONTROL, MapVirtualKey(VK_CONTROL, 0), 0, 0);
        keybd_event(Ord('U'), MapVirtualKey(Ord('U'), 0), 0, 0);
        keybd_event(Ord('U'), 0, KEYEVENTF_KEYUP, 0);
        keybd_event(VK_CONTROL, MapVirtualKey(VK_CONTROL,0), KEYEVENTF_KEYUP, 0);
      end;
    end;
    //Вставляем текст
      for i:= 1 to Length(text) do
        begin
          PostMessage(vGuiInfo.hwndFocus, wm_Char, Word(text[i]), 0);
          Application.ProcessMessages;
        end;
  if ttk then
    begin
     if Form3.TKB.Checked then   //Если стоит птичка, то посылаем Ctrl+B, делаем нежирным
      begin
        keybd_event(VK_CONTROL, MapVirtualKey(VK_CONTROL, 0), 0, 0);
        keybd_event(Ord('B'), MapVirtualKey(Ord('B'), 0), 0, 0);
        keybd_event(Ord('B'), 0, KEYEVENTF_KEYUP, 0);
        keybd_event(VK_CONTROL, MapVirtualKey(VK_CONTROL,0), KEYEVENTF_KEYUP, 0);
      end;
     if Form3.TKI.Checked then //Если стоит птичка, то посылаем Ctrl+I, делаем не курсивом
      begin
        keybd_event(VK_CONTROL, MapVirtualKey(VK_CONTROL, 0), 0, 0);
        keybd_event(Ord('I'), MapVirtualKey(Ord('I'), 0), 0, 0);
        keybd_event(Ord('I'), 0, KEYEVENTF_KEYUP, 0);
        keybd_event(VK_CONTROL, MapVirtualKey(VK_CONTROL,0), KEYEVENTF_KEYUP, 0);
      end;
     if Form3.TKU.Checked then //Если стоит птичка, то посылаем Ctrl+U, делаем не подчеркнутым
      begin
        keybd_event(VK_CONTROL, MapVirtualKey(VK_CONTROL, 0), 0, 0);
        keybd_event(Ord('U'), MapVirtualKey(Ord('U'), 0), 0, 0);
        keybd_event(Ord('U'), 0, KEYEVENTF_KEYUP, 0);
        keybd_event(VK_CONTROL, MapVirtualKey(VK_CONTROL,0), KEYEVENTF_KEYUP, 0);
      end;
    end;
  //Восстанавливаем состояние управляющих клавиш
  if ct then   keybd_event(VK_CONTROL, MapVirtualKey(VK_CONTROL,0), 0, 0);
  if al then   keybd_event(VK_MENU, MapVirtualKey(VK_MENU,0), 0, 0);
  if sh then   keybd_event(VK_SHIFT, MapVirtualKey(VK_SHIFT,0), 0, 0);
end;
Пример вызова процедуры:
Код:
inse(false, '(Техническая съемка.)');
Никогда не знаешь, где тебе повезет... (Фрай)
DIgorevich вне форума Ответить с цитированием
Старый 02.02.2013, 05:10   #2
Кольша
Далеко не
Участник клуба
 
Аватар для Кольша
 
Регистрация: 11.08.2011
Сообщений: 1,512
По умолчанию

Возможно, надо посылать не активному окну, а компоненты(классу) который лежит на этом окне и принимает текст...определить его класс и имя для поиска можно через spy++
Кольша вне форума Ответить с цитированием
Старый 02.02.2013, 08:38   #3
DIgorevich
Погулять вышел
Участник клуба
 
Аватар для DIgorevich
 
Регистрация: 17.05.2010
Сообщений: 1,573
По умолчанию

Да отсыл-то текста сам по себе проходит всегда и успешно, потому что посылается именно активному компоненту
Код:
 vGuiInfo.cbSize:=SizeOf(TGUIThreadInfo);
  GetGUIThreadInfo(GetWindowThreadProcessId(GetForegroundWindow),vGuiInfo);

 PostMessage(vGuiInfo.hwndFocus, wm_Char, Word(text[i]), 0);
А вот сочетания клавиш отсылаются не всегда. Подозреваю, что где-то я перемудрил с отжатием-нажатием управляющих клавиш, но решение пока найти не могу.
Никогда не знаешь, где тебе повезет... (Фрай)
DIgorevich вне форума Ответить с цитированием
Старый 02.02.2013, 11:36   #4
Кольша
Далеко не
Участник клуба
 
Аватар для Кольша
 
Регистрация: 11.08.2011
Сообщений: 1,512
По умолчанию

Код:
Procedure SetKey(Key: Integer);
Begin
Keybd_Event(Key, 0, KEYEVENTF_EXTENDEDKEY Or KEYEVENTF_KEYUP, 0);
Keybd_Event(Key, 0, KEYEVENTF_EXTENDEDKEY,0);
Keybd_Event(Key, 0, KEYEVENTF_EXTENDEDKEY Or KEYEVENTF_KEYUP, 0);
End;
//может так?
Кольша вне форума Ответить с цитированием
Старый 02.02.2013, 12:46   #5
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Я бы не делал принудительное отжимание и восстановление состояния управляющих клавиш. Проверку можно сделать, предупредить и не посылать данные в поле ввода, если какая-то из них нажата. Без этого все нормально работает, если не одна из них не нажата, а так абракадабристо, особенно с Alt и Shift
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 02.02.2013, 13:37   #6
DIgorevich
Погулять вышел
Участник клуба
 
Аватар для DIgorevich
 
Регистрация: 17.05.2010
Сообщений: 1,573
По умолчанию

Дело в том, что сама процедура "inse(false, '(Техническая съемка.)'); вызывается по нажатию глобальной горячей клавиши. То есть схематично это выглядит так:
программа висит себе где-нибудь фоном,
нажимается горячая клавиша (сочетание в данном случае),
в активном поле ввода (word) шрифт меняется на курсив/жирный/подчеркнутый (в зависимости от указанных настроек),
вводится текст выбранным шрифтом,
шрифт меняется в исходное положение (убирается курсив/жирный/подчеркнутый).
Сделал небольшой проектик для демонстрации. Просто запустить программу, поставить нужные галочки. Программу свернуть. Запустить word (openoffice) и по нажатию комбинации Ctrl+Shift+J смотреть, что вводиться в документ.
Получается через раз, особенно если поставить сразу две или три галочки.
test.rar
Никогда не знаешь, где тебе повезет... (Фрай)
DIgorevich вне форума Ответить с цитированием
Старый 04.02.2013, 13:36   #7
DIgorevich
Погулять вышел
Участник клуба
 
Аватар для DIgorevich
 
Регистрация: 17.05.2010
Сообщений: 1,573
По умолчанию

Ребят, помощь все еще нужна!
Никогда не знаешь, где тебе повезет... (Фрай)
DIgorevich вне форума Ответить с цитированием
Старый 04.02.2013, 14:58   #8
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Код:
//    keybd_event(VK_CONTROL, MapVirtualKey(VK_CONTROL,0), KEYEVENTF_KEYUP, 0);
//    keybd_event(VK_MENU, MapVirtualKey(VK_MENU,0), KEYEVENTF_KEYUP, 0);
//    keybd_event(VK_SHIFT, MapVirtualKey(VK_SHIFT,0), KEYEVENTF_KEYUP, 0);
  if ttk then
    begin
     if Form1.TKB.Checked then   //Если стоит птичка, то посылаем Ctrl+B, делаем жирным
      begin
        keybd_event(VK_CONTROL, MapVirtualKey(VK_CONTROL, 0), 0, 0);
        keybd_event(Ord('B'), MapVirtualKey(Ord('B'), 0), KEYEVENTF_EXTENDEDKEY, 0);
        keybd_event(Ord('B'), 0, KEYEVENTF_EXTENDEDKEY or KEYEVENTF_KEYUP, 0);
        keybd_event(VK_CONTROL, MapVirtualKey(VK_CONTROL,0), KEYEVENTF_KEYUP, 0);
        Sleep(50);
      end;
     if Form1.TKI.Checked then //Если стоит птичка, то посылаем Ctrl+I, делаем курсивом
      begin
        keybd_event(VK_CONTROL, MapVirtualKey(VK_CONTROL, 0), 0, 0);
        keybd_event(Ord('I'), MapVirtualKey(Ord('I'), 0), KEYEVENTF_EXTENDEDKEY, 0);
        keybd_event(Ord('I'), 0, KEYEVENTF_EXTENDEDKEY OR KEYEVENTF_KEYUP, 0);
        keybd_event(VK_CONTROL, MapVirtualKey(VK_CONTROL,0), KEYEVENTF_KEYUP, 0);
        Sleep(50);
      end;
     if Form1.TKU.Checked then //Если стоит птичка, то посылаем Ctrl+U, делаем подчеркнутым
      begin
        keybd_event(VK_CONTROL, MapVirtualKey(VK_CONTROL, 0), 0, 0);
        keybd_event(Ord('U'), MapVirtualKey(Ord('U'), 0), KEYEVENTF_EXTENDEDKEY, 0);
        keybd_event(Ord('U'), 0, KEYEVENTF_EXTENDEDKEY OR KEYEVENTF_KEYUP, 0);
        keybd_event(VK_CONTROL, MapVirtualKey(VK_CONTROL,0), KEYEVENTF_KEYUP, 0);
        Sleep(50);
      end;
    end;

    //Вставляем текст
      for i:= 1 to Length(text) do
        begin
          PostMessage(vGuiInfo.hwndFocus, wm_Char, Word(text[i]), 0);
          Application.ProcessMessages;
        end;

  if ttk then
    begin
     if Form1.TKU.Checked then //Если стоит птичка, то посылаем Ctrl+U, делаем не подчеркнутым
      begin
        keybd_event(VK_CONTROL, MapVirtualKey(VK_CONTROL, 0), 0, 0);
        keybd_event(Ord('U'), MapVirtualKey(Ord('U'), 0),KEYEVENTF_EXTENDEDKEY, 0);
        keybd_event(Ord('U'), 0, KEYEVENTF_EXTENDEDKEY OR KEYEVENTF_KEYUP, 0);
        keybd_event(VK_CONTROL, MapVirtualKey(VK_CONTROL,0), KEYEVENTF_KEYUP, 0);
        Sleep(50);
      end;
     if Form1.TKI.Checked then //Если стоит птичка, то посылаем Ctrl+I, делаем не курсивом
      begin
        keybd_event(VK_CONTROL, MapVirtualKey(VK_CONTROL, 0), 0, 0);
        keybd_event(Ord('I'), MapVirtualKey(Ord('I'), 0), KEYEVENTF_EXTENDEDKEY, 0);
        keybd_event(Ord('I'), 0, KEYEVENTF_EXTENDEDKEY OR KEYEVENTF_KEYUP, 0);
        keybd_event(VK_CONTROL, MapVirtualKey(VK_CONTROL,0), KEYEVENTF_KEYUP, 0);
        Sleep(50);
      end;
     if Form1.TKB.Checked then   //Если стоит птичка, то посылаем Ctrl+B, делаем нежирным
      begin
        keybd_event(VK_CONTROL, MapVirtualKey(VK_CONTROL, 0), 0, 0);
        keybd_event(Ord('B'), MapVirtualKey(Ord('B'), 0), KEYEVENTF_EXTENDEDKEY, 0);
        keybd_event(Ord('B'), 0, KEYEVENTF_EXTENDEDKEY OR KEYEVENTF_KEYUP, 0);
        keybd_event(VK_CONTROL, MapVirtualKey(VK_CONTROL,0), KEYEVENTF_KEYUP, 0);
        Sleep(50);
      end;
    end;

  //Восстанавливаем состояние управляющих клавиш
//  if ct then   keybd_event(VK_CONTROL, MapVirtualKey(VK_CONTROL,0), 0, 0);
//  if al then   keybd_event(VK_MENU, MapVirtualKey(VK_MENU,0), 0, 0);
//  if sh then   keybd_event(VK_SHIFT, MapVirtualKey(VK_SHIFT,0), 0, 0);
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 04.02.2013, 16:39   #9
DIgorevich
Погулять вышел
Участник клуба
 
Аватар для DIgorevich
 
Регистрация: 17.05.2010
Сообщений: 1,573
По умолчанию

Аватар, большое спасибо. Про sleep-то я и не подумал.
Никогда не знаешь, где тебе повезет... (Фрай)
DIgorevich вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Перебор сочетаний Orjanruusu PHP 2 12.05.2012 11:42
Перебор неповторяющихся сочетаний David Villa Общие вопросы C/C++ 3 08.05.2012 10:53
Найти количество сочетаний из n по k и вывести все комбинации этих сочетаний на экран Рон99 Паскаль, Turbo Pascal, PascalABC.NET 2 14.12.2011 00:05
Восстановление сочетаний клавиш... Busine2009 Microsoft Office Word 0 28.06.2009 20:17
По нажатию, каких сочетаний клавиш можно программно развернуть приложение, если оно свернуто в трее? Johnny_B Win Api 1 04.06.2007 08:20