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

Re: List View header control

Expand Messages
  • jonnyroberts1978
    This code works on XP & 2K had to use the HDN_ITEMCLICKW message as explorer didn t seem to respond to LVN_COLUMNCLICK. The message is sent to the list but in
    Message 1 of 15 , Mar 7, 2007
      This code works on XP & 2K had to use the HDN_ITEMCLICKW message as
      explorer didn't seem to respond to LVN_COLUMNCLICK.

      The message is sent to the list but in the structure I used the handle
      of the header control.

      sub WM_NOTIFY {0x004E};
      sub HDN_ITEMCLICKW {-322};
      sub LVN_COLUMNCLICK {-108};
      sub NM_RCLICK {-5};


      my $fgWindow = WaitWindowLike(undef, "My Computer", "CabinetWClass\$",
      undef, 3,30);
      SetForegroundWindow($fgWindow);

      ok( $fgWindow != 0, "Testing the main application started" );

      my @windows = FindWindowLike($fgWindow, undef, "SysListView32\$",
      undef, 8) ;

      foreach my $theList ( @windows ) {
      if( IsWindowVisible( $theList ) )
      {
      #Get the header control Commctrl.h LVM_GETHEADER
      my $header = SendMessage( $theList, 0x1000 + 31, 0, 0 );

      #Make sure we have the header
      if($header != 0)
      {
      my $str_buf = pack( "LLLLLL",
      $header, #nmh.hdr.hwndFrom hwnd
      GetWindowID( $header ), #nmh.hdr.idFrom
      HDN_ITEMCLICKW ,#nmh.hdr.code Code
      0,
      0,
      0);

      my $lvitem = AllocateVirtualBuffer( $header, 500 );
      WriteToVirtualBuffer( $lvitem, $str_buf );

      my $value = PostMessage( $theList, WM_NOTIFY, GetWindowID(
      $theList ), $lvitem->{ 'ptr' });
      sleep(1);
      FreeVirtualBuffer( $lvitem );

      printf("value returned = %d \n", $value);
      }
      }
      }

      --- In perlguitest@yahoogroups.com, "jonnyroberts1978"
      <jonnyroberts1978@...> wrote:
      >
      > Thats strange I am using XP and just tried to run the script and it
      > sent the message correctly and didn't crash.
      >
      > If I can find a 2K system around here I will try it on that.
      >
      > I wonder if it could be a problem with the explorer window not
      > responding to the message until after the script has ended, therefore
      > the memory that was allocated might have been cleaned up?
      >
      > --- In perlguitest@yahoogroups.com, "brentje" <brentje@> wrote:
      > >
      > > So that's how you're suppose to create the struct. That's good to
      know,
      > > thanks.
      > >
      > > The funny thing is that I now see the notify message with WinSpector,
      > > with the proper code (LVN_COLUMNCLICK). But nothing happens. Unless
      > > I put a wait-state anywhere in the code, then it crashes Windows
      > > Explorer almost every shot with the debug message "Access violation
      > > reading location...". I'm using the vitual buffer though, so I don't
      > > know why I'd be getting that particular error. I wonder if this is
      > > from the fact that Win2k doesn't allow notify messages between
      > > processes? It seems odd that I'd still see the notify message come up
      > > in WinSpector though.
      > >
      > > On the bright side, I noticed that when I crashed Windows Explorer, it
      > > reloads the taskbar. When it reloads, it puts the application icons
      > > in the same order as the current z-order, not in the order they were
      > > opened. I've always wanted to be able to move those icons around. I
      > > like having Outlook as the first application on the taskbar. I think
      > > I'm going to try exploiting this...
      > >
      > > Thanks
      > > Brent
      > >
      > >
      > > --- In perlguitest@yahoogroups.com, "jonnyroberts1978"
      > > <jonnyroberts1978@> wrote:
      > > >
      > > > Finally got it working.
      > > >
      > > > For some reason I had to use PostMessage rather then
      SendMessage. Also
      > > > I think the reason it was crashing before was because the memory I
      > > > was using was allocated outside the scop of the list control so
      I had
      > > > to use allocate virtual buffer etc.
      > > >
      > > > The other problem was with the nmhdr structure, this is an instance
      > > > rather then a pointer to another structure.
      > > >
      > > > my $action = pack( "l l",
      > > > 0, #ptaction.x
      > > > 0 #ptaction.y
      > > > );
      > > >
      > > > my $action_ptr = unpack( 'L!', pack( 'P',$action));
      > > >
      > > > my $str_buf = pack( "L L L l l L L L L l",
      > > > $keysList, #nmh.hdr.hwndFrom hwnd
      > > > GetWindowID( $keysList ), #nmh.hdr.idFrom
      > > > LVN_COLUMNCLICK ,#nmh.hdr.code Code
      > > > -1, #item
      > > > 1, #sub item
      > > > 0, #uNewState
      > > > 0, #uOldState
      > > > 0, #uChanged
      > > > $action_ptr, #action
      > > > 0 #lparam
      > > > );
      > > >
      > > > my $lvitem = AllocateVirtualBuffer( $keysList, 500 );
      > > > WriteToVirtualBuffer( $lvitem, $str_buf );
      > > >
      > > > my $value = PostMessage( $keysList, WM_NOTIFY, GetWindowID(
      > > > $keysList ), $lvitem->{ 'ptr' });
      > > > FreeVirtualBuffer( $lvitem );
      > > >
      > > > Thanks for your help.
      > > >
      > > > Regards
      > > > Jon
      > > >
      > >
      >
    • brentje
      Excellent...I got it working. Works beautifully actually. My problem was that I needed to put a wait-state in between the PostMessage and the
      Message 2 of 15 , Mar 7, 2007
        Excellent...I got it working. Works beautifully actually. My problem
        was that I needed to put a wait-state in between the PostMessage and
        the FreeVirtualBuffer. I guess it was destroying the struct before it
        was used by Explorer. Now that I know what I'm doing, I'm going to
        play with this more. See if I can clean up some of my code. Thanks
        for the help.

        Brent

        Wait...how'd this go from you asking a question to you helping me?

        --- In perlguitest@yahoogroups.com, "jonnyroberts1978"
        <jonnyroberts1978@...> wrote:
        >
        > This code works on XP & 2K had to use the HDN_ITEMCLICKW message as
        > explorer didn't seem to respond to LVN_COLUMNCLICK.
        >
        > The message is sent to the list but in the structure I used the handle
        > of the header control.
        >
        > sub WM_NOTIFY {0x004E};
        > sub HDN_ITEMCLICKW {-322};
        > sub LVN_COLUMNCLICK {-108};
        > sub NM_RCLICK {-5};
        >
        >
        > my $fgWindow = WaitWindowLike(undef, "My Computer", "CabinetWClass\$",
        > undef, 3,30);
        > SetForegroundWindow($fgWindow);
        >
        > ok( $fgWindow != 0, "Testing the main application started" );
        >
        > my @windows = FindWindowLike($fgWindow, undef, "SysListView32\$",
        > undef, 8) ;
        >
        > foreach my $theList ( @windows ) {
        > if( IsWindowVisible( $theList ) )
        > {
        > #Get the header control Commctrl.h LVM_GETHEADER
        > my $header = SendMessage( $theList, 0x1000 + 31, 0, 0 );
        >
        > #Make sure we have the header
        > if($header != 0)
        > {
        > my $str_buf = pack( "LLLLLL",
        > $header, #nmh.hdr.hwndFrom hwnd
        > GetWindowID( $header ), #nmh.hdr.idFrom
        > HDN_ITEMCLICKW ,#nmh.hdr.code Code
        > 0,
        > 0,
        > 0);
        >
        > my $lvitem = AllocateVirtualBuffer( $header, 500 );
        > WriteToVirtualBuffer( $lvitem, $str_buf );
        >
        > my $value = PostMessage( $theList, WM_NOTIFY, GetWindowID(
        > $theList ), $lvitem->{ 'ptr' });
        > sleep(1);
        > FreeVirtualBuffer( $lvitem );
        >
        > printf("value returned = %d \n", $value);
        > }
        > }
        > }
        >
      Your message has been successfully submitted and would be delivered to recipients shortly.