ChefZ -- 磨劍錄 (A Coder's Log)

慣看秋月春風 一壺濁酒喜相逢 古今多少事 皆賦談笑中
posts - 42, comments - 3, trackbacks - 0, articles - 6

wxWidgets 101 - 9 wxDialog (2)

Posted on 2008-11-15 03:55 chefZ 阅读(645) 评论(0)  编辑 收藏 引用
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 中例子。



只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理