#include "main.h" #include "windows.h" #include "Psapi.h" #include "shlwapi.h" #include "time.h" #include #define MY_TIMER 122 //MSG Msg;//Структура Msg типа MSG для получения сообщений Windows //------------------------------------------------------------------------------------- /*Главная функция WinMaln*/ HINSTANCE hInstance; const int iHeightEdit=20; HWND hWndMain; HWND hButExit,hButClear,hButRun; HWND hListBox; wchar_t buf[256]; LONG maxPlaces = 3; const int maxTrains = 5; HANDLE hSemaphore; HANDLE trainHandles[maxTrains]; int trainID[maxTrains]; int WINAPI WinMain(HINSTANCE hInst,HINSTANCE hPrev,LPSTR lpCmd, int nShow) { //------------------------------------------------------------------------------------- hInstance=hInst; WNDCLASSEX wc;//Структура we типа WNDCLASS для задания характеристик окна static LPCTSTR szClassName = TEXT("MainLab5Window");//Произвольное имя класса главного окна static LPCTSTR szTitle = TEXT("Железнодорожная станция");//заголовок окна /*Зарегистрируем класс главного окна*/ ZeroMemory(&wc,sizeof(wc));//Обнуление всех членов структуры wс wc.cbSize = sizeof(wc); // Set structure size wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc=WndProc; // Определяем оконную процедуру для главного окна wc.hInstance=hInst;//Дескриптор приложения wc.hIcon = LoadIcon(0, IDI_APPLICATION);//Стандартная пиктограмма wc.hCursor=LoadCursor(NULL,IDC_ARROW);//Стандартный курсор мыши char ID_MAINMENU[10] = "menu? o_0"; wc.hbrBackground=CreateSolidBrush(GetSysColor(COLOR_BTNFACE));// системный цвет рабочий области окна wc.lpszMenuName=(LPCWSTR)ID_MAINMENU; wc.lpszClassName=szClassName;//Имя класса окна RegisterClassEx(&wc);//Вызов функции Windows регистрации класса окна //Создадим главное окно по центру экрана и сделаем его видимым hWndMain=CreateWindow(szClassName, szTitle, WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX & ~WS_THICKFRAME,0,0,800,735,HWND_DESKTOP,NULL,hInst,NULL);//Родитель, меню, другие параметры RECT rc,rcMain; HWND hwndDesktop = GetDesktopWindow(); GetWindowRect(hwndDesktop, &rc); GetWindowRect(hWndMain, &rcMain); SetWindowPos(hWndMain, HWND_TOP, (rc.right-rc.left-rcMain.right)/2, (rc.bottom-rc.top-rcMain.bottom)/2, 0, 0, SWP_NOSIZE); ShowWindow(hWndMain,SW_SHOWNORMAL);//Вызов функции Windows показа окна /*Организуем цикл обнаружения сообщений*/ while(GetMessage(&Msg,NULL,0,0)) {// Если есть сообщение, передать его нам TranslateMessage(&Msg); DispatchMessage(&Msg);}//и вызвать оконную процедуру WndProc return 0;//После выхода из цикла вернуться в Windows }//Конец функции WinMain LRESULT CALLBACK WndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam){ switch(msg){ HANDLE_MSG (hwnd, WM_CREATE, OnCreate); HANDLE_MSG (hwnd, WM_COMMAND, OnCommand); //HANDLE_MSG (hwnd, WM_DESTROY, OnDestroy); //HANDLE_MSG (hwnd, WM_NOTIFY, OnNotify); default: //B случае всех остальных сообщений Windows обработка return(DefWindowProc(hwnd,msg,wParam,lParam)) ; //их по умолчанию }//Конец оператора switch }//Конец функции WndProc bool OnCreate (HWND hwnd, LPCREATESTRUCT){ //------------------------------------------------------------------------------------- TCHAR ButExit[]=TEXT(" Exit "); RECT Rect; GetClientRect(hwnd,&Rect); hButExit=CreateWindow(TEXT("BUTTON"),NULL,WS_CHILD|WS_VISIBLE|SS_CENTER,Rect.right- Rect.left-105,Rect.top+655+iHeightEdit,(int)(1,5*iHeightEdit),iHeightEdit ,hwnd,NULL,hInstance,NULL); SendMessage(hButExit,WM_SETTEXT, 0, (LPARAM)(LPCSTR)ButExit); hButClear=CreateWindow(TEXT("BUTTON"),NULL,WS_CHILD|WS_VISIBLE|SS_CENTER,Rect.right- Rect.left-235,Rect.top+655+iHeightEdit,(int)(1,5*iHeightEdit),iHeightEdit ,hwnd,NULL,hInstance,NULL); SendMessage(hButClear,WM_SETTEXT, 0, (LPARAM)(LPCSTR)TEXT("Clear")); hButRun=CreateWindow(TEXT("BUTTON"),NULL,WS_CHILD|WS_VISIBLE|SS_CENTER,Rect.right- Rect.left-600,Rect.top+55+iHeightEdit,(int)(1,5*iHeightEdit),iHeightEdit ,hwnd,NULL,hInstance,NULL); SendMessage(hButRun,WM_SETTEXT, 0, (LPARAM)(LPCSTR)TEXT("Пааааехали!")); hListBox= CreateWindow( TEXT("LISTBOX"), NULL, WS_CHILD | /*LBS_STANDARD |*/ WS_VSCROLL | LBS_DISABLENOSCROLL | WS_VISIBLE/* & (~LBS_SORT)*/, 340,30, 455, 550, hwnd, NULL, hInstance, NULL); HWND hAuthor=CreateWindow(TEXT("STATIC"),NULL,WS_CHILD|WS_VISIBLE|SS_LEFT ,(int)(Rect.left+250),(int)(Rect.top+680),(int)(Rect.right- Rect.left-550),20,hwnd,NULL,hInstance,NULL); SendMessage(hAuthor,WM_SETTEXT, 0, (LPARAM)(LPCSTR)TEXT("(c) Косоногова М.А., гр. ИТ-31, 2008")); return TRUE; } void OnCommand (HWND hwnd, int id, HWND hw, UINT){ //------------------------------------------------------------------------------------- if (hw==hButExit) OnClickButExit(); if (hw==hButClear) OnClickButClear(hWndMain); if (hw==hButRun) OnClickButRun(hWndMain); } void OnClickButExit() { PostQuitMessage(0); } void OnClickButClear(HWND hwnd) { RECT Rect; GetClientRect(hwnd,&Rect); } int Puass(double Lamda) { int k = 0; double p0 = exp(-Lamda); double P = p0; // Генерируем вещественное число в интервале 0 .. 1 double ver = (double)rand() / RAND_MAX; do { ver -= P; if(ver >= 0) { P = P*Lamda / (k+1); k += 1; } } while(ver >= 0); return k; } DWORD TrainThread(int *p) { __int64 gTime; QueryPerformanceCounter((LARGE_INTEGER *)&gTime); srand(gTime); wsprintf(buf,L"Train #%d...",*p); SendMessage(hListBox,LB_ADDSTRING, 0, (LPARAM)(LPCSTR)buf); int finished = 0; do { // Проверяем состояние семафора DWORD dwResult = WaitForSingleObject(hSemaphore, 1000); // !!! ждем 1 секунду DWORD time_stopping; switch(dwResult) { case WAIT_OBJECT_0: // Место есть, остановка wsprintf(buf,L"Train #%d is stoping...",*p); SendMessage(hListBox,LB_ADDSTRING, 0, (LPARAM)(LPCSTR)buf); time_stopping = Puass(200) * 10 + 1000; // Время стоянки Sleep(time_stopping); ReleaseSemaphore(hSemaphore, 1, NULL); // Освободим семафор finished = 1; break; case WAIT_TIMEOUT: // Семафор занят, сообщаем об этом, и повторяем попытку ... wsprintf(buf, L"Train #%d: no empty places...waiting",*p); SendMessage(hListBox,LB_ADDSTRING, 0, (LPARAM)(LPCSTR)buf); break; } } while(!finished); return 0; } void OnClickButRun(HWND hwnd) { // генератор случ. чисел //srand(time(NULL)); if(hSemaphore = CreateSemaphore(NULL, maxPlaces, maxPlaces, NULL)) { for(int i = 0; i < maxTrains; i++) { DWORD timeWait = Puass(200) * 10; // <--- Ну, коэффициенты сама подберешь wsprintf(buf, L"Ждем %ld ms перед генерацией следующего потока-поезда", timeWait); SendMessage(hListBox, LB_ADDSTRING, 0, (LPARAM)(LPCSTR)buf); // Ожидание, но все запущенные ранее потоки уже работают, // на них Sleep не распространяется Sleep(timeWait); trainID[i] = i+1; trainHandles[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)TrainThread, &trainID[i], 0, NULL); } int b = 1; do { // DWORD r = ; // дождаться всех switch(WaitForMultipleObjects(maxTrains, trainHandles, TRUE, 100)) { case WAIT_TIMEOUT: // Здесь добавить аналог Application->ProcessMessages() чтоб обновить окно; MSG lpMsg; while (PeekMessage(&lpMsg, NULL, 0, 0, PM_REMOVE)) { TranslateMessage(&lpMsg); DispatchMessage(&lpMsg); } break; default: b = 0; } } while(b); CloseHandle(hSemaphore); } else SendMessage(hListBox,LB_ADDSTRING, 0, (LPARAM)(LPCSTR)TEXT("Error by creation semaphore")); }