Пользователь
Регистрация: 23.03.2010
Сообщений: 43
|
Как прикрутить Events
Здравствуйте.
Прошу помощи, не могу разобраться с синхронизацией потоков
Написал вот такую программку, которая копирует несколько файлов в отдельных потоках.
После того как все файлы скопируются, выдается сообщение о завершении копирования. А вот как сделать, чтобы такое сообщение появлялось после завершения копирования каждого файла?
Код:
#pragma once
#include <windows.h>
#include <WindowsX.h>
#include <CommCtrl.h>
#include "resource.h"
#pragma comment (lib,"comctl32")
struct threads{
TCHAR szFileExist[255];
TCHAR szFileDest[255];
HWND hProgress;
HANDLE hThread;
};
threads Thr[5];
HWND hExist, hDest;
SECURITY_ATTRIBUTES sa;
BOOL bCancel;
int Count=0;
int Top=300;
BOOL CALLBACK DlgProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam);
DWORD CALLBACK CopyProgressRoutine(
__in LARGE_INTEGER TotalFileSize,
__in LARGE_INTEGER TotalBytesTransferred,
__in LARGE_INTEGER StreamSize,
__in LARGE_INTEGER StreamBytesTransferred,
__in DWORD dwStreamNumber,
__in DWORD dwCallbackReason,
__in HANDLE hSourceFile,
__in HANDLE hDestinationFile,
__in_opt LPVOID lpData
);
void Cls_OnClose(HWND hwnd);
BOOL Cls_OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam);
void Cls_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify);
DWORD WINAPI FileCopy(LPVOID lpParam);
int WINAPI WinMain( __in HINSTANCE hInstance, __in_opt HINSTANCE hPrevInstance, __in LPSTR lpCmdLine, __in int nShowCmd )
{
return DialogBox(hInstance,MAKEINTRESOURCE(IDD_DIALOG1),0,DlgProc);
}
BOOL CALLBACK DlgProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
switch(msg)
{
HANDLE_MSG(hwnd,WM_CLOSE,Cls_OnClose);
HANDLE_MSG(hwnd,WM_INITDIALOG,Cls_OnInitDialog);
HANDLE_MSG(hwnd,WM_COMMAND,Cls_OnCommand);
}
return FALSE;
}
void Cls_OnClose(HWND hwnd)
{
EndDialog(hwnd,0);
}
BOOL Cls_OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam)
{
hExist=GetDlgItem(hwnd,IDC_EDIT1);
hDest=GetDlgItem(hwnd,IDC_EDIT2);
return TRUE;
}
void Cls_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
{
if (id==IDC_PATH)
{
if(Count<5)
{
TCHAR Path[255];
TCHAR Buff[300];
SendMessage(hDest,WM_GETTEXT,255,(LPARAM)Path);
wsprintf(Buff,L"Копируется в: %s",Path);
Thr[Count].hProgress=CreateWindowEx(0,PROGRESS_CLASS,Buff,WS_VISIBLE|PBS_SMOOTH,300,Top,400,50,hwnd,NULL,NULL,NULL);
SendMessage(Thr[Count].hProgress,PBM_SETRANGE,0,MAKELPARAM(0,100));
SendMessage(Thr[Count].hProgress,PBM_SETSTEP,1,0);
SendMessage(Thr[Count].hProgress,PBM_SETPOS,0,0);
SendMessage(hExist,WM_GETTEXT,255,(LPARAM)Thr[Count].szFileExist);
SendMessage(hDest,WM_GETTEXT,255,(LPARAM)Thr[Count].szFileDest);
Count++;
Top+=100;
}
else
MessageBox(hwnd,L"Одновременно можно копировать не более 5-и файлов",L"Сообщение",MB_OK|MB_ICONERROR);
}
if(id==IDC_COPY_)
{
for (int i=0;i<Count;i++)
{
Thr[i].hThread=CreateThread(&sa,0,(LPTHREAD_START_ROUTINE)FileCopy,&Thr[i],0,NULL);
SetThreadPriority(Thr[i].hThread,THREAD_PRIORITY_IDLE);
}
}
}
DWORD WINAPI FileCopy(LPVOID lpParam)
{
DWORD ExitCode;
BOOL Copied=CopyFileEx(reinterpret_cast<threads *>(lpParam)->szFileExist,reinterpret_cast<threads *>(lpParam)->szFileDest,
CopyProgressRoutine,reinterpret_cast<threads *>(lpParam)->hProgress,&bCancel,COPY_FILE_FAIL_IF_EXISTS);
if(Copied==TRUE)
MessageBox(NULL,L"Копирование завершено",L"Сообщение",MB_OK|MB_ICONINFORMATION);
else
{
HLOCAL hlocal=NULL;
TCHAR Buff[500];
DWORD dwError=GetLastError();
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER,
NULL, dwError, MAKELANGID(LANG_RUSSIAN, SUBLANG_RUSSIAN_RUSSIA),
(LPTSTR) &hlocal, 0, NULL);
wsprintf(Buff,L"Не удалось скопировать файл:\n%s\n%s",reinterpret_cast<threads *>(lpParam)->szFileExist,(PCTSTR) LocalLock(hlocal));
LocalFree(hlocal);
MessageBox(NULL,Buff,L"Сообщение",MB_OK|MB_ICONERROR);
}
GetExitCodeThread(reinterpret_cast<threads *>(lpParam)->hThread,&ExitCode);
return ExitCode;
}
DWORD CALLBACK CopyProgressRoutine(
__in LARGE_INTEGER TotalFileSize,
__in LARGE_INTEGER TotalBytesTransferred,
__in LARGE_INTEGER StreamSize,
__in LARGE_INTEGER StreamBytesTransferred,
__in DWORD dwStreamNumber,
__in DWORD dwCallbackReason,
__in HANDLE hSourceFile,
__in HANDLE hDestinationFile,
__in_opt LPVOID lpData
)
{
static DWORD StepPrev;
if(TotalFileSize.QuadPart>=TotalBytesTransferred.QuadPart)
{
DWORD Step=100*TotalBytesTransferred.QuadPart/TotalFileSize.QuadPart;
if(Step!=StepPrev)
{
SendMessage((HWND)lpData,PBM_DELTAPOS,1,0);
StepPrev=Step;
}
return PROGRESS_CONTINUE;
}
else
return PROGRESS_STOP;
}
Заранее спасибо за помощь.
|