On approximately 5/17/2004 2:02 AM, came the following characters from
the keyboard of Jez White:

Assuming there is no problem with this example and people think it's useful I'll commit it to the samples folder today.

Well, as long as it isn't committed yet....? Or even if it is, perhaps another go-round would be acceptable. I have read through the code now, and apologies if I say something stupid, because I'm tired and it is bed-time, but perhaps a few extra comments would make the sample even more useful than it already is. I'll throw some in, but they may not be accurate, so please double check me.

Most of my comments are related to my thought that the NEM allows the writing of "generic" functions for particular functionality. I haven't tried any of the stuff I'm suggesting here.... yet....

==================
#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

# Because of this, it is necessary to redraw background explicitly if/when the bitmap changes size, especially if it becomes smaller.

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

# This Paint Hook uses an outer scope reference to the $ChildWin variable, tying it to this specific window. It also used a global $memdc, tying it to that particular bitmap. Factoring out these two items would make the function more generic. Something like

sub Paint {

# Can $ChildWin be derived from the parameters to the hook function?

  return & PaintHelp( $ChildWin, $memdc );
}

sub PaintHelp {
#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;
}

# Again, if the $ChildWin could be derived from the parameters to the Resize event, this function could be generic to any Scrollable window, it would appear.

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

# Three parameters ( $ChildWin, $bitmap, $memdc ) would make this function generic.

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

# This function appears to be generic to any scrollable window. Can the technique shown here to obtain $win be applied to obtain $ChildWin in some of the above functions? (Resize? Paint?)

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

--
Glenn -- http://nevcal.com/
===========================
The best part about procrastination is that you are never bored,
because you have all kinds of things that you should be doing.


Reply via email to