Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > C++ Builder
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 16.04.2013, 04:33   #1
Makin_tosh
Пользователь
 
Регистрация: 16.10.2011
Сообщений: 24
По умолчанию Вывод прогреса на форму из TThread

Здравствуйте! Подскажите, как сделать так, чтобы поток, созданный в форме выводил прогрес на эту форму.
Требуется осуществлять копирование файлов потоками.
Делаю так:
Создаю поток в динамически созданной форме
Код:
SFile_Temp = Edit1->Text;
DFile_Temp = Edit2->Text;

VProcess_Temp = 1;
TProcess *ODF_ThreadPro;
ODF_ThreadPro = new TProcess(true, VProcess_Temp, true, SFile_Temp,
	DFile_Temp, SMFile_Temp, SMDir_Temp);
int id_Thread = ODF_ThreadPro->ThreadID;
TForm::Caption = id_Thread;
ODF_ThreadPro->FreeOnTerminate = true;
ODF_ThreadPro->Resume();
В потоке:
Код:
DWORD CALLBACK CopyProgressRoutine(
	LARGE_INTEGER  TotalFileSize,          // размер файла
	LARGE_INTEGER  TotalBytesTransferred,  // переносимые байты
	LARGE_INTEGER  StreamSize,             // байты в потоке
	LARGE_INTEGER  StreamBytesTransferred, // переносимые потоком байты
	DWORD  dwStreamNumber,                 // текущий поток
	DWORD  dwCallbackReason,               // причина возврата
	HANDLE  hSourceFile,                   // дескриптор источ. файла
	HANDLE  hDestinationFile,              // дескриптор целевого файла
	LPVOID  lpData)                        // из CopyFileEx
{
	if (dwCallbackReason == CALLBACK_CHUNK_FINISHED)
		{
			int percent = (( double(TotalFileSizeP_All) / double(TotalFileSize_All)) *100);

		String namePrg = (String)GetCurrentThreadId();
		HWND hwndPB = 0;
		hwndPB = FindWindow("TForm2", namePrg.t_str());
		if(hwndPB)
		{
		PostMessage(hwndPB, WM_HANDLE_THREAD_M4, percent, GetCurrentThreadId());
		}

			//Посылка сообщения об общем прогрессе
			//------------------------------------------------------------------
			ODFProPanelLabel4P = "Байтов отработано " + (String)float(TotalBytesTransferred.QuadPart);
			ODFProPanelLabel4P = ODFProPanelLabel4P + " из " + (String)float(TotalFileSize.QuadPart);
		}
	return PROGRESS_CONTINUE;
}
И в форме обрабатываю сообщение:
Код:
void __fastcall TForm2::HANDLE_THREAD_M4(TMessage &S_Message)
	//Окно прогресса операций над файлами и каталогами
	//Прогресс текущего файла в процессе
{
	if (TForm2::Caption == S_Message.LParam) {
		ProgressBar1->Position = S_Message.WParam;
	}
}
Сейчас получается так, что прогресс первой из созданных форм повторяет прогрес второй.
Makin_tosh вне форума Ответить с цитированием
Старый 16.04.2013, 10:24   #2
FataLL
Форумчанин
 
Аватар для FataLL
 
Регистрация: 29.01.2013
Сообщений: 319
По умолчанию

Предполагаю, что GetCurrentThreadId возвращает один и тот же Id, а именно - основного потока.
FataLL вне форума Ответить с цитированием
Старый 16.04.2013, 13:51   #3
Makin_tosh
Пользователь
 
Регистрация: 16.10.2011
Сообщений: 24
По умолчанию Вывод прогреса на форму из TThread

Сейчас сделал так:
Создал форму:
Код:
	TForm2 *Form2_ = new TForm2(Owner);
	Form2_->_proForm = Form2_->Handle;
	Form2_->Show();
В самой форме стартую поток:
Код:
		ODF_ThreadPro = new TProcess(true, _proForm_, VProcess_Temp, true, SFile_Temp,
									DFile_Temp, SMFile_Temp, SMDir_Temp);
В потоке:
Код:
__fastcall TProcess::TProcess(bool CreateSuspended, HANDLE proForm, int VProcess, bool OptCopy,
	String SFile_, String DFile_, String SMFile_, String SMDir_)
	: TThread(CreateSuspended)
{
	VProcess_Th = VProcess;
	OptCopy_Th = OptCopy;
	SFile_Th = SFile_;
	DFile_Th = DFile_;
	SMDir_Th = SMDir_;
	SMFile_Th = SMFile_;
	proForm_ = proForm;
}
Функция CopyFileEx(Src.t_str(), Dest.t_str(), &CopyProgressRoutine, proForm_, NULL, dwCopyFlags_))
В DWORD CALLBACK CopyProgressRoutine(
Код:
...
PostMessage((HWND)lpData, WM_HANDLE_THREAD_M4, 0, percent);
Все равно, ловят Message все формы с прогрессбаром.
Как все сделать правильно? Спасибо!
Makin_tosh вне форума Ответить с цитированием
Старый 16.04.2013, 14:50   #4
FataLL
Форумчанин
 
Аватар для FataLL
 
Регистрация: 29.01.2013
Сообщений: 319
По умолчанию

Непонятно, откуда _proForm_ при создании потока? По идее, там должно быть _proForm, или просто Handle.
FataLL вне форума Ответить с цитированием
Старый 16.04.2013, 16:46   #5
Avazart
Форумчанин
 
Аватар для Avazart
 
Регистрация: 13.08.2011
Сообщений: 184
По умолчанию

Передавать в поток - хендл его формы - слать сообщение содержащее соответствующему окну ( handl-у ).

И не использовать это :
Код:
hwndPB = FindWindow("TForm2", namePrg.t_str());
1. FindWindow находит первое попавшееся окно.
2. Не используйте t_str() - это зло ... ( указывайте конкретно либо c_str() либо w_str() )

Для синхронизации можно использовать TIdNotify.

Последний раз редактировалось Avazart; 16.04.2013 в 17:02.
Avazart вне форума Ответить с цитированием
Старый 16.04.2013, 19:02   #6
Makin_tosh
Пользователь
 
Регистрация: 16.10.2011
Сообщений: 24
По умолчанию

У меня создается дополнительная форма по кнопке Создать поток
Код:
	TForm2 *Form2_ = new TForm2(Owner);
	Form2_->_proForm = Form2_->Handle;
	Form2_->Show();
Цитата:
Непонятно, откуда _proForm_ при создании потока? По идее, там должно быть _proForm, или просто Handle.
Я изменил сейчас на Handle
Код:
		TProcess *ODF_ThreadPro;
		ODF_ThreadPro = new TProcess(true, Handle, VProcess_Temp, true, SFile_Temp,
									DFile_Temp, SMFile_Temp, SMDir_Temp);
И, пытаюсь передать сообщение:
Код:
		if (!CopyFileEx(Src.t_str(), Dest.t_str(), &CopyProgressRoutine, proForm_Th, NULL, dwCopyFlags_)) {
			return false;
		}
Собственно, пересылка сообщения:
Код:
               PostMessage((HWND)lpData, WM_HANDLE_THREAD_M4, 0, percent);
proForm_Th = proForm;

ВСЕ РАВНО! Прогресс двигается одинаково.

Avazart! Дайте пример пожалуйста.
Makin_tosh вне форума Ответить с цитированием
Старый 16.04.2013, 19:17   #7
Avazart
Форумчанин
 
Аватар для Avazart
 
Регистрация: 13.08.2011
Сообщений: 184
По умолчанию

TProcess это поток ? Что за названия такие блин ?
Avazart вне форума Ответить с цитированием
Старый 16.04.2013, 19:31   #8
Avazart
Форумчанин
 
Аватар для Avazart
 
Регистрация: 13.08.2011
Сообщений: 184
По умолчанию

Код:
TForm2 *Form2_ = new TForm2(Owner);
TMyThread* TMyThread1= new TMyThread(false, Form2->Handle);
//...
Avazart вне форума Ответить с цитированием
Старый 16.04.2013, 19:39   #9
Makin_tosh
Пользователь
 
Регистрация: 16.10.2011
Сообщений: 24
По умолчанию

Avazart! Не трудно будет Вам взглянуть на мой проект, если возможно, поправить?
Проба 2.zip
Makin_tosh вне форума Ответить с цитированием
Старый 16.04.2013, 20:20   #10
Avazart
Форумчанин
 
Аватар для Avazart
 
Регистрация: 13.08.2011
Сообщений: 184
По умолчанию

У вас в проекте Альфа скины как я его запущу ?
Avazart вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
C# вывод в форму bestnicer Помощь студентам 0 30.01.2013 13:57
вывод из бд в форму маГГ85 PHP 4 28.02.2012 15:04
При освобождении обьекта TThread, он вешает всю программу. При этом код Execute у TThread уж выполнился.. Человек_Борща Общие вопросы Delphi 23 30.11.2011 09:18
при закрытии потока(Tthread) посылать на форму код ответа или сообщение Человек_Борща Общие вопросы Delphi 2 14.12.2010 21:19
Вывод на форму prosto_i Microsoft Office Excel 4 28.09.2010 00:45