Russian Qt Forum
Сентябрь 30, 2024, 20:20 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: не выполняется событие QTimer  (Прочитано 1922 раз)
Mikaell
Гость
« : Май 24, 2012, 15:36 »

Возникла следующая проблема. Прежде, чем задавать вопрос опишу ситуацию,
может мне надо подойти с другой стороны.
 
Есть UI-приложение, уже написанное на Qt.
Возникла необходимость подключить его к Outlook, т.е. ловить некоторые cобытия Outlook.
Для этого я решил использовать его COM-компоненту, объект Outlook получаю
через GetActiveObject. (QAxObject и другие классы из расширения QAxContainer
не использую так как, насколько я понял из документации
http://doc.qt.nokia.com/4.7-snapshot/qaxbase.html#disableEventSink через них не смогу принимать события)
Соответственно, если Outlook запущен, то я к нему подключаюсь.
Если нет, то я запускаю QTimer и проверяю по нему не включили ли Outlook.
Когда Outlook запускают, я останавливаю таймер.
Если из Outlook выходят, то я запускаю таймер внутри реакции на событие Quit
Outlook'a.
 
Проблема заключается в следующем: если при запуске моего приложения Outlook не активен,
то потом при запуске outlook'a приложение внутрь таймера не входит. Если же вернуть приложению фокус, то таймер моментально срабатывает. Если Outlook уже открыт при запуске приложения, то программа к нему нормально подсоединяется.
Т.е. складывается ощущение что таймер неактивен пока приложение не имеет фокуса.
 
Помимо кода в сообщении прикладываю тестовый проект, на котором воспроизводится.
 
Основное окно: .h-файл
Код:
#ifndef TIMTEST_H
#define TIMTEST_H
#include <QtGui/QMainWindow>
#include <QTimer>
#include "ui_timtest.h"
 
class timtest : public QMainWindow
{
    Q_OBJECT
public:
    timtest(QWidget *parent = 0, Qt::WFlags flags = 0);
    ~timtest();
    bool getOutlookApp();
    QTimer* pTimer;
    void* pMySinkApplicationEvents;
private:
    Ui::timtestClass ui;
private slots:
    void onTimerTick();
};
#endif // TIMTEST_H
.cpp-файл
Код:
#include "timtest.h"
#include "ctc.h"
#include <QMessageBox>
timtest::timtest(QWidget *parent, Qt::WFlags flags)
    : QMainWindow(parent, flags), pTimer(0), pMySinkApplicationEvents(0)
{
  ui.setupUi(this);
 
  pTimer = new QTimer(this);
  pTimer->setInterval(100);
  pTimer->setSingleShot(false);
 
  connect(pTimer, SIGNAL(timeout()), this, SLOT(onTimerTick()), Qt::AutoConnection);
  pTimer->start();
}
 
timtest::~timtest()
{}
void timtest::onTimerTick()
{
  bool bRes = getOutlookApp();
  if (bRes == true)
  {
    activateWindow();
    QMessageBox::information(this, "title", "text", QMessageBox::Ok, QMessageBox::NoButton);
    pTimer->stop();
  }
}
 
bool timtest::getOutlookApp()
{
  Outlook::_ApplicationPtr spApp;
 
  CLSID clsid;
  CLSIDFromProgID(L"Outlook.Application", &clsid); 
 
  HRESULT hr = 0;
  try
  {
    hr = spApp.GetActiveObject(clsid);
    if (hr != S_OK)
      return false;
 
    IConnectionPointContainer *pConnectionPointContainerApp = NULL;   
    hr = spApp->QueryInterface(IID_IConnectionPointContainer, (void**)&pConnectionPointContainerApp);
    if (hr != S_OK)
      return false;
 
    IID ieIID_App;// ApplicationEvents
    hr = IIDFromString(L"{0006304e-0000-0000-c000-000000000046}", &ieIID_App);
    if (hr != S_OK)
      return false;
    IConnectionPoint* pConnectionPointAppEvnts = 0;
    hr = pConnectionPointContainerApp->FindConnectionPoint(ieIID_App, &pConnectionPointAppEvnts);
    if (hr != S_OK)
      return false;
 
    if (pMySinkApplicationEvents != 0)
    {
      delete pMySinkApplicationEvents;
      pMySinkApplicationEvents = 0;
    }
    CApplicationEvents* pAEs = new CApplicationEvents();
    pAEs->app = this;
    pAEs->pConnPoint = pConnectionPointAppEvnts;
    hr = pConnectionPointAppEvnts->Advise((IUnknown*)pAEs, &(pAEs->dwCookie));
    if (hr != S_OK)
      return false;
 
    pMySinkApplicationEvents = (void*)pAEs;
    QMessageBox::information(this, "title", "text", QMessageBox::Ok, QMessageBox::NoButton);
    return true;
  }
  catch (...)
  {
    return false;
  }
}
Работа с Outlook
.h-файл
Код:
#pragma once
 
#ifndef CATCH_ATTACH_H
#define CATCH_ATTACH_H
 
#include <atlbase.h>
#include <atlcom.h>
#include <comdef.h>
 
#import "C:\Program Files\Common Files\Microsoft Shared\OFFICE12\MSO.DLL"\
  raw_interfaces_only, raw_native_types, no_namespace, named_guids, auto_search\
  rename("RGB", "OL_RGB")\
  rename("DocumentProperties", "OL_DocumentProperties")\
  exclude("IAccessible")
#import "C:\Program Files\Microsoft Office\OFFICE12\msoutl.olb"\
  rename("CopyFile","CopyFile2")\
  rename("PlaySound","PlaySound2")\
  rename_namespace("Outlook")
 
class BaseParentForMyEventsClasses : public IDispatch
{
public:
  void* app;
  ULONG refCount;
  IConnectionPoint* pConnPoint;
  DWORD dwCookie;
 
  BaseParentForMyEventsClasses::BaseParentForMyEventsClasses();
  BaseParentForMyEventsClasses::~BaseParentForMyEventsClasses();
 
  // IUnknown methods.
  virtual HRESULT __stdcall QueryInterface
    (
    REFIID riid, void **ppvObject)
  {
    if(
      IsEqualGUID(riid, IID_IDispatch) ||
      IsEqualGUID(riid, IID_IUnknown)
      )
    {
      this->AddRef();
      *ppvObject = this;
      return S_OK;
    }
    *ppvObject = NULL;
    return E_NOINTERFACE;
  }
 
  virtual ULONG _stdcall AddRef(void)
  {
    return ++refCount;
  }
 
  virtual ULONG _stdcall Release(void)
  {
    if(--refCount <= 0) {
      //Delete this;
      return 0;
    }
    return refCount;
  }
 
  // IDispatch methods.
  virtual HRESULT _stdcall GetTypeInfoCount(UINT *pctinfo)
  {
    if(pctinfo) *pctinfo = 0;
    return E_NOTIMPL;
  }
 
  virtual HRESULT _stdcall GetTypeInfo(
    UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
  {
    return E_NOTIMPL;
  }
 
  virtual HRESULT _stdcall GetIDsOfNames(
    REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid,
    DISPID *rgDispId)
  {
    return E_NOTIMPL;
  }
 
};
 
class CApplicationEvents : public BaseParentForMyEventsClasses//IDispatch
{
public:
 
  virtual HRESULT _stdcall Invoke(
    DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags,
    DISPPARAMS *pDispParams, VARIANT *pVarResult,
    EXCEPINFO *pExcepInfo, UINT *puArgErr);
};
 
#endif // CATCH_ATTACH_H
.cpp-файл
Код:
#include "ctc.h"
#include "timtest.h"
 
BaseParentForMyEventsClasses::BaseParentForMyEventsClasses()
{
  refCount = 1;
  app = 0;
  pConnPoint = 0;
}
 
BaseParentForMyEventsClasses::~BaseParentForMyEventsClasses()
{
  if (pConnPoint == 0)
    return;
  if (dwCookie == 0)
    return;
  try
  {
    HRESULT hr = pConnPoint->Unadvise(dwCookie);
    if (hr != S_OK)
    {
      return;
    }
  }
  catch(...)
  {
    return;
  }
}
 
HRESULT _stdcall CApplicationEvents::Invoke(
  DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags,
  DISPPARAMS *pDispParams, VARIANT *pVarResult,
  EXCEPINFO *pExcepInfo, UINT *puArgErr)
{
  switch(dispIdMember)
  {
  case 0x0000f007: // Application Quit
    {     
      timtest* pApp = reinterpret_cast<timtest*>(this->app);
      pApp->pTimer->start(100);
    }
    break;
  }
  return S_OK;
}
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.056 секунд. Запросов: 21.