Sign in to follow this  
Followers 0
odklizec

Help with simple C source conversion..

6 posts in this topic

Hi folks,

I'm inexperienced with conversion of C source code to AutoIt and this exact code drives me mad :whistle: I'm sure, it's quite simple, but even after all day spent with searching similar examples, I'm not able to get a success. Here is the original C source..

It should return the name of TTF font typeface..

typedef BOOL (WINAPI *PGFRI)(LPCWSTR, DWORD *, LPWSTR, DWORD);

// 1. parameter : seems to be the filename [IN]
// 2. parameter : size of the buffer [IN], size of the output [OUT]
// 3. parameter : a buffer [OUT]
// 4. parameter : an enumerated type
// return value is a simple BOOL : ok / not ok

// #define GetFontResourceInfo GetFontResourceInfoW


void main()
{
  HINSTANCE hDLL = LoadLibrary("GDI32.DLL");

  PGFRI GetFontResourceInfo = (PGFRI)GetProcAddress(hDLL, "GetFontResourceInfoW");

  WCHAR fontName[] = L"Arial.ttf";

  WCHAR wBuffer[1024];
  DWORD dwBufSiz = sizeof(wBuffer);

// a couple values I tested

  GetFontResourceInfo(fontName, &dwBufSiz, wBuffer, 0); // returns 1 (0x00000001) in wBuffer
  GetFontResourceInfo(fontName, &dwBufSiz, wBuffer, 1); // "Arial" in Unicode
  GetFontResourceInfo(fontName, &dwBufSiz, wBuffer, 2); // a (rather) large structure with some info
  GetFontResourceInfo(fontName, &dwBufSiz, wBuffer, 3); // nothing special
  GetFontResourceInfo(fontName, &dwBufSiz, wBuffer, 4); // the fullpath of the file

}

I'm able to load library and get ProcAddress but I stuck with correct declaration of DllStructCreate and correct syntax of DllCall. My main problem is in understanding how the things work and how to create the buffers.

Here is the code I'm working on. I'm sure the DllStructCreate and DllCall lines are completely wrong, but I cannot get them to work. Please, can someone help me? I just need a hint how to get on right track..

Dim $Krnl32 = ("Kernel32.Dll")
Dim $Gdi32 = ("GDI32.DLL")
Dim $ProcName = "GetFontResourceInfoW"
Dim $FontName = "C:\WINDOWS\Fonts\Arial.ttf"

$p  = DllStructCreate("dword; wchar[128]; wchar[1024]; dword; char[1024]")

$GdiH=LibLoad($gdi32)
ConsoleWrite("gdi: " & $GdiH & @CRLF)

$GetProc= GetProcAddress($GdiH, $ProcName)
ConsoleWrite("procaddress: " & $GetProc & @CRLF)

$ret = DllCall($GdiH, "hwnd", $GetProc, "wstr", $FontName, "int", 1024, "char[1024]", "", "int", 1, "ptr", DllStructGetPtr($p))
$ret_s = DllStructGetData($p,1)
ConsoleWrite("font name: " & $ret_s & @CRLF)

if Not $ret Then
    MsgBox(0,"DllCall Error","DllCall Failed")
    exit
EndIf
LibFree($GdiH)

Func LibLoad( $lpLibFileName )
$hKrnl = DllOpen("kernel32.dll")
Local $LibHandle = DllCall($hKrnl, "int", "LoadLibraryA", "str", $lpLibFileName)
DllClose($hKrnl)
Return $LibHandle[0]
EndFunc

Func LibFree($DllHandle)
$hKrnl = DllOpen("kernel32.dll")
Local $LibFreed = DllCall($hKrnl, "int", "FreeLibrary", "int", $DllHandle)
return $LibFreed[0]
EndFunc 

Func GetProcAddress( $hModule, $lpProcName)
$hKrnl = DllOpen("Kernel32.dll")
Local $ProcessAddy = DllCall($hKrnl,"int","GetProcAddress","int",$hModule,"str",$lpProcName)
DllClose($hKrnl)
Return $ProcessAddy[0]
EndFunc

Share this post


Link to post
Share on other sites



Anyone please? I'm sure it's not complicated for an advanced AutoIt scripter but because I'm inexperienced with dllcalls and C convention, I can't find the proper way :whistle:

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

Maybe this is helpfull:

$sName = GetFontName("lsans.ttf")
Msgbox(0, "Name", $sName)

Exit

Func GetFontName($sFontName)
    Local $nBuffersize  = DllCall("kernel32.dll", "int", "MultiByteToWideChar", _
                                                        "int", 0, _
                                                        "int", 0x00000001, _
                                                        "str", $sFontName, _
                                                        "int", -1, _
                                                        "ptr", 0, _
                                                        "int", 0)
                                                        
    Local $stWideString = DllStructCreate("byte[" & 2 * $nBuffersize[0] & "]")
    
    DllCall("kernel32.dll", "int", "MultiByteToWideChar", _
                                    "int", 0, _
                                    "int", 0x00000001, _
                                    "str", $sFontName, _
                                    "int", -1, _
                                    "ptr", DllStructGetPtr($stWideString), _
                                    "int", $nBuffersize[0])



    Local $nNeededSize = DllCall("gdi32.dll", "int", "GetFontResourceInfoW", _
                                                        "ptr", DllStructGetPtr($stWideString), _
                                                        "long_ptr", 0, _
                                                        "ptr", 0, _
                                                        "int", 1) ; Request type: 1 - Name?, 4 - Full path
    
    Local $stBuffer = DllStructCreate("byte[" & 2 * $nNeededSize[2] & "]")
    
    DllCall("gdi32.dll", "int", "GetFontResourceInfoW", _
                                "ptr", DllStructGetPtr($stWideString), _
                                "long_ptr", $nNeededSize[2], _
                                "ptr", DllStructGetPtr($stBuffer), _
                                "int", 1) ; Request type: 1 - Name?, 4 - Full path
                                
    $nBuffersize = DllCall("kernel32.dll", "int", "WideCharToMultiByte", _
                                                    "int", 0, _
                                                    "int", 0x00000200, _
                                                    "ptr", DllStructGetPtr($stBuffer), _
                                                    "int", -1, _
                                                    "ptr", 0, _
                                                    "int", 0, _
                                                    "ptr", 0, _
                                                    "ptr", 0)
                        
    Local $stName = DLLStructCreate("char[" & $nBuffersize[0] & "]")

    Local $nNameLen = DllCall("kernel32.dll", "int", "WideCharToMultiByte", _
                                                        "int", 0, _
                                                        "int", 0x00000200, _
                                                        "ptr", DllStructGetPtr($stBuffer), _
                                                        "int", -1, _
                                                        "ptr", DllStructGetPtr($stName), _
                                                        "int", $nBuffersize[0], _
                                                        "ptr", 0, _
                                                        "ptr", 0)
                        
    Return DllStructGetData($stName, 1)
EndFunc
Edited by Holger

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

Thank you very much! Now I have to analyze your code and learn why you did what you did :whistle: BTW just one thing... With some fonts it returns some funny characters instead of name (in fact always these three characters ?i[ ). Do you have any idea why? In Windows FontView it show correct name so I don't see any reason why this code returns something else? Check for example the attached file.

Edited by odklizec

Share this post


Link to post
Share on other sites

Yes, you are right! Do you have any idea why it happens? I thought that if I use full path to ttf file, it will return the typeface, no matter the font is installed or not? BTW, I tried to run the ttf file via FontView (from its position outside the Fonts folder and no installed) and leave it open, the script returns the correct name. I then closed the FontView, and the script again returns the three characters. So the ttf file doesn't need to be installed, but it seems it must be loaded in memory?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0