/*
 * Xailer source code:
 *
 * Core.c
 * Conjunto de funciones en C de apoyo a la librerķa
 *
 * Copyright 2003, 2007 Jose F. Gimenez
 * Copyright 2003, 2007 Xailer.com
 * All rights reserved
 *
 */

#undef _WIN32_WINNT
#define _WIN32_WINNT 0x0500
#define _WIN32_IE 0x0400

#include <windows.h>
#include <commctrl.h>
#include <psapi.h>
#include <xailer.h>
#include <hbset.h>


//--------------------------------------------------------------------------

XA_FUNC( REGISTERCLASS )  // RegisterClass( <cClassName>, <nClassStyle>, <hCursor>, <hBrush> ) --> nClassId
{
   WNDCLASSEX WndClassEx;

   WndClassEx.cbSize = sizeof( WNDCLASSEX );
   WndClassEx.style = hb_parnl( 2 );
   WndClassEx.lpfnWndProc = WindowProc;
   WndClassEx.cbClsExtra = 0;
   WndClassEx.cbWndExtra = 0;
   WndClassEx.hInstance = GetInstance( 0 );
   WndClassEx.hIcon = (HANDLE) NULL;
   WndClassEx.hCursor = (HANDLE) hb_parnl( 3 );
   WndClassEx.hbrBackground = (HANDLE) hb_parnl( 4 );
   WndClassEx.lpszMenuName = NULL;
   WndClassEx.lpszClassName = hb_parc( 1 );
   WndClassEx.hIconSm = (HANDLE) NULL;

   hb_retnl( RegisterClassEx( &WndClassEx ) );
}

//--------------------------------------------------------------------------

XA_FUNC( GETCLASSINFO )  // GetClassInfo( <cClassName>, <nClassStyle>, <hCursor>, <hBrush> ) --> lSuccess
{
   WNDCLASSEX WndClassEx;

   WndClassEx.cbSize = sizeof( WNDCLASSEX );
   WndClassEx.style = hb_parnl( 2 );
   WndClassEx.lpfnWndProc = WindowProc;
   WndClassEx.cbClsExtra = 0;
   WndClassEx.cbWndExtra = 0;
   WndClassEx.hInstance = GetInstance( 0 );
   WndClassEx.hIcon = (HANDLE) NULL;
   WndClassEx.hCursor = (HANDLE) hb_parnl( 3 );
   WndClassEx.hbrBackground = (HANDLE) hb_parnl( 4 );
   WndClassEx.lpszMenuName = NULL;
   WndClassEx.lpszClassName = hb_parc( 1 );
   WndClassEx.hIconSm = (HANDLE) NULL;

   hb_retl( GetClassInfoEx( GetInstance( 0 ), hb_parc( 1 ), &WndClassEx ) );
}

//--------------------------------------------------------------------------

XA_FUNC( GETCLASSNAME ) // GetClassName( <hWnd> ) --> cClassName
{
   char szName[256];
   int nLen;

   nLen = GetClassName( (HWND) hb_parnl( 1 ), szName, 256 );

   hb_retclen( szName, nLen );
}

//--------------------------------------------------------------------------

XA_FUNC( CREATEWINDOW ) // CreateWindow( <cClassName>, <cName>, <nStyle>, <nExStyle>, <nX>, <nY>, <nWidth>, <nHeight>, <hWndParent>, <hMenu> ) --> hWnd
{
   hb_retnl( (long) CreateWindowEx( hb_parnl( 4 ),          //DWORD dwExStyle,
                                    hb_parc( 1 ),           //LPCTSTR lpClassName,
                                    hb_parc( 2 ),           //LPCTSTR lpWindowName,
                                    hb_parnl( 3 ),          //DWORD dwStyle,
                                    hb_parnl( 5 ),          //int x,
                                    hb_parnl( 6 ),          //int y,
                                    hb_parnl( 7 ),          //int nWidth,
                                    hb_parnl( 8 ),          //int nHeight,
                                    (HWND) hb_parnl( 9 ),   //HWND hWndParent,
                                    (HMENU) hb_parnl( 10 ), //HMENU hMenu,
                                    GetInstance( 0 ),       //HANDLE hInstance,
                                    NULL ) );               //LPVOID lpParam
}

//--------------------------------------------------------------------------

XA_FUNC( DESTROYWINDOW )   // DestroyWindow( <hWnd> ) --> lSuccess
{
   hb_retl( DestroyWindow( (HWND) hb_parnl( 1 ) ) );
}

//--------------------------------------------------------------------------

XA_FUNC( SHOWWINDOW )      // ShowWindow( <hWnd>, <nShow> ) --> lSuccess
{
   hb_retl( ShowWindow( (HWND) hb_parnl( 1 ), hb_parnl( 2 ) ) );
}

//--------------------------------------------------------------------------

XA_FUNC( ENABLEWINDOW )    // EnableWindow( <hWnd>, <lEnable> ) --> lSuccess
{
   hb_retl( EnableWindow( (HWND) hb_parnl( 1 ), hb_parl( 2 ) ) );
}

//--------------------------------------------------------------------------

XA_FUNC( MOVEWINDOW )      // MoveWindow( <hWnd>, <nX>, <nY>, <nWidth>, <nHeight>, <lRepaint> ) --> lSuccess
{
   hb_retl( MoveWindow( (HWND) hb_parnl( 1 ), hb_parnl( 2 ), hb_parnl( 3 ),
                        hb_parnl( 4 ), hb_parnl( 5 ), hb_parl( 6 ) ) );
}

//--------------------------------------------------------------------------

XA_FUNC( SETWINDOWPOS ) // SetWindowPos( <hWnd>, <hWndAfter>, <nX>, <nY>, <nNewWidth>, <nNewHeight>, <nFlags> ) --> lSuccess
{
   hb_retl( SetWindowPos( (HWND) hb_parnl( 1 ), (HWND) hb_parnl( 2 ),
                          hb_parnl( 3 ), hb_parnl( 4 ), hb_parnl( 5 ),
                          hb_parnl( 6 ), hb_parnl( 7 ) ) );
}

//--------------------------------------------------------------------------

XA_EXPORT void CenterWindow( HWND hWnd, HWND hWndBase ) // CenterWindow( <hWnd>, <hWndBase ) --> void
{
   RECT WndRect, ScrRect;

   if( hWndBase == NULL )
      {
      HWND hOwner = NULL;
      MONITORINFO mi;

      if( !IsWindowVisible( hWnd ) )
         hOwner = GetWindow( hWnd, GW_OWNER );
      if( hOwner == NULL )
         hOwner = hWnd;
      mi.cbSize = sizeof( MONITORINFO );
      if( GetMonitorInfo( MonitorFromWindow( hOwner, MONITOR_DEFAULTTOPRIMARY ), &mi ) )
         CopyRect( &ScrRect, &mi.rcMonitor );
      else
         GetWindowRect( GetDesktopWindow(), &ScrRect );
      }
   else
      GetWindowRect( hWndBase, &ScrRect );
   GetWindowRect( hWnd, &WndRect );
   WndRect.left = ( ScrRect.right + ScrRect.left - WndRect.right + WndRect.left ) >> 1;
   WndRect.top = ( ScrRect.bottom + ScrRect.top - WndRect.bottom + WndRect.top ) >> 1;
   SetWindowPos( hWnd, NULL, WndRect.left, WndRect.top, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE );
}

//--------------------------------------------------------------------------

XA_FUNC( CENTERWINDOW )    // CenterWindow( <hWnd>, [<hWndParent>] ) --> Nil
{
   CenterWindow( (HWND) hb_parnl( 1 ), (HWND) hb_parnl( 2 ) );
}

//--------------------------------------------------------------------------

XA_FUNC( CENTERMDIWINDOW ) // CenterMDIWindow( <hWnd> ) --> Nil
{
   HWND hWnd = (HWND) hb_parnl( 1 );
   HWND hWndBase = GetParent( hWnd );
   RECT WndRect, ScrRect;

   if( hWndBase )
      {
      GetClientRect( hWndBase, &ScrRect );
      GetWindowRect( hWnd, &WndRect );
      WndRect.left = ( ScrRect.right - WndRect.right + WndRect.left ) >> 1;
      WndRect.top = ( ScrRect.bottom - WndRect.bottom + WndRect.top ) >> 1;
      SetWindowPos( hWnd, NULL, WndRect.left, WndRect.top, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE );
      }
}

//--------------------------------------------------------------------------

typedef BOOL (WINAPI * _SetLayeredWindowAttributes)( HWND, COLORREF, BYTE, DWORD );

XA_FUNC( SETLAYEREDWINDOWATTRIBUTES )  // SetLayeredWindowAttributes( hWnd, nColorKey, nAlpha, nFlags ) --> lSuccess
{
   BOOL bSuccess = FALSE;
   _SetLayeredWindowAttributes fn = (void *) GetProcAddress( GetModuleHandle( "user32.dll" ), "SetLayeredWindowAttributes" );

   if( fn )
      bSuccess = fn( (HWND) hb_parnl( 1 ), hb_parnl( 2 ), hb_parnl( 3 ), hb_parnl( 4 ) );

   hb_retl( bSuccess );
}

//--------------------------------------------------------------------------

typedef BOOL (WINAPI * _UpdateLayeredWindow)( HWND, HDC, POINT *, SIZE *, HDC, POINT *, COLORREF, BLENDFUNCTION *, DWORD );

XA_FUNC( UPDATELAYEREDWINDOW )  // UpdateLayeredWindow( hWnd, hdcDst, nLeft, nTop, nWidth, nHeight, hdcSrc, nSrcX, nSrcY, nColorKey, nAlpha, nFlags ) --> lSuccess
{
   BOOL bSuccess = FALSE;
   _UpdateLayeredWindow fn = GetProcAddress( GetModuleHandle( "user32.dll" ), "UpdateLayeredWindow" );

   if( fn )
      {
      POINT pptDst, pptSrc;
      SIZE siz;
      BLENDFUNCTION bf;

      pptDst.x = hb_parnl( 3 );
      pptDst.y = hb_parnl( 4 );
      siz.cx = hb_parnl( 5 );
      siz.cy = hb_parnl( 6 );
      pptSrc.x = hb_parnl( 8 );
      pptSrc.y = hb_parnl( 9 );
      bf.BlendOp = AC_SRC_OVER;
      bf.BlendFlags = 0;
      bf.SourceConstantAlpha = hb_parnl( 11 );
      bf.AlphaFormat = AC_SRC_ALPHA;
      bSuccess = fn( (HWND) hb_parnl( 1 ), (HDC) hb_parnl( 2 ), HB_ISNIL( 3 ) || HB_ISNIL( 4 ) ? NULL : &pptDst,
                     HB_ISNIL( 5 ) || HB_ISNIL( 6 ) ? NULL : &siz, (HDC) hb_parnl( 7 ), HB_ISNIL( 8 ) || HB_ISNIL( 9 ) ? NULL : &pptSrc,
                     hb_parnl( 10 ), &bf, hb_parnl( 12 ) );
      }

   hb_retl( bSuccess );
}

//--------------------------------------------------------------------------

XA_FUNC( SETPARENT )    // SetParent( <hWnd>, <hWndParent> ) --> lSuccess
{
   hb_retl( (BOOL) SetParent( (HWND) hb_parnl( 1 ), (HWND) hb_parnl( 2 ) ) );
}

//--------------------------------------------------------------------------

XA_FUNC( GETPARENT )    // GetParent( <hWnd> ) --> hWndParent
{
   hb_retnl( (LONG) GetParent( (HWND) hb_parnl( 1 ) ) );
}

//--------------------------------------------------------------------------

XA_FUNC( SENDMESSAGE )  // SendMessage( <hWnd>, <nMsg>, <nWParam>, <nLParam> ) --> nResult
{
   HANDLE Handle = (HANDLE) hb_parnl( 1 );
   WPARAM wParam;
   LPARAM lParam;

   if( HB_ISNUM( 3 ) )
      wParam = hb_parnl( 3 );
   else if( HB_ISLOG( 3 ) )
      wParam = hb_parl( 3 ) ? TRUE : FALSE;
   else if( HB_ISCHAR( 3 ) )
      wParam = (WPARAM) hb_parc( 3 );
   else
      wParam = 0;

   if( HB_ISNUM( 4 ) )
      lParam = hb_parnl( 4 );
   else if( HB_ISLOG( 4 ) )
      lParam = hb_parl( 4 ) ? TRUE : FALSE;
   else if( HB_ISCHAR( 4 ) )
      lParam = (LPARAM) hb_parc( 4 );
   else
      lParam = 0;

   if( Handle )
      hb_retnl( SendMessage( Handle, hb_parnl( 2 ), wParam, lParam ) );
   else
      hb_retnl( 0 );
}

//--------------------------------------------------------------------------

XA_FUNC( POSTMESSAGE )     // PostMessage( <hWnd>, <nMsg>, <nWParam>, <nLParam> ) --> nResult
{
   HANDLE Handle = (HANDLE) hb_parnl( 1 );
   WPARAM wParam;
   LPARAM lParam;

   if( HB_ISNUM( 3 ) )
      wParam = hb_parnl( 3 );
   else if( HB_ISLOG( 3 ) )
      wParam = hb_parl( 3 ) ? TRUE : FALSE;
   else if( HB_ISCHAR( 3 ) )
      wParam = (WPARAM) hb_parc( 3 );
   else
      wParam = 0;

   if( HB_ISNUM( 4 ) )
      lParam = hb_parnl( 4 );
   else if( HB_ISLOG( 4 ) )
      lParam = hb_parl( 4 ) ? TRUE : FALSE;
   else if( HB_ISCHAR( 4 ) )
      lParam = (LPARAM) hb_parc( 4 );
   else
      lParam = 0;

   if( Handle )
      hb_retnl( PostMessage( Handle, hb_parnl( 2 ), wParam, lParam ) );
   else
      hb_retnl( 0 );
}

//--------------------------------------------------------------------------

XA_FUNC( POSTQUITMESSAGE )    // PostQuitMessage( <hWnd> ) --> Nil
{
   PostQuitMessage( hb_parnl( 1 ) );
}

//--------------------------------------------------------------------------

XA_FUNC( GETSYSCOLOR )        // GetSysColor( <nIndex> ) --> nColor
{
   hb_retnl( GetSysColor( hb_parnl( 1 ) ) );
}

//--------------------------------------------------------------------------

XA_FUNC( SETBKMODE )          // SetBkMode( <hDC>, <nMode> ) --> nOldMode
{
   hb_retnl( SetBkMode( (HDC) hb_parnl( 1 ), hb_parnl( 2 ) ) );
}

//--------------------------------------------------------------------------

XA_FUNC( SETBKCOLOR )         // SetBkColor( <hDC>, <nColor> ) --> nOldColor
{
   hb_retnl( SetBkColor( (HDC) hb_parnl( 1 ), hb_parnl( 2 ) ) );
}

//--------------------------------------------------------------------------

XA_FUNC( SETTEXTCOLOR )       // SetTextColor( <hDC>, <nColor> ) --> nOldColor
{
   hb_retnl( SetTextColor( (HDC) hb_parnl( 1 ), hb_parnl( 2 ) ) );
}

//--------------------------------------------------------------------------

XA_FUNC( UPDATEWINDOW )       // UpdateWindow( <hWnd> ) --> lSuccess
{
   hb_retl( UpdateWindow( (HWND) hb_parnl( 1 ) ) );
}

//--------------------------------------------------------------------------

XA_FUNC( SETACTIVEWINDOW )    // SetActiveWindow( <hWnd> ) --> lSuccess
{
   hb_retl( (BOOL) SetActiveWindow( (HWND) hb_parnl( 1 ) ) );
}

//--------------------------------------------------------------------------

XA_FUNC( GETACTIVEWINDOW )    // GetActiveWindow() --> hWnd
{
   hb_retnl( (long) GetActiveWindow() );
}

//--------------------------------------------------------------------------

XA_FUNC( SETFOREGROUNDWINDOW )   // SetForegroundWindow( <hWnd> ) --> lSuccess
{
   hb_retl( SetForegroundWindow( (HWND) hb_parnl( 1 ) ) );
}

//--------------------------------------------------------------------------

XA_FUNC( GETFOREGROUNDWINDOW )   // GetForegroundWindow() --> hWnd
{
   hb_retnl( (long) GetForegroundWindow() );
}

//--------------------------------------------------------------------------

XA_FUNC( GETDESKTOPWINDOW )      // GetDesktopWindow() --> hWndDesktop
{
   hb_retnl( (long) GetDesktopWindow() );
}

//--------------------------------------------------------------------------

XA_FUNC( SETWINDOWLONG )         // SetWindowLong( <hWnd>, <nIndex>, <nData> ) --> nOldData
{
   hb_retnl( SetWindowLong( (HWND) hb_parnl( 1 ), hb_parnl( 2 ), hb_parnl( 3 ) ) );
}

//--------------------------------------------------------------------------

XA_FUNC( GETWINDOWLONG )         // GetWindowLong( <hWnd>, <nIndex> ) --> nData
{
   hb_retnl( GetWindowLong( (HWND) hb_parnl( 1 ), hb_parnl( 2 ) ) );
}

//--------------------------------------------------------------------------

XA_FUNC( ISWINDOW )              // IsWindow( <hWnd> ) --> lSuccess
{
   hb_retl( IsWindow( (HWND) hb_parnl( 1 ) ) );
}

//--------------------------------------------------------------------------

XA_FUNC( ISWINDOWVISIBLE )       // IsWindowVisible( <hWnd> ) --> lVisible
{
   hb_retl( IsWindowVisible( (HWND) hb_parnl( 1 ) ) );
}

//--------------------------------------------------------------------------

XA_FUNC( ISWINDOWENABLED )       // IsWindowEnabled( <hWnd> ) --> lEnabled
{
   hb_retl( IsWindowEnabled( (HWND) hb_parnl( 1 ) ) );
}

//--------------------------------------------------------------------------

XA_FUNC( ISCHILD )               // IsChild( <hWndParent>, <hWnd> ) --> lChild
{
   hb_retl( IsChild( (HWND) hb_parnl( 1 ), (HWND) hb_parnl( 2 ) ) );
}

//--------------------------------------------------------------------------

XA_FUNC( SETCLASSLONG )          // SetClassLong( <hWnd>, <nIndex>, <nData> ) --> nOldData
{
   hb_retnl( SetClassLong( (HWND) hb_parnl( 1 ), hb_parnl( 2 ), hb_parnl( 3 ) ) );
}

//--------------------------------------------------------------------------

XA_FUNC( GETCLASSLONG )          // GetClassLong( <hWnd>, <nIndex> ) --> nData
{
   hb_retnl( GetClassLong( (HWND) hb_parnl( 1 ), hb_parnl( 2 ) ) );
}

//--------------------------------------------------------------------------

XA_FUNC( GETWINDOWTEXT )         // GetWindowText( <hWnd> ) --> cText
{
   int  nLen = GetWindowTextLength( (HWND) hb_parnl( 1 ) );
   char *cText = hb_xgrab( nLen + 1 );

   GetWindowText( (HWND) hb_parnl( 1 ), cText, nLen + 1 );
   hb_retc( cText );
   hb_xfree( cText );
}

//--------------------------------------------------------------------------

XA_FUNC( SETWINDOWTEXT )         // SetWindowText( <hWnd>, <cText> ) --> lSuccess
{
   hb_retl( SetWindowText( (HWND) hb_parnl( 1 ), hb_parc( 2 ) ) );
}

//--------------------------------------------------------------------------

XA_FUNC( MAKELPARAM )            // MakeLParam( <nWord1>, <nWord2> ) --> nLParam
{
   hb_retnl( MAKELPARAM( hb_parnl( 1 ), hb_parnl( 2 ) ) );
}

//--------------------------------------------------------------------------

XA_FUNC( MAKEWORD )              // MakeWord( <nByte1>, <nByte2> ) --> nWord
{
   hb_retnl( MAKEWORD( hb_parnl( 1 ), hb_parnl( 2 ) ) );
}

//--------------------------------------------------------------------------

XA_FUNC( MAKELONG )              // MakeLong( <nWord1>, <nWord2> ) --> nDWord
{
   hb_retnll( (ULONG) MAKELONG( hb_parnl( 1 ), hb_parnl( 2 ) ) );
}

//--------------------------------------------------------------------------

XA_FUNC( MAKELONGLONG )          // MakeLongLong( <nLong1>, <nLong2> ) --> nLongLong
{
   hb_retnll( (ULONG) hb_parnl( 1 ) | ( (HB_LONGLONG) ( (ULONG) hb_parnl( 2 ) ) << 32 ) );
}

//--------------------------------------------------------------------------

XA_FUNC( LOBYTE )                // LoByte( <nWord> ) --> nByte
{
   hb_retnl( LOBYTE( hb_parnl( 1 ) ) );
}

//--------------------------------------------------------------------------

XA_FUNC( HIBYTE )                // HiByte( <nWord> ) --> nByte
{
   hb_retnl( HIBYTE( hb_parnl( 1 ) ) );
}

//--------------------------------------------------------------------------

XA_FUNC( LOINT )                // LoInt( <nLong> ) --> nInt
{
   hb_retni( (short) LOINT( hb_parnl( 1 ) ) );
}

//--------------------------------------------------------------------------

XA_FUNC( HIINT )                // HiInt( <nLong> ) --> nInt
{
   hb_retni( (short) HIINT( hb_parnl( 1 ) ) );
}

//--------------------------------------------------------------------------

XA_FUNC( LOWORD )                // LoWord( <nDWord> ) --> nWord
{
   hb_retni( (short) LOWORD( hb_parnl( 1 ) ) );
}

//--------------------------------------------------------------------------

XA_FUNC( HIWORD )                // HiWord( <nDWord> ) --> nWord
{
   hb_retni( (short) HIWORD( hb_parnl( 1 ) ) );
}

//--------------------------------------------------------------------------

XA_FUNC( LOLONG )                // LoLong( <nLongLong> ) --> nLong
{
   hb_retnl( (ULONG) hb_parnll( 1 ) & 0xFFFFFFFF );
}

//--------------------------------------------------------------------------

XA_FUNC( HILONG )                // HiLong( <nLongLong> ) --> nLong
{
   hb_retnl( (ULONG) ( ( (HB_ULONGLONG) hb_parnll( 1 ) ) >> 32 ) & 0xFFFFFFFF );
}

//--------------------------------------------------------------------------

XA_FUNC( LAND )                  // lAnd( <nValue1>, ..., <nValueN> ) --> lResult
{
   int i;
   HB_ULONGLONG ret = (HB_ULONGLONG) hb_parnll( 1 );

   for ( i = 2; i <= hb_pcount(); i++ )
      ret = ret & hb_parnll( i );

   hb_retl( ret != 0 );
}

//--------------------------------------------------------------------------

XA_FUNC( NAND )                  // nAnd( <nValue1>, ..., <nValueN> ) --> nResult
{
   int i;
   HB_ULONGLONG ret = (HB_ULONGLONG) hb_parnll( 1 );

   for ( i = 2; i <= hb_pcount(); i++ )
      ret = ret & hb_parnll( i );

   hb_retnll( ret );
}

//--------------------------------------------------------------------------

XA_FUNC( LOR )                   // lOr( <nValue1>, ..., <nValueN> ) --> lResult
{
   int i;
   HB_ULONGLONG ret = (HB_ULONGLONG) hb_parnll( 1 );

   for ( i = 2; i <= hb_pcount(); i++ )
      ret = ret | hb_parnll( i );

   hb_retl( ret != 0 );
}

//--------------------------------------------------------------------------

XA_FUNC( NOR )                   // nOr( <nValue1>, ..., <nValueN> ) --> nResult
{
   int i;
   HB_ULONGLONG ret = (HB_ULONGLONG) hb_parnll( 1 );

   for ( i = 2; i <= hb_pcount(); i++ )
      ret = ret | hb_parnll( i );

   hb_retnll( ret );
}

//--------------------------------------------------------------------------

XA_FUNC( NEXCLUDE )              // nExclude( <nValue1>, ..., <nValueN> ) --> nResult
{
   int i;
   HB_ULONGLONG ret = (HB_ULONGLONG) hb_parnll( 1 );

   for ( i = 2; i <= hb_pcount(); i++ )
      ret = ret & ~hb_parnll( i );

   hb_retnll( ret );
}

//--------------------------------------------------------------------------

XA_FUNC( LXOR )                  // lXOr( <nValue1>, ..., <nValueN> ) --> lResult
{
   int i;
   BOOL ret = HB_ISNUM( 1 ) ? hb_parnll( 1 ) : hb_parl( 1 );

   for ( i = 2; i <= hb_pcount(); i++ )
      ret = ret ^ ( HB_ISNUM( i ) ? hb_parnll( i ) : hb_parl( i ) );

   hb_retl( ret );
}

//--------------------------------------------------------------------------

XA_FUNC( NXOR )                  // nXOr( <nValue1>, ..., <nValueN> ) --> nResult
{
   int i;
   HB_ULONGLONG ret = (HB_ULONGLONG) hb_parnll( 1 );

   for ( i = 2; i <= hb_pcount(); i++ )
      ret = ret ^ hb_parnll( i );

   hb_retnll( ret );
}

//--------------------------------------------------------------------------

XA_FUNC( NNOT )                  // nNot( <nValue1>, ..., <nValueN> ) --> nResult
{
   hb_retnll( ~( (HB_ULONGLONG) hb_parnll( 1 ) ) );
}

//--------------------------------------------------------------------------

XA_FUNC( SHR )                   // SHR( <nValue1>, <nValue2> ) --> nResult
{
   hb_retnll( ( (HB_ULONGLONG) hb_parnll( 1 ) ) >> hb_parni( 2 ) );
}

//--------------------------------------------------------------------------

XA_FUNC( SHL )                   // SHL( <nValue1>, <nValue2> ) --> nResult
{
   hb_retnll( ( (HB_ULONGLONG) hb_parnll( 1 ) ) << hb_parni( 2 ) );
}

//--------------------------------------------------------------------------

XA_FUNC( BEGINPAINT )   // BeginPaint( <hWnd>, <@pPaintStruct> ) --> hDC
{
   PAINTSTRUCT ps;
   HDC hdc;

   hdc = BeginPaint( (HWND) hb_parnl( 1 ), &ps );
   hb_storclen( (void *) &ps, sizeof( PAINTSTRUCT ), 2 );
   hb_retnl( (long) hdc );
}

//--------------------------------------------------------------------------

XA_FUNC( ENDPAINT )     // EndPaint( <hWnd>, <pPaintStruct> ) --> lSuccess
{
   hb_retl( EndPaint( (HWND) hb_parnl( 1 ), (LPVOID) hb_parc( 2 ) ) );
}

//--------------------------------------------------------------------------

XA_FUNC( INVALIDATERECT )  // InvalidateRect( <hWnd>, [<aRect>], <lRedraw> ) --> lSuccess
{
   RECT rect;

   if ( HB_ISARRAY( 2 ) )
      {
      rect.left = hb_parvnl( 2, 1 );
      rect.top = hb_parvnl( 2, 2 );
      rect.right = hb_parvnl( 2, 3 );
      rect.bottom = hb_parvnl( 2, 4 );
      hb_retl( InvalidateRect( (HWND) hb_parnl( 1 ), &rect, hb_parl( 3 ) ) );
      }
   else
      hb_retl( InvalidateRect( (HWND) hb_parnl( 1 ), NULL, hb_parl( 3 ) ) );
}

//--------------------------------------------------------------------------

XA_FUNC( VALIDATERECT )    // ValidateRect( <hWnd>, [<aRect>] ) --> lSuccess
{
   RECT rect;

   if ( HB_ISARRAY( 2 ) )
      {
      rect.left = hb_parvnl( 2, 1 );
      rect.top = hb_parvnl( 2, 2 );
      rect.right = hb_parvnl( 2, 3 );
      rect.bottom = hb_parvnl( 2, 4 );
      hb_retl( ValidateRect( (HWND) hb_parnl( 1 ), &rect ) );
      }
   else
      hb_retl( ValidateRect( (HWND) hb_parnl( 1 ), NULL ) );
}

//--------------------------------------------------------------------------

XA_FUNC( REDRAWWINDOW )    // RedrawWindow( <hWnd>, [<aRect>], [<hRgn>], <nFlags> ) --> lSuccess
{
   RECT rect;

   if ( HB_ISARRAY( 2 ) )
      {
      rect.left = hb_parvnl( 2, 1 );
      rect.top = hb_parvnl( 2, 2 );
      rect.right = hb_parvnl( 2, 3 );
      rect.bottom = hb_parvnl( 2, 4 );
      hb_retl( RedrawWindow( (HWND) hb_parnl( 1 ), &rect, (HRGN) hb_parnl( 3 ), hb_parnl( 4 ) ) );
      }
   else
      hb_retl( RedrawWindow( (HWND) hb_parnl( 1 ), NULL, (HRGN) hb_parnl( 3 ), hb_parnl( 4 ) ) );
}

//--------------------------------------------------------------------------

XA_FUNC( GETLASTERROR )    // GetLastError() --> nLastError
{
   hb_retnl( GetLastError() );
}

//--------------------------------------------------------------------------

XA_FUNC( INITCOMMONCONTROLS )    // InitCommonControls( <nICC> ) --> lSuccess
{
   INITCOMMONCONTROLSEX icex;

   icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
   icex.dwICC   = hb_parnl( 1 );

   hb_retl( InitCommonControlsEx( &icex ) );
}

//--------------------------------------------------------------------------

HB_FUNC( GETCLIENTRECT )   // GetClientRect( <hwnd>, [<@aRect>] | [<@nLeft>, <@nTop>, <@nRight>, <@nBottom>] ) --> aRect
{
   RECT rect;

   GetClientRect( (HWND) hb_parnl( 1 ), &rect );

   if ( hb_pcount() == 2 )  // 2nd param is an array
      {
      hb_storvnl( rect.left, 2, 1 );
      hb_storvnl( rect.top, 2, 2 );
      hb_storvnl( rect.right, 2, 3 );
      hb_storvnl( rect.bottom, 2, 4 );
      }
   else if ( hb_pcount() == 5 )  // 2dn to 5th params is a rect
      {
      hb_stornl( rect.left, 2 );
      hb_stornl( rect.top, 3 );
      hb_stornl( rect.right, 4 );
      hb_stornl( rect.bottom, 5 );
      }
   else
      {
      hb_reta( 4 );
      hb_storvnl( rect.left, -1, 1 );
      hb_storvnl( rect.top, -1, 2 );
      hb_storvnl( rect.right, -1, 3 );
      hb_storvnl( rect.bottom, -1, 4 );
      }
}

//--------------------------------------------------------------------------

XA_FUNC( GETWINDOWRECT )   // GetWindowRect( <hwnd>, [<@aRect>] | [<@nLeft>, <@nTop>, <@nRight>, <@nBottom>] ) --> aRect
{
   RECT rect;

   GetWindowRect( (HWND) hb_parnl( 1 ), &rect );

   if ( hb_pcount() == 2 )  // 2nd param is an array
      {
      hb_storvnl( rect.left, 2, 1 );
      hb_storvnl( rect.top, 2, 2 );
      hb_storvnl( rect.right, 2, 3 );
      hb_storvnl( rect.bottom, 2, 4 );
      }
   else if ( hb_pcount() == 5 )  // 2dn to 5th params is a rect
      {
      hb_stornl( rect.left, 2 );
      hb_stornl( rect.top, 3 );
      hb_stornl( rect.right, 4 );
      hb_stornl( rect.bottom, 5 );
      }
   else
      {
      hb_reta( 4 );
      hb_storvnl( rect.left, -1, 1 );
      hb_storvnl( rect.top, -1, 2 );
      hb_storvnl( rect.right, -1, 3 );
      hb_storvnl( rect.bottom, -1, 4 );
      }
}

//--------------------------------------------------------------------------

XA_FUNC( SETFOCUS )     // SetFocus( <hWnd> ) --> hWndPrev
{
   hb_retnl( (long) SetFocus( (HWND) hb_parnl( 1 ) ) );
}

//--------------------------------------------------------------------------

XA_FUNC( GETFOCUS )     // GetFocus() --> hWnd
{
   hb_retnl( (long) GetFocus() );
}

//--------------------------------------------------------------------------

XA_FUNC( CREATECARET )     // CreateCaret( <hWnd>, <hBitmap>, <nWidth>, <nHeight> ) --> lSuccess
{
   HWND hWnd = (HWND) hb_parnl( 1 );
   int nWidth = hb_parnl( 3 );
   int nHeight = hb_parnl( 4 );

   if( ( nWidth == -1 ) || ( nHeight == -1 ) )
      {
      HDC hdc = GetDC( hWnd );
      TEXTMETRIC tm;

      GetTextMetrics( hdc, &tm );
      if( nWidth == -1 )
         nWidth = tm.tmAveCharWidth;
      if( nHeight == -1 )
         nHeight = tm.tmAscent;
      ReleaseDC( hWnd, hdc );
      }

   hb_retl( CreateCaret( hWnd, (HBITMAP) hb_parnl( 2 ), nWidth, nHeight ) );
}

//--------------------------------------------------------------------------

XA_FUNC( SHOWCARET )    // ShowCaret( <hWnd> ) --> lSuccess
{
   hb_retl( ShowCaret( (HWND) hb_parnl( 1 ) ) );
}

//--------------------------------------------------------------------------

XA_FUNC( SETKEYSTATE )  // SetKeyState( <nKey>, <lPressed> ) --> lPressed
{
   int nKey = hb_parnl( 1 );
   int nState = ( GetKeyState( nKey ) & 1 );
   BOOL nNewState = hb_parl( 2 );

   if( nState != nNewState )
      {
      INPUT input[2];

      memset( input, 0, sizeof( INPUT ) * 2 );
      input[0].type = INPUT_KEYBOARD;
      input[0].ki.wVk = nKey;
      input[1].type = INPUT_KEYBOARD;
      input[1].ki.wVk = nKey;
      input[1].ki.dwFlags = KEYEVENTF_KEYUP;
      SendInput( 2, input, sizeof( INPUT ) );
      }

   hb_retl( nNewState );
}

//--------------------------------------------------------------------------

XA_FUNC( GETKEYSTATE )     // GetKeyState( <nKey> ) --> nState
{
   hb_retnl( GetKeyState( hb_parnl( 1 ) ) );
}

//--------------------------------------------------------------------------

XA_FUNC( GETASYNCKEYSTATE )   // GetAsyncKeyState( <nKey> ) --> nState
{
   hb_retnl( GetAsyncKeyState( hb_parnl( 1 ) ) );
}

//--------------------------------------------------------------------------

XA_FUNC( LGETKEYSTATE )       // lGetKeyState( <nKey> ) --> lState
{
   hb_retl( GetKeyState( hb_parnl( 1 ) ) & 0xFFF0 );
}

//--------------------------------------------------------------------------

XA_FUNC( LGETASYNCKEYSTATE )  // lGetAsyncKeyState( <nKey> ) --> lState
{
   hb_retl( GetAsyncKeyState( hb_parnl( 1 ) ) & 0xFFF0 );
}

//--------------------------------------------------------------------------

XA_FUNC( MAPVIRTUALKEY )   // MapVirtualKey( <nVKey>, <nCode> ) --> nScanCode
{
   hb_retnl( MapVirtualKey( hb_parnl( 1 ), hb_parnl( 2 ) ) );
}

//--------------------------------------------------------------------------

XA_FUNC( VKEYTOASCII )     // VKeyToASCII( <nVKey>, <nCode> ) --> cKey
{
   char cKey[] = { 0, 0, 0, 0, 0 };
   BYTE aKeys[256];

   GetKeyboardState( (PBYTE) &aKeys );
   if( ToAscii( hb_parnl( 1 ), hb_parnl( 2 ), (PBYTE) &aKeys, (LPWORD) &cKey, 0 ) )
      hb_retc( cKey );
   else
      hb_retc( "" );
}

//--------------------------------------------------------------------------

XA_FUNC( LOADLIBRARY )     // LoadLibrary( <cFilename> ) --> hModule
{
   hb_retnl( (LONG) LoadLibrary( hb_parc( 1 ) ) );
}

//--------------------------------------------------------------------------

XA_FUNC( FREELIBRARY )  // FreeLibrary( <hModule> ) --> nErrorCode
{
   hb_retnl( FreeLibrary( (HINSTANCE) hb_parnl( 1 ) ) );
}

//--------------------------------------------------------------------------

XA_FUNC( CLIENTTOSCREEN )  // ClientToScreen( <hWnd>, [<@aPoint>] | [<@nX>, <@nY>] ) --> aPoint
{
   POINT pt;

   if ( hb_pcount() == 2 )  // 2nd param is an array
      {
      pt.x = hb_parvnl( 2, 1 );
      pt.y = hb_parvnl( 2, 2 );
      }
   else  // 2dn param is X, 3rd param is Y
      {
      pt.x = hb_parnl( 2 );
      pt.y = hb_parnl( 3 );
      }

   ClientToScreen( (HWND) hb_parni( 1 ), &pt );

   if ( hb_pcount() == 2 )  // 2nd param is an array
      {
      hb_storvnl( pt.x, 2, 1 );
      hb_storvnl( pt.y, 2, 2 );
      }
   else  // 2dn param is X, 3rd param is Y
      {
      hb_stornl( pt.x, 2 );
      hb_stornl( pt.y, 3 );
      }
   hb_reta( 2 );
   hb_storvnl( pt.x, -1, 1 );
   hb_storvnl( pt.y, -1, 2 );
}

//--------------------------------------------------------------------------

XA_FUNC( SCREENTOCLIENT )  // ScreenToClient( <hWnd>, [<@aPoint>] | [<@nX>, <@nY>] ) --> aPoint
{
   POINT pt;

   if ( hb_pcount() == 2 )  // 2nd param is an array
      {
      pt.x = hb_parvnl( 2, 1 );
      pt.y = hb_parvnl( 2, 2 );
      }
   else  // 2dn param is X, 3rd param is Y
      {
      pt.x = hb_parnl( 2 );
      pt.y = hb_parnl( 3 );
      }

   ScreenToClient( (HWND) hb_parni( 1 ), &pt );

   if ( hb_pcount() == 2 )  // 2nd param is an array
      {
      hb_storvnl( pt.x, 2, 1 );
      hb_storvnl( pt.y, 2, 2 );
      }
   else  // 2dn param is X, 3rd param is Y
      {
      hb_stornl( pt.x, 2 );
      hb_stornl( pt.y, 3 );
      }
   hb_reta( 2 );
   hb_storvnl( pt.x, -1, 1 );
   hb_storvnl( pt.y, -1, 2 );
}

//--------------------------------------------------------------------------

XA_FUNC( SETCAPTURE )   // SetCapture( <hWnd> ) --> hWndPrev
{
   hb_retnl( (long) SetCapture( (HWND) hb_parnl( 1 ) ) );
}

//--------------------------------------------------------------------------

XA_FUNC( RELEASECAPTURE )  // ReleaseCapture() --> lSuccess
{
   hb_retl( ReleaseCapture() );
}

//--------------------------------------------------------------------------

XA_FUNC( GETCAPTURE )      // GetCapture() --> hWndCapture
{
   hb_retnl( (long) GetCapture() );
}

//--------------------------------------------------------------------------

/* NOTA: Si cAppName contiene "#", el texto antes del caracter se pondra
   en el titulo y el restante en la caja de dialogo
*/
XA_FUNC( SHELLABOUT )   // ShellAbout( [<hWnd>], <cAppName>, <cMsg>, <hIcon> ) --> lSuccess
{
   HWND hWnd = HB_ISNUM( 1 ) ? (HWND) hb_parnl( 1 ) : 0;

   hb_retl( ShellAbout( hWnd, hb_parc( 2 ), hb_parc( 3 ),
                        (HICON) hb_parnl( 4 ) ) );
}

//--------------------------------------------------------------------------

XA_FUNC( GETDEVICECAPS )   // GetDeviceCaps( <hDC>, <nIndex> ) --> nCapability
{
   hb_retnl( GetDeviceCaps( (HDC) hb_parnl( 1 ), hb_parnl( 2 ) ) );
}

//--------------------------------------------------------------------------

XA_FUNC( MULDIV )          // MulDiv( <nNumber>, <nNumerator>, <nDenominator> ) --> nResult
{
   hb_retnl( MulDiv( hb_parnl( 1 ), hb_parnl( 2 ), hb_parnl( 3 ) ) );
}

//--------------------------------------------------------------------------

XA_FUNC( SHELLEXECUTE )    // ShellExecute( <hWnd>, <cVerb>, <cFilename>, <cParameters>, <cDirectory>, <nShow> ) --> nResult
{
   hb_retnl( (LONG) ShellExecute( (HWND) hb_parnl( 1 ), hb_parc( 2 ),
                                 hb_parc( 3 ), hb_parc( 4 ),
                                 hb_parc( 5 ), hb_parni( 6 ) ) );
}

//--------------------------------------------------------------------------

XA_FUNC( SHELLEXECUTEEX )     // ShellExecuteEx( <hWnd>, <cFilename>, <cVerb>, <cParams>, <cDirectory>, <nShow>, <nMask>, @<hProcess> ) --> nResult
{
   BOOL nOk;
   SHELLEXECUTEINFO sei;

   ZeroMemory( &sei, sizeof( sei ) );

   sei.cbSize = sizeof( sei );
   sei.hwnd   = (HWND) hb_parnl( 1 );
   sei.lpFile = (LPSTR) hb_parc( 2 );
   sei.lpVerb = HB_ISCHAR( 3 ) ? (LPSTR) hb_parc( 3 ) : NULL;
   sei.lpParameters = HB_ISCHAR( 4 ) ? (LPSTR) hb_parc( 4 ) : NULL;
   sei.lpDirectory = HB_ISCHAR( 5 ) ? (LPSTR) hb_parc( 5 ) : NULL;
   sei.nShow = hb_parnl( 6 );
   sei.fMask = hb_parnl( 7 );
   sei.hInstApp = NULL;

   nOk = ShellExecuteEx( &sei );
   hb_stornl( (long) sei.hProcess, 8 );
   hb_retnl( nOk );
}

//--------------------------------------------------------------------------

XA_FUNC( SEARCHPATH )      // SearchPath( <cPath>, <cFilename>, <cExtension> ) --> cFilename
{
   LPSTR lpFile = hb_xgrab( MAX_PATH );
   DWORD dwLen;

   dwLen = SearchPath( hb_parc( 1 ), hb_parc( 2 ), hb_parc( 3 ),
                        MAX_PATH, lpFile, NULL );

   if( dwLen )
      hb_retc( lpFile );
   else
      hb_retc( "" );

   hb_xfree( lpFile );
}

//--------------------------------------------------------------------------

XA_FUNC( GETSYSTEMMETRICS ) // GetSystemMetrics( <nIndex> ) --> nMetric
{
   hb_retnl( GetSystemMetrics( hb_parnl( 1 ) ) );
}

//--------------------------------------------------------------------------

XA_FUNC( TRACKMOUSEEVENT ) // TrackMouseEvent( <hWnd>, <nFlags>, [<nHoverTime>] ) --> lSuccess
{
   TRACKMOUSEEVENT tme;

   tme.cbSize = sizeof( TRACKMOUSEEVENT );
   tme.hwndTrack = (HWND) hb_parnl( 1 );
   tme.dwFlags = hb_parnl( 2 );
   tme.dwHoverTime = HB_ISNUM( 3 ) ? hb_parnl( 3 ) : 0;

   hb_retl( TrackMouseEvent( &tme ) );
}

//--------------------------------------------------------------------------

XA_FUNC( SETERRORMODE )    // SetErrorMode( <nErrorMode> ) --> nOldErrorMode
{
   hb_retnl( SetErrorMode( hb_parnl( 1 ) ) );
}

//--------------------------------------------------------------------------

typedef BOOL (WINAPI * STEM)( DWORD, DWORD * );

HB_FUNC( SETTHREADERRORMODE ) // SetThreadErrorMode( <nMode>, <@nOldMode> ) --> lSuccess
{
   HMODULE hMod = GetModuleHandle( "kernel32.dll" );
   STEM stem = (STEM) GetProcAddress( hMod, "SetThreadErrorMode" );

   if( stem )
   {
      DWORD dwOld = 0;
      BOOL bSuccess = stem( hb_parnl( 1 ), &dwOld );

      if( hb_pcount() == 2 )
         hb_stornl( dwOld, 2 );

      hb_retl( bSuccess );
   }
   else
      hb_retl( HB_FALSE );
}

//--------------------------------------------------------------------------

XA_FUNC( OEMTOANSI )    // OEMToAnsi( <cString> ) --> cAnsiString
{
   if( HB_ISCHAR( 1 ) )
   {
      const char * szStr = hb_parc( 1 );
      char * szAnsi = hb_xgrab( hb_parclen( 1 ) + 1 );

      OemToChar( szStr, szAnsi );
      hb_retc_buffer( szAnsi );
   }
   else
      hb_retc( "" );
}

//--------------------------------------------------------------------------

XA_FUNC( ANSITOOEM )    // AnsiToOEM( <cString> ) --> cOEMString
{
   if( HB_ISCHAR( 1 ) )
   {
      const char * szStr = hb_parc( 1 );
      char * szOem = hb_xgrab( hb_parclen( 1 ) + 1 );

      CharToOem( szStr, szOem );
      hb_retc_buffer( szOem );
   }
   else
      hb_retc( "" );
}

//--------------------------------------------------------------------------

XA_FUNC( WINEXEC )      // WinExec( <cFilename>, [<nShow>] ) --> nResult
{
   UINT uiMode = HB_ISNUM( 2 ) ? hb_parni( 2 ) : SW_NORMAL;

   hb_retni( WinExec( hb_parc( 1 ), uiMode ) );
}

//--------------------------------------------------------------------------

XA_FUNC( TOSTRING )     // ToString( <xParam>, [<cDefault>], [<lTrimAllDecimals>] ) --> cResult
{
   PHB_ITEM param = hb_param( 1, HB_IT_ANY );
   char cString[ 65 ], *p;
   ULONG nLen;
   BOOL lFree;
   int nInt, nDec;

   if( param )
      {
      switch( hb_itemType( param ) )
         {
         case HB_IT_LOGICAL:
            hb_retc( hb_parl( 1 ) ? ".T." : ".F." );
            break;

         case HB_IT_BLOCK:
            hb_retc( "{|| ... }" );
            break;

         case HB_IT_INTEGER:
         case HB_IT_LONG:
         case HB_IT_DOUBLE:
            hb_itemGetNLen( param, &nInt, &nDec );
            if( hb_itemStrBuf( cString, param, nDec ? 64 : nInt, nDec ? 16 : 0 ) )
               {
               if( nDec )
                  {
                  // Quitar ceros por la derecha (decimales) hasta dejar
                  // <nDec> decimales o ninguno si <lTrimAllDecimals> = .T.
                  nDec = hb_parl( 3 ) ? 16 : 16 - nDec;
                  p = &cString[ 63 ];
                  while( nDec-- && ( *p == '0' ) )
                     *p-- = 0;
                  if( *p == '.' )
                     *p = 0;
                  }
               // Quitar espacios por la izquierda
               p = cString;
               while( *p == ' ' )
                  p++;
               hb_retc( p );
               }
            else
               hb_retc( "" );
            break;

         case HB_IT_NIL:
            hb_retc( hb_pcount() > 1 ? hb_parc( 2 ) : "NIL" );
            break;

         default:
            p = hb_itemString( param, &nLen, &lFree );
            hb_retclen( p, nLen );
            if( lFree )
               hb_xfree( p );
         }
      }
   else
      hb_retc( "NIL" );
}

//--------------------------------------------------------------------------

XA_FUNC( GETWINDOW )    // GetWindow( <hWnd>, <nCmd> ) --> hWnd
{
   hb_retnl( (long) GetWindow( (HWND) hb_parnl( 1 ), hb_parnl( 2 ) ) );
}

//--------------------------------------------------------------------------

XA_FUNC( ISZOOMED )     // IsZoomed( <hWnd> ) --> lIsZoomed
{
   hb_retl( IsZoomed( (HWND) hb_parnl( 1 ) ) );
}

//--------------------------------------------------------------------------

XA_FUNC( ISICONIC )     // IsIconic( <hWnd> ) --> lIsIconic
{
   hb_retl( IsIconic( (HWND) hb_parnl( 1 ) ) );
}

//--------------------------------------------------------------------------

XA_FUNC( GETDRIVES )    // GetDrives( <nType> ) --> aDrives
{
   UINT nType = hb_parnl( 1 );
   DWORD dwDrives = GetLogicalDrives();
   int nTest = 1, n, nDrives = 0;
   char cDrive[4] = " :\\";

   hb_reta( 32 );

   for( n = 0; n < 32; n++ )
      {
      if( dwDrives & nTest )
         {
         cDrive[0] = 'A' + n;
         cDrive[2] = '\\';
         if( ( nType == 0 ) || ( GetDriveType( cDrive ) == nType ) )
            {
            cDrive[2] = 0;
            nDrives++;
            hb_storvc( cDrive, -1, nDrives );
            }
         }
      nTest = nTest << 1;
      }
   hb_arraySize( hb_param( -1, HB_IT_ARRAY ), nDrives );
}

//--------------------------------------------------------------------------

XA_FUNC( GETTEMPFILENAME )    // GetTempFilename( [<cPath>], [<cPrefix>], [<nUnique>] ) --> cFilename
{
   const char *cPath = hb_parc( 1 );
   const char *cPrefix = hb_parc( 2 );
   char cFile[ 256 ] = { 0 };
   char cTemp[ 256 ];

   if( !cPath )
      {
      GetTempPath( 256, cTemp );
      cPath = cTemp;
      }
   if( !cPrefix )
      cPrefix = "TMP";

   GetTempFileName( cPath, cPrefix, hb_parnl( 3 ), cFile );
   hb_retc( cFile );
}

//--------------------------------------------------------------------------

typedef HRESULT (WINAPI * DllRegisterServer)( void );
typedef HRESULT (WINAPI * DllUnregisterServer)( void );

XA_FUNC( DLLREGISTERSERVER )  // DllRegisterServer( <cFilename> ) --> lSuccess
{
   HRESULT hr = -1;

   if( HB_ISCHAR( 1 ) )
   {
      HINSTANCE hLib = LoadLibrary( hb_parc( 1 ) );

      if( hLib != NULL )
      {
         DllRegisterServer pRegServer = (DllRegisterServer) GetProcAddress( hLib, "DllRegisterServer" );

         if( pRegServer )
         {
            hr = (* pRegServer)();
         }

         FreeLibrary( hLib );
      }
   }

   hb_retl( SUCCEEDED( hr ) );
}

//--------------------------------------------------------------------------

XA_FUNC( DLLUNREGISTERSERVER )   // DllUnregisterServer( <cFilename> ) --> lSuccess
{
   HRESULT hr = -1;

   if( HB_ISCHAR( 1 ) )
   {
      HINSTANCE hLib = LoadLibrary( hb_parc( 1 ) );

      if( hLib != NULL )
      {
         DllUnregisterServer pUnregServer = (DllUnregisterServer) GetProcAddress( hLib, "DllUnregisterServer" );

         if( pUnregServer )
         {
            hr = (* pUnregServer)();
         }

         FreeLibrary( hLib );
      }
   }

   hb_retl( SUCCEEDED( hr ) );
}

//--------------------------------------------------------------------------

XA_FUNC( GETMODULEFILENAME )  // GetModuleFilename( <hInstance> ) --> cFilename
{
   char cFile[ MAX_PATH ] = "\0";

   GetModuleFileName( (HINSTANCE) hb_parnl( 1 ), cFile, MAX_PATH );
   hb_retc( cFile );
}

//--------------------------------------------------------------------------

XA_FUNC( GETMODULEHANDLE ) // GetModuleHandle( <cFilename> ) --> hInstance
{
   hb_retnl( (long) GetModuleHandle( hb_parc( 1 ) ) );
}

//--------------------------------------------------------------------------

XA_FUNC( EXECUTE )   // Execute( <cCommand>, [<cStartDirectory>], <lWait>, [<nShow>], [@<nProcessId>] ) --> nExitCode | hProcess
{
   hb_stornl( 0, 5 );
   if( HB_ISCHAR( 1 ) )
   {
      LPSTR cCommandLine = (LPSTR) hb_parc( 1 );
      LPSTR cInitialDir;
      BOOL lWait = hb_parl( 3 );
      STARTUPINFO si;
      PROCESS_INFORMATION pi;

      if( HB_ISCHAR( 2 ) )
         cInitialDir = (LPSTR) hb_parc( 2 );
      else
         cInitialDir = XA_ObjGetC( Application(), "CurrentDir" );

      memset( &si, 0, sizeof( STARTUPINFO ) );
      si.cb = sizeof( STARTUPINFO );
      si.dwFlags = STARTF_USESHOWWINDOW;
      si.wShowWindow = HB_ISNIL( 4 ) ? SW_SHOWNORMAL : hb_parnl( 4 );

      memset( &pi, 0, sizeof( PROCESS_INFORMATION ) );

      if( CreateProcess( NULL, cCommandLine, NULL, NULL, FALSE,
                         NORMAL_PRIORITY_CLASS, NULL, cInitialDir,
                         &si, &pi ) )
         {
         CloseHandle( pi.hThread );
         if( lWait )
            {
            DWORD nExitCode;

            WaitForSingleObject( pi.hProcess, INFINITE );
            GetExitCodeProcess( pi.hProcess, &nExitCode );
            CloseHandle( pi.hProcess );
            hb_retnl( nExitCode );
            }
         else
            {
            hb_retnl( (long) pi.hProcess );
            hb_stornl( pi.dwProcessId, 5 );
            }
         }
      else
         hb_retnl( 0 );
   }
   else
      hb_retnl( 0 );
}

//--------------------------------------------------------------------------

XA_FUNC( ISRUNNING ) // IsRunning( <hProcess> ) --> lResult
{
   HANDLE hProcess = (HANDLE) hb_parnl( 1 );
   DWORD nExitCode;

   hb_retl( FALSE );
   if( GetExitCodeProcess( hProcess, &nExitCode ) )
      {
      if( nExitCode == STILL_ACTIVE )
         hb_retl( TRUE );
      else
         CloseHandle( hProcess );
      }
}

//--------------------------------------------------------------------------

XA_FUNC( KILLPROCESS )  // KillProcess( <hProcess> ) --> lSuccess
{
   HANDLE hProcess = (HANDLE) hb_parnl( 1 );

   hb_retl( FALSE );
   if( TerminateProcess( (HANDLE) hb_parnl( 1 ), -1 ) )
      {
      CloseHandle( hProcess );
      hb_retl( TRUE );
      }
}

//--------------------------------------------------------------------------

XA_FUNC( GETPROCESSHANDLE )   // ( <cFilename> ) --> <hProcess>
{
   char cFullFilename[ MAX_PATH ], cName[ MAX_PATH ];
   HANDLE hProcess = NULL, hProc;
   DWORD aProcesses[ 1024 ], nCount = 0, n;

   if( GetFullPathName( hb_parc( 1 ), MAX_PATH, cFullFilename, NULL ) )
      {
      if( EnumProcesses( aProcesses, sizeof( aProcesses ), &nCount ) )
         {
         nCount = nCount / sizeof( DWORD );
         for( n = 0; n < nCount; n++ )
            {
            hProc = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_TERMINATE, FALSE, aProcesses[ n ] );
            if( hProc )
               {
               GetModuleFileNameEx( hProc, NULL, cName, MAX_PATH );
               if( strnicmp( cName, cFullFilename, MAX_PATH ) == 0 )
                  {
                  hProcess = hProc;
                  break;   // NOTA: Salir sin cerrar el handle
                  }
               }
            CloseHandle( hProc );
            }
         }
      }

   hb_retnl( (long) hProcess );
}

//--------------------------------------------------------------------------

HB_FUNC( SENDWMCOPYDATA )  // SendWMCopyData( <hWnd> | <cWindowTitle>, <cString>, [<nMsgID>] ) --> Nil
{
   HWND hWnd;

   if( HB_ISNUM( 1 ) )
      hWnd = (HWND) hb_parnl( 1 );
   else
      hWnd = FindWindow( NULL, hb_parc( 1 ) );

   if( hWnd )
   {
      LPTSTR lpStr = (LPSTR) hb_parc( 2 );
      COPYDATASTRUCT cds;

      cds.lpData = lpStr;
      cds.cbData = hb_parclen( 2 ) + 1;
      cds.dwData = HB_ISNUM( 3 ) ? hb_parnl( 3 ) : 0;

      SendMessage( hWnd, WM_COPYDATA, (WPARAM) hWnd, (LPARAM) (LPVOID) &cds );
   }
   hb_ret();
}

//--------------------------------------------------------------------------

XA_FUNC( ANIMATEWINDOW ) // AnimateWindow( <hWnd>, [<nMilliSeconds>], [<nFlags>] ) --> lSuccess
{
   hb_retl( AnimateWindow( (HWND) hb_parnl( 1 ), hb_parnl( 2 ), hb_parnl( 3 ) ) );
}

//--------------------------------------------------------------------------

XA_FUNC( ISDEBUGGERPRESENT ) // IsDebuggerPresent() --> lValue
{
   hb_retl( IsDebuggerPresent());
}

//--------------------------------------------------------------------------
