Russian Qt Forum

Qt => Общие вопросы => Тема начата: QCasper от Май 03, 2006, 12:53



Название: callback и qt
Отправлено: QCasper от Май 03, 2006, 12:53
в DirectDraw есть функция

Код:
HRESULT WINAPI DirectDrawEnumerate(
  LPDDENUMCALLBACK lpCallback,
  LPVOID lpContext
);


ей в качестве параметра передается callback функция, которая там потом вызывается. Она описывается например так:

Код:
static BOOL WINAPI DriverAvailable(LPGUID guid, LPSTR desc,
LPSTR name, LPVOID p );


что я делаю. Я создаю два приложения, одно MFC (Dialog based), другое Qt там тоже класс наследован от QDialog.

В MFC приложении в функции OnInitDialog() я вызываю DirectDrawEnumerate(DriverAvailable, this); а в Qt приложении я это делаю в конструкторе класса, который я наследую от QDizlog. Так вот в конечном итоге в MFC приложении эта callback функция вызывается, а в Qt нет. Что делать и как вообще обстоит дело с callback функциями в Qt?


Название: callback и qt
Отправлено: Hordi от Май 03, 2006, 15:02
никакой разницы в этом случае от MFC быть не должно. Qt здесь не при чем


Название: callback и qt
Отправлено: QCasper от Май 03, 2006, 15:20
Цитата: "Hordi"
никакой разницы в этом случае от MFC быть не должно. Qt здесь не при чем


ну вот не вызывается, хоть ап стену бейся. Все в точности одинаково определено, описано и вызывается...


Название: callback и qt
Отправлено: alex0303 от Май 03, 2006, 19:40
Должно работать, приведите весь не работающий код (максимально ужатый).

Кстати в этой static функции не вызываете случайно виртуальную функцию по передаваемому this? Если ДА, то это по сути вызов из конструктора класса виртуального метода этого же класса что не есть гут. Мож здесь собака порылась?


Название: callback и qt
Отправлено: QCasper от Май 04, 2006, 00:37
Цитата: "alex0303"
Должно работать, приведите весь не работающий код (максимально ужатый).

Кстати в этой static функции не вызываете случайно виртуальную функцию по передаваемому this? Если ДА, то это по сути вызов из конструктора класса виртуального метода этого же класса что не есть гут. Мож здесь собака порылась?


функция описывается одинакого и в MFC и в Qt версии а именно в приватной секции класса, наследованного от CDialog для MFC и QDialog для Qt так:

Код:
static BOOL WINAPI DriverAvailable(LPGUID guid, LPSTR desc,
              LPSTR name, LPVOID p );


затем для Qt:

Код:
qtdlg::qtdlg(QWidget *parent):QDialog(parent) {
     DirectDrawEnumerate((LPDDENUMCALLBACK)DriverAvailable, this);
}


и для MFC:

Код:
BOOL mfcdlg::OnInitDialog() {
   .....
   // to do: your extra initialization code here
   DirectDrawEnumerate((LPDDENUMCALLBACK)DriverAvailable, this);

   ......
}


реализация DriverAvailable (classname = mfcdlg или qtdlg):

Код:
BOOL WINAPI classname::DriverAvailable(LPGUID guid, LPSTR desc, LPSTR name, LPVOID p )
{
    DirectDrawWin* win = (DirectDrawWin*)p;

    if (win->totaldrivers >= MAXDRIVERS)
        return DDENUMRET_CANCEL;

    DriverInfo& info = win->driver[win->totaldrivers];

    if (guid)
    {
        info.guid = (GUID*)new BYTE[sizeof(GUID)];
        memcpy(info.guid, guid, sizeof(GUID));
    }
    else
        info.guid=0;

    info.desc = strdup(desc);
    info.name = strdup(name);

    win->totaldrivers++;

    return DDENUMRET_OK;
}



остальное вроде все стандартно. в MFC диалог создал аппвизардом, в Qt собсно вот, унаследовал от QDialog. В MFC DriverAvailable вызывается, в Qt - нет. Кстати в MFC программе пробовал в конструкторе диалога вызывать - тоже работает.


Название: callback и qt
Отправлено: Hordi от Май 04, 2006, 12:48
не нравится мне этот this... А код возврата какой?

добавлено спустя 23 минуты:

 ИМХО заблуждаюсь, this не должен ни на что влиять - он просто в функцию передается...


Название: callback и qt
Отправлено: QCasper от Май 04, 2006, 13:55
Цитата: "Hordi"
не нравится мне этот this... А код возврата какой?

добавлено спустя 23 минуты:

 ИМХО заблуждаюсь, this не должен ни на что влиять - он просто в функцию передается...


вообще по MSDN код неудачи DirectDrawEnumerate один - DDERR_INVALIDPARAMS.


Название: callback и qt
Отправлено: alex0303 от Май 04, 2006, 16:05
Цитата: "QCasper"


функция описывается одинакого и в MFC и в Qt версии а именно в приватной секции класса, наследованного от CDialog для MFC и QDialog для Qt так:

Код:
static BOOL WINAPI DriverAvailable(LPGUID guid, LPSTR desc,
              LPSTR name, LPVOID p );


Код:
qtdlg::qtdlg(QWidget *parent):QDialog(parent) {
     DirectDrawEnumerate((LPDDENUMCALLBACK)DriverAvailable, this);
}


реализация DriverAvailable (classname = mfcdlg или qtdlg):

Код:
BOOL WINAPI classname::DriverAvailable(LPGUID guid, LPSTR desc, LPSTR name, LPVOID p )
{
    DirectDrawWin* win = (DirectDrawWin*)p;

    if (win->totaldrivers >= MAXDRIVERS)
        return DDENUMRET_CANCEL;

    DriverInfo& info = win->driver[win->totaldrivers];

    if (guid)
    {
        info.guid = (GUID*)new BYTE[sizeof(GUID)];
        memcpy(info.guid, guid, sizeof(GUID));
    }
    else
        info.guid=0;

    info.desc = strdup(desc);
    info.name = strdup(name);

    win->totaldrivers++;

    return DDENUMRET_OK;
}




Откуда DirectDrawWin?
д.б. classname* win = (classname*)p;
где classname есть qtdlg.

Я б сделал так:
Код:

clаss MyDlg : public QDialog
{
    ...
    static BOOL WINAPI DriverAvailable(LPGUID guid, LPSTR desc,
              LPSTR name, LPVOID p );
    BOOL MyDriverAvailable(LPGUID guid, LPSTR desc, LPSTR name);
    ...
};


Код:

BOOL WINAPI MyDlg::DriverAvailable(LPGUID guid, LPSTR desc, LPSTR name, LPVOID p )
{
    return ((MyDlg*)p)->MyDriverAvailable(guid, desc, name);
}

BOOL MyDlg::MyDriverAvailable(LPGUID guid, LPSTR desc, LPSTR name)
{
    ...
    // Это уже не статик метод
    ...
}



Название: callback и qt
Отправлено: QCasper от Май 04, 2006, 16:32
Цитата: "alex0303"


Откуда DirectDrawWin?
д.б. classname* win = (classname*)p;
где classname есть qtdlg.



да, там classname, не оттуда скопировал просто

еще раз повторяю, до

Код:
BOOL WINAPI MyDlg::DriverAvailable(LPGUID guid, LPSTR desc, LPSTR name, LPVOID p )
{
    return ((MyDlg*)p)->MyDriverAvailable(guid, desc, name);
}


дело просто напросто не дойдет, BOOL WINAPI MyDlg::DriverAvailable НЕ ВЫЗЫВАЕТСЯ!!! другими словами, если поставить туда брэйкпойнт, то выполнение программы в режиме отладки на нем не остановится, если так понятнее :)
в этом то и весь вопрос. почему в МФЦ вызывается, а в кюте нет...


Название: callback и qt
Отправлено: Hordi от Май 04, 2006, 17:54
Тупой вопрос, но а вдруг... А мож Qt-версия без отладки собирается? TRACE попробуй поюзать или т.п.


Название: callback и qt
Отправлено: QCasper от Май 04, 2006, 20:24
Цитата: "Hordi"
Тупой вопрос, но а вдруг... А мож Qt-версия без отладки собирается? TRACE попробуй поюзать или т.п.


умный, да? во все функции входит, а в эту нет, и код ошибки возвращается, который вполне отслеживается средствами отладки


Название: callback и qt
Отправлено: alex0303 от Май 04, 2006, 21:56
Но чудес то не бывает! :)
Попробуй в main() вынести тестик.


Название: callback и qt
Отправлено: QCasper от Май 04, 2006, 22:30
Цитата: "alex0303"
Но чудес то не бывает! :)
Попробуй в main() вынести тестик.


уф. alex0303, если не сложно. Будь столь любезен. Создай простое Qt приложение, опиши там эту функцию, и вызови где-нить. Мож на самом деле у меня руки из трусов растут...
Ну или вообще кто-нибудь, для этого понадобится DirectX SDK.


Название: callback и qt
Отправлено: alex0303 от Май 05, 2006, 07:59
Цитата: "QCasper"

Ну или вообще кто-нибудь, для этого понадобится DirectX SDK.

А оно в platformSDK входит?
Чтото оно у меня ща не установлено.


Название: callback и qt
Отправлено: QCasper от Май 05, 2006, 14:50
Цитата: "alex0303"
Цитата: "QCasper"

Ну или вообще кто-нибудь, для этого понадобится DirectX SDK.

А оно в platformSDK входит?
Чтото оно у меня ща не установлено.


нет, не входит - я отдельно ставил. Кстати попробовал в мэйне - не вызывается...


Название: callback и qt
Отправлено: alex0303 от Май 05, 2006, 22:03
Осталось из main() всё что касается qt убрать! :)

Думаю стоит поизучать/посравнивать опции проекта да включаемые хидеры.


Название: callback и qt
Отправлено: QCasper от Май 06, 2006, 01:15
Цитата: "alex0303"
Осталось из main() всё что касается qt убрать! :)

Думаю стоит поизучать/посравнивать опции проекта да включаемые хидеры.


хочешь сказать создать консольное приложение? :) состоящее из одной функции DirectDrawEnumerate();