Russian Qt Forum

Qt => Вопросы новичков => Тема начата: koldun90 от Март 28, 2015, 10:15



Название: copyFileEx+winapi
Отправлено: koldun90 от Март 28, 2015, 10:15
Здравствуйте вопрос в следующем
почему copyfile winapi
не копирует системный файл

так копируеи

Код
C++ (Qt)
LPCSTR q=QString("C:\\am74364.dll").toLocal8Bit().data();
 
 
   LPCSTR a=QString("C:\\a\\am74364.dll").toLocal8Bit().data();
 
   BOOL ok=true;
 
  CopyFileA(q,a,ok);

а так нет..
Код
C++ (Qt)
LPCSTR q=QString("C:\\pagefile.sys").toLocal8Bit().data();
 
 
   LPCSTR a=QString("C:\\a\\pagefile.sys").toLocal8Bit().data();
 
   BOOL ok=true;
 
  CopyFileA(q,a,ok);


Название: Re: copyfile winapi
Отправлено: gil9red от Март 28, 2015, 10:23
Странно...

А почему не воспользуйтесь Qt?
Код
C++ (Qt)
QFile::copy("/path/file", "/path/copy-of-file");


Название: Re: copyfile winapi
Отправлено: Bepec от Март 28, 2015, 10:27
Не тормози, ошибку посмотри, нам напиши и довольный уходи :D


Название: Re: copyfile winapi
Отправлено: koldun90 от Март 28, 2015, 11:47
мне не понятно как использовать еще функцию CopyFileEx

Код
C++ (Qt)
BOOL CopyFileEx(
 LPCTSTR lpExistingFileName,           // имя существующего файла
 LPCTSTR lpNewFileName,                // имя нового файла
 LPPROGRESS_ROUTINE lpProgressRoutine, // функция обратного вызова
 LPVOID lpData,                        // параметры обратного вызова
 LPBOOL pbCancel,                      // отмененный статус
 DWORD dwCopyFlags                     // опции копирования
);
 
первый и второй параметр понятно
 LPPROGRESS_ROUTINE lpProgressRoutine, // функция обратного вызова
  LPVOID lpData,                        // параметры обратного вызова

функцию обратного вызова я должен сам в проекте определить правильно?
LPVOID lpData,                        // параметры обратного вызова   -- и что нужно указывать в параметрах обратного вызова)



Название: Re: copyfile copyfileex winapi
Отправлено: koldun90 от Март 28, 2015, 11:50
в mainwindow.h написал определил свою функцию

Код
C++ (Qt)
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);

в mainwindow.cpp

Код
C++ (Qt)
DWORD CALLBACK MainWindow::CopyProgressRoutine(LARGE_INTEGER TotalFileSize,
                                                  LARGE_INTEGER TotalBytesTransferred,
                                                  LARGE_INTEGER StreamSize,
                                                  LARGE_INTEGER StreamBytesTransferred,
                                                  DWORD dwStreamNumber,
                                                  DWORD dwCallbackReason,
                                                  HANDLE hSourceFile,
                                                  HANDLE hDestinationFile,
                                                  LPVOID lpData)
 
{
 
 
 
         return PROGRESS_CONTINUE;
}

вот только мне не понятно как мне вызывать функцию copyfileEx
Код
C++ (Qt)
CopyFileExA(q,a,&CopyProgressRoutine,NULL,FALSE,COPY_FILE_FAIL_IF_EXISTS);



Название: Re: copyfile copyfileex winapi
Отправлено: koldun90 от Март 28, 2015, 11:56
Код
C++ (Qt)
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
немпонятно как вызвать собственно мою функцию
из CopyFileEx

и как мне передать
в функцию CopyProgressRoutine
значения все кроме самого первого
потому что размер я могу вычислить методом qfile::size()


Название: Re: copyfile copyfileex winapi
Отправлено: Bepec от Март 28, 2015, 12:29
Эт называется от дурной головы рукам работы. Ошибку словите при помощи GetLastError. После обычной copyFile.


Название: Re: copyfile copyfileex winapi
Отправлено: koldun90 от Март 28, 2015, 12:41
я разобрался с copyFile
 
Код
C++ (Qt)
LPCSTR q=QString("C:\\am74364.dll").toLocal8Bit().data();
 
 
  LPCSTR a=QString("C:\\a\\am74364.dll").toLocal8Bit().data();
 
 
   BOOL ok=true;
   LPPROGRESS_ROUTINE progre;
  CopyFileA(q,a,ok);

так работает
тока не пойму что нужно сделать в copyfileEx


Название: Re: copyfile copyfileex winapi
Отправлено: koldun90 от Март 28, 2015, 12:45
я просто winapi начал изучать как бы
и вот хотелось бы сделать так копирую я файлик 500 мегабайт
скопировалась какая то часть и мне нужно получить сколько скопировалось допустим 10 мегабайт
вот я хочу использовать copyFileEx только не знаю что делать начиная с 3 параметра



Название: Re: copyfile copyfileex winapi
Отправлено: koldun90 от Март 28, 2015, 13:12
сделал по аналогии
http://www.jackyfox.com/2010/11/29/progress-kopirovaniya-fayla-copyfileex-i-progressbar/

Код
C++ (Qt)
#include "mainwindow.h"
#include "ui_mainwindow.h"
 
//#include <winbase.h>
 
 
MainWindow::MainWindow(QWidget *parent) :
   QMainWindow(parent),
   ui(new Ui::MainWindow)
{
   ui->setupUi(this);
 
   LPCSTR q=QString("C:\\am74364.dll").toLocal8Bit().data();
 
 
   LPCSTR a=QString("C:\\a\\am74364.dll").toLocal8Bit().data();
   LPPROGRESS_ROUTINE d;
 
   BOOL ok=true;
   LPPROGRESS_ROUTINE progre;
 
 
CopyFileExA(q,a,CopyProgressRoutine,NULL, 0, COPY_FILE_FAIL_IF_EXISTS);
 
 
 
}
 
MainWindow::~MainWindow()
{
   delete ui;
}
 
DWORD CALLBACK MainWindow::CopyProgressRoutine(LARGE_INTEGER TotalFileSize,
                                                  LARGE_INTEGER TotalBytesTransferred,
                                                  LARGE_INTEGER StreamSize,
                                                  LARGE_INTEGER StreamBytesTransferred,
                                                  DWORD dwStreamNumber,
                                                  DWORD dwCallbackReason,
                                                  HANDLE hSourceFile,
                                                  HANDLE hDestinationFile,
                                                  LPVOID lpData)
{
 
 
 
         ui->progressBar->setValue(TotalBytesTransferred.QuadPart/TotalFileSize.QuadPart);
         return PROGRESS_CONTINUE;
}
 
 

ругается на
Код
C++ (Qt)
CopyFileExA(q,a,CopyProgressRoutine,NULL, 0, COPY_FILE_FAIL_IF_EXISTS);

Код:
D:\423423\copy\mainwindow.cpp:23: ошибка: cannot convert 'MainWindow::CopyProgressRoutine' from type 'DWORD (MainWindow::)(LARGE_INTEGER, LARGE_INTEGER, LARGE_INTEGER, LARGE_INTEGER, DWORD, DWORD, HANDLE, HANDLE, LPVOID) {aka long unsigned int (MainWindow::)(_LARGE_INTEGER, _LARGE_INTEGER, _LARGE_INTEGER, _LARGE_INTEGER, long unsigned int, long unsigned int, void*, void*, void*)}' to type 'LPPROGRESS_ROUTINE {aka long unsigned int (__attribute__((__stdcall__)) *)(_LARGE_INTEGER, _LARGE_INTEGER, _LARGE_INTEGER, _LARGE_INTEGER, long unsigned int, long unsigned int, void*, void*, void*)}'
  CopyFileExA(q,a,CopyProgressRoutine,NULL, 0, COPY_FILE_FAIL_IF_EXISTS);

вроде нужно как то вызвать с параметрами но хз как подскажите
                                                                       ^


Название: Re: copyfile copyfileex winapi
Отправлено: koldun90 от Март 28, 2015, 13:56
я так понял мне нужно вызвать call back функцию а как мне это сделать?


Название: Re: copyfile copyfileex winapi
Отправлено: alex312 от Март 28, 2015, 14:29
http://www.codeguru.com/cpp/cpp/cpp_mfc/callbacks/article.php/c10557/Callback-Functions-Tutorial.htm


Название: Re: copyfile copyfileex winapi
Отправлено: koldun90 от Март 28, 2015, 14:58
не очень понятно не могли бы объяснить
как все таки мне седлать коллбек CopyProgressRoutine


Название: Re: copyfile copyfileex winapi
Отправлено: koldun90 от Март 28, 2015, 16:47
Сделал так но почему то ошибка на строке

Код
C++ (Qt)
Test=&CopyProgressRoutine;

mainwindow.h
Код
C++ (Qt)
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <windows.h>
#include <QMainWindow>
 
namespace Ui {
class MainWindow;
}
 
class MainWindow : public QMainWindow
{
   Q_OBJECT
 
public:
   explicit MainWindow(QWidget *parent = 0);
   ~MainWindow();
   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
   );
   void soobch();
 
LPPROGRESS_ROUTINE progre;
 
private:
   Ui::MainWindow *ui;
};
 
#endif // MAINWINDOW_H
 
mainwindow.cpp


Код
C++ (Qt)
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMessageBox>
 
//#include <winbase.h>
 
 
MainWindow::MainWindow(QWidget *parent) :
   QMainWindow(parent),
   ui(new Ui::MainWindow)
{
   ui->setupUi(this);
   DWORD CALLBACK(*Test)(LARGE_INTEGER,LARGE_INTEGER,LARGE_INTEGER,LARGE_INTEGER,DWORD,DWORD,HANDLE,HANDLE,LPVOID);
   Test=&CopyProgressRoutine;
 
   LPCSTR q=QString("C:\\am74364.dll").toLocal8Bit().data();
 
 
   LPCSTR a=QString("C:\\a\\am74364.dll").toLocal8Bit().data();
 
 
 
   LPVOID data;
 
CopyFileExA(q,a,Test,0,FALSE,COPY_FILE_FAIL_IF_EXISTS);
 
 
 
}
 
MainWindow::~MainWindow()
{
   delete ui;
}
 
DWORD CALLBACK MainWindow::CopyProgressRoutine(LARGE_INTEGER TotalFileSize,
                                                  LARGE_INTEGER TotalBytesTransferred,
                                                  LARGE_INTEGER StreamSize,
                                                  LARGE_INTEGER StreamBytesTransferred,
                                                  DWORD dwStreamNumber,
                                                  DWORD dwCallbackReason,
                                                  HANDLE hSourceFile,
                                                  HANDLE hDestinationFile,
                                                  LPVOID lpData)
 
{
 
 
         ui->progressBar->setValue(TotalBytesTransferred.QuadPart/TotalFileSize.QuadPart);
         return PROGRESS_CONTINUE;
}
 
void MainWindow::soobch()
{
   QMessageBox msg;
   msg.setText("11111");
   msg.exec();
}
 


Название: Re: copyfile copyfileex winapi
Отправлено: koldun90 от Март 28, 2015, 17:57
вот так вот программа запускается и подает признаки жизни
при клике по кнопке начинается копирование файла файл 10 гигабайт
Код
C++ (Qt)
void MainWindow::on_pushButton_clicked()
{
   LPCSTR q=QString("D:\\0C").toLocal8Bit().data();
 
 
   LPCSTR a=QString("D:\\qw\\0C").toLocal8Bit().data();
LPVOID lpData;
 
CopyFileExA(q,a,(LPPROGRESS_ROUTINE)&MyCopyProgressRoutine,NULL,FALSE,COPY_FILE_FAIL_IF_EXISTS);
DWORD p=GetLastError();
 
cout<<p<<endl;
}

 
Код
C++ (Qt)
DWORD p=GetLastError();
 
cout<<p<<endl;
эта штука распечатывает число 80
что может быть?
типо файл уже существует

вот бывает что происходит такая штука
Сигнатура проблемы:
  Имя события проблемы:   APPCRASH
  Имя приложения:   copy.exe
  Версия приложения:   0.0.0.0
  Отметка времени приложения:   033b8118
  Имя модуля с ошибкой:   copy.exe
  Версия модуля с ошибкой:   0.0.0.0
  Отметка времени модуля с ошибкой:   033b8118
  Код исключения:   c0000005
  Смещение исключения:   0000181b
  Версия ОС:   6.1.7601.2.1.0.256.1
  Код языка:   1049
  Дополнительные сведения 1:   0a9e
  Дополнительные сведения 2:   0a9e372d3b4ad19135b953a78882e789
  Дополнительные сведения 3:   0a9e
  Дополнительные сведения 4:   0a9e372d3b4ad19135b953a78882e789

такая фигня если удаляю файл из приемника и перезапускаю прогу


Название: Re: copyfile copyfileex winapi
Отправлено: alex312 от Март 29, 2015, 06:21
не очень понятно не могли бы объяснить
как все таки мне седлать коллбек CopyProgressRoutine
Cделай как в примере, что ты указывал. Т.е. калбэк должен быть отдельной функцией, а не методом класса ( в крайнем случае статическим методом).


Название: Re: copyFileEx+winapi
Отправлено: koldun90 от Март 29, 2015, 07:14
сделал так
mainwindow.h
Код
C++ (Qt)
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <windows.h>
#include <QMainWindow>
 
DWORD CALLBACK MyCopyProgressRoutine(
        LARGE_INTEGER TotalFileSize,
       LARGE_INTEGER TotalBytesTransferred,
       LARGE_INTEGER StreamSize,
       LARGE_INTEGER StreamBytesTransferred,
       DWORD dwStreamNumber,
       DWORD dwCallbackReason,
       HANDLE hSourceFile,
       HANDLE hDestinationFile,
       LPVOID lpData
     );
 
namespace Ui {
class MainWindow;
}
 
class MainWindow : public QMainWindow
{
   Q_OBJECT
 
public:
   explicit MainWindow(QWidget *parent = 0);
   ~MainWindow();
 
void pb(LARGE_INTEGER,LARGE_INTEGER);
 
LPPROGRESS_ROUTINE progre;
 
private slots:
void on_pushButton_clicked();
 
 
private:
   Ui::MainWindow *ui;
 
};
 
#endif // MAINWINDOW_H

mainwindow.cpp

Код
C++ (Qt)
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMessageBox>
#include <iostream>
#include <cstring>
//#include <winbase.h>
 
using namespace std;
 
MainWindow::MainWindow(QWidget *parent) :
   QMainWindow(parent),
   ui(new Ui::MainWindow)
{
   ui->setupUi(this);
   ui->progressBar->setMaximum(100);
//   DWORD CALLBACK(*Test)(LARGE_INTEGER,LARGE_INTEGER,LARGE_INTEGER,LARGE_INTEGER,DWORD,DWORD,HANDLE,HANDLE,LPVOID);
 //  Test=&MyCopyProgressRoutine;
 
 
 
 
}
 
MainWindow::~MainWindow()
{
   delete ui;
}
 
DWORD CALLBACK MyCopyProgressRoutine( LARGE_INTEGER TotalFileSize,  // размер файла в байтах
                                                  LARGE_INTEGER TotalBytesTransferred,  //байтов скопировано
                                                   LARGE_INTEGER StreamSize,
                                                  LARGE_INTEGER StreamBytesTransferred,
                                                  DWORD dwStreamNumber,
                                                  DWORD dwCallbackReason,
                                                  HANDLE hSourceFile,
                                                  HANDLE hDestinationFile,
                                                  LPVOID lpData)
 
 
{
//    switch(dwCallbackReason)
//    {
//        case CALLBACK_CHUNK_FINISHED:
//ui->progressBar->setValue((StreamSize.QuadPart*100)/TotalFileSize.QuadPart);
   //string w=QString("скопировано ").toStdString().data()
    MainWindow *s;
    s->pb(StreamSize,TotalFileSize);
 
           return PROGRESS_CONTINUE;   //StreamSize.
 
 
//    }
 
}
 
 
 
 
 
void MainWindow::on_pushButton_clicked()
{
   LPCSTR q=QString("D:\\NBA 2K15\\1I").toLocal8Bit().data();
//    LARGE_INTEGER s(1);
//            LARGE_INTEGER q(2);
//    pb(1,2);
 
   LPCSTR a=QString("D:\\qw\\123").toLocal8Bit().data();
LPVOID lpData;
QApplication::processEvents();
CopyFileExA(q,a,(LPPROGRESS_ROUTINE)&MyCopyProgressRoutine,NULL,FALSE,COPY_FILE_FAIL_IF_EXISTS);
// DWORD p=GetLastError();
 
// cout<<p<<endl;
}
void MainWindow::pb(LARGE_INTEGER StreamSize, LARGE_INTEGER TotalFileSize)
{
   ui->progressBar->setValue((StreamSize.QuadPart*100)/TotalFileSize.QuadPart);
}
 
сделал так все равно результат один и тот же


Название: Re: copyFileEx+winapi
Отправлено: alex312 от Март 29, 2015, 07:29
Я, конечно извиняюсь. Но что это за код :
Код
C++ (Qt)
MainWindow *s;
    s->pb(StreamSize,TotalFileSize);
Как , по твоему, это должно работать ?!  :o


Название: Re: copyFileEx+winapi
Отправлено: koldun90 от Март 29, 2015, 07:38
мне нужно как то вызвать изменения прогресс бара

если я вызываю
Код
C++ (Qt)
ui->progressBar->setValue((StreamSize.QuadPart*100)/TotalFileSize.QuadPart);

вот так
Код
C++ (Qt)
static DWORD CALLBACK MyCopyProgressRoutine( LARGE_INTEGER TotalFileSize,  // размер файла в байтах
                                                  LARGE_INTEGER TotalBytesTransferred,  //байтов скопировано
                                                   LARGE_INTEGER StreamSize,
                                                  LARGE_INTEGER StreamBytesTransferred,
                                                  DWORD dwStreamNumber,
                                                  DWORD dwCallbackReason,
                                                  HANDLE hSourceFile,
                                                  HANDLE hDestinationFile,
                                                  LPVOID lpData)
 
 
{
 
   ui->progressBar->setValue((StreamSize.QuadPart*100)/TotalFileSize.QuadPart);
   cout<<(StreamSize.QuadPart*100)/TotalFileSize.QuadPart<<endl;
           return PROGRESS_CONTINUE;   //StreamSize.
}

то пишет
D:\423423\copy\mainwindow.cpp:50: ошибка: 'ui' was not declared in this scope
     ui->progressBar->setValue((StreamSize.QuadPart*100)/TotalFileSize.QuadPart);
 ^
так откуда мне вызвать все таки вызвать
Код
C++ (Qt)
ui->progressBar->setValue
впрочем это не важно программа все равно крашится даже если просто сделать
Код
C++ (Qt)
static DWORD CALLBACK MyCopyProgressRoutine( LARGE_INTEGER TotalFileSize,  // размер файла в байтах
                                                  LARGE_INTEGER TotalBytesTransferred,  //байтов скопировано
                                                   LARGE_INTEGER StreamSize,
                                                  LARGE_INTEGER StreamBytesTransferred,
                                                  DWORD dwStreamNumber,
                                                  DWORD dwCallbackReason,
                                                  HANDLE hSourceFile,
                                                  HANDLE hDestinationFile,
                                                  LPVOID lpData)
 
 
{
 
 
           return PROGRESS_CONTINUE;  
}


Название: Re: copyFileEx+winapi
Отправлено: koldun90 от Март 29, 2015, 07:40
Я, конечно извиняюсь. Но что это за код :
Код
C++ (Qt)
MainWindow *s;
    s->pb(StreamSize,TotalFileSize);
Как , по твоему, это должно работать ?!  :o
ну я вызываю метод класса который изменяет прогресс бар
Код
C++ (Qt)
void MainWindow::pb(LARGE_INTEGER StreamSize, LARGE_INTEGER TotalFileSize)
{
   ui->progressBar->setValue((StreamSize.QuadPart*100)/TotalFileSize.QuadPart);
}


Название: Re: copyFileEx+winapi
Отправлено: alex312 от Март 29, 2015, 08:35
давай попробуй модифицировать код так:
Код
C++ (Qt)
#include <QDebug>
.....
void MainWindow::on_pushButton_clicked()
{
   static char q[] = "D:\\NBA 2K15\\1" ; //правильное имя файла
   static char a[] = "D:\\qw\\123"; //куда копировать
 
   CopyFileExA(q,a,(LPPROGRESS_ROUTINE)&MyCopyProgressRoutine,NULL,FALSE,COPY_FILE_FAIL_IF_EXISTS);
 
}
.....
DWORD CALLBACK MyCopyProgressRoutine( LARGE_INTEGER TotalFileSize,  // размер файла в байтах
                                                  LARGE_INTEGER TotalBytesTransferred,  //байтов скопировано
                                                   LARGE_INTEGER StreamSize,
                                                  LARGE_INTEGER StreamBytesTransferred,
                                                  DWORD dwStreamNumber,
                                                  DWORD dwCallbackReason,
                                                  HANDLE hSourceFile,
                                                  HANDLE hDestinationFile,
                                                  LPVOID lpData)
 
 
{
   qDebug() << "progress:" << TotalBytesTransferred ;
   return PROGRESS_CONTINUE;   //StreamSize.
}
 

В *.pro файле добавть строку:
Код:
CONFIG+=console


Название: Re: copyFileEx+winapi
Отправлено: koldun90 от Март 29, 2015, 09:07
делаю так
Код
C++ (Qt)
DWORD CALLBACK MyCopyProgressRoutine( LARGE_INTEGER TotalFileSize,  // размер файла в байтах
                                                  LARGE_INTEGER TotalBytesTransferred,  //байтов скопировано
                                                   LARGE_INTEGER StreamSize,
                                                  LARGE_INTEGER StreamBytesTransferred,
                                                  DWORD dwStreamNumber,
                                                  DWORD dwCallbackReason,
                                                  HANDLE hSourceFile,
                                                  HANDLE hDestinationFile,
                                                  LPVOID lpData)
 
 
{
 
           qDebug() << "progress:" << TotalBytesTransferred.QuadPart ;
           return PROGRESS_CONTINUE;   //StreamSize.
}
 
void MainWindow::on_pushButton_clicked()
{
 
   static char q[] = "D:\\game.dat" ; //правильное имя файла
       static char a[] = "D:\\qw\\123"; //куда копировать
 
 
   CopyFileExA(q,a,(LPPROGRESS_ROUTINE)&MyCopyProgressRoutine,NULL,FALSE,COPY_FILE_FAIL_IF_EXISTS);
}
 
ошибки нет пока
но куда прикрутить прогресс бар откуда вызвать ?


Название: Re: copyFileEx+winapi
Отправлено: koldun90 от Март 29, 2015, 09:19
если прогресс бар добавить так
Код
C++ (Qt)
DWORD CALLBACK MyCopyProgressRoutine( LARGE_INTEGER TotalFileSize,  // размер файла в байтах
                                                  LARGE_INTEGER TotalBytesTransferred,  //байтов скопировано
                                                   LARGE_INTEGER StreamSize,
                                                  LARGE_INTEGER StreamBytesTransferred,
                                                  DWORD dwStreamNumber,
                                                  DWORD dwCallbackReason,
                                                  HANDLE hSourceFile,
                                                  HANDLE hDestinationFile,
                                                  LPVOID lpData)
 
 
{
       MainWindow s;
       s.pb(TotalBytesTransferred,TotalFileSize);
           qDebug() << "progress:" << TotalBytesTransferred.QuadPart ;
           return PROGRESS_CONTINUE;   //StreamSize.
}
 
void MainWindow::pb(LARGE_INTEGER  TotalBytesTransferred, LARGE_INTEGER TotalFileSize)
{
   QApplication::processEvents();
   ui->progressBar->setValue((TotalBytesTransferred.QuadPart*100)/TotalFileSize.QuadPart);
}
 
 
прогресс бар не меняется
файл копируется все норм но мне нужно чтоб прогресс бар изменялся


Название: Re: copyFileEx+winapi
Отправлено: alex312 от Март 29, 2015, 09:49
я вижу так:
Код
C++ (Qt)
//*.hpp
class MainWindow : public QMainWindow
{
   Q_OBJECT
 
   static MainWindow* instance_;
public:
   static MainWindow* instance() {return instance_;}
public:
   explicit MainWindow(QWidget *parent = 0);
   ~MainWindow();
 
.....
};
...........
 
// *.cpp
 
 
MainWindow* MainWindow::instance_ = 0;
 
.....
 
MainWindow::MainWindow(QWidget *parent) :
   QMainWindow(parent),
   ui(new Ui::MainWindow)
{
   instance_ = this;
   ui->setupUi(this);
   .......
}
 
void MainWindow::pb(LARGE_INTEGER StreamSize, LARGE_INTEGER TotalFileSize)
{
   ui->progressBar->setValue((StreamSize.QuadPart*100)/TotalFileSize.QuadPart);
   qApp->processEvents();
}
 
DWORD CALLBACK MyCopyProgressRoutine( LARGE_INTEGER TotalFileSize,  // размер файла в байтах
                                                  LARGE_INTEGER TotalBytesTransferred,  //байтов скопировано
                                                   LARGE_INTEGER StreamSize,
                                                  LARGE_INTEGER StreamBytesTransferred,
                                                  DWORD dwStreamNumber,
                                                  DWORD dwCallbackReason,
                                                  HANDLE hSourceFile,
                                                  HANDLE hDestinationFile,
                                                  LPVOID lpData)
 
 
{
   qDebug() << "progress:" << TotalBytesTransferred ;
   MainWindow::instance()->pb(TotalBytesTransferred, TotalFileSize)
   return PROGRESS_CONTINUE;   //StreamSize.
}
 
 


Название: Re: copyFileEx+winapi
Отправлено: koldun90 от Март 29, 2015, 11:04
Ошибки
mainwindow.h
Код
C++ (Qt)
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <windows.h>
#include <QMainWindow>
 
static DWORD CALLBACK MyCopyProgressRoutine(
        LARGE_INTEGER TotalFileSize,
       LARGE_INTEGER TotalBytesTransferred,
       LARGE_INTEGER StreamSize,
       LARGE_INTEGER StreamBytesTransferred,
       DWORD dwStreamNumber,
       DWORD dwCallbackReason,
       HANDLE hSourceFile,
       HANDLE hDestinationFile,
       LPVOID lpData
     );
 
namespace Ui {
class MainWindow;
}
 
class MainWindow : public QMainWindow
{
   Q_OBJECT
 
   static MainWindow* instance_;
public:
   static  MainWindow* instance()
   {
       return instance_;
   }
 
public:
   explicit MainWindow(QWidget *parent = 0);
   ~MainWindow();
 
 
 
LPPROGRESS_ROUTINE progre;
 
private slots:
void on_pushButton_clicked();
public slots:
void pb(LARGE_INTEGER,LARGE_INTEGER);
 
private:
   Ui::MainWindow *ui;
 
};
 
#endif // MAINWINDOW_H
 

mainwindow.cpp
Код
C++ (Qt)
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMessageBox>
#include <iostream>
#include <cstring>
#include <QDebug>
#include <commctrl.h>
//#include <winbase.h>
 
using namespace std;
 
MainWindow::MainWindow(QWidget *parent) :
   QMainWindow(parent),
   ui(new Ui::MainWindow)
{
   instance_ = this;
       ui->setupUi(this);
   ui->progressBar->setMaximum(100);
   ui->progressBar->setValue(3);
 
}
 
 
MainWindow::~MainWindow()
{
   delete ui;
}
void MainWindow::on_pushButton_clicked()
{
 
 
   char q[] = "D:\\Error.log" ; //правильное имя файла
   char a[] = "D:\\qw\\123"; //куда копировать
 
 
   CopyFileExA(q,a,(LPPROGRESS_ROUTINE)&MyCopyProgressRoutine,NULL,FALSE,COPY_FILE_FAIL_IF_EXISTS);
}
void MainWindow::pb(LARGE_INTEGER  TotalBytesTransferred, LARGE_INTEGER TotalFileSize)
{
   QApplication::processEvents();
  // ui->progressBar->setValue((TotalBytesTransferred.QuadPart*100)/TotalFileSize.QuadPart);
   ui->progressBar->setValue(7);
}
 
DWORD CALLBACK MyCopyProgressRoutine( LARGE_INTEGER TotalFileSize,  // размер файла в байтах
                                                  LARGE_INTEGER TotalBytesTransferred,  //байтов скопировано
                                                   LARGE_INTEGER StreamSize,
                                                  LARGE_INTEGER StreamBytesTransferred,
                                                  DWORD dwStreamNumber,
                                                  DWORD dwCallbackReason,
                                                  HANDLE hSourceFile,
                                                  HANDLE hDestinationFile,
                                                  LPVOID lpData)
 
 
{
 
       MainWindow::instance()->pb(TotalBytesTransferred, TotalFileSize);
           qDebug() << "progress:" << TotalBytesTransferred.QuadPart ;
           return PROGRESS_CONTINUE;   //StreamSize.
}
ругается на
Код
C++ (Qt)
instance_ = this;
  -- на эту строчку  D:\423423\copy\mainwindow.h:32: ошибка: undefined reference to `MainWindow::instance_'
и на
Код
C++ (Qt)
public:
   static  MainWindow* instance()
   {
       return instance_;   -- на эту строчкуD:\423423\copy\mainwindow.cpp:16: ошибка: undefined reference to `MainWindow::instance_'
   }


Название: Re: copyFileEx+winapi
Отправлено: alex312 от Март 29, 2015, 11:16
Ошибки
потому как, надо в *.срр добавить строку
Код
C++ (Qt)
MainWindow* MainWindow::instance_ = 0;
прочитать про статические переменные класса, и внимательно посмотреть на мое предидущее сообщение.


Название: Re: copyFileEx+winapi
Отправлено: koldun90 от Март 29, 2015, 11:20
Ошибки
потому как, надо в *.срр добавить строку
Код
C++ (Qt)
MainWindow* MainWindow::instance_ = 0;
прочитать про статические переменные класса, и внимательно посмотреть на мое предидущее сообщение.

так
Код
C++ (Qt)
MainWindow* MainWindow::instance_ = 0;
   instance_ = this;
       ui->setupUi(this);
 
?

а нет добавил вроде бы так все скопмилировалось
Код
C++ (Qt)
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMessageBox>
#include <iostream>
#include <cstring>
#include <QDebug>
#include <commctrl.h>
//#include <winbase.h>
 
using namespace std;
 
MainWindow* MainWindow::instance_ = 0;
 
MainWindow::MainWindow(QWidget *parent) :
   QMainWindow(parent),
   ui(new Ui::MainWindow)
{
  // MainWindow* MainWindow::instance_ = 0;
   instance_ = this;
       ui->setupUi(this);
   ui->progressBar->setMaximum(100);
   ui->progressBar->setValue(0);
}
 


Название: Re: copyFileEx+winapi
Отправлено: Igors от Март 29, 2015, 11:23
...на эту строчку  D:\423423\copy\mainwindow.h:32: ошибка: undefined reference to `MainWindow::instance_'
Еще один пытается использовать форум как "живой хелп", типа "чего там думать? Копи-паста, дорисовал фразу вопроса, запостил - быстрее дело будет". Это было много раз и никогда ничем хорошим не кончалось. Это не справочник а люди, их доверием лучше не злоупотреблять.


Название: Re: copyFileEx+winapi
Отправлено: koldun90 от Март 29, 2015, 11:24
...на эту строчку  D:\423423\copy\mainwindow.h:32: ошибка: undefined reference to `MainWindow::instance_'
Еще один пытается использовать форум как "живой хелп", типа "чего там думать? Копи-паста, дорисовал фразу вопроса, запостил - быстрее дело будет". Это было много раз и никогда ничем хорошим не кончалось. Это не справочник а люди, их доверием лучше не злоупотреблять.
я поэтому и спрашиваю потому что не знаю


Название: Re: copyFileEx+winapi
Отправлено: koldun90 от Март 29, 2015, 11:28
Ошибки
потому как, надо в *.срр добавить строку
Код
C++ (Qt)
MainWindow* MainWindow::instance_ = 0;
прочитать про статические переменные класса, и внимательно посмотреть на мое предидущее сообщение.


вообщем огромное спасибо тебе

а где прочитать про статистические переменные доступно....


Название: Re: copyFileEx+winapi
Отправлено: koldun90 от Март 29, 2015, 11:30
я бы никогда не додумался до этого
Код
C++ (Qt)
  static MainWindow* instance_;
public:
   static  MainWindow* instance()
   {
       return instance_;
   }

и

Код
C++ (Qt)
MainWindow* MainWindow::instance_ = 0;

можно подробнее


Название: Re: copyFileEx+winapi
Отправлено: alex312 от Март 29, 2015, 12:35
вообщем огромное спасибо тебе
а где прочитать про статистические переменные доступно....
Я так понял, что заработало ?
По поводу почитать - http://www.stroustrup.com/4th.html (так сказать, из первых уст)


Название: Re: copyFileEx+winapi
Отправлено: koldun90 от Март 29, 2015, 12:52
да заработало


Название: Re: copyFileEx+winapi
Отправлено: kambala от Март 29, 2015, 13:17
почему никто не предложил лямбду в качестве коллбека?


Название: Re: copyFileEx+winapi
Отправлено: Bepec от Март 29, 2015, 14:33
Ну вот и без меня разобрались :)

to Kambala - потому что лямбда новый стандарт. Который если и применяется где то широко, то одиночными людьми :)


Название: Re: copyFileEx+winapi
Отправлено: alex312 от Март 29, 2015, 15:27
почему никто не предложил лямбду в качестве коллбека?
А как указать для лямбды соглашение о вызове __stdcall ? Равно как и для std::bind ?


Название: Re: copyFileEx+winapi
Отправлено: kambala от Март 29, 2015, 16:07
to Kambala - потому что лямбда новый стандарт. Который если и применяется где то широко, то одиночными людьми :)
которому уже не первый год ;)

у меня все работает по дефолту, без всяких указаний. компилятор от студии 2012.
Код
C++ (Qt)
   auto ok = ::CopyFileEx(L"d:\\video\\Krym.Put.Na.Rodinu.2015.HDTV.720p.x264.mkv", L"d:\\test.mkv", [](
                          _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
                          ) -> DWORD {
             qDebug() << TotalBytesTransferred.QuadPart << "/" << TotalFileSize.QuadPart;
             return PROGRESS_CONTINUE;
   }, 0, 0, 0);
   qDebug("result %d, GetLastError %lu", ok, ::GetLastError());
вывод:
Цитировать
0 / 3940615453
1048576 / 3940615453
...
3940548608 / 3940615453
3940615453 / 3940615453
result 1, GetLastError 0


Название: Re: copyFileEx+winapi
Отправлено: Igors от Март 29, 2015, 16:46
у меня все работает по дефолту, без всяких указаний. компилятор от студии 2012.
Вообще-то противоречит идее лямбды (как я ее понял со времен AutoLisp)  :) Хорошо получается если ф-ция или очень мала или "погружена в контекст", а здесь ни того ни другого.


Название: Re: copyFileEx+winapi
Отправлено: kambala от Март 29, 2015, 17:53
показывать прогресс копирования в прогресс баре - не мала и не погружена в контекст?..


Название: Re: copyFileEx+winapi
Отправлено: Igors от Март 29, 2015, 18:07
показывать прогресс копирования в прогресс баре - не мала и не погружена в контекст?..
Ну да, ни то ни другое. Ее наоборот надо выносить чтобы глаза не мозолила. Не мала - потому что отделаться печатью в консоли не удастся, надо городить окно и.т.д - хотя там только аргументов масса. Не погружена - потому что не зависит ни от одной локальной переменной в месте вызова. То до чого ота лямбда?  :) 


Название: Re: copyFileEx+winapi
Отправлено: kambala от Март 29, 2015, 20:21
во-первых, неизвестно что там у ТСа на самом деле в проекте (вероятно _progressBar->setProgress(double(TotalBytesTransferred.QuadPart) / TotalFileSize.QuadPart); ). во-вторых, выносить коллбек в отдельную функцию ради того, чтобы воспользоваться ею лишь в одном месте, смысла не вижу (с лямбдой намного нагляднее).

еще с коллбеком в виде функции придется возиться с передачей виджета в нее и кастовать lpData к виджету (да, это одна строчка, но можно же и без нее обойтись :) ).


Название: Re: copyFileEx+winapi
Отправлено: Авварон от Март 30, 2015, 12:24
Старожилы снова удивляют. 3 страницы уже нафлудили, а толку... Читать до просветления.

Код:
LPCSTR q=QString("C:\\am74364.dll").toLocal8Bit().data();


Название: Re: copyFileEx+winapi
Отправлено: kambala от Март 30, 2015, 13:36
видел эту магию когда первый раз читал, потом забыл отписать :)