Разработать программу, которая создает в отдельном потоке случайный массив А из N целых чисел в диапазоне от -999 до 999 выводит на экран эти числа. Создание и вывод элементов массива производится через заданное время T, N и T вводятся пользователем до запуска процесса....
Код собран под MS VC++ 6.0, под 2010 тоже собирается.
Состоит из диалога с двумя полями для ввода данных и кнопкой для запуска процесса.
По нажатию кнопки открываются 2 окна.
Запускается первый поток, создающий числа, функция ThreadA
После таймаута запускаются ещё два потока, выводящие числа, функция ThreadB
Данные в поток передаются через структуру CParam.
#include "stdafx.h"
#include
#include
#include
// DEFINITIONS ---------------------------------------------------
#define IDC_EDIT_NUMBER 1001
#define IDC_EDIT_TIMEOUT 1002
// PARAMETER ---------------------------------------------------
struct CParam
{
int N;
int **A;
HWND hWndOut;
BOOL bComplete;
};
// LOCAL -------------------------------------------------------
static HWND hWnd1 = NULL;
static HWND hWnd2 = NULL;
static int N = -1;
static int *A=NULL;
static int T;
static CParam param1;
static CParam param2;
// THREAD A ---------------------------------------------------
void ThreadA(void *pvParam)
{
if(!pvParam)
{
_endthread();
return;
}
CParam *pParam = (CParam *)pvParam;
*(pParam->A) = new int [pParam->N];
srand(GetTickCount());
for(int i=0; iN; i++)
{
(*pParam->A)[i] = rand()%1999 - 999;
}
_endthread();
}
// THREAD B ---------------------------------------------------
void ThreadB(void *pvParam)
{
if(!pvParam)
{
_endthread();
return;
}
CParam *pParam = (CParam *)pvParam;
if(NULL == pParam->A || NULL == *pParam->A)
{
SetWindowText(pParam->hWndOut, "It looks like A is sleeping somewhere... \r\n");
_endthread();
}
char szData[1024] = "";
char szTmp[128];
for(int i=0; iN; i++)
{
GetWindowText(pParam->hWndOut, szData, 1024);
sprintf(szTmp, "%d\r\n", (*pParam->A)[i]);
strcat(szData, szTmp);
SetWindowText(pParam->hWndOut, szData);
}
pParam->bComplete = TRUE;
_endthread();
}
// DLG PROCEDURE -----------------------------------------------
LRESULT CALLBACK DlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_COMMAND:
{
int wmId = LOWORD(wParam);
int wmEvent = HIWORD(wParam);
switch(wmId)
{
case IDCANCEL:
if(IDOK == MessageBox(hWnd, "quit ?", "confirmation", MB_OKCANCEL|MB_DEFBUTTON2|MB_ICONQUESTION))
PostQuitMessage(0);
break;
// [Go!]
case IDRETRY:
{
TCHAR szText[128];
GetDlgItemText(hWnd, IDC_EDIT_NUMBER, szText, 127);
int N = atoi(szText);
// CHECK #1, for entry data
if(N <= 0 )
{
MessageBox(hWnd, "N is too small, must be > 0", "error", MB_OK|MB_ICONERROR);
break;
}
else if(N > 100 )
{
MessageBox(hWnd, "N is too big, must be <= 100", "error", MB_OK|MB_ICONERROR);
break;
}
// CHECK #2, for timeout
GetDlgItemText(hWnd, IDC_EDIT_TIMEOUT, szText, 127);
int T = atoi(szText);
if(T <= 0 )
{
MessageBox(hWnd, "T is too short, must be > 0", "error", MB_OK|MB_ICONERROR);
break;
}
else if(T > 100 )
{
MessageBox(hWnd, "T is too long, must be <= 10 sec.", "error", MB_OK|MB_ICONERROR);
break;
}
// ALL IS OK!
if(!IsWindow(hWnd1))
hWnd1 = CreateWindowEx(WS_EX_TOPMOST, "EDIT", "", WS_OVERLAPPEDWINDOW|WS_VISIBLE|WS_VSCROLL|WS_HSCROLL|ES_MULTILINE, 10, 10, 200, 200, NULL, NULL, GetModuleHandle(NULL), NULL);
else
SetWindowText(hWnd1, "");
if(!IsWindow(hWnd2))
hWnd2 = CreateWindowEx(WS_EX_TOPMOST, "EDIT", "", WS_OVERLAPPEDWINDOW|WS_VISIBLE|WS_VSCROLL|WS_HSCROLL|ES_MULTILINE, 210, 10, 200, 200, NULL, NULL, GetModuleHandle(NULL), NULL);
else
SetWindowText(hWnd2, "");
SetCursor(LoadCursor(NULL, IDC_WAIT));
EnableWindow(GetDlgItem(hWnd, IDRETRY), FALSE);
// COMPILE PARAMETERS
param1.A = &A;
param1.N = N;
param1.hWndOut = hWnd1;
param1.bComplete = FALSE;
//
param2.A = &A;
param2.N = N;
param2.hWndOut = hWnd2;
param2.bComplete = FALSE;
unsigned long ulThreadIdA = _beginthread( ThreadA, 0, (void*)¶m1);
Sleep(T*1000);
unsigned long ulThreadIdB = _beginthread( ThreadB, 0, (void*)¶m1);
unsigned long ulThreadIdC = _beginthread( ThreadB, 0, (void*)¶m2);
// WAIT
SetTimer(hWnd, 1, 50, NULL);
}
break;
}
}
break;
case WM_TIMER:
if(param1.bComplete && param2.bComplete)
{
KillTimer(hWnd, 1);
EnableWindow(GetDlgItem(hWnd, IDRETRY), TRUE);
SetCursor(LoadCursor(NULL, IDC_ARROW));
}
break;
}
return 0;
}
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
// Create Dialog & button [Go!]
HWND hWndMain = CreateWindowEx(WS_EX_TOPMOST, "#32770", "Main window", WS_OVERLAPPEDWINDOW|WS_VISIBLE|DS_3DLOOK, 300, 300, 500, 300, NULL, NULL, GetModuleHandle(NULL), NULL);
HWND hGo = CreateWindowEx(0, "BUTTON", "Go!", WS_VISIBLE|WS_CHILD|WS_TABSTOP|BS_DEFPUSHBUTTON, 330, 220, 50, 20, hWndMain, (HMENU)IDRETRY, GetModuleHandle(NULL), NULL);
// Create edit elements
HWND hStatic1 = CreateWindowEx(0, "STATIC", "Number of numbers, N:", WS_VISIBLE|WS_CHILD|ES_NUMBER, 10, 10, 250, 20, hWndMain, (HMENU)-1, GetModuleHandle(NULL), NULL);
HWND hEdit1 = CreateWindowEx(0, "EDIT", "", WS_VISIBLE|WS_CHILD|WS_TABSTOP|ES_NUMBER, 10, 30, 250, 20, hWndMain, (HMENU)IDC_EDIT_NUMBER, GetModuleHandle(NULL), NULL);
HWND hStatic2 = CreateWindowEx(0, "STATIC", "Timeout in sec., T:", WS_VISIBLE|WS_CHILD|ES_NUMBER, 10, 50, 250, 20, hWndMain, (HMENU)-1, GetModuleHandle(NULL), NULL);
HWND hEdit2 = CreateWindowEx(0, "EDIT", "", WS_VISIBLE|WS_CHILD|WS_TABSTOP|ES_NUMBER, 10, 70, 250, 20, hWndMain, (HMENU)IDC_EDIT_TIMEOUT, GetModuleHandle(NULL), NULL);
SetFocus(hEdit1);
// attach Dialog procedure
SetWindowLong(hWndMain, DWL_DLGPROC, (long)DlgProc);
// main message loop
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
if(!IsDialogMessage(hWndMain, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if(!IsWindow(hWnd1) && !IsWindow(hWnd2) && !IsWindow(hWndMain))
break;
}
return 0;
}