//Листинг 6.6 Демонстрация работы семафора #include #include HANDLE hSemaphore; INT_PTR CALLBACK Dialog1(HWND, UINT, WPARAM,LPARAM); ////////////////////////////////////////////// HWND SetElement(HWND hDlg, HDC& mem, WORD IdBitmap, WORD IdProgress) { HBITMAP hBitmap = LoadBitmap(hInst, MAKEINTRESOURCE(IdBitmap)); HDC hdc = GetDC(hDlg); mem = CreateCompatibleDC(hdc); ReleaseDC(hDlg, hdc); SelectObject(mem, hBitmap); HWND handle = GetDlgItem(hDlg, IdProgress); SendMessage(handle, PBM_SETRANGE, 0, 30<<16); SendMessage(handle, PBM_SETSTEP, 1, 0); SendMessage(handle, PBM_SETPOS, 0, 0); return handle; } ////////////////////////////////////////////// unsigned __stdcall MyTbread1(void* param) { HWND hWnd = (HWND)param; HDC hdc, mem; int t = 0; HWND hProgress = SetElement(hWnd, mem, IDB_BITMAP1, IDC_PROGRESS1); while(1) { WaitForSingleObject(hSemaphore, INFINITE); Sleep(500); hdc = GetDC(hWnd); BitBlt(hdc, 320, 25, 25, 50, mem, 0, 0, SRCCOPY); ReleaseDC(hWnd, hdc); if (++t > 30) t = 0; SendMessage(hProgress, PBM_SETPOS, t, 0); ReleaseSemaphore(hSemaphore, 1, NULL); } return 0; } ////////////////////////////////////////////// unsigned __stdcall MyThread2(void* param) { HWND hWnd = (HWND)param; HDC hdc, mem; int t = 0; HWND hProgress = SetElement(hWnd, mem, IDB_BITMAP2, IDC_PROGRESS2); while(1) { WaitForSingleObject(hSemaphore, INFINITE); Sleep(500); hdc = GetDC(hWnd); BitBlt(hdc, 320, 25, 25, 50, mem, 0, 0, SRCCOPY); ReleaseDC(hWnd, hdc); if (++t > 30) t = 0; SendMessage(hProgress, PBM_SETPOS, t, 0); ReleaseSemaphore(hSemaphore, 1, NULL); } return 0; } ////////////////////////////////////////////// LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_COMMAND: switch (LOWORD(wParam)) { case ID_SEMAPHORE: DialogBox(hInst, MAKEINTRESOURCE(IDD_DIALOG1), hWnd, Dialog1); break; case IDM_EXIT: DestroyWindow(hWnd); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; } /////////////////////////////////////////////// INT_PTR CALLBACK Dialog1(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { static HANDLE hThread1, hThread2; switch (message) { case WM_INITDIALOG: InitCommonControls(); hSemaphore = CreateSemaphore(NULL, 1, 1, NULL); hThread1 = (HANDLE)_beginthreadex(NULL, 0, MyTbread1, hDlg, 0, NULL); hThread2 = (HANDLE)_beginthreadex(NULL, 0, MyThread2, hDlg, 0, NULL); return TRUE; case WM_COMMAND: if (LOWORD(wParam) == IDCANCEL) { TerminateThread(hThread1, 0); TerminateThread(hThread2, 0); CloseHandle(hThread1); CloseHandle(hThread2); EndDialog(hDlg, 0); return TRUE; } break; } return FALSE; }