Почему не работает CreateWindow
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
| ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
| [216.73.216.141] |
|
|
Правила раздела C/C++: Системное программирование и WinAPI
FAQ Сайта (C++)
FAQ Форума
Наши Исходники
Поиск по Разделу
MSDN Library Online (Windows Driver Kit)
Google
Почему не работает CreateWindow
|
Сообщ.
#1
,
|
|
|
|
Проект на WinAPI без MFC и без ресурсов.
Почему не отображается диалог, созданный с помощью CreateWindow ![]() ![]() в главной процедуре обработки сообщений окна: ... case WM_CREATE: habout = about.CreateDlg(hwnd, hinst); ... case WM_COMMAND: switch (LOWORD(wparam)) case IDM_START: about.ShowDlg(habout); ... ![]() ![]() в классе About LRESULT CALLBACK AboutDlgProc(HWND habout, UINT message, WPARAM wparam, LPARAM lparam) { switch (message) { case WM_INITDIALOG: return TRUE; case WM_COMMAND: switch (LOWORD(wparam)) { case IDOK: case IDCANCEL: EndDialog(habout, TRUE); return TRUE; } } return FALSE; } HWND About::CreateDlg(HWND hwnd, HINSTANCE hinstance) { HWND habout; WNDCLASS w; DWORD dwStyle; memset(&w, 0, sizeof(WNDCLASS)); w.style = CS_HREDRAW | CS_VREDRAW; w.lpfnWndProc = AboutDlgProc; w.hInstance = hinstance; w.hIcon = NULL; w.hCursor = LoadCursor(NULL, IDC_ARROW); w.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1); w.lpszMenuName = NULL; w.lpszClassName = "AboutClass"; RegisterClass(&w); dwStyle = DS_MODALFRAME | WS_POPUPWINDOW | WS_CAPTION; habout = CreateWindow("AboutClass", " About", dwStyle, 0, 0, 100, 200, hwnd, NULL, hinstance, NULL); //ShowWindow(hwnd, SW_SHOW); return habout; } void About::ShowDlg(HWND habout) { ShowWindow(habout, SW_SHOW); } dwStyle перепробовал разные варианты, безрезультатно. Ошибок нет, диалоговое окно не отображается. |
|
Сообщ.
#2
,
|
|
|
|
Цитата Designer @ Ошибок нет Как это понимать? Как GetLastError == 0? |
|
Сообщ.
#3
,
|
|
|
|
Цитата В смысле что приложение компилируется, запускается но при попытке вызвать диалог ни ответа, ни привета.Ошибок нет Я уже попробовал CreateWindowEx и заодно поставил MessageBox ![]() ![]() HWND About::CreateDlg(HWND hwnd, HINSTANCE hinstance) { InitCommonControls(); HWND habout; WNDCLASSEX w; DWORD dwStyle; w.cbSize = sizeof(w); w.style = CS_HREDRAW | CS_VREDRAW; w.lpfnWndProc = AboutDlgProc; w.cbClsExtra = 0; w.cbWndExtra = 0; w.hInstance = hinstance; w.hCursor = LoadCursor(NULL, IDC_ARROW); w.hIcon = LoadIcon(NULL, IDI_APPLICATION); w.hIconSm = LoadIcon(NULL, IDI_APPLICATION); w.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1); w.lpszMenuName = 0; w.lpszClassName = "AboutClass"; if (!RegisterClassEx(&w)) MessageBox(NULL, "Cannot register class", "Error", MB_OK | MB_ICONSTOP); dwStyle = WS_CHILD | DS_MODALFRAME | WS_POPUPWINDOW | WS_CAPTION; habout = CreateWindowEx(WS_EX_WINDOWEDGE, "AboutClass", " About", dwStyle, 0, 0, 100, 200, hwnd, NULL, hinstance, NULL); if(!habout) MessageBox(NULL, "Cannot create window", "Error", MB_OK | MB_ICONSTOP); //ShowWindow(hwnd, SW_SHOW); return habout; } void About::ShowDlg(HWND habout) { ShowWindow(habout, SW_SHOW); //UpdateWindow(habout); } Добавлено Выводится сообщение "Cannot create window" класс регистрируется, но окно не создается, почему ? |
|
Сообщ.
#4
,
|
|
|
|
Цитата Designer @ В смысле что приложение компилируется, запускается но при попытке вызвать диалог ни ответа, ни привета. Цитата MSDN CreateWindow If the function succeeds, the return value is a handle to the new window. If the function fails, the return value is NULL. To get extended error information, call GetLastError. |
|
Сообщ.
#5
,
|
|
|
|
Цитата Designer @ ![]() ![]() dwStyle = WS_CHILD | DS_MODALFRAME | WS_POPUPWINDOW | WS_CAPTION; Цитата WS_CHILD The window is a child window. A window with this style cannot have a menu bar. This style cannot be used with the WS_POPUP style. Добавлено Цитата WS_POPUPWINDOW = (WS_POPUP | WS_BORDER | WS_SYSMENU) |
|
Сообщ.
#6
,
|
|
|
|
Цитата Designer @ Проект на WinAPI без MFC и без ресурсов. Почитай книгу: Том1 Том2 диск с учебными исходниками к книге |
|
Сообщ.
#7
,
|
|
|
|
ЫукпШ спасибо, хорошая книга.
Попробовал GetLastError Прикреплённая картинка
По MSDN ошибка № 1813 что это может быть ? Скрытый текст Я так подозреваю, что без использования ресурсов, все упирается в отсутствие так называемого шаблона диалога. С помощью шаблона в предыдущей теме получилось создать диалоговое окно. Но оно очень ущербное. А в функции CreateWindowEx нет шаблона. Добавлено PS Почитаю Petzold-а, может что и прояснится. |
|
Сообщ.
#8
,
|
|
|
|
Скорее всего, не та ошибка, что вы привели, а эта:
Цитата winError.H ![]() ![]() // // MessageId: ERROR_RESOURCE_TYPE_NOT_FOUND // // MessageText: // // The specified resource type cannot be found in the image file. // #define ERROR_RESOURCE_TYPE_NOT_FOUND 1813L |
|
Сообщ.
#9
,
|
|
|
|
Сейчас обратил внимание, что у автора AboutDlgProc для диалогового окна, а не для CreateWindow, требующей вызова DefWindowProc.
|
|
Сообщ.
#10
,
|
|
|
|
B.V. Из приведенных мной фрагментов может не все понятно. Но у меня есть две функции обработки сообщений
1) для ![]() ![]() int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) ... w.lpfnWndProc = WndProc; ... ![]() ![]() LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) ... return DefWindowProc(hwnd, message, wparam, lparam); ... 2) для ![]() ![]() HWND About::CreateDlg(HWND hwnd, HINSTANCE hinstance) ... w.lpfnWndProc = AboutDlgProc; ... ![]() ![]() LRESULT CALLBACK AboutDlgProc(HWND habout, UINT message, WPARAM wparam, LPARAM lparam) // здесь нет DefWindowProc в литературе читал что и не надо. Завтра приведу исходник. (Исходник на работе, интернет дома) |
|
Сообщ.
#11
,
|
|
|
|
Цитата Designer @ // здесь нет DefWindowProc в литературе читал что и не надо. DefWindowProc надо всегда, если окно создается посредством CreateWindow[Ex] |
|
Сообщ.
#12
,
|
|
|
|
Ок, завтра попробую.
|
|
Сообщ.
#13
,
|
|
|
|
Действительно, DefWindowProc помогло, диалог отображается.
правда, диалог ни капли не модальный несмортря на стиль DS_MODALFRAME; сделал родительскому окну EnableWindow(hwnd, FALSE); стал диалог модальный все как и надо, но теперь другая беда - как родителя опять сделать Enable ? когда закрываем диалог; напрашивается послать SendMessage родителю ![]() ![]() LRESULT CALLBACK AboutDlgProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) { HWND hparent = GetParent(hwnd); switch (message) { case WM_INITDIALOG: return 0; case WM_COMMAND: switch (LOWORD(wparam)) { case IDOK: case IDCANCEL: EndDialog(hwnd, TRUE); //EnableWindow(hparent, TRUE); // <- эти 2 строки не помогли //SetFocus(hparent); //SendMessage(hparent, WM_COMMAND, LOWORD(IDC_ABOUT_CANCEL), 0); // <- тогда решил послать сообщение родителю return 0; } } return DefWindowProc(hwnd, message, wparam, lparam); } LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) { switch (message) { case WM_CREATE: form.CreateGeneralMenu(hwnd); htoolbar = form.CreateToolbar(hwnd, hinst); hpicturebox = form.CreatePictureBox(hwnd, hinst); about.CreateDlg(hinst); case WM_SIZE: form.Resize(hwnd, htoolbar, hpicturebox); return 0; case WM_COMMAND: switch (LOWORD(wparam)) { case IDM_EXIT: SendMessage(hwnd, WM_CLOSE, NULL, NULL); break; case IDM_OPTIONS: break; case IDM_ABOUT: case IDM_START: habout = about.ShowDlg(hwnd, hinst); break; //case IDC_ABOUT_CANCEL: // <- родитель получает сообщение и должен стать Enable // EnableWindow(hwnd, TRUE); // SetFocus(hwnd); // break; } return 0; case WM_ERASEBKGND: return 0; case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProc(hwnd, message, wparam, lparam); } Прикреплённый файл source.rar (21,22 Кбайт, скачиваний: 103)
Прикреплённый файл release.rar (97,51 Кбайт, скачиваний: 97)
Варианты моих действий (наверное неправильных) я закоментировал, а как сделать модальный диалог правильно? |
|
Сообщ.
#14
,
|
|
|
|
Цитата Designer @ правда, диалог ни капли не модальный несмортря на стиль DS_MODALFRAME; Диалоговые стили не поддерживаются функциями CreateWindow[Ex] Цитата Designer @ а как сделать модальный диалог правильно? Не изобретая велосипед, воспользоваться функциями DialogBox[Indirect/Param] Цитата Designer @ EndDialog(hwnd, TRUE); Это диалоговая функция. Оконные функции Windows завершаются вызовом DestroyWindow. |
|
Сообщ.
#15
,
|
|
|
|
Made my day
![]() |
|
Сообщ.
#16
,
|
|
|
|
Цитата Designer @ сделал родительскому окну EnableWindow(hwnd, FALSE); стал диалог модальный все как и надо, но теперь другая беда - как родителя опять сделать Enable ? ![]() ![]() EnableWindow(hwnd, TRUE); |
|
Сообщ.
#17
,
|
|
|
|
Цитата EnableWindow(hwnd, TRUE) так это я понял, а куда это поставить? В процедуру обработки сообщений от AboutDlgProc() не помогло, а если в процедуру обработки сообщений родителя WndProc(), то не знаю как его там вызвать. В коде я закоментировал мои пробы. |
|
Сообщ.
#18
,
|
|
|
|
Цитата Designer @ так это я понял, а куда это поставить? В сообщение WM_CLOSE диалога. Именно так я и делаю. Вот кусочек: ![]() ![]() void WINAPI PMDLG::enableParent(void) { Hide(); if(hwndMain) ::EnableWindow(hwndMain,TRUE); ::EnableWindow (hwndParent,TRUE); ::SetFocus (hwndParent); ::BringWindowToTop (hwndParent); } "EndDialog" совершенно не нужен и очень вреден. |
|
Сообщ.
#19
,
|
|
|
|
ЫукпШ, твой подход не является решением проблемы автора. Давать неправильное решение хуже, чем не давать никакого
|
|
Сообщ.
#20
,
|
|
|
|
Цитата B.V. @ ЫукпШ, твой подход не является решением проблемы автора. Давать неправильное решение хуже, чем не давать никакого Откуда ты знаешь, какие проблемы автора и как лучше их решать ? Я отвечаю на его конкретный вопрос и решение по этому поводу буду принимать сам. |
|
Сообщ.
#21
,
|
|
|
|
Цитата ЫукпШ @ Откуда ты знаешь, какие проблемы автора и как лучше их решать ? У меня просто с памятью немного получше: Как создать модальное диалоговое окно (сообщение #3631052) Цитата ЫукпШ @ Я отвечаю на его конкретный вопрос и решение по этому поводу буду принимать сам. А если он спросит, как засунуть пальцы в розетку, ты ему инструкцию по разборке розетки предложишь? |
|
Сообщ.
#22
,
|
|
|
|
Нет, нет, уважаемые все нормально, вы мне оба очень помогли
B.V. ![]() ![]() DefWindowProc ... DestroyWindow ЫукпШ ![]() ![]() WM_CLOSE ::EnableWindow (hwndParent,TRUE); ::SetFocus (hwndParent); ::BringWindowToTop (hwndParent); В своей программе я, естественно, все приспособил под свои нужды. Иногда, даже намек в сторону правильного решения здорово помогает. Итог : Стало понятно, что диалоговое окно без ресурсов можно создавать двумя способами. 1) с помощью шаблона диалога. 2) с помощью функции CreateWindow[Ex] Скрытый текст Мои ошибки: 1) По незнанию, я все время пытался "смешать" эти два способа. 2) Выяснилась одна неприятная особенность Visual Studio (может это только у меня) : Студийное окно мое maximize все время лезет поверх приложения. Поэтому в самостоятельной попытке найти решение методом перебора вариантов куда поставить нужные функции я пропустил верное решение. Предполагал, что если главное окно приложения станет активным, после закрытия диалога, то окно будет на экране активное развернуто как в любом приложении. А оно висело все время свернутое. При верном рабочем варианте я решил, что раз главное окно сворачивается при закрытии диалога, то значит оно не стало EnableWindow / SetFocus / BringWindowToTop. На самом деле оно стало EnableWindow / SetFocus, а BringWindowToTop перекрыла студия. Если запускать приложение без студии - все нормально. |
|
Сообщ.
#23
,
|
|
|
|
Цитата Designer @ Стало понятно, что диалоговое окно без ресурсов можно создавать двумя способами. Неверно. Диалоговым окно, созданное посредством CreateWindow[Ex] не является, если опираться на терминологию Windows. Диалоговые окна -- это не только модальность, у них есть целый ряд собственных особенностей: https://msdn.microsoft.com/en-us/library/wi...p/ms644995.aspx. Диалоговые окна следует рассматривать как более высокоуровневую надстройку над CreateWindow[Ex], а не как аналог. Повторить функциональность диалоговых окон нативными функциями, конечно, можно, но тут возникает закономерный вопрос -- а зачем? |
|
Сообщ.
#24
,
|
|
|
|
Цитата B.V. @ но тут возникает закономерный вопрос -- а зачем? ну делали ж такое лет так семь назад, было просто интересно а сейчас, наверное, актуальность таких вещей стремиться к нулю |