Модераторы: feodorv, GremlinProg, xvr, Fixin

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Собственное сообщение WindowProc, как созд. и обработ. собств. сообщение? 
:(
    Опции темы
GGoga
Дата 18.7.2007, 18:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 49
Регистрация: 1.5.2007
Где: Харьков

Репутация: нет
Всего: нет



Здравствуйте, уважаемые господа программисты! Помогите, пожалуйста, начинающему программисту smile

Как можно реализовать следующую задачу: необходимо, чтобы при наступлении определенного события, обрабатывать его в функции WindowProc. Я так понимаю, что необходимо определить свое сообщение, для этого я пишу следующий код:

Код

#define WM_GAMEOVER (WM_USER + 1)


После этого ловлю данное сообщение в функции WindowProc:
Код

long FAR PASCAL WindowProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{
    using namespace arcadeworks;
    switch( message )
    {
    case WM_GAMEOVER:
        AfxMessageBox(_T("Game Over!"), MB_OK);
        break;
    case WM_ACTIVATEAPP:
...
}


И отправляю данное сообщение при наступлении события:
Код

if(ball)
{
...
    if(ball && ball->GetCollObj() == bottom)
        WindowProc(AfxGetMainWnd()->GetSafeHwnd(), WM_GAMEOVER, 0, 0);
...
}


Однако при этом ничего не происходит, сообщение "Game Over!" на экран не выводится :(

Я просто уверен, что я что-то делаю не так или не все! Вот только не знаю, что именно нужно изменить или добавить. Подскажите кто-нибудь решение проблемы. Заранее ОГРОМНОЕ СПАСИБО!
PM MAIL ICQ Skype   Вверх
zkv
Дата 18.7.2007, 19:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Участник Клуба
Сообщений: 2133
Регистрация: 23.7.2006
Где: Санкт-Петербург

Репутация: 12
Всего: 92



Код

if(ball && ball->GetCollObj() == bottom)
        AfxGetMainWnd()->PostMessage( WM_GAMEOVER, 0, 0 );//либо SendMessage() если нужно дождаться обработки сообщения 

интересная сигнатура у твоей WindowProc если работаешь в МФС, то перегружай соответствующий метод (WindowProc) у главного окна, и там лови 
PM MAIL   Вверх
GGoga
Дата 18.7.2007, 22:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 49
Регистрация: 1.5.2007
Где: Харьков

Репутация: нет
Всего: нет



Цитата(zkv @ 18.7.2007,  19:00)
...
интересная сигнатура у твоей WindowProc если работаешь в МФС, то перегружай соответствующий метод (WindowProc) у главного окна, и там лови

Работаю с WinAPI с поддержкой MFC. Пробовал вариант c SendMessage(), только при этом приложение вылетает с неизвестной ошибкой :( Как ее избежать я не знаю, при троссировке показывает доступ к неизвестной области памяти... 
PM MAIL ICQ Skype   Вверх
zkv
Дата 18.7.2007, 22:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Участник Клуба
Сообщений: 2133
Регистрация: 23.7.2006
Где: Санкт-Петербург

Репутация: 12
Всего: 92



Цитата(GGoga @  18.7.2007,  18:41 Найти цитируемый пост)
ловлю данное сообщение в функции WindowProc

эта функция - оконная процедура главного окна?

Цитата(GGoga @  18.7.2007,  22:16 Найти цитируемый пост)
Пробовал вариант c SendMessage(), только при этом приложение вылетает с неизвестной ошибкой

видимо не приходит сообщение до адреса. Где-то напутал чего-то...
PM MAIL   Вверх
zkv
Дата 18.7.2007, 23:44 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Участник Клуба
Сообщений: 2133
Регистрация: 23.7.2006
Где: Санкт-Петербург

Репутация: 12
Всего: 92



вот тебе пример рабочий:
Код

#include <windows.h>
#include "resource.h"

LRESULT CALLBACK MainProc(HWND, UINT, UINT, LONG);

#define WM_MYMESSAGE (WM_USER+1)

HINSTANCE hInst; 

int WINAPI WinMain(HINSTANCE hInstance,
        HINSTANCE hPrevInstance,
        LPSTR lpCmdLine,
        int nCmdShow)
{
    MSG msg;

    hInst = hInstance;
    ::CreateDialog( hInst, MAKEINTRESOURCE( IDD_DIALOG1 ), NULL, (DLGPROC)MainProc );

    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return 0;
}


LRESULT CALLBACK MainProc(HWND hDlg, UINT message, UINT wParam, LONG lParam)
{
    switch(message)
    {
    case WM_MYMESSAGE:
        MessageBox( hDlg, "WM_MYMESSAGE has been received", "MyApp", MB_ICONINFORMATION | MB_OK );
        break;
    
    case WM_COMMAND:
    {
        switch( LOWORD(wParam) )
        {
        case IDCANCEL: 
            PostQuitMessage( 0 );
            break;
        case IDC_BUTTON1: 
            SendMessage( hDlg, WM_MYMESSAGE, 0, 0 );
            break;
        }
    }
    break;

    case WM_DESTROY:
        PostQuitMessage (0);
        break;
    }

    return 0;
}

проект на всякий случай прикладываю (VC7.1)

Это сообщение отредактировал(а) zkv - 21.7.2007, 01:51

Присоединённый файл ( Кол-во скачиваний: 11 )
Присоединённый файл  testAPI.zip 5,59 Kb
PM MAIL   Вверх
CMD
Дата 19.7.2007, 00:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 30
Регистрация: 1.8.2006

Репутация: 1
Всего: 1



Здравствуй.
1) Ход мыслей почти правильный, только свои сообщения нужно отлавливать соответствующе, а отправляються они окну не напрямую, а через сообщение WM_COMMAND, в параметре wParam. Для твоего случая это будет выглядить так:
Код

long FAR PASCAL WindowProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{
    using namespace arcadeworks;
    switch( message )
    {
          case WM_COMMAND:
                switch( LOWORD(wParam))
                {
                 case WM_GAMEOVER:
                 AfxMessageBox(_T("Game Over!"), MB_OK);
                 break;
                 
                 case WM_СООБЩЕНИЕ
                 ...
                 break;
                 }
          return 0; // Не забывай, что WM_COMMAND должен либо что-то вернуть, либо должна продолжиться обработка остальных оконных сообщений.
    case WM_ACTIVATEAPP:
...
}


2) Исходя из первого пункта думаю понятно, что ты пытаешься вызвать неопределённое действие.

Если хочешь, стучи в аську 367-й0й, й=5. Я - BO$$.
PM MAIL   Вверх
zkv
Дата 19.7.2007, 07:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Участник Клуба
Сообщений: 2133
Регистрация: 23.7.2006
Где: Санкт-Петербург

Репутация: 12
Всего: 92



Цитата(CMD @  19.7.2007,  00:22 Найти цитируемый пост)
а отправляються они окну не напрямую, а через сообщение WM_COMMAND, в параметре wParam.

можно ссылку на источник этой информации?
почему мой код работает?
PM MAIL   Вверх
W4FhLF
Дата 19.7.2007, 08:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


found myself
****


Профиль
Группа: Участник Клуба
Сообщений: 2831
Регистрация: 2.12.2006

Репутация: 12
Всего: 121



Цитата(zkv @  19.7.2007,  07:39 Найти цитируемый пост)
можно ссылку на источник этой информации?


Я так понял, так делается в случае, когда в программе используется Accelerator. Но с чего решили, что он здесь используется?

http://msdn2.microsoft.com/en-us/library/ms645526.aspx
http://msdn2.microsoft.com/en-us/library/ms647591.aspx


--------------------
"Бог умер" © Ницше
"Ницше умер" © Бог
PM ICQ   Вверх
CMD
Дата 19.7.2007, 12:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 30
Регистрация: 1.8.2006

Репутация: 1
Всего: 1



Цитата

можно ссылку на источник этой информации?
почему мой код работает? 

Ты ж его не сам писал, вот и непотрудился разобраться, что к чему:
http://msdn2.microsoft.com/en-us/library/ms644931.aspx
Там чётко написано, какие бывают сообщения, я не видел всего твоего кода, но думаю, что целесообразнее использовать WM_APP, вместо WM_USER.

Цитата

Я так понял, так делается в случае, когда в программе используется Accelerator. Но с чего решили, что он здесь используется?

http://msdn2.microsoft.com/en-us/library/ms645526.aspx
http://msdn2.microsoft.com/en-us/library/ms647591.aspx 

Неправильно ты понял, там же доступным языком написано, что:
Цитата(http://msdn2.microsoft.com/en-us/library/aa930761.aspx)

This message is sent when the user selects a command item from a menu, when a control sends a message to its parent window, or when an accelerator keystroke is translated.

А parent window - это контрол.
Акселераторы тут непричём.
PM MAIL   Вверх
zkv
Дата 19.7.2007, 13:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Участник Клуба
Сообщений: 2133
Регистрация: 23.7.2006
Где: Санкт-Петербург

Репутация: 12
Всего: 92



Цитата(CMD @  19.7.2007,  12:42 Найти цитируемый пост)
Ты ж его не сам писал, вот и непотрудился разобраться, что к чему:

сам, от первой до последней строчки. Хамите сударь! 

Цитата(CMD @  19.7.2007,  12:42 Найти цитируемый пост)
Там чётко написано, какие бывают сообщения, я не видел всего твоего кода, но думаю, что целесообразнее использовать WM_APP, вместо WM_USER.

почитал информацию по вашей ссылке, интересно, не знал, всегда работал с WM_USER, проблем не было. Спасибо.

Цитата(CMD @  19.7.2007,  12:42 Найти цитируемый пост)
А parent window - это контрол.

чего?

CMD, WM_COMMAND точно такое же сообщение как и все остальные в системе. 
Что пошлем, то и ловить надо, или вы хотите сказать, что если мы делаем SendMessage( WM_USER+1 ) своему окну, то ловить придется WM_COMMAND? smile
Вот поэтому и работает мой пример. В вашей ссылке говорится, что такое сообщение может использоваться другими классами окон, те возможны конфликты (в моей практике не было, кто-нить сталкивался? интересно), но кто говорил о том, что обрабатывать надо WM_COMMAND, если мы сами его не слали? Не путайте пожалуйста пользовательские сообщения с notifications контролов.

Прошу вас, не пытаться устроить тут войну, я буду очень вам благодарен, если вы расскажете мне что-то, чего я не знаю. 
PM MAIL   Вверх
CMD
Дата 19.7.2007, 15:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 30
Регистрация: 1.8.2006

Репутация: 1
Всего: 1



Цитата

сам, от первой до последней строчки. Хамите сударь! 

zkv, извини, я ошибся ибо имел ввиду автора темы - GGoga.

Что косаеться контролов - то это тоже окна. 
А про конфликты - видимо имелось ввиду, что если определить сообщение, которое уже зарезервировано системой, то тогда и будут конфликты.

PM MAIL   Вверх
zkv
Дата 19.7.2007, 15:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Участник Клуба
Сообщений: 2133
Регистрация: 23.7.2006
Где: Санкт-Петербург

Репутация: 12
Всего: 92



Цитата(CMD @  19.7.2007,  15:25 Найти цитируемый пост)
Что косаеться контролов - то это тоже окна

в курсе. только контрол по отношению к форме это child window, а форма по отношению к контролу как раз  parent window
Цитата(CMD @  19.7.2007,  15:25 Найти цитируемый пост)
А про конфликты - видимо имелось ввиду, что если определить сообщение, которое уже зарезервировано системой, то тогда и будут конфликты.

я тоже так понял, но до конца еще не уверен, что понял правильно, множество исходников есть, где люди используют WM_USER и не стесняются.
PM MAIL   Вверх
CMD
Дата 19.7.2007, 19:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 30
Регистрация: 1.8.2006

Репутация: 1
Всего: 1



Цитата

я тоже так понял, но до конца еще не уверен, что понял правильно, множество исходников есть, где люди используют WM_USER и не стесняются. 


А чего тут стесняться? Из приведенных мною выше ссылок следует, что есть несколько типов сообщений, для каждого типа - есть область идентификаторов сообщений. По этому можно совершенно спокойно наплодить довольно большую кучку собственных сообщений и ни о чём не беспокоиться.
PM MAIL   Вверх
GGoga
Дата 20.7.2007, 21:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 49
Регистрация: 1.5.2007
Где: Харьков

Репутация: нет
Всего: нет



Цитата(zkv @ 18.7.2007,  23:44)
вот тебе пример рабочий:
...

Спасибо Вам за пример!
Я вот только не могу получить указатель на окно :( Я пытаюсь вызвать функцию AfxGetMainWnd(), однако она возвращает NULL. Может она и не должна возвращать указатель, ведь приложение не MFC (хотя с его поддержкой). Если этой функцией нельзя, то как в такой ситуации быть?

А вот если сделать так:
Код

AfxGetMainWnd()->MessageBox(_T("Game Over!"), _T("Attention"), MB_OK);


То сообщение нормально, без каких-либо проблем, будет выведено на экран.

Подскажите, пожалуйста, как в такой ситуации поступить? Как правильно получить указатель на окно, если AfxGetMainWnd() возвращает NULL?

Заранее, СПАСИБО!
PM MAIL ICQ Skype   Вверх
CMD
Дата 20.7.2007, 23:35 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 30
Регистрация: 1.8.2006

Репутация: 1
Всего: 1



Цитата

А вот если сделать так:
Выделить всёБез подсветки
1:
    
AfxGetMainWnd()->MessageBox(_T("Game Over!"), _T("Attention"), MB_OK);


То сообщение нормально, без каких-либо проблем, будет выведено на экран.

Функция MessageBox будет выполянться в любом случае, при любом hWnd, даже если он равен нулю.

Цитата

Я вот только не могу получить указатель на окно :( Я пытаюсь вызвать функцию AfxGetMainWnd(), однако она возвращает NULL

А как же ты его интересно создавал? Если средствами WinAPI, то при создании сам определяешь указатель на него. Лучше приведи свой код для ясности. FindWindow  найдёт окно по названию.

PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.1227 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.