C++ Builder
| Главная | Уроки | Статьи | FAQ | Форум | Downloads | Литература | Ссылки | RXLib | Диски |

 
Событие закрытия ToolBar
Лёлик2
Отправлено: 22.05.2006, 10:35


Не зарегистрирован







ToolBar может перетаскиватся и встраиватся. Когда она ввиде окошка её можно закрыть кнопочкой с крестиком в правом верхнем углу. Какое событие в этот момент наступает? (нужно сбросить флажок видимости панели). Работаю в C++ Builder 6.
olegenty
Отправлено: 22.05.2006, 12:03


Ветеран

Группа: Модератор
Сообщений: 2412



мне думается, что происходит WM_SYSCOMMAND с параметром SC_CLOSE
Лёлик2
Отправлено: 23.05.2006, 20:17


Не зарегистрирован







QUOTE (olegenty @ 22/05/2006, 12:03)
мне думается, что происходит WM_SYSCOMMAND с параметром SC_CLOSE

Чесно говоря обрабатывать сообщения Windows приходится впервые.
И что-то не получается. Я написал:
В UShrift.h:
private: // User declarations
void __fastcall OnCloseToolBar(TWMSyscommand& Message);
public: // User declarations
__fastcall TForm1(TComponent* Owner);
BEGIN_MESSAGE_MAP
MESSAGE_HANDLER (WM_SYSCOMMAND,TWMSyscommand,OnCloseToolBar)
END_MESSAGE_MAP (TComponent)

};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif

Жирным выделенно то что добавил я.

В модуле UShrift.cpp:
void __fastcall TForm1::OnCloseToolBar(TWMSyscommand& a)
{
if (a.uCmdType==SC_CLOSE)Beep();
a.Result=0;
}


Вообще не компилирутся — находит 4 ошибки!!!
Что не так?
И ещё говорят надо писать так:
CODE
if ((0xFFF0 &= a.uCmdType)==SC_CLOSE)Beep();

Это правда?
Лёлик2
Отправлено: 26.05.2006, 12:49


Не зарегистрирован







Ну я понимаю что лень, что вопрос детский. Но ведь все "такими" когда-то были!
Gedeon
Отправлено: 26.05.2006, 13:01


Ветеран

Группа: Модератор
Сообщений: 1742



А поискать по форуму например по BEGIN_MESSAGE_MAP
Лёлик2
Отправлено: 26.05.2006, 22:26


Не зарегистрирован







QUOTE (Gedeon @ 26/05/2006, 13:01)
А поискать по форуму например по BEGIN_MESSAGE_MAP

Нашло два сообщения из которых одно моё. А во втором я посмотрел вроде порядок тот же что и у меня, за исключением некоторых деталей (но они и решали другую задачу), да и делал я всё по книге Архангельского — там был пример в котором я, практичекски, поменял только название сообщения, и почему не компилируется ума не приложу!
Gedeon
Отправлено: 29.05.2006, 13:43


Ветеран

Группа: Модератор
Сообщений: 1742



Ошибки кто приводить будет?
Лёлик2
Отправлено: 30.05.2006, 11:45


Не зарегистрирован







QUOTE (Gedeon @ 29/05/2006, 13:43)
Ошибки кто приводить будет?

Не понял вопрос!
Gedeon
Отправлено: 30.05.2006, 12:00


Ветеран

Группа: Модератор
Сообщений: 1742



Что компилятор говорит?
Лёлик2
Отправлено: 30.05.2006, 18:36


Не зарегистрирован







QUOTE (Gedeon @ 30/05/2006, 12:00)
Что компилятор говорит?

Ошыбка №1:
Файл UShrift.h
Красным выделена строка:
void __fastcall OnCloseToolBar(TWMSyscommand& Message);
Курсор мигает сразу после символа &
Компилятор пишет:
E2293 ) Expected

Ошыбка №2:
Файл UShrift.h
Красным выделена строка:
MESSAGE_HANDLER (WM_SYSCOMMAND,TWMSyscommand,OnCloseToolBar)
Курсор мигает сразу после первых символов ME
Компилятор пишет:
E2268 Call to undefined function 'OnCloseToolBar'

Ошыбка №3:
Файл UShrift.h
Красным выделена строка:
MESSAGE_HANDLER (WM_SYSCOMMAND,TWMSyscommand,OnCloseToolBar)
Курсор мигает сразу после первых символов ME
Компилятор пишет:
E2451 Undefined symbol 'TWMSyscommand'

Ошыбка №4:
Файл UShrift.h
Красным выделена строка:
MESSAGE_HANDLER (WM_SYSCOMMAND,TWMSyscommand,OnCloseToolBar)
Курсор мигает сразу после первых символов ME
Компилятор пишет:
E2188 Expression syntax

Ошыбка №5:
Файл UShrift.cpp
Красным выделена строка:
void __fastcall TForm1::OnCloseToolBar(TWMSyscommand& a)
Курсор мигает сразу после скобки (
Компилятор пишет:
E2147 'TWMSyscommand' cannot start a parameter declaration

Ошыбка №6:
Файл UShrift.cpp
Красным выделена строка:
{
начало блока функции void __fastcall TForm1::OnCloseToolBar(TWMSyscommand& a)
Курсор мигает сразу после скобки {
Компилятор пишет:
E2316 '__fastcall TForm1::OnCloseToolBar(int &)' is not a member of 'TForm1'

Архангельский рекомендовал в своей книге пользоватся "наворотом" New Method. Я убрал все свои предыдущие записи, открыл это диалоговое окно, ввёл в полях:
Method Name OnCloseToolBar
Add to Class TForm1
Arguments TWMSyscommand& a
Method type Function
Function Result void
Visibility Private
Directives _fastcall(4)
поставил галочку Message Handler WM_SYSCOMMAND
в поле Implementation details никаких галочек не ставил
Жму ОК.
Билдер сам добавил:
в раздел private:
void __fastcall OnCloseToolBar(TWMSyscommand& a);
в раздел protected:
BEGIN_MESSAGE_MAP
VCL_MESSAGE_HANDLER(WM_SYSCOMMAND, TWMSyscommand, OnCloseToolBar)
END_MESSAGE_MAP(TForm)

и в самом конце после слова #endif написал
void __fastcall TForm1::OnCloseToolBar(TWMSyscommand& a)
{
//TODO: Add your source code here
}

Я ничего не трогая запускаю компиляцию он находит теже ошибки в том что сам минуту назад напрограммировал!!!

В общем я в шоке!
GIZMO
Отправлено: 31.05.2006, 11:32


Машинист паровоза

Группа: Участник
Сообщений: 174



QUOTE (Лёлик2 @ 30/05/2006, 18:36)
QUOTE (Gedeon @ 30/05/2006, 12:00)
Что компилятор говорит?

Ошыбка №1:

Ошыбка №2:

Ошыбка №3:

Ошыбка №4:

Ошыбка №5:

Ошыбка №6:

//void __fastcall OnCloseToolBar(TWMSyscommand& Message);
void __fastcall OnCloseToolBar(TMessage& Message);

GIZMO
Отправлено: 31.05.2006, 11:35


Машинист паровоза

Группа: Участник
Сообщений: 174



QUOTE (GIZMO @ 31/05/2006, 11:32)
QUOTE (Лёлик2 @ 30/05/2006, 18:36)
QUOTE (Gedeon @ 30/05/2006, 12:00)
Что компилятор говорит?

Ошыбка №1:

Ошыбка №2:

Ошыбка №3:

Ошыбка №4:

Ошыбка №5:

Ошыбка №6:

//void __fastcall OnCloseToolBar(TWMSyscommand& Message);
void __fastcall OnCloseToolBar(TMessage& Message);

В догонку — есть подозрения, что с WM_SYSCOMMAND с параметром SC_CLOSE тебя пустили по ложному следу... Крестик, крестику рознь.
Guest
Отправлено: 31.05.2006, 12:35


Не зарегистрирован







Поверено, и компилится и работает
CODE

... class TForm1
...
private:
void __fastcall MyNotify (TMessage& Msg);

#pragma warn -inl
BEGIN_MESSAGE_MAP
 VCL_MESSAGE_HANDLER(WM_SYSCOMMAND, TMessage, MyNotify)
END_MESSAGE_MAP(TForm)

#pragma warn .inl

};

void __fastcall TForm1::MyNotify (TMessage& Msg)
{
Memo1->Lines->Add(
"Msg: " + IntToHex(int(Msg.Msg),      0) + " (" +
"w="    + IntToHex(int(Msg.WParam),   0) + ", " +
"ll="   + IntToHex(int(Msg.LParamLo), 0) + ", " +
"lh="   + IntToHex(int(Msg.LParamHi), 0) + ") " +
"");

TForm::Dispatch(&Msg);
}
Лёлик2
Отправлено: 31.05.2006, 16:03


Не зарегистрирован







QUOTE (Guest @ 31/05/2006, 12:35)
Поверено, и компилится и работает
CODE

... class TForm1
...
private:
void __fastcall MyNotify (TMessage& Msg);

#pragma warn -inl
BEGIN_MESSAGE_MAP
VCL_MESSAGE_HANDLER(WM_SYSCOMMAND, TMessage, MyNotify)
END_MESSAGE_MAP(TForm)

#pragma warn .inl

};

void __fastcall TForm1::MyNotify (TMessage& Msg)
{
Memo1->Lines->Add(
"Msg: " + IntToHex(int(Msg.Msg), 0) + " (" +
"w=" + IntToHex(int(Msg.WParam), 0) + ", " +
"ll=" + IntToHex(int(Msg.LParamLo), 0) + ", " +
"lh=" + IntToHex(int(Msg.LParamHi), 0) + ") " +
"");

TForm::Dispatch(&Msg);
}

Действительно компилируется! Но вот насчёт работы..., может я что-то не так сделал:
-добавил Memo1, ControlBar и на неё ToolBar;
-установил свойства ToolBar DragMode=dmAutomatic и DragKind=dkDock (на этапе проектирования)
-вставил код
В Unit1.h (привожу концовку в которую я вмешивался):
private: // User declarations
void __fastcall MyNotify (TMessage& Msg);
public: // User declarations
__fastcall TForm1(TComponent* Owner);
#pragma warn -inl
BEGIN_MESSAGE_MAP
VCL_MESSAGE_HANDLER(WM_SYSCOMMAND, TMessage, MyNotify)
END_MESSAGE_MAP(TForm)

#pragma warn .inl


};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif

В файл Unit1.cpp (сразу после конструктора формы):
void __fastcall TForm1::MyNotify (TMessage& Msg)
{
Memo1->Lines->Add(
"Msg: " + IntToHex(int(Msg.Msg), 0) + " (" +
"w=" + IntToHex(int(Msg.WParam), 0) + ", " +
"ll=" + IntToHex(int(Msg.LParamLo), 0) + ", " +
"lh=" + IntToHex(int(Msg.LParamHi), 0) + ") " +
"");

TForm::Dispatch(&Msg);
}


Результат:
Вытаскиваю ToolBar в плавающее окно, закрываю — в Memo1 новых строк не добавляется;
Пробую сворачивать-разворачивать главную форму — есть, появляются в Memo1 строки, т.е., я так понял, сообщение ловится но не то!
olegenty
Отправлено: 31.05.2006, 16:08


Ветеран

Группа: Модератор
Сообщений: 2412



так я только предполагал. вот теперь узнай, что это за событие и поставь его вместо указанного мной. главное — ты понял, как работает этот механизм.
Лёлик2
Отправлено: 31.05.2006, 22:57


Не зарегистрирован







QUOTE (olegenty @ 31/05/2006, 16:08)
так я только предполагал. вот теперь узнай, что это за событие и поставь его вместо указанного мной. главное — ты понял, как работает этот механизм.

Ну узнавать мне неоткуда. Все свои книги (а их всего две) я просмотрел перед обращением на форум.
Зашёл на сайт MSDN. Поиск ничего не дал. Зашел на форум и задал аналогичный вопрос, правда не знаю поймут ли они меня (с английским у меня не очень). В общем если там кто-то что-то вразумительное скажет я тут опубликую.

P.S. Если кто-то знает что это за чудо сообщение Windows, пишите не стесняйтесь, а то на этих американцев я особых надежд не возлагаю.
olegenty
Отправлено: 01.06.2006, 07:05


Ветеран

Группа: Модератор
Сообщений: 2412



Spy++?
Winsight?
заголовочник определения констант-идентификаторов событий?
Лёлик2
Отправлено: 01.06.2006, 15:38


Не зарегистрирован







QUOTE (olegenty @ 01/06/2006, 07:05)
Spy++?
Winsight?
заголовочник определения констант-идентификаторов событий?

Я вас опять не понял! (Что такое?). Напишите более развёрнуто свой вопрос, пожалуйста.
olegenty
Отправлено: 01.06.2006, 15:47


Ветеран

Группа: Модератор
Сообщений: 2412



посмотреть события своего приложения можно посредством Spy++, либо WinSight, затем залезть в юнит с константами WM_BASE + ... и найти там по значению интересующее событие.

Отредактировано olegenty — 01/06/2006, 16:48
Лёлик2
Отправлено: 01.06.2006, 22:07


Не зарегистрирован







QUOTE (olegenty @ 01/06/2006, 15:47)
посмотреть события своего приложения можно посредством Spy++, либо WinSight, затем залезть в юнит с константами WM_BASE + ... и найти там по значению интересующее событие.

Spy++ у меня точно нет (пользуюсь Borland C++ builder 6), а WinSight нет наверно потому что мне Билдер достался укороченный, у меня много чего нету, похоже WinSight в этом списке.
В Интернете, оказалось, скачать её неоткуда. Если она небольшого размера (до 20 Mb), поделитесь каким-то образом, пожалуйста!
AVC
Отправлено: 02.06.2006, 09:04


Ветеран

Группа: Модератор
Сообщений: 1583



QUOTE

Spy++ у меня точно нет (пользуюсь Borland C++ builder 6), а WinSight нет наверно потому что мне Билдер достался укороченный, у меня много чего нету, похоже WinSight в этом списке.

Забудьте о WinSight — "бяка"
Здесь можно закачать Spy++
Guest
Отправлено: 02.06.2006, 13:43


Не зарегистрирован







QUOTE (AVC @ 02/06/2006, 09:04)
QUOTE

Spy++ у меня точно нет (пользуюсь Borland C++ builder 6), а WinSight нет наверно потому что мне Билдер достался укороченный, у меня много чего нету, похоже WinSight в этом списке.

Забудьте о WinSight — "бяка"
Здесь можно закачать Spy++

Спасибо! Сейчас полез в Интернет за приёмами работы с SpyXX.
Лёлик2
Отправлено: 02.06.2006, 17:05


Не зарегистрирован







Нашёл! При закрытии плавающего окна посылается сообщение WM_WINDOWPOSCHANGING. Поскольку панелей у меня две и я не знаю для какой именно послано это сообщение, я собирался обрабатывать это сообщение так:
Action4->Checked=ActionToolBar1->Visible;
Action5->Checked=ToolBar1->Visible;
Но оказалось что свойство Visible панели сбрасывается на false при закрытии плавающего окна, позже того как я обрабатываю сообщение WM_WINDOWPOSCHANGING, и поэтому флажок не сбрасывается. Я посмотрел какое далее посылается сообщение, это было WM_ACTIVATE. Я вставил выше указанный код в стандартный обработчиком OnActivate главной формы, но оказалось что свойство Visible панели сбрасывается на false ещё позже! А дальше никаких сообщений уже не посылается!
В итоге добавил я таймер (выставил интервал 10 мс) в обработчике OnActivate главной формы я включаю таймер, он выполняет выше указанный код и сам себя выключает. Работает. Но я чувствую что изобрёл велосипед.
Может у кого-то есть какие нибудь предложения? А если нет, то фиг с ним, пусть так и остаётся.
В любом случае спасибо всем кто мне помагал, и в часности olegenty'y, Gedeon'y, Guest'y, AVC'y.

Вернуться в Вопросы программирования в C++Builder