для чего нужны стили окна, которые не работают
Использую (пытаюсь использовать:) ) VS2005.
"Отсутствуют вызовы функций ShowWindow и UpdateWindow. Это обусловлено тем, что окно создано со стилем WS_VISIBLE". Проверял на VS 6.0 - тоже не хочет так работать. Возможно вопрос и не принципиален, но хочется все-таки в нем детально разобраться.
В связи с молчанием на форуме, хотелось бы узнать:
1) эти вещи не работают только у меня?
2) никто не знает, почему не работает? или
3) никого это не парит, никто в это серьезо не вникает, и обычно используются иные методы работы с окнами (которые, кстати говоря мне уже известны, здесь - вопрос принципа)
Заранее благодарен за ответ.
[quote=]иные методы[/quote]
ADD: правда возможно просто WS_VISIBLE и другие несовместимы друг с другом и надо использовать только те что совместимы. например если поставить WS_POPUP и WS_MAXIMIZE то все работает. думаю пролема именно в совместимости стилей.
ADD 2: замечено то, что как только стоит у окна поставить WS_CAPTION WS_MAXIMIZE уже не пашет.
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
Окно не создается! (или его не видно).
Тоже самое если:
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
и
// ShowWindow(hWnd, nCmdShow);
// UpdateWindow(hWnd);
Окно не появляется.
Почему kosfiz у тебя работает, признавайся :) . Так чета к мозгам эта фигня прилипла, второй день сижу перебираю эти стили дурацкие. Если есть какая-то несовместимость, почему же эти гады нигде даже не обмолвились об этом.
CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, NULL, NULL, hInstance, NULL);
To have Windows set the window's initial position, an application uses CW_USEDEFAULT for the X parameter to CreateWindow or CreateWindowEx. When an application uses CW_USEDEFAULT to set an overlapped window's position and uses the WS_VISIBLE style to have the window visible when it is created, Windows passes the Y parameter of CreateWindow or CreateWindowEx to ShowWindow. Thus, when an application uses CW_USEDEFAULT for the X parameter to CreateWindow or CreateWindowEx, the Y parameter must be one of the following:
SW_HIDE
SW_SHOWNORMAL
SW_NORMAL
SW_SHOWMINIMIZED
SW_SHOWMAXIMIZED
SW_MAXIMIZE
SW_SHOWNOACTIVATE
SW_SHOW
SW_MINIMIZE
SW_SHOWMINNOACTIVE
SW_SHOWNA
SW_RESTORE
Usually an application should use SW_SHOW for the Y parameter because SW_SHOW allows the proper functioning for WS_MAXIMIZE and WS_MINIMIZE styles.
To have Windows set the window's initial size, an application uses CW_USEDEFAULT for the nWidth parameter to CreateWindow or CreateWindowEx. When an application uses CW_USEDEFAULT to have Windows set the window's initial size, the nHeight parameter to CreateWindow or CreateWindowEx is ignored.
Кароче говоря, чтобы сделать окно максимального размера нужно в параметр X поставить CW_USEDEFAULT, а в параметр Y передать соответственно SW_MAXIMIZE, который впоследствии передается функции ShowWindow (!). Логика железная, сам никогда не додумаешься.
Похожими операциями можно добиться показа окна со стилем WS_VISIBLE без использования последующих вызовов функций ShowWindow и UpdateWindow. И главное обо всех эих фичях не прочитаешь в описани функции CreateWindow. Наверное MSDN и WIN32 API специально создавались для русских, чтобы нам тяжелее было во всем этом разобраться :)
Спасибо kosfiz'у за толчек в нужном направлении.
типа в отместку за использование пиратских виндов? :D
[quote=black_priest]Кароче говоря, чтобы сделать окно максимального размера нужно в параметр X поставить CW_USEDEFAULT, а в параметр Y передать соответственно SW_MAXIMIZE, который впоследствии передается функции ShowWindow (!). Логика железная, сам никогда не додумаешься.[/quote]
А я вот собссно думаю, а зачем использовать стиль WS_VISIBLE для главного окна с такими заморочками... не проще ли юзать ShowWindow?
PS. А мелкомягкие как всегда намудрили :)
(пользуюсь компилятором командной строки,
т.к. не сильно уважаю интегрированные среды,
а тем более визуальные).
С WM_VISIBLE у меня все нормально.
Если этот стиль указать,
то никакого ShowWindow не надо.
А вот WM_MAXIMIZE не работает.
Нужно писать ShowWindow(hWnd,SW_MAXIMIZE);
Видимо, все зависит и от компилятора
(это еще ничего),
и от версии Windows
(а это уже ни в какие окна не лезет).
CW_USEDEFAULT, SW_MAXIMIZE, 0, 0, NULL, NULL, hInstance, NULL);
// ShowWindow(hWnd, nCmdShow);
// UpdateWindow(hWnd);
У меня распахивается на все окно без проблем.
Недавно наткнулся на тему Matush'а http://forum.codenet.ru/showthread.php?t=33949 , тоже на тему стилей. Ужоснах, как это все работает? :rolleyes:
Но вообще-то ShowWindow всё равно желательно использовать, чтобы отследить переданный приложению параметр nCmdShow. Таким образом вызывающие ваше приложение программа или пользователь (посредством ярлыка) получат возможность самим решать, должно ли главное окно иметь стиль WM_MAXIMIZE или нет. (Между прочим, когда вы указываете в ярлыке, что главное окно приложения должно быть максимизированным, а оно по-прежнему открывается стандартного размера, потому что программист явно и однозначно задал соответствующий стиль в программе, это немножечко бесит).
DialogBox???. И как ты будешь обрабатывать очередь сообщений?
в данной функции 4 параметром идет указатель на процедуру диалогового окна, она(процедура эта) и предназначена для обработки сообщений(хотя может и есть некоторые нюансы).
ADD: уж раз здесь спрашивают про CreateWindow(Ex), то давайте с ней и разбираться будем.
неявным образом запускает CreateWindow
с какими-то там параметрами по умолчанию.
Так что никакой принципиальной разницы
между обычными и диалоговыми окнами нет.
В параметр Y записывать SW_MAXIMIZE
я не стану записывать из принципа.
Кстати, не первый раз замечаю,
что в WinApi аргументы функций
разработаны не слишком логично (мягко говоря).
неявным образом запускает CreateWindow
с какими-то там параметрами по умолчанию.
Так что никакой принципиальной разницы
между обычными и диалоговыми окнами нет.[/quote]
DialogBox вызывает(!) неявным образом DialogBoxParam с dwInitParam = 0
А та, создает диалоговое окно по шаблону из ресурса. Причем модальное.
Так что разница как раз есть, и большая!
{
TranslateMessage(&Message);
DispatchMessage(&Message);
}
Точно также по закрытии главного окна происходит выход из цикла, только не нужно писать всей этой белиберды, достаточно только вызвать DialogBox.
Как по мне, очень удобно.
Во-первых я не критикую DialogBox. Просто все хорошо на своем месте.
[quote=ShadyMan]Всё он вызывает как раз довольно-таки явно, потому что это подробно описано в MSDN.[/quote]
Приведу цитату:
[quote=MSDN]The DialogBox macro creates a modal dialog box from a dialog box template resource. DialogBox does not return control until the specified callback function terminates the modal dialog box by calling the EndDialog function. The DialogBox macro uses the DialogBoxParam function.[/quote]
The DialogBoxParam function creates a modal dialog box from a dialog box template resource.
Собссно что я и пояснил по поводу того, что brodotsky сказал что разницы нет.
Что касается обработки очереди сообщений, то, как ты сам сказал
[quote=ShadyMan]А смысл модальности в том, что выход из функции DialogBox происходит по закрытии диалога.[/quote]
тоесть вот:
DialogBox(hinst, 1, 0, DialogProc);
... // то что далее, выполнится после завершения диалога
while(GetMessage(&Message,hWnd,0,0)>0)
{
TranslateMessage(&Message);
DispatchMessage(&Message);
}
Есть ли смысл?
[quote=ShadyMan]Эта ситуация ничем не отличается от обычного цикла получения и обработки событий типа ...[/quote]
Поясни, что ты этим хотел сказать
[quote=ShadyMan]На то и есть четвёртый параметр - указатель на диалоговую функцию, которая полностью идентична обычной оконной.[/quote]
НЕ идентична!
PS. И уж поверь, в чем смысл модальности, я знаю!
[QUOTE]The DialogBox macro creates a modal dialog box from a dialog box template resource. DialogBox does not return control until the specified callback function terminates the modal dialog box by calling the EndDialog function. The DialogBox macro uses the DialogBoxParam function.
[/QUOTE]
А слабо было дальше одной статьи проследить предмет разговора? Справку по DialogBoxParam смотреть не пробовал? Так почитай:
А это что за чушь ты мне написал:
... DialogBox(hinst, 1, 0, DialogProc); ... // то что далее, выполнится после завершения диалога
while(GetMessage(&Message,hWnd,0,0)>0)
{
TranslateMessage(&Message);
DispatchMessage(&Message);
}
Есть ли смысл?
?
Действительно, смысла нет никакого. Я ж тебе говорю, что либо ты пишешь что-то типа этого:
{
HWND hWnd;
MSG Message;
make_wnd_class(hInstance);
hWnd=CreateWindowEx(0, "SimpleWnd", "Title", WS_VISIBLE|WS_POPUP|WS_BORDER,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
hBtn=CreateWindowEx(0, "BUTTON", "Button", WS_CHILD|WS_VISIBLE|BS_AUTOCHECKBOX, 0, 30, 230, 20, hWnd, 0, NULL, NULL);
CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "Edity", WS_CHILD|WS_VISIBLE, 0, 0, 230, 20, hWnd, 0, NULL, NULL);
CreateWindowEx(0, "STATIC", "Static", WS_CHILD|WS_VISIBLE, 0, 50, 230, 20, hWnd, 0, NULL, NULL);
while(GetMessage(&Message,hWnd,0,0)>0)
{
TranslateMessage(&Message);
DispatchMessage(&Message);
}
return 0;
}
{
return DialogBox(hInstance, MAKEINTRESOURCE(100), NULL, &DlgProc);
}
Поясни, что ты этим хотел сказать[/QUOTE]Да я всё про модальность: то ли писать цикл получения событий (сообщений) while(GetMessage... и т. д., то ли просто вызвать DialogBox - и там и там одна и та же модальность. В первом случае идёт ожидание завершения цикла, во втором - ожидание выхода из функции DialogBox. Чем, ради всего святого, тебе вообще не угодила модальность, что ты так на неё налегаешь?
Да ну?! Парень, а у тебя вообще MSDN-то есть при себе?
HWND hwndDlg, // handle to dialog box
UINT uMsg, // message
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
);
LRESULT CALLBACK WindowProc(
HWND hwnd, // handle of window
UINT uMsg, // message identifier
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
);
Тебя что, смущает отличие BOOL от LRESULT? Так забей: и то и другое всё равно 32-разрядное целое.
Пробовал, и даже смотрел, и неоднократно). Я и не спорю что она вызывает CreateWindowEx, я и не говорил, что это не так. Я лишь поправил brodotsky
[quote=brodotsky]неявным образом запускает CreateWindow
с какими-то там параметрами по умолчанию.[/quote]
что не с параметрами по умолчанию, а ИЗ РЕСУРСА!!! И что разница есть.
[quote=ShadyMan]Мне больше нравится последний вариант.[/quote]
Ок, согласен, не отрицаю, это удобно, НО! как насчет этого?
haccMain = LoadAccelerator(hinst,1);
while (GetMessage(&msg,NULL,0,0)) {
if (![COLOR="Red"]TranslateAccelerator(hwndMain,haccMain,&msg)[/COLOR]) {
TranslateMessage(&msg);
DisplatchMessage(&msg);
}
}
...
что зачастую необходимо!
и это лишь частичный пример, что можно делать ТОЛЬКО в цикле обработки очереди сообщений.
[quote=ShadyMan]Тебя что, смущает отличие BOOL от LRESULT?[/quote]
Нет, это меня совсем не смущает, мало того, есть всего 4 типа данных: Byte, Word, DoubleWord и QuadWord, а остальное все лишь типовые надстройки языков.
Я про другое:
WM_CREATE для WindowProc, и
WM_INITDIALOG для DialogProc
может хватит? здесь вообще-то обсуждение "для чего нужны стили окна, которые не работают", а не DialogBox vs CreateWindow(Ex). хотите поспорить на всеобщем обозрении - ступайте в гостевую.
while (GetMessage(&msg,NULL,0,0))
{
if (!TranslateAccelerator(hwndMain,haccMain,&msg))
{
TranslateMessage(&msg);
DisplatchMessage(&msg);
}
} ...
Терзают меня смутные подозрения, что и в диалогах из ресурсов проблема акселераторов должна как-то решаться: не зря же диалоговые окна из файлов ресурсов могут содержать меню. Но доказывать, что функция DialogBox применима всегда и везде, конечно, не стану. Макрос на то и есть макрос, что удобен для наиболее рутинных и обычных случаев. Шаг влево, шаг вправо - и он уже не катит.
Не могу только удержаться от критики по поводу этого:
Цитата из MSDN:
while (GetMessage( lpMsg, hWnd, 0, 0)) ...
Следует писать
CreateWindow(pszClassName, "Window", WS_OVERLAPPEDWINDOW|WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, (HWND)NULL, (HMENU)NULL, hInstance, (LPVOID)NULL);