Сообщений 3 Оценка 18 Оценить |
Допустим, вы вставили в программу вызов DialogBox (или похожей функции) и обнаружили, что диалог почему-то не создаётся. Что делать в такой ситуации? На этот вопрос я и постараюсь ответить.
Первое, что необходимо проверить - это параметры, которые вы передаёте функции. Проверьте, что хэндл модуля задаётся правильно, что шаблон имеет именно тот идентификатор, который вы передаёте, и что родительское окно, которое вы назначаете вновь создаваемому диалогу, действительно существует.
Если параметры заданы правильно, обратите внимание на инициализацию диалога в обработчике WM_INITDIALOG. Возможно, вы сами закрываете диалог в ответ на какую-то ошибку инициализации. Например:
case WM_INITDIALOG: { HICON hIcon = LoadIcon(...); if(hIcon == NULL) EndDialog(hwndDlg, 0); ... return TRUE; } |
Если в этом примере загрузка иконки закончится неудачно, создание диалога будет отменено.
Следующее, что необходимо проверить - все ли контролы, которые размещены в диалоге, могут быть созданы. Чтобы контрол можно было создать, необходимо, как минимум, зарегистрировать его оконный класс. Если для простейших контролов (кнопки, поля ввода) это делается автоматически, то для более мощных контролов (ListView, TreeView) классы необходимо регистрировать вручную, используя функцию InitCommonControls(Ex). Если вы используете RichEdit, вам необходимо загрузить библиотеку riched32.dll или riched20.dll при помощи функции LoadLibrary. Обратите внимание, что редактор ресурсов Visual C++ всегда вставляет в диалог RichEdit 1.0, которому соответствует библиотека riched32.dll. Чтобы вставить в диалог RichEdit 2.0, используйте Custom Control.
Библиотека MFC сама вызывает за вас InitCommonControls(Ex). Если же вы используете в диалоге RichEdit, вам необходимо загрузить нужную библиотеку, используя функцию AfxInitRichEdit. Обычно её вызывают из функции CWinApp::InitInstance. |
Следующая причина специфична для MFC. Довольно часто, переделывая сгенерированный визардом код, программисты пишут примерно следующее.
BOOL CMyApp::InitInstance()
{
...
CMyDlg dlg;
m_pMainWnd = &dlg;
dlg.Create(IDD_MAIN_DIALOG);
dlg.ShowWindow(SW_SHOW);
return TRUE;
}
|
В этом варианте диалог создаётся успешно, но тут же разрушается в деструкторе локального объекта dlg. Выход сделать этот объект глобальным или статическим или сделать его членом класса.
Если вы работаете под Windows 9x, посмотрите, не задан ли у вас в настройках проекта макрос UNICODE. В этом случае диалог создаётся при помощи функции DialogBoxW (или ей подобной), которая не реализована под Windows 9x. Это и приводит к ошибке.
Если проблема до сих пор не найдена, загляните в rc-файл вашего приложения. Иногда в нём можно найти интересные вещи, которые редактор ресурсов не показывает, - особенно если ресурс диалога был перенесён из другого приложения. Например, вы можете обнаружить в rc-файле такую строчку:
IDD_DIALOG1 DIALOG DISCARDABLE 0, 0, 278, 180
STYLE DS_MODALFRAME | DS_NOFAILCREATE | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "Dialog"
FONT 8, "MS Sans Serif"
CLASS "custom_dialog_class"
BEGIN
// Здесь описаны контролы...
END
|
Как видим, для диалога задан нестандартный оконный класс. Если в вашей программе он не регистрируется, создание диалога закончится неудачно. Если вы не можете разобраться в rc-файле, попробуйте просто пересоздать ресурс диалога "с нуля" в редакторе Visual C++.
На самом деле, причин, из-за которых диалог создать не удаётся, может быть очень и очень много, вплоть до нехватки памяти. Я перечислил лишь некоторые. Теперь несколько слов о том, что может помочь вам отыскать ошибку.
В первую очередь следует обратить внимание на значение, возвращаемое функцией DialogBox, а также расширенный код ошибки, который можно получить от функции GetLastError. Тем не менее, моя практика показывает, что эти коды редко бывают осмысленными. Более реальную помощь может оказать стиль DS_NOFAILCREATE, который можно назначить диалогу (в редакторе ресурсов Visual C++ ему соответствует "галочка" No fail create). Если этот стиль задан, диалог создаётся, даже если какие-то дочерние контролы создать не удалось. Посмотрев, чего "не хватает" в диалоге с таким стилем, можно угадать, в чём проблема. Если же диалог не появляется даже с этим стилем, это значит, что причина не связана с дочерними контролами, а имеет отношение к самому диалогу (не так заданы параметры и т. д.).
Сообщений 3 Оценка 18 Оценить |