Wparam lparam что это
Перейти к содержимому

Wparam lparam что это

  • автор:

Wparam lparam что это

Эта функция производит обработку сообщений для окна. Мы ее связываем с окном при заполнении структуры класса окна WNDCLASS в поле lpfnWndProc:

WNDCLASS WC; . WC.lpfnWndProc = WndProc;

Вот эта функция WndProc и будет получать сообщения, которые Windows будет отсылать окну. Соответственно эта функция должна быть объявлена ранее. Прототип у этой функции такой:

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM,LPARAM);

Общий вид для реализации:

LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wparam,LPARAM lparam) < if (Message == WM_DESTROY ) < PostQuitMessage(0); return 0; >return DefWindowProc(hwnd,Message,wparam,lparam); >

В этой функции мы обрабатываем сообщения от Windows. При этом, если обработку не совершаем, то вызываем функцию по умолчанию DefWindowProc, которая уммет обрабатывать сообщения по умолчанию.

LRESULT DefWindowProc ( HWND hWnd, // указатель окна UINT Msg, // идентификатор сообщения WPARAM wParam, // первый параметр сообщения LPARAM lParam // второй параметр сообщения );

Возврашает результат обработки сообщения. Обычно в функции WndProc организуется огромный switch для обработки сообщений.

Написание процедуры окна

Функция DispatchMessage вызывает процедуру окна окна, которое является целью сообщения. Процедура окна имеет следующую подпись.

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); 

Существует четыре параметра:

  • Hwnd — это дескриптор окна.
  • UMsg — это код сообщения, например сообщение WM_SIZEуказывает,что окно было изменено.
  • wParam и lParam содержат дополнительные данные, относящиеся к сообщению. Точное значение зависит от кода сообщения.

LRESULT — это целочисленное значение, которое программа возвращает в Windows. Он содержит ответ вашей программы на определенное сообщение. Значение этого значения зависит от кода сообщения. CALLBACK — это соглашение о вызовах для функции.

Обычная процедура окна — это просто большая инструкция коммутатора, которая переключается на код сообщения. Добавьте варианты для каждого сообщения, которое требуется обрабатывать.

switch (uMsg) < case WM_SIZE: // Handle window resizing // etc >

Дополнительные данные для сообщения содержатся в параметрах lParam и wParam. Оба параметра представляют собой целочисленные значения размера ширины указателя (32 бита или 64 бита). Значение каждого зависит от кода сообщения (uMsg). Для каждого сообщения необходимо найти код сообщения в MSDN и привести параметры к правильному типу данных. Обычно данные являются числовым значением или указателем на структуру. Некоторые сообщения не имеют данных.

Например, в документации по сообщению WM_SIZE указано следующее:

  • wParam — это флаг, указывающий, был ли окно свернуто, развернуто или изменено.
  • lParam содержит новую ширину и высоту окна в виде 16-разрядных значений, упакованных в один 32-или 64-разрядный номер. Чтобы получить эти значения, потребуется выполнить некоторые битовые сдвиги. К счастью, файл заголовка WinDef.h включает вспомогательные макросы, которые делают это.

Типичная процедура окна обрабатывает десятки сообщений, поэтому она может расти довольно долго. Один из способов сделать код более модульным — поместить логику обработки каждого сообщения в отдельную функцию. В процедуре окна приведите параметры wParam и lParam к правильному типу данных и передайте эти значения в функцию. Например, чтобы обработать сообщение WM_SIZE , процедура окна будет выглядеть следующим образом:

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) < switch (uMsg) < case WM_SIZE: < int width = LOWORD(lParam); // Macro to get the low-order word. int height = HIWORD(lParam); // Macro to get the high-order word. // Respond to the message: OnSize(hwnd, (UINT)wParam, width, height); >break; > > void OnSize(HWND hwnd, UINT flag, int width, int height) < // Handle resizing >

Макросы LOWORD и HIWORD получают 16-разрядные значения ширины и высоты из lParam. (Эти сведения можно найти в документации MSDN по каждому коду сообщения.) Процедура окна извлекает ширину и высоту, а затем передает эти значения OnSize функции.

Обработка сообщений по умолчанию

Если вы не обрабатываете определенное сообщение в процедуре окна, передайте параметры сообщения непосредственно в функцию DefWindowProc . Эта функция выполняет действие по умолчанию для сообщения, которое зависит от типа сообщения.

return DefWindowProc(hwnd, uMsg, wParam, lParam); 

Предотвращение узких мест в процедуре окна

Хотя процедура окна выполняется, она блокирует любые другие сообщения для окон, созданных в том же потоке. Поэтому избегайте длительной обработки в процедуре окна. Например, предположим, что программа открывает TCP-подключение и ожидает неограниченное время, пока сервер будет отвечать. Если это делается в процедуре окна, пользовательский интерфейс не будет отвечать до завершения запроса. В течение этого времени окно не может обрабатывать ввод мыши или клавиатуры, перезапугать себя или даже закрыть.

Вместо этого следует переместить работу в другой поток, используя одну из многозадаочных средств, встроенных в Windows:

  • Создайте новый поток.
  • Использование пула потоков.
  • Используйте асинхронные вызовы ввода-вывода.
  • Используйте асинхронные вызовы процедур.

Developing.ru

Учу Visual C++. Читала книги, но не могу толком понять для чего нужны в некоторых ф-ях lParam и wParam? В чем их суть и что вместо них вставляется (например, вместо int можно поставить целое чисо)? Может, кто объяснит попроще?

WinMain Сообщения: 913 Зарегистрирован: 14 янв 2005, 10:30 Откуда: Москва Контактная информация:

Обычно функции SendMessage(), PostMessage() и др. используют данные параметры. Содержимое WPARAM и LPARAM зависят от каждого конкретного оконного сообщения. Смотри в MSDN информацию по оконным функциям и сообщениям.

Absurd Сообщения: 1213 Зарегистрирован: 26 фев 2004, 13:24 Откуда: Pietari, Venäjä Контактная информация:

Читала книги, но не могу толком понять для чего нужны в некоторых ф-ях lParam и wParam?

Превед из 16-битной Win 3.11.
lParam — 32 — битовый парaметр (long в 16 битовой среде это 32 бита), wParam — word param, word это 16 бит. Сейчас понятия «WORD» и «DWORD» устарели.
Ныне оба типа — это 32 или 64 битовые целые в зависимости от ОС — Win32 или Win64.
Нести эти два параметра могут все что угодно: координаты мыши, код нажатой клавиши на клавиатуре, или указатель на интерфейс/функцию.

2B OR NOT(2B) = FF
Лена89 Сообщения: 51 Зарегистрирован: 20 июн 2007, 10:36

А здесь, чем их можно заменить?

case WM_CTLCOLOR:< if((HWND)lParam == hEdit) SetTextColor((HDC)wParam, RGB(255 ,0 ,0));

Absurd Сообщения: 1213 Зарегистрирован: 26 фев 2004, 13:24 Откуда: Pietari, Venäjä Контактная информация:

Не понял вопрос. Если сообщение - WM_CTLCOLOR, то действительно wParam - Это Handle to Display Context, а lParam - это HWND контрола. Что вам нужно заменить?

2B OR NOT(2B) = FF

Absurd Сообщения: 1213 Зарегистрирован: 26 фев 2004, 13:24 Откуда: Pietari, Venäjä Контактная информация:

Remarks
The WM_CTLCOLOR message has been replaced by more specific notifications in 32-bit versions of Windows. These replacements include the following:

WM_CTLCOLORBTN
WM_CTLCOLOREDIT
WM_CTLCOLORDLG
WM_CTLCOLORLISTBOX
WM_CTLCOLORSCROLLBAR
WM_CTLCOLORSTATIC

2B OR NOT(2B) = FF
Лена89 Сообщения: 51 Зарегистрирован: 20 июн 2007, 10:36
Нет, я имела ввиду вместо: (HWND)lParam, (HDC)wParam и hEdit.
Лена89 Сообщения: 51 Зарегистрирован: 20 июн 2007, 10:36
Что примерно. вообще там может быть?
BBB Сообщения: 1272 Зарегистрирован: 27 дек 2005, 13:37
Лена89 писал(а): Что примерно. вообще там может быть?
Все, что угодно. Зависит от конкретного Windows-сообщения:

WinMain писал(а): Обычно функции SendMessage(), PostMessage() и др. используют данные параметры. Содержимое WPARAM и LPARAM зависят от каждого конкретного оконного сообщения. Смотри в MSDN информацию по оконным функциям и сообщениям.

Absurd писал(а): Нести эти два параметра могут все что угодно: координаты мыши, код нажатой клавиши на клавиатуре, или указатель на интерфейс/функцию.

Обычно, в описании того или иного Windows-сообщения (иденцифицируемого константой вида WM_xxxxxxxx) указывается, используются ли для ДАННОГО сообщения wParam и lParam и какая информация (опять же - для ДАННОГО сообщения) в них находится.

Romeo Сообщения: 3091 Зарегистрирован: 02 мар 2004, 17:25 Откуда: Крым, Севастополь Контактная информация:

Лена, ты издеваешься? Тебе же сказали, что значение этих параметров зависит от мессэйджа. Они не статичны!

Например для WM_SIZE wParam хранит тип ресайза, а lParam - новую ширину и высоту в младшем и, соответственно, старшем словах.

Для того же WM_PAINT - эти параметры не используются.

Какой смысл имеет wParam и lParam для конкретного сообщения можно прочесть в MDSN.

Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.

Использование оконных процедур

В этом разделе объясняется, как выполнять следующие задачи, связанные с процедурами окон.

  • Проектирование процедуры окна
  • Связывание процедуры Window с классом Window
  • Подклассы окна

Проектирование процедуры окна

В следующем примере показана структура типичной процедуры окна. Процедура окна использует аргумент сообщения в операторе switch с отдельными сообщениями, обрабатываемыми отдельными операторами case . Обратите внимание, что каждый случай возвращает определенное значение для каждого сообщения. Для сообщений, которые не обрабатываются, процедура окна вызывает функцию DefWindowProc .

LRESULT CALLBACK MainWndProc( HWND hwnd, // handle to window UINT uMsg, // message identifier WPARAM wParam, // first message parameter LPARAM lParam) // second message parameter < switch (uMsg) < case WM_CREATE: // Initialize the window. return 0; case WM_PAINT: // Paint the window's client area. return 0; case WM_SIZE: // Set the size and position of the window. return 0; case WM_DESTROY: // Clean up window-specific data objects. return 0; // // Process other messages. // default: return DefWindowProc(hwnd, uMsg, wParam, lParam); >return 0; > 

Сообщение WM_NCCREATE отправляется сразу после создания окна, но если приложение отвечает на это сообщение, возвращая значение FALSE, функция CreateWindowEx завершается ошибкой. Сообщение WM_CREATE отправляется после создания окна.

Сообщение WM_DESTROY отправляется, когда окно будет уничтожено. Функция DestroyWindow отвечает за уничтожение всех дочерних окон окна, которые будут уничтожены. Сообщение WM_NCDESTROY отправляется непосредственно перед уничтожением окна.

По крайней мере, оконная процедура должна обрабатывать WM_PAINT сообщение для рисования себя. Как правило, он также должен обрабатывать сообщения мыши и клавиатуры. Ознакомьтесь с описаниями отдельных сообщений, чтобы определить, следует ли обрабатывать их в процедуре окна.

Приложение может вызывать функцию DefWindowProc в процессе обработки сообщения. В этом случае приложение может изменить параметры сообщения перед передачей сообщения в DefWindowProc или продолжить обработку по умолчанию после выполнения собственных операций.

Процедура диалогового окна получает WM_INITDIALOG сообщение вместо сообщения WM_CREATE и не передает необработанные сообщения в функцию DefDlgProc . В противном случае процедура диалогового окна точно такая же, как и процедура окна.

Связывание процедуры Window с классом Window

При регистрации класса процедура окна связывается с оконным классом. Необходимо заполнить структуру WNDCLASS сведениями о классе, а член lpfnWndProc должен указать адрес процедуры окна. Чтобы зарегистрировать класс, передайте адрес структуры WNDCLASS в функцию RegisterClass . После регистрации класса window процедура окна автоматически связывается с каждым новым окном, созданным с помощью этого класса.

В следующем примере показано, как связать процедуру окна в предыдущем примере с классом окна.

int APIENTRY WinMain( HINSTANCE hinstance, // handle to current instance HINSTANCE hinstPrev, // handle to previous instance LPSTR lpCmdLine, // address of command-line string int nCmdShow) // show-window type < WNDCLASS wc; // Register the main window class. wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = (WNDPROC) MainWndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hinstance; wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = GetStockObject(WHITE_BRUSH); wc.lpszMenuName = "MainMenu"; wc.lpszClassName = "MainWindowClass"; if (!RegisterClass(&wc)) return FALSE; // // Process other messages. // >

Подклассы окна

Чтобы выполнить подкласс экземпляра окна, вызовите функцию SetWindowLong и укажите дескриптор окна для подкласса флага GWL_WNDPROC и указателя на процедуру подкласса. SetWindowLong возвращает указатель на исходную процедуру окна; Используйте этот указатель для передачи сообщений в исходную процедуру. Процедура окна подкласса должна использовать функцию CallWindowProc для вызова исходной процедуры окна.

Чтобы написать код, совместимый как с 32-разрядной, так и с 64-разрядной версиями Windows, используйте функцию SetWindowLongPtr .

В следующем примере показано, как выполнить подкласс экземпляра элемента управления редактирования в диалоговом окне. Процедура окна подкласса позволяет элементу управления редактирования получать все входные данные с клавиатуры, включая клавиши ВВОД и TAB, всякий раз, когда элемент управления имеет фокус ввода.

WNDPROC wpOrigEditProc; LRESULT APIENTRY EditBoxProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) < HWND hwndEdit; switch(uMsg) < case WM_INITDIALOG: // Retrieve the handle to the edit control. hwndEdit = GetDlgItem(hwndDlg, ID_EDIT); // Subclass the edit control. wpOrigEditProc = (WNDPROC) SetWindowLong(hwndEdit, GWL_WNDPROC, (LONG) EditSubclassProc); // // Continue the initialization procedure. // return TRUE; case WM_DESTROY: // Remove the subclass from the edit control. SetWindowLong(hwndEdit, GWL_WNDPROC, (LONG) wpOrigEditProc); // // Continue the cleanup procedure. // break; >return FALSE; UNREFERENCED_PARAMETER(lParam); > // Subclass procedure LRESULT APIENTRY EditSubclassProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *