Monday, June 11, 2007

Combo box problem

Scenario :
---------------
I added the combo box in a dialog box by using the resource editor.

Next I am using

SendMessage(hwnd,CB_ADDSTRING,0,"Sundar");

or

SendDlgItemMessage(dlgHwnd,IDC_combo,CB_ADDSTRING,0,"Sundar");


Both the SendMessage() function is not working. the combo box style is a drop down. I am not able to identify the cause of the problem.


Solution Attempts:
-------------------------
1. If I am creating the combo box dynamically in a dialog box,the above code is working.( string is added to the

combo box.

2. So I checked the style and properties of the combo box. I changed the style as dropdown list. But it is also not working.



Solution : I got the solution from the google groups.

the answer might be very silly...

change the vertical size in Combo Box, then it will works fine.

Solution Reason :


During design time the width and height is determined based on the control size. Here the problem lies...

The Height of the combo box is both the edit control and the drop down list .

literally combo box is nothing but a combination of edit box(static for Drop down list) and list box .

the height is for both the edit control and list box control. Actually during design time, the height is allocated only for the

edit control. So there is no size left for displaying the items in a drop down list.


1. I changed the width and height of the combo box in a .rc ( resource script file) look at the format of the controls in .rc file


For EDITTEXT, SCROLLBAR, LISTBOX, and COMBOBOX, the format is

control-type id, xPos, yPos, xWidth, yHeight, iStyle




2.So in the dynamically created Combo box also this will be true ???

Check whether this problem also be arised to dynamically created combo box ?

yes I got the same problem in dynamically created control also...


The following code have x,y,width,height in sequence as 100,100,200,10.

the height is 10... So there is no place for displaying the drop down list box.



hwndCombo = CreateWindow("combobox","sundar",CBS_DROPDOWNLIST | WS_CHILD | WS_TABSTOP,100,100,200,10,hWnd,NULL,hInstance,NULL);

if I changed the height as 100 then it displays the drop down list box look at the following code it works well.


hwndCombo = CreateWindow("combobox","sundar",CBS_DROPDOWNLIST | WS_CHILD | WS_TABSTOP,100,100,200,100,hWnd,NULL,hInstance,NULL);





Learnt things from this problem :

Combo Box styles :

3 types of combo box

1.Simple ( displays the edit control and list box control )
2.Dropdown ( edit control with list box but the listbox is displayed only when drop down button is clicked )
3. Drop Down list ( static control with list box, we can't enter data into the static control )


Difference Between CB_ADDSTRING and CB_INSERTSTRING :
-----------------------------------------------------------------------------

1. CB_ADDSTRING adds the data in a sorted order

For Example

SendMessage(hwndCombo, CB_ADDSTRING,0, "Sundar");
SendMessage(hwndCombo, CB_ADDSTRING,0, "Arun");

The items are displayed in the combo box in the following order :

Arun
Sundar

2.In case of CB_INSERTSTRING will not add data in a sorted order


SendMessage(hwnCombo, CB_INSERTSTRING, -1 // Add data at the end of the combo box
"sundar");

SendMessage(hwndCombo, CB_INSERTSTRING, -1, // adds data at the end of the combo box

"arun");

The items are displayed in the combo box in the following order :
sundar
arun



Test the ATL based SendMessage :
------------------------------------------------

win32 Dialog based application structure:

WinMain() fn has DialogBox() method to create the dialog box.


define IDD_DIALOG 101
#define IDC_COMBO 201
/* end combobox.h */
/* begin combobox.rc */

#include "winresrc.h"
#include "combobox.h"


IDD_DIALOG DIALOG DISCARDABLE 0, 0, 186, 95
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Dialog"
FONT 8, "MS Sans Serif"
BEGIN
DEFPUSHBUTTON "OK",IDOK,129,7,50,14
PUSHBUTTON "Cancel",IDCANCEL,129,24,50,14
COMBOBOX IDC_COMBO,17,16,101,65,CBS_DROPDOWN |
WS_VSCROLL | WS_TABSTOP
END
/* end combobox.rc */
/* begin combobox.c */


#include "windows.h"
#include
#include "combobox.h"

BOOL CALLBACK DlgProc(HWND hw, UINT msg, WPARAM wp, LPARAM lp)
{
HWND combo = 0;
int cursel = 0;
char before[100] = {0};
char after [100] = {0};
char results[sizeof before + sizeof after] = {0};
switch(msg)
{
case WM_INITDIALOG:
combo = GetDlgItem(hw, IDC_COMBO);
SendMessage(combo, CB_ADDSTRING, 0, (LPARAM)"one");
SendMessage(combo, CB_ADDSTRING, 0, (LPARAM)"two");
SendMessage(combo, CB_ADDSTRING, 0, (LPARAM)"three");
return TRUE;
case WM_COMMAND:
switch(LOWORD (wp))
{
case IDOK:
case IDCANCEL:

EndDialog(hw, 0);
return TRUE;

case IDC_COMBO:
if(HIWORD(wp) == CBN_SELCHANGE)
{
SendMessage((HWND)lp, WM_GETTEXT, sizeof before,
(LPARAM)before);
cursel = SendMessage((HWND)lp, CB_GETCURSEL, 0, 0);
SendMessage((HWND)lp, CB_GETLBTEXT, cursel, (LPARAM)after);
sprintf(results, "before: %s\nafter: %s", before, after);
MessageBox(hw, results, "", MB_OK);
}
return TRUE;
}
}
return 0;
}


int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG), 0, DlgProc);
return 0;
}

/* end combobox.c */




Some more try :


CWindow myWindow;
myWindow.Attach(hWndFoo);
myWindow.SendMessage(WM_PAINT,0L,0L);


Within ATL based component , I used the following code :


::SendDlgItemMessage(m_hWnd,IDC_cboReplacementForRed, CB_SETCURSEL,(WPARAM)GetCurrentSelection (m_ShiftChannelsParams.replacementForRed),0);


I changed it as ATL based window class as follows , it is also working well.


HWND hwndForRed;
hwndForRed = GetDlgItem(IDC_cboReplacementForRed);

CWindow wndForRed;
wndForRed.Attach(hwndForRed);
wndForRed.SendMessage(CB_SETCURSEL,(WPARAM)GetCurrentSelection(m_ShiftChannelsParams.replacementForRed),0);



I modified the above code as follows :

HWND hwndForRed;
hwndForRed = GetDlgItem(IDC_cboReplacementForRed);
CWindow wndForRed(hwndForRed);
wndForRed.SendMessage(CB_SETCURSEL,(WPARAM)GetCurrentSelection(m_ShiftChannelsParams.replacementForRed),0);


if we are using Attach() method we must call Detach() method inorder to remove the hwnd from CWindow.
Ideas :
------------


If we got any error in the GUI controls, then check the net for the source code...

if they have some width and height, then use it in ur program also... this is the simple way to solve the problem.

( But not a knowledge based way...) this can be done when we want quick results.

No comments: