1

I'm trying to create a custom C++ function which I can call from JavaScript. The function is a simple one to just resize the window.

I have the following bits in the following places:

In appshell_extensions_platform.h:

#if defined(OS_WIN)
void ResizeWindow(CefRefPtr<CefBrowser> browser, int width, int height);
#endif

In appshell_extensions_win.cpp:

void ResizeWindow(CefRefPtr<CefBrowser> browser, int width, int height) {
    OutputDebugString(L"ResizeWindow");
    CefWindowHandle hWnd = browser->GetHost()->GetWindowHandle();
    SetWindowPos(hWnd, 0, 0, 0, width, height, SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE);
}

In appshell_extensions.js:

/**
  * Resize the window to the given size.
  *
  * @param {number} width
  * @param {number} height
  *
  * @return None. This is an asynchronous call that sends all return information to the callback.
 */
 native function ResizeWindow();
 appshell.app.resizeWindow = function (width, height) {
     ResizeWindow(width, height);
 };

In appshell_extensions.cpp:

} else if (message_name == "ResizeWindow") {
    // Parameters:
    //  0: int32 - width
    //  1: int32 - height
    int width = argList->GetInt(0);
    int height = argList->GetInt(1);
    ResizeWindow(browser, width, height);
}

Using Visual Studio 2012, I then Build and Debug on the Debug Win32 release. When I open the console, appshell.app.resizeWindow is there as expected. I can call it and it works just fine. If I put additional JavaScript code in the function, it also works.

To the function in appshell_extensions.cpp, I've added OutputDebugString(std::wstring(message_name.begin(), message_name.end()).c_str());. For functions other than the one I wrote, it will output the message name properly. For the one I wrote, I get nothing.

I don't get the output from the function itself either.

It appears that the message isn't actually getting to the function which processes it, but I have no clue. I'm just using the sln that came with brackets-shell (converted to 2012) to compile. Is there a build step I'm maybe missing or something?

Thanks.

hirse
  • 2,394
  • 1
  • 22
  • 24
samanime
  • 25,408
  • 15
  • 90
  • 139

2 Answers2

0

The ProcessMessageDelegate::OnProcessMessageReceived() method (appshell_extension.cpp) in which you try to debug the message name, is running in the Renderer process. You have to attach VS debugger to that subprocess to be able to debug it. Right now you are debugging the Browser process (main process).

For an easy way to debug subprocesses in console window, try creating a console window for each subprocess:

if (show_console) {
    AllocConsole();
    FILE* freopen_file;
    freopen_s(&freopen_file, "CONIN$", "rb", stdin);
    freopen_s(&freopen_file, "CONOUT$", "wb", stdout);
    freopen_s(&freopen_file, "CONOUT$", "wb", stderr);
}

Put this code before CefExecuteProcess() that launches subprocesses.

See how I've done it in the PHP Desktop project:

  1. See the subprocess_show_console variable. https://code.google.com/p/phpdesktop/source/browse/phpdesktop-chrome/main.cpp?r=6de71bd0217a#126

  2. A call to InitializeLogging() that runs the code above.

  3. Then CefExecuteProcess is called.


On Linux it is easier to debug subprocesses in console window, as all the output from subprocesses is automatically forwarded to console from the main process. Windows is missing this neat feature.

Czarek Tomczak
  • 20,079
  • 5
  • 49
  • 56
  • Hi Czarek, thanks for the comment. I do seem to get some output from ProcessMessageDeletegate::OnProcessMessageReceived. The only time I don't is when it is the function I added that is called (or not, as I suspect the case may be). If I call anything else that is there, like the DragWindow function, I see "DragWindow" in my Output. It's just not my own function. – samanime Feb 13 '14 at 21:24
  • @samanime Try rebuilding VS project, it might be some cache issue. Clean it. Rebuild it. – Czarek Tomczak Feb 16 '14 at 09:47
  • @samanime It may be also that you're editing the wrong file or at the wrong time. Edit .js file before rebuilding project. – Czarek Tomczak Feb 16 '14 at 09:57
  • I tried doing both a Rebuild and then manually Clean and Build. Same symptoms. I'm also editing all files before I try building and debugging. Any other ideas? Thanks for the help. – samanime Feb 18 '14 at 18:40
  • @samanime Take a look at "QuitApplication". It's defined only in .js. In your case you're defining it in .h and .cpp. So it's already implemented so there is no reason for it to appear in OnProcessMessageReceived() in appshell_extensions.cpp when it's called. Some functions can be executed immediately in the Renderer process. Some need to be passed to the Browser process and executed from there, using process messaging. Don't forget to +1 if that helped you. – Czarek Tomczak Feb 18 '14 at 19:42
0

I figured out the problem.

Apparently, in the JavaScript functions, the first parameter MUST be a callback, even if you don't use it.

Changing the JavaScript portion to this fixed the problem:

/**
  * Resize the window to the given size.
  *
  * @param {number} width
  * @param {number} height
  *
  * @return None. This is an asynchronous call that sends all return information to the callback.
 */
 native function ResizeWindow();
 appshell.app.resizeWindow = function (width, height) {
     ResizeWindow(_dummyCallback, width, height);
 };

I also had a bit of an issue with the actual resize logic. You need to use the window handle of the browser->getHost()->getWindowHandle() parent:

`CefWindowHandle hWnd = getParent(browser->GetHost()->GetWindowHandle());
samanime
  • 25,408
  • 15
  • 90
  • 139