Control arrays possible in C++?

This is a discussion on Control arrays possible in C++? within the Windows Programming forums, part of the Platform Specific Boards category; Hi Is it possible to have control arrays in C++? I have a lot of check boxes which I want ...

  1. #1
    TJJ
    TJJ is offline
    Registered User
    Join Date
    Nov 2003
    Posts
    15

    Smile Control arrays possible in C++?

    Hi

    Is it possible to have control arrays in C++? I have a lot of check boxes which I want to check the value of (ie checked or unchecked) and think that the easiest way to do this would be something like:

    Code:
    for(i=0; i<8, i++)
    {
    cout << CheckBox[i].Value
    }
    (I know the code isnt right - just using it for ease of illustration)

    Is that kind of thing possible?

    Thanks for any help

    TJJ

  2. #2
    erstwhile
    Join Date
    Jan 2002
    Posts
    2,227
    The simplest way to achieve this would be to store the control handles in an array (or use std::vector). For example, to check them (BM_SETCHECK), something like:
    Code:
    HWND CheckBox[NUM_CHKBOXES]; 
    /*create checkboxes and store their handles in 'CheckBox' array */
    /* ... */
    for (n=0;n<NUM_CHKBOXES;++n)
      {
      SendMessage(CheckBox[n],BM_SETCHECK,BST_CHECKED,0);
      }
    where NUM_CHKBOXES is some previously defined const value for the number of checkboxes you are using.
    CProgramming FAQ
    Caution: this person may be a carrier of the misinformation virus.

  3. #3
    TJJ
    TJJ is offline
    Registered User
    Join Date
    Nov 2003
    Posts
    15
    Hi

    Thanks for your reply!

    Ive been having a play with the code, but am having difficulties

    Ive tried getting the state of an individual checkbox by stating its handle explicitly:

    Code:
    long lresult = SendMessage(IDC_CHECK5, BM_GETCHECK);
    if(lresult == BS_CHECKED)
    {
    SetDlgItemText(IDC_EDIT1, "Checked");
    }
    This compiles without error but doesn't seem to do anything. I was thinking that maybe it doesn't work because I didnt create the checkbox through code?

    Any suggestions?

    Thanks

    TJJ

  4. #4
    erstwhile
    Join Date
    Jan 2002
    Posts
    2,227
    Looks like you're using mfc (CWnd::SendMessage, CWnd::SetDlgItemText )...

    Your 'SendMessage(IDC_CHECK5, BM_GETCHECK)' doesn't do much because the first parameter to CWnd::SendMessage should be the message id and not the control id.

    For CWnd::SendMessage the syntax is:
    Code:
    LRESULT lresult = SendMessage(BM_GETCHECK);
    For the winapi SendMessage, then:
    Code:
    LRESULT lresult = SendMessage(hCheckbox,WM_GETCHECK,0,0);
    Returning to your original question, if you are using mfc then build an array of checkbox control object instances rather than handles(HWND) and use their SendMessage (CWnd::SendMessage) member function.

    If you need to get the handle (HWND) of an mfc control then use the CWnd::HWND operator to return it ie. just use the class object instance as a synonym for any HWND parameter in functions that require it.

    CWnd::GetDlgItem can be used to retrieve control object pointers for dialog box controls; the corresponding winapi function, which returns a window handle (HWND) is, unsurprisingly, GetDlgItem.

    It's always a good idea to mention whether you're using mfc or raw winapi as some of us don't do mfc much (like me).
    CProgramming FAQ
    Caution: this person may be a carrier of the misinformation virus.

  5. #5
    TJJ
    TJJ is offline
    Registered User
    Join Date
    Nov 2003
    Posts
    15
    Hi

    Thanks again for your help - much appreciated

    Ive had a go at getting everything straight in my mind:

    Im using MFC so I will make an array of checkbox control object instances, so I will need CWnd::GetDlgItem:
    Code:
    CWnd* CheckBox[5]; 
    
    CheckBox[0] = CWnd::GetDlgItem(IDC_CHECK1);
    CheckBox[1] = CWnd::GetDlgItem(IDC_CHECK2);
    CheckBox[2] = CWnd::GetDlgItem(IDC_CHECK3);
    CheckBox[3] = CWnd::GetDlgItem(IDC_CHECK4);
    CheckBox[4] = CWnd::GetDlgItem(IDC_CHECK5);
    Then I will use the CWnd SendMessage to get the checked state:
    Code:
    for (n=0;n<5;n++)
      {
    LRESULT lresult = CheckBox[n]::SendMessage(BM_GETCHECK);  
    
    if(lresult == BS_CHECKED)
    {
    SetDlgItemText(IDC_EDIT1, "Checked");
    }
      }
    Using this method I receive an error because it doesn't like a long type being used to store the send message result, but if I don't use this type I can't check the result in the if statement?

    Am I going about it in the wrong way?

    TJJ

  6. #6
    erstwhile
    Join Date
    Jan 2002
    Posts
    2,227
    You don't need 'CWnd::' to use the member functions, ie.
    Code:
    CWnd* CheckBox[5]; 
    
    CheckBox[0] = GetDlgItem(IDC_CHECK1);
    CheckBox[1] = GetDlgItem(IDC_CHECK2);
    CheckBox[2] = GetDlgItem(IDC_CHECK3);
    CheckBox[3] = GetDlgItem(IDC_CHECK4);
    CheckBox[4] = GetDlgItem(IDC_CHECK5);
    should suffice. You should also use '->' operator to use member functions with a given object pointer, but check for a valid pointer first:
    Code:
    LRESULT lresult;
    for (n=0;n<5;n++)
      {
      if (CheckBox[n]!=0)
        {
        lresult = CheckBox[n]->SendMessage(BM_GETCHECK);  
    
        if(lresult == BS_CHECKED)
          {
          SetDlgItemText(IDC_EDIT1, "Checked");
          }
        }
      }
    BTW, i've just noticed from the CWnd::GetDlgItem description on msdn that "The returned pointer may be temporary and should not be stored for later use." although, ironically, the window handle (HWND) should be ok. It may, therefore, be in your best interests to adopt another strategy for your control array or, if you know their identifiers have consecutive values, you could just:
    Code:
    CWnd *pCheckBox;
    int n;
    for (n=0;n<5;++n)
      {
      pCheckBox=GetDlgItem(IDC_CHECK1+n);
      if (pCheckBox)
        {
        if (pCheckBox->SendMessage(BM_GETCHECK)==BST_CHECKED)
          {
          SetDlgItemText(IDC_EDIT1, "Checked");
          }
        }
      }
    If you want or need to stick with the original control array idea then something like:
    Code:
    CWnd CheckBox[5];
    CheckBox[0].Attach(GetDlgItem(IDC_CHECK1));
    CheckBox[1].Attach(GetDlgItem(IDC_CHECK2));
    //etc
    might work (CWnd::Attach) to ensure persistent CWnd objects.
    Last edited by Ken Fitlike; 04-13-2004 at 10:28 AM.
    CProgramming FAQ
    Caution: this person may be a carrier of the misinformation virus.

  7. #7
    TJJ
    TJJ is offline
    Registered User
    Join Date
    Nov 2003
    Posts
    15
    Thank you very much for your help - its working great now - I opted for the pointers method as this used less code as long as I created all the checkbox controls sequentially.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. line number on a rich edit control
    By rakan in forum Windows Programming
    Replies: 1
    Last Post: 02-18-2008, 06:58 AM
  2. Spy++ view messages posted/sent to a control, or from it?
    By hanhao in forum Windows Programming
    Replies: 2
    Last Post: 06-24-2007, 11:07 PM
  3. creating an activex control
    By Benzakhar in forum Windows Programming
    Replies: 9
    Last Post: 12-29-2003, 05:32 PM
  4. Updating a list control
    By MPSoutine in forum Windows Programming
    Replies: 2
    Last Post: 12-05-2003, 01:03 AM
  5. Problems with my edit control...
    By tyouk in forum Windows Programming
    Replies: 19
    Last Post: 10-19-2003, 12:36 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21