Xbase++ to harbour / HMG Question

Discuss anything else that does not suite other forums.

Moderator: Rathinagiri

User avatar
AUGE_OHR
Posts: 53
Joined: Sun Aug 25, 2019 3:12 pm
DBs Used: DBF, PostgreSQL, MySQL, SQLite
Location: Hamburg, Germany
Has thanked: 1 time
Been thanked: 5 times

Xbase++ to harbour / HMG Question

Post by AUGE_OHR » Tue Aug 27, 2019 5:48 pm

hi,

i have some Question when migrate Xbase++ Code to harbour / HMG

how to use DEFAULT :?:

Code: Select all

FUNCTION ABCD(xValue)
// how to use DEFAULT with harbour / HMG Question
DEFAULT xValue TO "Hello world"
ist there a ConfirmBox :?:

Code: Select all

FUNCTION DXE_ConfirmBox(oOwner, cMessage, cTitle, nButtons,nStyle,nStartBtn)
...
   // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-messageboxa
   nRet := @User32:MessageBoxA(hWnd,cMessage,cTitle,uType)
how to convert BIN to HEX :?:

Code: Select all

// Store Bitmap in HEX Format using cBin2Hex()
LOCAL cSql    := "UPDATE " + ::_cTable + " SET "
   // Bin to HEX Format using ot4xb
   //
   cSql += ::_aBroFields[ nCol ] [ DBS_NAME ] + "= '\x" + cBin2Hex( cBuffer ) + "' "
how to convert HEX to BIN :?:

Code: Select all

// read Bitmap in HEX Format using cHex2Bin()
   // Hex to Bin Format using ot4xb
   //
   oBMP:setBuffer( cHex2Bin( cBuffer ) )
how to choise CPU :?:

Code: Select all

FUNCTION SmpGetCPU() 
LOCAL i
    i := DllCall("Xpprt1.dll",DLL_CDECL, "_sysGetCPU")
RETURN i

FUNCTION SmpSetCPU(nCpuMask) 
LOCAL rc
    rc := DllCall("Xpprt1.dll",DLL_CDECL, "_sysSetCPU", nCpuMask)
RETURN rc 
how to use Thread ( with different CPU ) :?:
now to use GRID (c:\hmg.3.4.4\SOURCE\h_grid.prg) :?:

need help please

ROBROS
Posts: 177
Joined: Thu May 25, 2017 6:30 pm
DBs Used: DBF
Has thanked: 52 times
Been thanked: 17 times

Post by ROBROS » Tue Aug 27, 2019 6:37 pm

Hi Jimmy,
if you install IDE and choose References you will find a description of all controls, methods and so on. Very useful the external guides and tutorials.

In the folder C:\hmg.3.4.4\SAMPLES\ you will find a lot source codes. And in this forum you will find useful sources.
I'm just working on a prog with toolbar and grid, but I can't publish it here, for the personal data are real existing.The grid is already working, the buttons have yet to be filled with functions.
Regards

Robert

PS: If you are interested I could anonymize the personal data (name and city), so I could publish the dbf.
Last edited by ROBROS on Tue Aug 27, 2019 8:05 pm, edited 1 time in total.

User avatar
jairpinho
Posts: 340
Joined: Mon Jul 18, 2011 5:36 pm
Location: Rio Grande do Sul - Brasil
Has thanked: 3 times
Been thanked: 11 times
Contact:

Post by jairpinho » Tue Aug 27, 2019 7:33 pm

AUGE_OHR wrote:
Tue Aug 27, 2019 5:48 pm
hi,

i have some Question when migrate Xbase++ Code to harbour / HMG

how to use DEFAULT :?:

Code: Select all

FUNCTION ABCD(xValue)
// how to use DEFAULT with harbour / HMG Question
DEFAULT xValue TO "Hello world"
ist there a ConfirmBox :?:

Code: Select all

FUNCTION DXE_ConfirmBox(oOwner, cMessage, cTitle, nButtons,nStyle,nStartBtn)
...
   // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-messageboxa
   nRet := @User32:MessageBoxA(hWnd,cMessage,cTitle,uType)
how to convert BIN to HEX :?:

Code: Select all

// Store Bitmap in HEX Format using cBin2Hex()
LOCAL cSql    := "UPDATE " + ::_cTable + " SET "
   // Bin to HEX Format using ot4xb
   //
   cSql += ::_aBroFields[ nCol ] [ DBS_NAME ] + "= '\x" + cBin2Hex( cBuffer ) + "' "
how to convert HEX to BIN :?:

Code: Select all

// read Bitmap in HEX Format using cHex2Bin()
   // Hex to Bin Format using ot4xb
   //
   oBMP:setBuffer( cHex2Bin( cBuffer ) )
how to choise CPU :?:

Code: Select all

FUNCTION SmpGetCPU() 
LOCAL i
    i := DllCall("Xpprt1.dll",DLL_CDECL, "_sysGetCPU")
RETURN i

FUNCTION SmpSetCPU(nCpuMask) 
LOCAL rc
    rc := DllCall("Xpprt1.dll",DLL_CDECL, "_sysSetCPU", nCpuMask)
RETURN rc 
how to use Thread ( with different CPU ) :?:
now to use GRID (c:\hmg.3.4.4\SOURCE\h_grid.prg) :?:

need help please

hello follow some documentation links that contain all your initial doubts in hmg and harbour, in case you can't find what you're looking for put your question again

HMG
hmgdoc/data/

HARBOUR
http://www.marinas-gui.org/projects/harbour_manual/
http://www.elektrosoft.it/tutorials/Har ... -guide.htm
https://harbour.github.io/doc/
https://vouch.info/harbour/index.html?vm.htm
Jair Pinho
HMG ALTA REVOLUÇÃO xBASE
HMG xBASE REVOLUTION HIGH
http://www.hmgforum.com.br

User avatar
IMATECH
Posts: 173
Joined: Sun May 27, 2012 9:33 pm
Location: Brazil: Goiânia-GO.
Has thanked: 1 time
Been thanked: 3 times

Post by IMATECH » Tue Aug 27, 2019 10:23 pm

how to use DEFAULT :?:

Code: Select all

cData := hb_DefaultValue( cData, "Default Value" )
ist there a ConfirmBox :?:

Code: Select all

MsgYesNo( "MessageBox Test", "MsgYesNo", bDefult )
how to convert BIN to HEX :?: how to convert HEX to BIN :?:

Code: Select all

*** hbmk2 -find hex
hbmisc.hbc
   DecToHexa()
   HexaToDec()
   IsHexa()
hbnf.hbc (instalado):
   ft_Byt2Hex()
   ft_Hex2Dec()
xhb.hbc
   HexToNum()
   HexToStr()
   NumToHex()
   StrToHex()
Harbour Core ***
   hb_HexToNum()
   hb_HexToStr()
   hb_NumToHex()
   hb_StrToHex()

*** hbmk2 -find bin
hbmisc.hbc
   BinToDec()
   DecToBin()
   IsBin()
hbnf.hbc
   ft_Dec2Bin()
Harbour Core ***  Return -> Int <- Param
   Bin2I()
   Bin2L()
   Bin2W()
   I2Bin()
   L2Bin()
how to choise CPU :?:
how to use Thread ( with different CPU ) :?:
how to use GRID (c:\hmg.3.4.4\SOURCE\h_grid.prg) :?:

Code: Select all

\hmge\SAMPLES
M., Ronaldo

By: IMATECH

Imation Tecnologia

User avatar
AUGE_OHR
Posts: 53
Joined: Sun Aug 25, 2019 3:12 pm
DBs Used: DBF, PostgreSQL, MySQL, SQLite
Location: Hamburg, Germany
Has thanked: 1 time
Been thanked: 5 times

Post by AUGE_OHR » Wed Aug 28, 2019 1:29 am

hi,

THX all for Answer

for Newbie it always the Problem "where" to search "what" as i don't know Xbase++ Parts Name is in Harbour / HMB

Code: Select all

Confirmbox() -> MsgYesNo() -> c:\hmg.3.4.4\SOURCE\h_msgbox.prg
---

about Thread i found

Code: Select all

 Hb_ThreadStart( {|| func() } )
Question : is there a "Starttime" for Thread :?:

Code: Select all

   oThread1:setStartTime( SECONDS()+1 )
   oThread1:start( {|| PostAppEvent(xbeE_Start,{0,0}) } )
---

about CPU i don't find something like "SetProcessAffinityMask" or "SMP" :?:

Code: Select all

//*-------------------   GetAffinity   --------------------
// find the current active processor (bit position)
//
function GetAffinity
  local ProcMask := 0
  local SysMask := 0
  local t := 
@kernel32:GetProcessAffinityMask(@kernel32:GetCurrentProcess(),@ProcMask,@SysMask)
return ProcMask

//*-------------------   SetAffinity   --------------------
// set the current active processor
//
function SetAffinity(nProc)
   @kernel32:SetProcessAffinityMask(@kernel32:GetCurrentProcess(),2^nProc)
return nil
---

about GRID ( c:\hmg.3.4.4\SOURCE\h_grid.prg)
is it a WC_LISTVIEW (SysListView32) :?:

i'm not sure about Syntax : does "ALIAS Test" work with ROWSOURCE "Test" ... how can i check if "PGRDD" ist working :?:

Code: Select all

   USE "SELECT * FROM "+cTable+" ;" ALIAS Test NEW VIA "pgrdd" CONNECTION nConnectionHandle
   // Check it
    ? USED()
    ? ALIAS()
    // how in harbour / HMG
    ? DBINFO( DBO_DBENAME )  // RDD Name

   DEFINE WINDOW Form_1 ;
   ....
   // hm ... why is it empty

      @ 10,10 GRID Grid_1 ;
         WIDTH 770 ;
         HEIGHT 440 ;
         HEADERS aField
         WIDTHS aWidth
         ROWSOURCE "Test"
i got the GRID with Header but no Data :o
Table have create before and i can access it with PgAdmin.

User avatar
Anand
Posts: 404
Joined: Tue May 24, 2016 4:36 pm
DBs Used: DBF
Has thanked: 110 times
Been thanked: 60 times

Post by Anand » Wed Aug 28, 2019 10:20 am

Hi Jimmy,

I see, you are trying to convert your Xbase++ codes to HMG.

Best would be, if you post whatever code you have made and we can check and suggest correction to it.
There are many ways a similar Xbase++ logic can be converted to HMG. Note, I said "logic" and not "code". There are many functions in HMG which will simplify logic and which does not exist in Xbase++. So if you try converting "code-by-code" it will be difficult for both you and us to guide.

Regards,

Anand
Image

User avatar
AUGE_OHR
Posts: 53
Joined: Sun Aug 25, 2019 3:12 pm
DBs Used: DBF, PostgreSQL, MySQL, SQLite
Location: Hamburg, Germany
Has thanked: 1 time
Been thanked: 5 times

Post by AUGE_OHR » Thu Aug 29, 2019 1:30 am

hi,

i have modify SMP Sample to run under harbour / HMG
i need to use

Code: Select all

libs=hbxpp
to use Xbase++ Syntax for DLL Call ... but it crash with harbour / HMG :?

Code: Select all

   rc := dllcall( "Kernel32.dll", DLL_STDCALL, "SetProcessAffinityMask",ip,nProc)
   rc := dllcall( "Kernel32.dll", DLL_STDCALL, "GetProcessAffinityMask",ip,@ProcMask,@SysMask)
i saw DLL Call with User32

Code: Select all

c:\hmg.3.4.4\HARBOUR\contrib\hbxpp\tests\dllcall.prg
 ? "MsgBox:", DllCall( "user32.dll", DLL_OSAPI, "MessageBoxA", 0, "Hello world!", "Harbour sez", hb_bitOr( MB_OKCANCEL, MB_ICONEXCLAMATION, MB_HELP ) )

c:\hb30\tests\testdyn.prg
 ? "MsgBox:", hb_dynCall( { "MessageBoxA", "user32.dll", HB_DYN_CALLCONV_STDCALL }, 0, "Hello world!", "Harbour sez", hb_bitOr( MB_OKCANCEL, MB_ICONEXCLAMATION, MB_HELP ) )
but do not know what to use with Kernel32 :?:

---

about SMPRUN
it will assign a CPU Core to App while running using a BitMask (2^n)

Code: Select all

Core 0   1
Core 1   2
Core 2   4
Core 3   8
---

have use HMG_CallDLL ( ) now an App start ... but i can not change CPU :(
SMPRUN.ZIP
(3.39 KiB) Downloaded 15 times

User avatar
gfilatov
Posts: 656
Joined: Fri Aug 01, 2008 5:42 am
Location: Ukraine
Has thanked: 24 times
Been thanked: 227 times
Contact:

Post by gfilatov » Thu Aug 29, 2019 6:39 pm

AUGE_OHR wrote:
Thu Aug 29, 2019 1:30 am
hi,

i have modify SMP Sample to run under harbour / HMG
...
about SMPRUN
it will assign a CPU Core to App while running using a BitMask (2^n)

Code: Select all

Core 0   1
Core 1   2
Core 2   4
Core 3   8
---

but i can not change CPU :(
Hi Jimmy,

Thanks for your sample code :!:

I was succeed with changing of a CPU core on my PC (after many wrong times).

Please take a look for the updated working sample below: :arrow:

Code: Select all

#include "dll.ch"
#include "inkey.ch"
#include "common.ch"

#define MB_OK                       0x00000000
#define MB_ICONEXCLAMATION          0x00000030

/*
 * Einfache Test-Schleife zum Abfragen/Setzen der CPU
 * 0 - Beendet Beispiel
 * 1 = Nur Erste CPU, 2 = 2. CPU, 4 = 3. CPU, 16 = 8. CPU
 */
PROCEDURE Main
LOCAL nCpu := 1 , nMax := 0
LOCAL aCPU := {1,2,4,8,16,32,64,128,256,512}
LOCAL ProcMask := 0
LOCAL SysMask := 0

#IFDEF __XPP__
   Thread():new():start("stress")
#ELSE
   REQUEST HB_GT_WIN_DEFAULT
   Hb_ThreadStart({|| Stress() } )
#ENDIF

   CLS
   nMax := CHECKCPU()
   ? "CPU have "+ STR(nMax) + " Core"

   DO WHILE .T.
       nCpu := SmpGetCPU(@ProcMask,@SysMask)

       IF EMPTY(nCpu)
         nCpu := 1
       ENDIF

       ? "Apps run under CPU(s): " + STR(nCpu)

       INPUT "New CPU-Mask: (0 => End)" TO nCpu

       IF nCpu = 0
          EXIT
       ENDIF

       IF ASCAN(aCPU, {|e| e = nCpu }) > 0
          IF SmpSetCPU(nCpu) = 0
             ? "Error CPU-Mask :" + STR(nCpu)
          ENDIF
       ENDIF
   ENDDO
RETURN

FUNCTION SmpGetCPU(ProcMask,SysMask)
LOCAL i
*#IFDEF __XPP__
*    i := DllCall("Xpprt1.dll",DLL_CDECL, "_sysGetCPU")
*#ELSE
   GetProcessAffinityMask(@ProcMask,@SysMask)
   i := Mask2CPU(ProcMask)
*#ENDIF
RETURN --i

FUNCTION SmpSetCPU(nCpuMask)
LOCAL rc
*#IFDEF __XPP__
*    rc := DllCall("Xpprt1.dll",DLL_CDECL, "_sysSetCPU", nCpuMask)
*#ELSE
    rc := SetProcessAffinityMask(nCpuMask)
*#ENDIF
RETURN rc

PROCEDURE Stress()
LOCAL a:= {3,2,1,0}
    DO WHILE .T.
        ASort(a)
    ENDDO
RETURN

* ------------------------------------------------------------------------ *
//
// Syntax need libs=hbxpp
//

FUNCTION GetCurrentProcess()
LOCAL rc := 0
   rc := dllcall( "Kernel32.dll", DLL_OSAPI, "GetCurrentProcess" )
RETURN rc

FUNCTION GetProcessAffinityMask(ProcMask,SysMask)
LOCAL rc := 0
LOCAL ip := 0
LOCAL bOldError

   bOldError := ERRORBLOCK( { | e | BREAK( e ) } )
   BEGIN SEQUENCE
      ip := GetCurrentProcess()
      rc := dllcall( "Kernel32.dll", DLL_OSAPI, "GetProcessAffinityMask",ip,@ProcMask,@SysMask)
   END SEQUENCE
   ERRORBLOCK( bOldError )

   IF EMPTY(rc)
      DllCall( "user32.dll", DLL_OSAPI, "MessageBoxA", 0, "Error GetProcessAffinityMask"+STR(ProcMask)+STR(GetLastError()), "Invalid parameter", hb_bitOr( MB_OK, MB_ICONEXCLAMATION ) )
      rc := 0
   ENDIF
RETURN rc

FUNCTION SetProcessAffinityMask(nProc)
LOCAL rc := 0
LOCAL ip := 0
LOCAL bOldError

   bOldError := ERRORBLOCK( { | e | BREAK( e ) } )
   BEGIN SEQUENCE
      ip := GetCurrentProcess()
      rc := dllcall( "Kernel32.dll", DLL_OSAPI, "SetProcessAffinityMask",ip,nProc)
   END SEQUENCE
   ERRORBLOCK( bOldError )

   IF EMPTY(rc)
      DllCall( "user32.dll", DLL_OSAPI, "MessageBoxA", 0, "Error SetProcessAffinityMask"+STR(nProc)+STR(GetLastError()), "Invalid parameter", hb_bitOr( MB_OK, MB_ICONEXCLAMATION ) )
      rc := 0
   ENDIF

RETURN rc

* ------------------------------------------------------------------------ *

*#IFDEF __XPP__
FUNCTION GetLastError()
LOCAL rc := 0
   rc := dllcall( "Kernel32.dll", DLL_OSAPI, "GetLastError")
RETURN rc
*#ENDIF

FUNCTION switchcpu( nMax )
LOCAL nWorkCPU
LOCAL nStep

   DEFAULT nMax TO 1

#IFDEF __XPP__
   IF nMax > 1
      nStep := RandomInt( 2, nMax )
   ELSE
      nStep := RandomInt( 1, nMax )
   ENDIF
#ELSE
   IF nMax > 1
      nStep := Int(Random( 2, nMax ))
   ELSE
      nStep := Int(Random( 1, nMax ))
   ENDIF
#ENDIF

   IF nStep = 1
      SmpSetCPU( 1 )
   ELSE
      nWorkCPU := 2 ^ INT( nStep - 1 )

      IF SmpSetCPU( nWorkCPU ) = 0
         SmpSetCPU( 1 )
      ENDIF
   ENDIF
   nWorkCPU := SmpGetCPU()

RETURN nStep

FUNCTION CHECKCPU()
LOCAL nStep
LOCAL nMaxCPU
   nStep := 1
   DO WHILE .T.
      nMaxCPU := 2 ^ nStep
//      IF SmpSetCPU( nMaxCPU ) = 0
         EXIT
//      ENDIF
      nStep ++
   ENDDO

   nStep := Mask2CPU(nStep)

RETURN nStep

FUNCTION Mask2CPU(nMask)
LOCAL nCPU := 1
LOCAL nRest := nMask

   DO WHILE nRest >= 1
      nRest := nRest / 2
      nCPU++
   ENDDO

RETURN nCPU

*
*
*
Please note that I should set the multithread switch in my link script for correct work of above application.

Hope that helps :idea:
Kind Regards,
Grigory Filatov

"Everything should be made as simple as possible, but no simpler." Albert Einstein

User avatar
AUGE_OHR
Posts: 53
Joined: Sun Aug 25, 2019 3:12 pm
DBs Used: DBF, PostgreSQL, MySQL, SQLite
Location: Hamburg, Germany
Has thanked: 1 time
Been thanked: 5 times

Post by AUGE_OHR » Thu Aug 29, 2019 8:28 pm

hi,
gfilatov wrote:
Thu Aug 29, 2019 6:39 pm
I was succeed with changing of a CPU core on my PC (after many wrong times).
THX for your Time and working Sample.
gfilatov wrote: Please take a look for the updated working sample below: :arrow:
as i can see you change Constant DLL_STDCALL to DLL_OSAPI.

i have test your Sample with Xbase++ and it still run with DLL_OSAPI
so i have to check my Xbase++ Code where i used DLL_STDCALL and try DLL_OSAPI instead

while i want to learn harbour / HMG i like to ask how it look like

Code: Select all

#IFDEF __XPP__
   rc := dllcall( "Kernel32.dll", DLL_OSAPI, "GetCurrentProcess" )
#ELSE
*  rc := hb_dynCall( "GetCurrentProcess", "Kernel32.dll", HB_DYN_CALLCONV_SYSCALL  )
   rc := HMG_CallDLL ( "Kernel32.dll", HB_DYN_CALLCONV_SYSCALL, "GetCurrentProcess" )
#ENDIF
gfilatov wrote: Please note that I should set the multithread switch in my link script for correct work of above application.
is this in *.HBC :?:

Code: Select all

libs=hbxpp
mt=yes
i do not know about harbour / HMG Multithread. can i use more than 1 x Core for harbour / HMG :?:

---

as Xbase++ can only use 1 x Core i have ASCAN() in Demo Code to validate if it is 2^n

with harbour / HMG you can try other combination of e.g.

Code: Select all

(2^1) + (2^2) + (2^3) + (2^4)
to run on 4 x CPU

SetProcessAffinityMask() is for hole App. for Thread is a SetThreadAffinityMask() API Function
https://docs.microsoft.com/de-de/window ... finitymask

but it need an Pointer so i add Variable pThread

Code: Select all

   pThread := Hb_ThreadStart({|| Stress() } )
and HMG Debugger show me pThread as Pointer but no Value :?:

User avatar
AUGE_OHR
Posts: 53
Joined: Sun Aug 25, 2019 3:12 pm
DBs Used: DBF, PostgreSQL, MySQL, SQLite
Location: Hamburg, Germany
Has thanked: 1 time
Been thanked: 5 times

Post by AUGE_OHR » Sun Sep 01, 2019 4:45 am

hi,

what is used in harbour / HMG for
PeekWord(<pMem>,[[@]<nShift>]) -> <nWord>
PeekWord(<pMem>,[[@]<nShift>], <nItems>) -> <aWords>

Retrieve the value of one or more WORDs from the memory buffer pointed by <pMem> starting at the position <nShift>.
attach Sample is to detect if DLL is for 32 Bit or 64 Bit
DLL6432.ZIP
(617 Bytes) Downloaded 12 times

Code: Select all

#include "Fileio.ch"
#include "ot4xb.ch" // this include Ot4Xb.LIB which have PeekWord()

#define IMAGE_FILE_MACHINE_I386  0x14c
#define IMAGE_FILE_MACHINE_IA64  0x200
#define IMAGE_FILE_MACHINE_AMD64 0x8664

PROCEDURE Main(cDLL)
LOCAL cBuffer, nHandle, nBytes, nPointer
LOCAL cMachineType
LOCAL hHex
LOCAL cText := ""

   IF !FILE(cDLL)
      ALERT("Dll Name missing")
      QUIT
   ENDIF

   nHandle  := FOpen( cDLL , FO_READ )
   cBuffer  := Space(512)
   nBytes   := FRead(nHandle, @cBuffer, 512)
   FClose( nHandle )

   nPointer := AT("PE"+CHR(0)+CHR(0),cBuffer)
   IF nPointer > 0
      cMachineType := ( SUBSTR(cBuffer,nPointer+4,2) )
      
 // this line
      hHex := PeekWord(cMachineType)
      DO CASE
         CASE hHex = IMAGE_FILE_MACHINE_I386
            cText := "for 32bit Machine"

         CASE hHex = IMAGE_FILE_MACHINE_IA64 .OR. ;
                   hHex = IMAGE_FILE_MACHINE_AMD64
            cText := "for 64bit Machine"

      OTHERWISE
            cText := "unknown Machine"
      ENDCASE
   ENDIF

   ALERT(cText)
RETURN

Post Reply