From: Vadim Zeitlin Date: Thu, 19 Oct 2000 23:50:07 +0000 (+0000) Subject: 1. some more tests in console X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/6ba636000f13b4bf7d3e7dcfad429713085f6700 1. some more tests in console 2. added wxFileType::GetOpenCommand() demo in the exec sample 3. "fixed" the error messages from wxExecute() - still no idea why it happens though :-( git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@8588 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/samples/console/console.cpp b/samples/console/console.cpp index 7b1313c567..313907e968 100644 --- a/samples/console/console.cpp +++ b/samples/console/console.cpp @@ -1134,6 +1134,39 @@ static void TestRegistryRead() } } +static void TestRegistryAssociation() +{ + /* + The second call to deleteself genertaes an error message, with a + messagebox saying .flo is crucial to system operation, while the .ddf + call also fails, but with no error message + */ + + wxRegKey key; + + key.SetName("HKEY_CLASSES_ROOT\\.ddf" ); + key.Create(); + key = "ddxf_auto_file" ; + key.SetName("HKEY_CLASSES_ROOT\\.flo" ); + key.Create(); + key = "ddxf_auto_file" ; + key.SetName("HKEY_CLASSES_ROOT\\ddxf_auto_file\\DefaultIcon"); + key.Create(); + key = "program,0" ; + key.SetName("HKEY_CLASSES_ROOT\\ddxf_auto_file\\shell\\open\\command"); + key.Create(); + key = "program \"%1\"" ; + + key.SetName("HKEY_CLASSES_ROOT\\.ddf" ); + key.DeleteSelf(); + key.SetName("HKEY_CLASSES_ROOT\\.flo" ); + key.DeleteSelf(); + key.SetName("HKEY_CLASSES_ROOT\\ddxf_auto_file\\DefaultIcon"); + key.DeleteSelf(); + key.SetName("HKEY_CLASSES_ROOT\\ddxf_auto_file\\shell\\open\\command"); + key.DeleteSelf(); +} + #endif // TEST_REGISTRY // ---------------------------------------------------------------------------- @@ -3695,7 +3728,9 @@ int main(int argc, char **argv) #endif // TEST_INFO_FUNCTIONS #ifdef TEST_REGISTRY - TestRegistryRead(); + if ( 0 ) + TestRegistryRead(); + TestRegistryAssociation(); #endif // TEST_REGISTRY #ifdef TEST_SOCKETS diff --git a/samples/exec/exec.cpp b/samples/exec/exec.cpp index e8483a828a..5b1794ba83 100644 --- a/samples/exec/exec.cpp +++ b/samples/exec/exec.cpp @@ -45,6 +45,8 @@ #include "wx/process.h" +#include "wx/mimetype.h" + #ifdef __WINDOWS__ #include "wx/dde.h" #endif // __WINDOWS__ @@ -88,6 +90,8 @@ public: void OnExecWithRedirect(wxCommandEvent& event); void OnExecWithPipe(wxCommandEvent& event); + void OnFileExec(wxCommandEvent& event); + void OnDDEExec(wxCommandEvent& event); void OnAbout(wxCommandEvent& event); @@ -104,6 +108,8 @@ private: const wxArrayString& output, const wxString& title); + void DoAsyncExec(const wxString& cmd); + wxString m_cmdLast; wxListBox *m_lbox; @@ -178,6 +184,7 @@ enum Exec_SyncExec = 200, Exec_AsyncExec, Exec_Shell, + Exec_OpenFile, Exec_DDEExec, Exec_Redirect, Exec_Pipe, @@ -203,6 +210,8 @@ BEGIN_EVENT_TABLE(MyFrame, wxFrame) EVT_MENU(Exec_Redirect, MyFrame::OnExecWithRedirect) EVT_MENU(Exec_Pipe, MyFrame::OnExecWithPipe) + EVT_MENU(Exec_OpenFile, MyFrame::OnFileExec) + EVT_MENU(Exec_DDEExec, MyFrame::OnDDEExec) EVT_MENU(Exec_About, MyFrame::OnAbout) @@ -276,6 +285,9 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size) execMenu->Append(Exec_Pipe, _T("&Pipe through command...\tCtrl-P"), _T("Pipe a string through a filter")); + execMenu->AppendSeparator(); + execMenu->Append(Exec_OpenFile, _T("Open &file...\tCtrl-F"), + _T("Launch the command to open this kind of files")); #ifdef __WINDOWS__ execMenu->AppendSeparator(); execMenu->Append(Exec_DDEExec, _T("Execute command via &DDE...\tCtrl-D")); @@ -323,6 +335,24 @@ void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event)) _T("About Exec"), wxOK | wxICON_INFORMATION, this); } +void MyFrame::DoAsyncExec(const wxString& cmd) +{ + wxProcess *process = new MyProcess(this, cmd); + long pid = wxExecute(cmd, FALSE /* async */, process); + if ( !pid ) + { + wxLogError(_T("Execution of '%s' failed."), cmd.c_str()); + + delete process; + } + else + { + wxLogStatus(_T("Process %ld (%s) launched."), pid, cmd.c_str()); + + m_cmdLast = cmd; + } +} + void MyFrame::OnSyncExec(wxCommandEvent& WXUNUSED(event)) { wxString cmd = wxGetTextFromUser(_T("Enter the command: "), @@ -350,20 +380,7 @@ void MyFrame::OnAsyncExec(wxCommandEvent& WXUNUSED(event)) if ( !cmd ) return; - wxProcess *process = new MyProcess(this, cmd); - long pid = wxExecute(cmd, FALSE /* async */, process); - if ( !pid ) - { - wxLogError(_T("Execution of '%s' failed."), cmd.c_str()); - - delete process; - } - else - { - wxLogStatus(_T("Process %ld (%s) launched."), pid, cmd.c_str()); - - m_cmdLast = cmd; - } + DoAsyncExec(cmd); } void MyFrame::OnShell(wxCommandEvent& WXUNUSED(event)) @@ -474,6 +491,39 @@ void MyFrame::OnExecWithPipe(wxCommandEvent& WXUNUSED(event)) m_cmdLast = cmd; } +void MyFrame::OnFileExec(wxCommandEvent& event) +{ + static wxString s_filename; + + wxString filename = wxLoadFileSelector(_T("file"), _T(""), s_filename); + if ( !filename ) + return; + + s_filename = filename; + + wxString ext = filename.AfterFirst(_T('.')); + wxFileType *ft = wxTheMimeTypesManager->GetFileTypeFromExtension(ext); + if ( !ft ) + { + wxLogError(_T("Impossible to determine the file type for extension '%s'"), + ext.c_str()); + return; + } + + wxString cmd; + bool ok = ft->GetOpenCommand(&cmd, + wxFileType::MessageParameters(filename, _T(""))); + delete ft; + if ( !ok ) + { + wxLogError(_T("Impossible to find out how to open files of extension '%s'"), + ext.c_str()); + return; + } + + DoAsyncExec(cmd); +} + void MyFrame::OnDDEExec(wxCommandEvent& WXUNUSED(event)) { #ifdef __WINDOWS__ diff --git a/src/msw/dde.cpp b/src/msw/dde.cpp index f3fba5f994..6a7e4d547c 100644 --- a/src/msw/dde.cpp +++ b/src/msw/dde.cpp @@ -530,6 +530,7 @@ bool wxDDEConnection::Execute(const wxChar *data, int size, wxIPCFormat format) XTYP_EXECUTE, DDE_TIMEOUT, &result) != 0; + if ( !ok ) { DDELogError(_T("DDE execute request failed")); diff --git a/src/msw/utilsexc.cpp b/src/msw/utilsexc.cpp index e6287d9f28..26f8ca415f 100644 --- a/src/msw/utilsexc.cpp +++ b/src/msw/utilsexc.cpp @@ -320,6 +320,7 @@ long wxExecute(const wxString& cmd, bool sync, wxProcess *handler) wxCHECK_MSG( !!cmd, 0, wxT("empty command in wxExecute") ); wxString command; + #if wxUSE_IPC // DDE hack: this is really not pretty, but we need to allow this for // transparent handling of DDE servers in wxMimeTypesManager. Usually it @@ -327,7 +328,7 @@ long wxExecute(const wxString& cmd, bool sync, wxProcess *handler) // given type. Sometimes, however, this command just launches the server // and an additional DDE request must be made to really open the file. To // keep all this well hidden from the application, we allow a special form - // of command: WX_DDE::DDE_SERVER:DDE_TOPIC:DDE_COMMAND in which + // of command: WX_DDE##DDE_SERVER#DDE_TOPIC#DDE_COMMAND in which // case we execute just and process the rest below wxString ddeServer, ddeTopic, ddeCommand; static const size_t lenDdePrefix = 7; // strlen("WX_DDE:") @@ -383,6 +384,28 @@ long wxExecute(const wxString& cmd, bool sync, wxProcess *handler) { ddeCommand += *p++; } + + // maybe we don't have to launch the DDE server at all - if it is + // already running, for example + wxDDEClient client; + wxLogNull nolog; + wxConnectionBase *conn = client.MakeConnection(_T(""), + ddeServer, + ddeTopic); + if ( conn ) + { + // FIXME we don't check the return code as for some strange reason + // it will sometimes be FALSE - it is probably a bug in our + // DDE code but I don't see anything wrong there + (void)conn->Execute(ddeCommand); + + // ok, the command executed - return value indicating success, + // making it up for async case as we really don't have any way to + // get the real PID of the DDE server here + return sync ? 0 : -1; + } + //else: couldn't establish DDE conversation, now try launching the app + // and sending the DDE request again } else #endif // wxUSE_IPC @@ -617,12 +640,37 @@ long wxExecute(const wxString& cmd, bool sync, wxProcess *handler) if ( !!ddeServer ) { wxDDEClient client; - wxConnectionBase *conn = client.MakeConnection(_T(""), - ddeServer, - ddeTopic); - if ( !conn || !conn->Execute(ddeCommand) ) + wxConnectionBase *conn; + + { + // try doing it the first time without error messages + wxLogNull nolog; + + conn = client.MakeConnection(_T(""), ddeServer, ddeTopic); + } + + if ( !conn ) + { + // give the app some time to initialize itself: in fact, a common + // reason for failure is that we tried to open DDE conversation too + // soon (before the app had time to setup its DDE server), so wait + // a bit and try again + ::Sleep(2000); + + wxConnectionBase *conn = client.MakeConnection(_T(""), + ddeServer, + ddeTopic); + if ( !conn ) + { + wxLogError(_("Couldn't launch DDE server '%s'."), command.c_str()); + } + } + + if ( conn ) { - wxLogError(_("Couldn't launch DDE server '%s'."), command.c_str()); + // FIXME just as above we don't check Execute() return code + wxLogNull nolog; + (void)conn->Execute(ddeCommand); } } #endif // wxUSE_IPC