GetForegroundWindow не всегда правильно?

У меня есть код, который, кажется, с ошибкой. Я не писал его, на самом деле он написан на с ++, и до тех пор, пока несколько недель назад я никогда не писал никакого кода на с ++.

У нас есть клавиатура для сенсорного экрана, которую мы вызываем, когда требуется ввод с клавиатуры, и закрываем, когда ее нет. Наше программное обеспечение можно использовать в киоске без физической клавиатуры, используя клавиатуру с сенсорным экраном, которую мы разработали много лет назад (ограничено a-z, 0-9, ввод, смещение, вкладка).

Клавиатура «отстает» от приложения на некоторых компьютерах с Windows 7 (могут быть другие, но не видят проблему на других ОС).

Работал годами. Я обновил другие части, чтобы наконец работать с Windows 7, теперь на 66% наших установок Windows 7 клавиатура вообще не подходит (находится за приложением). Сначала я думал, что на моем компьютере это происходит в 100% случаев, но продолжающиеся тесты показали, что это происходит в 95-99% случаев, что затрудняет поиск неисправностей.

Кроме того, большинство постов о GetForegroundWindow () имеют дело с отправкой или получением сообщений в и из другого приложения, а не о многоуровневых приложениях (как мне нужно).

Когда я начал, код выглядел так:

  bool ShowKeyBoad(bool Show)
{
int WizHeight = 422;
int KeyWidth,KeyHeight,KeyLeft, KeyTop;
AnsiString Params;
AnsiString ShowFile = GetFullPath(GetExeDir(), "OnscreenKeyboard.exe");
AnsiString HideFile = GetFullPath(GetExeDir(), "bkecekeyboard.exe");

KeyHeight = Screen->Height - WizHeight;
KeyWidth = Screen->Width;
if (KeyWidth > Screen->Width)
KeyWidth = Screen->Width;

KeyLeft   = (Screen->Width - KeyWidth) / 2;
KeyTop    = (Screen->Height) - KeyHeight;

Params = "x-"  + IntToStr(KeyLeft)   + " y-" + IntToStr(KeyTop) +
" h-" + IntToStr(KeyHeight) + " w-" + IntToStr(KeyWidth);

if (Show)
{
HWND Hand= GetForegroundWindow();
ShellExecute(NULL, "open", ShowFile.c_str(), Params.c_str(), NULL, SW_SHOWNORMAL);
Sleep(100);
SetForegroundWindow(Hand);
SetActiveWindow(Hand);
}
else
ShellExecute(NULL, "open", HideFile.c_str(), "/stop", NULL, SW_HIDE);

return true;
}

Я попробовал несколько вещей.
Захват HWND ShellExecute и передача его в SetActiveWindow (ShellHand), казалось, имели некоторый эффект. Но все еще не соответствует.
HWND shellHand = ShellExecute (NULL, «open», ShowFile.c_str (), Params.c_str (), NULL, SW_SHOWNORMAL);

Добавление Sleep (25) перед HWND Hand = GetForegroundWindow (); оказал наибольшее влияние на графический интерфейс — но я не хочу полагаться на правильное время.

Различные поиски в Интернете указали мне на некоторый код, который также казался довольно хорошим. Но это меняет настройки реестра, и это не кажется мудрым выбором.

С этим решением мы меняем SetForeground на SetForegroundInternal

  void SetForegroundWindowInternal(HWND hWnd)
{
if(!::IsWindow(hWnd)) return;

//relation time of SetForegroundWindow lock
DWORD lockTimeOut = 0;
HWND  hCurrWnd = ::GetForegroundWindow();
DWORD dwThisTID = ::GetCurrentThreadId(),
dwCurrTID = ::GetWindowThreadProcessId(hCurrWnd,0);

//we need to bypass some limitations from Microsoft :)
if(dwThisTID != dwCurrTID)
{
::AttachThreadInput(dwThisTID, dwCurrTID, TRUE);

::SystemParametersInfo(SPI_GETFOREGROUNDLOCKTIMEOUT,0,&lockTimeOut,0);
::SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT,0,0,SPIF_SENDWININICHANGE | SPIF_UPDATEINIFILE);

::AllowSetForegroundWindow(ASFW_ANY);
}

::SetForegroundWindow(hWnd);

if(dwThisTID != dwCurrTID)
{
::SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT,0,(PVOID)lockTimeOut,SPIF_SENDWININICHANGE | SPIF_UPDATEINIFILE);
::AttachThreadInput(dwThisTID, dwCurrTID, FALSE);
}
}

Обновить
предполагая, что Hand = NULL — моя проблема, я сделал код похожим на это:

  bool ShowKeyBoad(bool Show)
{
int WizHeight = 422;
int KeyWidth,KeyHeight,KeyLeft, KeyTop;
AnsiString Params;
AnsiString ShowFile = GetFullPath(GetExeDir(), "OnscreenKeyboard.exe");
AnsiString HideFile = GetFullPath(GetExeDir(), "bkecekeyboard.exe");

KeyHeight = Screen->Height - WizHeight;
KeyWidth = Screen->Width;
if (KeyWidth > Screen->Width)
KeyWidth = Screen->Width;

KeyLeft   = (Screen->Width - KeyWidth) / 2;
KeyTop    = (Screen->Height) - KeyHeight;

Params = "x-"  + IntToStr(KeyLeft)   + " y-" + IntToStr(KeyTop) +
" h-" + IntToStr(KeyHeight) + " w-" + IntToStr(KeyWidth);

if (Show)
{

HWND Hand;
int intfail=1000;  // count down seems correct in this case, usually don't
while (Hand = NULL)
{
if (intfail <=0)
break;

Hand = GetForegroundWindow();
intfail--;
}

if (Hand == NULL)
{
// Send Message to screen giving instructions to try again
return false;
}

ShellExecute(NULL, "open", ShowFile.c_str(), Params.c_str(), NULL, SW_SHOWNORMAL);
Sleep(100);
SetForegroundWindow(Hand);
SetActiveWindow(Hand);
}
else
ShellExecute(NULL, "open", HideFile.c_str(), "/stop", NULL, SW_HIDE);

return true;
}

Похоже, чтобы решить проблему.

0

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]