Using Juce in an existing Windows Application (CWinApp)

Hi
No request or question here, just sharing my CWinApp / Juce cohabitation experience for whoever it might be useful to.
I have a Windows CWinApp application (which development started long time before JUCE even existed) and use some JUCE core, Audio processors and a bit of UI in it. Until then I had nothing else to do than to start juce::initialiseJuce_GUI() in MyWinApp::InitInstance() and juce::shutdownJuce_GUI() in MyWinApp::ExitInstance() to have everything working.
But recently I wanted Juce VST hosting to report something else than “Juce VST Host” since some VST plug-ins don’t behave the same according the reported host. With the existing VSTPluginFormat code this requires running a JUCEApplication.
I can’t and don’t want to change my whole CWinApp into a JUCEApplication, and the CWinApp already deals with the Message loop so I created a fake Juce App class, just enough to specify Application Name, version, and have JUCEApplicationBase::appInstance member non null.
First the fake class definition:

class MyJuceApp : public juce::JUCEApplicationBase
{
public:
    void setMfcApp(CWinApp* app) { mfcApp = app; }
    CWinApp* getMfcApp() const { return mfcApp; }
    const juce::String getApplicationName() override {return "My Application";}
    const juce::String getApplicationVersion() override { return __PRODUCTVERSION__;}
    bool moreThanOneInstanceAllowed() override {return false;}
    void initialise(const juce::String& ) override {}
    void shutdown() override {}
    void anotherInstanceStarted(const juce::String&) override{}
    void systemRequestedQuit() override {}
    void suspended() override {}
    void resumed() override {}
    void unhandledException(const std::exception*, const juce::String& , int ) override {}
protected:
    CWinApp* mfcApp = nullptr;
};

the createApplication callback:

juce::JUCEApplicationBase* juce_CreateApplication()
{
    MyJuceApp *theApp = new MyJuceApp(); 
    theApp->setMfcApp(AfxGetApp());
    return theApp;
}

And the CWinApp Init / Exit Instance() overrides code:

BOOL CMyMfcApp::InitInstance()
{
    /*...*/
    juce::JUCEApplicationBase::createInstance = &juce_CreateApplication; // sets the callback function defined above
    s_pJUCEApp = juce::JUCEApplicationBase::createInstance(); // JUCEApplicationBase* static member of CMyMfcApp
    juce::initialiseJuce_GUI();
    s_pJUCEApp->initialiseApp();
    juce::Desktop::getInstance().setDefaultLookAndFeel(&s_myJuceLookAndFeel); // for custom look and feel
    /*...*/
}

int CMyMfcApp::ExitInstance()
{
    /* ... */
    juce::Desktop::getInstance().setDefaultLookAndFeel(nullptr);
    if(s_pJUCEApp != nullptr)
    {
        delete s_pJUCEApp;
        s_pJUCEApp = nullptr;
    }
    juce::shutdownJuce_GUI();
}

Note that this relies entirely on the current JUCEApplicationBase::main() implementation for Windows so highly dependent on the state of JUCE source code.

Fred
Merging Technologies

4 Likes