Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Win32::API::Struct Question about WINDOWPLACEMENT

Posted on 2004-10-07
5
Medium Priority
?
563 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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 2000 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: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering 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

I've just discovered very important differences between Windows an Unix formats in Perl,at least 5.xx.. MOST IMPORTANT: Use Unix file format while saving Your script. otherwise it will have ^M s or smth likely weird in the EOL, Then DO NOT use m…
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…
Six Sigma Control Plans

688 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