Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Блокировка клавиатуры


Автор: Rommik 4.9.2006, 18:18
В моем проекте есть DBGRID. При нажатии на нем определенных клавиш клавиатуры запускаются сторонние приложения с своими окнами и обрабатывают текущие записи грида. Так вот, при мгновенном нажатии, например Entera, запускается стороннее приложение, но фокус ввода остается на моей форме. Как бы мне передавать фокус в новое окно?? Если нажатие на клавиши происходит с некоторым интервалом, то все Ок, фокус на запущенном приложении. Как мне поступить???

Автор: Rodman 4.9.2006, 18:31
Цитата(Rommik @  4.9.2006,  18:18 Найти цитируемый пост)
запускается стороннее приложение


Так это у тя совсем другой ЕХЕшник или другая форма???


Если другая форма то
Код

Form2.SetFocus;

Автор: Fedia 5.9.2006, 02:30
Цитата(Rommik @  4.9.2006,  18:18 Найти цитируемый пост)
При нажатии на нем определенных клавиш клавиатуры запускаются сторонние приложения с своими окнами и обрабатывают текущие записи грида.

А зачем все так сложно закрученно ?

Цитата(Rommik @  4.9.2006,  18:18 Найти цитируемый пост)
Как бы мне передавать фокус в новое окно??

На запущенное приложение ?
Если запускать проложение напримет вот так:
Код

ShellExecute(0, 'open', 'test.exe', nil, nil, SW_SHOWNORMAL)
, то запущенное приложение автоматом получает фокус ввода. Если же фокус теряется, то можно опять передать ему фокус так:
Код

var
  h: Integer;
  AHWND: HWND;
begin
  AHWND:=FindWindow(nil, 'Тест');
  h := GetWindowLong(AHWND, GWL_HWNDPARENT);
  if IsIconic(h) then
  ShowWindow(h, SW_RESTORE);
  SetForegroundWindow(h);
end;
, где 'Тест' - заголовок окна запущенного приложения. Но лучше разобраться с причиной потери фокуса приложением.

Автор: bazzzman 5.9.2006, 03:13
SetForegroundWindow(h); не всегда работает. Но в данном случае работать будет.

Цитата
A process can set the foreground window only if one of the following conditions is true: 

The process is the foreground process. 
The process was started by the foreground process. 
The process received the last input event. 
There is no foreground process. 
The foreground process is being debugged. 
The foreground is not locked (see LockSetForegroundWindow). 
The foreground lock time-out has expired (see SPI_GETFOREGROUNDLOCKTIMEOUT in SystemParametersInfo). 
Windows 2000/XP: No menus are active.

Автор: Rommik 5.9.2006, 10:44
Запускается другой ехешник. Мне нужно дождаться завершения работы ехешника.

Автор: Romikgy 5.9.2006, 10:50
Цитата(Rommik @  5.9.2006,  09:44 Найти цитируемый пост)
Запускается другой ехешник

после этого поставь в своем приложении или Sleep(500); или юзай
WaitForSingleObject(хендл процесса, время ожидания);
если поставить время ожидания INFINITE будет ждать вечно пока не закроется вызваное тобой приложение

Автор: Rommik 5.9.2006, 11:09
Так и сделано. Но все равно при мгновенном нажатии клавиш запускается стороннее приложение а фокус ввода остается на моей форме.

Автор: Romikgy 5.9.2006, 12:57
Rommik, исходник в студию

Автор: Rommik 5.9.2006, 13:42
Код





Fillchar(startinfo,Sizeof(startinfo),#0);
startinfo.cb:=Sizeof(startinfo);
startinfo.dwFlags:=STARTF_USESHOWWINDOW;
h:=FindWindow(pchar('TMainForm'),pchar(MainForm.caption));
EnableWindow(h,False);
MainForm.Enabled:=false;
if not CreateProcess(nil, p1, nil, nil, true, REALTIME_PRIORITY_CLASS, nil, p2, startinfo,procinfo) then
                                begin
                                         MainForm.Enabled:=true;
                                         EnableWindow(h,True);
                                         Exit;
                                end;
                hh:=Procinfo.dwThreadId;
                        repeat
                                case WaitForSingleObject(Procinfo.hProcess, 10) of
                                        WAIT_OBJECT_0: Break;
                                        WAIT_TIMEOUT: MainForm.Repaint;
                                else
                                        RaiseLastOSError;
                                end;
                                Application.Restore;
                        until False;

                        CloseHandle( Procinfo.hProcess );
                        CloseHandle( Procinfo.hThread );
                        Application.Restore;

                MainForm.Enabled:=true;
                EnableWindow(h,True);


Автор: Демо 5.9.2006, 14:57
Код

//Запуск процесса
function ExecCmd(const aPath,aCommand: String;const aShow, aWaitExit: Boolean): Integer;
var
  pi:PROCESS_INFORMATION;
  si:STARTUPINFO;
  cmdLine: String;
  isOk: Boolean;
  Ret: DWord;
begin
  ZeroMemory(@si,sizeof(si));
  si.cb:=SizeOf(si);
  si.dwFlags := STARTF_FORCEONFEEDBACK+STARTF_USESHOWWINDOW;
  if aShow then si.wShowWindow := (SW_SHOWNORMAL) else si.wShowWindow := SW_HIDE;
  cmdLine := aCommand;

  isOk :=
         CreateProcess( nil,             // No module name (use command line).
                        PChar(cmdLine),  // Command line.
                        nil,             // Process handle not inheritable.
                        nil,             // Thread handle not inheritable.
                        False,           // Set handle inheritance to FALSE.
                        0,               // No creation flags.
                        nil,             // Use parent's environment block.
                        PChar(aPath),     // Use parent's starting directory.
                        si,              // Pointer to STARTUPINFO structure.
                        pi );             // Pointer to PROCESS_INFORMATION structure.
  if isOk then
  begin
    CloseHandle(pi.hThread);
    try
      if aWaitExit then WaitForSingleObject( pi.hProcess, INFINITE );
      GetExitCodeProcess(pi.hProcess,Ret);
      Result := Ret;
    finally
      CloseHandle(pi.hProcess);
    end;
  end
  else Result := -1;
end;

Автор: Rommik 5.9.2006, 17:47
Все отлично. Но все равно при мгновенном нажатии клавиш запускается стороннее приложение а фокус ввода остается на моей форме. Как мне активировать стороннее приложение, когда известно только имя ехешника???

Автор: dumb 5.9.2006, 18:10
EnumWindows + GetWindowModuleFileName + SetForegroundWindow

Автор: Elfebet 5.9.2006, 18:20
а какое ты действие обрабатываеш при нажатии клавиши onkeypress или onkeypressdown?
я к тому шо может быть у тя при нажатии клавиши фокус переходит на твой компонент, елси да то попробуй
Код

windowPrev:=GetNextWindow(Handle, GW_HWNDPREV);
SetActiveWindow(windowPrev);


Добавлено @ 18:21 
 smile 

Автор: Romikgy 5.9.2006, 18:58
Цитата(Rommik @  5.9.2006,  12:42 Найти цитируемый пост)
 end;                                Application.Restore;

на кой?

Автор: Rommik 7.9.2006, 09:52
Restore делаю для того, чтобы при передвижении запущенной программы на моей форме не было белого шлейфа.

Автор: Romikgy 7.9.2006, 10:09
попробуй заменить на Application.ProcessMessage

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)