Page 2 of 3

Re: WindowEventCodeBlock

Posted: Wed Feb 18, 2015 2:50 am
by srvet_claudio
Pablo César wrote:
srvet_claudio wrote:
Pablo César wrote: I have replaced InvalidateRect (GetParent (hWnd)) inside of IF flag == .T. then seems become faster when moving Grid position.
Of course, but the repainting of the parent window is not the same.
Y que esto influenciaria, Dr. Claudio ?
The title bar of the GRID on some occasions was not properly repaint it superpose with background of parent window.

WindowEventCodeBlock

Posted: Wed Feb 18, 2015 2:57 am
by Pablo César
Thank you Claudio for your explanation.

What I've noted when is reached the maximum limit, executes three times the ProcMoveSizeControl function.
This is easy to note when you put a PlayBeep() inside of IF flag == .T. because three sounds is actioned.

Re: WindowEventCodeBlock

Posted: Wed Feb 18, 2015 2:58 am
by srvet_claudio
With WindowEventCodeBlock we can make of HMG a better world or the disaster we want :lol: :lol: :lol:

WindowEventCodeBlock

Posted: Wed Feb 18, 2015 3:02 am
by Pablo César
I would like to use in all controls for FMGEditor, with this new function it makes easier moving a resizing controls.

For sure it's so good count with this new function ! :D

Also imaging to prepare a new form and resize and positioned according our taste and and keep/save those four values. ;)

Thank again Claudio !

Re: WindowEventCodeBlock

Posted: Wed Feb 18, 2015 3:15 am
by srvet_claudio
Pablo César wrote:I would like to use in all controls for FMGEditor, with this new function it makes easier moving a resizing controls.

For sure it's so good count with this new function ! :D

Also imaging to prepare a new form and resize and positioned according our taste and and keep/save those four values. ;)

Thank again Claudio !
I'm working on a more elaborate version of these functions, I'll included in the next patch of HMG.

Re: WindowEventCodeBlock

Posted: Wed Feb 18, 2015 4:49 am
by Rathinagiri
Looking great Claudio. :)

What I have found is, even with the below code, (leaving WS_CAPTION ) we can still move/resize. 'Move' using left and right edge (when the control is in full width / height) and 'Size' using right and bottom edge. Cool.

Code: Select all

HMG_ChangeWindowStyle (hWnd, WS_SIZEBOX, NIL, .F., .T.)

WindowEventCodeBlock

Posted: Wed Feb 18, 2015 12:58 pm
by Pablo César
Rathinagiri wrote:What I have found is, even with the below code, (leaving WS_CAPTION ) we can still move/resize. 'Move' using left and right edge (when the control is in full width / height) and 'Size' using right and bottom edge. Cool.

Code: Select all

HMG_ChangeWindowStyle (hWnd, WS_SIZEBOX, NIL, .F., .T.)
Even cutting off WS_CAPTION style, in my tests I have not experienced the same than you Rathi :? (confused).
There is not way to resize at all. Moving only by click on title bar of control with this your code Rathi.

I'm testing with Win7 32bits in classic mode. But repeat not same experience than you Rathi.

And is still start running alternately with not success at first time but working at second time.
Even with last Claudios's code. :(

WindowEventCodeBlock

Posted: Wed Feb 18, 2015 2:23 pm
by Pablo César
I wish to let it this adpated demo:

<Source code demo was removed, because there is an updated version more ahead of this topic>
<You an access this one: viewtopic.php?p=39957#p39957>

I changed HMG_ChangeWindowStyle (hWnd, WS_CAPTION + WS_SIZEBOX, NIL, .F., .T.) for:
HMG_ChangeWindowStyle (hWnd, WS_CAPTION + WS_THICKFRAME , NIL, .F., .T.)

I also changed:
  • Title in Grid frame with actual position.
  • Yellow frame ON Paint and labels to display a range in moving control.
  • InvalidateRect (GetParent (hWnd)) inside IF flag == .T.
  • Local variables and declare CONSTANTs at begining of code
  • Added buttons to Enable/Disable Move/Size control and refresh control
Screen1.png
Screen1.png (51.68 KiB) Viewed 1554 times
All merits to Claudio !

srvet_claudio wrote:
Pablo César wrote:I have replaced InvalidateRect (GetParent (hWnd)) inside of IF flag == .T. then seems become faster when moving Grid position.
Of course, but the repainting of the parent window is not the same.
..//..
The title bar of the GRID on some occasions was not properly repaint it superpose with background of parent window.
I saw when is given double click in Grid Title Bar (when maximized control) is overwritting control Grid with Labels.
For this reason I made a RefreshIt() function.

srvet_claudio wrote:
Pablo César wrote:In all my tests when running executable, it's working alternately.

One time is working and in second time not. Subsequently.

Strange behaviour.
Image

Running on Win 7 32 bits in Classic and Aero mode (both with runtime error).
I'm sorry, It is an elementary problem of converting pointers in C
But still is not working 100%. It's unstable (first time not working but second time working)
New code C was replaced and do not know what is wrong... :(

It's seems something like as a prisoner event or is something that can not be released ?

Re: WindowEventCodeBlock

Posted: Wed Feb 18, 2015 3:42 pm
by srvet_claudio
Please test this version.

The syntax is:
nIndex := SetEventCodeBlock (hWnd, {|| ProcMoveSizeControl()}, NIL ) // Precess all messages

nIndex := SetEventCodeBlock (hWnd, {|| ProcMoveSizeControl()}, { WM_KEYUP, WM_SIZE, WM_WINDOWPOSCHANGED } ) // Precess only this list of messages

nIndex := SetEventCodeBlock (hWnd, {|| ProcMoveSizeControl()}, WM_WINDOWPOSCHANGED ) // Precess only this message

RemoveEventCodeBlock (nIndex)

Code: Select all


#include "hmg.ch"

Function Main

public aRows [21] [3]

   aRows [1]   := {'Simpson','Homer','555-5555'}
   aRows [2]   := {'Mulder','Fox','324-6432'} 
   aRows [3]   := {'Smart','Max','432-5892'} 
   aRows [4]   := {'Grillo','Pepe','894-2332'} 
   aRows [5]   := {'Kirk','James','346-9873'} 
   aRows [6]   := {'Barriga','Carlos','394-9654'} 
   aRows [7]   := {'Flanders','Ned','435-3211'} 
   aRows [8]   := {'Smith','John','123-1234'} 
   aRows [9]   := {'Pedemonti','Flavio','000-0000'} 
   aRows [10]   := {'Gomez','Juan','583-4832'} 
   aRows [11]   := {'Fernandez','Raul','321-4332'} 
   aRows [12]   := {'Borges','Javier','326-9430'} 
   aRows [13]   := {'Alvarez','Alberto','543-7898'} 
   aRows [14]   := {'Gonzalez','Ambo','437-8473'} 
   aRows [15]   := {'Batistuta','Gol','485-2843'} 
   aRows [16]   := {'Vinazzi','Amigo','394-5983'} 
   aRows [17]   := {'Pedemonti','Flavio','534-7984'} 
   aRows [18]   := {'Samarbide','Armando','854-7873'} 
   aRows [19]   := {'Pradon','Alejandra','???-????'} 
   aRows [20]   := {'Reyes','Monica','432-5836'} 
   aRows [21]   := {'Fernández','two','0000-0000'} 

   FOR i = 1 TO 21
     AADD (aRows[i],str(i))
   NEXT

   DEFINE WINDOW Form_1 ;
      AT 0,0 ;
      WIDTH 800 ;
      HEIGHT 650 ;
      MAIN 

      @  10, 10 Label Label_1 ;
         width 80;
         height 20;
         value "WindowEventCodeBlock: this is beautiful";
         autosize

      @  50, 10 Label Label_2; 
         width 80;
         height 20;
         value "Limits the size and movement of the GRID in the screen (max Row,Col --> 150,150) (Width, Height --> 200 to 500)"; 
         autosize

      @ 80,10 GRID Grid_1 ;
         WIDTH 540 ;
         HEIGHT 500 ;
         HEADERS {'Last Name','First Name','Phone',"Num"} ;
         WIDTHS {140,140,140,50};
         ITEMS aRows ;
         VALUE 1

         Form_1.Grid_1.ColumnCONTROL (4) := {"TEXTBOX", "NUMERIC",NIL,NIL}
         Form_1.Grid_1.ColumnJUSTIFY (4) := GRID_JTFY_RIGHT

   END WINDOW


      #define WS_BORDER  0x00800000
      #define WS_CAPTION 0x00C00000
      #define WS_SIZEBOX 0x00040000

      #define WM_WINDOWPOSCHANGED 0x0047

      #define WM_SIZE 0x0005
      #define WM_MOVE 0x0003

      hWnd := Form_1.Grid_1.Handle
      HMG_ChangeWindowStyle (hWnd, WS_CAPTION + WS_SIZEBOX, NIL, .F., .T.)

//    nIndex := SetEventCodeBlock (hWnd, {|| ProcMoveSizeControl()}, NIL )   // Precess all messages 
//    nIndex := SetEventCodeBlock (hWnd, {|| ProcMoveSizeControl()}, { WM_KEYUP, WM_SIZE, WM_WINDOWPOSCHANGED } )   // Precess only this list of messages
      nIndex := SetEventCodeBlock (hWnd, {|| ProcMoveSizeControl()}, WM_WINDOWPOSCHANGED )   // Precess only this message

      ON KEY F5 OF Form_1 ACTION MsgDebug (RemoveEventCodeBlock (nIndex))


   MAXIMIZE WINDOW Form_1

   ACTIVATE WINDOW Form_1

Return


Function ProcMoveSizeControl
LOCAL aEventCodeBlockInfo := GetEventCodeBlockInfo()
LOCAL hWnd   := aEventCodeBlockInfo [1]
LOCAL nMsg   := aEventCodeBlockInfo [2]
LOCAL wParam := aEventCodeBlockInfo [3]
LOCAL lParam := aEventCodeBlockInfo [4]
LOCAL nIndex := aEventCodeBlockInfo [5]
LOCAL aInfo, x, y, cx, cy
LOCAL flag := .F.

   IF nMsg == WM_WINDOWPOSCHANGED

      aInfo := WM_WINDOWPOSCHANGED_INFO ( lParam )
      x  := aInfo [1]   // nCol
      y  := aInfo [2]   // nRow
      cx := aInfo [3]   // nWidth
      cy := aInfo [4]   // nHeight

      IF x > 150
         x := 150
         flag := .T.
      ENDIF

      IF y > 150
         y := 150
         flag := .T.
      ENDIF

      IF cx > 500
         cx := 500
         flag := .T.
      ENDIF

      IF cx < 200
         cx := 200
         flag := .T.
      ENDIF

      IF cy > 500
         cy := 500
         flag := .T.
      ENDIF

      IF cy < 200
         cy := 200
         flag := .T.
      ENDIF
 
      Form_1.Title := "AT "+HB_NTOS(x)+" , "+HB_NTOS(y)+" SIZE "+HB_NTOS(cx)+" , "+HB_NTOS(cy)

      InvalidateRect  (GetParent (hWnd))
      
      IF flag == .T.
         SetWindowPos (hWnd, 0, x, y, cx, cy, SWP_NOOWNERZORDER + SWP_NOSENDCHANGING + SWP_DRAWFRAME + SWP_FRAMECHANGED)
         // RedrawWindow (GetParent (hWnd))
         Return 0
      ENDIF

   ELSE
      Form_1.Title := "MSG "+HB_NTOS(nMsg)
   ENDIF

Return NIL



#pragma BEGINDUMP

#include "SET_COMPILE_HMG_UNICODE.ch"
#include "HMG_UNICODE.h"


#include <windows.h>
#include <tchar.h>
#include <commctrl.h>

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


HB_FUNC ( WM_WINDOWPOSCHANGED_INFO )
{
   LPARAM lParam = (LPARAM) HMG_parnl (1);
   if ( lParam )
   {  LPWINDOWPOS lpWindowPos = (LPWINDOWPOS) lParam;
      hb_reta (4);
      hb_storvni (lpWindowPos->x,   -1, 1);
      hb_storvni (lpWindowPos->y,   -1, 2);
      hb_storvni (lpWindowPos->cx,  -1, 3);
      hb_storvni (lpWindowPos->cy,  -1, 4);
   }
}



/********************************************************************/
/*   WindowEventCodeBlock,   by Dr. Claudio Soto,   February 2015   */
/********************************************************************/

PHB_ITEM  pArrayEventCodeBlock  = NULL;


HWND      EventCodeBlock_hWnd   = NULL;
UINT      EventCodeBlock_uMsg   = 0;
WPARAM    EventCodeBlock_wParam = 0;
LPARAM    EventCodeBlock_lParam = 0;
DWORD_PTR EventCodeBlock_nIndex = 0;


typedef struct
{
   HWND hWnd;
   PHB_ITEM  pCodeBlock;
   PHB_ITEM  pArrayMSG;
} EventCBData;


//        GetEventCodeBlockInfo () --> array { hWnd, uMsg, wParam, lParam, nIndex }
HB_FUNC ( GETEVENTCODEBLOCKINFO )
{
   hb_reta (5);
   HMG_storvnl ((LONG_PTR) EventCodeBlock_hWnd,    -1, 1);
   HMG_storvnl ((LONG_PTR) EventCodeBlock_uMsg,    -1, 2);
   HMG_storvnl ((LONG_PTR) EventCodeBlock_wParam,  -1, 3);
   HMG_storvnl ((LONG_PTR) EventCodeBlock_lParam,  -1, 4);
   HMG_storvnl ((LONG_PTR) EventCodeBlock_nIndex,  -1, 5);
}


// Process CodeBlocks of Window Event
LRESULT CALLBACK SubClassProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
{
   UNREFERENCED_PARAMETER (uIdSubclass);

   EventCodeBlock_hWnd   = hWnd;
   EventCodeBlock_uMsg   = uMsg;
   EventCodeBlock_wParam = wParam;
   EventCodeBlock_lParam = lParam;
   EventCodeBlock_nIndex = dwRefData;

   EventCBData * pEventCBData = (EventCBData *) hb_arrayGetPtr ( pArrayEventCodeBlock, (HB_SIZE) dwRefData );

   if ( pEventCBData )
   {
      HB_SIZE nPos = 0;
      if (pEventCBData->pArrayMSG)
      {
         PHB_ITEM pValue = hb_itemNew ( NULL );
         hb_itemPutNI (pValue, (int) uMsg);
         nPos = hb_arrayScan (pEventCBData->pArrayMSG, pValue, NULL, NULL, HB_FALSE);
         hb_itemRelease (pValue);
      }
      else
         nPos = 1;

      if (pEventCBData->pCodeBlock && nPos > 0)
      {  PHB_ITEM pItem = hb_vmEvalBlock ( pEventCBData->pCodeBlock );
         if ( pItem && ( hb_itemType (pItem) & HB_IT_NUMERIC ))
         {
            #ifdef _WIN64
               LRESULT nRet = (LRESULT) hb_itemGetNLL (pItem);
            #else
               LRESULT nRet = (LRESULT) hb_itemGetNL  (pItem);
            #endif
            // hb_itemRelease (pItem);
            return nRet;
         }
         else if (pItem)
         {   // hb_itemRelease (pItem);
         }
      }
   }

   return DefSubclassProc(hWnd, uMsg, wParam, lParam);
}


//        SetEventCodeBlock ( hWnd, CodeBlock [, nMsg | aMsg ] ) --> nIndex
HB_FUNC ( SETEVENTCODEBLOCK )
{
   static UINT_PTR uIdSubclass = 0;
   static DWORD_PTR dwRefData  = 0;

   HWND     hWnd       = (HWND) HMG_parnl (1);
   PHB_ITEM pCodeBlock = (HB_ISBLOCK (2) ? hb_itemClone (hb_param (2, HB_IT_BLOCK)) : NULL);

   if (IsWindow(hWnd) && pCodeBlock)
   {
      if (pArrayEventCodeBlock == NULL)
         pArrayEventCodeBlock = hb_itemArrayNew (0);

      EventCBData * pEventCBData = (EventCBData *) hb_xgrab (sizeof (EventCBData));
 
      PHB_ITEM pArrayMSG  = NULL;

      if (HB_ISNUM (3))
      {  pArrayMSG = hb_itemArrayNew (0);
         hb_arrayAddForward (pArrayMSG, hb_itemPutNI (NULL, hb_parni(3)));
      }
      else if (HB_ISARRAY (3) && (hb_parinfa (3,0) > 0))
         pArrayMSG = hb_itemClone (hb_param (3, HB_IT_ARRAY)); 

/*
      else if (HB_ISARRAY (3))
      {  pArrayMSG = hb_itemClone (hb_param (3, HB_IT_ARRAY)); 
         if (hb_arrayLen (pArrayMSG) == 0)
         {  hb_itemRelease (pArrayMSG);
            pArrayMSG = NULL;
         }
      }
*/
      pEventCBData->hWnd       = hWnd;
      pEventCBData->pCodeBlock = pCodeBlock;
      pEventCBData->pArrayMSG  = pArrayMSG;

      hb_arrayAddForward (pArrayEventCodeBlock, hb_itemPutPtr (NULL, (void *) pEventCBData));

      SetWindowSubclass (hWnd, (SUBCLASSPROC) SubClassProc, ++uIdSubclass, ++dwRefData);

      HMG_retnl ((LONG_PTR) uIdSubclass);
   }
   else
      HMG_retnl ((LONG_PTR) 0);
}


//        RemoveEventCodeBlock ( nIndex ) --> lBoolean
HB_FUNC ( REMOVEEVENTCODEBLOCK )
{
   UINT_PTR uIdSubclass = (UINT_PTR) HMG_parnl (1);
   BOOL lRet = FALSE;

   if (pArrayEventCodeBlock && (uIdSubclass > 0) && (uIdSubclass <= (UINT_PTR) hb_arrayLen (pArrayEventCodeBlock)))
   {
      EventCBData * pEventCBData = (EventCBData *) hb_arrayGetPtr (pArrayEventCodeBlock, (HB_SIZE) uIdSubclass);

      if (pEventCBData && RemoveWindowSubclass (pEventCBData->hWnd, (SUBCLASSPROC) SubClassProc, uIdSubclass))
      {
         if (pEventCBData->pCodeBlock)
            hb_itemRelease (pEventCBData->pCodeBlock);

         if (pEventCBData->pArrayMSG)
            hb_itemRelease (pEventCBData->pArrayMSG);

         hb_xfree ((void *) pEventCBData);

         hb_arraySetPtr (pArrayEventCodeBlock, (HB_SIZE) uIdSubclass, NULL);
         lRet = TRUE;
      }
   }
   hb_retl (lRet);
}


#pragma ENDDUMP


Re: WindowEventCodeBlock

Posted: Wed Feb 18, 2015 3:52 pm
by serge_girard
Thanks all!

Serge