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. Other Discussions
  3. Clever Code
  4. ListView_SetItemText is not a function, which can make someone mad

ListView_SetItemText is not a function, which can make someone mad

Scheduled Pinned Locked Moved Clever Code
debugginghelpquestion
5 Posts 3 Posters 3 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.
  • H Offline
    H Offline
    Hans
    wrote on last edited by
    #1

    I've run across this nasty bug in using ListView_SetItemText. // Format64() returns a string object (which has operator const wchar*) ListView_SetItemText(items.list, i, 1, const_cast<wchar*>((const wchar*)Format64(space[i]))); Runs great in debug mode, but if running actually under debugger control listview gets garbage :confused: So, lets look at the generated assembler (it always pays to at least understand asm a little) ;-) Oh, destructor for returned string object from Format64 is called before SendMessage. Blaming the compiler is generating wrong code, as temporaries must only be destructed after function call? After some thought about writing a nasty bug report I realized ListView_SetItemText is a macro. #define ListView_SetItemText(hwndLV, i, iSubItem_, pszText_) \ { LV_ITEM _ms_lvi;\ _ms_lvi.iSubItem = iSubItem_;\ _ms_lvi.pszText = pszText_;\ SNDMSG((hwndLV), LVM_SETITEMTEXT, (WPARAM)(i), (LPARAM)(LV_ITEM *)&_ms_lvi);\ } So the compiler is correct and I know once more macros are evil:)

    Hans

    M P 2 Replies Last reply
    0
    • H Hans

      I've run across this nasty bug in using ListView_SetItemText. // Format64() returns a string object (which has operator const wchar*) ListView_SetItemText(items.list, i, 1, const_cast<wchar*>((const wchar*)Format64(space[i]))); Runs great in debug mode, but if running actually under debugger control listview gets garbage :confused: So, lets look at the generated assembler (it always pays to at least understand asm a little) ;-) Oh, destructor for returned string object from Format64 is called before SendMessage. Blaming the compiler is generating wrong code, as temporaries must only be destructed after function call? After some thought about writing a nasty bug report I realized ListView_SetItemText is a macro. #define ListView_SetItemText(hwndLV, i, iSubItem_, pszText_) \ { LV_ITEM _ms_lvi;\ _ms_lvi.iSubItem = iSubItem_;\ _ms_lvi.pszText = pszText_;\ SNDMSG((hwndLV), LVM_SETITEMTEXT, (WPARAM)(i), (LPARAM)(LV_ITEM *)&_ms_lvi);\ } So the compiler is correct and I know once more macros are evil:)

      Hans

      M Offline
      M Offline
      Mark Salsbery
      wrote on last edited by
      #2

      In big letters at the top of the documentaion for ListView_SetItemText is ListView_SetItemText Macro ;P

      "Do you know what it's like to fall in the mud and get kicked... in the head... with an iron boot? Of course you don't, no one does. It never happens. It's a dumb question... skip it."

      H 1 Reply Last reply
      0
      • M Mark Salsbery

        In big letters at the top of the documentaion for ListView_SetItemText is ListView_SetItemText Macro ;P

        "Do you know what it's like to fall in the mud and get kicked... in the head... with an iron boot? Of course you don't, no one does. It never happens. It's a dumb question... skip it."

        H Offline
        H Offline
        Hans
        wrote on last edited by
        #3

        Hi, thanks for the hint. All ListView_XXX functions are macros by the way. And most of WindowsX.h functions (well macros) are macros. So they are all possible candidates for surprises? I think we must differentiate good macros (evaluate args only once, do not scope fiddling) with evil ones (yes and for these in big red letters IS A MACRO please) :)

        Hans

        M 1 Reply Last reply
        0
        • H Hans

          Hi, thanks for the hint. All ListView_XXX functions are macros by the way. And most of WindowsX.h functions (well macros) are macros. So they are all possible candidates for surprises? I think we must differentiate good macros (evaluate args only once, do not scope fiddling) with evil ones (yes and for these in big red letters IS A MACRO please) :)

          Hans

          M Offline
          M Offline
          Mark Salsbery
          wrote on last edited by
          #4

          :laugh:

          Hans wrote:

          So they are all possible candidates for surprises?

          Every time I use something new in the OS it's a candidate for a surprise!

          "Do you know what it's like to fall in the mud and get kicked... in the head... with an iron boot? Of course you don't, no one does. It never happens. It's a dumb question... skip it."

          1 Reply Last reply
          0
          • H Hans

            I've run across this nasty bug in using ListView_SetItemText. // Format64() returns a string object (which has operator const wchar*) ListView_SetItemText(items.list, i, 1, const_cast<wchar*>((const wchar*)Format64(space[i]))); Runs great in debug mode, but if running actually under debugger control listview gets garbage :confused: So, lets look at the generated assembler (it always pays to at least understand asm a little) ;-) Oh, destructor for returned string object from Format64 is called before SendMessage. Blaming the compiler is generating wrong code, as temporaries must only be destructed after function call? After some thought about writing a nasty bug report I realized ListView_SetItemText is a macro. #define ListView_SetItemText(hwndLV, i, iSubItem_, pszText_) \ { LV_ITEM _ms_lvi;\ _ms_lvi.iSubItem = iSubItem_;\ _ms_lvi.pszText = pszText_;\ SNDMSG((hwndLV), LVM_SETITEMTEXT, (WPARAM)(i), (LPARAM)(LV_ITEM *)&_ms_lvi);\ } So the compiler is correct and I know once more macros are evil:)

            Hans

            P Offline
            P Offline
            peterchen
            wrote on last edited by
            #5

            That is nasty! Even though documentation says it isd a macro, this is a side effect that I think should be documented. (I shunned away from these macros most of my time anyway, now more incentive to do soo...) I wonder: would the following definition would help: #define ListView_SetItemText(hwndLV, i, iSubItem_, pszText_) \ { LV_ITEM _ms_lvi;\ _ms_lvi.iSubItem = iSubItem_;\ (_ms_lvi.pszText = pszText_,\ SNDMSG((hwndLV), LVM_SETITEMTEXT, (WPARAM)(i), (LPARAM)(LV_ITEM *)&_ms_lvi));\ }


            Developers, Developers, Developers, Developers, Developers, Developers, Velopers, Develprs, Developers!
            We are a big screwed up dysfunctional psychotic happy family - some more screwed up, others more happy, but everybody's psychotic joint venture definition of CP
            Linkify!|Fold With Us!

            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