Manipulação de eventos da janela infantil WTL
Pergunta
Estou desenvolvendo um aplicativo de janela, pois estou tendo duas janelas filhos no lado esquerdo e direito. Eu quero lidar com eventos de entrada para ambos os Windows separadamente. Como alcançá -lo?
Meu código:
class EditorWindow : public DxWindow
{
public:
CSplitterWindow m_vSplit;
CPaneContainer m_lPane;
CPaneContainer m_rPane;
PropertyDialog m_propertyWnd;
DECLARE_WND_CLASS(_T("Specific_Class_Name"))
BEGIN_MSG_MAP(EditorWindow)
MESSAGE_HANDLER(WM_CREATE, OnCreate)
MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
MESSAGE_HANDLER(WM_LBUTTONDOWN, KeyHandler)
MESSAGE_HANDLER(WM_KEYUP, KeyHandler)
MESSAGE_HANDLER(WM_LBUTTONDOWN, KeyHandler)
END_MSG_MAP()
LRESULT OnCreate(UINT, WPARAM, LPARAM, BOOL&)
{
CRect rcVert;
GetClientRect(&rcVert);
m_vSplit.Create(m_hWnd, rcVert, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN);
m_vSplit.SetSplitterPos(rcVert.Width()/1.4f); // from left
m_lPane.Create(m_vSplit.m_hWnd);
m_vSplit.SetSplitterPane(0, m_lPane);
//m_lPane.SetTitle(L"Left Pane");
m_rPane.Create(m_vSplit.m_hWnd);
m_vSplit.SetSplitterPane(1, m_rPane);
m_rPane.SetTitle(L"Properties");
m_propertyWnd.Create(m_rPane.m_hWnd);
//m_vSplit.SetSplitterPane(SPLIT_PANE_LEFT, md.m_hWnd);
return 0;
}
LRESULT OnDestroy( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled )
{
PostQuitMessage(0);
bHandled = FALSE;
return 0;
}
LRESULT KeyHandler( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled )
{
return 0;
}
};
Solução
Wtl :: csplitterwindow e wtl :: cpaneContainer não encaminham as mensagens wm_keyxxx e wm_mousexxx para seus pais.
Derive seu editorWindow de WTL :: CSplitterWindowImpl e seus painéis de WTL :: cpaneContainerImpl, por exemplo:
class CMyPaneContainer : public CPaneContainerImpl<CMyPaneContainer>
{
public:
DECLARE_WND_CLASS_EX(_T("MyPaneContainer"), 0, -1)
BEGIN_MSG_MAP(CMyPaneContainer)
MESSAGE_RANGE_HANDLER(WM_KEYFIRST, WM_KEYLAST, OnForward)
MESSAGE_RANGE_HANDLER(WM_MOUSEFIRST, WM_MOUSELAST, OnForward)
CHAIN_MSG_MAP(CPaneContainerImpl<CMyPaneContainer>)
END_MSG_MAP()
LRESULT OnForward(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
if (uMsg == WM_MOUSEWHEEL)
return bHandled = FALSE; // Don't forward WM_MOUSEWHEEL
return GetParent().SendMessage(uMsg, wParam, lParam);
}
};
class EditorWindow : public CSplitterWindowImpl<EditorWindow, true, CWindow/*DxWindow*/>
{
typedef CSplitterWindowImpl<EditorWindow, true, CWindow/*DxWindow*/> baseClass;
public:
CMyPaneContainer m_lPane;
CMyPaneContainer m_rPane;
//PropertyDialog m_propertyWnd;
DECLARE_WND_CLASS(_T("Specific_Class_Name"))
BEGIN_MSG_MAP(EditorWindow)
MESSAGE_HANDLER(WM_CREATE, OnCreate)
MESSAGE_HANDLER(WM_LBUTTONDOWN, KeyHandler)
MESSAGE_HANDLER(WM_KEYUP, KeyHandler)
CHAIN_MSG_MAP(baseClass)
END_MSG_MAP()
LRESULT OnCreate(UINT, WPARAM, LPARAM, BOOL&)
{
m_lPane.Create(m_hWnd);
m_lPane.SetTitle(L"Left Pane");
m_rPane.Create(m_hWnd);
m_rPane.SetTitle(L"Properties");
//m_propertyWnd.Create(m_rPane.m_hWnd);
SetSplitterPosPct(70); // 70% from left
SetSplitterPanes(m_lPane, m_rPane);
return 0;
}
Outras dicas
Você pode usar ALT_MSG_MAP()
em combinação com CContainedWindow
- Você especifica um ID do mapa de mensagens para ATL_MSG_MAP()
para o qual você passa CContainedWindow
s construtor.
A documentação do ATL para CContainedWindowT
tem um exemplo.
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow