开发者

wxWidgets Commandline / GUI Hybrid Application Fails to Get Dialog Input

开发者 https://www.devze.com 2023-01-28 20:10 出处:网络
I have a command-line application written in C++ and built with gcc/make that runs on MacOS.This application does not have its own GUI and it not supposed to have any root windows -- it\'s a console a

I have a command-line application written in C++ and built with gcc/make that runs on MacOS. This application does not have its own GUI and it not supposed to have any root windows -- it's a console app meant to be controlled by another application.

However, there is a need to show a file selection dialog at one point, which makes this a bit of a hybrid.

I've used wxWidgets to create the dialog, but it fails to get input. I've seen in the various FAQs and user groups that a bundle is probably required. When I tried to create a bundle it didn't solve the problem.

Here's how wxWidgets is initialized:

#ifdef __WXMAC__
    if (!wxEntryStart(argc, argv))
    {
        cout << "Failed to initialize wxWidgets." << endl;
        return 0;  
    }
#endif
    clientApp = new MainClass();
    clientApp->Run(argc, argv);
#ifdef __WXMAC__   
    wxEntryCleanup();
#endif

When I try to show a browse file dialog, using this code, it shows the file chooser but does not respond, acting like it has no message pump:

#ifdef __WXMAC__
    wxFileDialog* dlg = new wxFileDialog( NULL, _("Upload File"), _(""), _(""),
        _("All Files (*.*)|*.*"), wxFD_OPEN|wxFD_FILE_MUST_EXIST );
    if (dlg->ShowModal() == wxID_CANCEL )
    {
        INFOLOG("File upload dialog has been cancelled." << endl )
        return false;
    }
#endif

Since the FAQs say that creating a bundle is a way to automagically create a message pump and make a GUI responsive. I tried creating a bundle:

myapp.app --> Contents --> MacOS --> myapp (executable file) --> cert.crt (ssl certificate used by app) --> Resources --> myapp.icns --> Info.plist (points ot myapp as executable and uses myapp.icns as icon)

The application controlling this is not one I have control over and has to run it in exactly this way:

myapp

The controlling app needs to read the console output of this app and that is primarily why this has been a console-only app.

Since the executable is a few directories deeper, I tried creating a shell script in the root directory above the bundle to run the application and calling it myapp. Myapp just runs myapp.app/Contents/MacOS/myapp, forwarding the commandline parameters.

This didn't work. The browse file window is created and just sits there, giving me the rainbow spinwheel every time I mouse over it.

What can I do to get a message pump going? Is there a call I can add to the wxWidgets code or do I need to do something differnently with the bundle? Does having the shell script launch 开发者_Go百科the app that is inside the bundle completely defeat the "message pump magic" that the bundle is supposed to give, and if so, is there a sensible workaround? Do I just need to create some sort of pseudo-parent for the wxFileDialog?


I've heard reports that an alternative to creating an application bundle is to use the following code (which I never recommend to anyone over a bundle, but it sounds like your situation is a good reason to use it):

#include <ApplicationServices/ApplicationServices.h>

ProcessSerialNumber PSN;
GetCurrentProcess(&PSN);
TransformProcessType(&PSN,kProcessTransformToForegroundApplication);

This is of course platform specific, so wrap it accordingly.

Do you have a derived wxApp, and wxApp::OnInit()? These are likely still required to initialize the event loop.


You can make your app a full GUI app and just hide the main window using wxWindow::Show( false ). This will give you your working message pump. You should still be able to catch stdout and stderror.

0

精彩评论

暂无评论...
验证码 换一张
取 消