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