Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C++ Builder > Системные сообщения


Автор: cyberstream 26.9.2006, 10:45
Hello, ALL !!! Озадачился сегодня следующим:
Создаём пункт системного меню
Код

    hSystemMenu = GetSystemMenu(Handle, false);
    AppendMenu(hSystemMenu, MF_SEPARATOR, 0, "");
    AppendMenu(hSystemMenu, MF_STRING, SC_UserItem, "&Условие задачи");
 при клике на коем вызывается 2-я форма: 
Код

void __fastcall TForm1::WMSysCommand(TWMSysCommand& Msg)
{   if (Msg.CmdType == SC_UserItem) FormTask->ShowWnd(Form1);
     DefWindowProc(Handle,WM_SYSCOMMAND,Msg.CmdType, MAKELPARAM(Msg.XPos,Msg.YPos));
  Msg.Result=0;
}
 центрируется по главному окну
Код

void __fastcall TFormTask::ShowWnd(TForm *MainForm)
{   Top=MainForm->Top+MainForm->Height/2-Height/2;
   Left=MainForm->Left+MainForm->Width/2-Width/2;
   Show();
}
 и вылазит. Деактивируясь закрывается в стиле fade
Код

void __fastcall TFormTask::FormDeactivate(TObject *Sender)
{ // SetWindowPos(Handle, HWND_TOPMOST, 0, 0, 0, 0,
    //               SWP_NOMOVE + SWP_NOSIZE);
      while (AlphaBlendValue!=0)
             AlphaBlendValue--;
//      SetWindowPos(Handle, HWND_NOTOPMOST, 0, 0, 0, 0,
  //                 SWP_NOMOVE + SWP_NOSIZE);
 Close(); }
 Закомментированные строки придавали окну во время fading статус "Поверх всех", иначе оно перекроется главным, и эффект не виден (ShowModal не использовал - не позволяет деактивировать, кликать вне окна). Если раскомментрировать, то всё идёт как надо, НО, главное окно не становится активным, кнопки не отвечают на клики, окно можно только таскать, свернуть, ... Идёт непрерывное обращение к 
Код

        BEGIN_MESSAGE_MAP
        MESSAGE_HANDLER(WM_SYSCOMMAND,TWMSysCommand,WMSysCommand);
        END_MESSAGE_MAP(TComponent); 

Где копнуть, что упустил?

Автор: Vyacheslav 26.9.2006, 12:12
Main form
Код

#include <vcl.h>
#pragma hdrstop

#include "Unit6.h"
#include "Unit7.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Form2Click(TObject *Sender)
{
    new TForm2(this)->Show();
}
//--------------------------------------------------------------------------


  
Код

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit7.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm2 *Form2;
//---------------------------------------------------------------------------
__fastcall TForm2::TForm2(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm2::FormDeactivate(TObject *Sender)
{

     while (AlphaBlendValue--);
    Close();
}
//---------------------------------------------------------------------------
void __fastcall TForm2::FormClose(TObject *Sender, TCloseAction &Action)
{
    Action = caFree;
}
//---------------------------------------------------------------------------



Автор: Vyacheslav 26.9.2006, 12:29
Виноват. Забыл указать для Form2 установить
FormStyle = fsStayOnTop(всегда по верху)
Postion = poOwnerFormCenter (по центру окна владельца)


Автор: cyberstream 27.9.2006, 16:56
Действительно, всё гениальное просто. Преогромный thanks, Vyacheslav !!   smile 

Вот только:
  1. У вас работает изящная конструкция вида 
Код

while (AlphaBlendValue--);
 ? У меня ругается 
Код

Е2369 Cannot use the result of a property assignment as an rvalue
 Обидно !!  smile 
  2.Если у формы AlphaBlend=false; (чтобы не тормозило при Resize, Move...), 
Код

void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{   AlphaBlend=true; 
    AlphaBlendValue=255;
    while (AlphaBlendValue>0)
           AlphaBlendValue--;

}
 При этом форма чернеет, и её чёрный прямоугольник fade-ится. Что за глюк? Как лечить?

Автор: dumb 27.9.2006, 17:16
Цитата(cyberstream @  27.9.2006,  16:56 Найти цитируемый пост)
AlphaBlend=true;

либо в дизайнере сделай, либо при создании формы.

Автор: Vyacheslav 27.9.2006, 17:40
Цитата(cyberstream @  27.9.2006,  16:56 Найти цитируемый пост)
У меня ругается 
Е2369 Cannot use the result of a property assignment as an rvalue

У меня тоже smile
Изящная конструкция не проходит. Так что Ваше решение более изящно, потому как работает smile 
Код

 while (AlphaBlendValue>0)
           AlphaBlendValue--;


Добавлено @ 17:43 
Цитата(cyberstream @  27.9.2006,  16:56 Найти цитируемый пост)
 При этом форма чернеет, и её чёрный прямоугольник fade-ится. Что за глюк? Как лечить?

Код

void __fastcall TForm2::FormDeactivate(TObject *Sender)
{
    AlphaBlend = true;
    Repaint();
     while(AlphaBlendValue)
     {
        AlphaBlendValue--;
     };
    Close();
}


Автор: dumb 28.9.2006, 02:24
Цитата(Vyacheslav @  27.9.2006,  17:40 Найти цитируемый пост)

Код

void __fastcall TForm2::FormDeactivate(TObject *Sender)
{
    AlphaBlend = true;
    Repaint();


так все равно заметно, как перед fade'ом мигает черным... так что лучше AlphaBlend выставлять при создании...

Автор: cyberstream 28.9.2006, 08:31
Ладно, пускай тормозит, выставим при создании.
И ещё вопрос:
Вторую форму пихаем в dll, код коего следующий
Код

void ChildFormShow()
{ TFormTask* ChildForm = new TFormTask(Application);
  ChildForm->Show();
}//=============================================================================
 Вылазит окно и кидает свою кнопку на taskbar. Куда только не пихал  smile  
Код

ShowWindow(Handle, SW_HIDE);  
Как её скрыть с панели задач? В том я направлении мыслил?

Автор: Vyacheslav 28.9.2006, 09:45
Не в том.
1)Первый вариант(не очень хороший).
Перед вызом формы из dll выполнить подмену Аpplication из dll на Application приложения. И перед выгрузкой dll выполнить замену обратно. В dll должны быть функции типа 
Код

TApplication* OldApp;
void InitApplication(TApplication* app)
{
       OldApp = Application;
        Application = app;

}
void RestoreApplication()
{
    Application = OldApp;
}


2)Второй вариант.
Собрать и dll и приложение с включенной опцией  Build with runtime package



Автор: cyberstream 3.10.2006, 15:31
Код

Второй вариант.
Собрать и dll и приложение с включенной опцией  Build with runtime package
 smile 
У меня не получается. Куда пихать вызов ShowWindow(Handle, SW_HIDE); и использовать ли его вообще? Другие варианты есть? Он не всегда работает, как хочется?

Код формы в DLL

Код

#include <vcl.h>
#pragma hdrstop
#include "TaskCode.h"
//==============================================================================
#pragma package(smart_init)
#pragma resource "*.dfm"
TFormTask *FormTask;
//TForm *MainForm;
//==============================================================================
__fastcall TFormTask::TFormTask(TComponent* Owner)
        : TForm(Owner)
{    }//========================================================================

void __fastcall TFormTask::PanelExit(TObject *Sender)
{ ActiveControl=Panel; }
//==============================================================================

void __fastcall TFormTask::FormDeactivate(TObject *Sender)
{   while (AlphaBlendValue!=0)
           AlphaBlendValue--;
    Close();
}
//==============================================================================

void __fastcall TFormTask::FormClose(TObject *Sender, TCloseAction &Action)
{  Action = caFree; }
//==============================================================================

void __fastcall TFormTask::FormShow(TObject *Sender)
{ HelpContext=1;     ShowWindow(Handle, SW_HIDE); }
//==============================================================================

void __fastcall TFormTask::FormPaint(TObject *Sender)
{   if (HelpContext)
    {  HelpContext=0;
       AlphaBlendValue=0;
       while (AlphaBlendValue!=255)
              AlphaBlendValue++;
    }
}//=============================================================================

void __fastcall TFormTask::FormMouseDown(TObject *Sender,
      TMouseButton Button, TShiftState Shift, int X, int Y)
{ if(Button == mbLeft)
  {  long SC_DRAGMOVE = 0xF012;
     ReleaseCapture();
     SendMessage(Handle, WM_SYSCOMMAND, SC_DRAGMOVE, 0);
  }
}//=============================================================================

Код DLL
Код

#include <vcl.h>
#include <windows.h>
#pragma hdrstop
#include "TaskCode.h"
#include "TaskWnd.h"
#pragma argsused
void ChildFormShow();
void InsertSysMenuItem(HWND, UINT);
//==============================================================================
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{   return 1;   }
//==============================================================================

void ChildFormShow()
{ TFormTask* ChildForm = new TFormTask(Application);
  ChildForm->Show();
}//=============================================================================

void InsertSysMenuItem(HWND handle, UINT SC_UserItem)
{  HMENU hSystemMenu;
    hSystemMenu = GetSystemMenu(handle, false);
    AppendMenu(hSystemMenu, MF_SEPARATOR, 0, "");
    AppendMenu(hSystemMenu, MF_STRING, SC_UserItem, "&Условие задачи");
}//=============================================================================


И ещё вопрос. Имеем: простое приложение, 1 форма. 
Почему не вызывается FormDeactivate при потере фокуса? Что за специфика такая непростая у этого события?
Код

#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{ }//---------------------------------------------------------------------------

void __fastcall TForm1::FormDeactivate(TObject *Sender)
{    Close();   }
//---------------------------------------------------------------------------


Автор: cyberstream 5.10.2006, 12:25
Ладно, сделаем по-другому, как в OnDeactivate, Minimize example в Builder Нelp
Код

void __fastcall TForm1::AppDeactivate(TObject *Sender)
{   Application->Minimize();   }

void __fastcall TForm1::FormCreate(TObject *Sender)
{  Application->OnDeactivate = AppDeactivate;  } 
 Но это работает, пока не запихнём в DLL. У меня упорно не хочет ничего срабатывать при Deactivate !! А если код DLL и формы в ней не компилить в DLL, а подключать по-простому - модулями, то всё нормально. Разве это нормально? Как быть? 

Если отключить rBuild with runtime package, то будет fade-иться, но не спрячется в Taskbar-e, если влючить - наоборот, не появится на панели задач, но и не захочет закрываться при потере фокуса. Как это побороть? 

Автор: cyberstream 7.10.2006, 14:50
Ребята, вы где?
У кого какие мысли есть? 
Поделитесь !!

Автор: Vyacheslav 9.10.2006, 12:43
Цитата(cyberstream @  3.10.2006,  15:31 Найти цитируемый пост)
 У меня не получается. Куда пихать вызов ShowWindow(Handle, SW_HIDE); и использовать ли его вообще? Другие варианты есть? Он не всегда работает, как хочется?

Должно получиться. Убедись, что точно экзешник и dll перестроены с данной опцией. Это весьма  известный эффект и способы его решения  стандартны
ShowWindow(Handle, SW_HIDE);  использовать не нужно.

Цитата(cyberstream @  3.10.2006,  15:31 Найти цитируемый пост)
И ещё вопрос. Имеем: простое приложение, 1 форма. 
Почему не вызывается FormDeactivate при потере фокуса? Что за специфика такая непростая у этого события?

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





Автор: cyberstream 9.10.2006, 16:57
Код

Убедись, что точно экзешник и dll перестроены с данной опцией

Убедился, да и по размеру видно, что И как было скомпилено. Сдвигов нет. 8(

Код

Это весьма  известный эффект
 Хотелось бы поподробнее! Линк например?

Код

и способы его решения  стандартны
 Подмена Аpplication-ов и runtime? Упрямятся. Ещё есть?

Код

ShowWindow(Handle, SW_HIDE);  использовать не нужно.
 То есть, если я правильно понял, 2-я форма не вывалится отдельной кнопкой на TaskBar если и dll и приложение собрать с включенной опцией Build with runtime package? Вроде так оно и происходит, если код DLL и формы в ней подключать  модулями. Как вы и указывали, безо всякого SW_HIDE. 
Но как только оформляем DLL, начинается ... Если с Build with runtime packages то 2-я кнопка появляется по-любому - и с SW_HIDE и без SW_HIDE. Зато закрывается, теряя фокус. Если компилим без runtime packages (при этом отключать Use dynamic RTL ??? ), то с подменой Аpplication-ов и с SW_HIDE 2-е окно не вылезет, но уже и не захочет прятаться при потере фокуса. Не знаю уже, что и делать! Есть подозрения, что присутствует разумное этому объяснение, вот только какое?

Автор: Vyacheslav 9.10.2006, 18:07
Не могли бы Вы прояснить следущие взаимоисключающие фразы фразы
Цитата(cyberstream @  9.10.2006,  16:57 Найти цитируемый пост)
Вроде так оно и происходит, если код DLL и формы в ней подключать  модулями


Цитата(cyberstream @  9.10.2006,  16:57 Найти цитируемый пост)
Но как только оформляем DLL, начинается ... Если с Build with runtime packages то 2-я кнопка появляется по-любому - и с 

Так появляется или не появлется?
Уверяю Вас, что у Вы что-то собираете не так.  Совершенно точно, что кнопка не появится, если собирать с включенной опцией Build with runtime. 
И разумное объяснение этому делу есть. При такой сборке на exe и dll  присутсвует один общий эксземпляр Application.
Еще раз и очень громко(чтобы все слышали) НЕ ТОЛЬКО DLL, НО И ОСНОВНОЕ ПРИЛОЖЕНИЕ ДОЛЖНО БЫТЬ СОБРАНО С BUILD WITH RUNTIME PACKAGE. 
Что бы окончательно убедиться в этом идите http://bcdev.narod.ru/Articles/dll_template.htm. Там внизу есть пример. 
К сожалению, он сразу не оттранслируется. Там прописались лишние пакеджи, которых нет у Вас.
Отредактируйте строчку, которая расположена ниже Build with runtime: уберите все, начиная с ExtAction. И оттранслировав, Вы сможите убедиться, что формыЮ загружаемые из DLL не создают лополнительных кнопок на таскбаре.
Кстати, может у Вас с этой строчкой что-то не впорядке. Например, она пустая ?






Автор: cyberstream 11.10.2006, 17:50
НЕ ТОЛЬКО DLL, НО И ОСНОВНОЕ ПРИЛОЖЕНИЕ ДОЛЖНО БЫТЬ СОБРАНО С BUILD WITH RUNTIME PACKAGE.
[/code] Так и делаю. 

Код

если код DLL и формы в ней подключать  модулями
 Т.е. если не компилировать код DLL в DLL, а подключить исходным текстом и он скомпилируется с программой в одно целое. При этом проблем не возникает. А если скомпилить DLL и подключать готовый DLL, with runtime packages кнопка появляется, а без runtime packages c подменой Application не появляется но и не закрывается при потере фокуса. А стремлюсь добиться, чтобы кнопка не появлялась, и форма закрывалась, потеряв фокус.
[code=nocolor]


Автор: Vyacheslav 11.10.2006, 18:58
Вы пример мой собрали?

Автор: cyberstream 13.10.2006, 17:39
Ваш пример собрал. Работает. Кнопка не появляется. А у меня должно было работать http://forum.vingrad.ru/index.php?showtopic=113557&view=findpost&p=875928 или определённо нет?

И как заставить форму закрываться при потере фокуса? 

Автор: FFFFFFF7 14.10.2006, 15:18
Цитата(cyberstream @  13.10.2006,  17:39 Найти цитируемый пост)
И как заставить форму закрываться при потере фокуса? 

Смотря какого... Перепеши .http://www.sysman.ru/index.php?showtopic=7056&st=0

Автор: Vyacheslav 16.10.2006, 17:58
Цитата(cyberstream @  13.10.2006,  17:39 Найти цитируемый пост)
Ваш пример собрал. Работает. Кнопка не появляется. А у меня должно было работать Код DLL и формы или определённо нет?

И как заставить форму закрываться при потере фокуса?  


Ты бы уж выложил в архиве полностью проект,  а то словами объяснять получается малоэффективно. 

Автор: cyberstream 18.10.2006, 09:42
http://ifolder.ru/295708.

Автор: Vyacheslav 18.10.2006, 11:07
Ну вот все и выяснилось. Извините, но до меня не дошло, что Вы используя dll пытаетесь линковать ее статически. Обычно dll подгружают динамически, чтобы иметь возможность модифицировать ее код, не занимаясь перекомпилированием основного приложения. 
Если Вам так уж необходимо линковать статически, то тогда уж используйте package вместо dll. Package - это dll от Borland и там все проблемы решены. Кстати при статической линковке  можно просто экспортировать класс формы и с ним работать , а не использовать функцию.
Если же надумаете использовать динамическую подгрузку dll, то я приааттачил проект с динамической подгрузкой. При работе  с ним лучше открывать не отдельные проекты, целиком группу(файл  FormInDll.bpg  )   

Автор: cyberstream 18.10.2006, 14:08
Не могу скачать ваш архив.
Код

Сообщение Форума 
Обнаружена ошибка:
Эта функция запрещена для Гостей 


Отчего так ?

Автор: Vyacheslav 18.10.2006, 14:16
Так скачивайте, зарегистрировавшись.

Автор: cyberstream 19.10.2006, 11:25
Не понимаю. Раз я выполнил вход и написал эти строки, значит я зарегестрирован? А форум так не думает. Отправьте на ящик, please.

Автор: cyberstream 25.10.2006, 14:56
Ура! Всё работает!

while (1)
{ Application->ShowMessage(" smile Thanks Vyacheslav  smile "); }

Наберу 100 постов - не забуду  smile 

Автор: Vyacheslav 25.10.2006, 15:28
Надеюсь. А то пашешь-пашешь на Вас, а Вы вырастаете и забываете smile

Автор: cyberstream 27.10.2006, 17:31
Ну... такое нам не грозит ... не скоро исчезнет с полки ваша "книга рецептов"  smile 

Автор: Vyacheslav 27.10.2006, 18:09
Поддел, все таки, зараза smile  Ну ничего, ты только спроси в будущем  что нибудь еще . Я тебе так отвечу, что потянет  на 27 постов, как здесь, на все 100  smile 

Автор: cyberstream 28.10.2006, 14:08
Вы чего ?  smile  Я ж не обидеть хотел ! Ладно, next time ни шагу от темы. 8-|

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)