Solved

Win32::API::Struct Question about WINDOWPLACEMENT

Posted on 2004-10-07
5
558 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

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Many time we need to work with multiple files all together. If its windows system then we can use some GUI based editor to accomplish our task. But what if you are on putty or have only CLI(Command Line Interface) as an option to  edit your files. I…
Checking the Alert Log in AWS RDS Oracle can be a pain through their user interface.  I made a script to download the Alert Log, look for errors, and email me the trace files.  In this article I'll describe what I did and share my script.
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…

840 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