Page 1 of 2

PathCompactPath

Posted: Fri Jan 13, 2017 3:00 pm
by Pablo César
e.g. "C:\Program...\Adobe"  
The GRID headers give the same effect, but we do not have this function available to the user in HMG yet. :|
It would be useful as in these cases:
 
Image
 
  1. Here is a solution: https://www.codeproject.com/articles/36 ... it-control
     
  2. In Minigui Extended there is another solution, like as this code:

    Code: Select all

    // Jacek Kubica <kubica@wssk.wroc.pl> HMG 1.1 Experimental Build 11a
    // cFile - string to be compacted (may be for example fullpath, path or file name)
    // nMax  - required string size (characters count)
    // _GetCompactPath("C:\Program Files\Adobe",20) -> "C:\Program...\Adobe"
    
    FUNCTION _GetCompactPath ( cFile, nMax )
    LOCAL cShort := Space( hb_IsNumeric( nMax, nMax + 1, 64 ) )
    
    Return iif( GetCompactPath( @cShort, cFile, hb_IsNumeric( nMax, nMax, 63 ), NIL ) > 0, cShort, cFile )

    Code: Select all

    // Grigory Filatov <gfilatov@inbox.ru> HMG 1.1 Experimental Build 11a
    typedef INT ( WINAPI * _GETCOMPACTPATH )( LPTSTR pszOut, LPTSTR pszSrc, INT cchMax, DWORD dwFlags );
    
    HB_FUNC( GETCOMPACTPATH )
    {
       HINSTANCE handle = LoadLibrary( "shlwapi.dll" );
    
       if( handle )
       {
          _GETCOMPACTPATH pFunc;
          pFunc = ( _GETCOMPACTPATH ) GetProcAddress( handle, "PathCompactPathExA" );
          hb_retni( pFunc( ( LPTSTR ) hb_parc( 1 ), ( LPTSTR ) hb_parc( 2 ), ( INT ) hb_parni( 3 ), ( DWORD ) hb_parnl( 4 ) ) );
          FreeLibrary( handle );
       }
    }
 
We would need to convert this code to UNICODE/ANSI and I imagine we need to use HMG_DEFINE_DLL_FUNC but I do not know how to adapt it to HMG. :oops:

IMHO, first option is better doing in pixels not in pixel considering GetFontSize. :?

I think it would be useful to have a solution where prevent texts from being truncated.

Re: PathCompactPath

Posted: Sat Jan 14, 2017 12:39 am
by srvet_claudio
Include the header file:
#include "Shlwapi.h"

and call direct the func:
PathCompactPath or PathCompactPathEx

see:
https://msdn.microsoft.com/en-us/librar ... s.85).aspx

https://msdn.microsoft.com/en-us/librar ... s.85).aspx

PathCompactPath

Posted: Sat Jan 14, 2017 2:32 am
by Pablo César
So simple like that ?

I will check tomorrow. Really tired now for testing.

I got already before but I suppose to make it in ANSI mode... It's what I think.

Thank Claudio.

Re: PathCompactPath

Posted: Sat Jan 14, 2017 10:30 pm
by KDJ
This can be done without coding in C.
Example:

Code: Select all

#include 'hmg.ch'

FUNCTION Main()

  SET FONT TO 'MS Shell Dlg', 8

  DEFINE WINDOW MainWA;
    MAIN;
    WIDTH  380;
    HEIGHT 230;
    TITLE  'Path Compact';
    NOMAXIMIZE;
    NOSIZE

    DEFINE LABEL PathLA
      ROW     10
      COL     10
      WIDTH  350
      HEIGHT  13
      VALUE  'Path to compact:'
    END LABEL

    DEFINE TEXTBOX PathTE
      ROW        25
      COL        10
      WIDTH     310
      HEIGHT     20
      MAXLENGTH 259
      VALUE     CurDir()
      ONCHANGE  CompactPaths()
    END TEXTBOX

    DEFINE BUTTON PathBU
      ROW      25
      COL     330
      WIDTH    30
      HEIGHT   20
      CAPTION '>>'
      ACTION  SetPath()
    END BUTTON

    DEFINE LABEL CompCharLA
      ROW     55
      COL     10
      WIDTH  350
      HEIGHT  13
      VALUE  'Compact path - length in characters:'
    END LABEL

    DEFINE TEXTBOX CompCharTE
      ROW        70
      COL        10
      WIDTH     310
      HEIGHT     20
      MAXLENGTH 259
      READONLY  .T.
      DISABLEDBACKCOLOR {224, 224, 224}
      ONGOTFOCUS SendMessage(MainWA.CompCharTE.HANDLE, 177 /*EM_SETSEL*/, 0, -1)
    END TEXTBOX

    DEFINE TEXTBOX CharsTE
      ROW         70
      COL        330
      WIDTH       30
      HEIGHT      20
      VALUE       30
      DATATYPE   NUMERIC
      RIGHTALIGN .T.
      INPUTMASK  '999'
      ONCHANGE   CompactPaths()
    END TEXTBOX

    DEFINE LABEL CompPixLA
      ROW    100
      COL     10
      WIDTH  350
      HEIGHT  13
      VALUE  'Compact path - length in pixels:'
    END LABEL

    DEFINE TEXTBOX CompPixTE
      ROW       115
      COL        10
      WIDTH     310
      HEIGHT     20
      MAXLENGTH 259
      READONLY  .T.
      DISABLEDBACKCOLOR {224, 224, 224}
      ONGOTFOCUS SendMessage(MainWA.CompPixTE.HANDLE, 177 /*EM_SETSEL*/, 0, -1)
    END TEXTBOX

    DEFINE TEXTBOX PixelsTE
      ROW        115
      COL        330
      WIDTH       30
      HEIGHT      20
      VALUE      120
      DATATYPE   NUMERIC
      INPUTMASK  '999'
      RIGHTALIGN .T.
      ONCHANGE   CompactPaths()
    END TEXTBOX

    DEFINE LABEL CompWndLA
      ROW    145
      COL     10
      WIDTH  350
      HEIGHT  13
      VALUE  'Compact path to control width:'
    END LABEL

    DEFINE TEXTBOX CompWndTE
      ROW       160
      COL        10
      WIDTH     310
      HEIGHT     20
      MAXLENGTH 259
      READONLY  .T.
      DISABLEDBACKCOLOR {224, 224, 224}
      ONGOTFOCUS SendMessage(MainWA.CompWndTE.HANDLE, 177 /*EM_SETSEL*/, 0, -1)
    END TEXTBOX

    DEFINE TEXTBOX WidthTE
      ROW        160
      COL        330
      WIDTH       30
      HEIGHT      20
      VALUE      160
      DATATYPE   NUMERIC
      INPUTMASK  '999'
      RIGHTALIGN .T.
      ONCHANGE   (MainWA.CompWndTE.WIDTH := If(MainWA.WidthTE.VALUE < 0, 0, MainWA.WidthTE.VALUE), CompactPaths())
    END TEXTBOX

    ON KEY ESCAPE ACTION MainWA.RELEASE

  END WINDOW

  MainWA.CENTER
  MainWA.ACTIVATE

RETURN NIL


FUNCTION SetPath()
  LOCAL cPath := GetFile()

  IF ! Empty(cPath)
    MainWA.PathTE.VALUE := cPath
  ENDIF

RETURN NIL


FUNCTION CompactPaths()

  IF IsControlDefined(CompCharTE, MainWA)
    MainWA.CompCharTE.VALUE := GetCompactPathChar(MainWA.PathTE.VALUE, MainWA.CharsTE.VALUE)
  ENDIF

  IF IsControlDefined(CompPixTE, MainWA)
    MainWA.CompPixTE.VALUE := GetCompactPathPix(MainWA.PathTE.VALUE, MainWA.PixelsTE.VALUE, MainWA.CompPixTE.HANDLE)
  ENDIF

  IF IsControlDefined(CompWndTE, MainWA)
    MainWA.CompWndTE.VALUE := GetCompactPathWnd(MainWA.PathTE.VALUE, MainWA.CompWndTE.HANDLE)
  ENDIF

RETURN NIL


FUNCTION GetCompactPathChar(cPath, nChars)
  LOCAL cPathComp

  IF ++nChars < 0
    nChars := 0
  ENDIF

  cPathComp := Space(nChars)

RETURN If(HMG_CallDLL('Shlwapi.dll', 0, 'PathCompactPathEx', @cPathComp, cPath, nChars, NIL) == 0, cPath, cPathComp)


FUNCTION GetCompactPathPix(cPath, nPixels, nHWnd)
  LOCAL nHDC   := GetDC(nHWnd)
  LOCAL nHFont := HMG_CallDLL('Gdi32.dll', 0, 'SelectObject', nHDC, SendMessage(nHWnd, 49 /*WM_GETFONT*/, 0, 0))

  IF nPixels < 0
    nPixels := 0
  ENDIF

  HMG_CallDLL('Shlwapi.dll', 0, 'PathCompactPath', nHDC, @cPath, nPixels)

  HMG_CallDLL('Gdi32.dll', 0, 'SelectObject', nHDC, nHFont)
  ReleaseDC(nHWnd, nHDC)

RETURN cPath


FUNCTION GetCompactPathWnd(cPath, nHWnd)

RETURN GetCompactPathPix(cPath, GetClientAreaWidth(nHWnd), nHWnd)


//#pragma BEGINDUMP
//  #include "SET_COMPILE_HMG_UNICODE.ch"
//  #include "HMG_UNICODE.h"
//
//  #include <windows.h>
//  #include <shlwapi.h>
//  #include "hbapi.h"
//
//  //this function does not work, error while linking: undefined reference to `_imp__PathCompactPathW@12'
//          //PathCompactPix(cPath, nPix, nHWnd)
//  HB_FUNC ( PATHCOMPACTPIX )
//  {
//    LPTSTR lpszPath = (LPTSTR) HMG_parc (1);
//    UINT   dx       = (UINT)   hb_parni (2);
//    HWND   hWnd     = (HWND)   HMG_parnl(3);
//    HDC    hDC      = GetDC(hWnd);
//    HFONT  hFont    = SelectObject(hDC, (HFONT) SendMessage(hWnd, WM_GETFONT, 0, 0));
//
//    PathCompactPath(hDC, lpszPath, dx);
//
//    SelectObject(hDC, hFont);
//    ReleaseDC(hWnd, hDC);
//    HMG_retc(lpszPath);
//  }
//
//#pragma ENDDUMP

PathCompactPath

Posted: Sun Jan 15, 2017 12:48 am
by Pablo César
WOW Krzysztof ! Image

Wonderful I did not imagined by this time that we can use DLL. This is thanks to HMG_CallDLL function enhancement fixed by Claudio and that you man were able to use wisely.

Thank you Krzysztof !

I've been busy preparing other types of examples today (very nice ones about UAC) and I could not see this question of CompactPath yet upto now.

But in the bathroom in the shower, last night (where ideas come up), I imagined using the second parameter as optional (to use or not) for the user. User can enter the numeric value or leave it not informed. In this way the function would automatically find the maximum value conform the width of the container. By testing incrementally figure until the maximum value is reached in the container. But this would be one more improvement that we could implement. Probably I will do tomorrow (know I'm gonna to the dancing club).
Image

However these functions deserve to be in the core of HMG and this example in the SAMPLES for next HMG release in my opinion. Claudio and Rathi please kindly you consider it a contribution and an excellent resource to avoid text truncations in containers that do not fit everything.
Image

Congratulations Krzysztof and thank you very much for your contribution. Thanks a lot to you Claudio for the tip and work in HMG_CallDLL and all your job around in HMG.
Image

Best regards

PD.: I've tested with changing of FONTNAME and FONTSIZE (to Courier New) and worked perfectly. What the another first examples were not correct.

Re: PathCompactPath

Posted: Sun Jan 15, 2017 9:43 am
by serge_girard
Thanks Pablo and Krzysztof !

Should indeed be in the core of HMG !

Serge

Re: PathCompactPath

Posted: Sun Jan 15, 2017 1:53 pm
by KDJ
KDJ wrote:

Code: Select all

//  //this function does not work, error while linking: undefined reference to `_imp__PathCompactPathW@12'
//          //PathCompactPix(cPath, nPix, nHWnd)
//  HB_FUNC ( PATHCOMPACTPIX )
//  {
//    LPTSTR lpszPath = (LPTSTR) HMG_parc (1);
//    UINT   dx       = (UINT)   hb_parni (2);
//    HWND   hWnd     = (HWND)   HMG_parnl(3);
//    HDC    hDC      = GetDC(hWnd);
//    HFONT  hFont    = SelectObject(hDC, (HFONT) SendMessage(hWnd, WM_GETFONT, 0, 0));
//
//    PathCompactPath(hDC, lpszPath, dx);
//
//    SelectObject(hDC, hFont);
//    ReleaseDC(hWnd, hDC);
//    HMG_retc(lpszPath);
//  }
It turns out that the compiler does not automatically enable to link the library "shlwapi".
You have to do it manually, eg. in .hbp file:
-lshlwapi
and all works right.

So I can now write another version of functions GetCompactPathChar and GetCompactPathPix - coding in C instead of using HMG_CallDLL.
This should work faster.

mol

Posted: Sun Jan 15, 2017 6:36 pm
by mol
Great!

PathCompactPath

Posted: Sun Jan 15, 2017 7:05 pm
by Pablo César
Krzysztof wrote:It turns out that the compiler does not automatically enable to link the library "shlwapi".
You have to do it manually, eg. in .hbp file:
-lshlwapi
and all works right.
:shock:
 
I did not know there was this lib in Harbour. I searched and only found it as DLL.
So I can now write another version of functions GetCompactPathChar and GetCompactPathPix - coding in C instead of using HMG_CallDLL.
This should work faster.
Please feel free, we would like to have this function. Very useful and follows the pattern so that there are no truncations with this function.


Ddziękuję Krzysztof ! :P

Re: PathCompactPath

Posted: Sun Jan 15, 2017 7:49 pm
by KDJ
Pablo César wrote: Sun Jan 15, 2017 7:05 pm
Krzysztof wrote:It turns out that the compiler does not automatically enable to link the library "shlwapi".
You have to do it manually, eg. in .hbp file:
-lshlwapi
and all works right.
:shock:
 
I did not know there was this lib in Harbour. I searched and only found it as DLL.
Pablo
This library is in C compiler (MinGW) named "libshlwapi.a".