WindowEventCodeBlock

Source code related resources

Moderator: Rathinagiri

User avatar
srvet_claudio
Posts: 2017
Joined: Thu Feb 25, 2010 8:43 pm
Location: Uruguay
Has thanked: 34 times
Been thanked: 143 times
Contact:

Re: WindowEventCodeBlock

Post by srvet_claudio » Wed Feb 18, 2015 2:50 am

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.
Best regards.
Dr. Claudio Soto
(from Uruguay)
http://srvet.blogspot.com

User avatar
Pablo César
Posts: 4059
Joined: Wed Sep 08, 2010 1:18 pm
Location: Curitiba - Brasil
Has thanked: 100 times
Been thanked: 179 times

Post by Pablo César » Wed Feb 18, 2015 2:57 am

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.
HMGing a better world
"Matter tells space how to curve, space tells matter how to move."
Albert Einstein

User avatar
srvet_claudio
Posts: 2017
Joined: Thu Feb 25, 2010 8:43 pm
Location: Uruguay
Has thanked: 34 times
Been thanked: 143 times
Contact:

Post by srvet_claudio » Wed Feb 18, 2015 2:58 am

With WindowEventCodeBlock we can make of HMG a better world or the disaster we want :lol: :lol: :lol:
Best regards.
Dr. Claudio Soto
(from Uruguay)
http://srvet.blogspot.com

User avatar
Pablo César
Posts: 4059
Joined: Wed Sep 08, 2010 1:18 pm
Location: Curitiba - Brasil
Has thanked: 100 times
Been thanked: 179 times

Post by Pablo César » Wed Feb 18, 2015 3:02 am

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 !
HMGing a better world
"Matter tells space how to curve, space tells matter how to move."
Albert Einstein

User avatar
srvet_claudio
Posts: 2017
Joined: Thu Feb 25, 2010 8:43 pm
Location: Uruguay
Has thanked: 34 times
Been thanked: 143 times
Contact:

Post by srvet_claudio » Wed Feb 18, 2015 3:15 am

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.
Best regards.
Dr. Claudio Soto
(from Uruguay)
http://srvet.blogspot.com

User avatar
Rathinagiri
Posts: 5210
Joined: Tue Jul 29, 2008 6:30 pm
DBs Used: MariaDB, SQLite, SQLCipher and MySQL
Location: Sivakasi, India
Has thanked: 155 times
Been thanked: 144 times
Contact:

Post by Rathinagiri » Wed Feb 18, 2015 4:49 am

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.)
East or West HMG is the Best.
South or North HMG is worth.
...the possibilities are endless.

User avatar
Pablo César
Posts: 4059
Joined: Wed Sep 08, 2010 1:18 pm
Location: Curitiba - Brasil
Has thanked: 100 times
Been thanked: 179 times

Post by Pablo César » Wed Feb 18, 2015 12:58 pm

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. :(
HMGing a better world
"Matter tells space how to curve, space tells matter how to move."
Albert Einstein

User avatar
Pablo César
Posts: 4059
Joined: Wed Sep 08, 2010 1:18 pm
Location: Curitiba - Brasil
Has thanked: 100 times
Been thanked: 179 times

Post by Pablo César » Wed Feb 18, 2015 2:23 pm

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 591 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 ?
HMGing a better world
"Matter tells space how to curve, space tells matter how to move."
Albert Einstein

User avatar
srvet_claudio
Posts: 2017
Joined: Thu Feb 25, 2010 8:43 pm
Location: Uruguay
Has thanked: 34 times
Been thanked: 143 times
Contact:

Post by srvet_claudio » Wed Feb 18, 2015 3:42 pm

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

Best regards.
Dr. Claudio Soto
(from Uruguay)
http://srvet.blogspot.com

User avatar
serge_girard
Posts: 2050
Joined: Sun Nov 25, 2012 2:44 pm
DBs Used: 1 MySQL - MariaDB
2 DBF
Location: Belgium
Has thanked: 410 times
Been thanked: 90 times
Contact:

Post by serge_girard » Wed Feb 18, 2015 3:52 pm

Thanks all!

Serge

Post Reply