Расширение интерфейса общего диалога

Для неординарных вопросов. Если вы опытный программист, попавший в трудную ситуацию, — вам сюда.

Модератор: gaidar

Правила форума
Этот раздел не предназначен для того, чтобы вы адресовали свою проблему профессионалам.
Этот раздел предназначен для профессионалов, которые столкнулись с проблемой и не могут решить ее самостоятельно.
Если вы считаете себя профессионалом, а свою проблему сложной — вам сюда.
Если модератор посчитает, что вы ошиблись, то на первый раз он перенесет ваше сообщение в основной раздел без последствий для автора. Во второй раз тема будет закрыта, а автору будет выписано нарушение. В третий раз автор будет забанен.
StrVL
Начинающий
Начинающий
 
Сообщения: 1
Зарегистрирован: 11.04.2009 (Сб) 15:15

Расширение интерфейса общего диалога

Сообщение StrVL » 11.04.2009 (Сб) 15:18

Здравствуйте!
Стоит задача расширить интерфейс стандартного общего диалога открытия файла, то есть добавить в него несколько кнопок и переключателей. Решил реализовывать это посредством API-шной функции CreateWindowEx. Чтобы создать компонент, ей нужно передать в том числе дескриптор (hWnd) окна, в котором он будет размещен (в данном случае - дескриптор общего диалога).
Первая проблема в том, как получить этот дескриптор для окна общего диалога. У компонента ComDlg нет подобной функции (у соответствующего компонента OpenDialog в среде Borland Delphi есть свойство Handle, которое всегда возвращает действительный дескриптор).
Можно было бы задать окну общего диалога определенный заголовок и искать его по заголовку окна посредством FindWindow. Но дело в том, что ни до, ни после вызова ShowOpen окна общего диалога в системе нет, и его дескриптор, соответственно, получить нельзя.
Единственный проверенный рабочий вариант – создавать два приложения, одно из которых будет отслеживать появление окна с определенным заголовком и добавлять в него необходимые компоненты.
Вторая проблема заключается опять же в том, что ни до, ни после вызова ShowOpen окна общего диалога нет, соответственно нельзя заранее до его открытия добавить нужные компоненты. Но этот вопрос также решается созданием двух приложений.
Тем не менее, на мой взгляд, создание двух приложений в данной задаче не выглядит разумным, и скорее относится к категории «программирование через одно место».
Итак, вопросы можно сформулировать следующим образом.
1. Существуют ли «нормальные» способы получения дескриптора окна общего диалога?
2. Можно ли как-нибудь перехватить событие открытия общего диалога?
3. Можно ли как-нибудь избавиться от программного прерывания, инициируемого при вызове функции ShowOpen?

MIT
Мега гуру
Мега гуру
Аватара пользователя
 
Сообщения: 2211
Зарегистрирован: 17.09.2006 (Вс) 22:46

Re: Расширение интерфейса общего диалога

Сообщение MIT » 11.04.2009 (Сб) 15:26

Изображение
You can change your face, but can`t change your mind. No matter what you do.
Создайте еще более понятный интерфейс и мир создаст еще более тупого юзера. (с) Баш

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

Re: Расширение интерфейса общего диалога

Сообщение Хакер » 11.04.2009 (Сб) 22:09

Начнём с главного: этот раздел — для профессионалов.

Первая проблема в том, как получить этот дескриптор для окна общего диалога. У компонента ComDlg нет подобной функции (у соответствующего компонента OpenDialog в среде Borland Delphi есть свойство Handle, которое всегда возвращает действительный дескриптор).

Компонент ComDlg — обёртка над соотв. функциями системы. Профессионалы знают об этом.
В целом, описанный способ — извращенство. Непонятно, зачем создавать отдельный процесс, когда можно создавать отдельный поток.


Профессионал — это не тот, кто имеет корочку. Это человек с особым устройством мышления и умением искать выходы (причём не абы-какие, а исключительно правильные) из различных ситуаций. У меня корочки нет, но я, тем не менее, считаю себя профессионалом.

Одним их характерных свойств профессионала является отсутствие у него прежебрежительного отношения к чтению документации. Поэтому, если у профессионала возникает вопрос (это вполне допустимо) по какой-то неэкзотической процедуре, он идёт читать документацию. В 95% случаев после чтения документации вопросов не остаётся.

Допустим, я бы не знал, как расширить стадартный диалогбокс своими контролами. Что бы я сделал? Я бы открыл документацию по GetOpenFileName.

Там в «Ремарках» я бы увидел:
MSDN писал(а):You can provide an OFNHookProc hook procedure for an Explorer-style Open dialog box. To enable the hook procedure, set the OFN_EXPLORER and OFN_ENABLEHOOK flags in the Flags member of the OPENFILENAME structure and specify the address of the hook procedure in the lpfnHook member.


Меня бы заинтересовала OFNHookProc, я бы кликнул по ней и там бы в ремарках увидел бы следующее:
MSDN писал(а):When you use the GetOpenFileName or GetSaveFileName functions to create an Explorer-style Open or Save As common dialog box, you can provide an OFNHookProc hook procedure. To enable the hook procedure, use the OPENFILENAME structure that you passed to the dialog creation function. Specify the pointer to the hook procedure in the lpfnHook member and specify the OFN_ENABLEHOOK flag in the Flags member.


Фраза «Чтобы включить хук-процедуру, используйте структуру OPENFILENAME, котору вы передаёте в функцию создания диалога». Я бы кликнул по OPENFILENAME и там бы увидел:
MSDN писал(а):OFN_EXPLORER
    Indicates that any customizations made to the Open or Save As dialog box use the new Explorer-style customization methods. For more information, see Explorer-Style Hook Procedures and Explorer-Style Custom Templates.
    By default, the Open and Save As dialog boxes use the Explorer-style user interface regardless of whether this flag is set. This flag is necessary only if you provide a hook procedure or custom template, or set the OFN_ALLOWMULTISELECT flag.

    If you want the old-style user interface, omit the OFN_EXPLORER flag and provide a replacement old-style template or hook procedure. If you want the old style but do not need a custom template or hook procedure, simply provide a hook procedure that always returns FALSE.



Я бы последовал совету «For more information, see Explorer-Style Hook Procedures and Explorer-Style Custom Templates» и поseeкал бы. Достаточно было бы клиунть по «Explorer-Style Custom Templates», как моему взору бы открылась статья, полностью описывающая как добавить с стадартный диалог свою начинку (специально для тебя цитирую полностью, да простят мне такой оверквотинг):
Explorer-Style Custom Templates
To define additional controls for an Explorer-style Open or Save As dialog box, use the OPENFILENAME structure to specify a template for a child dialog box that contains the additional controls. If your child dialog template is a resource in an application or dynamic-link library, set the OFN_ENABLETEMPLATE flag in the Flags member and use the hInstance and lpTemplateName members of the structure to identify the module and resource name. If the template is already in memory, set the OFN_ENABLETEMPLATEHANDLE flag and use the hInstance member to identify the memory object that contains the template. When providing a child dialog template for an Explorer-style dialog box, you must also set the OFN_EXPLORER flag; otherwise, the system assumes you are providing a replacement template for an old-style dialog box. Typically, if you provide additional controls, you must also provide an Explorer-style hook procedure to process messages for the new controls.

You can create your child dialog box template as you do any other template, except that you must specify the WS_CHILD and WS_CLIPSIBLINGS styles and should specify the DS_3DLOOK and DS_CONTROL styles. The system requires the WS_CHILD style because your template defines a child dialog of the default Open or Save As dialog box. The WS_CLIPSIBLINGS style ensures that the child dialog box does not paint over any of the controls in the default dialog box. The DS_3DLOOK style makes sure that the appearance of the controls in the child dialog box is consistent with the controls in the default dialog box. The DS_CONTROL style makes sure that the user can use the tab and other navigation keys to move between all controls, default or custom, in the customized dialog box.

To make room for the new controls, the system expands the default dialog box by the width and height of the custom dialog box. By default, all controls from the custom dialog box are positioned below the controls in the default dialog box. However, you can override this default positioning by including a static text control in your custom dialog box template and assigning it the control identifier value of stc32. (This value is defined in the DLG.H header file.) In this case, the system uses the control as the point of reference for determining where to position the new controls. All new controls above and to the left of the stc32 control are positioned the same amount above and to the left of the controls in the default dialog box. New controls below and to the right of the stc32 control are positioned below and to the right of the default controls. In general, each new control is positioned so that it has the same position relative to the default controls as it had to the stc32 control. To make room for these new controls, the system adds space to the left, right, bottom, and top of the default dialog box as needed.

The system requires the hook procedure to process all messages intended for the custom dialog box and therefore sends the same window messages to the hook procedure as to any other dialog box procedure. For example, the hook procedure receives WM_COMMAND messages when the user clicks on button controls in the custom dialog box. The hook procedure is responsible for initializing these controls and retrieving values from the controls when the dialog box is closed. Note that when the hook procedure receives the WM_INITDIALOG message, the system has not yet moved the controls to their final positions.

The default dialog box procedure handles messages for all the controls in the default dialog box, but the hook procedure receives theWM_NOTIFY notification messages for user actions on these controls as described in Explorer-Style Hook Procedures.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Debugger
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1658
Зарегистрирован: 17.06.2006 (Сб) 15:11

Re: Расширение интерфейса общего диалога

Сообщение Debugger » 12.04.2009 (Вс) 9:24

И где вы такие документации находите?
Программист - это локальный бог (С) Я

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

Re: Расширение интерфейса общего диалога

Сообщение iGrok » 12.04.2009 (Вс) 10:53

Debugger писал(а):И где вы такие документации находите?

http://www.google.com/search?q=GetOpenFileName
Первая строчка.
label:
cli
jmp label


Вернуться в Раздел для Профессионалов

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

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

    TopList