Question

So this is a common problem and has been addressed in a few places - not specific for an HTML Control on Windows Mobile 6.1 professional though.

So here's my problem

  • A WC_HTML HTML Control created as a child window of a Windows Mobile application window.
  • HTML Control serves html pages with editable fields.
  • When the full page is full of editable fields and the user is using the soft keyboard, for the fields at the bottom of the page, the soft keyboard overlays a few fields.

What I definitely missed out was to resize the window based on soft keyboard open/hide events.

What I tried already

  • First Approach - Using globally declared SHACTIVATEINFO sai; object which is initialized before the parent container window is created which is then passed onto the WM_SETTINGCHANGE AND WM_ACTIVATE methods of WndProc (as explained here). This doesn't have the desired effect. I have tried both - passing the parent HWND (as recommended) and also the Web Control's HWND - nothing happens.

    case WM_ACTIVATE: SHHandleWMActivate(hWnd, wParam, lParam, &sai, 0); break;

    case WM_SETTINGCHANGE: SHHandleWMSettingChange(hWnd, wParam, lParam, &sai); break;

  • Second Approach - Also tried manually resizing the window based on the keyboard event by checking the event using SIPINFO si; and then using si.fdwFlags to determine if the soft keyboard is being hidden or not

    case WM_SETTINGCHANGE: {
           SIPINFO si;
           switch( wParam ) 
           {
               case SPI_SETSIPINFO: {
               memset( &si, 0, sizeof( si ) );
               si.cbSize = sizeof( si );
               if( SHSipInfo( SPI_GETSIPINFO, 0, &si, 0 ) ) {
                   RECT rcMenuBar;
                   // Get the size of the menu bar
                   GetWindowRect(g_hWndMenuBar, &rcMenuBar);
                   // Keyboard opens up
                   if(si.fdwFlags == 0x00000003) { 
                       MoveWindow(webControlHWND, 0, 0, (si.rcVisibleDesktop.right - si.rcVisibleDesktop.left), (si.rcVisibleDesktop.bottom - si.rcVisibleDesktop.top), TRUE);          
                   } else if(si.fdwFlags == SIPF_DOCKED) { 
                         // keyboard closes down - weird that this msg comes when keyboard is closed instead of SIPF_OFF
                         // visible area above menu bar
                         si.rcVisibleDesktop.bottom -= (rcMenuBar.bottom - rcMenuBar.top);
                         MoveWindow(webControlHWND, 0, 0, (si.rcVisibleDesktop.right - si.rcVisibleDesktop.left), (si.rcVisibleDesktop.bottom - si.rcVisibleDesktop.top), TRUE);            
                   }
                }
             break;
           }
         }
    break;
    }
    

This second approach causes weird un-explainable problems - Here's what i observed

  1. If i sent one of the editable fields to focus using the JS, the Windows mobile's SETTINGCHANGED is triggered for (si.fdwFlags == 0x00000003) for which the MoveWindow() call is made to resize the window to the smaller visible area (after the keyboard comes up), And there is another message triggered (happening automatically) - could be because of the MoveWindow() and the Soft keyboard closes down and the window is resized to the full screen. After debugging I see that when a soft keyboard is opened, the message received is first 0x00000003 and then next 0x00000002 (SIPF_DOCKED) for closing.

  2. After #1 happens, sometimes the field is not clickable from the touch screen (can't focus on the field) but one can navigate to the field using the Direction pad or the soft keyboard arrow keys. So this is a big problem being caused due to Issue#1 where the keyboard is highlighted and then automatically hidden. Although i am able to pull up the Soft keyboard by force using the button (the auto toggle feature seems to be lost because of the change).

Has some one faced this problem before? I am hoping every one who has used the HTMLControl for Windows Mobile 6.1 professional must have gone through the same issue.

UPDATE - 22Mar2011-11:27AM Here, my parent window doesn't handle the WM_SETFOCUS or WM_KILLFOCUS methods, instead the child HTML Control (WC_HTML) would probably handle them. The worry here is that the Parent Window HWND's messaging loop gets the WM_SETTINGSCHANGE message which needs to be translated to the child window. I've also tried to do exactly like the HandleSIP Windows Mobile SDK sample which does by having the SHACTIVATEINFO object memset() each time a message is received - unlike previously where it was stored globally and the memset() is done once before the window is created or in WM_CREATE

case WM_CREATE : {
    memset(&sai, 0, sizeof(SHACTIVATEINFO));
    break;
}
case WM_ACTIVATE:
    if (SPI_SETSIPINFO == wParam){
        memset(&sai, 0, sizeof(SHACTIVATEINFO));
        SHHandleWMActivate(webControlHWND, wParam, lParam, &sai, 0);
    }
    break;
case WM_SETTINGCHANGE: {
    if (SPI_SETSIPINFO == wParam){
        memset(&sai, 0, sizeof(SHACTIVATEINFO));
        SHHandleWMSettingChange(webControlHWND, wParam, lParam, &sai);
    }
    break;
}

against both parent window and the HTML Control HWND which doesn't work either - the keyboard overlays the editable field (no window resize) and the window doesn't accept any more messages (hung)

Was it helpful?

Solution

So I actually found a work-around for this issue. There's some lame bug in Windows Mobile which hangs up the screen if the screen doesn't contain HTML < 1 page. So the final solution is

1) Stick to handling WM_SETTINGCHANGE message only when the phone doesn't have a physical keyboard. If it has, then I'd let my softkeyboard overlap the visible fields. Please note that if the device has a Physical keyboard, the softkeyboard doesn't pop out by default unless brought up explicitly and it retains that behavior after that..

case WM_SETTINGCHANGE: {
   SIPINFO si;
   switch( wParam ) 
   {
       case SPI_SETSIPINFO: {
       memset( &si, 0, sizeof( si ) );
       si.cbSize = sizeof( si );
       if( SHSipInfo( SPI_GETSIPINFO, 0, &si, 0 ) ) {
           RECT rcMenuBar;
           // Get the size of the menu bar
           GetWindowRect(g_hWndMenuBar, &rcMenuBar);
           // Keyboard opens up
           if(si.fdwFlags == 0x00000003) { 
           } else if(si.fdwFlags == SIPF_DOCKED || si.fdwFlags==10) { 
                 // keyboard closes down - weird that this msg comes when keyboard is closed instead of SIPF_OFF
                 // visible area above menu bar
                 si.rcVisibleDesktop.bottom -= (rcMenuBar.bottom - rcMenuBar.top);
           }
           MoveWindow(webControlHWND, 0, 0, (si.rcVisibleDesktop.right - si.rcVisibleDesktop.left), (si.rcVisibleDesktop.bottom - si.rcVisibleDesktop.top), TRUE);          

        }
     break;
   }
 }
 break;
 }

2) Inject a 1 page long transparent PNG If the phone doesn't have physical keyboard, then ensure to inject a "transparent 1 page long PNG" at the end of each of the HTML to be displayed. I know most of the folks can't do this as the HTML originates from some where else. But this is what I did and it works now. This is only to get rid of the hang issue that was happening other wise. This will ensure that all the pages have scroll bar w/o bothering about the content. The downside is the user can scroll through the empty space at the bottom (although will not affect anything).

p.s - It was a lucky find and I don't really know why MS has such a lame bug either. While I was testing my app with a longer HTML version it always worked and my real-tests didn't. That's when I tried the empty PNG at the end and it did work. :)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top