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
 Windows 10 acGetDesktopWindow() behavior & Z-order
 Forum Locked
 Printer Friendly
Author Previous Topic Topic Next Topic  

Hard.Wired

84 Posts

Posted - 05/09/2019 :  19:08:48  Show Profile
I want to force the desktop to be active, but

acActivateWindow(acGetDesktopWindow(), nil, nil, 0)


doesn't seem to get the job done. However

acActivateWindow(acFindWindowByTitleRegex("Program Manager"), nil, nil, 0)


seems to work.

Is there a difference here or might this be a Windows 10 issue?

Edited by - Hard.Wired on 05/15/2019 17:29:45

Rob

USA
2615 Posts

Posted - 05/09/2019 :  20:11:44  Show Profile  Visit Rob's Homepage
acGetDesktopWindow() gets the actual true desktop window, as far as Windows is concerned. But that's not the desktop as you'd think of it.

In StrokesPlus.net I have a sp.DesktopWindowListView() function which returns the visible/interactive desktop window, which uses this code snippet:
SystemWindow hProgman = SystemWindow.FindWindow("Progman", "");
IntPtr hDesktopWnd = GetDesktopWindow();

// If the main Program Manager window is found
if (hProgman != null)
{
	// Get and load the main List view window containing the icons (found using Spy++).
	IntPtr hShellViewWin = SystemWindow.FindWindowEx(hProgman.HWnd, IntPtr.Zero, "SHELLDLL_DefView", null);
	if (hShellViewWin != IntPtr.Zero)
		hDesktopListView = SystemWindow.FindWindowEx(hShellViewWin, IntPtr.Zero, "SysListView32", null);
	else
		// When this fails (happens in Windows-7 when picture rotation is turned ON), then look for the WorkerW windows list to get the
		// correct desktop list handle.
		// As there can be multiple WorkerW windows, so iterate through all to get the correct one
		do
		{
			hWorkerW = SystemWindow.FindWindowEx(hDesktopWnd, hWorkerW, "WorkerW", null);
			hShellViewWin = SystemWindow.FindWindowEx(hWorkerW, IntPtr.Zero, "SHELLDLL_DefView", null);
		} while (hShellViewWin == IntPtr.Zero && hWorkerW != IntPtr.Zero);

	// Get the ListView control
	hDesktopListView = SystemWindow.FindWindowEx(hShellViewWin, IntPtr.Zero, "SysListView32", null);
}
Go to Top of Page

Hard.Wired

84 Posts

Posted - 05/10/2019 :  06:15:34  Show Profile
Ah, I think see better now. I can't drill down the tree without using FindWindowEx... and even though acFindWindowByTitleRegex("Program Manager") seems to work, it really isn't correct, especially if the desktop icons are hidden (or at least it seems that way).

And GetDesktopWindow() is the highest handle in the tree that the other desktop processes start from (parent?).

So I'll have to do an alien.core dll call to access FindWindowEx. Hmm.

I will eventually get to StrokesPlus.net, but right now I need a few things to work in my StrokesPlus.com lua daily driver before I start converting everything.

I also need to figure out a way to get Window Z-order into a table. I've found some old code examples, but nothing that works well with Window 10 (or 8 for that matter).
Go to Top of Page

Hard.Wired

84 Posts

Posted - 05/10/2019 :  16:00:02  Show Profile
Hmm... is sp_all_windows supposed to be in Z-Order after acGetAllWindows(1)?
Go to Top of Page

Rob

USA
2615 Posts

Posted - 05/10/2019 :  16:15:35  Show Profile  Visit Rob's Homepage
It just calls EnumWindows and after filtering out the things like visible etc, to qualify the main windows, it just added each handle (as they are received by EnumWindowsProc, sent by Windows) via vector::push_back(). Then the ac function using this snippet to load the sp_all_windows table...so take from that what you will!
	for (int i=0; i<GetAllWindowsList.size(); i++) {
	  lua_pushinteger(L, (int)GetAllWindowsList[i]);
	  lua_rawseti (L, -2, i);
	}

See here for some other info about a question regarding the z-order: https://stackoverflow.com/questions/295996/is-the-order-in-which-handles-are-returned-by-enumwindows-meaningful.

Basically, it's either in correct z-order, or completely reversed...but I think it's top down, which is the reason I used push_back so the lua push would spit them out in the correct order when it loops. however, the entirety of the ordering process is dictated by what Windows pushes into the EnumWindowsProc, so I don't alter the z-order in any way other than my loops.
Go to Top of Page

Hard.Wired

84 Posts

Posted - 05/13/2019 :  13:20:05  Show Profile
After some testing, Z-Order seems consistent as long as I use
for i, hwnd in pairs(sp_all_windows) do
 ...
end

and not ipairs or something like
for i = #sp_all_windows, 1, -1 do
 ...
end

which is a bummer. To get them in a reverse order it looks like I have to do something like
local index_all_windows = {}
local iw = 1
for i, hwnd in pairs(sp_all_windows) do
 index_all_windows[iw] = hwnd
 iw = iw + 1
end


And then traverse through index_all_windows any way I want. Is there a better way to get the reverse order?
Go to Top of Page

Rob

USA
2615 Posts

Posted - 05/13/2019 :  14:06:57  Show Profile  Visit Rob's Homepage
I was never a Lua master, anything I could google, you probably could too :-/
Go to Top of Page

Hard.Wired

84 Posts

Posted - 05/13/2019 :  15:42:39  Show Profile
Yeah, thanks. I'll keep poking at it.
Go to Top of Page

Hard.Wired

84 Posts

Posted - 05/15/2019 :  17:28:05  Show Profile
After reading through the Lua docs (https://www.lua.org/manual/5.3/) and finding this info on Stack Exchange (https://stackoverflow.com/questions/15706270/sort-a-table-in-lua), I found out that Lua tables and for/pairs() can be tricky. For anyone interested, I'll repost the code here...
function spairs(t, order)
    -- collect the keys
    local keys = {}
    for k in pairs(t) do keys[#keys+1] = k end

    -- if order function given, sort by it by passing the table and keys a, b,
    -- otherwise just sort the keys 
    if order then
        table.sort(keys, function(a,b) return order(t, a, b) end)
    else
        table.sort(keys)
    end

    -- return the iterator function
    local i = 0
    return function()
        i = i + 1
        if keys[i] then
            return keys[i], t[keys[i]]
        end
    end
end

Example of use:
HighScore = { Robin = 8, Jon = 10, Max = 11 }

-- basic usage, just sort by the keys
for k,v in spairs(HighScore) do
    print(k,v)
end
--> Jon     10
--> Max     11
--> Robin   8

-- this uses an custom sorting function ordering by score descending
for k,v in spairs(HighScore, function(t,a,b) return t[b] < t[a] end) do
    print(k,v)
end
--> Max     11
--> Jon     10
--> Robin   8

Also, learned about "iterators".
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