Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    Opening a maxon::URL in the browser: Anchors and query parameters?

    Cinema 4D SDK
    r20 r21 s22 r23 c++
    2
    5
    676
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • fwilleke80F
      fwilleke80
      last edited by fwilleke80

      Follow-up to: How do I open a maxon::Url in the default web browser?

      Hi,

      I am trying to open a maxon::URL in the browser. It basically works, but lacks essential support for HTML anchors (delimited with "#") and - even more important - does not seem to handle query parameters (starting with "?" and separated with "&") correctly by default.

      Here is some code about the latter. I want to open the website where potential customers can request an activation key for my plugin:

      // Build request query string
      maxon::BaseArray<maxon::String> urlQueryParts;
      if (licensingInfo.firstName.IsPopulated())
      {
      	urlQueryParts.Append("firstname="_s + licensingInfo.firstName) iferr_ignore();
      }
      if (licensingInfo.lastName.IsPopulated())
      {
      	urlQueryParts.Append("lastname="_s + licensingInfo.lastName) iferr_ignore();
      }
      if (licensingInfo.organization.IsPopulated())
      {
      	urlQueryParts.Append("organization="_s + licensingInfo.organization) iferr_ignore();
      }
      if (licensingInfo.systemCode.IsPopulated())
      {
      	urlQueryParts.Append("inputcode="_s + licensingInfo.systemCode) iferr_ignore();
      }
      const maxon::String urlQueryString(JoinElements(urlQueryParts, "&"_s));
      
      // Build request URL
      maxon::Url url(GeLoadString(IDS_DEMOKEYGENERATORURL));
      url.Set(maxon::URLFLAGS::QUERY, urlQueryString) iferr_ignore();
      
      // DEBUG: Print URL to console
      maxon::String urlString = url.ToString(nullptr);
      GePrint(urlString);
      
      // Open URL in browser
      url.IoShowInOS(maxon::IOSHOWINOSFLAGS::OPEN_IN_EXPLORER) iferr_ignore();
      

      The part with adding the query parameters to the URL works fine, even though I think it's quite a lot of code for something so simple. I'm doing it this way, because the SDK docs about UrlInterface::SetUrl() kind of hints to this.

      The GePrint(urlString) call prints the following:

      https://demo.mypluginsite.com?firstname=Arthur&lastname=Dent&inputcode=14004902462
      

      So, that looks like exactly what I need. However, when calling url.IoShowInOS(), Safari tries to open this URL:

      https://demo.mypluginsite.com%3ffirstname=arthur&lastname=dent&inputcode=14004902462
      

      And when I set my MacBook's default browser to Chrome instead, Chrome just opens a new tab at about:blank. This happens on my old macBook with El Capitan as well as on a new iMac with macOS Catalina.

      My questions:

      • Why are the firstname and lastname values lower-case, and how can I prevent that from happening?
      • Why is the "?" before the query parameters escaped, and how can I prevent that from happening?
      • Why does Chrome not open the URL at all?

      Thanks for help & advice!

      Cheers,
      Frank

      www.frankwilleke.de
      Only asking personal code questions here.

      1 Reply Last reply Reply Quote 0
      • fwilleke80F
        fwilleke80
        last edited by fwilleke80

        In Python, it's dead simple to open the default web browser with a URL and query parameters.

        import webbrowser
        URL = "https://demo.mypluginsite.com?firstname=Arthur&lastname=Dent&inputcode=12312312320"
        webbrowser.open(URL)
        

        Guess, if Maxon::URL can't do that, I'll have to write a Python plugin and call it from within my C++ code πŸ˜•

        Cheers,
        Frank

        www.frankwilleke.de
        Only asking personal code questions here.

        1 Reply Last reply Reply Quote 0
        • fwilleke80F
          fwilleke80
          last edited by fwilleke80

          I ended up solving the problem with Python. Still, I would really appreciate some feedback from Maxon about why this doesn't work, if something can be done to fix it (and what), or a confirmation that it's actually a bug in Cinema. As things are now, maxon::Url::IoShowInOS() is not really usable to open URLs in the web browser. And that's a pity, because it would be really useful, too e.g. open a help website from within a PluginHelpDelegate.

          Here's my solution (works in R20 - R23):

          #include "ge_prepass.h"
          #include "operatingsystem.h"
          #include "maxon/vm.h"
          #include "maxon/cpython.h"
          #if API_VERSION >= 23000
          // R23+: Load Python 3
          #include "maxon/cpython37_raw.h"
          #else
          // Pre-R23: Load Python 2.7
          #include "maxon/cpython27_raw.h"
          #endif
          #if API_VERSION >= 22000
          #include "maxon/errortypes.h"
          #endif
          #include "c4d_general.h"
          #include "lib_py.h"
          
          ///
          /// \brief Simplified version of the ExecutePythonScript() example from the SDK docs
          ///
          maxon::Result<void> ExecutePythonCodeSimple(const maxon::String &code)
          {
          	iferr_scope;
          
          	// Check code
          	if (code.IsEmpty())
          		return maxon::IllegalArgumentError(MAXON_SOURCE_LOCATION);
          
          	// Create VM ref and scope
          #if API_VERSION >= 23000
          	const maxon::VirtualMachineRef& vm = MAXON_CPYTHON37VM();
          #else
          	const maxon::VirtualMachineRef& vm = MAXON_CPYTHON27VM();
          #endif
          	const maxon::VirtualMachineScopeRef scope = vm.CreateScope() iferr_return;
          
          	// Init script
          	iferr (scope.Init("Python Script"_s, code, maxon::ERRORHANDLING::PRINT, nullptr))
          	{
          		const String errorMessage = "Error on Init()"_s;
          		return maxon::UnknownError(MAXON_SOURCE_LOCATION, errorMessage);
          	}
          
          	// set __name__ = __main__
          	scope.Add("__name__"_s, maxon::Data("__main__"_s)) iferr_return;
          
          	// executes the script and returns when it got executed.
          	// info: if the script causes an unexpected infinite loop, Execute() does not return
          	// and there is no way to stop from the outside.
          	iferr (scope.Execute())
          	{
          		const String errorMessage = "Error on Execute()"_s;
          		return maxon::UnknownError(MAXON_SOURCE_LOCATION, errorMessage);
          	}
          
          	return maxon::OK;
          }
          

          And I'm using it like this:

          maxon::Result<void> OpenUrlInBrowser(const maxon::Url &url)
          {
          	iferr_scope;
          
          	maxon::String urlString = url.ToString(nullptr);
          
          	// Build Python code
          	maxon::String theCode;
          	theCode = "import webbrowser\n"_s;
          	theCode += "URL = \""_s + urlString + "\"\n"_s;
          	theCode += "webbrowser.open(URL)\n"_s;
          
          	// Execute code
          	TF4D::Python::ExecutePythonCodeSimple(theCode) iferr_return;
          
          	return maxon::OK;
          }
          

          Greetings,
          Frank

          www.frankwilleke.de
          Only asking personal code questions here.

          1 Reply Last reply Reply Quote 0
          • M
            m_adam
            last edited by

            Hi @fwilleke80 I can indeed confirm the issue, and I will create a bug report about it.
            This is the mac only issue and with Chrome on Windows everything work as expected.

            Regarding your Python implementation, it's alright to do it as you did πŸ˜‰

            Have a nice weekend,
            Cheers,
            Maxime.

            MAXON SDK Specialist

            Development Blog, MAXON Registered Developer

            1 Reply Last reply Reply Quote 0
            • fwilleke80F
              fwilleke80
              last edited by fwilleke80

              Thanks for confirming!

              The strange thing is that I can reproduce this even in R20. Seems, not many people use this function to open URLs.

              I'll mark this as solved then, as my solution presented in this thread works flawlessly on all R2x releases.

              Cheers,
              Frank

              www.frankwilleke.de
              Only asking personal code questions here.

              1 Reply Last reply Reply Quote 0
              • First post
                Last post