По примеру MessageBox

Обсуждения по программированию для ОС Windows безотносительно используемого языка программирования. Windows NT, Win32, Windows API, ядро и драйверы.
SLIM
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1840
Зарегистрирован: 04.04.2008 (Пт) 18:21
Откуда: Краснодар

По примеру MessageBox

Сообщение SLIM » 17.03.2011 (Чт) 0:26

Вот возник вопрос, который казался по-началу не таким уж великосложным.

Задача следующая. Есть какая-то основная программ Win32. Есть диалог. В какой-то момент этот диалог вызывается. Пользователь что-то в нем делает, работает с какими-то данными. Потом жмет "ОК" - диалог закрывается. По результатам работы диалога в основной программе случается то или иное. Вывод - из диалога нужно что-то вернуть. Если сможем вернуть хоть какое-то значение, значит можем вернуть все что угодно. Вроде бы у диалога есть WinProc, который возвращает какие-то значения. Но выполнение возвращается туда, откуда была вызвана WinProc, а она вызвана по сути системой, т.е. мы попадем куда-то в user32. А нам нужно вернуть что-то в то место, откуда была вызвана инициализация диалога. Значит возврат с WinProc не подойдет.

В общем-то это напоминает работу MessageBox - а. Нашел в загашниках исходник msgbox. Логично предположил что все счастье кроется в WinProc-е msgbox-а. Логично было бы предположить что чудо случается где-то WM_CLOSE и иже с ними. А нет. Мало того, стоять case-ы на IDOK, IDCANCEL, IDNO и т.д., но обработчиков их нет.
Зато есть что-то интересное в WM_INITDIALOG. Там вызывается ф-я NotifyWinEvent. Хуки? Но опять так, как это поможет?
В общем, с msgbox примера взять не получается. Ну как минимум на это нужно потратить очень много времени, и боюсь того что у меня есть по msgbox не хватит для полного разбора

Какие мысли у меня по этому поводу.
Первое что пришло в голову - события. После инициализации диалога, послать WM_USER сообщение, и передать HANDLE события, предварительно установив его в занятое состояние. По окончанию работы диалога, сбрасывать событие. Но событие придется ждать, а это плохо - вызывающий поток не будет работать. Можно создать еще один поток, и ждать в нем, тогда первый вызывающий поток не будет стоять в ожидании. Три потока на 1 msgbox (включая вызывающий) - уже не хило. Ну а для того, чтобы что-то вернуть с диалога можно передавать вместе с HANDLE и указатель на callback - функцию для передачи данных на вызывающую сторону. Возвращать можно в параметры через указатель на указатель на сами данные. И все это нужно будет запихнуть в функцию-обертку,которая наконец и вернет то что нужно на вызывающую сторону. Но это ж жуть а не способ. Такую обертку делать над элементарными функционалами...

Второе что пришло в голову - хуки. Ловить закрытие диалога. Я с хуками совсем не работал, как оповещение о том что событие случилось не понятно. И кого оповещать? Не вызывающую же сторону.

Гуглить я пробовал, но что-то не знаю как вопрос сформулировать.

Может кто-нибудь что-нибудь подсказать? Интерес частично академический, частично - есть куда применить.

(Хакер, надеюсь может ты чего напишешь)
Пишите жизнь на чистовик.....переписать не удастся.....

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: По примеру MessageBox

Сообщение Хакер » 17.03.2011 (Чт) 0:48

SLIM писал(а):(Хакер, надеюсь может ты чего напишешь)


Какая чушь :? .
При создании диалога (неважно, модального или нет) можно передать любое произвольное значение, например это может быть адрес структуры, поле или поля которого используются для возврата значения диалогом. Диалог может менять там значения прямо при совершении действий, или только по нажатию кнопки «ОК». В поля структуры можно засунуть указатели на функции, которые будут играть роль обработчиков событий, специфичных для этого диалога.

Более того, если диалог модальный, он должен быть закрыт исключительно функцией EndDialog, которая позволяет указать любой произольный параметр, который будет возвращён фукцией DialogBox(Param)(Indirect).

Более того, можно тупо из DlgProc (а не WindowProc!) менять значение любой глобальной переменной по нажатию кнопки «ОК». Хоть это некрасиво и неправильно, но ведь это можно.

P.S. Честно говоря, не хотел отвечать, но градус бредовости поста вынудил меня.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

SLIM
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1840
Зарегистрирован: 04.04.2008 (Пт) 18:21
Откуда: Краснодар

Re: По примеру MessageBox

Сообщение SLIM » 17.03.2011 (Чт) 0:59

Хакер писал(а):P.S. Честно говоря, не хотел отвечать, но градус бредовости поста вынудил меня.

Понимаю.

Хакер писал(а):При создании диалога (неважно, модального или нет) можно передать любое произвольное значение, например это может быть адрес структуры, поле или поля которого используются для возврата значения диалогом. Диалог может менять там значения прямо при совершении действий, или только по нажатию кнопки «ОК». В поля структуры можно засунуть указатели на функции, которые будут играть роль обработчиков событий, специфичных для этого диалога.

При создании диалога DialogBox нет мест куда можно передать что-то свое. Куда там передавать то?

Хакер писал(а):Более того, если диалог модальный, он должен быть закрыт исключительно функцией EndDialog, которая позволяет указать любой произольный параметр, который будет возвращён фукцией DialogBox(Param)(Indirect).


С модальным да.
Хакер писал(а):Более того, можно тупо из DlgProc (а не WindowProc!) менять значение любой глобальной переменной по нажатию кнопки «ОК». Хоть это некрасиво и неправильно, но ведь это можно.


Глобальная переменная не подойдет. Эта это жутко неудобно и не удобно например при многопоточности.

Но все это не то. Модальный диалог не подходит. Переданный указатель на функцию не подходит - нужно возвращать в вызывающую сторону напрямую.
Пишите жизнь на чистовик.....переписать не удастся.....

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: По примеру MessageBox

Сообщение Хакер » 17.03.2011 (Чт) 1:25

SLIM писал(а):При создании диалога DialogBox нет мест куда можно передать что-то свое. Куда там передавать то?

dwInitParam [in]
    LPARAM
    The value to be passed to the dialog box procedure in the lParam parameter in the WM_INITDIALOG message.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

SLIM
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1840
Зарегистрирован: 04.04.2008 (Пт) 18:21
Откуда: Краснодар

Re: По примеру MessageBox

Сообщение SLIM » 17.03.2011 (Чт) 6:26

Слать дополнительно WM_INITDIALOG?
Пишите жизнь на чистовик.....переписать не удастся.....

iGrok
Артефакт VBStreets
Артефакт VBStreets
 
Сообщения: 4272
Зарегистрирован: 10.05.2007 (Чт) 16:11
Откуда: Сетевое сознание

Re: По примеру MessageBox

Сообщение iGrok » 17.03.2011 (Чт) 14:59

label:
cli
jmp label

BV
Thinker
Thinker
Аватара пользователя
 
Сообщения: 3987
Зарегистрирован: 12.09.2004 (Вс) 0:55
Откуда: Молдавия, г. Кишинёв

Re: По примеру MessageBox

Сообщение BV » 17.03.2011 (Чт) 15:26

SLIM писал(а):Эта это жутко неудобно и не удобно например при многопоточности.

Используй volatile переменные, используй namespace'ы, используй многочисленные механизмы синхронизации, используй пайпы, мэйлслоты.. Очень странный у тебя вопрос
const char *out = "|*0>78-,+<|"; size_t cc = char_traits<char>::length(out);
for (size_t i=0;i<cc;i++){cout<<static_cast<char>((out[i]^89));}cout<<endl;

SLIM
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1840
Зарегистрирован: 04.04.2008 (Пт) 18:21
Откуда: Краснодар

Re: По примеру MessageBox

Сообщение SLIM » 17.03.2011 (Чт) 20:46

Все ок.
Спасибо всем, сказывается продолжительное время работы, просто заморочился на мелочи. На самом деле действительно проблем нет.
iGrok писал(а):Он сам всё шлёт.

http://msdn.microsoft.com/en-us/library/ms645445.aspx

За это спасибо, я что-то в эту сторону и не смотрел даже.
BV писал(а):Используй volatile переменные, используй namespace'ы, используй многочисленные механизмы синхронизации, используй пайпы, мэйлслоты.. Очень странный у тебя вопрос

Да там и так нехилая многопоточная обвязка, дополнительно на это не хочется тратить силы. Да и я не говорю что это не возможно.
Пишите жизнь на чистовик.....переписать не удастся.....

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: По примеру MessageBox

Сообщение Хакер » 17.03.2011 (Чт) 20:59

Щас он спросит, а где хранить переданное значение между вызовами DlgProc...
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

SLIM
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1840
Зарегистрирован: 04.04.2008 (Пт) 18:21
Откуда: Краснодар

Re: По примеру MessageBox

Сообщение SLIM » 17.03.2011 (Чт) 21:09

Да ладно тебе, не преувеличивай.
Пишите жизнь на чистовик.....переписать не удастся.....


Вернуться в Windows-программирование

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2

    TopList