how to get "Userdef" EVENT for ACTION

how to get "Userdef" EVENT for ACTION

Postby Jimmy » Tue Mar 28, 2023 10:07 am

hi,

i can call "find/replace" Dialod this Way

Code: Select all  Expand view  RUN
  FindReplaceDlg ( NIL, lNoUpDown, lNoMatchCase, lNoWholeWord, lCheckDown, lCheckMatchCase, lCheckWholeWord, cFind, cReplace, .T., cTitle )


now i need to receive Event

Code: Select all  Expand view  RUN
  _HMG_MsgIDFindDlg := REGISTERFINDMSGSTRING ()   // ADD

   case nMsg == _HMG_MsgIDFindDlg   // FindReplace Dialog Notification   ( by Dr. Claudio Soto, January 2014 )
         EVAL ( _HMG_FindReplaceOnAction )
 

but how to add Event to Fivewin :?:

---

Code: Select all  Expand view  RUN
static TCHAR       cFindWhat[ 1024 ];
static TCHAR       cReplaceWith[ 1024 ];
static FINDREPLACE FindReplace;
static HWND        hDlgFindReplace = NULL;

HB_FUNC( REGISTERFINDMSGSTRING )
{
   UINT MessageID = RegisterWindowMessage( FINDMSGSTRING );

   hb_retnl( ( LONG ) MessageID );
}

HB_FUNC( FINDREPLACEDLG )
{
   HWND hWnd           = HB_ISNIL( 1 ) ? GetActiveWindow() : ( HWND ) hb_parnl( 1 );
   BOOL NoUpDown       = ( BOOL ) ( HB_ISNIL( 2 ) ? FALSE : hb_parl( 2 ) );
   BOOL NoMatchCase    = ( BOOL ) ( HB_ISNIL( 3 ) ? FALSE : hb_parl( 3 ) );
   BOOL NoWholeWord    = ( BOOL ) ( HB_ISNIL( 4 ) ? FALSE : hb_parl( 4 ) );
   BOOL CheckDown      = ( BOOL ) ( HB_ISNIL( 5 ) ? TRUE  : hb_parl( 5 ) );
   BOOL CheckMatchCase = ( BOOL ) ( HB_ISNIL( 6 ) ? FALSE : hb_parl( 6 ) );
   BOOL CheckWholeWord = ( BOOL ) ( HB_ISNIL( 7 ) ? FALSE : hb_parl( 7 ) );
   BOOL lReplace       = ( BOOL ) hb_parl( 10 );

#ifndef UNICODE
   LPSTR FindWhat    = ( LPSTR ) hb_parc( 8 );
   LPSTR ReplaceWith = ( LPSTR ) hb_parc( 9 );
   LPSTR cTitle      = ( LPSTR ) hb_parc( 11 );
#else
   LPWSTR FindWhat    = AnsiToWide( ( char * ) hb_parc( 8 ) );
   LPWSTR ReplaceWith = AnsiToWide( ( char * ) hb_parc( 9 ) );
   LPWSTR cTitle      = AnsiToWide( ( char * ) hb_parc( 11 ) );
#endif

   if( hDlgFindReplace == NULL )
   {
      ZeroMemory( &FindReplace, sizeof( FindReplace ) );

      lstrcpy( cFindWhat, FindWhat );
      lstrcpy( cReplaceWith, ReplaceWith );

      FindReplace.lStructSize = sizeof( FindReplace );
      FindReplace.Flags       = ( NoUpDown  ? FR_HIDEUPDOWN : 0 ) | ( NoMatchCase    ? FR_HIDEMATCHCASE : 0 ) | ( NoWholeWord    ? FR_HIDEWHOLEWORD : 0 )
                                | ( CheckDown ? FR_DOWN : 0 ) | ( CheckMatchCase ? FR_MATCHCASE : 0 ) | ( CheckWholeWord ? FR_WHOLEWORD : 0 );
      FindReplace.hwndOwner        = hWnd;
      FindReplace.lpstrFindWhat    = cFindWhat;
      FindReplace.wFindWhatLen     = sizeof( cFindWhat ) / sizeof( TCHAR );
      FindReplace.lpstrReplaceWith = cReplaceWith;
      FindReplace.wReplaceWithLen  = sizeof( cReplaceWith ) / sizeof( TCHAR );

      if( lReplace )
         hDlgFindReplace = ReplaceText( &FindReplace );
      else
         hDlgFindReplace = FindText( &FindReplace );

      if( HB_ISCHAR( 11 ) )
         SetWindowText( hDlgFindReplace, cTitle );

      ShowWindow( hDlgFindReplace, SW_SHOW );
   }

#ifdef UNICODE
   hb_xfree( ( TCHAR * ) FindWhat );
   hb_xfree( ( TCHAR * ) ReplaceWith );
   hb_xfree( ( TCHAR * ) cTitle );
#endif
}
 
greeting,
Jimmy
User avatar
Jimmy
 
Posts: 1733
Joined: Thu Sep 05, 2019 5:32 am
Location: Hamburg, Germany

Re: how to get "Userdef" EVENT for ACTION

Postby Antonio Linares » Tue Mar 28, 2023 10:31 am

Dear Jimmy,

Is the event sent to hwndOwner ?

If so, then you need to inherit a class from TWindow and redefine HandleEvent() method and add support for such event
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42203
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: how to get "Userdef" EVENT for ACTION

Postby Jimmy » Tue Mar 28, 2023 2:50 pm

hi Antonio,
Antonio Linares wrote:Is the event sent to hwndOwner ?

i´m not sure ... it is like other "Common Dialog"

it have to do with FINDREPLACE A/W structure
https://learn.microsoft.com/en-us/windows/win32/api/commdlg/ns-commdlg-findreplacea

there is HB_FUNC( FINDTEXT ) in c:\fwh\source\winapi\findtext.c but no HB:FUNC() for "replace"

i have take HB_FUNC( FINDREPLACEDLG ) from HMG and modify it for Fivewin ( Parameter Type )

as both work with same FINDREPLACE Structure it must be same Way for ACTION ... but how under Fivewin :?:

Antonio Linares wrote:If so, then you need to inherit a class from TWindow and redefine HandleEvent() method and add support for such event

have found CLASS TDlgFind() which use HB_FUNC( FINDTEXT )

Code: Select all  Expand view  RUN
  REDEFINE BUTTON ID IDOK OF Self ;

it "this" the "OK" Button from "Dialog" :?:

what do i need for "these" Buttons when using
Code: Select all  Expand view  RUN
 FindReplaceDlg ( NIL, lNoUpDown, lNoMatchCase, lNoWholeWord, lCheckDown, lCheckMatchCase, lCheckWholeWord, cFind, cReplace, .T., cTitle )

Image

---
this is HMG CODE Syntax

Code: Select all  Expand view  RUN
#xtranslate FINDTEXTDIALOG  ;
           [ <dummy1: ACTION,ON ACTION> <action> ];
           [ FIND <cFind> ] ;
           [ <NoUpDown: NOUPDOWN> ] ;
           [ <NoMatchCase: NOMATCHCASE> ] ;
           [ <NoWholeWord: NOWHOLEWORD> ] ;
           [ CHECKDOWN <CheckDown> ] ;
           [ CHECKMATCHCASE <CheckMatchCase> ] ;
           [ CHECKWHOLEWORD <CheckWholeWord> ] ;
           [ TITLE <cTitle> ] ;
=> FindTextDlg ( <{action}>, <cFind>, <.NoUpDown.>, <.NoMatchCase.>, <.NoWholeWord.>, <CheckDown>, <CheckMatchCase>, <CheckWholeWord>, <cTitle> )

#xtranslate REPLACETEXTDIALOG ;
           [ <dummy1: ACTION,ON ACTION> <action> ];
           [ FIND <cFind> ] ;
           [ REPLACE <cReplace> ] ;
           [ <NoMatchCase: NOMATCHCASE> ] ;
           [ <NoWholeWord: NOWHOLEWORD> ] ;
           [ CHECKMATCHCASE <CheckMatchCase> ] ;
           [ CHECKWHOLEWORD <CheckWholeWord> ] ;
           [ TITLE <cTitle> ] ;
=> ReplaceTextDlg ( <{action}>, <cFind>, <cReplace>, <.NoMatchCase.>, <.NoWholeWord.>, <CheckMatchCase>, <CheckWholeWord> , <cTitle> )


this i use under HMG
Code: Select all  Expand view  RUN
    FINDTEXTDIALOG ON ACTION FindReplTXTProc() FIND cFind CHECKDOWN lDown CHECKMATCHCASE lMatchCase CHECKWHOLEWORD lWholeWord )


Code: Select all  Expand view  RUN
PROCEDURE FindReplTXTProc()
LOCAL lSelectFindText
LOCAL aPosRange       := { 0, 0 }
LOCAL cFind           := SP_cFindText()
LOCAL cHoleText, nPosi, hEditbox

STATIC nStart := 1

   IF FindReplaceDlg.RetValue == FRDLG_CANCEL                         // User Cancel or Close dialog
      RETURN
   ENDIF

   cFind := FindReplaceDlg.Find
   cReplace := FindReplaceDlg.Replace
   lDown := FindReplaceDlg.Down
   lMatchCase := FindReplaceDlg.MatchCase
   lWholeWord := FindReplaceDlg.WholeWord
   lSelectFindText := .T.

   SP_cFindText( cFind )
   cHoleText := TXTEdit.TXTCtrl.Value
   IF lDown = .T.
      nPosi := hb_at( UPPER( cFind ), UPPER( cHoleText ), nStart )
   ELSE
      nPosi := hb_rat( UPPER( cFind ), UPPER( cHoleText ), nStart )
   ENDIF

   IF nPosi > 0
      TXTEdit.TXTCtrl.CaretPos := nPosi
      hEditbox := GetControlHandle( "TXTCtrl", "TXTEdit" )
      SendMessage( hEditbox, EM_SETSEL, nPosi - 1, nPosi + LEN( cFind ) )
      nStart := nPosi + 1
   ELSE
      IF lDown = .T.
         MsgInfo( "EOF no more" )
         nStart := 1
      ELSE
         MsgInfo( "BOF no more" )
         nStart := LEN( cHoleText )
      ENDIF
   ENDIF

RETURN
greeting,
Jimmy
User avatar
Jimmy
 
Posts: 1733
Joined: Thu Sep 05, 2019 5:32 am
Location: Hamburg, Germany

Re: how to get "Userdef" EVENT for ACTION

Postby Jimmy » Tue Mar 28, 2023 3:55 pm

hi Antonio,
Antonio Linares wrote:Is the event sent to hwndOwner ?

i think Yes

Code: Select all  Expand view  RUN
 FindReplaceDlg ( NIL, lNoUpDown, lNoMatchCase, lNoWholeWord, lCheckDown, lCheckMatchCase, lCheckWholeWord, cFind, cReplace, .T., cTitle )


   HWND hWnd           = HB_ISNIL( 1 ) ? GetActiveWindow() : ( HWND ) hb_parnl( 1 );
   ...
   FindReplace.hwndOwner        = hWnd;


FindTextA function
https://learn.microsoft.com/en-us/windows/win32/api/commdlg/nf-commdlg-findtexta

The FindText function does not perform a search operation. Instead, the dialog box sends FINDMSGSTRING registered messages to the window procedure of the owner window of the dialog box. When you create the dialog box, the hwndOwner member of the FINDREPLACE structure is a handle to the owner window.


---
ReplaceTextA function
https://learn.microsoft.com/en-us/windows/win32/api/commdlg/nf-commdlg-replacetexta

The ReplaceText function does not perform a text replacement operation. Instead, the dialog box sends FINDMSGSTRING registered messages to the window procedure of the owner window of the dialog box. When you create the dialog box, the hwndOwner member of the FINDREPLACE structure is a handle to the owner window.
greeting,
Jimmy
User avatar
Jimmy
 
Posts: 1733
Joined: Thu Sep 05, 2019 5:32 am
Location: Hamburg, Germany

Re: how to get "Userdef" EVENT for ACTION

Postby Jimmy » Wed Mar 29, 2023 8:34 pm

hi,

have look into c:\fwh\source\classes\dlgfind.prg and found REDEFINE / ACTION ... hm ... :idea:

have made a copy and change into
Code: Select all  Expand view  RUN
  //    RegDialog( ::hWnd := FindText( cText, oWnd:hWnd, @nFindMsgString ) )
   RegDialog( ::hWnd := FindReplaceDlg( NIL, lNoUpDown, lNoMatchCase, lNoWholeWord, lCheckDown, lCheckMatchCase, lCheckWholeWord, cText, cReplace, lReplace, cTitle ) )

   REDEFINE BUTTON ID IDOK OF Self ;
           ACTION EVAL( bSearch, ;
           GetWindowText( GetWindow( GetWindow( ::hWnd, GW_CHILD ), GW_HWNDNEXT ) ), ;
           lForward, Self )

   REDEFINE BUTTON ID 0x400 OF Self ;
           ACTION MsgInfo( "400" )

   REDEFINE BUTTON ID 0x401 OF Self ;
           ACTION MsgInfo( "401" )

   REDEFINE BUTTON ID IDCANCEL OF Self ;
           ACTION nil

now i do not "wait" for Event, generate by press a Button, as i can "control" Button itself
REDEFINE is GREAT :D

p.s. i found BUTTON ID using WinID
https://dennisbabkin.com/winid/
greeting,
Jimmy
User avatar
Jimmy
 
Posts: 1733
Joined: Thu Sep 05, 2019 5:32 am
Location: Hamburg, Germany

Re: how to get "Userdef" EVENT for ACTION

Postby Jimmy » Thu Mar 30, 2023 6:33 am

hi Antonio,
Antonio Linares wrote:If so, then you need to inherit a class from TWindow and redefine HandleEvent() method and add support for such event

Code: Select all  Expand view  RUN
CLASS TMyWindow FROM TWindow
   CLASSDATA lRegistered

   METHOD HandleEvent( nMsg, nWParam, nLParam )
   METHOD Notify( nIdCtrl, nPtrNMHDR ) // Common controls notifications
ENDCLASS

METHOD HandleEvent( nMsg, nWParam, nLParam ) CLASS TMyWindow
   DO CASE
     CASE nMsg == _HMG_MsgIDFindDlg
         _HMG_FindReplaceOptions := FindReplaceDlgGetOptions( nLParam )
         EVAL( HMG_FindReplaceOnAction )
         IF _HMG_FindReplaceOptions[ 1 ] == 0                         // User CANCEL or CLOSE Dialog
            FindReplaceDlgRelease( .T. )                              // Destroy Dialog Window and Set NULL Dialog Handle
         ENDIF
         AFILL( _HMG_FindReplaceOptions, NIL )

     CASE nMsg == WM_POWERBROADCAST
         RETURN BROADCAST_QUERY_DENY
   ENDCASE

RETURN ::Super:HandleEvent( nMsg, nWParam, nLParam )

YES, that was the missing part

FindReplaceDlgGetOptions( nLParam ) will get "Info" of Dialog in a Array AFTER i press a Button in Dialog
Code: Select all  Expand view  RUN
         _HMG_FindReplaceOnAction := { || FindReplTXTProc(oMGet,cFind,cMemo) }
         DlgFindReplace( @cFind, oWnd, { || nil }, ;
                                        lReplace, cReplace, cTitle, lNoUpDown, lNoMatchCase, lNoWholeWord, lCheckDown, lCheckMatchCase, lCheckWholeWord )

i need to call as "other" Codeblock "_HMG_FindReplaceOnAction" which run under "TMyWindow"
greeting,
Jimmy
User avatar
Jimmy
 
Posts: 1733
Joined: Thu Sep 05, 2019 5:32 am
Location: Hamburg, Germany


Return to FiveWin for Harbour/xHarbour

Who is online

Users browsing this forum: No registered users and 82 guests