Имеется диалог, в который встроен ещё один (дочерний), напоминает SheetPage. На дочернем диалоге имеется контрол Edit (не TEdit) со стилем WS_EX_ACCEPTFILES, его я сабклассирую, чтобы перхвать очередь сообщений и перехватить сообщение WM_DROPFILES. Проблема в том, что именно это сообщение и не ловится. Если я ставлю ловушку на весь диалог, то сообщение в диалоге нормально ловится. Кто знает, в чём загвоздка?
// сабклассирование Edit-а
...
case Msg of
WM_DROPFILES :
try
if DragQueryFile(wParam, 0, FileName, MAX_PATH) > 0 then
begin
SendMessage(GetParent(Wnd), WM_COMMAND, ID_BTNFILE, 0);
DragFinish(wParam);
Exit;
end;
finally
DragFinish(wParam);
end;
end;
...
// дочерний диалог
WM_INITDIALOG :
begin
...
// не нужно, но так на всякий случай
// в ресурсном файле, этот флаг уже установлен
DragAcceptFiles(GetDlgItem(hWndDlg, ID_EDTFILE), True);
// subclass the drag-drop edit control
hEditPrev := Pointer(GetWindowLong(GetDlgItem(hWndDlg, ID_EDTFILE), GWL_WNDPROC));
SetWindowLong(GetDlgItem(hWndDlg, ID_EDTFILE), GWL_WNDPROC, Longint(@EditWndProc));
SetWindowLong(GetDlgItem(hWndDlg, ID_EDTFILE), GWL_EXSTYLE, GetWindowLong(GetDlgItem(hWndDlg, ID_EDTFILE), GWL_EXSTYLE) or WS_EX_ACCEPTFILES);
...
end;
из вашего кода не совсем понятно где чьи хендлы, пока отмечу ошибочку — DragFinish(wParam) у вас вызывается дважды. секция финализации работает при любом раскладе.
Здравствуйте, angvelem, Вы писали:
A>Имеется диалог, в который встроен ещё один (дочерний), напоминает SheetPage. На дочернем диалоге имеется контрол Edit (не TEdit) со стилем WS_EX_ACCEPTFILES, его я сабклассирую, чтобы перхвать очередь сообщений и перехватить сообщение WM_DROPFILES. Проблема в том, что именно это сообщение и не ловится.
Ищите ошибку в вашей процедуре сабкласса, WM_DROPFILES ловится Edit-ом без разговоров
(и нафига "на всякий случай" на WM_INITDIALOG, раз WS_EX_ACCEPTFILES Edit-у уже назначено в ресурсах).
Здравствуйте, angvelem, Вы писали:
A>Имеется диалог, в который встроен ещё один (дочерний), напоминает SheetPage. На дочернем диалоге имеется контрол Edit (не TEdit) со стилем WS_EX_ACCEPTFILES, его я сабклассирую, чтобы перхвать очередь сообщений и перехватить сообщение WM_DROPFILES. Проблема в том, что именно это сообщение и не ловится. Если я ставлю ловушку на весь диалог, то сообщение в диалоге нормально ловится. Кто знает, в чём загвоздка?
А если едит лежит на просто одном диалоге — всё ок работает?
Я бы ещё попробовал дочернему диалогу добавить стиль DS_CONTROL
Здравствуйте, kero, Вы писали:
K>Ищите ошибку в вашей процедуре сабкласса, WM_DROPFILES ловится Edit-ом без разговоров
какраз тут разговоры то есть
UAC
You will need to add WM_DROPFILES and WM_COPYGLOBALDATA to message filter (ChangeWindowMessageFilter), if you want to drag files from non-elevated applications to yours (elevated).
другое дело, что сперва действительно надо разобраться с сабклассингом, потому как "не ловится" и "не передается" это уже другое...
Здравствуйте, kero, Вы писали:
OAB>>а сделать сабклассинг да еще и с глобальными переменными не проблема. K>это-то тут причем?
потому как у автора топика скорее всего проблема с сабклассингом, и сделай он как вы — проблем бы небыло, вот только реюзабильность этого кода стремится к нулю.
Здравствуйте, Oleg A. Bachin, Вы писали:
OAB>Здравствуйте, kero, Вы писали:
OAB>>>а сделать сабклассинг да еще и с глобальными переменными не проблема. K>>это-то тут причем? OAB>потому как у автора топика скорее всего проблема с сабклассингом, и сделай он как вы — проблем бы небыло, вот только реюзабильность этого кода стремится к нулю.
Какой ужас
Простейший рабочий примерчик всего-то и призван успокоить, что Edit — таки принимает.
GWL_USERDATA, SetProp, etc — опосля.
Здравствуйте, kero, Вы писали:
K>Какой ужас K>Простейший рабочий примерчик всего-то и призван успокоить, что Edit — таки принимает. K>GWL_USERDATA, SetProp, etc — опосля.
глубина ваших рассуждений для меня не постижима...
чтобы понять что edit, впрочем как и любой другой хэндлед контрол, принимает сообщение — примеры писать не надо, для этого есть msdn, ну и сабклассинг уж темболее не нужен для проверки.
Здравствуйте, angvelem, Вы писали:
A>Имеется диалог, в который встроен ещё один (дочерний), напоминает SheetPage. На дочернем диалоге имеется контрол Edit (не TEdit) со стилем WS_EX_ACCEPTFILES, его я сабклассирую, чтобы перхвать очередь сообщений и перехватить сообщение WM_DROPFILES.
В Visual Studio есть утилита Spy++. В борландовских продуктах аналогичная утилита называется, если мне память не изменяет, winspectr. Запусти одну из них и натрави на свой edit, посмотри, приходит ли туда это сообщение.
>Проблема в том, что именно это сообщение и не ловится. Если я ставлю ловушку на весь диалог, то сообщение в диалоге нормально ловится. Кто знает, в чём загвоздка?
А вот это не совсем понятно. Что за ловушка на весь диалог и почему сообщение вдруг ловится в диалоге самом ?
Здравствуйте, Oleg A. Bachin, Вы писали:
OAB>из вашего кода не совсем понятно где чьи хендлы, пока отмечу ошибочку — DragFinish(wParam) у вас вызывается дважды. секция финализации работает при любом раскладе.
Здравствуйте, kero, Вы писали:
K>Ищите ошибку в вашей процедуре сабкласса, WM_DROPFILES ловится Edit-ом без разговоров K>(и нафига "на всякий случай" на WM_INITDIALOG, раз WS_EX_ACCEPTFILES Edit-у уже назначено в ресурсах).
Ошибки в сабклассировании нет, остальные сообщения проходят.
Добавлял для проверки, когда не работало с флагом в ресурсах.
Здравствуйте, CEMb, Вы писали:
CEM>А если едит лежит на просто одном диалоге — всё ок работает? CEM>Я бы ещё попробовал дочернему диалогу добавить стиль DS_CONTROL
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>В Visual Studio есть утилита Spy++. В борландовских продуктах аналогичная утилита называется, если мне память не изменяет, winspectr. Запусти одну из них и натрави на свой edit, посмотри, приходит ли туда это сообщение. PD>А вот это не совсем понятно. Что за ловушка на весь диалог и почему сообщение вдруг ловится в диалоге самом ?
Не требуется и Spy, при пошаговом прохождении я туда не попадаю.
Когда я делаю вызов DragAcceptFiles(hWndDlg, True) для всего диалога, в диалоге WM_DROPFILES отлавливается.
Всем спасибо. Сделал тестовое приложение в котором выкинул всё лишние оставив только два едита, на основном диалоге и дочернем, и запустил. Оба едита сообщение отлавливают. Теперь буду разбирать кто или что не пропускает его в основной программе.
Здравствуйте, angvelem, Вы писали:
A>Здравствуйте, kero, Вы писали:
K>>так что здесь хитрого? - K>>http://files.rsdn.ru/42164/wmdropfiles_edit.zip
A>Этот пример бесполезен, так как рассчитан на обычный диалог.
Выше вами описан необычный? И где же?
(А пример рассчитан на то, что вы новичок, как мне показалось).
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Это не аргумент. Может быть, ты что-то не так сделал, поэтому и не попадаешь. Убедись, что это сообщение туда приходит. Для этого и нужен Spy++
Не пригодился бы, в этом я убедился когда нашёл в чём причина.
Здравствуйте, kero, Вы писали:
K>Выше вами описан необычный? И где же? K>(А пример рассчитан на то, что вы новичок, как мне показалось).
Глаза замылились, показалось, что адрес msdn... , а их примеры я видел. Я давно не новичок и приведённый пример весьма примитивен , но на казусы попадают и достаточно опытные люди.
А теперь сама причина. Она оказалась до смешного простой. В ресурсном файле первым в списке находился GroupBox, он и мешал. Перенос его вниз списка решил проблему.
Да, кстати, использование флага WS_CLIPCHILDREN, как в приведённом Вами примере, может весьма негативно сказаться на правильной отрисовке дочернего диалога. Правильнее использовать WS_CLIPSIBLINGS и то, только в дочернем диалоге.
Здравствуйте, angvelem, Вы писали:
A>>Здравствуйте, kero, Вы писали:
A>Да, кстати, использование флага WS_CLIPCHILDREN, как в приведённом Вами примере, может весьма негативно сказаться на правильной отрисовке дочернего диалога. Правильнее использовать WS_CLIPSIBLINGS и то, только в дочернем диалоге.
Так вы бы хоть словечком намекнули, что у вас там групбокс в загашнике, такить нет, утаили, а уж если б показали ресурсы — в тот же миг верхняя крышка над эдитом и обнаружилась бы
Так что метод примитивнейшей, но рабочей демки (см. мой пример) в ситуации длительного заскока — оченно годится.
Здравствуйте, kero, Вы писали:
K>Так вы бы хоть словечком намекнули, что у вас там групбокс в загашнике, такить нет, утаили, а уж если б показали ресурсы — в тот же миг верхняя крышка над эдитом и обнаружилась бы
K>Так что метод примитивнейшей, но рабочей демки (см. мой пример) в ситуации длительного заскока — оченно годится.
Сколько писал, никогда не думал, что GroupBox может такую подлянку подкинуть.
Когда посмотрел ваш пример на асме, понял — ошибок в коде нет. Значит, что то мешает. Ну и начал сначала куски кода отрубать, а когда не помогло и до ресурса добрался.