Click to open or copy the MTGDI project files.
The MTGDI sample is a demonstration of sharing GDI resources among multiple threads using the framework's single document interface (SDI) support for documents and views.
To run MTGDI, just build the sample and run the application. You can use the Thread menu to add 1, 10, or 25 new threads at a time. Each thread displays either a moving ball, rectangle, or line in a random color.
MTGDI uses a set of CWinThread-derived classes, all of them implemented in Threads.cpp. The sample's own CGDIThread
is the virtual base class for each of these GDI thread classes (one each for balls, rectangles, and lines). Since GDI resources cannot be shared among threads as MFC objects, this sample also demonstrates how to convert from standard GDI resources to MFC objects and back.
The application creates the desired number of threads when the user chooses to add new objects to those being displayed by the Thread menu. Each new object displayed is handled in its own thread. Any number of threads can be added to those already in progress. The number of threads currently being handled is shown in the title bar.
The threads are shut down all at once from the Thread menu, but you have a choice between whether this shutdown is done slowly or quickly. If there are fewer than 100 threads, it is difficult to tell the difference in speed between these two methods for MTGDI.
This sample demonstrates the following keywords:
CDC::Attach; CDC::Detach; CDocument::OnNewDocument; CGdiObject::Attach; CGdiObject::Detach; CObject::AssertValid; CObject::Dump; CObject::Serialize; CPoint::Offset; CRect::OffsetRect; CRect::SetRect; CString::Format; CString::LoadString; CView::GetDocument; CView::OnDraw; CWinApp::AddDocTemplate; CWinApp::Enable3dControls; CWinApp::ExitInstance; CWinApp::InitInstance; CWinApp::OnFileNew; CWnd::DoDataExchange; CWnd::GetParentFrame; CWnd::Invalidate; CWnd::OnCreate; CWnd::OnDestroy; CWnd::OnSize; CWnd::PreCreateWindow; CWnd::SetWindowText; CloseHandle; CreateEvent; CreateThread; DeleteCriticalSection; Ellipse; EnterCriticalSection; GdiFlush; GetClientRect; InitializeCriticalSection; LeaveCriticalSection; LineTo; MoveTo; RGB; Rectangle; ResumeThread; SelectObject; SetEvent; SetThreadPriority; Sleep; WaitForSingleObject