views:

86

answers:

1

I am trying to create a GUI to display information read from a file. So I will need some number of pushbuttons, text fields, and radio buttons - but I won't know how many I need until run-time.

I am using Visual Studio 6.0. My toolset is fairly non-negotiable, so please refrain from suggesting Java, or any C++ toolkit that does not come pre-installed in Visual Studio. My problem is that most of the tutorials I have found online focus on using the WYSIWYG editor - which requires knowing what controls are needed up front.

I found a code sample that allows me to add controls manually (exerpts below):

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 file:

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;
    }

What I'm having trouble figuring out is how to handle the message processing without using the BEGIN_MESSAGE_MAP(), etc macros - which, again, require knowing how many handlers you need up front.

The only solution I've been able to find looks like this:

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;
}

Which is great, except.. I don't have a WinMain...

My understanding is that you can either do a "Win32" application (the WinMain code above) or an "MFC" application (the CButton code above). But I can only find examples of manually adding controls for MFC, and I can only find examples of manually processing messages for Win32.

Can you point me to one of the things I'm missing here? Ideally, I want a solution for handling my own messages with MFC, but I'd settle for a good tutorial on creating controls with Win32...

+2  A: 

Once upon a time I did something like this. I allocated a rage of control ids (not used in resource.h). Added controls with these ids dynamically to the page.

To handle the event I took over the OnCommand on the Windows and listened for controls with ids in the range I was looking for.

(I need to search old code to be more specific)

Arve
Sounds like a good starting point... but it looks like CFrameWnd::OnCommand only takes two parameters, wParam and lParam... ... MSDN says for CWnd::OnCommand, lParam is the control that originated the message... Okay, this might be my answer!
Rini
Rini
You could go even lower and take over OnMessage()
John Dibling