Problem hosting WebBrowser control in an ATL app - internet-explorer-8

I have a legacy atl app that hosts a webbrowser control in an ATL window. I create an instance of the client to host the browser using the following sequence
CComPtr<IOleObject> spOleObject;
HRESULT hr = CoCreateInstance(CLSID_WebBrowser, NULL, CLSCTX_INPROC, ID_IOleObject,(void**)&spOleObject);
spOleObject->SetClientSite(this);
GetClientRect(&rcClient);
hr = spOleObject->DoVerb(OLEIVERB_INPLACEACTIVATE, &msg, this, 0, m_hWnd, &rcClient);
hr = AtlAdvise(m_spWebBrowser, GetUnknown(), DIID_DWebBrowserEvents2, &m_dwCookie);
CComVariant navvar(navurl);
m_spWebBrowser->Navigate2(&navvar, NULL, NULL, NULL, NULL);
This sequence works fine to create the initial browse window. The call to navigate2 works and if I look at the window via spy++ I have Shell Embedding -> Shell DocObject View -> Internet Explorer_Server. When a popup occurs (detected through NewWindow3) I launch a new window and execute the same code sequence for the new window. In the popup window the navigate2 doesnt work, and when I look at this new window in spy++ I just have Shell Embedding. I get the same problem even if I instantiate the popup window on startup, so its not related to NewWindow3 at all - it seems the second instance of the web control isnt instantiating even though all the calls return S_OK.
This sequence worked fine under IE7 but now I am using IE8 and the popup window isnt working. There is clearly something I am missing but I cant guess what it may be. Any suggestions would be incredibly helpful.

Turns out that when I created the main window I called
m_spInPlaceObject = m_spWebBrowser;
_ASSERT(m_spInPlaceObject);
if (m_spInPlaceObject)
m_spInPlaceObject->SetObjectRects(&rcClient, &rcClient);
But I didnt have this call in the popup initialization. Once I added this to the popup initialization it worked fine.
For whatever reason it worked on IE7 but not on IE8.
Slack coding on my part. Hosting the IE control in an ATL app is still as neat as ever!

Related

Unable to focus electron app (on Windows)

Hopefully a simple question: I'm making a timer-style application, and I'd like the application to regain focus when the timer ends. The application successfully pops back up when the timer ends, and I can even see a blinking cursor in the first text box, but when I type something it still goes to the app behind it. I've tried every method I could find in the electron documentation (listed below), and none of them work. Is there another avenue I'm missing, or is this just not possible?
Object.values(windows).forEach((window) => { // windows here stores all the application's BrowserWindows
window.focus();
window.focusOnWebView();
window.webContents.focus();
});
app.focus({ steal: true });
Thanks!
I tried all the documented methods as well and nothing really works (at least in Windows 10).
To bring the app on top I have to toggle AlwaysOnTop like this (renderer process):
let currentWindow = window.require("electron").remote.getCurrentWindow();
currentWindow.setAlwaysOnTop(true);
currentWindow.setAlwaysOnTop(false);
but unfortunately it doesn't help with the app focus.
People say that BrowserWindow::restore() function correctly sets focus back to the app. So you might do something like this (although it looks terrible):
currentWindow.minimize();
currentWindow.restore();
It is interesting that I have a similar problem in my other C++ project, so probably it is something OS-related. To solve the problem in the C++ project I had to call SetForegroundWindow function after activating the window. Since ElectronJS BrowserWindow has a getNativeWindowHandle function that returns Windows HWND handle, maybe you could utilize this if nothing else works.
Good luck!

How to react to 'Close window' in right-click menu of task bar in Windows

Using Qt 5.3.0 and Windows 8.1:
Don't know if I'm missing something or if this is an oversight in Qt, but when I simply have a QMainWindow that opens a QDialog (with exec()) and then try to use the 'Close window' function of the right-click menu of the Windows task bar icon (while the dialog is still open), the application is not closing as expected, but nothing happens. I also do not get a closeEvent in the QDialog or the QMainWindow.
When only the QMainWindow is open, the application is closed successfully and I'm also getting a closeEvent.
This is actually also reproducible when e.g. using Qt Designer and opening an additional dialog and then trying to use the 'Close window' function.
Any ideas how to fix this behavior?
The behavior you're seeing is not really surprising. In fact, it's exactly what happens with a (mostly) well-behaved Windows app like Notepad, so I'm not sure I'd even call it a bug.
Open Notepad, and select Help->About to get a modal dialog. Now choose Close from the task bar icon. Nothing happens.
The Close from the task bar is sent to the main window as if the user had selected the Close option from the "system" menu. That arrives as a WM_SYSCOMMAND with SC_CLOSE. If you don't handle that explicitly, then DefWindowProc turns it into a WM_CLOSE message, which most main windows handle.
But if you have a modal dialog open, the main window is disabled and thus doesn't get the message.
One way to fix it would be not to have modal dialogs and instead simulate modality with modeless dialogs. That would allow the main window to receive and respond to the message. But that would be a lot of work for a small fix.
If you call your QDialog via QDialog::show() passing the MainWindow as parent ( QDialog *dialog = new QDialog(this) ) where this is the pointer to your MainWindow, it will work. However the dialog won't be modal anymore. I don't know if modality is important in your case.

How to shut a Win app from another app without reboot?

Hi I want to make a small test window app that can force IE to save its data and shutdown upon a button click and restart with same tabs when another button is clicked??
I am fairly new to Win32 programming can anyone help me out here.??
Any leads will be appriciated??
Try to find one of each browser class with EnumChildWindows then you save the text(current link) of each one, and send a WM_CLOSE message to the program, if you debug the IE you'll probably see a CALL to the function to open a new window, when you find it, you can call it again and with the new browser class you put the text you got from the one that was opened

Create a background process in windows

How do I make a process go the background programatically?
What I want is for the user to double-click the process executable, and it just goes into the background ... and does not open a window while executing.
Any code snippet in visual c++ would be very helpful
Have you considered creating a Windows Service instead? They're specifically designed to run in the background without showing a UI.
Otherwise, just create an application without a window.
I know this is old, but I thought I would post something for when people find this through search.
While I like Cody Gray's answer for design correctness, sometimes you don't have a choice.
If you want to launch a program without jumping to the new window (it appears in the background or minimized) or not create a window at all try looking at the ShellExecute and ShellExecuteEx functions. The argument nShowCmd (or nShow) gives you (among others) the options:
SW_HIDE
Hides the window and activates another window.
SW_SHOWMINNOACTIVE
Displays the window as a minimized window. The active window remains active.
As the documentation says, SW_HIDE creates a process running the executable you give it, but if this program would normally create a window, none appears.
This might help: http://ss64.com/nt/start.html
I tried this way and it worked fine:
Create a console application and write your codes in the sub main as any other console application.
Now change the application type in the project properties to windows Forms application from Console application
thats it

Modal dialogs opened by a fullscreen OpenGL window on Windows 7 are not showing

It seems that my problem may be the same as an unanswered related question (OpenGL with GLUT on windows 7, fullscreen mode not showing the message box).
Since I switched to Win7 as a development environment, and a possible target platform for my applications, I noticed a regression in their behaviour.
Whenever I have a fullscreen window containing a fullscreen OpenGL context, the applications have problems displaying modal dialog boxes (such as message boxes, file open dialog, etc.)
The window is just created with WS_POPUP style. The GL context is nothing fancy. And everything is fine with Windows XP.
The problem under Windows 7 is that the modal dialog boxes are invisible at their opening (maybe their appear behind the full screen window). You have to Alt-Tab the application to have the dialogs appear.
This is a major problem as the application appears to be frozen, while it in fact waits for user input.
Did anyone encounter this behaviour ? Does anyone know a workaround ?
I've quickly made up a sample test application ; its source code can be found at http://pastebin.com/K4v2NNDs. A simple MSVC8 project can be found here.
PS. I've also posted on opengl.org forums, sorry for those of you that follow both.
EDIT
Thanks to Chris comment, I've tested the modal dialog on various events, such as WM_TIMER or WM_RBUTTONUP, but the problem is still there.
I've also called 'DwmEnableComposition' with 'DWM_EC_DISABLECOMPOSITION' just to check : problem still there.
I've also tested the application by replacing the OpenGL bits by DirectX, and this way everything works as expected... It's really OpenGL causing the problem.
(updated pastebin http://pastebin.com/Rq1Ehm3w and my scratchpad)
EDIT
The problem also exists on Windows 8.
A workaround has been posted on opengl.org by Joseph Steel, so, for reference I put it here as well :
The solution I found for this problem was to ensure that the pixel format for the window uses the WGL_SWAP_COPY_ARB swap method rather than the WGL_SWAP_EXCHANGE_ARB.
I've noted that one must use 'wglChoosePixelFormatARB' to obtain the pixel format.
I tried with the classic 'ChoosePixelFormat' with the 'PFD_SWAP_COPY' flag, but it does not work on my system (Win7 x64 + NVidia GeFo 9600GT v196.21) as it always returns me a pixel format with 'PFD_SWAP_EXCHANGE' instead.
I'm only half-happy with the results, as it introduces some tearing in my display, but as least it works !
For reference, I've updated my test source code.
EDIT, dec.2013
This workaround does not work anymore, at least on my system (laptop, Optimus GeForce 650M). The WGL_SWAP_COPY_ARB is setup but the modal dialog does not show. So far, it seems that creating the window with a 1 pixel border (adding WS_BORDER to WS_POPUP style) does the trick, and prevents entering 'fullscreen' mode.
Solution on my system was pretty simple:
- DO NOT specify WS_POPUP style at the window creation time.
- Just after you obtain hwnd, re-set your windows styles to what you want (but no WS_POPUP again) using SetWindowLong(hwnd,GWL_STYLE, yr_styles);
I had the same problem with OpenGL under Win7 64 bit.
Modal dialog boxes and modal windows are not shown, also they are active in the background.
My project used stereo display (quad buffers).
In my case, the problem was due to an incorrect setting in the control panel of the display adapter (Nvidia Quadro FX3800).
The setting was "Stereo Enabled", which was incorrectly on "off".
Switching it on solved the problem.
when i want, for example, open a filedialog in OpenGL fullscreen (Windows10
or every Windows before), i call
RedrawWindow(hwnd, 0, 0, RDW_INTERNALPAINT);
( this causes a WM_PAINT message to be posted to the window regardless of whether any portion of the window is invalid )
and just after this i call the filedialog.
The filedialog will be shown now in OpenGL fullscreen.
In WndProc inside the case WM_PAINT: i do a SwapBuffers(hdc)
RedrawWindow(hwnd, 0, 0, RDW_INTERNALPAINT);
// important when fullscreen; forces a WM_PAINT message,
GLwin->Fileselect(s_fname); // or whatever dialog
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lparam)
{
switch(message)
{
case WM_PAINT:
SwapBuffers(hdc); // (same as in the render-loop)
break;

Resources