Click to open or copy the MTMDI project files.
MTMDI illustrates a Microsoft Foundation Class Library (MFC) user interface thread, where user interface events are processed in a separate thread from the main application thread. This sample is a modified version of the single-thread MDI sample.
The MTMDI sample does not claim a strong rationale for putting the bouncing ball window in a separate thread. A user would not be able to detect the difference between the MDI and MTMDI samples on a single-processor computer. Even on a multiprocessor computer, the user would not be able to detect the difference, given that the ball movement is based on a window timer.
Nevertheless, MTMDI does illustrate techniques for implementing an MFC user interface thread. Compare the sources for the MDI and MTMDI samples to study the programming overhead associated with using MFC user interface threads.
The programming overhead in MTMDI should be a warning that you should have a good reason for using a user interface thread to justify the programming cost. The much more common type of thread in MFC is the worker thread, illustrated by the MTRECALC sample.
The user interface for MTMDI is very similar to the user interface of the MDI sample. However, MTMDI includes one additional user interface feature: you can click anywhere in the bounce window to change the position of the moving ball immediately.
You can use the File menu to create new windows of two different types. Once the windows are created, the application will let you change the attributes of the items in the window by using commands in one of these menus: Color, Speed, Window, and Help. Notice that the "Hello!" windows do not have a Speed menu.
MTMDI makes use of its own CWinThread-derived class, called CBounceThread. CBounceThread is implemented in the Mtbounce.cpp file. The thread contains all of the painting and timing code that the bouncing ball window needs to animate the ball in the window.
The application creates each thread just as the MDI child window is created. This happens in the CBounceMDIChildWnd::Create function, found in Bounce.cpp. This function creates both the window and the thread, associating the thread to the window.
Whenever you close a bounce window, the associated thread is automatically destroyed. The "Hello!" windows do not have a thread of their own; their messages are handled by the application's primary thread.
This sample demonstrates the following keywords:
AfxGetInstanceHandle; AfxMessageBox; AfxRegisterWndClass; CBitmap::CreateCompatibleBitmap; CCmdTarget::OnCmdMsg; CCmdUI::SetCheck; CColorDialog::DoModal; CColorDialog::GetColor; CDC::BitBlt; CDC::CreateCompatibleDC; CDC::DeleteDC; CDC::DrawText; CDC::Ellipse; CDC::FillRect; CDC::GetDeviceCaps; CDC::SelectObject; CDC::SetBkColor; CDC::SetTextColor; CFrameWnd::LoadFrame; CFrameWnd::rectDefault; CGdiObject::DeleteObject; CMDIChildWnd::Create; CMenu::LoadMenu; CRect::Height; CRect::Width; CWinApp::Enable3dControls; CWinApp::ExitInstance; CWinApp::InitInstance; CWnd::Create; CWnd::DestroyWindow; CWnd::GetClientRect; CWnd::GetCurrentMessage; CWnd::GetDC; CWnd::GetDlgItem; CWnd::GetWindow; CWnd::Invalidate; CWnd::KillTimer; CWnd::MessageBox; CWnd::OnCreate; CWnd::OnDestroy; CWnd::OnLButtonDown; CWnd::OnPaint; CWnd::OnSize; CWnd::OnTimer; CWnd::ReleaseDC; CWnd::SendMessage; CWnd::SetTimer; CWnd::SetWindowPos; CWnd::ShowWindow; CWnd::UpdateWindow; CloseHandle; CreateEvent; CreateThread; EnumChildWindows; GetSysColor; GetVersion; LOWORD; LoadCursor; LoadIcon; LoadMenu; MAKEINTRESOURCE; RGB; SetEvent; Sleep; WaitForSingleObject; max; min