Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Problem with select row in list control

Problem with select row in list control

Scheduled Pinned Locked Moved C / C++ / MFC
helptutorialquestion
7 Posts 2 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • T Offline
    T Offline
    tataxin
    wrote on last edited by
    #1

    I have a list control which is declared like this

    CListCtrl m_list1;

    I set the background color to black, and the text color to white. Whenever I select a row, I just want to draw a rectangular wrap to the row. So I implement the item change method, like this:

    void AlarmCompreMsgDig::OnLvnItemchangedList1(NMHDR *pNMHDR, LRESULT *pResult)
    {
    LPNMLISTVIEW pNMLV = reinterpret_cast(pNMHDR);
    m_lstAlarmCompreMsg.SetItemState(-1, 0, LVIS_SELECTED); // first, diselect the row

    int rowIndex = pNMLV->iItem;
    
    CRect rec;  // boundary rectangular that wrap the row
    m\_lstAlarmCompreMsg.GetItemRect(rowIndex, rec, LVIR\_BOUNDS);
    
    
    // a little adjust the rectangular
        rec.top -= 2;
    rec.bottom += 2;
    
    CDC\* cdc = m\_lstAlarmCompreMsg.GetDC();
    
    CPen aPen;
    aPen.CreatePen(PS\_SOLID, 1, RGB(255, 255, 255)); // select color White
    
    CPen\* pOldPen = cdc->SelectObject(&aPen); // Select the pen
    
    // Now draw the rectangular
    cdc->Rectangle(rec);
    
        // select back the old pen
    cdc->SelectObject(pOldPen);
        
        \*pResult = 0;
    

    }

    That's all. When I select a row, it works. Then I select another row, it works but do not erase the previous rectangular. So my list control is full of rectangular. :(( Does anyone know how to erase the previous rectangular? Thanks in advance, :)

    D 1 Reply Last reply
    0
    • T tataxin

      I have a list control which is declared like this

      CListCtrl m_list1;

      I set the background color to black, and the text color to white. Whenever I select a row, I just want to draw a rectangular wrap to the row. So I implement the item change method, like this:

      void AlarmCompreMsgDig::OnLvnItemchangedList1(NMHDR *pNMHDR, LRESULT *pResult)
      {
      LPNMLISTVIEW pNMLV = reinterpret_cast(pNMHDR);
      m_lstAlarmCompreMsg.SetItemState(-1, 0, LVIS_SELECTED); // first, diselect the row

      int rowIndex = pNMLV->iItem;
      
      CRect rec;  // boundary rectangular that wrap the row
      m\_lstAlarmCompreMsg.GetItemRect(rowIndex, rec, LVIR\_BOUNDS);
      
      
      // a little adjust the rectangular
          rec.top -= 2;
      rec.bottom += 2;
      
      CDC\* cdc = m\_lstAlarmCompreMsg.GetDC();
      
      CPen aPen;
      aPen.CreatePen(PS\_SOLID, 1, RGB(255, 255, 255)); // select color White
      
      CPen\* pOldPen = cdc->SelectObject(&aPen); // Select the pen
      
      // Now draw the rectangular
      cdc->Rectangle(rec);
      
          // select back the old pen
      cdc->SelectObject(pOldPen);
          
          \*pResult = 0;
      

      }

      That's all. When I select a row, it works. Then I select another row, it works but do not erase the previous rectangular. So my list control is full of rectangular. :(( Does anyone know how to erase the previous rectangular? Thanks in advance, :)

      D Offline
      D Offline
      David Crow
      wrote on last edited by
      #2

      When you select an item in a list control, OnLvnItemchangedList1() gets called multiple times. Once for the previous item, and again for the current item. Change the pen color accordingly.

      "Love people and use things, not love things and use people." - Unknown

      "To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne

      T 1 Reply Last reply
      0
      • D David Crow

        When you select an item in a list control, OnLvnItemchangedList1() gets called multiple times. Once for the previous item, and again for the current item. Change the pen color accordingly.

        "Love people and use things, not love things and use people." - Unknown

        "To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne

        T Offline
        T Offline
        tataxin
        wrote on last edited by
        #3

        Thank you for your answer, DavidCrow. Actually, I have a int member of dialog to keep the old row. So this function look like this:

        void AlarmCompreMsgDig::OnLvnItemchangedList1(NMHDR *pNMHDR, LRESULT *pResult)
        {
        LPNMLISTVIEW pNMLV = reinterpret_cast(pNMHDR);
        m_lstAlarmCompreMsg.SetItemState(-1, 0, LVIS_SELECTED); // first, diselect the row

        int rowIndex = pNMLV->iItem;
        
        CRect rec;  // boundary rectangular that wrap the row
        m\_lstAlarmCompreMsg.GetItemRect(rowIndex, rec, LVIR\_BOUNDS);
        
        
        // a little adjust the rectangular
            rec.top -= 2;
        rec.bottom += 2;
        
        CDC\* cdc = m\_lstAlarmCompreMsg.GetDC();
        
        CPen aPen;
        
            // oldRowIndex is the member of dialog
           if (oldRowIndex == rowIndex){ // this occurs 1st, and 3rd also 
                 aPen.CreatePen(PS\_SOLID, 1, RGB(0, 0, 0)); // select color Black (background color)
            } 
            else // this occurs 2nd
            {
                 aPen.CreatePen(PS\_SOLID, 1, RGB(255, 255, 255)); // select color White
                 oldRowIndex = rowIndex;   // update oldRowIndex
            }        
        
        CPen\* pOldPen = cdc->SelectObject(&aPen); // Select the pen
        
        // Now draw the rectangular
        cdc->Rectangle(rec);
        
            // select back the old pen
        cdc->SelectObject(pOldPen);
            
            \*pResult = 0;
        

        }

        But there is something wrong here: this function is called 3 time totally. The 1st time it will erase the old rectangular, the second time it draw new rectangular, and then the last time it erase the new created rectangular. I don't know why???

        D 1 Reply Last reply
        0
        • T tataxin

          Thank you for your answer, DavidCrow. Actually, I have a int member of dialog to keep the old row. So this function look like this:

          void AlarmCompreMsgDig::OnLvnItemchangedList1(NMHDR *pNMHDR, LRESULT *pResult)
          {
          LPNMLISTVIEW pNMLV = reinterpret_cast(pNMHDR);
          m_lstAlarmCompreMsg.SetItemState(-1, 0, LVIS_SELECTED); // first, diselect the row

          int rowIndex = pNMLV->iItem;
          
          CRect rec;  // boundary rectangular that wrap the row
          m\_lstAlarmCompreMsg.GetItemRect(rowIndex, rec, LVIR\_BOUNDS);
          
          
          // a little adjust the rectangular
              rec.top -= 2;
          rec.bottom += 2;
          
          CDC\* cdc = m\_lstAlarmCompreMsg.GetDC();
          
          CPen aPen;
          
              // oldRowIndex is the member of dialog
             if (oldRowIndex == rowIndex){ // this occurs 1st, and 3rd also 
                   aPen.CreatePen(PS\_SOLID, 1, RGB(0, 0, 0)); // select color Black (background color)
              } 
              else // this occurs 2nd
              {
                   aPen.CreatePen(PS\_SOLID, 1, RGB(255, 255, 255)); // select color White
                   oldRowIndex = rowIndex;   // update oldRowIndex
              }        
          
          CPen\* pOldPen = cdc->SelectObject(&aPen); // Select the pen
          
          // Now draw the rectangular
          cdc->Rectangle(rec);
          
              // select back the old pen
          cdc->SelectObject(pOldPen);
              
              \*pResult = 0;
          

          }

          But there is something wrong here: this function is called 3 time totally. The 1st time it will erase the old rectangular, the second time it draw new rectangular, and then the last time it erase the new created rectangular. I don't know why???

          D Offline
          D Offline
          David Crow
          wrote on last edited by
          #4

          tataxin wrote:

          But there is something wrong here: this function is called 3 time totally.

          Which is correct. The first time you select an item, it should get called once with a new state of LVSI_FOCUSED|LVSI_SELECTED. The next time you select an item, it should get called three times: the first time for the old item to remove the LVSI_FOCUSED style; the second time for the old item to remove the LVSI_SELECTED style; and a third time for the new item with a new state of LVSI_FOCUSED|LVSI_SELECTED. Make sense?

          "Love people and use things, not love things and use people." - Unknown

          "To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne

          T 1 Reply Last reply
          0
          • D David Crow

            tataxin wrote:

            But there is something wrong here: this function is called 3 time totally.

            Which is correct. The first time you select an item, it should get called once with a new state of LVSI_FOCUSED|LVSI_SELECTED. The next time you select an item, it should get called three times: the first time for the old item to remove the LVSI_FOCUSED style; the second time for the old item to remove the LVSI_SELECTED style; and a third time for the new item with a new state of LVSI_FOCUSED|LVSI_SELECTED. Make sense?

            "Love people and use things, not love things and use people." - Unknown

            "To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne

            T Offline
            T Offline
            tataxin
            wrote on last edited by
            #5

            oh, that's great. I try to find out this, but not success up to now. And, can you explain some more, what should I change in my source code now? I tried some thing but not correct. the structure of pNMLV is

            typedef struct tagNMLISTVIEW {
            NMHDR hdr;
            int iItem;
            int iSubItem;
            UINT uNewState;
            UINT uOldState;
            UINT uChanged;
            POINT ptAction;
            LPARAM lParam;
            } NMLISTVIEW, *LPNMLISTVIEW;

            which member should I take and how to compare with LVIS_FOCUSED, LVIS_SELECTED? In fact, I tried this

            int x = pNMLV->uChanged;
            if (x == ){
            // draw rectangular here
            } else if (x == LVIS_FOCUSED){
            // remove old rectangular here
            } else if (x == LVIS_SELECTED){
            // do nothing
            }

            but it's always be LVIS_FOCUSED|LVIS_SELECTED, so it always draws and draws

            D T 2 Replies Last reply
            0
            • T tataxin

              oh, that's great. I try to find out this, but not success up to now. And, can you explain some more, what should I change in my source code now? I tried some thing but not correct. the structure of pNMLV is

              typedef struct tagNMLISTVIEW {
              NMHDR hdr;
              int iItem;
              int iSubItem;
              UINT uNewState;
              UINT uOldState;
              UINT uChanged;
              POINT ptAction;
              LPARAM lParam;
              } NMLISTVIEW, *LPNMLISTVIEW;

              which member should I take and how to compare with LVIS_FOCUSED, LVIS_SELECTED? In fact, I tried this

              int x = pNMLV->uChanged;
              if (x == ){
              // draw rectangular here
              } else if (x == LVIS_FOCUSED){
              // remove old rectangular here
              } else if (x == LVIS_SELECTED){
              // do nothing
              }

              but it's always be LVIS_FOCUSED|LVIS_SELECTED, so it always draws and draws

              D Offline
              D Offline
              David Crow
              wrote on last edited by
              #6

              tataxin wrote:

              int x = pNMLV->uChanged;

              Look at the two "state" members.

              tataxin wrote:

              if (x == ){

              You have to compare bits here.

              "Love people and use things, not love things and use people." - Unknown

              "To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne

              1 Reply Last reply
              0
              • T tataxin

                oh, that's great. I try to find out this, but not success up to now. And, can you explain some more, what should I change in my source code now? I tried some thing but not correct. the structure of pNMLV is

                typedef struct tagNMLISTVIEW {
                NMHDR hdr;
                int iItem;
                int iSubItem;
                UINT uNewState;
                UINT uOldState;
                UINT uChanged;
                POINT ptAction;
                LPARAM lParam;
                } NMLISTVIEW, *LPNMLISTVIEW;

                which member should I take and how to compare with LVIS_FOCUSED, LVIS_SELECTED? In fact, I tried this

                int x = pNMLV->uChanged;
                if (x == ){
                // draw rectangular here
                } else if (x == LVIS_FOCUSED){
                // remove old rectangular here
                } else if (x == LVIS_SELECTED){
                // do nothing
                }

                but it's always be LVIS_FOCUSED|LVIS_SELECTED, so it always draws and draws

                T Offline
                T Offline
                tataxin
                wrote on last edited by
                #7

                I solved it, The final source code is;

                if ((pNMLV->uChanged & LVIF_STATE) != LVIF_STATE)
                return; // state has not changed

                if (pNMLV->uOldState & LVIS\_SELECTED)
                {
                	// remove old rectangular here
                }
                else if (pNMLV->uNewState & LVIS\_SELECTED)
                {
                	// draw new rectangular here
                }
                

                It works, great!!!!! Thank you for your suggestion, DavidCrow, :)

                1 Reply Last reply
                0
                Reply
                • Reply as topic
                Log in to reply
                • Oldest to Newest
                • Newest to Oldest
                • Most Votes


                • Login

                • Don't have an account? Register

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • World
                • Users
                • Groups