SendDlgItemMessage

Started by Unixtohack, March 06, 2012, 10:55:26 PM

Previous topic - Next topic

Unixtohack

Dear All, I try to fill in or populate a combo box with data from an array. The only problem I have is it seems imposible to populate the combobox, even the string in the array is correct and copyed into another array to check.

        case WM_INITDIALOG:
   cboxCodes = GetDlgItem(hDlg, DLG_COMBO_CODES);
               for(int Count = 0; Count < 5; Count++)
   {
       memset(szTest, FALSE, 100 );
       memcpy(szTest, szBuffer[Count], 5);
                   bResult = SendDlgItemMessage(hDlg, DLG_COMBO_CODES, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR) szTest);
       bResult = SendMessage(cboxCodes, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR) szTest);
               }
               return TRUE;

There are two formats of populating due find out something.

thanks

CommonTater

#1
To give you the best answer we will need to see a bit more of your code...

Generally the way it's done is to have your array of strings as  strings[num][maxlen]  with your text lines stored there.

Your dialog message handler gives you the handle of the dialog in hit's HWND parameter... so...


char Strings[20][40];  // room for 20 strings of 39 chars each.

// populate list box
void IntList(HWND Dlg, CHAR* Strings, INT Count)
  { for (int x = 0; x < count; x++)
        SendDlgItemMessage(Dlg,ID_COMBOBOX, CB_ADDSTRING, 0, (LPARAM) Strings[x]); }

// dialog message tosser
BOOL CALLBACK DlgProc(HWND Dlg, UINT Msg, LPARAM lParm, WPARAM wParm)
   {  switch (Msg)
         {  case WM_INITDIALOG :
                  InitList(Dlg,Strings,20);
                  return 0;

             //    .... other cases here

         }
   }


In general, I find it's bad practice to put much code in switch() statements.  Instead I write each "case" as a function and call it from the switch.  This does two things for you : First, it modularizes your code, making it much easier to maintain.  Second, it simplifies the task of troubleshooting a switch() gone wrong. 

Anyway... if this doesn't solve your problem for you, post the relevent code (inside code tags, please) and we'll see what we can do...


Unixtohack

Thanks, but the result is the same. No data inside the combo... empty... However the return value of the CB_ADDSTRING must be the index, but here it returns nothing, so there is no index created I think. The code is now

char   szBuffer[5][10] = {"EEN\0h", "TWEE\0h", "DRIE\0h", "VIER\0h", "VIJF\0h"};
...

...
        case WM_INITDIALOG:
   // Populate the Combo
                for(int Count = 0; Count < 5; Count++)
   {
       // Send the message to the selected item
                    bResult = SendDlgItemMessage(hDlg, DLG_COMBO_CODES,
                                                                        CB_ADDSTRING, 0, (LPARAM) szBuffer[Count]);
   }
                // Test the dirty cleaning functions
   InvalidateRect( hDlg, FALSE, TRUE );
            return TRUE;

The final data must be extracted from a MySql database, but first it must be OK with the test array.


CommonTater

#3
Quote from: Unixtohack on March 08, 2012, 12:16:45 AM

CB_ADDSTRING, 0, (LPARAM) szBuffer[Count]);


Try ...  CB_ADDSTRING, 0, (LPARAM) &szBuffer[count]);

Are you sure the DLG_COMBO_CODES is correctly identifying the combo box?

Also you don't need the \0h, as static initializers they are automatically null terminated...


aardvajk

The vertical size of a combobox window includes the populated drop down list. If your CreateWindow or resource statement gives a small vertical size, the combobox will only fractionally open and hence, never look fully populated. This is most likely your problem, but without seeing how you create it, it's impossible to be sure

CommonTater

#5
Quote from: aardvajk on March 08, 2012, 01:44:13 AM
The vertical size of a combobox window includes the populated drop down list. If your CreateWindow or resource statement gives a small vertical size, the combobox will only fractionally open and hence, never look fully populated. This is most likely your problem, but without seeing how you create it, it's impossible to be sure

Good point... if he checked the "No Integral Height" option then closed it up to be only the size of the entry area, he'd never see anything.   Simply unchecking that option would convert the list to automatic sizing so he can see what's in there.  He should also be sure he's added the vertical scroll bar.

Just looking at the incomplete code samples; it looks like it should work...

Thanks for pointing this out... I hadn't thought of it.

Unixtohack

Dear friends, I found the fault with the combo, I used an extenden combo and not the standard combo. Now the messages sended to the item are properly inserted into the object. Right now is the next step is to fill the array with some data from the DB and yeah, without the \0h figures. It is a good idea to find out how to use the extended combo... maybe. Any ideas.

TimoVJL

Example for ComboBoxEx:char *aStr[] = {"row1","row2","row3"};
void InitCBEx(HWND hwndDlg)
{
COMBOBOXEXITEM cbiex;
int rc;
cbiex.mask = CBEIF_TEXT;
for (int iC = 0; iC < sizeof(aStr) / sizeof(aStr[0]); iC++) {
cbiex.iItem = iC;
cbiex.pszText = aStr[iC];
rc = SendDlgItemMessage(hwndDlg, 4002, CBEM_INSERTITEM, 0, (LPARAM)(LPCTSTR)&cbiex);
}
}
May the source be with you

CommonTater

Quote from: Unixtohack on March 08, 2012, 09:46:58 AM
Dear friends, I found the fault with the combo, I used an extenden combo and not the standard combo. Now the messages sended to the item are properly inserted into the object. Right now is the next step is to fill the array with some data from the DB and yeah, without the \0h figures. It is a good idea to find out how to use the extended combo... maybe. Any ideas.

Just about everything you need to know about windows API is.... HERE   
You can also download a copy for local use from ... HERE   

DMac

Here's something that I put together to customize the Combo and ComboEx a while back that you might find interesting. http://forum.pellesc.de/index.php?topic=3195.msg12073#msg12073
No one cares how much you know,
until they know how much you care.

Unixtohack


Unixtohack

The final result of this conversation:
...
        case WM_INITDIALOG:
         FillComboFromMySQL( hDlg, DLG_COMBO_CODES, "MyData", "select omschrijving from codes", 35 );
         InvalidateRect( hDlg, FALSE, TRUE );
            return TRUE;
...
It was more than 15 years ago I was programming in C, so it is a fine warmup.

CommonTater

#12
Quote from: Unixtohack on March 08, 2012, 11:43:55 PM
The final result of this conversation:
...
        case WM_INITDIALOG:
         FillComboFromMySQL( hDlg, DLG_COMBO_CODES, "MyData", "select omschrijving from codes", 35 );
         InvalidateRect( hDlg, FALSE, TRUE );
            return TRUE;
...
It was more than 15 years ago I was programming in C, so it is a fine warmup.

You shouldn't have to invalidate any rectangles, if you simply return FALSE the default dialog proc will repaint as needed.  Also most windows controls will repaint automatically when their content is modified.  What you get from repeatedly painting over the same thing is windows that flash and flicker because their backgrounds are repeatedly repainted.

Moreover; I think you will find you are calling InvalidateRect() incorrectly and it's actually failing...
Check HERE for specifics.





Unixtohack

The compiler and stuff don't find any fault.
The InvalidateRect seems to me OK, the Handle, False or NULL to select the whole area, TRUE to enable erase.
Flickering is not found, due a small dialog. You have reason to say this and I agree with it.
I will erase it, but I am buzy now to make the sql-strings I want to.
thanks anyway.

CommonTater

Quote from: Unixtohack on March 10, 2012, 06:33:44 PM
The compiler and stuff don't find any fault.

Hard lesson #1 in programming:  "Compiles" does not imply "Works". 

Try checking the return value from InvalidateRect() ....
Also try commenting it out and see if it makes any difference.