Jump to content

Help with simple C source conversion..


Recommended Posts

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
Link to comment
Share on other sites

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
Link to comment
Share on other sites

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
Link to comment
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?

Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...