Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

для чего нужны стили окна, которые не работают

22K
13 марта 2007 года
black_priest
19 / / 12.03.2007
Может ли кто нибудь компетентно разьяснить, для чего нужен WS_VISIBLE, если независимо от него все равно впоследствии необходимо использовать функцию ShowWindow() для того, чтобы окно стало видимым (у Ганеева судя по его книжке WS_VISIBLE работает как надо), или WS_MAXIMIZE, от которого не созадается a window of maximum size, как написано в MSDN. Что я не то делаю все-таки? Использовать функцию SetWindowLong() для последующего изменения стиля окна тоже не принесло результатов. Заранее благодарен за вразумительные ответы.
Использую (пытаюсь использовать:) ) VS2005.
397
13 марта 2007 года
SergPas
527 / / 03.02.2007
Стиль WS_VISIBLE предназначен для отображения дочерних окон (кнопок, однострочных редакторов и т.д. и т.п) в родительском окне. Если не указать это стиль при создании дочернего окна, оно и не отобразится. Функция ShowWindow предназначена для отображения родительского (главного) окна.
22K
14 марта 2007 года
black_priest
19 / / 12.03.2007
И все-таки насчет стилей: у Ганеева в книжке есть пример, в котором создается главное окно со стилем WS_VISIBLE, и далее написано
"Отсутствуют вызовы функций ShowWindow и UpdateWindow. Это обусловлено тем, что окно создано со стилем WS_VISIBLE". Проверял на VS 6.0 - тоже не хочет так работать. Возможно вопрос и не принципиален, но хочется все-таки в нем детально разобраться.
В связи с молчанием на форуме, хотелось бы узнать:
1) эти вещи не работают только у меня?
2) никто не знает, почему не работает? или
3) никого это не парит, никто в это серьезо не вникает, и обычно используются иные методы работы с окнами (которые, кстати говоря мне уже известны, здесь - вопрос принципа)
Заранее благодарен за ответ.
257
14 марта 2007 года
kosfiz
1.6K / / 18.09.2005
вообщем у меня WS_VISIBLE достаточно для того, чтобы не вызывать ShowWindow (пробовал в Dev-C++, VC++ 6.0 (7.1 и 8.0), Delphi 7). правда вот с WS_MAXIMIZE и т.д. реагирует только в Dev-C++. в других случаях я использую для отображения окна
[quote=]иные методы[/quote]
ADD: правда возможно просто WS_VISIBLE и другие несовместимы друг с другом и надо использовать только те что совместимы. например если поставить WS_POPUP и WS_MAXIMIZE то все работает. думаю пролема именно в совместимости стилей.
ADD 2: замечено то, что как только стоит у окна поставить WS_CAPTION WS_MAXIMIZE уже не пашет.
22K
14 марта 2007 года
black_priest
19 / / 12.03.2007
Мда, блин. Тяжело обьять необьятное. Создаю новый простой проект. НИЧЕГО в нем не меняю. Создаю окно следующим образом:
 
Код:
hWnd = CreateWindow(szWindowClass, szTitle, WS_POPUP|WS_MAXIMIZE,
      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

Окно не создается! (или его не видно).
Тоже самое если:
 
Код:
hWnd = CreateWindow(szWindowClass, szTitle, WS_VISIBLE,
      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

и

  // ShowWindow(hWnd, nCmdShow);
  // UpdateWindow(hWnd);

Окно не появляется.
Почему kosfiz у тебя работает, признавайся :) . Так чета к мозгам эта фигня прилипла, второй день сижу перебираю эти стили дурацкие. Если есть какая-то несовместимость, почему же эти гады нигде даже не обмолвились об этом.
257
15 марта 2007 года
kosfiz
1.6K / / 18.09.2005
попробуй так:
 
Код:
hWnd = CreateWindow(szWindowClass, szTitle, WS_VISIBLE,
      CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, NULL, NULL, hInstance, NULL);
22K
15 марта 2007 года
black_priest
19 / / 12.03.2007
Поиск по CW_USEDEFAULT натолкнул меня в конце концов на какой-то Windows User Interface Technical Article в MSDN (автор Kyle Marsh :)), из которого стали понятны причины странного поведения этих стилей, после которого у меня появилась еще одна причина ненавидеть ребят из мелкософта:
Цитата:

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'у за толчек в нужном направлении.

334
16 марта 2007 года
HexEdit
809 / / 27.07.2006
[quote=black_priest]Наверное MSDN и WIN32 API специально создавались для русских, чтобы нам тяжелее было во всем этом разобраться[/quote]
типа в отместку за использование пиратских виндов? :D
[quote=black_priest]Кароче говоря, чтобы сделать окно максимального размера нужно в параметр X поставить CW_USEDEFAULT, а в параметр Y передать соответственно SW_MAXIMIZE, который впоследствии передается функции ShowWindow (!). Логика железная, сам никогда не додумаешься.[/quote]
А я вот собссно думаю, а зачем использовать стиль WS_VISIBLE для главного окна с такими заморочками... не проще ли юзать ShowWindow?

PS. А мелкомягкие как всегда намудрили :)
22K
16 марта 2007 года
black_priest
19 / / 12.03.2007
Да конечно можно и ShowWindow, я так впринципе и сделал, просто зацепило: что же оно не работает как написано. Люблю во всем досконально колупаться, а с чистым API совсем недавно работаю, поэтому куча таких проблем. Что-то находишь в доках, до чего то додумываешься, но до таких фишек я еще не дорос:). А насчет пирацких виндов так это стопудова. Пендосов там жаба душит,что мы их винды бесплатно юзаем, поэтому они нам глюки все подсовывают. Или может пишут свои проги как смогут, потом читают наши форумы и по ним правят свои баги (новыми багами):).
334
16 марта 2007 года
HexEdit
809 / / 27.07.2006
Да я тоже люблю, просто это как-то не заметил, а щя увидел, по думал, на ну его... тока лишний гемор %).
22K
16 марта 2007 года
black_priest
19 / / 12.03.2007
Да, гемор еще тот. И если бы это был единственный :) . Чем больше чего-то пытаюсь писать, тем больше его всплывает. Честно говоря обидно, что изучение API во многих местах сводится не к осознанию какой-то внутренней идеологии, а к забиванию головы запоминанием особенностей реализации конкретных механизмов. Вот блин написал :eek:
584
17 марта 2007 года
brodotsky
33 / / 25.01.2004
У меня Windows 98 и компилятор Borland C++ 5
(пользуюсь компилятором командной строки,
т.к. не сильно уважаю интегрированные среды,
а тем более визуальные).
С WM_VISIBLE у меня все нормально.
Если этот стиль указать,
то никакого ShowWindow не надо.
А вот WM_MAXIMIZE не работает.
Нужно писать ShowWindow(hWnd,SW_MAXIMIZE);
Видимо, все зависит и от компилятора
(это еще ничего),
и от версии Windows
(а это уже ни в какие окна не лезет).
22K
17 марта 2007 года
black_priest
19 / / 12.03.2007
А пробовал для WM_MAXIMIZE делать эту злобную процедуру, которую я описывал?:
 
Код:
hWnd = CreateWindowA(szWindowClass, szTitle, WS_OVERLAPPED | WS_VISIBLE,
       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:
3.3K
18 марта 2007 года
ShadyMan
191 / / 15.07.2006
А не проще ли для главного окна воспользоваться замечательной функцией DialogBox и не париться со всякими там CreateWindow и CreateWindowEx? (Это к вопросу о WM_VISIBLE - всё будет видно сразу и без проблем).
Но вообще-то ShowWindow всё равно желательно использовать, чтобы отследить переданный приложению параметр nCmdShow. Таким образом вызывающие ваше приложение программа или пользователь (посредством ярлыка) получат возможность самим решать, должно ли главное окно иметь стиль WM_MAXIMIZE или нет. (Между прочим, когда вы указываете в ярлыке, что главное окно приложения должно быть максимизированным, а оно по-прежнему открывается стандартного размера, потому что программист явно и однозначно задал соответствующий стиль в программе, это немножечко бесит).
334
18 марта 2007 года
HexEdit
809 / / 27.07.2006
[quote=ShadyMan]А не проще ли для главного окна воспользоваться замечательной функцией DialogBox и не париться со всякими там CreateWindow и CreateWindowEx? (Это к вопросу о WM_VISIBLE - всё будет видно сразу и без проблем).[/quote]
DialogBox???. И как ты будешь обрабатывать очередь сообщений?
257
18 марта 2007 года
kosfiz
1.6K / / 18.09.2005
[quote=HexEdit]DialogBox???. И как ты будешь обрабатывать очередь сообщений?[/quote]
в данной функции 4 параметром идет указатель на процедуру диалогового окна, она(процедура эта) и предназначена для обработки сообщений(хотя может и есть некоторые нюансы).

ADD: уж раз здесь спрашивают про CreateWindow(Ex), то давайте с ней и разбираться будем.
584
18 марта 2007 года
brodotsky
33 / / 25.01.2004
Макрос DialogBox
неявным образом запускает CreateWindow
с какими-то там параметрами по умолчанию.
Так что никакой принципиальной разницы
между обычными и диалоговыми окнами нет.

В параметр Y записывать SW_MAXIMIZE
я не стану записывать из принципа.
Кстати, не первый раз замечаю,
что в WinApi аргументы функций
разработаны не слишком логично (мягко говоря).
334
18 марта 2007 года
HexEdit
809 / / 27.07.2006
[quote=brodotsky]Макрос DialogBox
неявным образом запускает CreateWindow
с какими-то там параметрами по умолчанию.
Так что никакой принципиальной разницы
между обычными и диалоговыми окнами нет.[/quote]
DialogBox вызывает(!) неявным образом DialogBoxParam с dwInitParam = 0
А та, создает диалоговое окно по шаблону из ресурса. Причем модальное.
Так что разница как раз есть, и большая!
3.3K
18 марта 2007 года
ShadyMan
191 / / 15.07.2006
Нет, HexEdit, ты не прав, что критикуешь DialogBox. Всё он вызывает как раз довольно-таки явно, потому что это подробно описано в MSDN. И раз в конечном счёте вызывается именно CreateWindowEx, то никакой разницы в обработке событий нет. На то и есть четвёртый параметр - указатель на диалоговую функцию, которая полностью идентична обычной оконной. А смысл модальности в том, что выход из функции DialogBox происходит по закрытии диалога. Эта ситуация ничем не отличается от обычного цикла получения и обработки событий типа
 
Код:
while(GetMessage(&Message,hWnd,0,0)>0)
 {
  TranslateMessage(&Message);
  DispatchMessage(&Message);
 }

Точно также по закрытии главного окна происходит выход из цикла, только не нужно писать всей этой белиберды, достаточно только вызвать DialogBox.
Как по мне, очень удобно.
334
18 марта 2007 года
HexEdit
809 / / 27.07.2006
2ShadyMan
Во-первых я не критикую 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. И уж поверь, в чем смысл модальности, я знаю!
3.3K
18 марта 2007 года
ShadyMan
191 / / 15.07.2006
Значит, ты всё-таки решил попререкаться, любитель шестнадцатеричных кодов. Ну ладно, поехали.
Цитата:
Приведу цитату:
[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 смотреть не пробовал? Так почитай:

Цитата:
The DialogBoxParam function uses the CreateWindowEx function to create the dialog box.


А это что за чушь ты мне написал:

Цитата:
тоесть вот:
 
Код:
Код:
... DialogBox(hinst, 1, 0, DialogProc); ... // то что далее, выполнится после завершения диалога
while(GetMessage(&Message,hWnd,0,0)>0)
{
 TranslateMessage(&Message);
 DispatchMessage(&Message);
}

Есть ли смысл?

?
Действительно, смысла нет никакого. Я ж тебе говорю, что либо ты пишешь что-то типа этого:

Код:
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
 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;
}
, либо просто
 
Код:
int WINAPI WinMain(HINSTANCE hPrevInstance, HINSTANCE hInstance, LPSTR lpCmdStr, int iShowWnd)
{
  return DialogBox(hInstance, MAKEINTRESOURCE(100), NULL, &DlgProc);
}
. Что лучше смотрится? Мне больше нравится последний вариант.
Цитата:
[QUOTE]Эта ситуация ничем не отличается от обычного цикла получения и обработки событий типа ...


Поясни, что ты этим хотел сказать[/QUOTE]Да я всё про модальность: то ли писать цикл получения событий (сообщений) while(GetMessage... и т. д., то ли просто вызвать DialogBox - и там и там одна и та же модальность. В первом случае идёт ожидание завершения цикла, во втором - ожидание выхода из функции DialogBox. Чем, ради всего святого, тебе вообще не угодила модальность, что ты так на неё налегаешь?

Цитата:
НЕ идентична!


Да ну?! Парень, а у тебя вообще MSDN-то есть при себе?

Код:
BOOL CALLBACK DialogProc(

    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-разрядное целое.
334
19 марта 2007 года
HexEdit
809 / / 27.07.2006
[quote=ShadyMan]А слабо было дальше одной статьи проследить предмет разговора? Справку по DialogBoxParam смотреть не пробовал?[/quote]
Пробовал, и даже смотрел, и неоднократно). Я и не спорю что она вызывает 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
257
19 марта 2007 года
kosfiz
1.6K / / 18.09.2005
HexEdit & ShadyMan
может хватит? здесь вообще-то обсуждение "для чего нужны стили окна, которые не работают", а не DialogBox vs CreateWindow(Ex). хотите поспорить на всеобщем обозрении - ступайте в гостевую.
3.3K
19 марта 2007 года
ShadyMan
191 / / 15.07.2006
Цитата:
 
Код:
... haccMain = LoadAccelerator(hinst,1);
while (GetMessage(&msg,NULL,0,0))
{
 if (!TranslateAccelerator(hwndMain,haccMain,&msg))
 {
  TranslateMessage(&msg);
  DisplatchMessage(&msg);
 }
} ...


Терзают меня смутные подозрения, что и в диалогах из ресурсов проблема акселераторов должна как-то решаться: не зря же диалоговые окна из файлов ресурсов могут содержать меню. Но доказывать, что функция DialogBox применима всегда и везде, конечно, не стану. Макрос на то и есть макрос, что удобен для наиболее рутинных и обычных случаев. Шаг влево, шаг вправо - и он уже не катит.
Не могу только удержаться от критики по поводу этого:

 
Код:
while (GetMessage(&msg,NULL,0,0))

Цитата из MSDN:
Цитата:
Note that the function return value can be TRUE, FALSE, or -1. Thus, you should avoid code like this:
while (GetMessage( lpMsg, hWnd, 0, 0)) ...


Следует писать

 
Код:
while (GetMessage( lpMsg, hWnd, 0, 0)>0)
15K
11 апреля 2007 года
GrayWolf
4 / / 11.01.2006
Гм, а ты так не пробовал? У меня ВСЕГДА работает
CreateWindow(pszClassName, "Window", WS_OVERLAPPEDWINDOW|WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, (HWND)NULL, (HMENU)NULL, hInstance, (LPVOID)NULL);
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог