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

Re: A SysListView32 control with multiple columns

Expand Messages
  • 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 1 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 2 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 3 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 4 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 5 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 6 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 7 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.