Hi,
The code below shows an example of using a child window containing a bitmap
which is scrolled using the scroll bars of the child window. The example uses a
hooked paint message to pain directly to the child window via a memory DC.
Assuming there is no problem with this example and people think it's useful
I'll commit it to the samples folder today.
Cheers,
jez.
==================
#This example creates a scrolling bitmap within another window. This example
uses
#a hooked event to paint to the window directly, rather than using a Graphic
#Control.
use Win32::GUI;
use strict;
#create a new class which stops the WM_ERASEBKGND message from erasing the
background
my $WC = new Win32::GUI::Class(
-name => "NoFlicker",
-style => 0,
);
#Create the window and child controls.
my $mainwin = new Win32::GUI::Window (
-pos => [100, 100],
-size => [330, 235],
-name => "Window",
-text => "Bitmap Scroll demo",
-pushstyle => WS_CLIPCHILDREN,
-class => $WC,
#NEM Events for this window
-onResize => \&Resize,
-onTerminate => sub {return -1;}
);
$mainwin->AddButton (
-name => 'Open',
-pos => [205, 20],
-size => [110, 20],
-text => 'Open Bitmap',
-onClick => \&OpenBitmap,
);
#Create a child window with a scroll bars.
my $ChildWin = new Win32::GUI::Window (
-parent => $mainwin,
-name => "ChildWin",
-pos => [0, 0],
-size => [200, 200],
-popstyle => WS_CAPTION | WS_SIZEBOX,
-pushstyle => WS_CHILD | WS_CLIPCHILDREN,
-pushexstyle => WS_EX_CLIENTEDGE,
-class => $WC,
-hscroll => 1,
-vscroll => 1,
-onScroll => \&Scroll,
);
#hook into the paint event of the child window
$ChildWin->Hook(15, \&Paint);
#Create a memory DC compatible with the child window DC
my $memdc=$ChildWin->GetDC->CreateCompatibleDC();
#Define global variables
my $bitmap; #will hold the bitmap
#show both windows and enter the Dialog phase.
$mainwin->Show();
$ChildWin->Show();
Win32::GUI::Dialog();
sub Paint {
#Paint event handler, called when ever the window needs to be redrawn/painted
return unless $bitmap;
#tell windows that we are starting to paint
$ChildWin->BeginPaint;
#get the DC of the child window
my $dc=$ChildWin->GetDC;
#Performa a bit block transfer of the memory DC into the child window DC
#The cordinates are based upon the possition of the scroll bars
$dc->BitBlt(0, 0,
$ChildWin->Width,$ChildWin->Height,$memdc,$ChildWin->ScrollPos(0),$ChildWin->ScrollPos(1));
#tell windows that we have finished painting.
$ChildWin->EndPaint;
}
sub Resize {
#Resize handler
my ($width, $height) = ($mainwin->GetClientRect)[2..3];
$mainwin->Open->Left($width-120);
#Resize the child window and set the scroll bar page of each scroll bar.
#This has the effect of increasing/decreasing the size of the bar within the
scroll bar
#as the window is resized.
$ChildWin->Resize($width-150,$height);
$ChildWin->ScrollPage(0,$ChildWin->Width);
$ChildWin->ScrollPage(1,$ChildWin->Height);
}
sub OpenBitmap {
#Function to load in the bitmap
my $file = Win32::GUI::GetOpenFileName(
-owner => $mainwin,
-hidereadonly => 0,
-title => "Open an bitmap file",
-filter => ['Bitmaps' => '*.bmp',
'All files' => '*.*',
],
);
$bitmap=new Win32::GUI::Bitmap($file);
if ($bitmap) {
#if we have a valid bitmap, get the dimentions
my ($width,$height)=$bitmap->Info();
#select the bitmap into the memory DC so it can be maniplated later.
$memdc->SelectObject($bitmap);
#set the scroll bar range and position based upon the height and width of
the bitmap.
$ChildWin->ScrollRange(1,0,$height+20); #add 20 for the scroll bar
$ChildWin->ScrollRange(0,0,$width+20);
$ChildWin->ScrollPage(0,$ChildWin->Width);
$ChildWin->ScrollPage(1,$ChildWin->Height);
#set the scroll bars to 0.
$ChildWin->ScrollPos(0,0);
$ChildWin->ScrollPos(1,0);
$ChildWin->InvalidateRect(0); #invalidate the child window so windows
triggers the paint event
}
}
sub Scroll {
#Scroll event handler. We have to explicitly "move" the scroll bars.
#Once they have been moved, we repaint the window.
my($win,$scrollbar, $operation, $position) = @_;
if($operation == SB_THUMBTRACK) {
$win->ScrollPos($scrollbar,$position);
}
elsif($operation == SB_LINEDOWN) {
$win->ScrollPos($scrollbar,$win->ScrollPos($scrollbar)+1);
}
elsif($operation == SB_LINEUP) {
$win->ScrollPos($scrollbar,$win->ScrollPos($scrollbar)-1);
}
elsif($operation == SB_PAGEDOWN) {
$win->ScrollPos($scrollbar,$win->ScrollPos($scrollbar) +
$win->ScrollPage($scrollbar));
}
elsif($operation == SB_PAGEUP) {
$win->ScrollPos($scrollbar,$win->ScrollPos($scrollbar) -
$win->ScrollPage($scrollbar));
}
#invalidate the child window so windows triggers the paint event
$win->InvalidateRect(0);
}