У меня есть код, который, кажется, с ошибкой. Я не писал его, на самом деле он написан на с ++, и до тех пор, пока несколько недель назад я никогда не писал никакого кода на с ++.
У нас есть клавиатура для сенсорного экрана, которую мы вызываем, когда требуется ввод с клавиатуры, и закрываем, когда ее нет. Наше программное обеспечение можно использовать в киоске без физической клавиатуры, используя клавиатуру с сенсорным экраном, которую мы разработали много лет назад (ограничено 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;
}
Похоже, чтобы решить проблему.
Задача ещё не решена.
Других решений пока нет …