0

エラーがあると思われるコードがいくつかあります。私はそれを書きませんでした。実際、これは C++ で書かれており、数週間前まで C++ でコードを書いたことはありませんでした。

キーボード入力が必要な場合は表示し、必要でない場合は閉じるタッチ スクリーン用のキーボードがあります。当社のソフトウェアは、数年前に開発したタッチ スクリーン キーボード (az、0-9、enter、shift、tab に限定) を使用して、物理キーボードなしでキオスクで使用できます。

Windows 7 を搭載した一部のコンピューターでは、キーボードがアプリケーションの「背後」にあります (他のコンピューターでは可能性がありますが、他の OS では問題は見られません)。

何年も働いた。最終的に Windows 7 で動作するように他の部分を更新しましたが、Windows 7 インストールの 66% で、キーボードがまったく表示されません (アプリケーションの背後にあります)。私のコンピュータでは、最初は 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;
  } 

私はいくつかのことを試しました。
ShellExecute の HWND をキャプチャし、それを SetActiveWindow(ShellHand) に渡すと、何らかの効果があるように見えました。しかし、まだ一貫していません。HWND shellHand = ShellExecute(NULL, "open", ShowFile.c_str(), Params.c_str(), NULL, SW_SHOWNORMAL);

HWND の前に Sleep(25) を追加する Hand= GetForegroundWindow(); GUI に最高の影響を与えましたが、タイミングが適切であることに依存したくありません。

さまざまなインターネット検索で、かなり良さそうなコードがいくつか見つかりました。しかし、それはレジストリ設定を変更するので、賢明な選択ではないようです。

そのソリューションでは、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;
  } 

問題を解決するようです。

4

0 に答える 0