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

Ваш аккаунт

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

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

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

Размеры окна

243
20 июля 2005 года
pacific_7
1.9K / / 06.09.2004
Разгребаю последствия Билдера :( Там все это просто.
Как узнать текущий размер окна? Как узнать установленный максимальный и минимальный я нашел - это при помощи структуры MINMAXINFO, а наоборот, т.е. установить?
10
20 июля 2005 года
Freeman
3.2K / / 06.03.2004
Цитата:
Originally posted by pacific_7
Как узнать установленный максимальный и минимальный я нашел - это при помощи структуры MINMAXINFO, а наоборот, т.е. установить?


Отрабатывать сообщение WM_GETMINMAXINFO?

406
20 июля 2005 года
vitaly2003s
481 / / 27.07.2004
GetWindowPlacement,SetWindowPlacement
243
20 июля 2005 года
pacific_7
1.9K / / 06.09.2004
Цитата:
Originally posted by vitaly2003s
GetWindowPlacement,SetWindowPlacement


Спасибо.
Freeman - я же говорю, это как раз наоборот от требуемого.

243
20 июля 2005 года
pacific_7
1.9K / / 06.09.2004
Еще один вопрос из той же оперы: как осуществить привязку размеров дочерних окон к родительскому? Например я хочу, что бы окно при изменении размера родительского тянулось не за верхней гранью, а за нижней, или за обоими.
Обрабатывать сообщение WM_SIZE, или есть более простые пути?
406
20 июля 2005 года
vitaly2003s
481 / / 27.07.2004
Цитата:
Originally posted by pacific_7
Еще один вопрос из той же оперы: как осуществить привязку размеров дочерних окон к родительскому? Например я хочу, что бы окно при изменении размера родительского тянулось не за верхней гранью, а за нижней, или за обоими.
Обрабатывать сообщение WM_SIZE, или есть более простые пути?


Придется обрабатывать ручками после получения родительским окном данного сообщения.

243
20 июля 2005 года
pacific_7
1.9K / / 06.09.2004
Цитата:
Originally posted by vitaly2003s
Придется обрабатывать ручками после получения родительским окном данного сообщения.


Ясненько. "Наша работа и опасна и трудна..." :)

243
25 июля 2005 года
pacific_7
1.9K / / 06.09.2004
Не хочу создавать новую тему.

1) Создаем дочернее окно, создаем на нем кнопку, присваеваем ей id. Как теперь ловить сообщения от этой кнопки оконной функцией? case WM_COMMAND - ноль реакции на все щелчки.
Обобщу - как обрабатывать сообщения от дочерних окон: изменение размера и т.п.

2) Как создать дочернее окно "фрейм" (или как его правильно назвать)? Т.е. нечто вроде панели истории в браузерах.
406
26 июля 2005 года
vitaly2003s
481 / / 27.07.2004
Цитата:
Originally posted by pacific_7
Не хочу создавать новую тему.

1) Создаем дочернее окно, создаем на нем кнопку, присваеваем ей id. Как теперь ловить сообщения от этой кнопки оконной функцией? case WM_COMMAND - ноль реакции на все щелчки.
Обобщу - как обрабатывать сообщения от дочерних окон: изменение размера и т.п.

2) Как создать дочернее окно "фрейм" (или как его правильно назвать)? Т.е. нечто вроде панели истории в браузерах.



1)
Заглянем в MSDN и там найдем:
The WM_COMMAND message is sent when the user selects a command item from a menu, when a control sends a notification message to its parent window, or when an accelerator keystroke is translated.

Syntax

WM_COMMAND

WPARAM wParam
LPARAM lParam;

Parameters

wParam
The high-order word specifies the notification code if the message is from a control. If the message is from an accelerator, this value is 1. If the message is from a menu, this value is zero.
The low-order word specifies the identifier of the menu item, control, or accelerator.

lParam
Handle to the control sending the message if the message is from a control. Otherwise, this parameter is NULL.

Return Value

If an application processes this message, it should return zero.

Т.е. для родительского(главного) окна имеется функция - обработчик,в ней к примеру имеется
case WM_COMMAND:
switch(HIWORD(wParam))//выбираем сообщение от контролов
{
case BN_CLICKED://кнопка нажата
switch(LOWORD(wParam))//выбираем id кнопки
{
case IDOK:
//кнопка с id = IDOK нажата
return 0;
}
}

Для каждого контрола свой набор notification message.
Такие сообщения как BN_CLICKED и другие являются notification message(сообщениями уведомления контролов) и посылаются в обработчик родительского окна данного контрола,а чтобы поймать сообщения от контролов не являющиеся уведомительными такие как WM_SIZE и др необходимо использовать субклассинг(подмену стандартного обработчика WndProc на свой собственный) либо если данное child окно непосредственно создано вами с вашим собственным классом то использовать WndProc непосредственно назначенный данному окну и в нем уже или подмененом обработчике отлавливать такие сообщения.


2) IMHO при программировании на чистом win32 api нет такого понятия как фрейм. Придется самому создавать свой глобальный класс интерфейса и уже через него эмулировать функциональность фреймов.
Хотя в MFC или WTL скорее всего есть что то подобное,не заню не увлекался этим.

243
27 июля 2005 года
pacific_7
1.9K / / 06.09.2004
Цитата:
Originally posted by vitaly2003s
1)
Заглянем в MSDN и там найдем...


Заглядывали... И находили это, но это не то. Пожалуйста, обработчик:

Код:
LRESULT CALLBACK WndProc(HWND win, UINT messg, UINT wparam, LONG lparam)
{
    static CLIENTCREATESTRUCT client;

    static HWND mdi_win, btn;

    switch(messg)
    {
    case WM_CREATE:
        client.hWindowMenu=NULL;
        client.idFirstChild=0;

        mdi_win=CreateWindow("MDICLIENT",NULL,
                                WS_CHILD|WS_VISIBLE|WS_DLGFRAME|WS_SIZEBOX,
                                5,35,200,100,win,NULL,h_inst,&client);
        btn=CreateWindow("button","йМНОЙЮ",WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON|
                        NULL,50,50,70,20,mdi_win,(HMENU)BTN_CLOSE,h_inst,NULL);
        return 0;
    case WM_COMMAND:
        OK_MSG("OK");//макрозамена MessageBox'а
//так вот, при щелчке на btn ни каких ОК не выскакивает :(
//т.е. главному окну (win) не идет сообщение WM_COMMAND,
//оно идет окну (mdi_win)
//выход вижу пока только в создании отдельного обработчика
//для mdi_win

        return 0;
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc(win, messg, wparam, lparam);
}

Есть еще варианты, или у меня все же что-то не правильно?
406
27 июля 2005 года
vitaly2003s
481 / / 27.07.2004
Естественно оно идет не в этот обработчик а в обработчик для mdi_win так как ты при создании кнопки указал что родителем данной кнопки будет mdi_win. взгляни на свой код:

btn=CreateWindow("button","йМНОЙЮ",WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON| NULL,50,50,70,20,[COLOR=red]mdi_win[/COLOR] ,(HMENU)BTN_CLOSE,h_
inst,NULL);

замени здесь хэндл mdi_win на реальный родительский хэндл,в данном случае win.Получаем

btn=CreateWindow("button","йМНОЙЮ",WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON| NULL,50,50,70,20,win,(HMENU)BTN_CLOSE,h_
inst,NULL);

Правда тогда кнопка будет создаваться не на mdi_win а на win. А если требуется чтоб кнопка отображалась на mdi_win,то тогда необходимо делать отдельный обработчик для mdi_win.
Если все же нужно добиться чтобы кнопка принадлежащяя mdi_win обрабатывалась в процедуре win то необходимо сделать субклассинг и там перенаправлять сообщения в нужное окно,только зачем этот геморой.
243
28 июля 2005 года
pacific_7
1.9K / / 06.09.2004
Цитата:
Originally posted by vitaly2003s
Естественно оно идет не в этот обработчик а в обработчик для mdi_win так как ты при создании кнопки указал что родителем данной кнопки будет mdi_win. взгляни на свой код...


Спасибо :D Давным давно взглянул. Я как-то привык сперва сам задумываться и рассматривать свой код, а только затем выкладывать его на форум.
Просто предпологал, что сообщения от дочерних окон можно обработать в родительском без дополнительных наворотов. Теперь вижу, что нельзя.

Цитата:
Originally posted by vitaly2003s

Правда тогда кнопка будет создаваться не на mdi_win а на win.


Ага, вот в этом и проблема.

Цитата:
Originally posted by vitaly2003s

Если все же нужно добиться чтобы кнопка принадлежащяя mdi_win обрабатывалась в процедуре win то необходимо сделать субклассинг и там перенаправлять сообщения в нужное окно,только зачем этот геморой.


А есть варианты расположения кнопки на родительском окне, да так, что бы при перемещении дочернего одновременно перемещалась и наша кнопка на родительском окне (без еще большЕго гемора)? Или, например мне нужно спрятать дочернее окно - тогда мне нужно будет отдельно прятать все кнопочки которые как-бы находятся на нем (а реально - на родительском).
Кстати, если сперва создать дочернее окно, а затем кнопочку, то она оказывается под ним (по логике вещей - должно быть наоборот) и из-за этого оказывается недоступной. Т.е. ее видно, а щелкнуть по ней не получается. Нужно либо строго соблюдать порядок создания окон - сперва все контроллы, а затем дочернее окно; либо вытягивать их дополнительным набором функций на передний план уже после создания. Что-то мне кажется, что это еще больший гемор, чем создание дополнительной оконной функции. Во всяком случае о структуре программы тогда можно будет забыть.
Видимо других вариантов пока нет. Значит будем делать так.

ЗЫ Я человек тёмный: субклассинг - это что такое: Создание дочернего окна при помощи WNDCLASS? Где про это можно почитать?

406
28 июля 2005 года
vitaly2003s
481 / / 27.07.2004
Если честно то я не догоняю нахрена тебе это нужно отображать кнопки которые как бы относятся к одному окну а отображаются на другом. Зачем? Можеш описать или показать концепцию твоего интерфейса,т.е. что должно получиться или привести пример того где ты это видел. В обычных случаях данные методы как ты хочеш не требуются по крайней мере для контролов(т.е. управление расположение контролов в зависимости от расположения сторонних окон). Можно конечно реализовать абсолютно все что ты описал,но гемор и структура улетят к черту.IMHO Лучше делать так(для чистого winapi):
имеем класс CInterface который будет служить для базовых операций (т.е. управлением менюшками и общими кнопками а также созданием отдельных оконных модулей(т.е. окон с доп контролами,обработка которых ложится исключительно на данные модули а не главный Wndproc,желательно чтобы модуль был классом) и т.д. Т.е. данный класс обединяет все модули в единое целое,здесь же соответсвенно осуществляется управление расположением,перемещением одних модулей относительно других,их отображение и скрытие. Но здесь не обрабатываются сообщения из контролов относящихся к отдельному модулю.
Конечно реализовать не так то просто,зато все будет потом логически ясным и проще что-то будет изменять,и уже не надо будет лезть в глобальное состояние всего интерфейса а скажем только обратится к классу отдельного модуля.
Хотя существуют библиотеки о которых ты знаеш типа MFC,WTL и т.д которые могут упростить всю архитектуру,но я ими не пользуюсь. Мне пока и чистого winapi хватает,поэтому по этим библиотекам нмчего сказать не могу.

Хотя конечно интерфейс простой то не стоит так заморачиваться,а просто писать как пишеш обычно.

Про субклассинг почитай из мсдн: (если непонятно будет обясню с примером)
Subclassing Defined
Subclassing is a technique that allows an application to intercept messages destined for another window. An application can augment, monitor, or modify the default behavior of a window by intercepting messages meant for another window. Subclassing is an effective way to change or extend the behavior of a window without redeveloping the window. Subclassing the default control window classes (button controls, edit controls, list controls, combo box controls, static controls, and scroll bar controls) is a convenient way to obtain the functionality of the control and to modify its behavior. For example, if a multiline edit control is included in a dialog box and the user presses the ENTER key, the dialog box closes. By subclassing the edit control, an application can have the edit control insert a carriage return and line feed into the text without exiting the dialog box. An edit control does not have to be developed specifically for the needs of the application.


When an application subclasses a window, it can take three actions with the message: (1) pass the message to the original window procedure; (2) modify the message and pass it to the original window procedure; (3) not pass the message.

The application subclassing a window can decide when to react to the messages it receives. The application can process the message before, after, or both before and after passing the message to the original window procedure.

Types of Subclassing
The two types of subclassing are instance subclassing and global subclassing.

Instance subclassing is subclassing an individual window's information structure. With instance subclassing, only the messages of a particular window instance are sent to the new window procedure.

The subclassing process may not use the original window procedure address directly.
In Win16, an application could use the window procedure address returned from SetWindowLong or SetClassLong to call the procedure directly. After all, the return value is simply a pointer to a function, so why not just call it? In Win32, this is a definitive no-no. The value returned from SetWindowLong and GetClassLong may not be a pointer to the previous window procedure at all. Win32 may return a pointer to a data structure that it can use to call the actual window procedure. This occurs in Windows NT™ when an application subclasses a Unicode™ window with a non-Unicode window procedure, or a non-Unicode window with a Unicode window procedure. In this case, the operating system must perform a translation between Unicode and ANSI for the messages the window receives. If an application uses the pointer to this structure to directly call the window procedure, the application will immediately generate an exception. The only way to use the window procedure address returned from SetWindowLong or SetClassLong is as a parameter to CallWindowProc.

Instance Subclassing
The SetWindowLong function is used to subclass an instance of a window. The application must have the address of the subclass function. The subclass function is the function that receives the messages from Windows and passes the messages to the original window procedure. The subclass function must be exported in the application's or the DLL's module definition file.

The application subclassing the window calls SetWindowLong with the handle to the window the application wants to subclass, the GWL_WNDPROC option (defined in WINDOWS.H), and the address of the new subclass function. SetWindowLong returns a DWORD, which is the address of the original window procedure for the window. The application must save this address to pass the intercepted messages to the original window procedure and to remove the subclass from the window. The application passes the messages to the original window procedure by calling CallWindowProc with the address of the original window procedure and the hWnd, Message, wParam, and lParam parameters used in Windows messaging. Usually, the application simply passes the arguments it receives from Windows to CallWindowProc.

The application also needs the original window procedure address for removing the subclass from the window. The application removes the subclass from the window by calling SetWindowLong again. The application passes the address of the original window procedure with the GWL_WNDPROC option and the handle to the window being subclassed.

The following code subclasses and removes a subclass to an edit control:

LONG FAR PASCAL SubClassFunc(HWND hWnd,UINT Message,WPARAM wParam,
LONG lParam);
FARPROC lpfnOldWndProc;
HWND hEditWnd;

//
// Create an edit control and subclass it.
// The details of this particular edit control are not important.
//
hEditWnd = CreateWindow("EDIT", "EDIT Test",
WS_CHILD | WS_VISIBLE | WS_BORDER ,
0, 0, 50, 50,
hWndMain,
NULL,
hInst,
NULL);
//
// Now subclass the window that was just created.
//
lpfnOldWndProc = (FARPROC)SetWindowLong(hEditWnd,
GWL_WNDPROC, (DWORD) SubClassFunc);
.
.
.
//
// Remove the subclass for the edit control.
//
SetWindowLong(hEditWnd, GWL_WNDPROC, (DWORD) lpfnOldWndProc);

//
// Here is a sample subclass function.
//
LONG FAR PASCAL SubClassFunc( HWND hWnd,
UINT Message,
WPARAM wParam,
LONG lParam)
{
//
// When the focus is in an edit control inside a dialog box, the
// default ENTER key action will not occur.
//

if ( Message == WM_GETDLGCODE )
return DLGC_WANTALLKEYS;

return CallWindowProc(lpfnOldWndProc, hWnd, Message, wParam,
lParam);
}

When an application subclasses a subclassed window, the subclasses must be removed in reverse of the order in which they were performed.

Global Subclassing
Global subclassing is similar to instance subclassing. The application calls SetClassLong to globally subclass a window class. As it does with instance subclassing, the application needs the address of the subclass function, and the subclass function must be exported in the application's or the DLL's module definition file.

To globally subclass a window class, the application must have a handle to a window of that class. To get a handle to a window in the desired class, most applications create a window of the class to be globally subclassed. When the application removes the subclass, it needs a handle to a window of the type the application wants to subclass, so creating and keeping a window for this purpose is the best technique. If the application creates a window of the type it wants to subclass, the window is usually hidden. After obtaining a handle to a window of the correct type, the application calls SetClassLong with the window handle, the GCL_WNDPROC option (defined in WINDOWS.H), and the address of the new subclass function. SetClassLong returns a DWORD, which is the address of the original window procedure for the class. The original window procedure address is used in global subclassing in the same way it is used in instance subclassing. Messages are passed to the original window procedure in the same way as in instance subclassing, by calling CallWindowProc.

The following code globally subclasses and removes a subclass to an edit control:

LONG FAR PASCAL SubClassFunc(HWND hWnd,UINT Message,WORD wParam,
LONG lParam);
FARPROC lpfnOldClassWndProc;
HWND hEditWnd;


hEditWnd = CreateWindow("EDIT", "EDIT Test",
WS_CHILD,
0, 0, 50, 50,
hWndMain,
NULL,
hInst,
NULL);
lpfnOldClassWndProc =
(FARPROC)SetClassLong(hEditWnd, GCL_WNDPROC, (DWORD)
SubClassFunc);
.
.
.
//
// To remove the subclass:
//
SetClassLong(hEditWnd, GWL_WNDPROC, (DWORD) lpfnOldClassWndProc);
DestroyWindow(hEditWnd);
243
28 июля 2005 года
pacific_7
1.9K / / 06.09.2004
Цитата:
Originally posted by vitaly2003s
Если честно то я не догоняю нахрена тебе это нужно отображать кнопки которые как бы относятся к одному окну а отображаются на другом. Зачем?


Гы-гы-гы :) Я вижу мы решительно друг-друга не понимаем. Нужно сделать как раз наоборот.

Цитата:
Originally posted by vitaly2003s

Можеш описать или показать концепцию твоего интерфейса,т.е. что должно получиться или привести пример того где ты это видел.


Да ничего особенного - считай нечто вроде браузера с боковой панелью истории. Для начала мне с головой хватит.

Цитата:
Originally posted by vitaly2003s

В обычных случаях данные методы как ты хочеш не требуются по крайней мере для контролов(т.е. управление расположение контролов в зависимости от расположения сторонних окон).


Мням... Я снова не догнал. Например имеем боковую панель истории в файерфоксе. В ней есть эдит-контрол "найти". При изменении размера (ширины) этой боковой панели у нас меняется: 1 - ширина этого контрола; 2 - размер области вкладок. Я про это, как это все можно нормально реализовать? Т.е. как можно обработать сообщение WM_SIZE посылаемое именно боковой панели, а не главному окну. Ведь размер главного окна не изменяется. И еще: я поковырял через Spy++ файерфокс: можешь мне объяснить - зачем у него главное меню, панель инструментов и эта же панель истории находятся не непосредственно на главном окне, а на дочернем, которое занимает практически всю клиентскую область главного?

Цитата:
Originally posted by vitaly2003s

имеем класс CInterface который будет служить для базовых операций (т.е. управлением менюшками и общими кнопками а также созданием отдельных оконных модулей(т.е. окон с доп контролами,обработка которых ложится ------------------------------
изменять,и уже не надо будет лезть в глобальное состояние всего интерфейса а скажем только обратится к классу отдельного модуля.


Понял пока только на уровне теории.

Цитата:
Originally posted by vitaly2003s

Хотя конечно интерфейс простой то не стоит так заморачиваться,а просто писать как пишеш обычно.


По моему у меня он простой. Просто голова пока как-то неправильно работает :)

Ладно, будем разбираться.

243
29 июля 2005 года
pacific_7
1.9K / / 06.09.2004
Пришел в 3 ночи с моря и кажется всё понял. :)
406
29 июля 2005 года
vitaly2003s
481 / / 27.07.2004
Цитата:
Originally posted by pacific_7
Пришел в 3 ночи с моря и кажется всё понял. :)



Что понял?

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог