Get notified in c++ code when button/link clicked on Page

Do not post support requests, bug reports or feature requests. Discuss CEF here. Non-CEF related discussion goes in General Discussion!

Get notified in c++ code when button/link clicked on Page

Postby manish » Tue Feb 11, 2020 12:01 pm

I have created a sample Browser in C++ using CEF sdk which loads my specified URL

I have a situation where i want to recieve notification in my c++ code from my loaded page (example- when i click on specific button/link on page)

i have implemented OnProcessMessageReceived() in my Handler code.
so how to achieve this..
can anyone please provide c++ sample code.

Thank you.
manish
Newbie
 
Posts: 4
Joined: Tue Feb 11, 2020 11:36 am

Re: Get notified in c++ code when button/link clicked on Pag

Postby magreenblatt » Tue Feb 11, 2020 1:05 pm

You can use JavaScript to add an onclick listener and then communicate with native code via JS bindings. See https://bitbucket.org/chromiumembedded/ ... t-bindings
magreenblatt
Site Admin
 
Posts: 12382
Joined: Fri May 29, 2009 6:57 pm

Re: Get notified in c++ code when button/link clicked on Pag

Postby manish » Thu Feb 13, 2020 2:39 am

Thanks for your reply.

I read this link https://bitbucket.org/chromiumembedded/ ... t-bindings
what I understood is, we can run a javascript code through our render process and can recieve message in render process by running this javascript.
but in my case i have scenario like below -->
i have third party website which i need to load in my CEF browser. this website has a href link (ex- "resize me"). by clicking this link it resizes the page. It calls a javascript function to resize itself. (I find the Javascript function name by inspecting this webpage)
Now I also want to resize my CEF Browser window, when user clicks on "resize me" link on webpage to resize the page.
I cannot change code for this website page. What i can do is change our CEF browser window size through our c++ code accordingly.

So how can my c++ code knows when user clicks on the link present on this Website. I just want a callback to my code.
I am new to CEF sdk so can you please help me out with some sample code for handlers.

So far what i did -->

Website Page executes --> "hideShowForm();" javascript function which shrinks the page.

In my Code -->

class CEFApplication : public CefApp, public CefBrowserProcessHandler, public CefRenderProcessHandler, public CefV8Handler
{
virtual CefRefPtr<CefRenderProcessHandler> GetRenderProcessHandler() OVERRIDE { return this; }
virtual CefRefPtr<CefBrowserProcessHandler> GetBrowserProcessHandler() OVERRIDE { return this; }

virtual bool OnProcessMessageReceived(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefProcessId source_process,
CefRefPtr<CefProcessMessage> message) OVERRIDE
{
CefString cefstrFuncName = message->GetName();
// should i get a callback here for function name "hideShowForm();" ...?
}

virtual void OnContextInitialized() OVERRIDE
{

}

virtual void OnWebKitInitialized() OVERRIDE
{

}

virtual bool Execute(const CefString& name,
CefRefPtr<CefV8Value> object,
const CefV8ValueList& arguments,
CefRefPtr<CefV8Value>& retval,
CefString& exception) OVERRIDE
{
if (name == "hideShowForm") // Should I check like this ..?
{ }
return false;
}

virtual void OnContextCreated(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefV8Context> context) OVERRIDE
{
// Retrieve the context's window object.
CefRefPtr<CefV8Value> object = context->GetGlobal();

CefRefPtr<CefV8Handler> handler = new CEFApplication();
CefRefPtr<CefV8Value> func = CefV8Value::CreateFunction("hideShowForm", handler);

// Add the "hideShowForm" function to the "window" object.
object->SetValue("hideShowForm", func, V8_PROPERTY_ATTRIBUTE_NONE);
}

private:
IMPLEMENT_REFCOUNTING(CEFApplication);
};

my code did not hit any breakpoint on any of these above functions.
I might be confused with my understandings.
your help is really appreciated.

Thank you.
manish
Newbie
 
Posts: 4
Joined: Tue Feb 11, 2020 11:36 am

Re: Get notified in c++ code when button/link clicked on Pag

Postby magreenblatt » Thu Feb 13, 2020 4:03 pm

manish wrote:i have third party website which i need to load in my CEF browser. this website has a href link (ex- "resize me"). by clicking this link it resizes the page.

Is it always the same website and resize link? If so, you can probably use JavaScript to replace the default onclick handler with your own version after the website loads. You can then implement your own resize logic as demonstrated in cefclient when loading http://tests/window and implemented in tests/cefclient/browser/window_test* source files.
magreenblatt
Site Admin
 
Posts: 12382
Joined: Fri May 29, 2009 6:57 pm

Re: Get notified in c++ code when button/link clicked on Pag

Postby manish » Thu Feb 20, 2020 8:47 am

Thank you for your reply.

yes it is always the same website and resize link.
as you suggested, I went through implimentation of tests/cefclient/browser/window_test* source files.

I created browser which loads "tests\cefclient\resources\window.html" (available in cef sdk)
and the code as follow:

My CefClient code --
Code: Select all
class CEFHandler :     public CefClient,
                                  public CefLifeSpanHandler,
                                  public CefLoadHandler,
              public CefDisplayHandler,
              public CefDOMVisitor,
              public CefRequestHandler,
              public CefDownloadHandler
{
   virtual CefRefPtr<CefDisplayHandler> GetDisplayHandler() OVERRIDE {
   return this;
   }
   virtual CefRefPtr<CefLifeSpanHandler> GetLifeSpanHandler() OVERRIDE {
   return this;
   }
   virtual CefRefPtr<CefLoadHandler> GetLoadHandler() OVERRIDE {
   return this;
   }
   virtual CefRefPtr<CefRequestHandler> GetRequestHandler() OVERRIDE {   
   return this;
   }
   virtual CefRefPtr<CefDownloadHandler> GetDownloadHandler() OVERRIDE {   
   return this;
   }

   virtual void OnAfterCreated(CefRefPtr<CefBrowser> browser) OVERRIDE;

   CefRefPtr<CefMessageRouterBrowserSide> browser_side_router_;
   CefMessageRouterBrowserSide::Handler* myHandler_;

}

void SetRouterConfig(CefMessageRouterConfig& config) {
  config.js_query_function = "cefQuery";
  config.js_cancel_function = "cefQueryCancel";
}

void CEFHandler::OnAfterCreated(CefRefPtr<CefBrowser> browser)
{
   CefMessageRouterConfig config;
   SetRouterConfig(config);
   browser_side_router_ = CefMessageRouterBrowserSide::Create(config);

   myHandler_ = new Handler();

   bool status = browser_side_router_->AddHandler(myHandler_, true);
}

// Handle messages in the browser process.
class Handler : public CefMessageRouterBrowserSide::Handler
{
 public:
 
  // Called due to cefBroadcast execution in window.html.
  virtual bool OnQuery(CefRefPtr<CefBrowser> browser,
                       CefRefPtr<CefFrame> frame,
                       int64 query_id,
                       const CefString& request,
                       bool persistent,
                       CefRefPtr<Callback> callback) OVERRIDE
  {
     const std::string& url = frame->GetURL();
     const std::string& message_name = request;
   
   if (message_name.find("WindowTest.Position") == 0)
   {
      // do some work.
   }
   else if (message_name == "WindowTest.Minimize")
   {
      MessageBox(NULL, L"Minimize", L"", MB_OK);
   }
   else if (message_name == "WindowTest.Maximize")
   {
      MessageBox(NULL, L"Maximize", L"", MB_OK);
   }
   else if (message_name == "WindowTest.Restore")
   {
      MessageBox(NULL, L"restore", L"", MB_OK);
   }
   else
   {
      NOTREACHED();
   }

    callback->Success("");
    return true;
  }
};


My CefApp code --
Code: Select all
class CEFApplication : public CefApp,  public CefBrowserProcessHandler, public CefRenderProcessHandler
{
 public:
   // CefApp methods.
   virtual CefRefPtr<CefRenderProcessHandler> GetRenderProcessHandler() OVERRIDE {   return this; }
   virtual CefRefPtr<CefBrowserProcessHandler> GetBrowserProcessHandler() OVERRIDE { return this; }

   void OnContextCreated(CefRefPtr<CefBrowser> browser,
                        CefRefPtr<CefFrame> frame,
                        CefRefPtr<CefV8Context> context) OVERRIDE;
   {}
   void OnWebKitInitialized() OVERRIDE;
   {}
   void OnContextInitialized() OVERRIDE;
   {}
   
   virtual bool OnProcessMessageReceived(CefRefPtr<CefBrowser> browser,
                                 CefRefPtr<CefFrame> frame,
                                 CefProcessId source_process,
                                 CefRefPtr<CefProcessMessage> message) OVERRIDE
   {
      CefString cefstrFuncName = message->GetName();
      return false;
   }
   
private:
   IMPLEMENT_REFCOUNTING(CEFApplication);
};


my project settings are as -
Code: Select all
//CEF global settings at start
CefMainArgs main_args(GetModuleHandle(NULL));
CefSettings settings;
settings.multi_threaded_message_loop = true;
settings.log_severity = LOGSEVERITY_DISABLE;
CefRefPtr<CEFApplication> app(new CEFApplication);

CefExecuteProcess(main_args, app.get(), NULL);

// Initialize CEF.
if (!CefInitialize(main_args, settings, app.get(), NULL))
   return;



I put debug break point on OnQuery. But this breakpoint never hit.
I did not get any callback to my OnQuery() function after pressing buttons on "tests\cefclient\resources\window.html"

Am I doing anything wrong in my code or anything that I am missing.
Please help me.

Thanks in Advanced.
manish
Newbie
 
Posts: 4
Joined: Tue Feb 11, 2020 11:36 am

Re: Get notified in c++ code when button/link clicked on Pag

Postby magreenblatt » Thu Feb 20, 2020 11:24 am

See the list of necessary changes at https://bitbucket.org/chromiumembedded/ ... ge_router/
magreenblatt
Site Admin
 
Posts: 12382
Joined: Fri May 29, 2009 6:57 pm

Re: Get notified in c++ code when button/link clicked on Pag

Postby manish » Tue Feb 25, 2020 12:16 pm

Thanks for reply.

As per your suggestion I went through https://bitbucket.org/chromiumembedded/ ... ge_router/
I corrected my code accordingly.
But still OnQuery callback does not hit.

My CEF settings are --

CefSettings settings;
settings.multi_threaded_message_loop = true;

Is it creating problem?

I do not want to show browser window as POPUP window so I created browser window as follows:
Code: Select all
BOOL MyMFCDlg::OnInitDialog()
{
   CDialogEx::OnInitDialog();
        ...

       RECT rect;
       GetDlgItem(IDC_STATIC_BROWSER)->GetClientRect(&rect);
       window_info.SetAsChild( GetDlgItem(IDC_STATIC_BROWSER)->GetSafeHwnd(), rect );

      CefBrowserHost::CreateBrowser(window_info, new Client(), CefString(m_wstrHomePageUrl.c_str()), browser_settings, NULL, NULL);

      ...

}


where IDC_STATIC_BROWSER is the ID of Picture control of my MFC window. (where I want to show browser window)

Please help in designing above code as I already went through CEF documentation but not getting my things done.

Thank you.
manish
Newbie
 
Posts: 4
Joined: Tue Feb 11, 2020 11:36 am


Return to CEF Discussion

Who is online

Users browsing this forum: No registered users and 16 guests