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); }