[EMAIL PROTECTED] wrote:

Robert,

Square window is okay with me.

OK, I need to apologise to Jeremy. It appears that balloon tooltips are (partially) supported already - this must have been there for a long time, but it's the first time I looked at this part of the code. There's a missing method to set the balloon title and icon, but that can be worked around:

#!perl -w
use strict;
use warnings;

use Win32::GUI();

# Win32::GUI::Constants (v1.04 only) does not include
# Tootip constants TTF_* and TTM_*
sub TTM_SETTITLE() {1056}

my $mw = Win32::GUI::Window->new(
        -title => "Balloon Tooltips",
        -size  => [400,300],
);

# BUG1: There's no AddTooltip() method
my $tt = Win32::GUI::Tooltip->new(
        -parent  => $mw,
        -balloon => 1,  # undocumented -balloon option!
);

# BUG2: No SetTitle() method to set the balloon title
# and icon.  Work around, use SendMessage instead:
# WPARAM: 0 - no icon
#         1 - Info Icon
#         2 - Warning Icon
#         3 - Error Icon
# LPARAM: title string
# note that title and icon are per tooltip window, and
# not per tool
$tt->SendMessage(TTM_SETTITLE, 1, "Balloon Tooltip Title");

$tt->AddTool(
    -window => $mw,
    -text => "Balloon tooltip body text",
    -subclass => 1,  # Should subclass be on by default?
);

$mw->Show();
Win32::GUI::Dialog();
$mw->Hide();
exit(0);
__END__

> Is there a way to have it popup when you
move the mouse over a specific item in a listview (not just the row or column). Clicking on it would be okay also, probably would work better if you click so you don't have windows popping up every time you move the mouse.

On trying to put an example together to do this I've found a bug with setting tools to be regions of windows, rather than whole windows. The following should work to pop up balloons as you hover over each item, but doesn't:

#!perl -w
use strict;
use warnings;

use Win32::GUI();

my $NUM_ITEMS = 4;

my $mw = Win32::GUI::Window->new(
        -title => "Listview Tooltips",
        -size  => [400,300],
);

$mw->AddListView(
    -name   => "LV",
    -width  => $mw->ScaleWidth(),
    -height => $mw->ScaleHeight(),
);
$mw->LV->InsertColumn( -text => "Column1", -width => 100);

my $tt = Win32::GUI::Tooltip->new(
        -parent  => $mw,
        -balloon => 1,
);

for my $i (1..$NUM_ITEMS) {
    $mw->LV->InsertItem(
        -text  => "Item $i",
    );

    my ($l,$t,$r,$b) = $mw->LV->GetItemRect($i-1);

        $tt->AddTool(
        -id => $i,
        -hwnd => $mw->LV,
                -text => "Item $i tooltip",
                -rect => [$l, $t, $r, $b],
                -subclass => 1,
        );
}


$mw->Show();
Win32::GUI::Dialog();
$mw->Hide();
exit(0);
__END__

So here's an alternative using your 'click' proposal that does work. There's lots of problems with the Tooltip method implementations (enough that I'm not going to look at it now), but this code shows how to work around it. Personally, having seen it, I don't like the 'click to see tip' behaviour, but there should be enough here for you to alter it to display during the mousemove event if that's what you want.

#!perl -w
use strict;
use warnings;

use Win32::GUI();

sub LVHT_ONITEMLABEL()  {4}
sub TTF_IDISHWND()      {1}
sub TTM_TRACKACTIVATE() {1041}
sub TTM_UPDATETIPTEXT() {1036}

my $NUM_ITEMS = 4;
my $tip_showing = undef;

my $mw = Win32::GUI::Window->new(
    -title => "Listview Tooltips",
    -size  => [400,300],
);

$mw->AddListView(
    -name   => "LV",
    -width  => $mw->ScaleWidth(),
    -height => $mw->ScaleHeight(),
    -onMouseDown => \&showTip,
    -onMouseMove => \&hideTip,
);
$mw->LV->InsertColumn( -text => "Column1", -width => 100);

my $tt = Win32::GUI::Tooltip->new(
    -parent  => $mw,
    -balloon => 1,
);

for my $i (1..$NUM_ITEMS) {
    $mw->LV->InsertItem(
        -text  => "Item $i",
    );
}

$tt->AddTool(
    -window => $mw->LV,
    -track => 1,
    -absolute => 1,
    -text => "Body text",
);

$mw->Show();
Win32::GUI::Dialog();
$mw->Hide();
undef $tt;
undef $mw;
exit(0);

# If we clicked on an item, update the tool text,
# position the tooltip window, and show the tool.
sub showTip
{
    my ($lv, $cx, $cy) = @_;
    my ($item, $where) = $lv->HitTest($cx,$cy);

    # see if we clicked on an item label
    if ($where & LVHT_ONITEMLABEL) {
        # Note which item we're showing
        $tip_showing = $item;

        # Change the text to what we want.
        # BUG: UpdateTipText only works with regions, not windows,
        # so roll our own
        my $text = "Tip body for item " . ($item+1);
        my $toolinfo1 = pack( "LLLLLLLLLpL",
            44,              # cbSize
            TTF_IDISHWND,    # uFlags
            $mw->{-handle},  # hwnd
            $lv->{-handle},  # uId
            0, 0, 0, 0, 0,
            $text,           # lpszText
            0);
        $tt->SendMessage(TTM_UPDATETIPTEXT, 0, $toolinfo1);

        # convert client co-ordinates to screen
        my($sx, $sy) = $lv->ClientToScreen($cx, $cy);
        # .. and set the tooltip position
        $tt->TrackPosition($sx,$sy);

        # activate the tool
        # BUG: trackactivate only works with regions, not windows,
        # so roll owr own
        my $toolinfo2 = pack( "LLLLLLLLLLL",
            44,              # cbSize
            TTF_IDISHWND,    # uFlags
            $mw->{-handle},  # hwnd
            $lv->{-handle},  # uId
            0, 0, 0, 0, 0, 0, 0);
        $tt->SendMessage(TTM_TRACKACTIVATE, 1, $toolinfo2);
    }

    return 1; # allow message to be
              # passed on for deafult processing
}

# If the mouse moves off an item, hide the tooltip
sub hideTip {
    my ($lv, $cx, $cy) = @_;
    my $item = $lv->HitTest($cx,$cy);

    # if we're showing a tip, and now we're not
    # over it, hide it
    if(defined $tip_showing and $tip_showing != $item) {
        # de-activate the tool
        # BUG: trackactivate only works with regions, not windows,
        # so roll owr own
        my $toolinfo = pack( "LLLLLLLLLLL",
            44,              # cbSize
            TTF_IDISHWND,    # uFlags
            $mw->{-handle},  # hwnd
            $lv->{-handle},  # uId
            0, 0, 0, 0, 0, 0, 0);
        $tt->SendMessage(TTM_TRACKACTIVATE, 0, $toolinfo);

        # and we're not showing a tip any more
        $tip_showing = undef;
    }

    return 1; # allow message to be
              # passed on for deafult processing
}
__END__

Enjoy!
Regards,
Rob.
--
Robert May
Win32::GUI, a perl extension for native Win32 applications
http://perl-win32-gui.sourceforge.net/


Reply via email to