title: MFC on screen keyboard when focusing editable control
body: <p>I want to do a thing conceptually simple as this: For every control that accepts keyboard input(CEdit, CCombobox with Editable text, etc.), when the control is focused and enabled, make the On Screen Keyboard appear. Preferably with accessibility support (I've done some reading about Microsoft User Interface Automation) rather than calling directly the osk.exe utility.</p>
  
  <p>A thing very like the touchscreen smartphones when the user puts the focus on an editable control.</p>
  
  <p>UPDATE: If there is a Windows option that can make the On Screen Keyboard to behave the way I describe that's just fine!</p>
  
  <p>UPDATE 2: The thing I want is similar to <a href="http://msdn.microsoft.com/en-us/library/windows/apps/hh465404.aspx" rel="nofollow">http://msdn.microsoft.com/en-us/library/windows/apps/hh465404.aspx</a> , but in Windows 7.</p>
  
  <p>I had done experiments with the IUIAutomation class, calling directly osk.exe when focusing an editable control, and closing that window  when focusing a non-editable one. </p>
  
  <p>But, I still have three problems:</p>
  
  <p>1) When opening a CFileDialog application becomes unresponsive. The same is happening for only another Modal Dialog of the application (in every other Modal Dialog everything works fine). I discovered that CFileDialog opens some background threads and my only problematic modal too. I suspect this has to do with threading issues.</p>
  
  <p>2) When some other control is focused, and thereafter I click directly the DropDown button of a CBS_DROPDOWN combobox, not picking on its edit control, I see a flash of OSK appear and disappear. Using Spy++ and UIA Inspect I got the suspicion of the text edit being focused before the combobox goes to the dropped state.</p>
  
  <p>3) After doing some experiments with SetWindowPos, MoveWindow </p>
  
  <pre><code>::MoveWindow(osk_wnd-&gt;m_hWnd, LeftOsk, TopOsk, -1, -1, FALSE);
  </code></pre>
  
  <p>Or</p>
  
  <pre><code>osk_wnd-&gt;SetWindowPos(NULL, LeftOsk, TopOsk, -1, -1, SWP_NOSIZE | SWP_NOACTIVATE);
  </code></pre>
  
  <p>and using also some message processing experiments like</p>
  
  <pre><code>//osk_wnd is a CWnd* variable that represents OSK main window
  osk_wnd-&gt;PostMessage(WM_SYSCOMMAND, SC_MOVE + HTCAPTION, MAKELPARAM(point.x, point.y));
  </code></pre>
  
  <p>Or</p>
  
  <pre><code>POINT       point       = {0};
  
  GetCursorPos(&amp;point);
  SendMessage(osk_wnd-&gt;m_hWnd, WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(point.x, point.y));
  
  SendMessage(osk_wnd-&gt;m_hWnd, WM_NCMOUSEMOVE, HTCAPTION, MAKELPARAM(LeftOsk, TopOsk));
  
  GetCursorPos(&amp;point);
  SendMessage(osk_wnd-&gt;m_hWnd, WM_NCLBUTTONUP, HTCAPTION, MAKELPARAM(LeftOsk + point.x, TopOsk + point.y));
  </code></pre>
  
  <p>I could not move the OSK window. It is important that I can move it; otherwise, it will appear covering the focused control, and the user can not see the input he is giving to the control!
  Side note: the following code for unminimizing OSK window worked perfectly:</p>
  
  <pre><code>if(osk_wnd-&gt;IsIconic())
      osk_wnd-&gt;PostMessage(WM_SYSCOMMAND, SC_RESTORE, NULL);
  </code></pre>
  
  <p>Even trying to move that window with this AutoIt script did nothing:</p>
  
  <pre><code>If WinActivate("[CLASS:OSKMainClass]") Then
  
     If WinWaitActive("[CLASS:OSKMainClass]") Then
  
        ConsoleWrite("activ" &amp; @CRLF)
  
        Sleep(500)
  
        If WinMove("[CLASS:OSKMainClass]", "", 30 ,320,360,123) Then
           ConsoleWrite("move 1" &amp; @CRLF)
        EndIf
     EndIf
  EndIf
  
  If WinMove("[CLASS:OSKMainClass]", "", 30 ,320,360,123) Then
     ConsoleWrite("move 2" &amp; @CRLF)
  EndIf
  </code></pre>
  
  <p>I see the text</p>
  
  <p>activ</p>
  
  <p>move 1</p>
  
  <p>move 2</p>
  
  <p>being printed, but the OSK window is not being moved to anywhere. Maybe it is actively rejecting posiotioning instructions. </p>
  
  <p>I tried this AutoIt script to move the Tabtip.exe Window and it also fails. I tried this script to move the Visual Studio Command Prompt's Window and it moves! GRRRRR!</p>
  
  <p>UPDATE 3: Seems to me this thing has to do with User Access Control and Permissions. If I disable User Access Control or run the application as Administrator the MoveWindow instruction works perfectly! The same applies to AutoIt trying to move OSKMainCLASS window! So, is there some Local or group policy in Windows 7 that allow me to make an exception to the OSK application?</p>
  
  <p>4) For getting the osk.exe running on 64 bit operating system I tried everything that didn't force to disable the SysWOW64 redirection, but I could not escape from it. Till now, I did not see any problems, but maybe the following code will cause problems in the future.</p>
  
  <pre><code>const int sysDirNameSize= 1024;
  TCHAR sysDir[sysDirNameSize];
  if( !GetSystemDirectory( sysDir,  sysDirNameSize) )
  {
      ASSERT(FALSE);
      return;
  }
  
  CString osk_path = CString(sysDir) + _T("\\osk.exe");
  PVOID pOldValue = NULL;
  BOOL bRes= Wow64DisableWow64FsRedirection(&amp;pOldValue);
  ::ShellExecute(NULL, NULL, osk_path, _T("") , sysDir, SW_SHOW);
  if(bRes)
      Wow64RevertWow64FsRedirection(pOldValue);
  </code></pre>
  
  <p>UPDATE 5: Seems last times I tried to execute osk.exe the process begins, but its window doesn't appear! To attribute the value to osk_wnd, I have a function that traverses all GW_CHILD windows of the CWnd::GetDesktopWindow() to search the one which GetClassName(...) is "OSKMainClass" and none is found!</p>