2016-04-22 46 views
1

下面是在wxWidgets中測試Native Win32 Edit控件的簡單代碼,無論是否添加樣式WS_EX_CONTROLPARENT或不管是否添加TranslateMessage函數, EDIT控件簡單不接受ENTER鍵和TAB鍵。我還捕獲了wxEVT_NAVIGATION_KEY並將其發送到子窗口,但它不起作用。這似乎是一個基本功能。我錯過了什麼? (接受的意思表示ENTER和在編輯框中TAB字符,如果可以看到GIF,該消息被捕捉,但在編輯框中沒有ENTER或TAB字符)如何在wxwidgets中編輯接受ENTER和TAB鍵的編輯控件

enter image description here

#include <wx/wx.h> 
#include <wx/xrc/xmlres.h> 
#include <wx/fs_mem.h> 
#include <wx/textdlg.h> 
#include <wx/sysopt.h> 
#include <wx/socket.h> 
#include <wx/aboutdlg.h> 
#include <wx/utils.h> 
#include <wx/nativewin.h> 
#include <wx/process.h> 
#include <wx/infobar.h> 
#ifdef __WXMSW__ 
#include "wx/msw/private.h" 
#endif 

#include <wx/log.h> 
//============================================================================== 
class MyMSWEdit : public wxNativeWindow{ 
protected: 
    HWND   m_cHWnd; 
protected: 
    virtual WXLRESULT MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) wxOVERRIDE { 
     switch (nMsg){ 
     case WM_KEYDOWN: 
     case WM_KEYUP: 
     case WM_CHAR: 
      //MSG messages; 
      //while (PeekMessage(&messages, (HWND)0, 0, 0, PM_REMOVE)) 
      //{ 
      // /* Translate virtual-key messages into character messages */ 
      // TranslateMessage(&messages); 
      // /* Send message to WindowProcedure */ 
      // DispatchMessage(&messages); 
      //} 
      wxLogMessage("%d",wParam); 
      return wxNativeWindow::MSWWindowProc(nMsg, wParam, lParam); 
     } 
     return wxNativeWindow::MSWWindowProc(nMsg, wParam, lParam); 
    } 
public: 
    explicit MyMSWEdit(wxWindow * parent) : wxNativeWindow(){ 
     int winmode = WS_CHILD | WS_VISIBLE | ES_MULTILINE; 
     int exwinmode = 0; 
     m_cHWnd = CreateWindowExW(exwinmode, TEXT("EDIT"), TEXT("EDIT"), winmode, CW_USEDEFAULT, CW_USEDEFAULT, 100, 100, parent->GetHWND(), NULL, NULL, NULL); 
     if (m_cHWnd) 
      (void)Create(parent, wxID_ANY, m_cHWnd); 
    } 
    HWND Gethwnd(){ 
     return m_cHWnd; 
    } 
    virtual ~MyMSWEdit(){ 
     Disown(); 
    } 
}; 
//============================================================================== 
class MainFrame : public wxFrame { 
protected: 
    HWND   m_pHWnd; 
    HWND   m_cHWnd; 
    MyMSWEdit * m_myedit; 

public: 

    explicit MainFrame(const wxString& title) { 
     wxXmlResource::Get()->LoadFrame(this, NULL, "Frame1"); 
     this->SetTitle(title); 
#ifdef _DEBUG 
     auto pLog = new wxLogWindow(this, "Debug"); 
     pLog->PassMessages(false); 
     wxLog::SetActiveTarget(pLog); 
#else 
     wxLog::EnableLogging(false); 
     wxLog::SetActiveTarget(NULL); 
#endif 
     auto P1 = XRCCTRL(*this, "m_panel1", wxPanel); 
     P1->Bind(wxEVT_NAVIGATION_KEY, [=](wxNavigationKeyEvent& event){ 
      ::SendMessage(event.GetCurrentFocus()->GetHWND(),WM_CHAR, VK_TAB, 0); 
      wxLogMessage("NAV"); 
      return 0; 

     }); 
     auto P2 = XRCCTRL(*this, "m_panel2", wxPanel); 
     m_myedit = new MyMSWEdit(P2); 
     wxASSERT(m_myedit); 
     P2->GetSizer()->Insert(0, m_myedit, 1, wxEXPAND | wxALL, 0); 
     P2->GetSizer()->Layout(); 
     m_cHWnd = m_myedit->Gethwnd(); 
    } 
    //-------------------------------------------------------------------------- 
    virtual ~MainFrame(){ 
    } 
};// end class MainFrame 
//============================================================================= 
class CJApp : public wxApp { 
protected: 
    MainFrame* m_pFrame; 
public: 
    CJApp() { 
     m_pFrame = NULL; 
    } 
    static bool LoadFromString(const wxString & data) { 
     static int s_memFileIdx = 0; 
     // Check for memory FS. If not present, load the handler: 
     wxMemoryFSHandler::AddFile(wxT("XRC_resource/dummy_file"), 
      wxT("dummy data")); 
     wxFileSystem fsys; 
     wxFSFile *f = 
      fsys.OpenFile(wxT("memory:XRC_resource/dummy_file")); 
     wxMemoryFSHandler::RemoveFile(wxT("XRC_resource/dummy_file")); 
     if (f) 
      delete f; 
     else 
      wxFileSystem::AddHandler(new wxMemoryFSHandler); 

     // Now put the resource data into the memory FS 
     wxString filename(wxT("XRC_resource/data_string_")); 
     filename << s_memFileIdx; 
     s_memFileIdx += 1; 
     wxMemoryFSHandler::AddFile(filename, data); 

     // Load the "file" into the resource object 
     bool retval = wxXmlResource::Get()->Load(wxT("memory:") + filename); 
     return retval; 
    } 
    virtual bool OnInit() { 
     wxSystemOptions::SetOption("msw.remap", 2); 
     wxInitAllImageHandlers(); 
     wxXmlResource::Get()->InitAllHandlers(); 
#ifdef USERES 
     TCHAR * sResName = _T("#131"); 
     TCHAR * sRestype = _T("CUSTOMERSTRING"); 
     HRSRC hres = FindResource(NULL, sResName, sRestype); 
     HGLOBAL hbytes = LoadResource(NULL, hres); 
     LPVOID pdata = LockResource(hbytes); 
     LPBYTE sData = (LPBYTE)pdata; 
     LPTSTR sXml = (LPTSTR)sData; 
     char tmp[99999]; 
     sprintf(tmp, "%s", sXml); 
     tmp[99998] = 0; 
     std::string XRC(tmp); 
     if (LoadFromString(XRC)){ 
      goto success; 
     } 
#else 
     if (wxXmlResource::Get()->Load("Frame1.xrc")){ 
      goto success; 
     } 
#endif 
     return false; 
    success: 
     m_pFrame = new MainFrame(""); 
     m_pFrame->Show(true); 
     return true; 
    } 
}; 
//============================================================================== 
DECLARE_APP(CJApp) 
IMPLEMENT_APP(CJApp) 

Frame1中.xrc:

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> 
<resource xmlns="http://www.wxwindows.org/wxxrc" version="2.3.0.1"> 
    <object class="wxFrame" name="Frame1"> 
     <style>wxDEFAULT_FRAME_STYLE|wxTAB_TRAVERSAL</style> 
     <size>500,300</size> 
     <title></title> 
     <centered>1</centered> 
     <aui_managed>0</aui_managed> 
     <object class="wxPanel" name="m_panel1"> 
      <style>wxTAB_TRAVERSAL</style> 
      <object class="wxBoxSizer"> 
       <orient>wxVERTICAL</orient> 
       <object class="sizeritem"> 
        <option>1</option> 
        <flag>wxEXPAND | wxALL</flag> 
        <border>5</border> 
        <object class="wxPanel" name="m_panel2"> 
         <style>wxTAB_TRAVERSAL</style> 
         <object class="wxBoxSizer"> 
          <orient>wxVERTICAL</orient> 
         </object> 
        </object> 
       </object> 
       <object class="sizeritem"> 
        <option>0</option> 
        <flag>wxALL</flag> 
        <border>5</border> 
        <object class="wxButton" name="m_button1"> 
         <label>MyButton</label> 
         <default>0</default> 
        </object> 
       </object> 
       <object class="sizeritem"> 
        <option>0</option> 
        <flag>wxALL</flag> 
        <border>5</border> 
        <object class="wxButton" name="m_button2"> 
         <label>MyButton</label> 
         <default>0</default> 
        </object> 
       </object> 
      </object> 
     </object> 
    </object> 
</resource> 
+0

究竟是什麼問題? 「接受」是什麼意思?此外,這是太多的代碼,爲什麼你需要帶按鈕的XRC以及所有其他的東西,當然這與問題無關,不管它是什麼。 –

+0

@ VZ.Hi VZ,美好的一天,這些按鈕與我忘記刪除它們的問題無關。如果可以看到GIF,可以在調試窗口中看到代碼65/97,13,9爲「a」,ENTER和TAB被捕獲,但編輯框中只顯示「a」,TAB和ENTER不是所示。 – Boying

+1

你如何期待ENTER和TAB被顯示?對不起,但這個問題對我沒有意義。 –

回答

1

通過這篇文章 Win32 - Appending text to an Edit Control和一些wxWidget源代碼啓發的src \ MSW \ textctrl.cpp

問題通過以下方式解決:

protected: 
    void WriteText(TCHAR *newText) { 
     // get the current selection 
     //DWORD StartPos, EndPos; 
     //SendMessage(m_cHWnd, EM_GETSEL, reinterpret_cast<WPARAM>(&StartPos), reinterpret_cast<WPARAM>(&EndPos)); 

     // move the caret to the end of the text 
     //int outLength = GetWindowTextLength(m_cHWnd); 
     //SaendMessage(m_cHWnd, EM_SETSEL, outLength, outLength); 

     // insert the text at the new caret position 
     SendMessage(m_cHWnd, EM_REPLACESEL, TRUE, reinterpret_cast<LPARAM>(newText)); 

     // restore the previous selection 
     //SendMessage(m_cHWnd, EM_SETSEL, StartPos, EndPos); 

    } 
    virtual WXLRESULT MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) wxOVERRIDE { 
     switch (nMsg){ 
     case WM_CHAR: 
      //MSG messages; 
      //while (PeekMessage(&messages, (HWND)0, 0, 0, PM_REMOVE)) 
      //{ 
      // /* Translate virtual-key messages into character messages */ 
      // TranslateMessage(&messages); 
      // /* Send message to WindowProcedure */ 
      // DispatchMessage(&messages); 
      //} 
      wxLogMessage("%d",wParam); 
      switch (wParam){ 
      case VK_RETURN: 
       WriteText(L"\r\n"); 
       break; 
      case VK_TAB: 
       WriteText(L"\t"); 
       break; 
      } 
     } 
     return wxNativeWindow::MSWWindowProc(nMsg, wParam, lParam); 
    }