Loading ...
Sorry, an error occurred while loading the content.

A SysListView32 control with multiple columns

Expand Messages
  • mustard99122
    I m having a problem getting the contents of a SysListView32 with multiple columns using GetListViewContents. I noticed that a few other people are also
    Message 1 of 13 , Apr 21, 2005
    • 0 Attachment
      I'm having a problem getting the contents of a SysListView32 with
      multiple columns using GetListViewContents. I noticed that a few
      other people are also having problems. Is this feature on anyone's
      todo list? It would be well worth my time to implement this feature,
      but don't have any experience with the Windows API.

      Has anyone had any luck getting data from the SysHeader32 control?

      Anyone have a work-around?

      Thanks for the great tool!

      - Dale
    • Dennis K. Paulsen
      This issue will need to be looked at. If you have a moment to document it at http://sourceforge.net/projects/winguitest, please do so. As far as SysHeader32,
      Message 2 of 13 , Apr 29, 2005
      • 0 Attachment
        This issue will need to be looked at. If you have a moment to
        document it at http://sourceforge.net/projects/winguitest, please do
        so. As far as SysHeader32, it should be a walk-in-the-park, time
        permitting; which it hasn't been for me as of late.


        Regards,
        Dennis

        --- In perlguitest@yahoogroups.com, "mustard99122"
        <dale_bertrand@y...> wrote:
        >
        >
        >
        > I'm having a problem getting the contents of a SysListView32 with
        > multiple columns using GetListViewContents. I noticed that a few
        > other people are also having problems. Is this feature on anyone's
        > todo list? It would be well worth my time to implement this feature,
        > but don't have any experience with the Windows API.
        >
        > Has anyone had any luck getting data from the SysHeader32 control?
        >
        > Anyone have a work-around?
        >
        > Thanks for the great tool!
        >
        > - Dale
      • denishowe
        In perlguitest@yahoogroups.com, mustard99122 ... In guitest.xs: ListView_GetItemText(g_hWnd, iItem, 0, g_szBuffer, MAX_DATA_BUF); the 0 selects the first
        Message 3 of 13 , Sep 29, 2005
        • 0 Attachment
          In perlguitest@yahoogroups.com, "mustard99122"
          <dale_bertrand@y...> wrote:
          > I'm having a problem getting the contents of a SysListView32
          > with multiple columns using GetListViewContents.

          In guitest.xs:

          ListView_GetItemText(g_hWnd, iItem, 0, g_szBuffer, MAX_DATA_BUF);

          the "0" selects the first column. It looks like it should be possible
          to extend GetListViewContents() to collect values from all the columns
          and return the contents as a list of lists.

          If I was to do this, what would I do with the patch or should I try to
          get set up for CVS access to SourceForge?
        • Piotr Kaluski
          ... to ... The best way would be if you take the most recent files from CVS (Instructions how to do it are here: https://sourceforge.net/cvs/?group_id=104592)
          Message 4 of 13 , Sep 29, 2005
          • 0 Attachment
            >
            > If I was to do this, what would I do with the patch or should I try
            to
            > get set up for CVS access to SourceForge?

            The best way would be if you take the most recent files from CVS
            (Instructions how to do it are here:
            https://sourceforge.net/cvs/?group_id=104592) and apply your changes
            there and than send me a patch. Note that after getting the files
            from
            CVS, you have to remove build.pl file (yes: REMOVE). Otherwise the
            code
            will not build.
            Please send a patch directly to me. Yahoo eats some spaces when
            displaying posts and "patch" program gets confused.
            Eventualy, if you really can't make cvs work for you, you can modify
            whatever file version you have and send it to me. Again - to me
            directly. Or even better - post changes in the group and send it to
            me
            directly (so people will have an opportunity to comment).

            -Piotr
          • denishowe
            Firstly, thanks to Piotr and co for their magnificent work on Win32::GuiTest. I gave up trying to get cvsnt to connect to SourceForge via sockscap. I ve been
            Message 5 of 13 , Oct 3, 2005
            • 0 Attachment
              Firstly, thanks to Piotr and co for their magnificent work on
              Win32::GuiTest.

              I gave up trying to get cvsnt to connect to SourceForge via sockscap.

              I've been playing with the XS code (my first attempt at this sort of
              thing). I succeeded in reading all the items and subitems out of a
              multi-column ListView control, but only by a couple of gross hacks:

              sub GetListViewContents
              {
              my $window = shift;
              my @res;
              my $item_count = GetListViewItemCount($window);
              for my $item_index (0..$item_count-1)
              {
              my $subitem_index = 0;
              my @item;
              while ($subitem_index < 10)
              {
              my $subitem = GetListViewItem(
              $window, $item_index << 16 | $subitem_index);
              push @item, $subitem;
              $subitem_index++;
              }
              push @res, \@item;
              $item_index++;
              }
              return @res;
              }

              Note that I always collect ten columns. Also note that I'm packing
              the item and subitem indexes into a single arg rather than trying to
              marshal multiple args through SendMessage.

              I exposed GetLVItemText(), passing through the item/subitem arg:

              SV*
              GetListViewItem(hWnd, iItem)
              HWND hWnd
              int iItem
              CODE:
              char szItem[MAX_DATA_BUF+1] = "";
              GetLVItemText(hWnd, iItem, szItem);
              RETVAL = newSVpv(szItem, 0);
              OUTPUT:
              RETVAL

              And I exposed GetLVItemCount():

              int
              GetListViewItemCount(hWnd)
              HWND hWnd
              CODE:
              RETVAL = GetLVItemCount(hWnd);
              OUTPUT:
              RETVAL

              HookProc unhacks the WM_LV_GETTEXT message like this:

              if (pCW->message == WM_LV_GETTEXT) {
              *g_szBuffer = NUL;
              int iItem = pCW->wParam;
              int iSubItem = iItem & 0xFFFF;
              iItem >>= 16;
              ListView_GetItemText(g_hWnd, iItem, iSubItem, g_szBuffer,
              MAX_DATA_BUF);
              UnhookWindowsHookEx(g_hHook);
              } else ...

              All of this sort of assumes the ListView is in "Detail" mode (in which
              it can have multiple columns and a header).

              I found an easy way to get the count of columns for ListView handle
              $lv:

              use Win32::GUI;
              my $header = Win32::GUI::ListView::GetHeader($lv);
              my $n_cols = Win32::GUI::Header::GetItemCount($header);

              Which makes me wonder how much of Win32::GUI it is desirable to
              duplicate into GuiTest. It would be better to move FindWindowLike(),
              SendKeys(), and the other things that are unique to GuiTest, into GUI
              and scrap GuiTest rather than slowly and painfully copying lots of
              functions the other way.
            • Piotr Kaluski
              ... That s really nice to read. However, the foundation of module was created by Ernesto Guisado and then extented by Dennis Paulsen and Gabor Szabo. I have
              Message 6 of 13 , Oct 3, 2005
              • 0 Attachment
                --- In perlguitest@yahoogroups.com, "denishowe" <dbh@d...> wrote:
                > Firstly, thanks to Piotr and co for their magnificent work on
                > Win32::GuiTest.
                >

                That's really nice to read. However, the foundation of module was
                created by Ernesto Guisado and then extented by Dennis Paulsen and
                Gabor Szabo. I have only made few recent changes.

                As for the remaining part of your post I need some to digest it.

                -Piotr
              • Piotr Kaluski
                Denis, I totally understand your point. However, I think there are some subtle differences between Win32::GUI and Win32::GuiTest. Win32::GUI is a perl wrapper
                Message 7 of 13 , Oct 4, 2005
                • 0 Attachment
                  Denis,
                  I totally understand your point. However, I think there are some
                  subtle differences between Win32::GUI and Win32::GuiTest.
                  Win32::GUI is a perl wrapper around user32.dll and gdi32.dll. It is
                  basically a perl OO library for writing Win GUI applications. Most of
                  this library's methods assume that controls and windows they operate
                  are owned by the same process, which calls those methods. This is
                  different for Win32::GuiTest. Its functions assume that controls and
                  windows they operate are hosted by a different process. It does not
                  matter for basic controls, but it does matter for more advanced
                  controls like ListView.
                  Calls to Win32::GUI::ListView::GetHeader() and
                  Win32::GUI::Header::GetItemCount() worked because those functions
                  send and return numbers. But I expect that you will get application
                  crashes if you will try to retrieve/add items to the list using
                  Win32::GUI methods. This is why Dennis Paulsen had to adopt hooking
                  for simple ListView operations. This is why I implemented Virtual
                  Memory functions. Have a look at a more detailed explanation:
                  http://www.piotrkaluski.com/files/winguitest/docs/ch02s04.html.

                  -Piotr


                  >
                  > I found an easy way to get the count of columns for ListView handle
                  > $lv:
                  >
                  > use Win32::GUI;
                  > my $header = Win32::GUI::ListView::GetHeader($lv);
                  > my $n_cols = Win32::GUI::Header::GetItemCount($header);
                  >
                  > Which makes me wonder how much of Win32::GUI it is desirable to
                  > duplicate into GuiTest. It would be better to move FindWindowLike
                  (),
                  > SendKeys(), and the other things that are unique to GuiTest, into
                  GUI
                  > and scrap GuiTest rather than slowly and painfully copying lots of
                  > functions the other way.
                • denishowe
                  ... You re right of course. When Win32::GUI tried to get the text of a ListView item the program under test blew up, just as you explain in your tutorial.
                  Message 8 of 13 , Oct 4, 2005
                  • 0 Attachment
                    In perlguitest@yahoogroups.com, "Piotr Kaluski" <pkaluski@p...> wrote:
                    > Win32::GuiTest...functions assume that controls and
                    > windows they operate are hosted by a different process.
                    > It does not matter for basic controls, but it does
                    > matter for more advanced controls like ListView.

                    You're right of course. When Win32::GUI tried to get the text of a
                    ListView item the program under test blew up, just as you explain in
                    your tutorial.

                    Couldn't one still merge Win32::GuiTest into Win32::GUI if certain GUI
                    functions used the message-hook trick for controls in other processes?
                    How tricky would that be?
                  • Piotr Kaluski
                    Well, first of all it is not our decision. The idea has to be accepted by Win::GUI development team. Apart from this, I am not sure there is someone who would
                    Message 9 of 13 , Oct 4, 2005
                    • 0 Attachment
                      Well, first of all it is not our decision. The idea has to be accepted
                      by Win::GUI development team. Apart from this, I am not sure there is
                      someone who would actually have time to do it. Win32::GuiTest is a kind
                      of procedural API, whereas Win32::GUI is a an object oriented library.
                      So we can't just copy and paste the code.
                      There is a space for discussion on this merge. Especially from
                      design/phylosophy point of view. But whatever would be a conclusion,
                      the hard facts are that there are no resources to code it (not that I
                      know of). However, if it occurs that there is a strong will to do that
                      and a strong commitment to do the actuall work, I would be happy to
                      help.
                      -Piotr

                      >
                      > Couldn't one still merge Win32::GuiTest into Win32::GUI if certain
                      GUI
                      > functions used the message-hook trick for controls in other
                      processes?
                      > How tricky would that be?
                    • Piotr Kaluski
                      Hi, I just had a closer look on Win32::GUI. Boy, that s impressive what those guys did. They wrapped many, many useful Win32 API functions. So we should
                      Message 10 of 13 , Oct 6, 2005
                      • 0 Attachment
                        Hi,
                        I just had a closer look on Win32::GUI. Boy, that's impressive what
                        those guys did. They wrapped many, many useful Win32 API functions.
                        So we should definitely have a closer look at this module. For some
                        functions, there would be this interprocess boundaries problem. But
                        there is quite a lot of functions, which can be used already.
                        The only problem I see right now is that Win32::GUI is object
                        oriented and it assumes, that you create windows and controls. I did
                        not find a function allowing to attach to existing window created by
                        some other process (which does not mean that such a functions does
                        not exist).

                        --Piotr

                        --- In perlguitest@yahoogroups.com, "Piotr Kaluski" <pkaluski@p...>
                        wrote:
                        > Well, first of all it is not our decision. The idea has to be
                        accepted
                        > by Win::GUI development team. Apart from this, I am not sure there
                        is
                        > someone who would actually have time to do it. Win32::GuiTest is a
                        kind
                        > of procedural API, whereas Win32::GUI is a an object oriented
                        library.
                        > So we can't just copy and paste the code.
                        > There is a space for discussion on this merge. Especially from
                        > design/phylosophy point of view. But whatever would be a
                        conclusion,
                        > the hard facts are that there are no resources to code it (not that
                        I
                        > know of). However, if it occurs that there is a strong will to do
                        that
                        > and a strong commitment to do the actuall work, I would be happy to
                        > help.
                        > -Piotr
                        >
                        > >
                        > > Couldn't one still merge Win32::GuiTest into Win32::GUI if certain
                        > GUI
                        > > functions used the message-hook trick for controls in other
                        > processes?
                        > > How tricky would that be?
                      • Piotr Kaluski
                        OK, I sent a question to Win32::GUI list. Have a look below on my question and the answer. Give it a try. Win32::GUI has many handy functions (I am not hired
                        Message 11 of 13 , Oct 6, 2005
                        • 0 Attachment
                          OK,
                          I sent a question to Win32::GUI list. Have a look below on my
                          question and the answer. Give it a try. Win32::GUI has many handy
                          functions (I am not hired by Win32::GUI team to promote them :-))

                          --Piotr

                          QUESTION:
                          Hi,
                          I am one of developers of Win32::GuiTest library. It is a module for
                          GUI test automation. I am actually pretty impressed with all the
                          great work you have done. Using your module should free us from
                          writing some functions ourselves.
                          I have one question. My impression is, that your library is object
                          oriented and it assumes, that a script using it has actually created
                          all windows it manipulates. Is it possible to attach to a
                          window/control created by some other application? Say I have a handle
                          of a main window of Windows calculator. How do I turn it into
                          Win::GUI object?


                          ANSWER (sent by Jeremy White):
                          Interesting question. As a quick/dirty answer, yes it could be
                          possible. The basic problem is that when Win::GUI object's are
                          destroyed the underlying window handle is also "destroyed".This could
                          be solved by having some sort of flag to say if Win::GUI actually
                          owns the object or not.

                          Ok - the above is true when we're using objects via method calls but
                          most of the internals can also be called as functions. For example:

                          $win->Show(); #shows the window

                          but we could also call it this way:

                          Win32::GUI::Show($win);

                          Where $win is a Win32::GUI object OR the handle...So, if you've got a
                          handle for some other app, then it should just work...

                          Hope that makes some sense.

                          Cheers,

                          jez.

                          END OF ANSWER




                          --- In perlguitest@yahoogroups.com, "Piotr Kaluski" <pkaluski@p...>
                          wrote:
                          > Hi,
                          > I just had a closer look on Win32::GUI. Boy, that's impressive what
                          > those guys did. They wrapped many, many useful Win32 API functions.
                          > So we should definitely have a closer look at this module. For some
                          > functions, there would be this interprocess boundaries problem. But
                          > there is quite a lot of functions, which can be used already.
                          > The only problem I see right now is that Win32::GUI is object
                          > oriented and it assumes, that you create windows and controls. I
                          did
                          > not find a function allowing to attach to existing window created
                          by
                          > some other process (which does not mean that such a functions does
                          > not exist).
                          >
                          > --Piotr
                          >
                          > --- In perlguitest@yahoogroups.com, "Piotr Kaluski" <pkaluski@p...>
                          > wrote:
                          > > Well, first of all it is not our decision. The idea has to be
                          > accepted
                          > > by Win::GUI development team. Apart from this, I am not sure
                          there
                          > is
                          > > someone who would actually have time to do it. Win32::GuiTest is
                          a
                          > kind
                          > > of procedural API, whereas Win32::GUI is a an object oriented
                          > library.
                          > > So we can't just copy and paste the code.
                          > > There is a space for discussion on this merge. Especially from
                          > > design/phylosophy point of view. But whatever would be a
                          > conclusion,
                          > > the hard facts are that there are no resources to code it (not
                          that
                          > I
                          > > know of). However, if it occurs that there is a strong will to do
                          > that
                          > > and a strong commitment to do the actuall work, I would be happy
                          to
                          > > help.
                          > > -Piotr
                          > >
                          > > >
                          > > > Couldn't one still merge Win32::GuiTest into Win32::GUI if
                          certain
                          > > GUI
                          > > > functions used the message-hook trick for controls in other
                          > > processes?
                          > > > How tricky would that be?
                        • Piotr Kaluski
                          ... Dennis, I had a look at your code. I haven t tested it yet, but I have some comments and would like to hear your and other people s opinion. I have placed
                          Message 12 of 13 , Nov 1, 2005
                          • 0 Attachment
                            --- In perlguitest@yahoogroups.com, "Piotr Kaluski" <pkaluski@p...> wrote:
                            >
                            > >
                            > > If I was to do this, what would I do with the patch or should I try
                            > to
                            > > get set up for CVS access to SourceForge?
                            >
                            > The best way would be if you take the most recent files from CVS
                            > (Instructions how to do it are here:
                            > https://sourceforge.net/cvs/?group_id=104592) and apply your changes
                            > there and than send me a patch. Note that after getting the files
                            > from
                            > CVS, you have to remove build.pl file (yes: REMOVE). Otherwise the
                            > code
                            > will not build.
                            > Please send a patch directly to me. Yahoo eats some spaces when
                            > displaying posts and "patch" program gets confused.
                            > Eventualy, if you really can't make cvs work for you, you can modify
                            > whatever file version you have and send it to me. Again - to me
                            > directly. Or even better - post changes in the group and send it to
                            > me
                            > directly (so people will have an opportunity to comment).
                            >
                            > -Piotr
                            >

                            Dennis,
                            I had a look at your code. I haven't tested it yet, but I have some
                            comments and would like to hear your and other people's opinion.
                            I have placed your code (and diffs with release 1.50.4) in the files
                            section of this group (new_lv.zip file).
                            Your code is terse, which proves that you have a pretty good command
                            of perl. However, I am afraid that this terseness, may make the code
                            slightly less readable for some less experienced developers.

                            The main point of your change was to give a user a chance to choose
                            not only an element from the list, but also a column in this element.
                            So you had to add a mechinism to pass an index of a column (subitem).
                            You have chosen, to merge this parameter with list view item index.
                            The code looks as follows:

                            #define pCW ((CWPSTRUCT*)lParam)
                            LRESULT HookProc (int code, WPARAM wParam, LPARAM lParam)
                            {
                            //// List Views ////
                            if (pCW->message == WM_LV_GETTEXT) {
                            *g_szBuffer = NUL;
                            int iItem = pCW->wParam;
                            int iSubItem = iItem & 0xFFFF;
                            iItem >>= 16;
                            ListView_GetItemText(g_hWnd, iItem, iSubItem, g_szBuffer,
                            MAX_DATA_BUF);
                            UnhookWindowsHookEx(g_hHook);
                            ......

                            --End of code--

                            So you treat pCW->wParam as a double word, which has iItem and
                            iSubItem in it. It probably works fine (I didn't test it), but I am
                            wondering if we can use pCW->lParam to pass iSubItem as separate
                            value. The code would look like this:

                            #define pCW ((CWPSTRUCT*)lParam)
                            LRESULT HookProc (int code, WPARAM wParam, LPARAM lParam)
                            {
                            //// List Views ////
                            if (pCW->message == WM_LV_GETTEXT) {
                            *g_szBuffer = NUL;
                            int iItem = pCW->wParam;
                            int iSubItem = pCW->lParam;
                            ListView_GetItemText(g_hWnd, iItem, iSubItem, g_szBuffer,
                            MAX_DATA_BUF);
                            UnhookWindowsHookEx(g_hHook);
                            ......

                            --End of code--

                            GetListViewContents would then look like this:

                            sub GetListViewContents
                            {
                            my $lv = shift;
                            my @res;
                            my $item_count = GetListViewItemCount($lv);
                            my $header = GetListViewHeader($lv);
                            my $column_count = $header ? GetHeaderColumnCount($header) : 1;
                            # Items are numbered from 0
                            for my $item_index (0..$item_count-1)
                            {
                            # Sub-items are numbered from 1
                            # push @res, [map(GetListViewItem($lv, $item_index << 16 | $_),
                            # 1..$column_count)];
                            # PK: Instead of lines above it would be:
                            push @res, [map(GetListViewItem($lv, $item_index, $_ ),
                            1..$column_count)];

                            }
                            return @res;
                            }

                            --End of code

                            That would of course require some changes in other functions:
                            GetListViewItem, GetLVItemText.

                            What do you think?

                            --Piotr
                          • denishowe
                            ... Yes, that works perfectly for me. MSDN had convinced me that I couldn t use lParam but I can no longer find the relevant page.
                            Message 13 of 13 , Nov 8, 2005
                            • 0 Attachment
                              In perlguitest@yahoogroups.com, "Piotr Kaluski" <pkaluski@p...> wrote:

                              > I am wondering if we can use pCW->lParam
                              > to pass iSubItem as separate value.

                              Yes, that works perfectly for me. MSDN had convinced me that I
                              couldn't use lParam but I can no longer find the relevant page.
                            Your message has been successfully submitted and would be delivered to recipients shortly.