HWND handle being returned via FindWindowW differs from top-level parent - node.js

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:
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.
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!

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.

Related

Closing an Imgui window: this seems like it should be easy. How does one do it?

I have started using the imgui system for visualizing "whatever". I am in my first few hours, and am running up against what seem to be common snags.
However, although I can see some pretty good support for the C++ versions of ImGui (which I'll transition to eventually), the python imgui content is mostly obscured.
What I am looking for is the solution to the following problem:
while not glfw.window_should_close(window):
...
imgui.new_frame()
imgui.begin("foo-window", closable=True)
imgui.end()
Everything works fine. However, the window doesn't close. I understand that the window doesn't close because it is always created every loop.
What I am looking for is:
How do I detect and identify that the particular window has been closed, and block it from being re-generated?
I'm not at all familiar with the imGui for Python, but if it at all follows the similar pattern as in imGui for c++, then you need to follow this pattern:
static bool show_welcome_popup = true;
if(show_welcome_popup)
{
showWelcomePopup(&show_welcome_popup);
}
void showWelcomePopup(bool* p_open)
{
//The window gets created here. Passing the bool to ImGui::Begin causes the "x" button to show in the top right of the window. Pressing the "x" button toggles the bool passed to it as "true" or "false"
//If the window cannot get created, it will call ImGui::End
if(!ImGui::Begin("Welcome", p_open))
{
ImGui::End();
}
else
{
ImGui::Text("Welcome");
ImGui::End();
}
}
JerryWebOS's answer is basically correct, but to add to that here's the python version. Note that the documentation for pyimgui is a good source to find answers to questions like this one.
https://pyimgui.readthedocs.io/en/latest/reference/imgui.core.html?highlight=begin#imgui.core.begin
imgui.begin() returns a tuple of two bools: (expanded, opened).
You can use this to detect when the user closes the window, and skip rendering the window in the next frames accordingly:
window_is_open = True
while not glfw.window_should_close(window):
...
imgui.new_frame()
if window_is_open:
_, window_is_open = imgui.begin("foo-window", closable=True)
...
imgui.end()

AS3 load new URLRequest through a string

I want to load a new URL (which is in a array), everytime I press the button. I have the following code to do so:
public function selectRadio(radio:Radio):void {
var soundR:Sound = new Sound();
if(!playing) {
soundR.load(new URLRequest(radio.getURL()));
soundChannel = soundR.play();
playing = true;
}
else{
soundChannel.stop();
playing = false;
}
trace("You are now listening to " + radio.getTitle());
}
But it gives me this error:
"implicit coercion of a value of type flash.net:URLRequest to an unrelated type string"
It works if I just leave it like this:
soundR.load(radio.getURL());
But if i do so, I can only press play and stop 4 times. After the fourth there is no sound, like it can't load the URL.
Is it possible to fix this?
Radio.getURL() should return a string instead of a URLRequest?
Ah nevermind I see you tried avoiding that by removing URLRequest, but you are having problems with only 4 connections.
In all but the simplest cases, your application should pay attention to the sound’s loading progress and watch for errors during loading. For example, if the click sound is fairly large, it might not be completely loaded by the time the user clicks the button that triggers the sound. Trying to play an unloaded sound could cause a run-time error. It’s safer to wait for the sound to load completely before letting users take actions that might start sounds playing.
http://help.adobe.com/en_US/as3/dev/WS5b3ccc516d4fbf351e63e3d118a9b90204-7d25.html
If you can't wait for the sound to completely load you may need NetStream:
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/net/NetStream.html

Is there anything like GetDlgItemInt but for a Window that has been created? Win32 Api

Using C++ Win32 API, I've created a window ( CreateWindow() ) instead of a dialogue box. Are there any commands similar to "GetDlgItemInt" or "SetDlgItemInt" that is used for getting and setting data in an edit window for Win 32 API instead? Otherwise I'll have to make a dialogue box or do a heap of code for converting INTs to a string then back again.
The idea is that the user specifies the window width and height by typing in the two edit dialogue boxes within the window I have created. There are nice easy tutorials that basically tell me how to do that through a dialogue box, but I would like to know if there are similar functions that I can use that are not dependent on a dialogue box?
I'm hoping to have something like this...
xVal = 1280;
yVal = 720;
hwndResoX = CreateWindow("edit",xVal, WS_CHILD|WS_VISIBLE|WS_BORDER|ES_NUMBER,20,20,40,20, _hwnd, NULL, NULL, NULL);
hwndResoY = CreateWindow("edit",yVal, WS_CHILD|WS_VISIBLE|WS_BORDER|ES_NUMBER,80,20,40,20, _hwnd, NULL, NULL, NULL);
But as you can imagine, I can not use the xVal or yVal in the CreateWindow() because I get a compile error stating I can not convert from INT to CHAR*
Simplest way to do this:
// Create the window. Note that for edits, the caption is not the same as its contents,
// so we leave that empty here:
hwndResoX = CreateWindow("edit","", WS_CHILD|WS_VISIBLE|WS_BORDER|ES_NUMBER,20,20,40,20, _hwnd, NULL, NULL, NULL);
// Now create a string to use to set as the content:
char content[32];
sprintf(content, "%d", xVal); // Recommend using StringCchPrintf if there's any chance that the buffer size might be too small
SetWindowText(hwndResoX, content);
See also this MSDN page on Using Edit Controls.
For getting the data back, use GetWindowText to get a string, then parse that using whichever string-to-int parsing function you want (eg. strtol, atoi, sscanf, etc.)
While you do have to convert manually between int and string, it's not all that much code, just a couple of extra lines, so a lot less hassle than converting to use a dialog.
Having said that, if you use a proper dialog here, you get a couple of extra benefits: notably the user can tab from field to field automatically, which you have to do extra work to enable in a non-dialog.
You can use GetDlgItemInt, just specify an int ID for the HMENU parameter in CreateWindow.

How to attach mouse event listeners to embedded nsIWebBrowser in C++

I've embedded an nsIWebBrowser in my application. Because I'm just generating HTML for it on the fly, I'm using OpenStream, AppendToStream, and CloseStream to add content. What I need is to add event listeners for mouse movement over the web browser as well as mouse clicks. I've read documentation and tried lots of different things, but nothing I have tried has worked. For instance, the code below would seem to do the right thing, but it does nothing:
nsCOMPtr<nsIDOMWindow> domWindow;
mWebBrowser->GetContentDOMWindow(getter_AddRefs(domWindow));
if (!mEventTarget) {
mEventTarget = do_QueryInterface(domWindow);
if (mEventTarget)
mEventTarget->AddEventListener(NS_LITERAL_STRING("mouseover"), (nsIDOMEventListener *)mEventListener, PR_FALSE);
}
Perhaps it isn't working because this is run during initialization, but before any content is actually added. However, if I add it during AppendStream, or CloseStream, it segfaults.
Please tell me a straightforward way to do this.
Well, here's the answer:
nsCOMPtr<nsIDOMEventTarget> cpEventTarget;
nsCOMPtr<nsIDOMWindow> cpDomWin;
m_pWebBrowser->GetContentDOMWindow (getter_AddRefs(cpDomWin));
nsCOMPtr<nsIDOMWindow2> cpDomWin2 (do_QueryInterface (cpDomWin));
cpDomWin2->GetWindowRoot(getter_AddRefs(cpEventTarget));
rv = cpEventTarget->AddEventListener(NS_LITERAL_STRING("mousedown"),
m_pBrowserImpl, PR_FALSE);

Flash trace output in firefox, linux

I'm developing an applications which I've got running on a server on my linux desktop. Due to the shortcomings of Flash on Linux (read: too hard) I'm developing the (small) flash portion of the app in Windows, which means there's a lot of frustrating back and forth. Now I'm trying to capture the output of the flash portion using flash tracer and that is proving very difficult also. Is there any other way I could monitor the output of trace on linux? Thanks...
Hope this helps too (for the sake of google search i came from):
In order to do trace, you need the debugger version of Flash Player from
http://www.adobe.com/support/flashplayer/downloads.html (look for "debugger" version specifically - they are hard to spot on first look)
Then an mm.cfg file in your home containing
ErrorReportingEnable=1 TraceOutputFileEnable=1 MaxWarnings=50
And then you are good to go - restart the browser. When traces start to fill in, you will find the log file in
~/.macromedia/Flash_Player/Logs/flashlog.txt
Something like
tail ~/.macromedia/Flash_Player/Logs/flashlog.txt -f
Should suffice to follow the trace.
A different and mind-bogglingly simple workaround that I've used for years is to simply create an output module directly within the swf. All this means is a keyboard shortcut that attaches a MovieClip with a textfield. All my traces go to this textfield instead of (or in addition to) the output window. Over the years I've refined it of course, making the window draggable, resizable, etc. But I've never needed any other approach for simple logging, and it's 100% reliable and reusable across all platforms.
[EDIT - response to comment]
There's no alert quite like javascript's alert() function. But using an internal textfield is just this simple:
ACTIONSCRIPT 1 VERSION
(See notes at bottom)
/* import ExternalInterface package */
import flash.external.*;
/* Create a movieclip for the alert. Set an arbitrary (but very high) number for the depth
* since we want the alert in front of everything else.
*/
var alert = this.createEmptyMovieClip("alert", 32000);
/* Create the alert textfield */
var output_txt = alert.createTextField("output_txt", 1, 0, 0, 300, 200);
output_txt.background = true;
output_txt.backgroundColor = 0xEFEFEF;
output_txt.selectable = false;
/* Set up drag behaviour */
alert.onPress = function()
{
this.startDrag();
}
alert.onMouseUp = function()
{
stopDrag();
}
/* I was using a button to text EI. You don't need to. */
testEI_btn.onPress = function()
{
output_txt.text = (ExternalInterface.available);
}
Notes: This works fine for AS1, and will translate well into AS2 (best to use strong data-typing if doing so, but not strictly required). It should work in Flash Players 8-10. ExternalInterface was added in Flash 8, so it won't work in previous player versions.
ACTIONSCRIPT 3 VERSION
var output_txt:TextField = new TextField();
addChild(output_txt);
output_txt.text = (String(ExternalInterface.available));
If you want to beef it out a bit:
var alert:Sprite = new Sprite();
var output_txt:TextField = new TextField();
output_txt.background = true;
output_txt.backgroundColor = 0xEFEFEF;
output_txt.selectable = false;
output_txt.width = 300;
output_txt.height = 300;
alert.addChild(output_txt);
addChild(alert);
alert.addEventListener(MouseEvent.MOUSE_DOWN, drag);
alert.addEventListener(MouseEvent.MOUSE_UP, stopdrag);
output_txt.text = (String(ExternalInterface.available));
function drag(e:MouseEvent):void
{
var alert:Sprite = e.currentTarget as Sprite;
alert.startDrag();
}
function stopdrag(e:MouseEvent):void
{
var alert:Sprite = e.currentTarget as Sprite;
alert.stopDrag();
}
[/EDIT]
If you only need the trace output at runtime, you can use Firebug in Firefox and then use Flash.external.ExternalInterface to call the console.log() Javascript method provided by Firebug.
I've used that strategy multiple times to a large degree of success.
Thunderbolt is a great logging framework with built-in firebug support.
I use the flex compiler on linux to build actionscript files, [embed(source="file")] for all my assets including images and fonts, I find actionscript development on linux very developer friendly.
Then again, I'm most interested in that flash has become Unix Friendly as aposed to the other way around :)
To implement FlashTracer, head to the following address and be sure you have the latest file. http://www.sephiroth.it/firefox/flashtracer/ . Install it and restart the browser.
Head over to adobe and get the latest flash debugger. Download and install the firefox version as FlashTracer is a firefox addition.
Now that firefox has the latest flash debugger and flash tracer we need to locate mm.cfg
Location on PC: C:\Documents and Settings\username
Inside of mm.cfg should be:
ErrorReportingEnable=1
TraceOutputFileEnable=1
MaxWarnings=100 //Change to your own liking.
Once that is saved, open firefox, head to the flash tracer window by heading to tools > flash tracer. In the panel that pops up there is two icons in the bottom right corner, click the wrench and make sure the path is set to where your log file is being saved. Also check to see that flash tracer is turned on, there is a play/pause button at the bottom.
I currently use this implementation and hope that it works for you. Flash Tracer is a little old, but works with the newest versions of FireFox. I am using it with FireFox 3.0.10.

Resources