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

1714Re: List View header control

Expand Messages
  • jonnyroberts1978
    Mar 6, 2007
      Looking at this link:

      http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/commctls/common/messages/wm_notify.asp

      it states "For Windows 2000 and later systems, the WM_NOTIFY message
      cannot be sent between processes".

      --- In perlguitest@yahoogroups.com, "brentje" <brentje@...> wrote:
      >
      > PostMessage crashes things, eh? I haven't tried it before since I
      > thought the only difference would be that it doesn't return anything.
      > But I just tried it now and got a notify message to the ListView
      > object. This is good. This gives me hope. I'll play around with
      > that today.
      >
      > Oh...and I just realised, I don't think the workaround even needs to
      > deal with the header. Just do the GetWindowRect on the ListView
      > itself and that should work.
      >
      > Brent
      >
      > --- In perlguitest@yahoogroups.com, "jonnyroberts1978"
      > <jonnyroberts1978@> wrote:
      > >
      > > Thankyou very much for your help I will go with your work around for
      > now.
      > >
      > > It is strange that the PostMessage seems to cause a crash but the
      > > SendMessage doesn't do anything.
      > >
      > > I hadn't come across win spector before it looks like a very usefull
      > tool!
      > >
      > > Regards
      > > Jon
      > >
      > > --- In perlguitest@yahoogroups.com, "brentje" <brentje@> wrote:
      > > >
      > > > 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