none
Can't set combobox height greater than 16 under WEC2013 RRS feed

  • Question

  • I use CB_SETITEMHEIGHT / CComboBox::SetItemHeight to set combobox height.

    m_ComboBox1.SetItemHeight(-1, height);

    Under WCE6 I can set height up to 255. Now under Windows Embedded Compact 2013 I can set height to max 16. If I try to set height greater than 16, I'm getting CB_ERR.

    Can I change this WEC2013 limitation somehow?

    Maybe registry settings or BSP changes?



    • Edited by Dariusz Czarnecki Thursday, June 21, 2018 10:00 AM corrected title spelling mistake
    Monday, November 20, 2017 4:25 PM

All replies

  • Hi Dariusz,

    Assuming you have everything else right with Owner Drawable etc, just taking a quick look on the web, it looks like this might be a factor of the font selected for the control.  If you change the font, does this limit change?

    Sincerely,

    IoTGirl

    Wednesday, June 13, 2018 8:50 PM
    Moderator
  • Hi IoTGirl

    I made tests by setting the font of the dialog box where the combo box is located. I did not modify the font of the combo box directly. The tests were done with Tahoma font. Below are results:

    Font size up to 10

    • CB_GETITEMHEIGHT always return 16
    • CB_SETITEMHEIGHT can't set anything above 16

    Font size over 10

    • CB_GETITEMHEIGHT return values above 16 (for example 18 for font size 11)
    • CB_SETITEMHEIGHT can't set anything above 16

    I also did quick test with Courier font with similar results.

    Conclusions:

    • The font size and type make no difference to how maximum combo box height I can set with CB_SETITEMHEIGHT. It is always only 16, even if with larger font, default size is larger than 16.
    • The default minimum combo box height is 16

    It seems that in the function that handles CB_SETITEMHEIGHT may be a mistake in argument validation. It looks as if the minimum combo box height instead of the maximum has been used in the validation.

    Below is the test code:

    #include <windows.h>
    #include "resource.h"
    
    void OnInitDialog(HWND hWnd)
    {
    	HWND hwndCtl = GetDlgItem(hWnd, IDC_COMBO1);
    	LRESULT Res = SendMessage(hwndCtl, CB_SETITEMHEIGHT, (WPARAM)-1, (LPARAM)17);
    	if (Res == CB_ERR)
    		MessageBox(hWnd, _T("CB_SETITEMHEIGHT = CB_ERR"), _T(""), MB_OK);
    }
    
    BOOL CALLBACK MainWndProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
    {
    	switch (wMsg)
    	{
    	case WM_INITDIALOG:
    		OnInitDialog(hWnd);
    		break;
    	}
    	return FALSE;
    }
    
    int WINAPI WinMain(HINSTANCE hInstance,	HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
    {
    	return DialogBox(hInstance, MAKEINTRESOURCE(IDD_ABOUTBOX), NULL, MainWndProc);
    }
    
    

    And the dialog box resource:

    IDD_ABOUTBOX DIALOGEX 0, 0, 180, 94
    STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
    EXSTYLE 0x80000000L
    CAPTION "Test Application"
    FONT 11, "Tahoma", 400, 0, 0xEE
    BEGIN
        COMBOBOX        IDC_COMBO1,30,13,124,30,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
    END

    Thursday, June 14, 2018 11:42 AM
  • Hi Dariusz,

    I don't see either of these items, CBS_OWNERDRAWFIXED or CBS_OWNERDRAWVARIABLE so why do you think it is ownerdraw?  I think you are getting the correct behavior based on your definition.

    I recommend taking a look at the sample at

    https://msdn.microsoft.com/en-us/library/windows/desktop/hh404152%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396

    It uses OWNERDRAWFIXED but explains:

    "An owner-drawn combo box sends the WM_MEASUREITEM message to its parent window or dialog box procedure so that the application can set the dimensions of each list item. Because the example combo box has the CBS_OWNERDRAWFIXED style, the system sends the WM_MEASUREITEM message only once. Combo boxes with the CBS_OWNERDRAWVARIABLE style send a WM_MEASUREITEM message for each list item. "

    I hope that helps.

    Sincerely,

    IoTGirl

    Thursday, June 14, 2018 3:16 PM
    Moderator
  • Hi IoTGirl,

    Thanks for the links and explanations, but in my case I want to set combo box height (hence the wParam = -1). I don't want set particular list items height by its indexes. As I understand the documentation, there is no need to use owner drawable style in that case. According to the documentation, owner draw combo boxes are even not supported under Windows Embedded Compact.

    To illustrate the behavior I performed tests under Windows CE 6.0, Windows Embedded Compact 2013 and Windows 10. As you can see, only on WEC2013 I can't set the height above 16. Screenshots and code are below:

    Test code

    void OnInitDialog(HWND hWnd)
    {
    	SendMessage(GetDlgItem(hWnd, IDC_COMBO2), CB_SETITEMHEIGHT, (WPARAM)-1, (LPARAM)10);
    	SendMessage(GetDlgItem(hWnd, IDC_COMBO3), CB_SETITEMHEIGHT, (WPARAM)-1, (LPARAM)30);
    	SendMessage(GetDlgItem(hWnd, IDC_COMBO4), CB_SETITEMHEIGHT, (WPARAM)-1, (LPARAM)60);
    }


    IDD_ABOUTBOX DIALOG  0, 0, 229, 94
    STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
    EXSTYLE 0x80000000L
    CAPTION "Windows Embedded Compact 2013"
    FONT 11, "Tahoma"
    BEGIN
    	COMBOBOX        IDC_COMBO1, 7, 7, 124, 30, CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
    	COMBOBOX        IDC_COMBO2, 7, 23, 124, 30, CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
    	COMBOBOX        IDC_COMBO3, 7, 37, 124, 30, CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
    	COMBOBOX        IDC_COMBO4, 7, 59, 124, 30, CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
    	LTEXT           "Default height", IDC_STATIC, 141, 10, 46, 8
    	LTEXT           "Set height 10", IDC_STATIC, 141, 24, 44, 8
    	LTEXT           "Set height 30", IDC_STATIC, 141, 39, 44, 8
    	LTEXT           "Set height 60", IDC_STATIC, 141, 60, 44, 8
    END

    Friday, June 15, 2018 10:15 AM
  • I found out that the same problem concerns also WEC7 but not WCE6 and earlier (at least not WCE6 and WCE4.2). Similar question concerning WEC7 is here.

    From debugging WEC7 and WEC2013 I found out that in function that handles CB_SETITEMHEIGHT message is the code shown below. This is not exact source code, because I don't have access to the full CE source code, but it is reconstructed from disassembly and symbols.

    int ComboBoxControl_t::SetEditItemHeight(int dyEdit)
    {
    	...
    	if(dyEdit > g_MinimumTextHeight)
    	{
    		return CB_ERR;
    	}
    	...
    }

    While debugging, the value of global variable g_MinimumTextHeight is always 16. The dyEdit is value passed to CB_SETITEMHEIGHT lParam (for wParam==-1), so it is the height of the combo box we want to set.

    As you can see above, g_MinimumTextHeight is compared against the height to be set and if height is grater than g_MinimumTextHeight, the function fails. Probably someone who wrote the code had in mind the reverse condition (dyEdit <g_MinimumTextHeight), which would be more logical with respect to the MinimumTextHeight variable name.

    So it seems that it is obvious mistake in SetEditItemHeight introduced in WEC7. I hope it will be fixed asap.

    If some workaround exists, pleas let me know.

    In the case of WEC2013 tests were performed with the WEC2013 with the latest updates applied (May-2018).
    • Edited by Dariusz Czarnecki Tuesday, June 19, 2018 3:08 PM Added WEC2013 version info
    Tuesday, June 19, 2018 10:28 AM
  • Hi Dariusz,

    You should have access to at least one version of the MFC source code, if not multiple. Visual Studio instruction link here: https://msdn.microsoft.com/en-us/library/bs046sh0.aspx

    For Windows CE, I would look around (VCInstallDir)ce\atlmfc for sources. 

    My assumption is, you could build with the code you want to use and statically link as to not use the built-in version on the device.

    Sincerely,

    IoTGirl

    Tuesday, June 19, 2018 4:25 PM
    Moderator
  • Hi IoTGirl,

    The problematic code I wrote about in the previous post is not from MFC (unfortunately my first post could have suggested it because I used the MFC function there). The MFC implementation of SetItemHeight is only a wrapper:

    int CComboBox::SetItemHeight(int nIndex, UINT cyItemHeight)
    {
    	return (int)::SendMessage(m_hWnd, CB_SETITEMHEIGHT, nIndex, MAKELONG(cyItemHeight, 0));
    }

    The code fragment of ComboBoxControl_t::SetEditItemHeight that I sent in previous post is WEC2013 private code (not included in generally available "Shared Source"). It is from gwes.dll. According to output from Platform Builder "List Sources" the source code is in d:\bt\2707\private\winceos\coreos\gwe\controls\cmbctl\cmncore\combobox.cpp.

    Wednesday, June 20, 2018 9:40 AM
  • Hi Dariusz,

    Sadly, I doubt this issue will be fixed for either CE 7 or 8 but you should certainly report it through your license provider.  I know the docs say that ownerdrawn is not supported but did you try?  does it give an error or any behavior change? 

    Sincerely,

    IoTGirl

    Wednesday, June 20, 2018 7:50 PM
    Moderator
  • Hi IoTGirl,

    I did a try of the CBS_OWNERDRAWFIXED and also CBS_OWNERDRAWVARIABLE. They are undefined under WEC2013, so I defined them to the values I found in header files.

    #define  CBS_OWNERDRAWFIXED   0x0010L            
    #define  CBS_OWNERDRAWVARIABLE 0x0020L            

    I did not noticed any behavior change under WEC2013. The WM_MEASUREITEM nor WM_DRAWITEM were not received in DialogProc. Just for verification, unlike WEC2013, my test code worked under Win32 (WM_MEASUREITEM and WM_DRAWITEM were received).

    Anyway, thank you for your time.
    Thursday, June 21, 2018 9:45 AM
  • Hi Dariusz,

    Sorry I did not have a better answer for you.  I am curious what you mean "Just for verification, unlike WEC2013, my test code worked under Win32 (WM_MEASUREITEM and WM_DRAWITEM were received)." In what situation did they work?  I assume this is not a viable work around for you?

    I have not done it myself but back in the day you could create a custom control.  Is that still an option here?

    Sincerely,

    IoTGirl

    Friday, June 22, 2018 12:58 AM
    Moderator
  • Hi IoTGirl,

    In the sentence "Just for verification..." I meant that I verified correctness of my "test code" under Desktop Windows and under Desktop Windows it worked as expected. The same "test code" not worked under Windows Embedded Compact 2013 - no WM_MEASUREITEM nor WM_DRAWITEM received.

    Yes, creating custom control may be still an option. However, I suppose that creating such control from scratch may not be an easy task. In addition, because we are porting our existing application code from CE6.0, it would also require many changes to existing code. Now, we don't have time to do such things, so unfortunately for now it must stay as is.

    Our application will run on our device with our BSP. Therefore it seems that the simplest workaround would be to patch the binary code of the gwes.dll (or one of the lib files from which it is built), but I'm not sure if it will not violate the WEC license terms. Additionally such solution would be cumbersome in maintenance as future WEC updates may overwrite the patched binaries.

    Best regards,

    Dariusz Czarnecki

    Friday, June 22, 2018 10:17 AM
  • Hi Dariusz,

    There is an added complexity that while CE 6 binaries will run in CE 7, previous versions will not run in CE 8.  As there really is no work-around, have you reported this through your license provider? 

    Sincerely,

    IoTGirl

    Friday, June 22, 2018 5:12 PM
    Moderator
  • Hi IoTGirl,

    I know, about the binary incompatibility, but it isn't big problem to us. Our applications source code porting from CE6 to WEC2013 was generally without problems.

    I reported the problem through my account at devicepartner.microsoft.com/en-us/contact-us/ "Submit a support request". As far as I know, we only have a runtime license supplier for CE6 (the product based on WEC2013 is still under development). Should I still report a problem through this supplier?

    Best regards,
    Dariusz Czarnecki


    Friday, June 22, 2018 6:54 PM
  • Hi Dariusz,

    So great that you used the partner portal!  I would also let your supplier know and also tell them it is logged through the portal.  I think you get a tracking number you can share as well.

    Sincerely,

    IoTGirl

    Saturday, June 23, 2018 12:17 AM
    Moderator