sub HDI_WIDTH {0x1} sub HDI_FORMAT {0x4} sub HDF_SORTUP {0x400} sub HDF_SORTDOWN {0x200} sub HDM_FIRST {0x1200} sub HDM_GETITEM {&HDM_FIRST+11} sub HDM_SETITEM {&HDM_FIRST+12} sub HDF_LEFT {0x0} sub HDF_RIGHT {0x1} sub HDF_CENTER {0x2} sub HDF_STRING {0x4000} # loop over columns, setting the arrow on the clicked column # and removing it from the others for (0 .. scalar $myListView->GetColumnOrderArray()){ my $arrowstate = ($_ == $columnclicked) # $columnclicked courtesy of ColumnClick event handler ? $state # $state can be 'asc' or 'desc' (or something alike) : 'unset'; # and 'unset' setSortArrow($myListView, $_, $arrowstate); } sub setSortArrow { my ($listview, $column, $state) = @_; # request information on the format and the width of the column header my $hditem = pack("L11", HDI_FORMAT | HDI_WIDTH, # mask 0, # cxy 0, # pszText 0, # hbm 0, # cchTextMax 0, # fmt 0, # lParam 0, # iImage 0, # iOrder 0, # type 0 # pvFilter ); my $ptr = pack('P44', $hditem); my $hwnd = $listview->GetHeader(); my $r = Win32::GUI::SendMessage($hwnd, HDM_GETITEM, $column, unpack('L!', $ptr)); return unless $r; my @members = unpack('L11', $hditem); # cxy and fmt now updated by call to HDM_GETITEM my $width = $members[1]; my $cxy = 0; my $fmt = sprintf("%X", $members[5]); my $justf = (($fmt | HDF_RIGHT) eq $fmt) ? HDF_RIGHT : ((($fmt | HDF_CENTER) eq $fmt) ? HDF_CENTER : HDF_LEFT); my $flags = HDF_STRING | $justf; # keep text and its justification unless($state eq 'unset'){ $flags |= ($state eq 'asc') ? HDF_SORTUP : HDF_SORTDOWN; # text on narrow columns will be trunacted with ellipses: adjust width a little # FIXME: "80" is a little arbitrary and repeated sorting will keep very narrow # columns growing until they are 80 pixels wide if((($fmt & HDF_SORTDOWN & HDF_SORTUP) > 0) && ($width < 80)){ $cxy = $width + 5; } } $members[0] = HDI_FORMAT | ($cxy ? HDI_WIDTH : 0x0); $members[1] = $cxy; $members[5] = $flags; $hditem = pack("L11", @members); $ptr = pack('P44', $hditem); $r = Win32::GUI::SendMessage($hwnd, HDM_SETITEM, $column, unpack('L!', $ptr)); }