Russian Qt Forum

Программирование => С/C++ => Тема начата: Winand от Май 15, 2011, 21:49



Название: QLibrary, Win7, DEP? (BEX error)
Отправлено: Winand от Май 15, 2011, 21:49
Решил я быстренько переписать свою прогу меняющую цвет окон в Win7 на средний цвет волпапера с, прости господи, VB6 на с++. Получил проблем больше, чем когда на бейсике писал:)

Она отлично работает, когда в qt creator выставляю режим Debug, а в Release падает с ошибкой BEX на вызовах к библиотеке dwmapi.
Вот почти весь код, что я делаю не так?
Код
C++ (Qt)
#include <QCoreApplication>
#include <QLibrary>
#include "wpmonitor.h"
#define DwmGetColorizationParameters_ (const char*) 127
#define DwmSetColorizationParameters_ (const char*) 131
 
int main(int argc, char* argv) {
   QCoreApplication a(argc, &argv);
   QLibrary lib("dwmapi");
   void* prcgetpar = lib.resolve(DwmGetColorizationParameters_);
   if(!prcgetpar) return -1;
   void* prcsetpar = lib.resolve(DwmSetColorizationParameters_);
   if(!prcsetpar) return -1;
   new WpMonitor(prcgetpar, prcsetpar);
   return a.exec();
}
Код
C++ (Qt)
#include "wpmonitor.h"
#include <QFileInfo>
#include <QDebug>
#include <windows.h>
#include <QTimerEvent>
#include <QLinearGradient>
#include <QColor>
#include <QPainter>
#include <QPixmap>
 
WpMonitor::WpMonitor(void* prcgetpar, void* prcsetpar) :
smoothtimer(0) {
   DwmGetColorizationParameters = (DwmGetColPar)prcgetpar;
   DwmSetColorizationParameters = (DwmSetColPar)prcsetpar;
   steps.n = 40;
   steps.i = 0;
   igrd = QImage(1, steps.n, QImage::Format_ARGB32);
   timerEvent(0);
   startTimer(1000); //poll once a second
}
 
void WpMonitor::timerEvent(QTimerEvent* event) {
   if((smoothtimer == 0) || (event->timerId() != smoothtimer)) {
       wchar_t wppath[MAX_PATH];
       SystemParametersInfo(SPI_GETDESKWALLPAPER, MAX_PATH, (PVOID)wppath, 0);
       QString qwppath = QString::fromWCharArray(wppath);
       QFileInfo fi(qwppath);
       if(fi.exists()) {
           if((qwppath != wpfilepath) || (fi.lastModified() != lastmod)) { //any changes?
               wpfilepath = qwppath;
               lastmod = fi.lastModified();
               QImage img(qwppath);
               if(!img.isNull()) {
                   //get average color (stupidly)
                   img = img.scaled(1, 1, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
                   DwmGetColorizationParameters(&p);
                   somemagic = p.Color1 & 0xFF000000; //some value:)
 
                   QLinearGradient grad(0, 0, 0, steps.n);
                   grad.setColorAt(0.0, QColor(p.Color1 | 0xFF000000));
                   grad.setColorAt(1.0, img.pixel(0, 0));
                   QPainter p(&igrd);
                   p.fillRect(igrd.rect(), grad);
 
                   if(smoothtimer) killTimer(smoothtimer);
                   steps.i = 0;
                   smoothtimer = startTimer(50);
                   qDebug() << "start wallpaper change";
               } else qDebug() << "wrong wallpaper file";
           }
       } else qDebug() << "no wallpaper file";
   } else { //smooth color switch
       if(steps.i < steps.n) {
           p.Color1 = somemagic | (igrd.pixel(0, steps.i) & 0xFFFFFF);
           p.Color2 = p.Color1;
           DwmSetColorizationParameters(&p, 0);
           steps.i++;
       } else {
           killTimer(event->timerId());
           qDebug() << "end wallpaper change";
       }
   }
}


Название: Re: QLibrary, Win7, DEP? (BEX error)
Отправлено: Winand от Май 15, 2011, 21:54
ну и последний файл проекта до кучи
Код
C++ (Qt)
#ifndef WPMONITOR_H
#define WPMONITOR_H
#include <QObject>
#include <QDateTime>
#include <QImage>
 
class WpMonitor : public QObject {
Q_OBJECT
private:
   struct STEPOF {
       uint n;
       uint i;
   };
   struct WDM_COLORIZATION_PARAMS {
       uint Color1;
       uint Color2;
       uint Intensity;
       uint Unknown1;
       uint Unknown2;
       uint Unknown3;
       uint Opaque;
   };
   typedef void (*DwmGetColPar)(WDM_COLORIZATION_PARAMS* parameters);
   typedef void (*DwmSetColPar)(WDM_COLORIZATION_PARAMS* parameters, uint uUnknown);
   DwmGetColPar DwmGetColorizationParameters;
   DwmSetColPar DwmSetColorizationParameters;
 
   QDateTime lastmod;
   QString wpfilepath;
   int smoothtimer;
   STEPOF steps; //smooth color switch steps
   QImage igrd; //gradient
   uint somemagic;
   WDM_COLORIZATION_PARAMS p;
public:
   explicit WpMonitor(void* prcgetpar, void* prcsetpar);
protected:
   void timerEvent(QTimerEvent* event);
signals:
 
public slots:
 
};
 
#endif // WPMONITOR_H
 


Название: Re: QLibrary, Win7, DEP? (BEX error)
Отправлено: zenden от Май 16, 2011, 00:25
Обратите внимание на соглашение о вызове функции
Виндовые библиотеки используют соглашение __stdcall

Код
C++ (Qt)
typedef  void  (__stdcall *DwmGetColPar)(WDM_COLORIZATION_PARAMS* parameters);
typedef  void  (__stdcall *DwmSetColPar)(WDM_COLORIZATION_PARAMS* parameters, uint uUnknown);


Название: Re: QLibrary, Win7, DEP? (BEX error)
Отправлено: Winand от Май 16, 2011, 00:58
zenden, ну надо же:) Спасибо. И ведь нередко так, ищешь какую-то глобальную проблему, а всё намного проще