【问题标题】:Manual alternative to message map?手动替代消息映射?
【发布时间】:2010-02-05 20:42:42
【问题描述】:

我正在尝试创建一个 GUI 来显示从文件中读取的信息。所以我需要一些按钮、文本字段和单选按钮 - 但直到运行时我才知道需要多少。

我正在使用 Visual Studio 6.0。我的工具集是不可协商的,所以请不要推荐 Java 或任何未预装在 Visual Studio 中的 C++ 工具包。我的问题是,我在网上找到的大多数教程都侧重于使用 WYSIWYG 编辑器 - 这需要预先知道需要哪些控件。

我找到了一个允许我手动添加控件的代码示例(以下摘录):

class CalcApp : public CWinApp
{
    ...
};

class CWindow : public CFrameWnd
{ 
    ...

    afx_msg void HandleButton2();
    afx_msg HBRUSH OnCtlColor( CDC* pDC, CWnd* pWnd, UINT nCtlColor );
    DECLARE_MESSAGE_MAP();
    virtual BOOL PreTranslateMessage(MSG* msg);
};

.cpp 文件:

BEGIN_MESSAGE_MAP( CWindow, CFrameWnd )

    ON_BN_CLICKED(IDC_BUTTON1, HandleButton1)
    ON_BN_CLICKED(IDC_BUTTON2, HandleButton2)

END_MESSAGE_MAP()

CWindow::CWindow()
{ 
    Create(NULL, "Title", 
            WS_OVERLAPPED | WS_MINIMIZEBOX | WS_SYSMENU, 
            CRect(CPoint(50,50),CSize(180,300))); 

    ...

    button2 = new CButton();
    button2 -> Create("&Quit",
            WS_CHILD|WS_VISIBLE|WS_TABSTOP,
            CRect(CPoint(2,202),CSize(152,38)),
            this, IDC_BUTTON2);
    }

    void CWindow::HandleButton2()
    {
        DestroyWindow ();
    }

    BOOL CalcApp::InitInstance()
    {
        m_pMainWnd = new CWindow();
        m_pMainWnd->ShowWindow(m_nCmdShow);
        m_pMainWnd->UpdateWindow();
        return TRUE;
    }

我无法弄清楚如何在不使用 BEGIN_MESSAGE_MAP() 等宏的情况下处理消息 - 同样,这需要知道您需要多少个处理程序。

我能找到的唯一解决方案如下:

LRESULT CALLBACK WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                   LPSTR lpCmdLine, int nCmdShow)
{
    ...
    WndClsEx.lpfnWndProc   = WndProc;

    RegisterClassEx(&WndClsEx);

    hWnd = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW,
                      ClsName,
                      WindowCaption,
                      WS_OVERLAPPEDWINDOW,
                      100,
                      120,
                      640,
                      480,
                      NULL,
                      NULL,
                      hInstance,
                      NULL);

    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);

    while( GetMessage(&Msg, NULL, 0, 0) )
    {
        TranslateMessage(&Msg);
        DispatchMessage(&Msg);
    }

    return Msg.wParam;
}
//---------------------------------------------------------------------------
LRESULT CALLBACK WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
    switch(Msg)
    {
    case WM_DESTROY:
        PostQuitMessage(WM_QUIT);
        break;
    default:
        return DefWindowProc(hWnd, Msg, wParam, lParam);
    }
    return 0;
}

这很好,除了...我没有 WinMain...

我的理解是你可以做一个“Win32”应用程序(上面的 WinMain 代码)或一个“MFC”应用程序(上面的 CButton 代码)。但是我只能找到MFC手动添加控件的例子,Win32只能找到手动处理消息的例子。

你能指出我在这里遗漏的一件事吗?理想情况下,我想要一个使用 MFC 处理我自己的消息的解决方案,但我会接受一个关于使用 Win32 创建控件的好教程...

【问题讨论】:

    标签: c++ c visual-c++ mfc winapi


    【解决方案1】:

    曾几何时,我做过这样的事情。我分配了大量的控制 ID(未在 resource.h 中使用)。将具有这些 id 的控件动态添加到页面。

    为了处理这个事件,我接管了 Windows 上的 OnCommand 并监听了 id 在我正在寻找的范围内的控件。

    (我需要搜索旧代码才能更具体)

    【讨论】:

    • 听起来是个不错的起点...但看起来 CFrameWnd::OnCommand 只需要两个参数,wParam 和 lParam... ... MSDN 说对于 CWnd::OnCommand,lParam 是产生消息的控件...好吧,这可能是我的答案!
    • 作为记录,检查 lParam 似乎不起作用,但检查 wParam 的低位字 (wParam & 0xFFFF) 似乎与正确的 ID 匹配。
    • 你可以走得更低,接管 OnMessage()
    猜你喜欢
    • 2012-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多