//////////// // FUNCTION ApiLoadDll_(cDll, cError) // Carrega a Dll, onde: // -> Dll to be loaded // [@] -> Error message // Retorna o handle da Dll ou 0 se ela nao pode ser carregada // ///// STATIC aDllLoaded := {} // Loaded Dlls {{cDllName, nDllHandle}, ...} LOCAL nDllHandle cDll := Lower(AllTrim(cDll)) if Right(cDll, 4) <> '.dll' cDll += '.dll' endif nDllHandle := AScan(aDllLoaded, {|x| x[01] == cDll}) if nDllHandle > 0 nDllHandle := aDllLoaded[nDllHandle, 02] else nDllHandle := DllLoad(cDll) if nDllHandle > 0 AAdd(aDllLoaded, {cDll, nDllHandle}) else cError := DosErrorMessage(DosError()) endif endif RETURN nDllHandle //////////// // FUNCTION ApiLoadRemoveFont_(cFontFile, lLoad, cError) // -> complete path where is the desired font // More than one font may to be specified separeted by "|" (without quotes)) // Valid extensions are, in example: // .fon, fnt, ttf, ttc, fot, otf, mmm, pfb, pfm etc. // -> install or desinstall the font? // . .t. instals the font(s) // May be it is uninstalled when the computer is reinitialized // . .f. uninstall the font installed by thisfunction // [@] -> Error message // // Retorna: .t. if the font was installed | desinstalled depending on to be .t. | .f. // .f. if the font was not desinstalled | desinstalled depending on to be .t. | .f. ////// STATIC cLoad, cLoadEx, cRemove, cRemoveEx LOCAL nDll, lOk, nAt, nCount cFontFile := AllTrim(cFontFile) if cLoad == NIL nDll := ApiLoadDll_('GDI32.dll') // http://msdn.microsoft.com/en-us/library/windows/desktop/dd183326(v=vs.85).aspx cLoad := DllPrepareCall(nDll, DLL_STDCALL, 'AddFontResourceA') // https://msdn.microsoft.com/en-us/library/windows/desktop/dd183327%28v=vs.85%29.aspx cLoadEx := DllPrepareCall(nDll, DLL_STDCALL, 'AddFontResourceExA') // http://msdn.microsoft.com/en-us/library/windows/desktop/dd162922(v=vs.85).aspx cRemove := DllPrepareCall(nDll, DLL_STDCALL, 'RemoveFontResourceA') // http://msdn.microsoft.com/en-us/library/windows/desktop/dd162923(v=vs.85).aspx cRemoveEx := DllPrepareCall(nDll, DLL_STDCALL, 'RemoveFontResourceExA') endif nCount := 1 nAt := 0 // // Count the amount of fonts must to be installed | uninstalled. // They are separated by "|" (without quotes) do while .t. nAt += 1 nAt := At('|', cFontFile, nAt) if nAt == 0 Exit endif nCount += 1 enddo if lLoad lOk := (DllExecuteCall(cLoad, cFontFile) == nCount .or.; DllExecuteCall(cLoadEx, cFontFile) == nCount) else lOk := (DllExecuteCall(cRemove, cFontFile) == nCount .or.; DllExecuteCall(cRemoveEx, cFontFile) == nCount) endif if lOk Sleep(70) ApiSendMessage_(AppDesktop():getHWND(), WM_FONTCHANGE) else if Empty(cError) cError := '' endif cError += ApiGetLastError_(1063) // Erro fatal durante a instalação endif RETURN lOk //////////// // FUNCTION ApiGetLastError_() // Get the error message: // Retorns: '' if no errors or the error message without trailer CRLF ///// STATIC cErrorInternet, cGetLast, cFormatError LOCAL nHandle, nLastErr, nInternetErr, cMessage, nLen if cGetLast == NIL nHandle := ApiLoadDll_('WinInet.dll') cErrorInternet := DllPrepareCall(nHandle, DLL_STDCALL, 'InternetGetLastResponseInfoA') nHandle := ApiLoadDll_('Kernel32.dll') cGetLast := DllPrepareCall(nHandle, DLL_STDCALL, 'GetLastError') cFormatError := DllPrepareCall(nHandle, DLL_STDCALL, 'FormatMessageA') // DWORD WINAPI FormatMessage(_In_ DWORD dwFlags, // _In_opt_ LPCVOID lpSource, // _In_ DWORD dwMessageId, // _In_ DWORD dwLanguageId, // _Out_ LPTSTR lpBuffer, // _In_ DWORD nSize, // _In_opt_ va_list *Arguments) endif nLastErr := DllExecuteCall(cGetLast) if nLastErr == 0 .or.; nLastErr == ERROR_INTERNET_EXTENDED_ERROR cMessage := Space(INTERNET_MAX_PATH_LENGTH) nLen := INTERNET_MAX_PATH_LENGTH nInternetErr := 0 DllExecuteCall(cErrorInternet, @nInternetErr, @cMessage, @nLen) cMessage := Left(cMessage, nLen) if nInternetErr <> 0 cMessage := ('Error found: ' + LTrim(Str(nInternetErr)) + ', ' + cMessage) elseif nLastErr == ERROR_INTERNET_EXTENDED_ERROR cMessage := ('Error found undetailed: ' + LTrim(Str(nLasterr)) + ', ' + DosErrorMessage(nLastErr)) else cMessage := '' endif else cMessage := Space(INTERNET_MAX_PATH_LENGTH) nLen := DllExecuteCall(cFormatError, FORMAT_MESSAGE_FROM_SYSTEM,; NIL,; nLastErr,; 0,; @cMessage,; INTERNET_MAX_PATH_LENGTH,; NIL) cMessage := ('Error found: ' + (LTrim(Str(nLastErr)) + ', ' + Left(cMessage, nLen))) endif if !Empty(cMessage) cMessage += (CRLF + Space(10) + ProcName(1) + '(' + LTrim(Str(ProcLine(1))) + ')') if !Empty(ProcName(2)) cMessage += (CRLF + Space(10) + ProcName(2) + '(' + LTrim(Str(ProcLine(2))) + ')') endif endif RETURN cMessage