Re[5]: Как из DialogProc проверить, была ли вызвана EndDial
От: Кодёнок  
Дата: 30.09.05 06:04
Оценка: 8 (2)
Здравствуйте, sergmann, Вы писали:

S>К сожалению, этот флаг, видимо, является недокументированной особенностью, и его проверка действительно является хаком.


Документировано — никак Если тебе нужно недокументированное знание, то DM_GETDEFID в случае установленного флага завершения всегда возвращает ноль. Это найдено в исходниках w2k. Можешь проверить для остальных систем, и если тоже справедливо — используй на свой страх и риск у меня это работает на xp sp2 (даже если нет кнопок в диалоге вообще) Т.е. если не был вызван EndDialog, то DM_GETDEFID всегда возвращает не ноль (а именно — DC_HASDEFID + единица, т.е. IDOK)

        case DM_GETDEFID:
            pwndT1 = GetParentDialog(pwnd);

            if (!PDLG(pwndT1)->fEnd && PDLG(pwndT1)->result)
                return(MAKELONG(PDLG(pwndT1)->result, DC_HASDEFID));
            else
                return 0;
            break;


Кроме DM_GETDEFID других бескровных путей я не нашёл.
Re[3]: Как из DialogProc проверить, была ли вызвана EndDial
От: srggal Украина  
Дата: 29.09.05 14:05
Оценка: 2 (1)
Здравствуйте, sergmann, Вы писали:

Как пример того как можно делать в сложных случаях

#include "stdafx.h"
#include <windows.h>
#include <limits>

void EndDialog( int arg1, int arg2 )
{
    std::cout << "EndDialog stub" << std::endl;
}
#define EndDialog( arg1, arg2 ) \
    { \
    EndDialogCalled = true; \
    ::EndDialog( arg1, arg2 ); \
    }

void foo( bool callEndDialog )
{
    bool    EndDialogCalled = false;

    if( callEndDialog )
    {
        EndDialog( 0, 0);
    }

    if( EndDialogCalled )
    {
        std::cout << "Called" << std::endl;
    }
}


int _tmain(int argc, _TCHAR* argv[])
{
    foo( false );
    foo( true );
    return 0;
}
... << RSDN@Home 1.1.4 stable rev. 510>>
Как из DialogProc проверить, была ли вызвана EndDialog?
От: sergmann  
Дата: 29.09.05 09:32
Оценка:
Привет всем!

Подскажите, пожалуйста, возможно ли из диалоговой процедуры узнать, был ли (из неё же) сделан вызов EndDialog?
Например:

BOOL CALLBACK MyDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
BOOL bResult;

....

if (uMsg == WM_COMMAND && LOWORD(wParam) == IDC_OK && HIWORD(wParam) == BN_CLICKED)
{
EndDialog(0);
}

....

(Возможно ли здесь определить, была ли вызвана EndDialog?)

return bResult;
}

Может возникнуть вопрос: зачем может понадобиnься такой бред. Дело в том, что у меня реализован Hook над чужой диалоговой процедурой, т.е. моя DlgProc для системы является диалоговой процедурой окна, а истинная DlgProc вызывается уже из моей, поэтому мне нужно в моей диалоговой процедуре после вызова истинной определить, завершила ли она диалог или нет?
В MSDN написано, что при вызове EndDialog устанавливается флаг, который затем проверяется системой, и в случае, если он установлен, диалог "убивается"? А можно ли его проверить самому?
Спасибо!
Serg
Re: Как из DialogProc проверить, была ли вызвана EndDialog?
От: rus blood Россия  
Дата: 29.09.05 09:44
Оценка:
Здравствуйте, sergmann, Вы писали:

S>Может возникнуть вопрос: зачем может понадобиnься такой бред. Дело в том, что у меня реализован Hook над чужой диалоговой процедурой, т.е. моя DlgProc для системы является диалоговой процедурой окна, а истинная DlgProc вызывается уже из моей, поэтому мне нужно в моей диалоговой процедуре после вызова истинной определить, завершила ли она диалог или нет?

S>В MSDN написано, что при вызове EndDialog устанавливается флаг, который затем проверяется системой, и в случае, если он установлен, диалог "убивается"? А можно ли его проверить самому?

Перехват WM_DESTROY не подойдет?
Имею скафандр — готов путешествовать!
Re: Как из DialogProc проверить, была ли вызвана EndDialog?
От: VladKurmaz Украина http://tis-method.org/
Дата: 29.09.05 10:21
Оценка:
Здравствуйте, sergmann, Вы писали:

S>Привет всем!


S>Подскажите, пожалуйста, возможно ли из диалоговой процедуры узнать, был ли (из неё же) сделан вызов EndDialog?

S>Например:

S>BOOL CALLBACK MyDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)

S>{
S> BOOL bResult;

S> ....


S> if (uMsg == WM_COMMAND && LOWORD(wParam) == IDC_OK && HIWORD(wParam) == BN_CLICKED)

S> {
S> EndDialog(0);
S> }

S> ....


S> (Возможно ли здесь определить, была ли вызвана EndDialog?)


S> return bResult;

S>}

S>Может возникнуть вопрос: зачем может понадобиnься такой бред. Дело в том, что у меня реализован Hook над чужой диалоговой процедурой, т.е. моя DlgProc для системы является диалоговой процедурой окна, а истинная DlgProc вызывается уже из моей, поэтому мне нужно в моей диалоговой процедуре после вызова истинной определить, завершила ли она диалог или нет?

S>В MSDN написано, что при вызове EndDialog устанавливается флаг, который затем проверяется системой, и в случае, если он установлен, диалог "убивается"? А можно ли его проверить самому?
S>Спасибо!

Попробуй GetWindowLong( hWnd, DWL_MSGRESULT );
Re[2]: Как из DialogProc проверить, была ли вызвана EndDial
От: Pavel Dvorkin Россия  
Дата: 29.09.05 11:18
Оценка:
Здравствуйте, rus blood, Вы писали:


RB>Перехват WM_DESTROY не подойдет?


От вызова EndDialog до WM_DESTROY много всякого произойдет. Так что вполне возможно время, когда EndDialog уже вызвана, но WM_DESTROY еще не пришел.

Формальный ответ ИМХО единственно корректный — перехват EndDialog известными методами перехвата функций.
With best regards
Pavel Dvorkin
Re[2]: Как из DialogProc проверить, была ли вызвана EndDial
От: sergmann  
Дата: 29.09.05 11:39
Оценка:
Здравствуйте, rus blood, Вы писали:

RB>Здравствуйте, sergmann, Вы писали:



RB>Перехват WM_DESTROY не подойдет?


К сожалению, не подходит, т.к. проверку нужно сделать находясь в обработчике всё того же WM_COMMAND, но ниже по коду, т.е:

BOOL CALLBACK MyDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
BOOL bResult;

....

if (uMsg == WM_COMMAND && LOWORD(wParam) == IDC_OK && HIWORD(wParam) == BN_CLICKED)
{
EndDialog(0);
}

....

if (uMsg == WM_COMMAND && LOWORD(wParam) == IDC_OK && HIWORD(wParam) == BN_CLICKED)
{
<ПРОВЕРИТЬ НУЖНО ЗДЕСЬ>
}

return bResult;
}

А WM_DESTROY приходит уже позже (при новом вызове).
Serg
Re[2]: Как из DialogProc проверить, была ли вызвана EndDial
От: sergmann  
Дата: 29.09.05 11:49
Оценка:
Здравствуйте, VladKurmaz, Вы писали:


VK>Попробуй GetWindowLong( hWnd, DWL_MSGRESULT );


К сожалению, GetWindowLong(hWnd, DWL_MSGRESULT) не возвращает ничего ценного (только 0), независимо от того была ли вызвана EndDialog или нет.
Serg
Re[3]: Как из DialogProc проверить, была ли вызвана EndDial
От: sergmann  
Дата: 29.09.05 11:53
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Здравствуйте, rus blood, Вы писали:


RB>>Перехват WM_DESTROY не подойдет?


PD>От вызова EndDialog до WM_DESTROY много всякого произойдет. Так что вполне возможно время, когда EndDialog уже вызвана, но WM_DESTROY еще не пришел.


PD>Формальный ответ ИМХО единственно корректный — перехват EndDialog известными методами перехвата функций.


Да, похоже что так! Печально, не хотелось париться с этим, система ведь умеет проверять какой-то хитрый флаг, жалко, что не предусмотрено такой функции.
Serg
Re[3]: Как из DialogProc проверить, была ли вызвана EndDial
От: VladKurmaz Украина http://tis-method.org/
Дата: 29.09.05 14:40
Оценка:
Здравствуйте, sergmann, Вы писали:

S>Здравствуйте, VladKurmaz, Вы писали:



VK>>Попробуй GetWindowLong( hWnd, DWL_MSGRESULT );


S>К сожалению, GetWindowLong(hWnd, DWL_MSGRESULT) не возвращает ничего ценного (только 0), независимо от того была ли вызвана EndDialog или нет.


EndDialog(MSDN)
EndDialog does not destroy the dialog box immediately. Instead, it sets a flag and allows the dialog box procedure to return control to the system. The system checks the flag before attempting to retrieve the next message from the application queue. If the flag is set, the system ends the message loop, destroys the dialog box, and uses the value in nResult as the return value from the function that created the dialog box.

Если этот флаг, это не GetWindowLong(hWnd, DWL_MSGRESULT), значит он находиться где-то
в GetWindowLong(hWnd, 0|4|8...) в экземпляре окна диалога.
Если это так, то это на хак похоже и может зависить от реализации Win32 GUI в разных
линейках Windows.
Re[4]: Как из DialogProc проверить, была ли вызвана EndDial
От: sergmann  
Дата: 29.09.05 14:47
Оценка:
S>>Здравствуйте, VladKurmaz, Вы писали:


VK>>>Попробуй GetWindowLong( hWnd, DWL_MSGRESULT );


S>>К сожалению, GetWindowLong(hWnd, DWL_MSGRESULT) не возвращает ничего ценного (только 0), независимо от того была ли вызвана EndDialog или нет.


VK>EndDialog(MSDN)

VK>EndDialog does not destroy the dialog box immediately. Instead, it sets a flag and allows the dialog box procedure to return control to the system. The system checks the flag before attempting to retrieve the next message from the application queue. If the flag is set, the system ends the message loop, destroys the dialog box, and uses the value in nResult as the return value from the function that created the dialog box.

VK>Если этот флаг, это не GetWindowLong(hWnd, DWL_MSGRESULT), значит он находиться где-то

VK>в GetWindowLong(hWnd, 0|4|8...) в экземпляре окна диалога.
VK>Если это так, то это на хак похоже и может зависить от реализации Win32 GUI в разных
VK>линейках Windows.

К сожалению, этот флаг, видимо, является недокументированной особенностью, и его проверка действительно является хаком.
Serg
Re[4]: Как из DialogProc проверить, была ли вызвана EndDial
От: Аноним  
Дата: 30.09.05 05:43
Оценка:
S>Да, похоже что так! Печально, не хотелось париться с этим, система ведь умеет проверять какой-то хитрый флаг, жалко, что не предусмотрено такой функции.

а нельзя создать static флаг, который сам будешь устанавливать или скидывать непосредственно перед вызвовом EndDialog?
Re[5]: Как из DialogProc проверить, была ли вызвана EndDial
От: sergmann  
Дата: 30.09.05 07:36
Оценка:
Здравствуйте, Аноним, Вы писали:

S>>Да, похоже что так! Печально, не хотелось париться с этим, система ведь умеет проверять какой-то хитрый флаг, жалко, что не предусмотрено такой функции.


А>а нельзя создать static флаг, который сам будешь устанавливать или скидывать непосредственно перед вызвовом EndDialog?


EndDialog вызывает не мой код, а DlgProc диалога (над которым я повис), следовательно т.к. код, вызывающий EndDialog не мой, то сбросить флаг он не сможет, если не перехватывать EndDialog, конечно.
Serg
Re[6]: Как из DialogProc проверить, была ли вызвана EndDial
От: sergmann  
Дата: 30.09.05 07:40
Оценка:
Здравствуйте, Кодёнок, Вы писали:

S>>К сожалению, этот флаг, видимо, является недокументированной особенностью, и его проверка действительно является хаком.


Кё>Документировано — никак Если тебе нужно недокументированное знание, то DM_GETDEFID в случае установленного флага завершения всегда возвращает ноль. Это найдено в исходниках w2k. Можешь проверить для остальных систем, и если тоже справедливо — используй на свой страх и риск у меня это работает на xp sp2 (даже если нет кнопок в диалоге вообще) Т.е. если не был вызван EndDialog, то DM_GETDEFID всегда возвращает не ноль (а именно — DC_HASDEFID + единица, т.е. IDOK)


Кё>
Кё>        case DM_GETDEFID:
Кё>            pwndT1 = GetParentDialog(pwnd);

Кё>            if (!PDLG(pwndT1)->fEnd && PDLG(pwndT1)->result)
Кё>                return(MAKELONG(PDLG(pwndT1)->result, DC_HASDEFID));
Кё>            else
Кё>                return 0;
Кё>            break;
Кё>


Кё>Кроме DM_GETDEFID других бескровных путей я не нашёл.


Большое спасибо! Обязательно попробую!
Serg
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.