Load URL in Default Browser and Bring to Front - c++

I have a fullscreen application written in c++ using straight winapi. The application contains an embedded web browser (using CEF, but I don't think that matters in this case). I am currently intercepting any popup windows as the result of clicking on a link and opening them in the systems default browser using ShellExecute. However, on many of our test systems the browser window is displayed behind my application window, which is a problem since my window covers up the task bar so the user has no indication that a new window has been displayed.
I've read everything I can find on this site and others and have not been able to find a single solution that works:
Using ShellExecuteEx to get the process handle, then using the process handle to find the window handle and bringing it to the front - Many times the process handle is NULL, which appears to be related to the browser opening a new tab in an existing window. In addition, if Edge is the default browser then the process handle always seems to be NULL.
Using ShellExecute (or Ex) then finding the new window based on the name - I have no idea what the name of the window will be. It's based on the content that is opened, which may be many different things depending on the link the user clicked (html, pdf, etc).
Attempting to figure out the path to the default browser and then launching it using CreateProcess - So far I haven't had any luck with this if Edge is the default (since apparently Edge is a "modern" application that doesn't have an executable that can be launched with CreateProcess). If anyone knows how to make this work I could see this actually being a decent solution.
So right now I'm heading down a path of enumerating all of the windows before and after launching the browser and attempting to figure out which one is the correct one to bring forward. I'm envisioning all sorts of issues that could possibly occur (a tab opening on an existing browser for instance). If anyone has any solution to the issue I would appreciate it!
Edit: Code I'm using for ShellExecuteEx:
SHELLEXECUTEINFO sxi = { 0 };
sxi.cbSize = sizeof( sxi );
sxi.nShow = SW_NORMAL;
sxi.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_NOASYNC | SEE_MASK_WAITFORINPUTIDLE;
sxi.lpVerb = _T( "open" );
sxi.lpFile = url;
if( ShellExecuteEx( &sxi ) )

Related

Creating two or more CEF browser windows

I have been suffering for two weeks, please help me:
And I use the built-in CEF example - "cefsimple" - it works fine: https://bitbucket.org/chromiumembedded/cef/src/master/tests/cefsimple/?at=master
The "cefsimple" example creates a browser window and opens the specified URL in it.
But as soon as I add another browser window creation feature:
CefBrowserHost::CreateBrowser(window_info, my_browser_handler_, "google.com", browser_settings, nullptr, nullptr);
That's where the problems happen.
The second browser window is being created, BUT a problem occurs - the two created windows seem to blink constantly, as if switching between each other very quickly.
I tried the advice - install:
window_info.ex_style = WS_EX_NOACTIVATE;
But it doesn't help at all.
Maybe someone has created more than one window browser in CEF ? What am I doing wrong ?
I've encounter this problem recently, and this may help you.
In your native window proc, process WM_SETFOCUS with:
if (!::GetFocus())
{
// set cef focus;
}
Without call ::GetFocus(), two cef windows will blink constantly.

Open a new browser tab without losing focus on current application using C++

I would like to open a new browser tab using C++ on Windows, ideally browser-independent, if that is not possible chrome is good enough.
But there are some restrictions:
The current application can not lose focus, but the browser must switch to the new tab.
The tab must be opened to a specific URL
The tab must be opened from a 3rd party application, so not from inside the browser.
I have tried using system("start <url>") but that causes the application focus to switch to the browser. I could not find a chrome:// URL to open a new tab with an initial URL.
I have also found several threads showing similar things in JavaScript, but none for C++.
Is there a way (ideally safer than using system()) to open a new browser tab without losing focus on the current application, using C++ on windows?
Additional clarification:
3 windows open: One game, the browser and a 3rd party application.
The game is in the foreground, but the 3rd party application opens the browser tab on certain events. Sadly, this means that DLL injection is not an option, due to several anti-cheat restrictions. This also means that a background application needs to open a new browser tab of a browser that is also in the background without ever losing focus on the game.

How to prevent "How do you want to open this file" dialog?

In my app I open a report using HTML file as such:
//pStrPath is file:///C:/Users/appts/AppData/Local/Temp/Report_View.htm
ShellExecute(hParentWnd, L"", pStrPath, NULL, NULL, SW_SHOW);
On my development machine it opens up in a web browser, but when I just tested it on a new installation of Windows 10, it showed this dialog instead:
So how can I prevent it from being shown and go with "keep using this app" option from the get-go? Otherwise it may be very confusing for my users.
PS. Note that Edge is installed and can open .htm files if I double-click them.
Referring to Launching Applications (ShellExecute, ShellExecuteEx, SHELLEXECUTEINFO) we note the text
Object Verbs
The verbs available for an object are essentially the items that you find on an object's shortcut menu. To find which verbs are available, look in the registry under HKEY_CLASSES_ROOT\CLSID{object_clsid}\Shell\verb
Commonly available verbs include:
edit - Launches an editor and opens the document for editing.
find - Initiates a search starting from the specified directory.
open - Launches an application. If this file is not an executable
file, its associated application is launched.
print - Prints the document file.
properties - Displays the object's properties.
Given that a double-click is the generally equivalent to selecting "open" in the object's shortcut menu, if we supply the function with the open verb, we can expect the behaviour to mirror that of a user's double-click. - Please see Ken's comment below
As such, we can expect the following code to achieve the desired result.
//pStrPath is file:///C:/Users/appts/AppData/Local/Temp/Report_View.htm
ShellExecute(hParentWnd, L"open", pStrPath, NULL, NULL, SW_SHOW);
If you are trying to open the default program FROM a 32 bit program in 64 bit Windows the ShellExecute and ShellExecuteEX may display the "How do you want to open this file?" dialog box each time. This is due to the way that the default program registered itself in Windows I think.
I could reproduce this error on Windows 11 fresh install where the Photos is set to the Default Program for .jpg files.
In my case, I found that if I use the ShellExecuteExW function and pass the extension into the .lpClass of SHELLEXECUTEINFOW Type that it works.
It should also work with the ShellExecuteExA function
Make sure it's not an exe, reg, bat file, or a URL you are trying to open. It has to be a document type of file.
Use the .lpClass to pass the extension like ".jpg"
Add the SEE_MASK_CLASSNAME As Long = &H1 to the .fMask parameter you are passing in like .fMask = YourMaskValue Or SEE_MASK_CLASSNAME
The reason I think this works is it bypasses any redirection and reads directly from the HKEY_CLASSES_ROOT.jpg

How to lock Windows 7 into a single program with C++?

I have been working on an app in Visual Studio 2015 (C++). It's a kiosk app for my school's tech support. Basically, it's a support site that will run in a kiosk. I need to figure out how to lock windows so it only runs that program. It would also be helpful to run the program in fullscreen mode. Keep in mind that all of the kiosks run Windows 7.
Set registry key
HKCU SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon
Shell="c:\path\to\whatever.exe"
Disallow task manager via security of taskmgr.exe (add a deny read + deny execute to the binary)
Set autologn:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon
DefaultUserName = whatever
DefaultPassword = whatever
Have a boot disk handy. The only way to reverse this is to boot the boot disk and undo one of the steps after mounting the appropriate hive.
you can create your program with main window in full screen mode and popup:
hWnd = CreateWindowEx(WS_EX_CLIENTEDGE|WS_EX_APPWINDOW|WS_EX_TOPMOST,
lpClsName,
"MDI Project under Visual C++ WINAPI",
WS_BORDER|WS_POPUP,
...);// add the remaining parameters
and find taskmgr.exe and hide it and start menu button and hide them also:
hTaskBar = ::FindWindow ("Shell_TrayWnd", "");
hStart = ::FindWindowEx(GetDesktopWindow(), NULL, "Button", "Start");
ShowWindow(hTaskBar, SW_HIDE);
ShowWindow(hStart, SW_HIDE);
so your program looks like easycafe or handycafe
I actually switched from C++ to C#, so I'm gonna explain my answer with C#.
I used a keyboard hook library to capture keyboard input and block all non-letter/number input so alt-f4, alt-tab etc. would not work. I then determined a closing sequence of characters using another keyboard hook (LWin+C+Home+F12+PrtSc).
As for Ctrl-Alt-Del, that cannot be disabled (as far as I know) because it is a system function, so I just left that as it is.
I also got the bounds of the screen and set the size of the window to the maximum screen size at application launch, as well as whenever the app is resized or moved. This essentially makes it so the app covers the task bar, and the bar with the close and minimize buttons is also covered, but if someone found a way to move it it would immediately go back to it's full size.
I also set up autologin as was detailed in a previous answer, but I just didn't do it through code.

Check Which Website is Visited

I've been having trouble finding a way to check if the user of the program is visiting a specific website. If I wanted to open a pop up box telling me which website I was currently on, what would be the best way to do it?
I've been thinking about various ways but I can never come to a definite conclusion. Thought about checking which browser is open by browsing the processes or checking the window, but how would I find it out? Even if I didn't find out exact website address but just the name, would be fine.
For example, right now the window open says 'Check Which Website is Visited - Stack Overflow - Mozilla Firefox', is there a way to get that from a programming standpoint? Like somehow check and read what windows are currently open.
Thanks for any help.
To get the title of the active window use this code:
HWND hwnd = GetForegroundWindow();
CString title;
LPTSTR str = title.GetBufferSetLength(GetWindowTextLength(hwnd));
GetWindowText(hwnd, str, title.GetLength() + 1);
if (title.IsEmpty())title = _T("User Desktop");
...
The active window will be under "title".
To get the active running application use this code:
DWORD pid;
GetWindowThreadProcessId(GetForegroundWindow(), &pid);
HANDLE hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid);
if (hProcess != NULL)
{
TCHAR path[MAX_PATH] = { 0 };
TCHAR filename[MAX_PATH] = { 0 };
GetProcessImageFileName(hProcess, path, MAX_PATH);
_wsplitpath(path, NULL, NULL, filename, NULL);
CloseHandle(hProcess);
...
filename will hold the active application
Getting the exact URL of the current site from a web browser is going to be specific to each browser. In most cases the easiest way is going to be creating a browser plugin or extension that your application can communicate with to retrieve the desired information. Whether that is a viable option or not is going to be specific to what you are trying to do and whether the user is willing to install the plugin. A lot of applications such as Yahoo Messenger used to do this to integrate messenger functionality into the browser but I don't know if they still do.
Even retrieving just the title is going to be problematic as each browser is different. In some cases you can use GetWindowText to retrieve the caption bar title. Unfortunately browsers such as Internet Explorer and Chrome use tabs or custom embedded controls to present that information to users so using GetWindowText is of limited use in this case.
In order to use GetWindowText to retrieve the text in the caption bar you will have to obtain the handle to the specific web browser window though. You can do this with EnumWindows and use information like process ID with that owns the window or the window class (not a C++ class) to determine if it's a browser window. You will also need to deal with the possibility that there could be more than own browser window open. In this case you could prompt the user with a list of titles and have them select one, it just depends on what you are actually trying to accomplish.