This App is No Longer Maintained. Visit the Replacement at StrokesPlus.net

StrokesPlus Forum
                       
StrokesPlus Forum
Home | Profile | Active Topics
Members | Search | FAQ
Username:
Password:
Save Password
Forgot your Password?

 All Forums
 General Discussion
 General Discussion
 Sending commands to the right window.
 Forum Locked
 Printer Friendly
Author Previous Topic Topic Next Topic  

YouraT

10 Posts

Posted - 08/14/2013 :  10:59:58  Show Profile
OK - bear with me - this is potentially a little confusing...!

I have an action that kick off this:

acActivateWindow(nil, gsx, gsy)
acSendKeys("z")

which is a 'Zoom' command in a PCB editor I use.

If I have different document windows open and tiled in an MDI fashion in the application, I don't always get the 'z' in the document window I'm over when I do the stroke until after I've clicked in the specific document - sometimes it's received in the 'other' document window which previously had focus (window title highlighted) and sometimes it appears to go nowhere, at those times when none of the document windows has focus.

Main question - am I using the acActiveWindow call correctly, or is there some other way to get what I'm expecting?

Many thanks,

Youra.

Rob

USA
2615 Posts

Posted - 08/14/2013 :  20:39:32  Show Profile  Visit Rob's Homepage
When acActivateWindow(nil, gsx, gsy) is called without a target window (the "nil" parameter), the internal code resolves the root owner of the window at the supplied coordinates (in your case, the starting point of the gesture [gsx, gsy]):

GetAncestor(WindowFromPoint(start),GA_ROOTOWNER)

(start is a POINT struct, start.x = gsx, start.y = gsy at this point)

So basically, WindowFromPoint(start) gets the window/control at the location of the gesture starting coordinates. GetAncestor (receiving the window handle from the previous sentence) then gets the root owner (due to the GA_ROOTOWNER parameter) of that window.

In nearly all cases, the root owner of a window/control is the main application window. So that code you simply activate the application and send "z". If the application is already active, nothing would really happen and the PCB app would handle the "z" based on whatever area of the app currently has focus.

Now, to address your issue... This is a little tricky without actually having the PCB app installed. If I did, I would use Spy++ to analyze the window hierarchy of the MDI windows and see what the proper call(s) would be. For example, if each MDI window is simply a canvas with no controls (meaning they're owner-drawn), then something like this may work fine:

acActivateWindow(acGetWindowByPoint(gsx, gsy))

Although, there are dependencies within the PCB program on how it handles certain Windows messages. It may not respond to or bubble up an activate message, resulting in still nothing working. Again, if I had it installed and the above didn't work, I'd start message logging and see what messages it does respond to.

Come to think of it, I'm not sure if acActivateWindow would work at all as it calls SetForegroundWindow, which may only affect top-level windows (not MDI).

To be honest, the first thing I would do is see if there's any non-overly-technical way to handle this. For example, if each of the MDI windows has a unique title, you might be able to call:
local sTitle = acGetWindowTitle(acGetWindowByPoint(gsx, gsy)) 
if sTitle == "Some Window" then
    --send menu commands (keystrokes) which would cause that window to become active
    --then
    acSendKeys("z")
end

There are probably a hundred different ways you can accomplish this. Someone posted once about splitting up the app into areas (within the action), so if the mouse was over a certain area which was pre-defined to designate a certain area of the window, the script would do one thing, in another area of the window, the script would do something different.

Hopefully, there's a simple way to handle this. If not, let me know the name of the PCB app and I'll see if I can find it somewhere to test out.
Go to Top of Page

YouraT

10 Posts

Posted - 08/15/2013 :  03:43:52  Show Profile
Hi Rob

Thanks for looking at this!

The first attempt:

acActivateWindow(acGetWindowByPoint(gsx, gsy))

doesn't help, as you suggested it might not.

Your other suggestion might have some legs - each of the MDI window titles ends in either "(PCB Design)" or "(Schematic Design)" The problem I can see is that the only way to cause that window become active is a mouse "left click" which might (probably would depending on where the cursor was at the time of the click) select something in the MDI window which would mean the meaning of 'z' would change slightly, as well as upsetting any multiple selections that had been set up previously....

Is there a way of determining the co-ordinates of the title bar of the MDI window and clicking there before returning the cursor to the position of the end of the stroke and sending the 'z' ? That would likely work.

The application I'm using is EasyPC from:

http://www.numberone.com/downloadrequest.asp?P=Easy-PC

I'm afraid you have to register to get a free trial version...

I can send you my preferences/actions file if that's of help too.
Go to Top of Page

Rob

USA
2615 Posts

Posted - 08/15/2013 :  12:31:41  Show Profile  Visit Rob's Homepage
Don't have the time to type a big explanation, but this works for me!


In your Global Lua: (adjust accordingly if you already have user/kernel defined, etc.))


aliencore = alien.core
alienstruct = alien.struct
kernel32 = aliencore.load("kernel32.dll")
user32 = aliencore.load("user32.dll")

-- ************ GetParent ************

gGetParent = user32.GetParent
gGetParent:types{ ret = 'long', abi = 'stdcall', 'long' }

function aGetParent(hWnd)
	return gGetParent(hWnd)
end

In your action:


local sMainPattern = "^Easy.PC"
local sPCBPattern = "PCB.Design"
local sSchematicPattern = "Schematic.Design"
local hControl = aGetParent(aGetParent(acGetWindowByPoint(gsx,gsy)))
local sControlTitle = acGetWindowTitle(hControl)
if string.find(sControlTitle,sMainPattern) == nil then
	if string.find(sControlTitle,sPCBPattern) ~= nil 
	  or string.find(sControlTitle,sSchematicPattern) ~= nil then
		local iTop = acGetWindowTop(hControl) + 10 
		local iLeft = acGetWindowLeft(hControl) + 50
		acConsumePhysicalInput(1)
		acMouseClick(iLeft, iTop, 2, 1, 1) 
		acMouseMove(gsx, gsy)
		acDelay(10)
		acSendKeys("z")
		acDelay(10)
		acMouseMove(gex, gey)
		acConsumePhysicalInput(0)
	end
end
Go to Top of Page

YouraT

10 Posts

Posted - 08/19/2013 :  09:05:25  Show Profile
Rob,

That's fabulous - works an absolute treat - I even *half* understand what the code's doing too - bonus!

As always, excellent support - Many Many Thanks!

Youra.
Go to Top of Page

Rob

USA
2615 Posts

Posted - 08/19/2013 :  10:57:20  Show Profile  Visit Rob's Homepage
Glad to hear, and you're welcome!
Go to Top of Page
  Previous Topic Topic Next Topic  
 Forum Locked
 Printer Friendly
Jump To:
StrokesPlus Forum © 2011-2018 Rob Yapchanyk Go To Top Of Page
Snitz Forums 2000