Sign in to follow this  
Followers 0
fisofo

Winmove doesn't change window state

12 posts in this topic

Just curious if there is a way to tell a window it is no longer maximized after moving it? What I mean is, if you perform a winmove on a window that is maximized and then read it's state (wingetstate), it will still list as being maximized.

I know i could run a winsetstate to @SW_RESTORE right before my winmove, but then the window jumps around. Any other way of setting the state to not maximized without changing the windows position more than once?

Thanks!

Share this post


Link to post
Share on other sites



Moving a window by code is not an user operation. Windows prevents users from moving maximized windows. Windows does not stop the modifying of a RECT.

You have to do it yourself. You could set the size and location of the window to fit the screen before moving it, then it doesn't jump.

Share this post


Link to post
Share on other sites

Moving a window by code is not an user operation. Windows prevents users from moving maximized windows. Windows does not stop the modifying of a RECT.

You have to do it yourself. You could set the size and location of the window to fit the screen before moving it, then it doesn't jump.

well that sucks...

I did just find This MSDN Page, so I'll try that and post how it works, but otherwise.... well, bummer.

Share this post


Link to post
Share on other sites

you're right it doesn't do jack when the state is set to maximized :P

Share this post


Link to post
Share on other sites

I found another page, but I'm having a little trouble implementing it, could someone possibly give me some pointers?

http://msdn2.microsoft.com/en-us/library/ms632611.aspx

$SWP_NOZORDER           = 0x0004
$SW_SHOWNA              = 8
$SW_RESTORE             = 9
$WPF_RESTORETOMAXIMIZED = 0x0002

Func _NewWinMove($hWindow, $xPos, $yPos, $Width, $Height)
    $state = WinGetState($hWindow)
    If Not BitAND($state, 32) Then
        WinMove($hWindow, "", $xPos, $yPos, $Width, $Height)
    Else
        $ptMinPosition = DllStructCreate("long;long")
        DllStructSetData($ptMinPosition, 1, 0)
        DllStructSetData($ptMinPosition, 2, 0)
        
        $ptMaxPosition = DllStructCreate("long;long")
        DllStructSetData($ptMaxPosition, 1, 0)
        DllStructSetData($ptMaxPosition, 2, 0)
        
        $rcNormalPosition = DllStructCreate("long;long;long;long")
        DllStructSetData($rcNormalPosition, 1, $xPos)
        DllStructSetData($rcNormalPosition, 2, $yPos)
        DllStructSetData($rcNormalPosition, 3, $Width)
        DllStructSetData($rcNormalPosition, 4, $Height)
        
        $WINDOWPLACEMENT = DllStructCreate("uint;uint;uint;ptr;ptr;ptr")
        DllStructSetData($WINDOWPLACEMENT, 1, 0)
        DllStructSetData($WINDOWPLACEMENT, 2, $WPF_RESTORETOMAXIMIZED)
        DllStructSetData($WINDOWPLACEMENT, 3, $SW_RESTORE) ;$SW_RESTORE, $SW_SHOWNA
        DllStructSetData($WINDOWPLACEMENT, 4, $ptMinPosition)
        DllStructSetData($WINDOWPLACEMENT, 5, $ptMaxPosition)
        DllStructSetData($WINDOWPLACEMENT, 6, $rcNormalPosition)
        DllStructSetData($WINDOWPLACEMENT, 1, DllStructGetSize($WINDOWPLACEMENT))
        
        DllCall("user32.dll", "int", "SetWindowPlacement", "hwnd", $hWindow, "ptr", $WINDOWPLACEMENT)
        If @error <> 0 Then
            MsgBox(0,"","problem")
        EndIf
        $ptMinPosition = 0
        $ptMaxPosition = 0
        $rcNormalPosition = 0
        $WINDOWPLACEMENT = 0
        WinSetState($hWindow, "", @SW_RESTORE)
    EndIf
    #cs
        typedef struct tagPOINT {
        LONG x;
        LONG y;
        } POINT, *PPOINT;
        
        typedef struct _RECT {
        LONG left;    Specifies the x-coordinate of the upper-left corner of the rectangle.
        LONG top;     Specifies the y-coordinate of the upper-left corner of the rectangle.
        LONG right;   Specifies the x-coordinate of the lower-right corner of the rectangle.
        LONG bottom;  Specifies the y-coordinate of the lower-right corner of the rectangle.
        } RECT, *PRECT;
        
        typedef struct _WINDOWPLACEMENT {
        UINT length;             sizeof(WINDOWPLACEMENT)
        UINT flags;              0
        UINT showCmd;            SW_SHOWNA
        POINT ptMinPosition;
        POINT ptMaxPosition;
        RECT rcNormalPosition;
        } WINDOWPLACEMENT;
        
        BOOL SetWindowPlacement(          HWND hWnd,
        WINDOWPLACEMENT *lpwndpl
        );
        
    #ce
EndFunc

I've checked all the DLL lines and none of them give me an error, but they also don't seem to actually do anything. I was hoping I could define the "Restore" position using this DLL, and then call the restore function to "move" it to where I want it to go. Right now it just restores to wherever the window was, not to where I define it to go.

Any ideas?

Share this post


Link to post
Share on other sites

bumpity bump.

I don't know much about this SetWindowPlacement DLL call, could anyone help me out? I'm still pretty new to the DLL stuff as it is, it took me quite a bit just to get the code i posted so far :P

Anyway, I'll keep searching, was just hoping someone might be able to enlighten me.

Share this post


Link to post
Share on other sites

Okay, how about this. I found this page and changed my code to try to match it:

Func _NewWinMove($hWindow, $xPos, $yPos, $Width, $Height)
    $state = WinGetState($hWindow)
    If Not BitAND($state, 32) Then
        WinMove($hWindow, "", $xPos, $yPos, $Width, $Height)
    Else
        $ptMinPosition = DllStructCreate("long;long")       
        $ptMaxPosition = DllStructCreate("long;long")
        $rcNormalPosition = DllStructCreate("long;long;long;long")
        DllStructSetData($rcNormalPosition, 1, $xPos)
        DllStructSetData($rcNormalPosition, 2, $yPos)
        DllStructSetData($rcNormalPosition, 3, $Width)
        DllStructSetData($rcNormalPosition, 4, $Height)
        
        $WINDOWPLACEMENT = DllStructCreate("uint;uint;uint;ptr;ptr;ptr")
        DllStructSetData($WINDOWPLACEMENT, 1, DllStructGetSize($WINDOWPLACEMENT))
        DllStructSetData($WINDOWPLACEMENT, 2, 0)
        DllStructSetData($WINDOWPLACEMENT, 3, $SW_SHOWNORMAL) ;$SW_RESTORE, $SW_SHOWNA
        DllStructSetData($WINDOWPLACEMENT, 6, $rcNormalPosition)
        
        DllCall("user32.dll", "int", "SetWindowPlacement", "hwnd", $hWindow, "ptr", $WINDOWPLACEMENT)
        If @error <> 0 Then
            MsgBox(0,"","problem")
        EndIf
        $ptMinPosition = 0
        $ptMaxPosition = 0
        $rcNormalPosition = 0
        $WINDOWPLACEMENT = 0
        WinSetState($hWindow, "", @SW_RESTORE)
    EndIf
EndFunc

But of course, it still doesn't take. Can anyone interpret that MS example page? It supposedly does exactly what I want...

Share this post


Link to post
Share on other sites

Update, more small changes:

$rcNormalPosition = DllStructCreate("long;long;long;long")
        DllStructSetData($rcNormalPosition, 1, $xPos)
        DllStructSetData($rcNormalPosition, 2, $yPos)
        DllStructSetData($rcNormalPosition, 3, $Width)
        DllStructSetData($rcNormalPosition, 4, $Height)
        
        $WINDOWPLACEMENT = DllStructCreate("uint;uint;uint;ptr;ptr;ptr")
        DllStructSetData($WINDOWPLACEMENT, 2, 0)
        DllStructSetData($WINDOWPLACEMENT, 3, $SW_RESTORE) ;$SW_RESTORE, $SW_SHOWNA
        DllStructSetData($WINDOWPLACEMENT, 6, $rcNormalPosition)
        DllStructSetData($WINDOWPLACEMENT, 1, DllStructGetSize($WINDOWPLACEMENT))
        
                DllCall("user32.dll", "int", "SetWindowPlacement", "hwnd", $hWindow, "ptr", DllStructGetPtr($WINDOWPLACEMENT))

I had forgotten the DllStructGetPtr. Still doesn't work though and i'm getting really tired... :D:P

I've tried another verification method, mainly by using the GetWindowPlacement, but I can't seem to figure out how to get an element that is in a Struct which is ALSO within a struct (aka the position values in $rcNormalPosition). Could someone at least help me get that working? That would probably ponit me in the right direction for the rest of it.

It also occurred to me that I shouldn't need { WinSetState($hWindow, "", @SW_RESTORE) } after the DLL call because the DLL should perform the move itself (i think). But yeah, I could really use some help here. It's 2:15am, i'll check back in after some sleep...

Share this post


Link to post
Share on other sites

#9 ·  Posted (edited)

SUCCESS!!!

For anyone else interested in how to do it, i've posted the script I was writing over here.

happy coding!

edit: stupid stupid stupid! I had a second script running that was doing what I wanted, except not... anyway, it does not actually work yet, i'll post again when it does. DOH!

Edited by fisofo

Share this post


Link to post
Share on other sites

Here is my most recent iteration of this thing, still no dice though in getting it to work:

$SW_RESTORE = 9

Func _NewWinMove($hWindow, $xPos, $yPos, $Width, $Height)
    $state = WinGetState($hWindow)
    If Not BitAND($state, 32) Then
        WinMove($hWindow, "", $xPos, $yPos, $Width, $Height)
    Else
        $rcNormalPosition = DllStructCreate("long;long;long;long")
        DllStructSetData($rcNormalPosition, 1, $xPos)
        DllStructSetData($rcNormalPosition, 2, $yPos)
        DllStructSetData($rcNormalPosition, 3, $Width)
        DllStructSetData($rcNormalPosition, 4, $Height)
        
        $WINDOWPLACEMENT = DllStructCreate("uint;uint;uint;ptr;ptr;ptr")
        DllStructSetData($WINDOWPLACEMENT, 2, 0)
        DllStructSetData($WINDOWPLACEMENT, 3, @SW_RESTORE) ;or $SW_RESTORE as defined above
        DllStructSetData($WINDOWPLACEMENT, 6, DllStructGetPtr($rcNormalPosition))
        DllStructSetData($WINDOWPLACEMENT, 1, DllStructGetSize($WINDOWPLACEMENT))
        
        DllCall("user32.dll", "int", "SetWindowPlacement", "hwnd", $hWindow, "ptr", DllStructGetPtr($WINDOWPLACEMENT))

        $rcNormalPosition = 0
        $WINDOWPLACEMENT = 0
    EndIf
EndFunc

I'm honestly out of ideas on this and could really use some help from someone who knows DllCall's... or better yet, someone who knows DllCalls and who has used SetWindowPlacement :P

Or perhaps someone could help me interpret one of these examples: VBnet example, MFC / C++ Example

Share this post


Link to post
Share on other sites

#11 ·  Posted (edited)

I'd really like to get this to work, anyone have input into the above code?

edit: an entire topic filled entirely with my posts... I guess I'll have to let this die. that sucks. :P

Edited by fisofo

Share this post


Link to post
Share on other sites

I'd really like to get this to work, anyone have input into the above code?

edit: an entire topic filled entirely with my posts... I guess I'll have to let this die. that sucks. :)

Reviving this old topic just to point out that _WinAPI_SetWindowPos() in the current WinAPI.au3 UDF handles setting the current window pos. There is now a working function for _WinAPI_GetWindowPlacement() to retrieve stored positions, and hopefully _WinAPI_SetWindowPlacement() will be coming soon.

:)


Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0