Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   C++ Builder (https://www.clubdelphi.com/foros/forumdisplay.php?f=13)
-   -   Gestionar el evento OnMouseMove de la barra de titulo del Form (https://www.clubdelphi.com/foros/showthread.php?t=89224)

aguml 19-10-2015 13:50:23

Gestionar el evento OnMouseMove de la barra de titulo del Form
 
Hola amigos, estoy investigando un poco como funcionan las ventanas MDI y que desconocia que hacian y las veo muy utiles pero ahora tengo un par de dudas. He hecho que pueda arrastar el form MDIChild y gestionando los eventos OnMouseMove, OnMouseDown, y OnMouseUp controlo para que la ventana no se pueda salir del form que la contiene, o sea, salirse no se puede salir pero me refiero a que no se pueda salir de la zona visible. Ahora me gustaria hacer lo mismo pero en este caso arrastrando la barra de titulo del form hijo y no veo la manera de controlar esos eventos en la barra de titulo. Imagino que iran por aqui pero cambiando alguna cosa: http://www.clubdelphi.com/foros/show...oton+minimizar
La otra duda es que con mi codigo controlo que el form hijo no se pueda salir pero aun asi si mueves el raton muy rapido llega a salirse un poquito aunque lo arreglo en el evento OnMouseUp pero mientras arrastro me muestra los Scrolls del form padre y me gustaria saber si hay alguna manera de hacer que estos no aparezcan aunque me salga ya que no se ve bien.
¿podeis ayudarme?

escafandra 19-10-2015 14:43:11

Maneja el mensaje WM_MOVING. En este hilo tienes un ejemplo en delphi.

Saludos.

aguml 19-10-2015 19:11:55

Lo siento pero me pierdo porque no tengo ni idea de delphi y aunque se parece pero me pierdo. Ahora mismo tengo esto:
En el .h:
Código PHP:

private:    // User declarations
   
void __fastcall WMSysCommand(TWMSysCommand &Msg);
protected:
  
BEGIN_MESSAGE_MAP
  VCL_MESSAGE_HANDLER
(WM_SYSCOMMANDTWMSysCommandWMSysCommand)
  
END_MESSAGE_MAP(TForm

En el .cpp:
Código PHP:

void __fastcall TFormHijo::WMSysCommand(TWMSysCommand &Msg)
{
   switch (
Msg.CmdType) {
      case 
SC_MOVE:
         
ShowMessage("Moviendo Form");
         break;
   }
   
DefaultHandler(&Msg);


Me interesaria mucho tu codigo pero para c++builder ya que antes de lo que estoy haciendo estuve intentando lo mismo que tu haces en tu codigo y lo consegui a medias.

escafandra 19-10-2015 19:44:20

Estas manejando el mensaje WM_SYSCOMMAND y debes manejar WM_MOVING en la ventana child que se está moviendo. Este mensaje se produce antes de que el movimiento de ejectue, por lo que podrás evitar salirte del límite sin el efecto que comentabas más arriba, al mover deprisa el ratón.

Cita:

Empezado por msdn
lParam
A pointer to a RECT structure with the current position of the window, in screen coordinates. To change the position of the drag rectangle, an application must change the members of this structure.

Ahora no puedo ponerte un ejemplo en Builder cuando llegue a casa, si puedo, te lo pongo.

Saludos.

aguml 19-10-2015 21:17:48

Ok muchísimas gracias. Intentare seguir probando a ver que consigo pero la verdad es que el que no sabe es como el que no ve y voy dando palos de ciego.

escafandra 19-10-2015 23:23:38

Ejemplo simple reescribiendo la función virtual WndProc de un formulario:

Código PHP:

#include <Forms.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:    // IDE-managed Components
private:    // User declarations
protected:
  
virtual void __fastcall WndProc(TMessagemsg);
public:        
// User declarations
  
__fastcall TForm1(TComponentOwner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif 

Código PHP:

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

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponentOwner)
  : 
TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::WndProc(TMessagemsg)
{
  if(
msg.Msg == WM_MOVING){
    
TRect *= (TRect*)msg.LParam;
    if(
R->Left 50){
      
R->Left 50;
      
R->Right Left Width;
    }
  }
  
TForm::WndProc(msg);


Este ejemplo impide desplazar el formulario a la izquierda más allá del valor 50.


Saludos.

aguml 20-10-2015 09:22:27

Muy bien, guiandome de tu codigo y de otro que encontré por la red en ruso pude sacar este codigo:
En el .h
Código PHP:

private:    // User declarations
   
void __fastcall CatchDrag(TMessage &Msg);
protected:
  
BEGIN_MESSAGE_MAP
  VCL_MESSAGE_HANDLER
(WM_MOVINGTMessageCatchDrag);
  
END_MESSAGE_MAP(TForm

En el .cpp:
Código PHP:

void __fastcall TFormHijo::CatchDrag(TMessage &Msg)
{
   
TForm::Dispatch(&Msg);
   if(
Msg.Msg == WM_MOVING){
      
PRECT pCurrentRec PRECT(Msg.LParam);

      
//El 5 creo que es por los bordes de la ventana padre
      
if(pCurrentRec->left FormPadre->Left 5){
         
pCurrentRec->left FormPadre->Left 5;
         
pCurrentRec->right Left Width 5;
      }else if(
pCurrentRec->right FormPadre->Left FormPadre->Width 5){
         
pCurrentRec->left FormPadre->Left + (FormPadre->Left FormPadre->Width - (Left Width) - 5);
         
pCurrentRec->right FormPadre->Left FormPadre->Width 5;
      }
      
//Tengo un Panel alineado arriba y el 32 creo que es porque es lo que mide
      //barra de titulo de la ventana padre
      
if(pCurrentRec->top FormPadre->Top FormPadre->Panel->Height 32){
         
pCurrentRec->top FormPadre->Top FormPadre->Panel->Height 32;
         
pCurrentRec->bottom Top Height 32;
      }else if(
pCurrentRec->bottom FormPadre->Top FormPadre->Height 5){
         
pCurrentRec->top FormPadre->Top + (FormPadre->Top FormPadre->Height - (Top Height)) - 5;
         
pCurrentRec->bottom FormPadre->Top FormPadre->Height 5;
      }
      
Caption "LeftBeforeMove: " IntToStr(pCurrentRec->left) +
                
"  TopBeforeMove: " IntToStr(pCurrentRec->top);
   }


El problema que tengo es que me redimensiona la ventana hija y no veo la manera de solucionarlo. O sea que no me respeta el tamaño que tenia la ventana hija y es porque algo hago mal al darle el right y el bottom.

aguml 20-10-2015 10:26:17

He intentado editar el mensaje anterior pero he llegado tarde por muy poquito y ya no me dejaba asi que lo pongo aqui. Ya he conseguido hacerlo. Al final coji papel y lapiz y lo plantee sobre el papel y me di cuenta de los fallos y asi quedó:
En el .h:
Código PHP:

private:    // User declarations
   //Necesarias para arrastrar la imagen por el ScrollBox
   
void __fastcall CatchDrag(TMessage &Msg);
protected:
  
BEGIN_MESSAGE_MAP
  VCL_MESSAGE_HANDLER
(WM_MOVINGTMessageCatchDrag);
  
END_MESSAGE_MAP(TForm

En el .cpp:
Código PHP:

void __fastcall TFormHijo::CatchDrag(TMessage &Msg)
{
   
TForm::Dispatch(&Msg);
   if(
Msg.Msg == WM_MOVING){
      
PRECT pCurrentRec PRECT(Msg.LParam);

      
//El 5 creo que es por los bordes de la ventana padre
      
if(pCurrentRec->left FormPadre->Left 5){
         
pCurrentRec->left FormPadre->Left 5;
         
pCurrentRec->right FormPadre->Left Width 5;
      }else if(
pCurrentRec->right FormPadre->Left FormPadre->Width 5){
         
pCurrentRec->left FormPadre->Left FormPadre->Width Width 5;
         
pCurrentRec->right FormPadre->Left FormPadre->Width 5;
      }
      
//Tengo un Panel alineado arriba y el 32 creo que es porque es lo que mide
      //barra de titulo de la ventana padre
      
if(pCurrentRec->top FormPadre->Top FormPadre->Panel->Height 32){
         
pCurrentRec->top FormPadre->Top FormPadre->Panel->Height 32;
         
pCurrentRec->bottom FormPadre->Top FormPadre->Panel->Height Height 32;
      }else if(
pCurrentRec->bottom FormPadre->Top FormPadre->Height 5){
         
pCurrentRec->top FormPadre->Top FormPadre->Height Height 5;
         
pCurrentRec->bottom FormPadre->Top FormPadre->Height 5;
      }
      
Caption "LeftBeforeMove: " IntToStr(pCurrentRec->left) +
                
"  TopBeforeMove: " IntToStr(pCurrentRec->top);
   }


La verdad es que ahora me gustaria meterme con el codigo que hiciste en delphi que con el uso de las MDI lo veo poco util pero muy interesante y me ha picado el gusanillo y quiero pasarlo a C++Builder para entender su funcionamiento. Muchas gracias por todo.

escafandra 21-10-2015 17:52:43

Pues la traducción del ejemplo que te puse al sistema de tratamiento de mensajes tipo delphi sería esta:
Código PHP:

#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
//---------------------------------------------------------------------------
struct TWMMoving{
  
DWORD Msg;
  
int   Edge;
  
PRect DragRect;
};

class 
TForm2 : public TForm
{
__published:    // IDE-managed Components
private:
  
__fastcall WMMoving(TWMMoving &Message);
public:        
// User declarations
  
__fastcall TForm2(TComponentOwner);

BEGIN_MESSAGE_MAP
  VCL_MESSAGE_HANDLER
(WM_MOVINGTWMMovingWMMoving)
END_MESSAGE_MAP(TForm)
};
//---------------------------------------------------------------------------
extern PACKAGE TForm2 *Form2;
//---------------------------------------------------------------------------
#endif 

Código PHP:

#include "Unit2.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm2 *Form2;


//---------------------------------------------------------------------------
__fastcall TForm2::TForm2(TComponentOwner)
  : 
TForm(Owner)
{
}
//---------------------------------------------------------------------------

__fastcall TForm2::WMMoving(TWMMoving &Message)
{
  if(
Message.DragRect->Left 50){
    
Message.DragRect->Left 50;
    
Message.DragRect->Right Left Width;
  }


Saludos.

aguml 21-10-2015 22:05:25

Ok muchas gracias. Seguiré investigando.


La franja horaria es GMT +2. Ahora son las 22:29:30.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi