Лёлик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. |
|