--- /dev/null
+//////////////////////////////////////////////\r
+// MainWnd.cpp\r
+// Definitions for the CMainWindow class\r
+\r
+#include "stdafx.h"\r
+#include "MainWnd.h"\r
+\r
+\r
+CMainWindow::CMainWindow() : m_nWindowsCreated(0)\r
+{\r
+ // Set the number of threads\r
+ m_nTestWin = 20;\r
+\r
+ // A couple of notes in case you're tempted to test how many threads with test windows can be created ...\r
+\r
+ // Note 1: A Windows limit of 10000 handles per process imposes a practical limit of aprox 1000 test windows.\r
+ // Refer to: http://support.microsoft.com/kb/327699\r
+ // Note 2: All our threads belong to the one process.\r
+ // Note 3: Creating (or destroying) more than say 200 windows may temporarily stress the Explorer process.\r
+ // Note 4: This sample is intended as "proof of concept" only. A well written program should not require 20 GUI threads!\r
+}\r
+\r
+HWND CMainWindow::Create(CWnd* pParent)\r
+{\r
+ CString str = _T("Main Thread Window");\r
+\r
+ // Create the main window\r
+ return CreateEx(WS_EX_TOPMOST, NULL, str, WS_OVERLAPPEDWINDOW | WS_VISIBLE,\r
+ 20 , 50, 400, 300, pParent, NULL);\r
+}\r
+\r
+void CMainWindow::OnCreate()\r
+{\r
+ // Create each CMyThread object\r
+ for (int i = 1 ; i <= m_nTestWin ; i++)\r
+ {\r
+ // Create the Test Window and store the CTestWindow pointer\r
+ CTestWindow* pTestWin = new CTestWindow(i);\r
+\r
+ CString str;\r
+ str.Format( _T("Thread %d started\n"), i );\r
+ TRACE(str);\r
+\r
+ m_vTestWnd.push_back(pTestWin);\r
+ }\r
+\r
+ std::vector<TestWndPtr>::iterator iter;\r
+ for (iter = m_vTestWnd.begin(); iter < m_vTestWnd.end(); ++iter)\r
+ {\r
+ (*iter)->ResumeThread();\r
+ }\r
+}\r
+\r
+void CMainWindow::OnAllWindowsCreated()\r
+{\r
+ CString str;\r
+ str.Format( _T("%d Test windows created in seperate threads\n"), m_nTestWin );\r
+ TRACE(str);\r
+}\r
+\r
+LRESULT CMainWindow::WndProc(UINT uMsg, WPARAM wParam, LPARAM lParam)\r
+{\r
+ switch (uMsg)\r
+ {\r
+ case WM_COMMAND:\r
+ if (HIWORD(wParam) == EN_SETFOCUS)\r
+ SetFocus();\r
+ break;\r
+\r
+ case WM_CLOSE:\r
+ {\r
+ // Close each thread window.\r
+ // The thread is then terminated with a WM_QUIT when its window is destroyed.\r
+ std::vector<TestWndPtr>::iterator iter;\r
+ for (iter = m_vTestWnd.begin(); iter < m_vTestWnd.end(); ++iter)\r
+ {\r
+ if ((*iter)->IsWindow())\r
+ (*iter)->SendMessage(WM_CLOSE, 0, 0);\r
+ }\r
+ }\r
+ break;\r
+\r
+ case WM_DESTROY:\r
+ {\r
+ // Terminate the primary thread.\r
+ ::PostQuitMessage(0);\r
+ }\r
+ break;\r
+\r
+ case WM_WINDOWCREATED:\r
+ {\r
+ // Message recieved when a test window is created\r
+ CString str;\r
+ ++m_nWindowsCreated;\r
+ str.Format( _T("Created Window %d\n"), m_nWindowsCreated );\r
+ TRACE(str);\r
+ if (m_nWindowsCreated == m_nTestWin)\r
+ OnAllWindowsCreated();\r
+ }\r
+ break;\r
+ }\r
+\r
+ return WndProcDefault(uMsg, wParam, lParam);\r
+}\r
+\r