Christopher Blue Posted November 4, 2004 Share Posted November 4, 2004 (edited) I am trying to run Warcraft 3 in Windowed mode. However it presented two problems:Problem 1. The game window has the standard Windows XP borders and also, it doesn't set itself to my desktop resolution (1024x768). Since the taskbar is larger than 12 pixels, I could not simply increase its size and then move it a little off-screen to compensate although I tried. However, I was told of WinCheat which allowed me to manually remove the Window borders at runtime. While it *does* present a solution to my problem, I am curious is AutoIt could either (a)talk to WinCheat and therefore automate it, or (b)remove the borders itself thus eliminating the need for WinCheat. I was unsuccessful at finding anything about border removal when using the stable AutoIt version but I am curious: Is there a DLL I might call (thanks to the new DLLCall) that would allow me to do what WinCheat does?Problem 2. I have dual monitors and anyone who has played Warcraft 3 knows that it involves alot of mouse scrolling. However, in Windowed mode Warcraft 3 doesn't trap the mouse within it's borders and thus the mouse can fly right outside the game window which is extremely disorienting and basically makes War3 unplayable. I have tried making my own mouse trapping script but it is slow and doesn't work well:expandcollapse popup#cs Algorithm: Get Active Window Find Window Get Window Dimensions Check Mouse Location against window dimensions Move Mouse to closest valid coordinate #ce Opt("WinTitleMatchMode", 3) Opt("MouseCoordMode", 0) Global $window_name = "Warcraft III" Global $shrink = 7 Global $titlebar = 26 Global $rest = 5 Global $hotkey1 = "{F1}" Global $hotkey2 = "{F2}" Global $Paused = 0 Global $window_info = WinGetPos($window_name) HotKeySet($hotkey1, "TogglePause") HotKeySet($hotkey2, "RecalculateWindow") while (1) CheckBoundries() Sleep($rest) WEnd Func CheckBoundries() If (WinActive($window_name)) Then $mouse_info = MouseGetPos() ; Left If ($mouse_info[0] < $shrink) Then MouseMove($shrink + 1, $mouse_info[1], 0) EndIf ; Left-Up If (($mouse_info[0] < $shrink) AND ($mouse_info[1] < $shrink + $titlebar)) Then MouseMove($shrink + 1, $shrink + $titlebar + 1, 0) EndIf ; Up If ($mouse_info[1] < $shrink + $titlebar) Then MouseMove($mouse_info[0], $shrink + $titlebar + 1, 0) EndIf ; Right-Up If (($mouse_info[0] > $window_info[2] - $shrink) AND ($mouse_info[1] < $shrink + $titlebar)) Then MouseMove($window_info[2] - $shrink - 1, $shrink + $titlebar + 1, 0) EndIf ; Right If ($mouse_info[0] > $window_info[2] - $shrink) Then MouseMove($window_info[2] - $shrink - 1, $mouse_info[1], 0) EndIf ; Right-Down If (($mouse_info[0] > $window_info[2] - $shrink) AND ($mouse_info[1] > $window_info[3] - $shrink)) Then MouseMove($window_info[2] - $shrink - 1, $window_info[3] - $shrink - 1, 0) EndIf ; Down If ($mouse_info[1] > $window_info[3] - $shrink) Then MouseMove($mouse_info[0], $window_info[3] - $shrink - 1, 0) EndIf ; Left-Down If (($mouse_info[0] < $shrink) AND ($mouse_info[1] > $window_info[3] - $shrink)) Then MouseMove($shrink + 1, $window_info[3] - $shrink - 1, 0) EndIf EndIf EndFunc Func TogglePause() $Paused = NOT $Paused While $Paused Sleep(100) WEnd EndFunc Func RecalculateWindow() $window_info = WinGetPos($window_name) EndFuncThe mouse is trapped, but it jumps around alot and isn't fully responsive near the screen edges. Is there a way to either improve my script or perhaps, redefine the mouse boundries at a very low-level so Window's traps the mouse instead of my crappy script? Edited November 4, 2004 by Christopher Blue Link to comment Share on other sites More sharing options...
Christopher Blue Posted November 4, 2004 Author Share Posted November 4, 2004 Hm, WinCheat allows you to install it's source code files and it has some DLL's as well! I shall investigate them but it will take me awhile. I am still at a dead-end in regards to the mouse-boundries issue. Link to comment Share on other sites More sharing options...
Administrators Jon Posted November 4, 2004 Administrators Share Posted November 4, 2004 I've just finishing changing the mouse/pixel commands so that in addition to the usual "screen" and "window" modes that are used for coordinate there is a "client" mode that uses coords relative to the window's client area (the bit inside the window frame). Will this make this problem go away? Deployment Blog:Â https://www.autoitconsulting.com/site/blog/ SCCM SDK Programming:Â https://www.autoitconsulting.com/site/sccm-sdk/ Link to comment Share on other sites More sharing options...
Valik Posted November 4, 2004 Share Posted November 4, 2004 to DLLCallsGetWindowLongSetWindowLongI can't remember how to remove styles from the result of GetWindowLong and apply it to SetWindowLong... I will research and try to answer before the more brainy (Valik, Jon) people get to it...Lar.<{POST_SNAPBACK}>Use either BitNOT to remove it, or use BitAND to test to see if it exists and then if so, use BitXOR to remove it. In C, it looks like:style = GetWindowLong(); if (style & StyleIWantToRemove) SetWindowLong(style ^ StyleIWantToRemove)(It should go without saying that the code isn't valid, that its only concept code) Link to comment Share on other sites More sharing options...
Christopher Blue Posted November 4, 2004 Author Share Posted November 4, 2004 Larry: I will start reading about the Windows Classes Reference. Jon: That will help me simplify my code since I don't have to take the Window borders into consideration, but I suspect my code will still be as slow and jumpy as before and thus I am curious as to if there is a low-level solution to setting Mouse Boundries. I mean, if Windows can tell the mouse that 768 is the max Y and 1024 (2048 in my dual monitor situation) is the max X, perhaps there is a way to change those values and thus make the mouse run in a box of the programmer's choosing. It doesn't even have to be that specific for I am merely trying to get it to stay within the area of a client Window (Warcraft III's game screen). Link to comment Share on other sites More sharing options...
Christopher Blue Posted November 4, 2004 Author Share Posted November 4, 2004 I am currently simplfying my mouse bounding script for when the window is bounded on three sides by the screen edges which is the case once I use WinCheat to take away the borders and then reposition the window in the upper left corner of my left-monitor. Since the borders are gone, I can easily resize War3 to 1024x768 using AutoIt. I shall post the simplified mouse trap soon but I still believe it is just a bandaid until I find out something lower level. Link to comment Share on other sites More sharing options...
Christopher Blue Posted November 4, 2004 Author Share Posted November 4, 2004 Sorry Larry, I used WinCheat since I wanted to quickly try my mouse script. I will go try your script right now and let you know what happens. Link to comment Share on other sites More sharing options...
Christopher Blue Posted November 4, 2004 Author Share Posted November 4, 2004 Larry, your script took away WS_BORDER but still left WS_DLGFRAME and WS_THICKFRAME. All 3 must be removed in order to have a truly borderless window, at least according to WinCheat. I am not sure what variables correspond to those in AutoIt 3. Link to comment Share on other sites More sharing options...
Valik Posted November 4, 2004 Share Posted November 4, 2004 (edited) example I wrote... @Valik: My implementation of Bit commands work... is there a simpler syntax?#include <GUIConstants.au3> Global $GWL_STYLE = -16 $hWnd = WinGetHandle("AutoIt Forums") $OldStyle = DLLCall( "user32.dll", "long", "GetWindowLong", "hwnd", $hWnd, "int", $GWL_STYLE ) If @error Then Exit $OldStyle = $OldStyle[0] $NewStyle = BitAND($OldStyle,BitNOT($WS_CAPTION) ) DLLCall( "user32.dll", "long", "SetWindowLong", "hwnd", $hWnd, "int", $GWL_STYLE, "long", $NewStyle ) Sleep(2000) DLLCall( "user32.dll", "long", "SetWindowLong", "hwnd", $hWnd, "int", $GWL_STYLE, "long", $OldStyle ) WinSetState($hWnd,"",@SW_MINIMIZE) WinSetState($hWnd,"",@SW_RESTORE)<{POST_SNAPBACK}>I prefer wrapping DllCall() functions in functions to make them more "natural" (and reusable). As far as the bitwise stuff goes, Shouldn't that be BitOR and not BitAND?Edit: Never mind, BitAND is correct, my brain is frazzled; I've been looking at COM way too much this morning. Is what you have the functional equivalent to:If BitAND($Style, $WS_CAPTION) Then $Style = BitXOR($Style, $WS_CAPTION)Edit2: Ignore me, my brain is taking a nap for a little while. Playing with vectors of pointers and COM does that to me. Edited November 4, 2004 by Valik Link to comment Share on other sites More sharing options...
Christopher Blue Posted November 4, 2004 Author Share Posted November 4, 2004 Absolutely incredible Larry! Your code works perfectly. I have implemented your suggestions and rolled the resulting script into my hide/unhide script: expandcollapse popup#include <GUIConstants.au3> Global $window_name = "Warcraft III" Global $hidden = 0 Global $GWL_STYLE = -16 HotKeySet("^q", "ToggleWindowHide") ;Remove the window borders $hWnd = WinGetHandle($window_name) $OldStyle = DLLCall( "user32.dll", "long", "GetWindowLong", "hwnd", $hWnd, "int", $GWL_STYLE ) If @error Then Exit $OldStyle = $OldStyle[0] $NewStyle = BitAND($OldStyle,BitNOT($WS_DLGFRAME) ) $NewStyle = BitAND($NewStyle,BitNOT($WS_THICKFRAME) ) $NewStyle = BitAND($NewStyle,BitNOT($WS_BORDER) ) DLLCall( "user32.dll", "long", "SetWindowLong", "hwnd", $hWnd, "int", $GWL_STYLE, "long", $NewStyle ) ; Move the Window into postion and resize it WinMove($window_name, "", 0, 0, 1024, 768) ; Wait for hotkey input while (1) Sleep (2147483647) WEnd ; Hides/Unhides window Func ToggleWindowHide() If ($hidden) Then WinSetState ($window_name, "", @SW_SHOW) ;WinMove($window_name, "", 0, 0, 1024, 768) ;MouseClick("left") Else WinSetState ($window_name, "", @SW_HIDE) ;WinMove($window_name, "", -5000, -5000) ;MouseClick("left") EndIf $hidden = NOT $hidden EndFun Now all that is left to tackle is how to keep the mouse from flying out of the right side of the screen unless I want it to... Link to comment Share on other sites More sharing options...
Christopher Blue Posted November 4, 2004 Author Share Posted November 4, 2004 I have refined my mouse trap script: it now only covers the right-hand side. It works but it is imperfect for the mouse, when moved quickly, will escape onto the second monitor for a split-second before it gets lassoed back in. expandcollapse popup#cs Algorithm: Get Active Window Find Window Get Window Dimensions Check Mouse Location against window dimensions Move Mouse to closest valid coordinate #ce Opt("WinTitleMatchMode", 3) Opt("MouseCoordMode", 0) Global $window_name = "Warcraft III" Global $rest = 1 Global $hotkey = "{F1}" Global $Paused = 0 Global $window_info = WinGetPos($window_name) HotKeySet($hotkey, "TogglePause") while (1) CheckBoundries() Sleep($rest) WEnd Func CheckBoundries() If (WinActive($window_name)) Then $mouse_info = MouseGetPos() ; Right If ($mouse_info[0] >= ($window_info[2] - 2)) Then MouseMove($window_info[2] - 2, $mouse_info[1], 0) EndIf EndIf EndFunc Func TogglePause() $Paused = NOT $Paused While $Paused Sleep(100) WEnd EndFunc Link to comment Share on other sites More sharing options...
Christopher Blue Posted November 4, 2004 Author Share Posted November 4, 2004 Sounds great Larry. I will read up on ClipCursor as MSDN in the meantime. Link to comment Share on other sites More sharing options...
Christopher Blue Posted November 4, 2004 Author Share Posted November 4, 2004 I am going to try writing a small C++ program that traps the cursor and then I will roll that into my AutoIt script. It will be a large undertaking for my newb-skills so it might be awhile until I post any code. Link to comment Share on other sites More sharing options...
Christopher Blue Posted November 4, 2004 Author Share Posted November 4, 2004 Wait, someone has shown me a wrapper DLL that might allow me to make API calls from inside my script. I am going to try that out in a bit (EMch homework is calling me =\ ) Link to comment Share on other sites More sharing options...
Christopher Blue Posted November 4, 2004 Author Share Posted November 4, 2004 (edited) Hm, I'm not sure what dynacall can do that DLLCall cannot. I guess I just got confused. =\ So the problem is the need to pass a RECT structure to ClipCursor? Edited November 4, 2004 by Christopher Blue Link to comment Share on other sites More sharing options...
Matt @ MPCS Posted November 4, 2004 Share Posted November 4, 2004 From what I get from the page you provided, I would say this won't work with AutoIt. It requires a COM interface, which AutoIt does not yet support (maybe sometime in the near future?). *** Matt @ MPCS Link to comment Share on other sites More sharing options...
Christopher Blue Posted November 5, 2004 Author Share Posted November 5, 2004 I have been able to write a tiny C++ program that uses ClipCursor. Now all I have to do is refine it and then incorporate it into an AutoIt script. Link to comment Share on other sites More sharing options...
Christopher Blue Posted November 5, 2004 Author Share Posted November 5, 2004 Ah darn I guess I spoke too soon: the cursor's clipping area keeps getting reset. I will try to fix that somehow in my program. In the meantime, how can I use AutoIt to kill a process that doesn't have a window? (I start my MouseTrap.exe in hidden window mode). Link to comment Share on other sites More sharing options...
Christopher Blue Posted November 5, 2004 Author Share Posted November 5, 2004 (edited) It appears that ClipCursor is reset as soon as another app gains focus. I will see if it sticks if I reapply it after the app has gained focus.edit: Ah it appears that it does stick it reapplied after the app has gained focus. In light of that, I can probably work around it then. Edited November 5, 2004 by Christopher Blue Link to comment Share on other sites More sharing options...
this-is-me Posted November 5, 2004 Share Posted November 5, 2004 Side note, any application you drag with the titlebar will reset the clipcursor. You will need to call clipcursor multiple times to keep it active. Who else would I be? Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now