Hi,

I'm trying to implement the StretchBlt function using a call to gdi32.dll in order to fill the window with the image.

here, I load the dll
my $ApiObj = new Win32::API ("gdi32", "StretchBlt", "PIIIIPIIIIN", "I");

Here, I call the StretchBlt
$ApiObj->Call($dc, 0, 0, $ww, $wh, $memDC, $bmw, $bmh, 13369376);
instead of this funtion
  # copy the image from the memory DC to the window's DC
  #$dc->BitBlt($l, $t, $bmw, $bmh, $memDC, 0, 0);

Any Idea about what is wrong?
I'll appreciate your help

best regards



#!perl -w
#
#  MDI sample
#

use strict;
use warnings;

use Win32::API;
use Win32::GUI;
use Win32::GUI::BitmapInline();

# My child counter for unique name.
my $ChildCount = 0;

my $Window;


my $ApiObj = new Win32::API ("gdi32", "StretchBlt", "PIIIIPIIIIN", "I");


# Load our bitmap
#my $bm = Win32::GUI::Bitmap->new("sail.bmp") or die "Creating Bitmap";
my $bm = get_bitmap();
# Store the width and height, as we'll use them a lot
my($bmw, $bmh) = ($bm->Info())[0..1];

# create a class without a background brush: this prevents
# defFrameWindowProc erasing the window background, as we want to
# paint it ourselves to avoid flicker
my $class = Win32::GUI::Class->new(
  -name => 'noflicker',
  -brush => 0,
  -widget => "MDIFrame",   # use the MDIFrame windowproc
);


# Create Main menu.
my $Menu = Win32::GUI::MakeMenu(
  "&File"         => "File",
  "   > &New"     => { -name => "File_New",  -onClick => \&NewChild },
  "   > -"        => 0,
  "   > E&xit"    => { -name => "File_Exit", -onClick => sub { -1; } },
  "&Window"       => "Window",
" > &Next" => { -name => "Next", -onClick => sub { $Window->{Client}->Next; } }, " > &Previous"=> { -name => "Prev", -onClick => sub { $Window->{Client}->Previous; } },
  "   > -"        => 0,
" > &Cascade" => { -name => "Cascade", -onClick => sub { $Window->{Client}->Cascade(); 0; } }, " > Tile &Horizontally" => { -name => "TileH", -onClick => sub { $Window->{Client}->Tile(1); } }, " > Tile &Vertically" => { -name => "TileV", -onClick => sub { $Window->{Client}->Tile(0); } },
  "&Help"         => "Help",
  "   > &About"   => { -name => "About", -onClick => sub { 1; } },
);

# First we create an MDIFrame window.
$Window = new Win32::GUI::MDIFrame (
  -title  => "Win32::GUI MDI Sample",
  -left   => 100,
  -top    => 100,
  -width  => 280,
  -height => 280,
  -name   => "Window",
  -menu   => $Menu,
  -class => $class,
-popstyle => WS_CLIPCHILDREN, # So that the MDIClient's window is not clipped
  -onPaint => \&paint,
  -onTerminate => sub {print "Terminate\n"; -1},   ) or die "Window";

# We add an MDIClient window, This window manage Child Window.
$Window->AddMDIClient(
    -name       => "Client",
-firstchild => 100, # Define Child ID for menu item -windowmenu => $Menu->{Window}->{-handle}, # Define Menu Handle where Add Window Child name
) or die "Client";


# Create a memory DC, compatible with our window's
# DC, containing our bitmap.  Do this once, here, to speed
# up the painting routine.  Use a local block, so that $dc
# goes out of scope, and $dc gets released (could call
# $dc->ReleaseDC() instead).
my $memDC;
{
  my $dc = $Window->GetDC();
  $memDC = $dc->CreateCompatibleDC();
  $memDC->SelectObject($bm);
}

# We need a brush to paint the window background
# with, select a grey one.  We don't need to worry
# about freeing stock objects when we're done with them
my $bkBrush = Win32::GUI::GetStockObject(1);


# Show main window and go to event loop
$Window->Show;
Win32::GUI::Dialog();

# We've got some closures on $Window in the
# functions below, which appear to be the cause of
# a 'Can't call Delete .. in global clean up' warning,
# udefining $Window here stops that.
undef $Window;
exit(0);

# Our window painting routine.  To avoid flicker we will
# paint the whole of the window, taking care not to draw any
# pixel more than once.
sub paint
{
  print "Painting...\n";
  my($window, $dc) = @_;

  # I will add StretchBlt to the next release so that we can stretch the
  # image to fit the window, but it's not there right now.
#$dc->StretchBlt(0, 0, ($window->GetClientRect())[2..3], $memDC, 0, 0, $bmw, $bmh);

  # clip each of the MDIChild windows, to avoid us drawing over them
  # and so removing flicker
  # $clip_rgn is the rgion into which we can draw, initialise
  # it to the client window
my $clip_rgn = Win32::GUI::Region->CreateRectRgn($window->GetClientRect());
  while (my ($name, $value) = each %{$window->{Client}}) {
   next unless $name =~ /^Child\d+/;
   my($l, $t, $r, $b) = $value->GetWindowRect();
   # $child_rgn is the MDI child's region in our window's client
   # co-ordinates
   my $child_rgn = Win32::GUI::Region->CreateRectRgn(
       $Window->ScreenToClient($l, $t), $Window->ScreenToClient($r, $b));
   # remove $child_rgn from the area we can draw
   $clip_rgn->CombineRgn($clip_rgn, $child_rgn, 4);
  }
  # selct the clip region into our DC.
  $dc->SelectClipRgn($clip_rgn) if $clip_rgn;

  #calculate the image position to center it in the window
  my ($ww, $wh) = ($window->GetClientRect())[2..3];

  my $l = ($ww - $bmw)/2;
  my $t = ($wh - $bmh)/2;
  my $r = $l + $bmw;
  my $b = $t + $bmh;

  # copy the image from the memory DC to the window's DC
  #$dc->BitBlt($l, $t, $bmw, $bmh, $memDC, 0, 0);

   #BOOL StretchBlt(
   #  HDC hdcDest,      // handle to destination DC
   #  int nXOriginDest, // x-coord of destination upper-left corner
   #  int nYOriginDest, // y-coord of destination upper-left corner
   #  int nWidthDest,   // width of destination rectangle
   #  int nHeightDest,  // height of destination rectangle
   #  HDC hdcSrc,       // handle to source DC
   #  int nXOriginSrc,  // x-coord of source upper-left corner
   #  int nYOriginSrc,  // y-coord of source upper-left corner
   #  int nWidthSrc,    // width of source rectangle
   #  int nHeightSrc,   // height of source rectangle
   #  DWORD dwRop       // raster operation code
   #);
# StretchBlt( hPrinter, 1000, 1000, width*3, height*3, hCompatibleDC, 0, 0, width, height, SRCCOPY ); #define SRCCOPY (DWORD)0x00CC0020 /* dest = source */ $ApiObj->Call($dc, 0, 0, $ww, $wh, $memDC, $bmw, $bmh, 13369376);
  # fill the spaces around the image with our background brush.
  # We should probably not draw when it is not necessary (i.e. when
  # the image meets the side(s), but we can get away with not checking,
  # as the DC is always clipped to the window's client rect.
  #$dc->FillRect(0,  0,  $ww, $t,  $bkBrush);
  #$dc->FillRect(0,  $b, $ww, $wh, $bkBrush);
  #$dc->FillRect(0,  $t, $l,  $b,  $bkBrush);
  #$dc->FillRect($r, $t, $ww, $b,  $bkBrush);

# We've drawn the background, so inform windows that there is nothing left
  # to draw.
  $dc->Validate();

  # we've processed the message, so return 0.
  return 0;
}


# This function create a new child window.
sub NewChild {
Win32::GUI::MessageBox($Window,"NewChild", "Some Title",&MB_OK|&MB_ICONWARNING|&MB_TASKMODAL); # Create a child window.
  my $Child = $Window->{Client}->AddMDIChild (
    -name         => "Child".$ChildCount++,
    -onActivate   => sub { print "Activate\n"; },
    -onDeactivate => sub { print "Deactivate\n"; },
-onTerminate => sub { $Window->InvalidateRect(0); print "Terminate\n";},
    -onResize => \&ChildSize,
  ) or die "Child";

  $Child->Hook(WM_MOVE, sub { $Window->InvalidateRect(0); return 1;});

  # Add a text filed into child window.
  $Child->AddTextfield (
      -name => "Edit",
      -multiline => 1,
      -pos => [0,0],
      -size => [100,100],        );

  # Force a resize.
  ChildSize($Child);
}

# This function manage child window resize.
sub ChildSize {
   my $self = shift;
my $handle = $self->{-handle} || 0; my ($width, $height) = ($self->GetClientRect())[2..3] if $handle; # TextField take all client aera
   $self->{Edit}->Resize($width, $height) if exists $self->{Edit};
}

sub get_bitmap
{
return Win32::GUI::BitmapInline->new(
[bitmap data removed to save size]
);
}



Reply via email to