Консультация № 187230
28.03.2013, 20:45
400.00 руб.
30.03.2013, 13:56
0 15 1
Уважаемые эксперты! Здравствуйте! Пожалуйста помогите с решением:
Задание
Разработать программу, которая создает в отдельном потоке случайный массив А из N целых чисел в диапазоне от -999 до 999 выводит на экран эти числа. Создание и вывод элементов массива производится через заданное время T, N и T вводятся пользователем до запуска процесса. Массив обрабатывается двумя другими потоками ВиС, работающими параллельно с потоком, создающим массив. Все потоки выводят результаты своей работы в текстовые окна, каждый поток в свое окно
Задание В
Вычисление общего количества цифр всех элементов массива
Задание С
Определение и вывод чисел, являющихся простыми числами

выполняться приложение должно без ошибок в Borland C++ Builder 6.
Спасибо!
Методичка

Обсуждение

давно
Посетитель
7438
7205
29.03.2013, 21:31
общий
Здравствуйте, Иван, Владимирович!
Вы задали вопрос в рассылку по WinAPI. Вас устроит реализация на чистом WinAPI?
Или может перенесем вопрос в рассылку C/C++, чтобы дождаться решения именно на Builder-е?
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
30.03.2013, 07:44
общий
Адресаты:
Здравствуйте!
Наверное я не в ту ветку задал вопрос. Нужно пногопоточное приложение на С++ с применением функций WinAPI. Давайте перенесем.
давно
Посетитель
7438
7205
30.03.2013, 13:58
общий
Уважаемые эксперты! Обратите, пожалуйста, внимание на эту консультацию.
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Академик
20764
1861
30.03.2013, 14:37
общий
Может стоит сделать автоматическое уведомление экспертов о перенесённых консультациях?
Неизвестный
01.04.2013, 20:00
общий
Уважаемые эксперты! Помогите пожалуйста с вопросом, времени почти не осталось...
Буду очень благодарен!
Неизвестный
02.04.2013, 06:10
общий
У меня Borland C++ Builder 6 нету
Неизвестный
02.04.2013, 06:59
общий
Нужно многопоточное приложение на С++ с применением функций WinAPI. Билдер С++ отменяется, думаю можно сделать на любой платформе... Думаю совместимо все, должно работать.
Неизвестный
02.04.2013, 07:05
общий
А проблема-то в чём?
Неизвестный
02.04.2013, 07:49
общий
Ну вот простенький вариант, с двумя потоками, написано на 6-й студии, консольное приложение.
Код:


#include "stdafx.h"
#include <process.h>
#include <stdio.h>
#include <iostream.h>
#include <stdlib.h>
#include <windows.h>

// PARAMETER ---------------------------------------------------
struct CParam
{
int N;
int *A;
};

// THREAD A ---------------------------------------------------
void ThreadA(void *pvParam)
{
if(!pvParam)
{
_endthread();
return;
}
CParam *pParam = (CParam *)pvParam;
pParam->A = new int [pParam->N];
for(int i=0; i<pParam->N; 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)
{
cout<<"It looks like A is sleeping somewhere... \n";
_endthread();
}
for(int i=0; i<pParam->N; i++)
{
cout<<pParam->A[i]<<"\n";
}

_endthread();
}

// ---------------------------------------------------
void ThreadC(void *pvParam)
{
}

// MAIN ---------------------------------------------------
int main(int argc, char* argv[])
{
int N = -1;
int *A=NULL;
int T;

cout<<"hi, uso, what's size?";
cin >> N;
while(N<=0 || N>100)
{
if(N <= 0 )
cout<<"no, too small, try again\n";
else if(N > 100 )
cout<<"no, too big, try again\n";
cin >> N;
}

cout<<"what's time?";
cin >> T;
while(T<=0 || T>10)
{
if(T <= 0 )
cout<<"no, too short, try again\n";
else if(T > 10 )
cout<<"no, too long, try again\n";
cin >> T;
}

CParam param;
param.A = A;
param.N = N;

unsigned long ulThreadIdA = _beginthread( ThreadA, 0, (void*)¶m);
Sleep(T*1000);
unsigned long ulThreadIdB = _beginthread( ThreadB, 0, (void*)¶m);

WaitForSingleObject((HANDLE)ulThreadIdB, INFINITE);

cout << "just type somth and press enter\n";
cin>>N;

return 0;
}



WaitForSingleObject + <windows.h> в принципе не нужен, можно заменить на Sleep(T*1000); для большей соместимости или убрать совсем.
cin в конце я поставил для просмотра в режиме отладки.
Неизвестный
02.04.2013, 08:53
общий
Спасибо за внимание к вопросу! Но нужно не консольное приложение, а под Win с формами и т.д. (пробегитесь по методичке, там пример для Delphi). Студию скачаю, поставлю, пусть будет в студии. А проблема в том что я в этих делах ни в зуб ногой
Прикрепленные файлы:
421cbc92e64a379e4f168a812e0c7e2d.docx
Неизвестный
02.04.2013, 09:42
общий
Добавил два окна, но начало осталось консольное, лень переделывать.
Оба окна открываются в основном потоке и потом передаются через параметр.
Указатель на массив передаётся теперь как адрес указателя, чтобы его можно было прокинуть во второй поток.

В конце основного потока стоит цикл диспетчера сообщений, который заканчивается, если оба окна закрыты.

Два последний потока построены на одной функции ThreadB, различаются только передаваемым параметром (т.о. только окном внутри параметра)

Код:

#include "stdafx.h"
#include <process.h>
#include <stdio.h>
#include <iostream.h>
//#include <stdlib.h>
#include <windows.h>


// PARAMETER ---------------------------------------------------
struct CParam
{
int N;
int **A;
HWND hWndOut;
};

// THREAD A ---------------------------------------------------
void ThreadA(void *pvParam)
{
if(!pvParam)
{
_endthread();
return;
}
CParam *pParam = (CParam *)pvParam;
*(pParam->A) = new int [pParam->N];
for(int i=0; i<pParam->N; 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; i<pParam->N; i++)
{
GetWindowText(pParam->hWndOut, szData, 1024);
sprintf(szTmp, "%d\r\n", (*pParam->A)[i]);
strcat(szData, szTmp);
SetWindowText(pParam->hWndOut, szData);
//cout<<pParam->A[i]<<"\n";
}

_endthread();
}

// MAIN ---------------------------------------------------
int main(int argc, char* argv[])
{
int N = -1;
int *A=NULL;
int T;

HWND hWnd1 = CreateWindowEx(WS_EX_TOPMOST, "EDIT", "", WS_OVERLAPPEDWINDOW|WS_VISIBLE|WS_VSCROLL|WS_HSCROLL|ES_MULTILINE, 10, 10, 400, 200, NULL, NULL, GetModuleHandle(NULL), NULL);
HWND hWnd2 = CreateWindowEx(WS_EX_TOPMOST, "EDIT", "", WS_OVERLAPPEDWINDOW|WS_VISIBLE|WS_VSCROLL|WS_HSCROLL|ES_MULTILINE, 20, 20, 400, 200, NULL, NULL, GetModuleHandle(NULL), NULL);

cout<<"hi, uso, what's size?";
cin >> N;
while(N<=0 || N>100)
{
if(N <= 0 )
cout<<"no, too small, try again\n";
else if(N > 100 )
cout<<"no, too big, try again\n";
cin >> N;
}

cout<<"what's time?";
cin >> T;
while(T<=0 || T>10)
{
if(T <= 0 )
cout<<"no, too short, try again\n";
else if(T > 10 )
cout<<"no, too long, try again\n";
cin >> T;
}

CParam param1;
param1.A = &A;
param1.N = N;
param1.hWndOut = hWnd1;

CParam param2;
param2.A = &A;
param2.N = N;
param2.hWndOut = hWnd2;

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);

MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if(!IsWindow(hWnd1) && !IsWindow(hWnd2))
break;
}

return 0;
}




всё, дальше самостоятельно
Неизвестный
02.04.2013, 14:04
общий
Полнотью оконный вариант:

Код:
#include "stdafx.h"
#include <process.h>
#include <stdio.h>
#include <stdlib.h>

// 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; i<pParam->N; 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; i<pParam->N; 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;
}




немного не по науке, но работает

ещё один важный момент: в свойствах проекта должно быть указано, что он многопоточный (в 6-й студии по умолчанию - однопоточный)
Неизвестный
04.04.2013, 21:58
общий
Не хотите оформить ответ?
Неизвестный
05.04.2013, 06:10
общий
это ответ
Здравствуйте, Иванов Иван Владимирович!

Код собран под MS VC++ 6.0, под 2010 тоже собирается.

Состоит из диалога с двумя полями для ввода данных и кнопкой для запуска процесса.
По нажатию кнопки открываются 2 окна.
Запускается первый поток, создающий числа, функция ThreadA
После таймаута запускаются ещё два потока, выводящие числа, функция ThreadB
Данные в поток передаются через структуру CParam.



Приложение:
#include "stdafx.h"
#include <process.h>
#include <stdio.h>
#include <stdlib.h>

// 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; i<pParam->N; 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; i<pParam->N; 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;
}


5
Неизвестный
05.04.2013, 08:00
общий
Не знаю, как поредактировать ответ, а вот код с более подробными комментариями, если можно, закиньте его в ответ
И в проверке на таймаут там ошибка, не 100 а 10 надо

Код:
#include "stdafx.h"
#include <process.h>
#include <stdio.h>
#include <stdlib.h>

// 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; // параметр для 1 и 2 потоков
static CParam param2; // параметр для 3 потока
// последние два можно было объявить прямо в WinMain

// 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; i<pParam->N; 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; i<pParam->N; 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)
{
// если нажали [x]
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);
// проверим, что она попадает в промежуток 1..10
if(T <= 0 )
{
MessageBox(hWnd, "T is too short, must be > 0", "error", MB_OK|MB_ICONERROR);
break;
}
else if(T > 10 )
{
MessageBox(hWnd, "T is too long, must be <= 10 sec.", "error", MB_OK|MB_ICONERROR);
break;
}
// теперь, если окна для вывода ещё не были созданы, создадим их.
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));
// блокируем кнопку [Go!] до тех пор, пока потоки не отрботают
EnableWindow(GetDlgItem(hWnd, IDRETRY), FALSE);
// собираем параметры для потоков:
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*)&Param1);
// ждём:
Sleep(T*1000);
// запускаем остальные потоки:
unsigned long ulThreadIdB = _beginthread( ThreadB, 0, (void*)&Param1);
unsigned long ulThreadIdC = _beginthread( ThreadB, 0, (void*)&Param2);
// устанавливаем таймер для опроса состояния потоков, 50 мсек.
SetTimer(hWnd, 1, 50, NULL);
}
break;
}
}
break;
case WM_TIMER:
// проверяем, выполнились ли оба потока?
if(param1.bComplete && param2.bComplete)
{
// если да - останавливаем таймер
KillTimer(hWnd, 1);
// и разблокируем кнопку [Go!]
EnableWindow(GetDlgItem(hWnd, IDRETRY), TRUE);
// возвращаем курсор-стрелочку
SetCursor(LoadCursor(NULL, IDC_ARROW));
}
break;
}
return 0;
}


// основная функция приложения, точка входа в программу
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
// создаём диалоговое окно и кнопку [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);

// создаём поля ввода и надписи к ним
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);

// приписываем функцию обработки к нашему дилоговому окну
SetWindowLong(hWndMain, DWL_DLGPROC, (long)DlgProc);

// стандартный цикл обрабоки сообщений Windows для приложения
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;
}


Форма ответа