I have a plugin which is primarily used for screen-capture. It loads with the browser. Now on click of the button a small window appears notifying the screen capture has started.
Here, I also want the browser to get minimized.
I tried the following approaches:
Approach 1.
HWND parentWH = ::FindWindow(L"Chrome_WidgetWin_1", L"test - SC1 - Google Chrome");
::ShowWindow(parentWH,SW_MINIMIZE);
It works! But the question is that how should I take the parameters of FindWindow dynamically.
like, parameter1 being 'WindowClassName' and 2 being 'WindowTitle'. for different browsers.
Approach 2.
HWND parentWH = ::GetAncestor(this->pluginWindowHandle,GA_ROOTOWNER);
::ShowWindow(parentWH,SW_MINIMIZE);
Does Not Work!
To minimize the browser window containing the plugin you've used to start a screen capture, I'd suggest the following steps:
Pass the document.title (JavaScript) of the page which embeds your plugin to the plugin.
Create an EnumWindowsProc callback function in your WinApi dll. This function will be given a HWND every time it is called. Inside this function you should use the GetWindowText function to check if the document.title from the browser is a substring of the title corresponding to the current HWND. If it is, then you can minimize the current HWND using ShowWindow, and if you want to restore it after a capture, you can store the HWND and use it again later. Return FALSE if you have found a match, and TRUE otherwise.
Use the EnumWindows function to enumerate through the windows on your system. Into this, you will pass a pointer to the callback function above. EnumWindows will run until the callback function returns FALSE, or it has enumerated through all of the windows.
Here's what worked for me for minimizing the browser window.
Approach 1:
::ShowWindow(pluginWindowHandle,SW_HIDE);
parentWH = ::GetForegroundWindow(); //for obtaining parent window handle
::ShowWindow(parentWH,SW_MINIMIZE);
Approach 2:
Before showing the plugin window, i'm getting the browser window handle
void NotificationWindow::showNotification()
{
parentWH = ::GetForegroundWindow();
::ShowWindow(parentWH,SW_MINIMIZE);
this->close();
this->displayWindow();
}
Here, till the displayWindow() function is not called, we can get the browser window handle directly by using GetForegroundWindow() function.
Related
I am looking to develop an application which is essentially a timer window which is always shown on the screen in front of any other application and never falls to the background when focusing other windows. An example is when I play a full-screen game I would like this timer to be overlaying the game and when I click the timer buttons on the window it does not close the game.
Any ideas how I can achieve this in C#/java/C++?
Thanks
C#: try setting the AlwaysOnTop property of the window (form)
java: call the setAlwaysOnTop(true) on the frame or dialog
I think that what you want to achieve can be achieved with the property TopMost of the form in C#, and setAlwaysOnTop on a Java Window ...
In C++ on Windows you have to call the SetWindowPos function and passing as argument : HWND_TOPMOST attribue.
UPDATE
Since you have an application in fullscreen mode try setting your application in foreground with the Win32 API function : SetForegroundWindow .
[System.Runtime.InteropServices.DllImport("user32.dll")]
public static extern bool SetForegroundWindow(IntPtr hWnd);
SetForegroundWindow(this.Handle);
Otherwise you can try to avoid using the Win32 SetForegroundWindow function with something like this :
this.TopMost = true;
this.Activate();
I can't figure out how to hide a child window (a control), more specifically a GroupBox and a PushButton. I thought ShowWindow() with SW_HIDE as the second parameter would do the job, but it simply doesn't work. Yet SW_SHOW works just fine. I have the correct window handle for both controls, so that's not the issue.
I googled and all I could find was people asking how to hide dialogs, not controls. Either that or MFC-based applications, which doesn't apply here.
I'm using pure Windows API, no MFC.
What am I getting wrong?
EDIT: More info: I'm writing some simple class wrappers for WinApi controls. The WindowsControl class has, along other methods, the following methods for showing and hiding the Control:
void Show() {
ShowWindow(this->_hWnd,SW_SHOWNOACTIVATE);
}
void Hide() {
ShowWindow(this->_hWnd,SW_HIDE);
}
Every control inherits from WindowsControl.
This image has the window layout so you understand exactly what I'm doing: http://i.stack.imgur.com/PHQnH.png
When the user clicks inside the "Chipset" Static control, it'll load information for a given Tile (which is stored in an array, but that's irrelevant). Depending on the setting, it'll hide the "Edit bitwall" button on the left and show the empty GroupBox behind it or viceversa.
Just to be clear this isn't something wrong with my windows api wrappers, I am getting the correct HWND. Though ShowWindow might not be able to be called from a Window Procedure that isn't the parent's (that'd be weird).
EDIT2: Using C++ with Visual Studio 2008, no MFC, no WTL, no CLR, no .NET
EDIT3: I'll post even more code so it's easier
Inside the static's window procedure, I handle WN_LBUTTONDOWN like this:
case WM_LBUTTONDOWN: {
...
update_tiledata(c, l)
void update_tiledata(GroupBox * c, ListView* l ) {
...
if (chp_copy.Tiles[selectedTile].Pass() == PT_BITWALL) {
c->Controls(CTL_BTNEDITBIT)->Show();
c->Controls(CTL_FRPHOLD)->Hide();
} else {
c->Controls(CTL_FRPHOLD)->Show();
c->Controls(CTL_BTNEDITBIT)->Hide();
}
update_edits();
}
The ommited code does nothing to affect the classes, as I said before, ShowWindow with SW_HIDE IS getting called, with the correct HWND, but nothing is happening.
A control in a Window or dialog can be hidden using
ShowWindow(hControlWin, SW_HIDE);
In a dialog you can retrive the controls window handle by calling
GetDlgItem(hDlg, < CtrlID >);
Typically you write something like:
ShowWindow(GetDlgItem(hDlg, 2), SW_HIDE);
It would be helpful if you give more information and some code: How did you create the controls? What language, compile and framework did you use?
I think the function call you want is EnableWindow I have used this before to disable a button on a form. You will need to get an handle to the Window (object) first though so you might want to use EnumChildWindows to iterate through all the controls to find the one you want.
When we use WindowFromPoint winapi function we usually can get the case, when Point specifies to some control within a window. And in such cases WindowFromPoint returns handle to that control, not to the window that handles that control.
For example in my small test application if I point to the "body" of chrome browser I get the control with class = Chrome_RenderWidgetHostHWND and its hwnd.
But what I need is to get the "parent" window for that control (which is obviously should be the chrome window).
Traverse the parents using GetAncestor() passing GA_PARENT. This differs from calling GetParent() which will return the owner if the window is a top-level window.
Can't you just use GetParent? Keep traversing until you find the desktop window.
Ho do I get hWnd of the current window/form in VB6?
If you're on the form: Me.hWnd. If you don't know which form is the current form: Screen.ActiveForm.hWnd
Using Windows API, GetForegroundWindow() will get the handle of the topmost window regardless of which application it is from, and GetActiveWindow() will get the handle of your application's active window. The Declare statements you will need:
Declare Function GetForegroundWindow Lib "user32.dll" () As Long
Declare Function GetActiveWindow Lib "user32.dll" () As Long
Calling either function will return a window handle as described above.
It's been a long time since I used VB6, but this is what I remember:
You'll want to open the API Viewer, which should be in the Start Menu around the VB6 entry. When you open it, you want to select win32api.txt, and you'll get a list of all of the Win32 API functions. This is the easiest way to not mess up the function signatures. Copy and paste the function declaration into one of your VB6 modules.
I always "cheated" and just looked for my window by caption name, instead of looping over all of the available windows with GetWindow. If you're okay with this, you want to use FindWindow and pass the caption name as the second parameter.
I'd like to prevent my window from being updated until I finish receiving data from the server and render it. Can I hook on the WM_PAINT event, or better still call some Win32API method to prevent the window from being updated and unfreeze it later?
More info:
In the context of an MMC snapin written in C#, our application suffers from annoying flickering and double sorting behaviour:
We use MMC's listViews, but since we subscribe to the sort event.
MMC does it's own magic and sorts the page being displayed (and we can't override that), and when we receive a reply from our server we change the listView again.
each row change is done sequentially, there's no beginUpdate etc. (AFAIK).
Normally hooking into WM_PAINT is the way to go, but make sure you also ignore all WM_ERASEBKGND notifcations, otherwise you'll still get flicker, because Windows erases the Windows area for you. (Return non-zero to prevent Windows from doing that)
One other possibility is to use the LockWindowUpdate function, but it has some drawbacks:
Only one window can be locked
Upon unlock the whole desktop and all sub-windows (i.e. everything) is repainted, resulting in short flash of the whole desktop. (It's worse on XP than on Vista)
Some controls have BeginUpdate and EndUpdate APIs for this purpose.
If you do something (e.g. hook and ignore paint events) do disable painting, then a way to force a repaint later is to call the Invalidate method.
OK, after all searching and checking I've found that LockUpdateWindow is bad idea - see for example articles of Raimond Chen OldNewThing. But even to implement the idea of SetRedrawWindow wasn't so simple - because what I had was only received from IConsole2* pConsole->GetMainWindow() HWND handler of main window. By setting it to SetRedraw = FALSE it was disappeared in very strange manner. Though to make the procedure run only for the TreeView and not for the whole application (ours left panel) I ran
EnumChildWindows(hWnd, SetChildRedraw, FALSE); //stopping redraw
//... here you do your operations
EnumChildWindows(hWnd, SetChildRedraw, TRUE); //restarting redraw
where SetChildRedraw callback was defined in next way:
#define DECLARE_STRING(str) TCHAR str[MAX_PATH]; ZeroMemory(str, sizeof(str));
BOOL CALLBACK SetChildRedraw(HWND hwndChild, LPARAM lParam)
{
RECT rcChildRect; ZeroMemory(&rcChildRect, sizeof(rcChildRect));
DECLARE_STRING(sText)
GetClassName(hwndChild, sText, MAX_PATH);
if (wcsstr(sText, L"SysTreeView32") != NULL)
{
SetWindowRedraw(hwndChild, lParam);
if (lParam == TRUE)
{
GetWindowRect(hwndChild, &rcChildRect);
InvalidateRect(hwndChild, &rcChildRect, TRUE);
}
}
return TRUE;
}