Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Win Api
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 26.01.2013, 22:50   #1
grandmixer
Пользователь
 
Аватар для grandmixer
 
Регистрация: 30.10.2012
Сообщений: 31
Печаль не могу разобраться с allocatehwnd

Почему я не могу отловить ни одного сообщения? Помогите пожалуйста!!!
Код:
program prog;

uses
  windows,
  messages,
  classes;

type
  mixer = class
    FWh:HWND;
    procedure WndProc(var Msg:TMessage);
    constructor Create;
    destructor Destroy; override;
  end;

var
  GrMix:mixer;
  f:text;
  Msg:TMsg;

constructor mixer.Create;
begin
  inherited Create;
  FWh:=AllocateHwnd(WndProc);
end;

destructor mixer.Destroy;
begin
  DeAllocateHwnd(FWh);
  inherited Destroy;
end;

procedure mixer.WndProc(var Msg:TMessage);
begin
  writeln(f,msg.Msg);
end;

begin
  GrMix:=mixer.Create;
  assignfile(f,'C:/my.txt');
  rewrite(f);
  while GetMessage(Msg, 0, 0, 0) do
  begin
    TranslateMessage(Msg);
    DispatchMessage(Msg);
  end;
  close(f);
  GrMix.Destroy;
end.
grandmixer вне форума Ответить с цитированием
Старый 27.01.2013, 02:46   #2
Smogg
Участник клуба
 
Регистрация: 14.06.2011
Сообщений: 1,138
По умолчанию

Хм, дейсвитно...
Как минимум, должна выскочить ошибка на WM_CREATE при попытке писать в неоткрытый файл...
Если только Message Only Window WM_CREATE не получает.. Что вряд ли.

А как Вы сообщения для FWh посылаете?
Smogg вне форума Ответить с цитированием
Старый 27.01.2013, 03:42   #3
EUGY
Форумчанин
 
Аватар для EUGY
 
Регистрация: 11.07.2010
Сообщений: 914
По умолчанию

WM_CREATE окну конечно должно посылается, но только окно к тому моменту еще не имеет переназначенной оконной процедуры. Да и потом окно остается скрытым, какие сообщения оно будет получать?
Наверно можно убедиться так
Код:
GrMix:=mixer.Create;
ShowWindow (GrMix.FWh, SW_SHOW);
Не знаю, как именно можно в эмбракоделы студио, а классически -надо регистрировать класс окна /RegisterClass/, тогда гарантированно WM_CREATE отловится.

Последний раз редактировалось EUGY; 27.01.2013 в 03:51.
EUGY вне форума Ответить с цитированием
Старый 27.01.2013, 04:03   #4
vbilez
Пользователь
 
Регистрация: 04.02.2009
Сообщений: 13
Сообщение

что именно нужно ловить?

Код:
 
while GetMessage(Msga, 0, 0, 0) do
  begin

    TranslateMessage(Msga);
    DispatchMessage(Msga);
    assignfile(f,'C:/my.txt');
    append(f);
    writeln(f,inttostr(Msga.message));
    close(f);

  end;
vbilez вне форума Ответить с цитированием
Старый 27.01.2013, 04:11   #5
EUGY
Форумчанин
 
Аватар для EUGY
 
Регистрация: 11.07.2010
Сообщений: 914
По умолчанию

Цитата:
Сообщение от vbilez Посмотреть сообщение
что именно нужно ловить?

Код:
 
while GetMessage(Msga, 0, 0, 0) do
Далеко не все сообщения проходят через очередь.
EUGY вне форума Ответить с цитированием
Старый 27.01.2013, 06:18   #6
Smogg
Участник клуба
 
Регистрация: 14.06.2011
Сообщений: 1,138
По умолчанию

Цитата:
Сообщение от EUGY Посмотреть сообщение
WM_CREATE окну конечно должно посылается, но только окно к тому моменту еще не имеет переназначенной оконной процедуры. Да и потом окно остается скрытым, какие сообщения оно будет получать?
Как не имеет переназначенной оконной процедуры?
А зачем тогда в функцию передается она?
Наверное для того, чтобы зарегистрировать класс с нею.

// впрочем, это флуд вокруг паскаля. Я на собственном опыте убедился, что с WinApi надо работать в VS на С++. Во-первых, потому что вся документация на С, во-вторых, пототому что все дефайны в студии уже определены, а в третьих - Дельфя широко использует какие-то странные неочевидности, типа самого верхнего, но всегда невидимого окна Application..
В данном случае - непонятно, куда втыкнуть вызов GetLastError();
Все, на чем могу строить догадки - если хендель не нулевой, значит окно создано. А если нулевой? Что там за ошибка?


Код:
begin
 GrMix:=mixer.Create;

while GetMessage(Msga, 0, 0, 0) do
  begin

    TranslateMessage(Msga);
    DispatchMessage(Msga);
    assignfile(f,'C:/my.txt');
    append(f);
    writeln(f,inttostr(Msga.message));
    close(f);

  end;
end;
Смотрим логику по порядку:

1. Сначала Вы создаете окно. (тут в дебаге смотрим на вернувшийся хендл.)
2. Оконная процедура отрабатывает все инициирующие месседжи. И замолкает. (Как-то уточнить, какая именно оконная процедура отрабатывается)
3. Запускается цикл сообщений. (запустился и ждет чего-то)
4. Никаких сообщений никто нигде никому не посылает.
I.e. цикл сообщений ни разу не срабатывает.
Smogg вне форума Ответить с цитированием
Старый 27.01.2013, 07:02   #7
EUGY
Форумчанин
 
Аватар для EUGY
 
Регистрация: 11.07.2010
Сообщений: 914
По умолчанию

Цитата:
Как не имеет переназначенной оконной процедуры?
А зачем тогда в функцию передается она?
Наверное для того, чтобы зарегистрировать класс с нею.
Мне сейчас не на чем проверить, но судя по всему должно создаваться окно уже зарегистрированного класса, а потом уже идет смена процедуры.
Условно так

Код:
HWND XXAllocateHwnd(WNDPROC  proc)
{
    HWND hwnd = CreateWindow("TSomeClassWindow"....
    // DefWindowProc отрабатывает все инициирующие месседжи.

    // И только потом идет смена процедуры
    SetWindowLong (hwnd, GWL_WNDPROC, proc);

    return hwnd;
}
Цитата:
Смотрим логику по порядку:
Целиком поддерживаю Вашу логику, но смена оконной процедуры здесь идет после создания окна.

Последний раз редактировалось EUGY; 27.01.2013 в 07:05.
EUGY вне форума Ответить с цитированием
Старый 28.01.2013, 00:03   #8
Smogg
Участник клуба
 
Регистрация: 14.06.2011
Сообщений: 1,138
По умолчанию

Цитата:
Сообщение от EUGY Посмотреть сообщение
Код:
HWND XXAllocateHwnd(WNDPROC  proc)
{
    HWND hwnd = CreateWindow("TSomeClassWindow"....
    // DefWindowProc отрабатывает все инициирующие месседжи.

    // И только потом идет смена процедуры
    SetWindowLong (hwnd, GWL_WNDPROC, proc);

    return hwnd;
}
А, вон как... Да, скорее всего так и есть, зачем плодить сущности, регистрирую совершенно одинаковые классы...

Цитата:
Далеко не все сообщения проходят через очередь.
Кратенько, какие не и какие да?
Все ли сообщения из другого треда попадают в очередь? А если цикл не запущен?
Smogg вне форума Ответить с цитированием
Старый 28.01.2013, 13:39   #9
EUGY
Форумчанин
 
Аватар для EUGY
 
Регистрация: 11.07.2010
Сообщений: 914
По умолчанию

Если кратко и своими словами, то сообщения могут посылаться окну двумя способами SendMessage и PostMessage. В первом случае сообщение идет непосредственно в процедуру окна.
А во втором ставится в очередь и в процедуру окна оно попадет, только если главный цикл получит его и передаст дальше \DispatchMessage\.
Если главного цикла нет, то конечно PostMessage бесполезен.
А вообще функций для сообщений довольно много. Можно послать сообщение не окну, а просто из одного потока в другой \PostThreadMessage\. И получить его \GetMessage\.
EUGY вне форума Ответить с цитированием
Старый 28.01.2013, 20:07   #10
Smogg
Участник клуба
 
Регистрация: 14.06.2011
Сообщений: 1,138
По умолчанию

Вот почему PostMessage ничего не возвращает. Я-то раньше думал, что это просто защита от зависа чужого приложения.

А как и результат SendMessage получить и не ждать бесконечно ответа от зависшего приложения? Или Винда сама как-то это разруливает?
Smogg вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Не могу разобраться с БД Wladimir33 Microsoft Office Access 7 02.11.2012 11:41
Не могу разобраться! romanov0303 C++ Builder 1 12.03.2012 10:48
не могу разобраться navolo4ka Qt и кроссплатформенное программирование С/С++ 3 03.02.2012 14:01
не могу разобраться Var17 Общие вопросы Delphi 6 27.03.2010 01:21
НЕ МОГУ РАЗОБРАТЬСЯ... GSV84 HTML и CSS 0 03.02.2010 01:38