Solved

Win32::API::Struct Question about WINDOWPLACEMENT

Posted on 2004-10-07
5
554 Views
Last Modified: 2008-02-01
I am trying to reposition a window using Win32::API.  I believe my struct in this case is malformed but I don't know what is malformed about it -- and the WinAPI just gives me a genertic "The parameter is incorrect.".  Any advise would be great -- thanks.  

--- CODE BELOW ---
use warnings;
use strict;

use Win32;
use Win32::API;
use Win32::API::Struct;

my $FindWindow = new Win32::API('user32', 'FindWindow', 'PP', 'N');
my $SetWindowPlacement = new Win32::API('user32', 'SetWindowPlacement', 'NP', 'N');

Win32::API::Struct->typedef( 'WINDOWPLACEMENT', qw(
      UINT length;
      UINT flags;
      UINT showCmd;
      POINT ptMinPosition;
      POINT ptMaxPosition;
      RECT rcNormalPosition;
));

Win32::API::Struct->typedef( 'POINT', qw(
      LONG x;
      LONG y;
));

Win32::API::Struct->typedef( 'RECT', qw(
      LONG left;
      LONG top;
      LONG right;
      LONG bottom;
));

my $window = $FindWindow->Call("Notepad", 'Untitled - Notepad');

my $UpperLeftPoint = new Win32::API::Struct->new( 'POINT' );
$UpperLeftPoint->{'x'} = 1;
$UpperLeftPoint->{'y'} = 1;

my $WindowSize = new Win32::API::Struct->new( 'RECT' );
$WindowSize->{'left'} = 1;
$WindowSize->{'top'} = 1;
$WindowSize->{'right'} = 1000;
$WindowSize->{'bottom'} = 1000;

my $WindowPlacement = new Win32::API::Struct->new( 'WINDOWPLACEMENT' );
$WindowPlacement->{'flags'} = 0;
$WindowPlacement->{'showCmd'} = 0;
$WindowPlacement->{'ptMinPosition'} = $UpperLeftPoint;
$WindowPlacement->{'ptMaxPosition'} = $UpperLeftPoint;
$WindowPlacement->{'rcNormalPosition'} = $WindowSize;
$WindowPlacement->{'length'} = $WindowPlacement->{'sizeof'};

print "Window: $window\n";
print "SetWindowPlacement: ".$SetWindowPlacement->Call($window, $WindowPlacement)."\n\n";

print "Errors (if any): ".Win32::FormatMessage(Win32::GetLastError());
0
Comment
Question by:rmelton
  • 4
5 Comments
 
LVL 18

Expert Comment

by:kandura
ID: 12261201
Hi rmelton,

I only have time for a couple of notes.
1. FindWindow expects the first argument to be a WindowClass. It so happens that Notepad's class is "Notepad", so that's okay.
2. sizeof is not an attribute of Win32::API::Structs, but a method, so to set the length, you need to do:

    $WindowPlacement->{'length'} = $WindowPlacement->sizeof;

Other than that, I haven't been able to get it to work yet.

HTH,
Kandura
0
 
LVL 18

Expert Comment

by:kandura
ID: 12261736
another quicky (also doesn't fix the problem...)

- you should define the struct WINDOWPLACEMENT *after* you define POINT and RECT, since it depends on those.

(I used Data::Dumper to see that it didn't have proper typedefs for the points and the rect.)
0
 
LVL 18

Accepted Solution

by:
kandura earned 500 total points
ID: 12262394
Got it working!

First of all, the error message at the end is grossly misleading. Don't call it unless SetWindowPlacement returns false.

OK, here's what I changed:
- I moved the struct definitions up towards the start of the script;
- I imported the API's instead of doing Win32::API->new
- your creation of the struct objects was flawed, you called "new struct->new()", but that should of course simply be "struct->new()"

Without much further ado, here is my version:

    use warnings;
    use strict;

    use Data::Dumper;
    use Win32;
    use Win32::API;
    use Win32::API::Struct;

    Win32::API::Struct->typedef( 'POINT' => qw(
         LONG x;
         LONG y;
    ));

    Win32::API::Struct->typedef( 'RECT' => qw(
         LONG left;
         LONG top;
         LONG right;
         LONG bottom;
    ));

    Win32::API::Struct->typedef( 'WINDOWPLACEMENT' => qw(
         UINT length;
         UINT flags;
         UINT showCmd;
         POINT ptMinPosition;
         POINT ptMaxPosition;
         RECT rcNormalPosition;
    ));


    my $FindWindow = new Win32::API('user32', 'FindWindow', 'PP', 'N');

    ### using Import instead of new
    Win32::API->Import('user32', 'INT SetWindowPlacement(HWND hWnd, WINDOWPLACEMENT lpwndplc)');
    Win32::API->Import('user32', 'INT GetWindowPlacement(HWND hWnd, WINDOWPLACEMENT lpwndplc)');

    my $window = $FindWindow->Call("ThunderRT6FormDC", "Perl"); # Quickpost for EE

    my $UpperLeftPoint = Win32::API::Struct->new( 'POINT' );
    $UpperLeftPoint->{'x'} = 1;
    $UpperLeftPoint->{'y'} = 1;

    my $LeftPoint = Win32::API::Struct->new( 'POINT' );
    $LeftPoint->{'x'} = 1;
    $LeftPoint->{'y'} = 1;

    my $WindowSize = Win32::API::Struct->new( 'RECT' );
    $WindowSize->{'left'} = 1;
    $WindowSize->{'top'} = 1;
    $WindowSize->{'right'} = 1000;
    $WindowSize->{'bottom'} = 1000;

    my $WindowPlacement = Win32::API::Struct->new( 'WINDOWPLACEMENT' );
    $WindowPlacement->{'length'} = sizeof $WindowPlacement;

    print "Window: $window\n";

    my $ret = GetWindowPlacement($window, $WindowPlacement);
    print "GetWindowPlacement: $ret\n\n";
    print Dumper($WindowPlacement);
    printf "Errors (if any): [%0x] %s", Win32::GetLastError(), Win32::FormatMessage(Win32::GetLastError()) unless $ret;

    $WindowPlacement->{'flags'} = 0;
    $WindowPlacement->{'showCmd'} = 6;
    $WindowPlacement->{'ptMinPosition'} = $UpperLeftPoint;
    $WindowPlacement->{'ptMaxPosition'} = $LeftPoint;
    $WindowPlacement->{'rcNormalPosition'} = $WindowSize;

    $ret = SetWindowPlacement($window, $WindowPlacement);
    print "SetWindowPlacement: $ret\n\n";
    print Dumper($WindowPlacement);
    printf "Errors (if any): [%0x] %s", Win32::GetLastError(), Win32::FormatMessage(Win32::GetLastError()) unless $ret;
0
 

Author Comment

by:rmelton
ID: 12264103
Thank you very much for taking the time to answer this -- I actually dodged the issue and using SetWindowPos instead, but I am sure this will help others.  Thanks again.
0
 
LVL 18

Expert Comment

by:kandura
ID: 12264186
heh. SetWindowPos makes a lot of sense if you just try to move the window...
at least I hope my post gives you some new insights in how Win32::API works. Pretty neat stuff.
0

Featured Post

What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

Join & Write a Comment

On Microsoft Windows, if  when you click or type the name of a .pl file, you get an error "is not recognized as an internal or external command, operable program or batch file", then this means you do not have the .pl file extension associated with …
I have been pestered over the years to produce and distribute regular data extracts, and often the request have explicitly requested the data be emailed as an Excel attachement; specifically Excel, as it appears: CSV files confuse (no Red or Green h…
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
This video discusses moving either the default database or any database to a new volume.

705 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now