Overview
Examples
Screenshots
Comparisons
Applications
Download
Documentation
Tutorials
Bazaar
Status & Roadmap
FAQ
Authors & License
Forums
Funding Ultimate++
Search on this site
Search in forums












SourceForge.net Logo
Home » U++ Library support » U++ Core » LaunchWebBrowser() problem and perhaps not the best solution
LaunchWebBrowser() problem and perhaps not the best solution [message #35714] Wed, 14 March 2012 11:40 Go to next message
koldo is currently offline  koldo
Messages: 3355
Registered: August 2008
Senior Veteran
Hello all

In my XP LaunchWebBrowser() does not work because of ShellExecute.

A possible solution proposed here ( http://stackoverflow.com/questions/1193873/which-reasons-cou ld-make-shellexecute-fail) is to create a separate thread for executing ShellExecute.
The reason could be this one(Calling Shell Functions and Interfaces from a Multithreaded Apartment: http://support.microsoft.com/?scid=kb%3Ben-us%3B287087&x =16&y=15).

The solution works for me. First call to ShellExecuteOpen() fails but second one in a separate thread, works.
However I am not sure if it is a right implementation. Please check it before approve.


#if defined(PLATFORM_WIN32) && !defined(PLATFORM_WINCE)
bool ShellExecuteOpen(const char *str)
{
	return 32 < int(ShellExecuteW(NULL, L"open", ToSystemCharsetW(str), NULL, L".", SW_SHOWDEFAULT));
}

void LaunchWebBrowser(const String& url)
{
	if (!ShellExecuteOpen(url)) {
		HANDLE handle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&ShellExecuteOpen, (LPVOID)~url, 0, NULL);
		if (handle == NULL)
			return;
		WaitForSingleObject(handle, 500);
		CloseHandle(handle);
	} 
}
#endif



Best regards
Iñaki
Re: LaunchWebBrowser() problem and perhaps not the best solution [message #35731 is a reply to message #35714] Wed, 14 March 2012 22:37 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
koldo wrote on Wed, 14 March 2012 06:40

Hello all

In my XP LaunchWebBrowser() does not work because of ShellExecute.

A possible solution proposed here ( http://stackoverflow.com/questions/1193873/which-reasons-cou ld-make-shellexecute-fail) is to create a separate thread for executing ShellExecute.
The reason could be this one(Calling Shell Functions and Interfaces from a Multithreaded Apartment: http://support.microsoft.com/?scid=kb%3Ben-us%3B287087&x =16&y=15).

The solution works for me. First call to ShellExecuteOpen() fails but second one in a separate thread, works.
However I am not sure if it is a right implementation. Please check it before approve.


#if defined(PLATFORM_WIN32) && !defined(PLATFORM_WINCE)
bool ShellExecuteOpen(const char *str)
{
	return 32 < int(ShellExecuteW(NULL, L"open", ToSystemCharsetW(str), NULL, L".", SW_SHOWDEFAULT));
}

void LaunchWebBrowser(const String& url)
{
	if (!ShellExecuteOpen(url)) {
		HANDLE handle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&ShellExecuteOpen, (LPVOID)~url, 0, NULL);
		if (handle == NULL)
			return;
		WaitForSingleObject(handle, 500);
		CloseHandle(handle);
	} 
}
#endif




Looks quite OK with me. Maybe the WaitForSingleObject is not needed...

Mirek
Re: LaunchWebBrowser() problem and perhaps not the best solution [message #35737 is a reply to message #35731] Thu, 15 March 2012 08:41 Go to previous messageGo to next message
koldo is currently offline  koldo
Messages: 3355
Registered: August 2008
Senior Veteran
Hello Mirek

In fact WaitForSingleObject() is useless as it always wait the timeout.

However I realized that sometimes the string passed is released BEFORE the thread is really run so second call to ShellExecuteW() fails as LaunchWebBrowser() has ended before Smile.

The proposed solution is this one:

void ShellExecuteOpen(char *str)
{
	ShellExecuteW(NULL, L"open", ToSystemCharsetW(str), NULL, L".", SW_SHOWDEFAULT);
	free((void *)str);
}

void LaunchWebBrowser(const String& url)
{
	if (int(ShellExecuteW(NULL, L"open", ToSystemCharsetW(url), NULL, L".", SW_SHOWDEFAULT)) <= 32) {
		char *curl = (char *)malloc(url.GetLength()+1);
		strcpy(curl, url);
		HANDLE handle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&ShellExecuteOpen, (LPVOID)curl, 0, NULL);
		if (handle == NULL)
			return;
		CloseHandle(handle);
	} 
}


The thread receives the string and releases it.


Best regards
Iñaki
Re: LaunchWebBrowser() problem and perhaps not the best solution [message #35946 is a reply to message #35737] Sun, 08 April 2012 16:15 Go to previous messageGo to next message
koldo is currently offline  koldo
Messages: 3355
Registered: August 2008
Senior Veteran
Hello Mirek

Could you check this?


Best regards
Iñaki
Re: LaunchWebBrowser() problem and perhaps not the best solution [message #35953 is a reply to message #35946] Sun, 08 April 2012 17:02 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
I have found a bug, IMO you should not have to use ToSystemCharsetW in thread, if you want this to work in U++ single-threaded mode...

After fixing this, commited.

Also used new "raw thread support".

Please check.

Mirek
Re: LaunchWebBrowser() problem and perhaps not the best solution [message #35954 is a reply to message #35953] Sun, 08 April 2012 18:30 Go to previous messageGo to next message
koldo is currently offline  koldo
Messages: 3355
Registered: August 2008
Senior Veteran
Curious the "raw thread support".

Best regards
Iñaki
Re: LaunchWebBrowser() problem and perhaps not the best solution [message #35955 is a reply to message #35954] Sun, 08 April 2012 19:10 Go to previous message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
koldo wrote on Sun, 08 April 2012 12:30

Curious the "raw thread support".


Will add note to development blog...

[Updated on: Sun, 08 April 2012 19:10]

Report message to a moderator

Previous Topic: bug in http.cpp
Next Topic: Little problem in util.cpp and simple solution
Goto Forum:
  


Current Time: Fri Mar 29 14:41:27 CET 2024

Total time taken to generate the page: 0.01461 seconds