MFC 中使用的 DDE, DDX, DDV
void xxx::DoDataExchange(wxValidator* pDX)
{
xxx::DoDataExchange(pDX);
/{{AFX_DATA_MAP(CCalcDlg)
DDX_Radio(pDX, IDC_aaa, m_aaa_);
DDX_Radio(pDX, IDC_bbb, m_bbb_);
DDX_Check(pDX, IDC_ddd, m_ccc_);
/}}AFX_DATA_MAP
}
在 wxWidgets 裡可以不必再使用, 而由 wxValidator 取代。 而 wxValidator 的使用,已在 wxIIIGenericJJJ 或是 wxIIIJJJBase 中定義。 而且, wxDialog 中所包含的全是控制元件, wxValidator 已在各別的元件類型中定義 。所以在實際應用中已沒有須要。
但 wxWidgets 裡仍然另設計了 wxServer。
A
wxServer
object represents the server part of a client-server DDE-like (Dynamic
Data Exchange) conversation. The actual DDE-based implementation using
wxDDEServer is available on Windows only, but a platform-independent, socket-based version of this API is available using
wxTCPServer, which has the same API.
To create a server which can communicate with a suitable client, you need to derive a class from wxConnection and another from wxServer. The custom wxConnection class will intercept communications in a 'conversation' with a client, and the custom wxServer is required so that a user-overridden wxServer::OnAcceptConnection member can return a wxConnection of the required class, when a connection is made. Look at the IPC sample and the Interprocess Communication for an example of how to do this.
wxServer 採用 client-server 的 approach,用來作為 long-running processes 大量資料的傳遞。用來作為傳遞一般Gui 的簡單資訊有些 over kill。
example:
in header
#define DDE_TOPIC _T("MYAPP DDE")
#define DDE_SERVICE _T("MYAPP")
class CDDEServer : public wxServer
{
public:
CDDEServer(MyAppFrm* frame) : m_pFrame(frame) {}
wxConnectionBase *OnAcceptConnection(const wxString& topic);
MyAppFrm* GetFrame(){ return m_pFrame; }
void SetFrame(MyAppFrm* frame){ m_pFrame = frame; }
private:
MyAppFrm* m_pFrame;
};
class CDDEConnection : public wxConnection
{
public:
CDDEConnection(MyAppFrm* frame) : m_pFrame(frame) {}
bool OnExecute(const wxString& topic, wxChar *data, int size, wxIPCFormat format);
private:
MyAppFrm* m_pFrame;
};
class MyApp: public wxApp
{
...
private:
CDDEServer* m_pDDEServer;
};
in cpp:
wxConnectionBase* CDDEServer::OnAcceptConnection(const wxString& topic)
{
if (topic == DDE_TOPIC)
{
return new CDDEConnection(m_pFrame);
}
// unknown topic
return 0L;
}
bool CDDEConnection::OnExecute(const wxString& topic, wxChar *data, int size, wxIPCFormat format)
{
wxString string = data;
wxLogMessage(string);
if (string.StartsWith(_T("[Open(\"")))
{
wxRegEx cmd(_T("\"(.*)\""));
if (cmd.Matches(string))
{
wxString file = cmd.GetMatch(string, 1);
if(m_pFrame)
{
m_pFrame->Raise();
if (file != _T("__startup__"))
{
m_pFrame->OpenFile(file);
}
}
}
return true;
}
return false;
}
IMPLEMENT_APP( MyApp )
IMPLEMENT_CLASS( MyApp, wxApp )
bool MyApp::OnInit()
{
MyAppFrm* mainWindow = new MyAppFrm( NULL, ID_MYAPP_FRAME );
...
///act like a client to request info i f there is any hidden server already
///you can change the localhost to some other hosts or to fire up a client array
///to open multiple connections to the same hidden server or other servers;
///this will be a call burst to kill the network. :-)
wxClient client;
wxConnection *connection = (wxConnection*)client.MakeConnection(_T("localhost"), DDE_SERVICE, DDE_TOPIC);
if (connection == NULL)
{
/* try to make a connection */
wxUsleep(200);
connection = (wxConnection*)client.MakeConnection(_T("localhost"), DDE_SERVICE, DDE_TOPIC);
}
wxArrayString filesIn; /// below just an example, can be replaced with anything you want
if (connection != NULL)
{
if (filesIn.GetCount() == 0) filesIn.Add(_T("__startup__"));
}
connection->Execute(_T("[Open(\"") + filesIn[0] + _T("\")]"));
connection->Disconnect();
return false;
}
}
///now got info, become a server
m_pDDEServer = new CDDEServer(mainWindow); ///create a new server instance
m_pDDEServer->Create(DDE_SERVICE);
...
}
int MyApp::OnExit()
{
if (m_pDDEServer)
{
delete m_pDDEServer; ///remember to kill the server
}
return wxApp::OnExit();
}
也可以參考 wxWidgets ipc 中例子。