0

I'm trying to create a utility that will selectively hide and show windows based on pre-assigned hotkeys and I'm working with the Windows API code.

I use a FindWindowW call to get a handle to a window as a test (in my case, a window with the text "Calculator - Calculator", which matched an open calculator window) and use that handle in a ShowWindow function.

Code below:

    var user32path = 'C:\\Windows\\System32\\user32.dll';


        function TEXT(text){
          return new Buffer(text, 'ucs2').toString('binary');
        }

          var user32 = new FFI.Library(user32path, {
        'FindWindowW': ['int', ['string', 'string']],
        'ShowWindow': ['int', ['int', 'int']],
        'ShowWindowAsync': ['int', ['int', 'int']],
        'FindWindowExW': ['int', ['int', 'int', 'string', 'string']],
        'BringWindowToTop': ['int', ['int']],
        'GetActiveWindow': ['int', ['int']]


        var handle = user32.FindWindowW(null,TEXT("Calculator ‎- Calculator"));

user32.ShowWindow(

handle, 'SW_Hide');

//associatedWindowHandle is a manually-created variable with the Spy++ variable.
//The Spy++ doesn't match and I'm not sure why. 


user32.ShowWindowAsync(activeHandle, 'SW_Hide');

var pruneLength = Object.keys(prunedData).length;

  for (let i = 0; i < pruneLength-1; i++){
    if (Object.entries(prunedData)[i][1] === hotkey){
      for(let j = 1; j <= prunedData.assocWindows.length; j++){

        let associatedWindow = Object.entries(prunedData)[i+1][j].toString();
          let associatedWindowHandle = parseInt(associatedWindow);
        user32.ShowWindowAsync(associatedWindowHandle, 'SW_Hide');
        user32.BringWindowToTop(associatedWindowHandle[i+1][j]);
      }
    }
  }

2 main issues:

  1. When I try hiding and/or minimizing the open calculator window, I can't seem to show it again when clicking on it. the preview image disappers and I notice a "Process Broker" is thrown.

  2. I can't seem to actually find the window handle given with tools like Spy++, which makes it somewhat hard to debug to see if I need to grab a different handle. The parent-level calculator window's handle doesn't seem to match, and I verified that it was the same tool.

I'd also like to be pointed to some decent resources to help self-educate on this so I can better troubleshoot this in the future.

Many thanks!

camelCaseCowboy
  • 946
  • 1
  • 10
  • 26
  • 2
    The calculator app in Win10 has changed, it is no longer a Win32 desktop app. Now a UWP app, it marches to a very different drummer. Consider doing your experiments on Notepad instead. – Hans Passant May 31 '18 at 08:39

1 Answers1

2

Firstly, I'd echo Hans Passant's remarks that you're probably better off not trying to so this with a UWP app like Calculator, but then again these apps are not going to go away so perhaps you might want to try anyway.

The shell doesn't appear to appreciate you trying to hide a UWP app (Win32 apps work fine though, go figure). As you have observed, it's icon remains visible in the toolbar but behaves strangely while the window is hidden. So, short version, don't do that.

Instead, try this:

PostMessage (hWnd, WM_SYSCOMMAND, SC_MINIMIZE, 0);

Then things work a lot better, although the user can still undo all your good work by reopening the window of course.

As for Spy++, I have no trouble locating the top-level window of a UWP app using the 'Finder tool' (Menu -> Search -> Find Window). You just have to walk a couple of levels up the window hierarchy afterwards until you get to the one you really want.

Spy++ seems not to be able to log messages being sent to such a window however, see (shameless plug): Why can't Spy++ see messages sent to UWP apps?. I plan to look into this a bit more when I have time.

Finally, what do you mean by 'a "Process Broker" is thrown' please? I don't understand that comment. There's something called RuntimeBroker, which shows up in Process Explorer and appears to be connected with UWP apps in some way, but I don't know if that's what you mean and and I don't know anything about it even if you did.

Paul Sanders
  • 24,133
  • 4
  • 26
  • 48
  • Do you know if there is a way to detect if a window is Win32 or UWP? My goal is to be able to hide and show the windows regardless of their format. – camelCaseCowboy May 31 '18 at 18:48
  • 1
    They seem all to have a top-level window class of `ApplicationFrameWindow`, but I bet there are exceptions. – Paul Sanders May 31 '18 at 18:53