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

1708Re: List View header control

Expand Messages
  • brentje
    Mar 1, 2007
    • 0 Attachment
      You shouldn't have to create a pointer for the HWND. Just send in the
      HWND for the ListView object should work. The one I'm testing with
      (Windows Explorer window set to Detailed list mode) comes out to a 6
      digit number for it's HWND. Plus your NMHDR looks a little off. It
      should be:

      my $test_hdr_buf = pack( "LLL",
      $hwnd, #nmh.hdr.hwndFrom hwnd
      GetWindowID( $hwnd ), #nmh.hdr.idFrom
      NM_RCLICK #nmh.hdr.code Code
      );

      where $hwnd is the handle to the ListView. But the NM_RCLICK message
      uses a NMITEMACTIVATE struct, which contains NMHDR, so the call won't
      work as it is. Read more here:

      http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/commctls/listview/notifications/nm_rclick_listview.asp

      I've been testing out the code you sent, plus looking up the various
      messages and structures for ListView. Everything I try doesn't seem
      to do anything. I'm using WinSpector to watch the messages, and
      nothing comes up whenever I run the code. The only thing that gets
      called in the LVM_GETHEADER SendMessage. Whenever I manually click a
      lot of messages are sent to both the ListView and it's header. But
      the Notify message doesn't get caught by the ListView or the header.
      I'm not sure whatelse to do. But I have come up with a workaround at
      least. All it does it get the column widths of all the columns up to
      the column you want and adds that to the left X value from
      GetWindowRect for the ListView header. It's cheating, but it works.

      $ListView is the HWND for the ListView object.

      #get the current mouse location.
      my ($x, $y) = GetCursorPos();

      #this is the index of the column we want
      my $index = 2;

      #to store the coordinate offset
      my $Offset = 0;

      my $i = 0;

      #Get the header control Commctrl.h LVM_GETHEADER
      my $Header = SendMessage( $ListView, 0x1000 + 31, 0, 0 );

      #loop through until we get to the column we want, adding up the widths
      as we go.
      for($i = 0; $i < $i_index; $i++)
      {
      #0x1000 + 29 is the message for LVM_GETCOLUMNWIDTH
      $Offset += SendMessage( $ListView, 0x1000 + 29, 0, 0 );
      }

      #Get the RECT coordinates of the header.
      #We only need to deal with the top left-hand corner.
      my ($leftx, $topy, undef, undef) = GetWindowRect( $Header );

      #Add the offset to the left X coordinate, plus a 10 pixel buffer.
      $leftx = $leftx + $Offset + 10;

      #Move the mouse and click...
      MouseMoveAbsPix($leftx, $topy + 5);
      SendMouse("{LEFTCLICK}");

      #Move the mouse back to where it was, just in case.
      MouseMoveAbsPix($x, $y);

      I'll try to work on the Notify messaging a little more, because it
      would be handy to figure out...

      --- In perlguitest@yahoogroups.com, "jonnyroberts1978"
      <jonnyroberts1978@...> wrote:
      >
      > I have managed to break my problem down slightly and found message
      > that sends only NMHDR part of the structure. This is the NM_RCLICK
      > message.
      >
      > Looking at the NMHDR structure I don't understand how to handle the
      > HWND member of the structure it appears to be more then a long value?
      >
      > I have attached a simpler form of the code which again doesn't do
      > anything, unless a change the SendMessage to a PostMessage in which
      > case the application crashes trying to decode the NMHDR structure.
      >
      > sub NM_RCLICK {-5};
      > sub WM_NOTIFY {0x4E};
      >
      > my $hwnd = pack( "LL",
      >
      > 0 #nmh.hdr.idFrom
      > );
      > my $hwnd_ptr = unpack( 'L!', pack( 'P',$hwnd));
      >
      > my $test_hdr_buf = pack( "LLL",
      > $hwnd_ptr, #nmh.hdr.hwndFrom hwnd
      > 0x3E8, #nmh.hdr.idFrom
      > NM_RCLICK #nmh.hdr.code Code
      > );
      >
      > my $test_hdr_buf_ptr = unpack( 'L!', pack( 'P',$test_hdr_buf));
      >
      > my $value = SendMessage( $keysList, WM_NOTIFY, 0,
      $test_hdr_buf_ptr);
      >
      > --- In perlguitest@yahoogroups.com, "jonnyroberts1978"
      > <jonnyroberts1978@> wrote:
      > >
      > > Hi thanks I have tried that attached but it didn't seem to work.
      > >
      > > Is there any easy way to debug the messages with MFC to see where it
      > > is going?
      > >
      > > Below is a copy of the NMLISTVIEW structure that I need to populate.
      > > the first member is an instance of a NMHDR item and the POINT is a
      > > pointer to a structure.
      > >
      > > Am I correct in unpacking my pointers like the following:
      > >
      > > my $action_ptr = unpack( 'L!', pack( 'P',$action));
      > >
      > >
      > > #typedef struct tagNMLISTVIEW {
      > > # NMHDR hdr;
      > > # int iItem;
      > > # int iSubItem;
      > > # UINT uNewState;
      > > # UINT uOldState;
      > > # UINT uChanged;
      > > # POINT ptAction;
      > > # LPARAM lParam;
      > > #} NMLISTVIEW, *LPNMLISTVIEW;
      > >
      > > sub LVN_COLUMNCLICK {-108};
      > >
      > > my $hdr_buf = pack( "L L L",
      > > $keysList, #nmh.hdr.hwndFrom hwnd
      > > 0x3E8, #nmh.hdr.idFrom
      > > LVN_COLUMNCLICK #nmh.hdr.code Code
      > > );
      > >
      > > my $hdr_buf_ptr = unpack( 'L!', pack( 'P',$hdr_buf));
      > >
      > > 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",
      > > $hdr_buf_ptr,
      > > -1, #item
      > > 0, #sub item
      > > 0, #uNewState
      > > 0, #uOldState
      > > 0, #uChanged
      > > $action_ptr, #action
      > > 0 #lparam
      > > );
      > >
      > > my $str_buf_ptr = unpack( 'L!', pack( 'P',$str_buf));
      > >
      > > my $value = SendMessage( $keysList, WM_NOTIFY, 0x3E8,
      > $str_buf_ptr);
      > > printf("value returned = %d \n", $value);
      > >
      > > --- In perlguitest@yahoogroups.com, "brentje" <brentje@> wrote:
      > > >
      > > > Hi
      > > >
      > > > Try creating a pointer for $hdr_buf like you do $str_buf. Most of C
      > > > works with pointers, so I think that may be the key.
      > > >
      > > > my $hdr_buf_ptr = pack( "l l l",
      > > > LVN_COLUMNCLICK, #nmh.hdr.code Code
      > > > $header, #nmh.hdr.hwndFrom hwnd
      > > > 0 #nmh.hdr.idFrom
      > > > );
      > > >
      > > > my $hdr_buf = unpack( "l!", pack( 'P',$hdr_buf_ptr));
      > > >
      > > > my $str_buf_ptr = pack( "l l l l l l l l l",
      > > > $hdr_buf, #nmh.hdr
      > > > -1, #item
      > > > 0, #sub item
      > > > 0, #HDITEM, not relevant for this notification
      > > > 0, #newState
      > > > 0, #oldstate
      > > > 0, #changed
      > > > 0, #action
      > > > 0 #lparam
      > > > );
      > > >
      > > > my $str_buf = unpack( "l!", pack( 'P',$str_buf_ptr));
      > > >
      > > > SendMessage( $keysList, WM_NOTIFY, 0, $str_buf);
      > > >
      > > > Brent
      > > >
      > > > --- In perlguitest@yahoogroups.com, "jonnyroberts1978"
      > > > <jonnyroberts1978@> wrote:
      > > > >
      > > > > Hi
      > > > >
      > > > > Thanks for your reply. I think one of my problems is setting
      up the
      > > > > structure to send to the list box as the first member in the
      > > > > NMLISTVIEW structure is a NMHDR structure, has anyone got any
      ideas
      > > > > how I should structure this in perl, my failed attempt is below.
      > > > >
      > > > > my $hdr_buf = pack( "l l l",
      > > > > LVN_COLUMNCLICK, #nmh.hdr.code Code
      > > > > $header, #nmh.hdr.hwndFrom hwnd
      > > > > 0 #nmh.hdr.idFrom
      > > > > );
      > > > >
      > > > > my $str_buf_ptr = pack( "l l l l l l l l l",
      > > > > $hdr_buf, #nmh.hdr
      > > > > -1, #item
      > > > > 0, #sub item
      > > > > 0, #HDITEM, not relevant for this notification
      > > > > 0, #newState
      > > > > 0, #oldstate
      > > > > 0, #changed
      > > > > 0, #action
      > > > > 0 #lparam
      > > > > );
      > > > >
      > > > > my $str_buf = unpack( "l!", pack( 'P',$str_buf_ptr));
      > > > >
      > > > > SendMessage( $keysList, WM_NOTIFY, 0, $str_buf);
      > > > >
      > > >
      > >
      >
    • Show all 15 messages in this topic