(C++ windows) Open default web browser

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
xDan
Competition winner
Posts: 673
Joined: Thu Mar 30, 2006 1:23 pm
Location: UK
Contact:

(C++ windows) Open default web browser

Post by xDan »

I know this isn't irrlicht specific but it may be useful to anyone developing a shareware game.

Code: Select all

#include <windows.h>
#include <string>

bool runApp(char *appName)
{
    STARTUPINFO sinfo;
    FillMemory(&sinfo, sizeof(STARTUPINFO), 0);
    sinfo.cb = sizeof(STARTUPINFO);

    PROCESS_INFORMATION pinfo;

    if (CreateProcess(NULL, appName, NULL, NULL, FALSE,
        NORMAL_PRIORITY_CLASS, NULL,
        NULL, // current dir
        &sinfo,
        &pinfo)
        )
    {
        CloseHandle(pinfo.hProcess);
        CloseHandle(pinfo.hThread);
        return true;
    }
    return false;
}

void openWebpage(char *page)
{
    // modified from http://www.codeproject.com/internet/urlnewwindow.asp
    
    std::string strBrowser;
    
    HKEY hKey = NULL;
    if (RegOpenKeyEx(HKEY_CLASSES_ROOT, "http\\shell\\open\\command", 0, KEY_READ, &hKey) == ERROR_SUCCESS)
    {
        DWORD cbData = 0;
        if (RegQueryValueEx(hKey, NULL, NULL, NULL, NULL, &cbData) == ERROR_SUCCESS && cbData > 0)
        {
            TCHAR *psz = new TCHAR[cbData];
            if (psz != NULL)
            {
                if (RegQueryValueEx(hKey, NULL, NULL, NULL, (LPBYTE)psz, &cbData) == ERROR_SUCCESS)
                {
                    strBrowser = psz;
                }
                delete [] psz;
            }
        }
        RegCloseKey(hKey);
    }
    
    if (strBrowser.length() > 0)
    {
        std::string::size_type nStart = strBrowser.find('"', 0);
        
        // if first is a quote, then exe path is in quotes, so find the second quote
        if (nStart == 0)
        {
            std::string::size_type nEnd = strBrowser.find('"', 1);
            if (nStart != nEnd && nEnd != std::string::npos)
            {
                strBrowser = strBrowser.substr(nStart+1, nEnd-nStart-1);
            }
        }
        // otherwise if no quotes, 2nd point is the first space after the last backslash
        else
        {
            std::string::size_type nIndex = strBrowser.rfind('\\', strBrowser.length()-1);
            if (nIndex != std::string::npos)
            {
                std::string::size_type nSpace = strBrowser.find(' ', nIndex);
                if (nSpace != std::string::npos)
                {
                    strBrowser = strBrowser.substr(0, nSpace);
                }
            }
        }
        
        std::string command = "\"";
        command += strBrowser;
        command += "\" \"";
        command += page;
        command += "\"";
        
        if (runApp((char *)command.c_str()))
        {
            return;
        }
    }
    
    ShellExecute(NULL, "open", page, NULL, NULL, SW_SHOWNORMAL);
}
To use: openWebpage("http://irrlicht.sourceforge.net");
Last edited by xDan on Wed Jul 04, 2007 6:53 pm, edited 3 times in total.
BlindSide
Admin
Posts: 2821
Joined: Thu Dec 08, 2005 9:09 am
Location: NZ!

Post by BlindSide »

Wow Im sure "runApp" will be useful too. I noticed in your game you had this and wondered how you did it. Thank you.
kompromis
Posts: 98
Joined: Mon Sep 11, 2006 2:36 pm
Location: sweden/stockholm

Post by kompromis »

just using system("url"); is allot easier
white tiger
Posts: 269
Joined: Tue Oct 31, 2006 3:24 pm
Contact:

Post by white tiger »

i have winxp, go to the DOS shell, type "url", press enter, but it seem not working. unknow command :(
Perceval
Posts: 158
Joined: Tue May 30, 2006 2:42 pm

Post by Perceval »

You have to type :
start theUrl
white tiger
Posts: 269
Joined: Tue Oct 31, 2006 3:24 pm
Contact:

Post by white tiger »

work. thanks
xDan
Competition winner
Posts: 673
Joined: Thu Mar 30, 2006 1:23 pm
Location: UK
Contact:

Post by xDan »

kompromis wrote:just using system("url"); is allot easier
Yes, however there are two problems with that:

1) it opens in an existing window (at least with IE)
2) your app hangs while waiting for the browser to load (and sometimes even for the entire life of the new process).
Midnight
Posts: 1772
Joined: Fri Jul 02, 2004 2:37 pm
Location: Wonderland

Post by Midnight »

xDan wrote:
kompromis wrote:just using system("url"); is allot easier
Yes, however there are two problems with that:

1) it opens in an existing window (at least with IE)
2) your app hangs while waiting for the browser to load (and sometimes even for the entire life of the new process).
1. using console it opens in a new tab with newest IE.
2. so pause your app code manually take the load off or run an app that launches it returns and shutsdown.
xDan
Competition winner
Posts: 673
Joined: Thu Mar 30, 2006 1:23 pm
Location: UK
Contact:

Post by xDan »

using console it opens in a new tab with newest IE.
Oh, well done. It doesn't in some browsers or I wouldn't have bothered posting this. :roll:
CuteAlien
Admin
Posts: 9927
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Post by CuteAlien »

I just had to figure that out for a linux system, so i might share also.

Many linux systems have no default browser, but i found a gpl script which i could modify slightly, so that it now starts a browser on most systems. Btw. don't worry about the gpl-license here, the script is an own application so you can still call it from within an application without having to release your own sources.

The script is called "open_browser.sh":

Code: Select all

#!/bin/sh
# Try to find a browser and start it with the parameters given to this script
# Terms of the GNU General Public License apply

HOMEPAGE=$@
BROWSER=`which htmlview`

if [ ! -x "$BROWSER" ]; then
	
	BROWSER=`which firefox`
	if [ ! -x "$BROWSER" ]; then
		
		BROWSER=`which opera`
		if [ ! -x "$BROWSER" ]; then
	
			BROWSER=`which mozilla`
			if [ ! -x "$BROWSER" ]; then
	
				BROWSER=`which konqueror`
				if [ ! -x "$BROWSER" ]; then
	
					BROWSER=`which galeon`
					if [ ! -x "$BROWSER" ]; then

						BROWSER=`which iceweasel`
						if [ ! -x "$BROWSER" ]; then

							BROWSER=`which netscape`
							if [ ! -x "$BROWSER" ]; then
								echo Please start your favorite webbrowser and open:
								echo $@
								exit 1
							fi
						fi
					fi
				fi
			fi
		fi
	fi
fi

$BROWSER $HOMEPAGE &
All i have to do now is to call that script:

Code: Select all

// that code is in the public domain

// you need to set the name used for your script here
#define BROWSER_SCRIPT "open_browser.sh"

void openWebpage(char *page) 
{
    int pid;
    switch ( pid=fork())
    {
        case 0: // child
            execl(BROWSER_SCRIPT, BROWSER_SCRIPT, page, (char*)0);

            // should never be reached
            perror("execl failed");
            exit(2);
        case -1:
            perror("fork failed");
            exit(2);
        default:
            // just continue
            break;
    }
}
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Halan
Posts: 447
Joined: Tue Oct 04, 2005 8:17 pm
Location: Germany, Freak City
Contact:

Post by Halan »

nice, but what files do i need to link?

greets,
halan
Ico
Posts: 289
Joined: Tue Aug 22, 2006 11:35 pm

Post by Ico »

Under Windows I use "ShellExecute" for such things as it allows me to specify the action (lpOperation) to perform too (i.e. for html documents/urls you might try "opennew" instead of just plain "open" - didn't test it on urls however :) ).
CuteAlien
Admin
Posts: 9927
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Post by CuteAlien »

@Halan: Do you get any linker errors? If you paste them we might be able to tell what you are missing.

@Ico: When you check xDan's code you see that he also uses ShellExecute if everything else fails. I tried also to get along with just using ShellExecute at first, but it had some problems. For example sometimes web pages would be opened in tiny browser windows.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Halan
Posts: 447
Joined: Tue Oct 04, 2005 8:17 pm
Location: Germany, Freak City
Contact:

Post by Halan »

sry its in german but i think you can read the functions so...
CLauncher.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__RegCloseKey@4" in Funktion ""public: void __thiscall CLauncher::openWebpage(char *)" (?openWebpage@CLauncher@@QAEXPAD@Z)".
CLauncher.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__RegQueryValueExA@24" in Funktion ""public: void __thiscall CLauncher::openWebpage(char *)" (?openWebpage@CLauncher@@QAEXPAD@Z)".
CLauncher.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__RegOpenKeyExA@20" in Funktion ""public: void __thiscall CLauncher::openWebpage(char *)" (?openWebpage@CLauncher@@QAEXPAD@Z)".
..\Bin\Client\ProjectFreedom.exe : fatal error LNK1120: 3 nicht aufgelöste externe Verweise.
greets,
halan
CuteAlien
Admin
Posts: 9927
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Post by CuteAlien »

According to msdn (http://msdn2.microsoft.com/en-us/library/ms724911.aspx) you need Advapi32.lib
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Post Reply