LOCK SYSMENU IN WINDOW

You can share your experience with HMG. Share with some screenshots/project details so that others will also be benefited.

Moderator: Rathinagiri

User avatar
srvet_claudio
Posts: 2193
Joined: Thu Feb 25, 2010 8:43 pm
Location: Uruguay
Contact:

LOCK SYSMENU IN WINDOW

Post by srvet_claudio »

Hola a todos,
en un post anterior se pidió como evitar el movimiento de una ventana.
jparada wrote:Is there any way (or trick) to prevent a user can not move a window by clicking on the title bar of the window (I hope I've explained).
Para ello varios de nosotros propusimos algunas formas,
viewtopic.php?p=9294&sid=4a2a85bc2346e7 ... 18ca#p9294
pero los resultados finales no resultaron del todo satisfactorio, por ejemplo, no se pudo evitar
que el usuario arrastrara la ventana con el mouse, auque al soltarla esta vovia al lugar, lo mismo sucedia con el boton de maximizar.

A pesar que la mayoria no le gusto la idea de tener una ventana fija en el monitor, no deja de ser un buen ejercicio de programacion
intentar hacerlo.

Yo intente ir un poco mas lejos, y desarrolle algunas funciones que permiten bloquear las acciones del menu del sistema de una ventana determinada, con lo cual
elimina los inconvenientes que tenian las soluciones anteriormente propuestas.


*****************************************************************************************************************
* DESCRIPCION:
*
* Bloquea o Desbloquea los comandos del menu del sistema (MOVE, SIZE, RESTORE, MAXIMIZE, MINIMIZE, CLOSE)
*
* de una determinada ventana al interceptar los mensajes WM_SYSCOMMAND que el sistema le envia a dicha ventana
*
* Con estas funciones se pueden evitar que el usuario mueva, cambie de tamaño, maximize, minimize, restablezca
*
* y/o cierre una ventana con el menu del sistema o con los botones del sistema en tiempo de ejecución.
*
*****************************************************************************************************************

*****************************************************************************************************************
* SINTAXIS:
*
* Definiciones de ID_n:
*
* #define ID_MOVE 1
* #define ID_SIZE 2
* #define ID_RESTORE 3
* #define ID_MAXIMIZE 4
* #define ID_MINIMIZE 5
* #define ID_CLOSE 6
* #define ID_ALL 7
*
* IS_SYSMENU_LOCK (WinName, ID_n)
* //Retorna .T. si ID_n de la ventana WinName esta bloqueado (LOCK)
* //Retorna .F. si ID_n de la ventana WinName esta desbloqueado (UNLOCK)
*
* LOCK SYSMENU IN WINDOW <WinName> ALL //Bloquea todos los ID_n de la ventana WinName
* UNLOCK SYSMENU IN WINDOW <WinName> ALL //Desbloquea todos los ID_n de la ventana WinName
*
* LOCK SYSMENU IN WINDOW <WinName> [MOVE] [SIZE] [RESTORE] [MAXIMIZE] [MINIMIZE] [CLOSE]
* // Bloquea solo los parametros especificados y
* // automaticamente desbloquea los no especificados
*******************************************************************************************************


La solucion definitiva al pedido de Jparada seria:

Code: Select all

LOCK SYSMENU IN WINDOW "Form_1"  MAXIMIZE MOVE SIZE
El funcionamiento de estos comandos es muy sencillo:
toda ventana tiene asociado un procedimiento (funcion definida por el usuario, genericamente denominada WndProc) que recibe y procesa los mensajes que el sistema
le envia a dicha ventana, yo lo que ago es sustituir el WndProc original por uno nuevo que filtra los mensajes que recibe la ventana, si son mensajes generado
por el accionar del menu del sistema de la ventana (WM_SYSCOMMAND) yo los proceso si corresponde, de lo contrario le paso los mensajes al WndProc original para
que el los procese. En definitiva lo encadeno al WndProc nuevo el WndProc original.


Con estas funciones se pueden evitar que el usuario mueva, cambie de tamaño, maximize, minimize, restablezca y/o cierre una ventana con el menu del sistema o
con los botones del sistema en tiempo de ejecucion.
Obviamente que la mayoria de estas acciones ya estan implementadas al definir una ventana, pero estan disponibles solo en tiempo de definición.
Aqui les dejo el codigo fuente, espero que les sirva para algo.

Saludos a todos,
Claudio Soto

Code: Select all

*****************************************************************************************************************
* PROGRAMA: LOCK SYSMENU IN WINDOW
* LENGUAJE: HARBOUR-MINIGUI 3.0.27
* FECHA:    9 ABRIL 2010
* AUTOR:    Dr. CLAUDIO SOTO
* PAIS:     URUGUAY
* E-MAIL:   srvet@adinet.com.uy
*****************************************************************************************************************

*****************************************************************************************************************
* DESCRIPCION:
*
* Bloquea o Desbloquea los comandos del menu del sistema (MOVE, SIZE, RESTORE, MAXIMIZE, MINIMIZE, CLOSE)
* de una determinada ventana al interceptar los mensajes WM_SYSCOMMAND que el sistema le envia a dicha ventana
*
* Con estas funciones se pueden evitar que el usuario mueva, cambie de tamaño, maximize, minimize, restablezca 
* y/o cierre una ventana con el menu del sistema o con los botones del sistema en tiempo de ejecucion. 
*****************************************************************************************************************

*****************************************************************************************************************
* SINTAXIS:
*
* Definiciones de ID_n:
*
* #define ID_MOVE      1
* #define ID_SIZE      2
* #define ID_RESTORE   3
* #define ID_MAXIMIZE  4
* #define ID_MINIMIZE  5
* #define ID_CLOSE     6
* #define ID_ALL       7
*
* IS_SYSMENU_LOCK (WinName, ID_n)    //Retorna .T. si ID_n de la ventana WinName esta bloqueado (LOCK)
*                                    //Retorna .F. si ID_n de la ventana WinName esta desbloqueado (UNLOCK)
*
* LOCK   SYSMENU IN WINDOW <WinName> ALL        //Bloquea todos los ID_n de la ventana WinName
* UNLOCK SYSMENU IN WINDOW <WinName> ALL        //Desbloquea todos los ID_n de la ventana WinName
* 
* LOCK SYSMENU IN WINDOW <WinName> [MOVE] [SIZE] [RESTORE] [MAXIMIZE] [MINIMIZE] [CLOSE]
*                                               // Bloquea solo los parametros especificados y
*                                               // automaticamente desbloquea los no especificados
*******************************************************************************************************


*******************************************************************************************************
* DEFINICION DE LOS COMANDOS
*******************************************************************************************************
#define ID_MOVE      1
#define ID_SIZE      2
#define ID_RESTORE   3
#define ID_MAXIMIZE  4
#define ID_MINIMIZE  5
#define ID_CLOSE     6
#define ID_ALL       7

#command LOCK SYSMENU IN WINDOW <WinName> ALL;
         => LOCK_SYSMENU_WIN (<WinName>,.T.,.T.,.T.,.T.,.T.,.T.)

#command UNLOCK SYSMENU IN WINDOW <WinName> ALL;
         => LOCK_SYSMENU_WIN (<WinName>,.F.,.F.,.F.,.F.,.F.,.F.)

#command LOCK SYSMENU IN WINDOW <WinName> [<mov: MOVE>] [<siz: SIZE>] [<res: RESTORE>] [<max: MAXIMIZE>] [<min: MINIMIZE>] [<clo: CLOSE>];
         => LOCK_SYSMENU_WIN (<WinName>, <.mov.>, <.siz.>, <.res.>, <.max.>, <.min.>, <.clo.>)
         
//       IS_SYSMENU_LOCK (WinName, ID_n)
******************************************************************************************************


#include "minigui.ch"

Function Main

	DEFINE WINDOW Form_1 ;
		AT 0,0 ;
		WIDTH 400 ;
		HEIGHT 500 ;
		TITLE 'LOCK SYSMENU IN WINDOW' ;
		MAIN
        
        
        DEFINE MAIN MENU
               DEFINE POPUP '&Lock'
                  ITEM "Lock: MOVE + SIZE"             ACTION accion (3)
                  ITEM "Lock: MINIMIZE + MAXIMIZE"     ACTION accion (4)
                  ITEM "Lock: MOVE + SIZE + MAXIMIZE"  ACTION accion (5)
                  ITEM "Lock: MOVE + SIZE + MAXIMIZE + MINIMIZE"  ACTION accion (6)
               END POPUP  
        END MENU

        
        @ 50, 100 BUTTON boton_1 CAPTION "LOCK ALL"         ACTION accion (1)
        @ 50, 250 BUTTON boton_2 CAPTION "UNLOCK ALL"       ACTION accion (2)
       
        @ 150, 100 LABEL label_1 AUTOSIZE BOLD
        @ 175, 100 LABEL label_2 AUTOSIZE BOLD
        @ 200, 100 LABEL label_3 AUTOSIZE BOLD
        @ 225, 100 LABEL label_4 AUTOSIZE BOLD
        @ 250, 100 LABEL label_5 AUTOSIZE BOLD
        @ 275, 100 LABEL label_6 AUTOSIZE BOLD
        @ 100, 100 LABEL label_7 AUTOSIZE BOLD
       
	
	    @ 350, 100 BUTTON boton_3 CAPTION "Lock All win2"    ACTION vent2 (1)
        @ 350, 250 BUTTON boton_4 CAPTION "Unlock All win2"  ACTION vent2 (2)        
      
		
	    accion (0)
	
	END WINDOW
   
	Form_1.Center 
	Form_1.Activate
Return


Procedure accion (n)
    DO CASE
       CASE n = 1
          LOCK SYSMENU IN WINDOW "Form_1" ALL
       CASE n = 2
          UNLOCK SYSMENU IN WINDOW "Form_1" ALL
       CASE n = 3
          LOCK SYSMENU IN WINDOW "Form_1"  MOVE SIZE
       CASE n = 4
          LOCK SYSMENU IN WINDOW "Form_1"  MINIMIZE MAXIMIZE   
       CASE n = 5   
          LOCK SYSMENU IN WINDOW "Form_1"  MAXIMIZE MOVE SIZE
       CASE n = 6
          LOCK SYSMENU IN WINDOW "Form_1"  MAXIMIZE MOVE SIZE MINIMIZE
    END CASE   
    
    Form_1.Label_1.Value := "Lock MOVE:      " +IF (IS_SYSMENU_LOCK ("Form_1", ID_MOVE),"True","False")
    Form_1.Label_2.Value := "Lock SIZE:      " +IF (IS_SYSMENU_LOCK ("Form_1", ID_SIZE),"True","False")
    Form_1.Label_3.Value := "Lock RESTORE:   " +IF (IS_SYSMENU_LOCK ("Form_1", ID_RESTORE),"True","False")
    Form_1.Label_4.Value := "Lock MAXIMIZE:  " +IF (IS_SYSMENU_LOCK ("Form_1", ID_MAXIMIZE),"True","False")
    Form_1.Label_5.Value := "Lock MINIMIZE:  " +IF (IS_SYSMENU_LOCK ("Form_1", ID_MINIMIZE),"True","False")
    Form_1.Label_6.Value := "Lock CLOSE:     " +IF (IS_SYSMENU_LOCK ("Form_1", ID_CLOSE),"True","False")
    Form_1.Label_7.Value := "Lock ALL:       " +IF (IS_SYSMENU_LOCK ("Form_1", ID_ALL),"True","False")
    
    Form_1.Label_1.FontColor  := IF (IS_SYSMENU_LOCK ("Form_1", ID_MOVE),RED,BLUE)
    Form_1.Label_2.FontColor  := IF (IS_SYSMENU_LOCK ("Form_1", ID_SIZE),RED,BLUE)
    Form_1.Label_3.FontColor  := IF (IS_SYSMENU_LOCK ("Form_1", ID_RESTORE),RED,BLUE)
    Form_1.Label_4.FontColor  := IF (IS_SYSMENU_LOCK ("Form_1", ID_MAXIMIZE),RED,BLUE)
    Form_1.Label_5.FontColor  := IF (IS_SYSMENU_LOCK ("Form_1", ID_MINIMIZE),RED,BLUE)
    Form_1.Label_6.FontColor  := IF (IS_SYSMENU_LOCK ("Form_1", ID_CLOSE),RED,BLUE)
    Form_1.Label_7.FontColor  := IF (IS_SYSMENU_LOCK ("Form_1", ID_ALL),RED,BLUE)
Return

Procedure vent2 (n)
    
   IF IsWindowDefined (Form_2) = .F. 
      DEFINE WINDOW Form_2 ;
	  	  AT 100,100 ;
		  WIDTH 200 ;
		  HEIGHT 300 ;
		  TITLE 'Win 2';
		  CHILD
		
		  @ 10, 10 LABEL label_8 AUTOSIZE BOLD

	  END WINDOW
   END	
   
   IF n = 1
      LOCK SYSMENU IN WINDOW "Form_2" ALL
   ELSE
      UNLOCK SYSMENU IN WINDOW "Form_2" ALL
   ENDIF
   
   Form_2.Label_8.Value := "Lock ALL Win 2:  " +IF (IS_SYSMENU_LOCK ("Form_2", ID_ALL),"True","False")
   Form_2.Label_8.FontColor  := IF (IS_SYSMENU_LOCK ("Form_2", ID_ALL),RED,BLUE)
   
   IF IsWindowActive (Form_2) = .F. 
      Form_2.activate
   ENDIF   
   
Return


*#########################################################################################################################
*   IMPLEMENTACION DE LAS FUNCIONES        
*#########################################################################################################################

#define ID_MOVE      1
#define ID_SIZE      2
#define ID_RESTORE   3
#define ID_MAXIMIZE  4
#define ID_MINIMIZE  5
#define ID_CLOSE     6
#define ID_ALL       7


Function IS_SYSMENU_LOCK (WinName, ID_n)
  DO CASE
     CASE ID_n = ID_MOVE
          Return IS_CHECK_ARRAY (GetFormHandle (WinName), ID_MOVE)      
     CASE ID_n = ID_SIZE      
          Return IS_CHECK_ARRAY (GetFormHandle (WinName), ID_SIZE)
     CASE ID_n = ID_RESTORE   
          Return IS_CHECK_ARRAY (GetFormHandle (WinName), ID_RESTORE)
     CASE ID_n = ID_MAXIMIZE  
          Return IS_CHECK_ARRAY (GetFormHandle (WinName), ID_MAXIMIZE)
     CASE ID_n = ID_MINIMIZE  
          Return IS_CHECK_ARRAY (GetFormHandle (WinName), ID_MINIMIZE)
     CASE ID_n = ID_CLOSE     
          Return IS_CHECK_ARRAY (GetFormHandle (WinName), ID_CLOSE)
     CASE ID_n = ID_ALL       
          IF  IS_CHECK_ARRAY (GetFormHandle (WinName), ID_MOVE)     .AND.;
              IS_CHECK_ARRAY (GetFormHandle (WinName), ID_SIZE)     .AND.; 
              IS_CHECK_ARRAY (GetFormHandle (WinName), ID_RESTORE)  .AND.;
              IS_CHECK_ARRAY (GetFormHandle (WinName), ID_MAXIMIZE) .AND.;
              IS_CHECK_ARRAY (GetFormHandle (WinName), ID_MINIMIZE) .AND.;
              IS_CHECK_ARRAY (GetFormHandle (WinName), ID_CLOSE)  
             Return .T.
          ELSE
             Return .F.   
          ENDIF               
  END CASE
Return .F.


Procedure LOCK_SYSMENU_WIN (WinName, MOVE, SIZE, RESTORE, MAXIMIZE, MINIMIZE, CLOSE, ALL) 
  IF ALL = .T.
     SET_ARRAY_DATOS (GetFormHandle (WinName),.T.,.T.,.T.,.T.,.T.,.T.)
  ELSE
     SET_ARRAY_DATOS (GetFormHandle (WinName), MOVE, SIZE, RESTORE, MAXIMIZE, MINIMIZE, CLOSE)
  ENDIF    
Return


Procedure UNLOCK_SYSMENU_WIN (WinName)
  SET_ARRAY_DATOS (GetFormHandle (WinName),.F.,.F.,.F.,.F.,.F.,.F.)
Return


*#########################################################################################################################
*   FUNCIONES EN C        
*#########################################################################################################################

#pragma begindump

#include <windows.h>

#include "hbapi.h"
#include "hbapiitm.h"


 LONG GetArray_Old_WndProc (HWND hWnd);  
 LRESULT CALLBACK WndProc_PIRATA (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
 WNDPROC p_WndProc_old;

 
 BOOL flag = FALSE;
 INT  cont = 0;
 PHB_ITEM pArray_HWND;
 PHB_ITEM pArray_MOVE;
 PHB_ITEM pArray_SIZE;
 PHB_ITEM pArray_RESTORE;
 PHB_ITEM pArray_MAXIMIZE;
 PHB_ITEM pArray_MINIMIZE;
 PHB_ITEM pArray_CLOSE;
 PHB_ITEM pArray_Old_WndProc; 

  
HB_FUNC (SET_ARRAY_DATOS)
{  int i;
   HWND hWND;
   
   
   // Si no existe crea la matriz que contiene los datos de las ventanas
   if (flag == FALSE)
   {   flag = TRUE;
       cont = 0;
       
       pArray_HWND     = hb_itemNew (NULL);
       pArray_MOVE     = hb_itemNew (NULL);
       pArray_SIZE     = hb_itemNew (NULL);
       pArray_RESTORE  = hb_itemNew (NULL);
       pArray_MAXIMIZE = hb_itemNew (NULL);
       pArray_MINIMIZE = hb_itemNew (NULL);
       pArray_CLOSE    = hb_itemNew (NULL);
       pArray_Old_WndProc = hb_itemNew (NULL);
                
       hb_arrayNew (pArray_HWND,     0);
       hb_arrayNew (pArray_MOVE,     0);
       hb_arrayNew (pArray_SIZE,     0);
       hb_arrayNew (pArray_RESTORE,  0);
       hb_arrayNew (pArray_MAXIMIZE, 0);
       hb_arrayNew (pArray_MINIMIZE, 0);
       hb_arrayNew (pArray_CLOSE,    0);
       hb_arrayNew (pArray_Old_WndProc,    0);
   }
   
   
   // Verifica si la ventana ya esta registrada y cambia el valor de los datos
   for (i=1; i <= cont; i++)
   {    if (hb_arrayGetNL (pArray_HWND, i) == hb_parnl (1)) 
        {  
            //hb_arraySetNL(pArray_HWND,     i, hb_parnl (1));
            hb_arraySetL (pArray_MOVE,       i, hb_parl  (2));
            hb_arraySetL (pArray_SIZE,       i, hb_parl  (3));
            hb_arraySetL (pArray_RESTORE,    i, hb_parl  (4));
            hb_arraySetL (pArray_MAXIMIZE,   i, hb_parl  (5));
            hb_arraySetL (pArray_MINIMIZE,   i, hb_parl  (6));
            hb_arraySetL (pArray_CLOSE,      i, hb_parl  (7));           
            return;
        }
   }       
   
   // Al no estar la ventana registrada, adiciona un elemento a la matriz y le agrega los datos
   cont++;
   hb_arraySize (pArray_HWND,     cont);
   hb_arraySize (pArray_MOVE,     cont);
   hb_arraySize (pArray_SIZE,     cont);
   hb_arraySize (pArray_RESTORE,  cont);
   hb_arraySize (pArray_MAXIMIZE, cont);
   hb_arraySize (pArray_MINIMIZE, cont);
   hb_arraySize (pArray_CLOSE,    cont);
   hb_arraySize (pArray_Old_WndProc,    cont);

   hb_arraySetNL(pArray_HWND,     cont, hb_parnl (1));
   hb_arraySetL (pArray_MOVE,     cont, hb_parl  (2));
   hb_arraySetL (pArray_SIZE,     cont, hb_parl  (3));
   hb_arraySetL (pArray_RESTORE,  cont, hb_parl  (4));
   hb_arraySetL (pArray_MAXIMIZE, cont, hb_parl  (5));
   hb_arraySetL (pArray_MINIMIZE, cont, hb_parl  (6));
   hb_arraySetL (pArray_CLOSE,    cont, hb_parl  (7));

   
   // Cambia el procedimiento de ventana original por WndProc_PIRATA, quien a su vez luego
   // de procesar WM_SYSCOMMAND engancha (llama) al procedimiento original
     
   hWND = (HWND) hb_parnl (1); 
   p_WndProc_old = (WNDPROC) SetWindowLongPtr(hWND, GWLP_WNDPROC, (LONG_PTR) WndProc_PIRATA);
   hb_arraySetNL (pArray_Old_WndProc, cont, (LONG) p_WndProc_old);
   
      
  // InvalidateRect(hWND, NULL, TRUE);
  // UpdateWindow(hWND);

}

#define ID_MOVE      1
#define ID_SIZE      2
#define ID_RESTORE   3
#define ID_MAXIMIZE  4
#define ID_MINIMIZE  5
#define ID_CLOSE     6

BOOL CheckArray (HWND hWND, int ID)
{  int i;

   // Verifica si la ventana ya esta registrada y devuelve el valor de los datos
   for (i=1; i <= cont; i++)
   {    if ((HWND) hb_arrayGetNL (pArray_HWND, i) == hWND) 
        {               
            switch (ID)
	        {
                    case ID_MOVE:
                         return hb_arrayGetL(pArray_MOVE, i);
                    case ID_SIZE:
                         return hb_arrayGetL(pArray_SIZE, i);
                    case ID_RESTORE:
                         return hb_arrayGetL(pArray_RESTORE, i);
                    case ID_MAXIMIZE:
                         return hb_arrayGetL(pArray_MAXIMIZE, i);
                    case ID_MINIMIZE:
                         return hb_arrayGetL(pArray_MINIMIZE, i);
                    case ID_CLOSE:
                         return hb_arrayGetL(pArray_CLOSE, i);
                    default:
                         return FALSE;
            }
                       
        }
   }       
 return FALSE;  
}


HB_FUNC (IS_CHECK_ARRAY)
{  hb_retl (CheckArray ((HWND) hb_parnl (1), hb_parni (2)));
}


LONG GetArray_Old_WndProc (HWND hWnd)
{  int i;

   // Busca la ventana  y devuelve el WndProc original
   for (i=1; i <= cont; i++)
   {    if ((HWND) hb_arrayGetNL (pArray_HWND, i) == hWnd)
            return (LONG) hb_arrayGetNL (pArray_Old_WndProc, i); 
   }
   return NULL;
}


LRESULT CALLBACK WndProc_PIRATA (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{   
    if (message == WM_SYSCOMMAND)
    {           
                     
        if ((wParam & 0xFFF0) == SC_MOVE && CheckArray (hWnd, ID_MOVE))
             return 0; 
        
        if ((wParam & 0xFFF0) == SC_SIZE && CheckArray (hWnd, ID_SIZE))
             return 0; 
        
        if ((wParam & 0xFFF0) == SC_RESTORE && CheckArray (hWnd, ID_RESTORE))
             return 0; 
        
        if ((wParam & 0xFFF0) == SC_MAXIMIZE && CheckArray (hWnd, ID_MAXIMIZE))
             return 0; 

        if ((wParam & 0xFFF0) == SC_MINIMIZE && CheckArray (hWnd, ID_MINIMIZE))
             return 0; 
        
        if ((wParam & 0xFFF0) == SC_CLOSE && CheckArray (hWnd, ID_CLOSE))
             return 0; 
        
     }
      
      p_WndProc_old = (WNDPROC) GetArray_Old_WndProc (hWnd);  
      return CallWindowProc(p_WndProc_old, hWnd, message, wParam, lParam);
}


#pragma enddump


Best regards.
Dr. Claudio Soto
(from Uruguay)
http://srvet.blogspot.com
jparada
Posts: 430
Joined: Fri Jan 23, 2009 5:18 pm

Re: LOCK SYSMENU IN WINDOW

Post by jparada »

Hola Claudio,

Gracias por tu esfuerzo,

Esta solución que has propuesto, al menos en mi opinión, si cumple el requerimiento deseado de no permitir el movimiento de determinada ventana, lo "malo", que una vez que consigues lo que necesitas, siempre quieres más, y en mi caso, te pregunto, sería posible evitar que el puntero del mouse cambie a modo de "resize" aun cuando el resize de la ventana no esté permitido (espero me explique bien).

Algo que se me presento solo una ocasión y que no ha vuelto a pasar es que al cerrar la ventana principal (salir del ejemplo), se desplego un mensaje haciendo referencia a algo acerca de valor integer... te soy sincero, no puse demasiada atención y no recuerdo el mensaje exacto, pero te lo comento para que quede registro de ese detalle.

Gracias por tu trabajo.

Saludos
Javier
User avatar
srvet_claudio
Posts: 2193
Joined: Thu Feb 25, 2010 8:43 pm
Location: Uruguay
Contact:

Re: LOCK SYSMENU IN WINDOW

Post by srvet_claudio »

Hola Javier,
jparada wrote:Algo que se me presento solo una ocasión y que no ha vuelto a pasar es que al cerrar la ventana principal (salir del ejemplo), se desplego un mensaje haciendo referencia a algo acerca de valor integer... te soy sincero, no puse demasiada atención y no recuerdo el mensaje exacto, pero te lo comento para que quede registro de ese detalle.
Gracias por el aviso, lo voy a investigar.
Yo probé muchas veces el ejemplo y nunca tuve ningún problema, si el problema vuelve a surgir por favor pasame el mensaje que desplegó la ventana.
jparada wrote:sería posible evitar que el puntero del mouse cambie a modo de "resize" aun cuando el resize de la ventana no esté permitido
En cuanto a tu ultima inquietud voy a intentarlo, pero no te prometo nada.

Saludos,
Claudio Soto
Best regards.
Dr. Claudio Soto
(from Uruguay)
http://srvet.blogspot.com
User avatar
srvet_claudio
Posts: 2193
Joined: Thu Feb 25, 2010 8:43 pm
Location: Uruguay
Contact:

Re: LOCK SYSMENU IN WINDOW

Post by srvet_claudio »

Hola Javier,
jparada wrote:sería posible evitar que el puntero del mouse cambie a modo de "resize" aun cuando el resize de la ventana no esté permitido
Para lograr que el puntero del mouse no cambie como lo sugeriste,
sustituí en el código fuente original la funcion: LRESULT CALLBACK WndProc_PIRATA por esta otra:

Code: Select all

LRESULT CALLBACK WndProc_PIRATA (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{   static HCURSOR hCursor = NULL;
  
    if (message == WM_SYSCOMMAND)
    {           
                     
        if ((wParam & 0xFFF0) == SC_MOVE && CheckArray (hWnd, ID_MOVE))
             return 0; 
        
        if ((wParam & 0xFFF0) == SC_SIZE && CheckArray (hWnd, ID_SIZE))
             return 0; 
        
        if ((wParam & 0xFFF0) == SC_RESTORE && CheckArray (hWnd, ID_RESTORE))
             return 0; 
        
        if ((wParam & 0xFFF0) == SC_MAXIMIZE && CheckArray (hWnd, ID_MAXIMIZE))
             return 0; 

        if ((wParam & 0xFFF0) == SC_MINIMIZE && CheckArray (hWnd, ID_MINIMIZE))
             return 0; 
        
        if ((wParam & 0xFFF0) == SC_CLOSE && CheckArray (hWnd, ID_CLOSE))
             return 0; 
        
    }
    
    if (message == WM_MOUSEMOVE) 
        hCursor = GetCursor();
    
    if (message == WM_NCMOUSEMOVE)
    {  
        if ((wParam == HTBOTTOM || wParam == HTBOTTOMLEFT || wParam == HTBOTTOMRIGHT || wParam == HTLEFT || wParam == HTRIGHT || wParam == HTTOP || wParam == HTTOPLEFT || wParam == HTTOPRIGHT)&& CheckArray (hWnd, ID_SIZE))
        { 
           SetCursor(hCursor);  
           return 0;
        } 
        else 
           hCursor = GetCursor();
    }    
      
    p_WndProc_old = (WNDPROC) GetArray_Old_WndProc (hWnd);  
    return CallWindowProc(p_WndProc_old, hWnd, message, wParam, lParam);
}
Saludos,
Claudio Soto
Best regards.
Dr. Claudio Soto
(from Uruguay)
http://srvet.blogspot.com
PeteWG
Posts: 176
Joined: Sun Mar 21, 2010 5:45 pm

Re: LOCK SYSMENU IN WINDOW

Post by PeteWG »

srvet_claudio wrote:Hola Javier,
jparada wrote:Algo que se me presento solo una ocasión y que no ha vuelto a pasar es que al cerrar la ventana principal (salir del ejemplo), se desplego un mensaje haciendo referencia a algo acerca de valor integer... te soy sincero, no puse demasiada atención y no recuerdo el mensaje exacto, pero te lo comento para que quede registro de ese detalle.
Gracias por el aviso, lo voy a investigar.
Yo probé muchas veces el ejemplo y nunca tuve ningún problema, si el problema vuelve a surgir por favor pasame el mensaje que desplegó la ventana.
jparada wrote:sería posible evitar que el puntero del mouse cambie a modo de "resize" aun cuando el resize de la ventana no esté permitido
En cuanto a tu ultima inquietud voy a intentarlo, pero no te prometo nada.

Saludos,
Claudio Soto

Code: Select all

HB_FUNC (IS_CHECK_ARRAY)
{  hb_retl (CheckArray ((HWND) hb_parnl (1), hb_parni (2)));
}


LONG GetArray_Old_WndProc (HWND hWnd)
{  int i;

   // Busca la ventana  y devuelve el WndProc original
   for (i=1; i <= cont; i++)
   {    if ((HWND) hb_arrayGetNL (pArray_HWND, i) == hWnd)
            return (LONG) hb_arrayGetNL (pArray_Old_WndProc, i);
   }
   return NULL;    <============ unconvenient return value (NULL instead of LONG)?
}
Hi Claudio Soto

I think the problem to which JPARADA is referring to, comes from the above denoted "return NULL" statement, that perhaps should be "return 0".
(but again, maybe i' m wrong since my C knowledge could easily be compared to my Spanish language fluency which is near (but not equal) to zero... ;))

P.S. : Excellent and useful LOCK WINDOW routines. Thank you very much!

regards,

---
Pete "Un salude de grecia" WG.
User avatar
srvet_claudio
Posts: 2193
Joined: Thu Feb 25, 2010 8:43 pm
Location: Uruguay
Contact:

Re: LOCK SYSMENU IN WINDOW

Post by srvet_claudio »

Hello PeteWG,
PeteWG wrote: LONG GetArray_Old_WndProc (HWND hWnd)
{  int i;

   // Busca la ventana  y devuelve el WndProc original
   for (i=1; i <= cont; i++)
   {    if ((HWND) hb_arrayGetNL (pArray_HWND, i) == hWnd)
            return (LONG) hb_arrayGetNL (pArray_Old_WndProc, i);
   }
   return NULL;    <============ unconvenient return value (NULL instead of LONG)?
}

I think the problem to which JPARADA is referring to, comes from the above denoted "return NULL" statement, that perhaps should be "return 0".

Yes, yes, yes!!!, you are right,
in C + + NULL = 0,
but in C for windows NULL = ((void *) 0) and is used to assign pointers and NOT variables.

Originally this routine returned a pointer (WNDPROC) and then I changed to a variable, and the error arose.

I doubt that your knowledge of C are close to zero.
I think they are very much higher than that. ;)

Thank you very much for your contribution.
Best regards,
Claudio Soto.

PS: Change original LONG GetArray_Old_WndProc and original HB_FUNC (IS_CHECK_ARRAY) by:

Code: Select all

HB_FUNC (IS_CHECK_ARRAY)
{  if (flag == TRUE) 
       hb_retl (CheckArray ((HWND) hb_parnl (1), hb_parni (2)));
   else
       hb_retl (FALSE);
}


LONG GetArray_Old_WndProc (HWND hWnd)
{  int i;

   // Busca la ventana  y devuelve el WndProc original
   for (i=1; i <= cont; i++)
   {    if ((HWND) hb_arrayGetNL (pArray_HWND, i) == hWnd)
            return (LONG) hb_arrayGetNL (pArray_Old_WndProc, i); 
   }
   return 0;
}

Best regards.
Dr. Claudio Soto
(from Uruguay)
http://srvet.blogspot.com
jparada
Posts: 430
Joined: Fri Jan 23, 2009 5:18 pm

Re: LOCK SYSMENU IN WINDOW

Post by jparada »

Hola Claudio,

Al parecer ha funcionado que cuando pasas el mouse por el borde de la ventana se evite que el puntero cambie a modo resize, pero si das click en el borde de la ventana vuelve a tomar el puntero el estilo resize.

Esto no te lo comento por molestar de ninguna manera, simplemente te doy mi opinión como usuario.

El Mensaje que se desplegaba te lo muestro en la figura adjunta, y por cierto al parecer con esta nueva ultima modificación se ha evitado, ya que no ha aparecido más, y el mensaje aparecia una vez que se ejecutaba el ejemplo y salia del ejemplo con combinación de teclas Alt-F4.

Gracias por tu esfuerzo.

Saludos
Javier
Attachments
nomove.png
nomove.png (9.56 KiB) Viewed 6094 times
User avatar
srvet_claudio
Posts: 2193
Joined: Thu Feb 25, 2010 8:43 pm
Location: Uruguay
Contact:

Re: LOCK SYSMENU IN WINDOW

Post by srvet_claudio »

Hola Javier,
jparada wrote: El Mensaje que se desplegaba te lo muestro en la figura adjunta, y por cierto al parecer con esta nueva ultima modificación se ha evitado, ya que no ha aparecido más, y el mensaje aparecia una vez que se ejecutaba el ejemplo y salia del ejemplo con combinación de teclas Alt-F4.
Gracias por enviarme el mensaje, es un mensaje de advertencia del compilador que la función GetArray_Old_WndProc estaba retornando un tipo de dato incorrecto tal como lo señalo PeteWG. Yo como no compilo en modo consola, lo hago directo con el IDE no me entero de muchos de los mensajes del compilador.
jparada wrote:Al parecer ha funcionado que cuando pasas el mouse por el borde de la ventana se evite que el puntero cambie a modo resize, pero si das click en el borde de la ventana vuelve a tomar el puntero el estilo resize.
Sobre esto ultimo tenes razón no me había dado cuenta, voy a intentar solucionarlo, gracias por avisarme.
Saludos,
Claudio Soto.
Best regards.
Dr. Claudio Soto
(from Uruguay)
http://srvet.blogspot.com
User avatar
srvet_claudio
Posts: 2193
Joined: Thu Feb 25, 2010 8:43 pm
Location: Uruguay
Contact:

Re: LOCK SYSMENU IN WINDOW

Post by srvet_claudio »

Hola Javier,
jparada wrote:Al parecer ha funcionado que cuando pasas el mouse por el borde de la ventana se evite que el puntero cambie a modo resize, pero si das click en el borde de la ventana vuelve a tomar el puntero el estilo resize.
Problema solucionado, cambia LRESULT CALLBACK WndProc_PIRATA por esta otra:

Code: Select all

LRESULT CALLBACK WndProc_PIRATA (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{   static HCURSOR hCursor = NULL;
  
    if (message == WM_SYSCOMMAND)
    {           
                     
        if ((wParam & 0xFFF0) == SC_MOVE && CheckArray (hWnd, ID_MOVE))
             return 0; 
        
        if ((wParam & 0xFFF0) == SC_SIZE && CheckArray (hWnd, ID_SIZE))
             return 0; 
        
        if ((wParam & 0xFFF0) == SC_RESTORE && CheckArray (hWnd, ID_RESTORE))
             return 0; 
        
        if ((wParam & 0xFFF0) == SC_MAXIMIZE && CheckArray (hWnd, ID_MAXIMIZE))
             return 0; 

        if ((wParam & 0xFFF0) == SC_MINIMIZE && CheckArray (hWnd, ID_MINIMIZE))
             return 0; 
        
        if ((wParam & 0xFFF0) == SC_CLOSE && CheckArray (hWnd, ID_CLOSE))
             return 0; 
        
    }
    
    if (message == WM_MOUSEMOVE) 
        hCursor = GetCursor();
    
    if (message == WM_NCMOUSEMOVE || 
        message == WM_NCLBUTTONDOWN || message == WM_NCLBUTTONUP || message == WM_NCLBUTTONDBLCLK ||
        message == WM_NCMBUTTONDOWN || message == WM_NCMBUTTONUP || message == WM_NCMBUTTONDBLCLK ||
        message == WM_NCRBUTTONDOWN || message == WM_NCRBUTTONUP || message == WM_NCRBUTTONDBLCLK)
    {  
        if ((wParam == HTBOTTOM || wParam == HTBOTTOMLEFT || wParam == HTBOTTOMRIGHT || wParam == HTLEFT || wParam == HTRIGHT || wParam == HTTOP || wParam == HTTOPLEFT || wParam == HTTOPRIGHT)&& CheckArray (hWnd, ID_SIZE))
        { 
           SetCursor(hCursor);  
           return 0;
        } 
        else 
           hCursor = GetCursor();
    }    
      
    p_WndProc_old = (WNDPROC) GetArray_Old_WndProc (hWnd);  
    return CallWindowProc(p_WndProc_old, hWnd, message, wParam, lParam);
}


Perdón por tantos inconvenientes,
un saludo cordial,
Claudio Soto.
Best regards.
Dr. Claudio Soto
(from Uruguay)
http://srvet.blogspot.com
jparada
Posts: 430
Joined: Fri Jan 23, 2009 5:18 pm

Re: LOCK SYSMENU IN WINDOW

Post by jparada »

Hola Claudio,

Al parecer tienes razón, está solucionado.
Perdón por tantos inconvenientes,
Pero muy al contrario Claudio, Muchas Gracias por tu esfuerzo y tu dedicación.

Saludos
Javier
Post Reply