I have a problem, that VB.NET throws an error runtime with my custom fonts, but not always. Sometimes it works, sometimes not. here's my code:
Dim path As String
Private Sub MMenu_Load(sender As Object, e As EventArgs) Handles MyBase.Load
path = "C:/MMCTools/"
Try
Dim privateFonts As New System.Drawing.Text.PrivateFontCollection()
privateFonts.AddFontFile(path & "font.ttf")
Dim font20 As New System.Drawing.Font(privateFonts.Families(0), 20)
Dim font14 As New System.Drawing.Font(privateFonts.Families(0), 14)
Label1.Font = New Font(font20, FontStyle.Regular)
Label2.Font = New Font(font14, FontStyle.Regular)
Catch
MsgBox("Hiba")
End Try
If My.Computer.FileSystem.FileExists(path & "username.mcusr") Then
PictureBox1.ImageLocation = _
"http://mestermc.hu/3dskin/3d.php?a=0&w=0&wt=0&abg=0&abd=0&ajg=0&ajd=0&ratio=13format=png&displayHairs=true& headOnly=false&login=" _
& (ReadALine(path & "username.mcusr", GetNumberOfLines(path & "username.mcusr"), 0))
Else
MCUsr.Show()
Me.Close()
End If
End Sub
The error message:
************** Error contents **************
System.ArgumentException: Invalid parameter.
at: System.Drawing.FontFamily.GetName(Int32 language)
at: System.Drawing.FontFamily.get_Name()
at: System.Windows.Forms.Internal.WindowsFont.FromFont(Font font, WindowsFontQuality fontQuality)
at: System.Windows.Forms.Internal.WindowsGraphicsCacheManager.GetWindowsFont(Font font, WindowsFontQuality fontQuality)
at: System.Windows.Forms.TextRenderer.MeasureText(String text, Font font, Size proposedSize, TextFormatFlags flags)
at: System.Windows.Forms.Layout.LayoutUtils.MeasureTextCache.GetUnconstrainedSize (String text, Font font, TextFormatFlags flags)
at: System.Windows.Forms.Layout.LayoutUtils.MeasureTextCache.TextRequiresWordBrea k(String text, Font font, Size size, TextFormatFlags flags)
at: System.Windows.Forms.Label.CreateTextFormatFlags(Size constrainingSize)
at: System.Windows.Forms.Label.CreateTextFormatFlags()
at: System.Windows.Forms.Label.OnPaint(PaintEventArgs e)
at: System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e, Int16 layer)
at: System.Windows.Forms.Control.WmPaint(Message& m)
at: System.Windows.Forms.Control.WndProc(Message& m)
at: System.Windows.Forms.Label.WndProc(Message& m)
at: System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at: System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at: System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam
This happens when fast switching forms.
Just came across the error myself and figured it out. You are defining the private font collection in the load event and it goes out of scope thereby making it eligible for garbage collection. So depending on how fast it gets collected it may or may not still be around when needed.
I'll tell you how you do it. Don't actually import the fonts into your program but import it on to your computer.
Just access the:
Control Panel -> Appearance and Personalization -> Fonts
And drag the fonts into the folder. Next time, Visual Studio will load the font. This is for windows. If you are using another computer, search how to load fonts onto computer.
I've got your mistake here!!!! It's very easy to solve.
Path most be written with "\" not "/" that's all of it ^^
path = "C:\MMCTools\"
Related
Im trying to get the privatefontcollection to work. But so far its not working, not in the sense of an error, just the font seen on screen is MS Sans Serif and not the Font im trying to load. so far i have tried two diffrent methods and neither seem to have worked for me.
First i tried:
Public Function GetFontInstance(ByVal data() As Byte, ByVal Size As Single, ByVal Style As FontStyle) As Font
Dim result As Font
Try
Dim pfc = New PrivateFontCollection
'LOAD MEMORY POINTER FOR FONT RESOURCE
Dim FontPtr As System.IntPtr = Marshal.AllocCoTaskMem(data.Length)
'COPY THE DATA TO THE MEMORY LOCATION
Marshal.Copy(data, 0, FontPtr, data.Length)
'LOAD THE MEMORY FONT INTO THE PRIVATE FONT COLLECTION
pfc.AddMemoryFont(FontPtr, data.Length)
'FREE UNSAFE MEMORY
'Marshal.FreeCoTaskMem(FontPtr)
result = New Font(pfc.Families(0), Size, Style)
pfc.Families(0).Dispose()
pfc.Dispose()
Catch ex As Exception
'ERROR LOADING FONT. HANDLE EXCEPTION HERE
MsgBox("Error in [GetFontInstance()]" & vbCrLf & ex.Message)
result = New Font(FontFamily.GenericMonospace, 8)
End Try
Return result
End Function
i called this function from the Print SubRoutine:
Dim newFont As Font = GetFontInstance(My.Resources.OpenSans_Bold, 22, FontStyle.Bold)
e.Graphics.DrawString("Hello World", newFont, Brushes.Black, 50, 2)
but what i see in the printdocument print preview, is just MS Sans Serif type font. not the font i have loaded into my Resources.
I then tried this method:
Dim sAppPath As String
sAppPath = System.Windows.Forms.Application.StartupPath
Dim fcollect As New PrivateFontCollection()
fcollect.AddFontFile(sAppPath & "\OpenSans-Bold.ttf")
Dim OpenSansFont As New Font(fcollect.Families(0), 50, FontStyle.Bold)
e.Graphics.DrawString("Hello World", OpenSansFont, Brushes.Black, 50, 2)
again i got the same result
is there something I'm missing to get this to work. other questions asked about this seem to indicate this should just work.
I should mention that the end user will run the Application on a system admin locked PC, so the option to "install" the font wont be possible. Id need to make use of the font only while the application is running / when the subroutine gets called.
I want to convert a file format BMP to PDF in Visual Studio using Visual Basic technology and I use the PDFsharp library to do this.
I recieved the following error:
An unhandled exception of type 'System.IO.FileNotFoundException' occurred in PdfSharp-wpf.dll
Additional information: The file 'E:...\bin\Debug-1493104802' does not exist.
I copied the whole contents of form to .bmp and it runs correctly. You can see my code:
Call SendMessage(TableLayoutPanel2.Handle, WM_PRINT, hdc, _ EDrawingOptions.PRF_CHILDREN Or _ EDrawingOptions.PRF_CLIENT Or _ EDrawingOptions.PRF_NONCLIENT Or _ EDrawingOptions.PRF_OWNED)
myGraphics.ReleaseHdc(hdc)
Dim doc As New PdfDocument()
doc.Pages.Add(New PdfPage())
Dim xgr As XGraphics = XGraphics.FromPdfPage(doc.Pages(0))
Dim img As XImage = XImage.FromFile(myGraphics.GetHdc)
xgr.DrawImage(img, 0, 0)
doc.Save("E:\out.pdf")
doc.Close()
' myBmp.Save("E:\out.bmp")
myGraphics.Dispose()
myGraphics = Nothing
myBmp = Nothing
After looking at your code it looks like you are generating an image using myGraphics, if that is the case you may want to save this to a tempfile, load it into the pdf and then you can delete it after you save the pdf.
Use the information on the following link to save the file.
https://stackoverflow.com/a/2881188/7436406
From your code snippet:
Dim img As XImage = XImage.FromFile(myGraphics.GetHdc)
You need a file name, but you pass an HDC? Great.
Maybe the compiler implicitly calls ToString() to make this compile. But there is no file.
Save the image to a Stream and then call XImage.FromStream to get that image in PDFsharp.
Background
I have a Winform application (VB.NET framework 4.0). Within the application are two forms: frmHome (startup form) and frmdePDF (secondary form with an Adobe PDF Reader COM control). frmHome grabs a PDF pathway from DFS, checks if the pathway actually exists, and if so, loads the file into my PDF control and shows frmdePDF. Now, this works 100% of the time on my local machine. However, the initial load on any other machine throws a NullReferenceException. Other events (e.g. my datagridview CellContentClick) that call the SAME code works fine on all machines. I understand (I hope correctly) that the issue is initializing that frmdePDF the first time.
Code
The code that loads the datagridview (dgDE) and pulls the PDF pathway:
Private Sub btnDELegalLOMCState_Click(sender As Object, e As EventArgs) Handles btnDELegalLOMCState.Click
loadStatus = "State"
Dim deState As String = Nothing
''Validate and set state
If Me.cbDEState.SelectedIndex = 0 Then
MessageBox.Show("Please select a state.")
Exit Sub
Else
deState = Me.cbDEState.Text
End If
''Populate dgDE/set data bindings
Try
Me.cbDERegion.ComboBox.SelectedIndex = -1
Me.dgDE.DataSource = Nothing
Me.SpSelectLOMAbyStateTableAdapter.Fill(Me.DevGISDataSet.spSelectLOMAbyState, 4, deState)
Me.dgDE.DataSource = Me.SpSelectLOMAbyStateBindingSource
Me.bnDE.BindingSource = Me.SpSelectLOMAbyStateBindingSource
Me.txtDEIssueDte.DataBindings.Clear()
Me.txtDECaseNum.DataBindings.Clear()
Me.txtDECommNum.DataBindings.Clear()
Me.txtDEIssueDte.DataBindings.Add(New System.Windows.Forms.Binding("Text", Me.SpSelectLOMAbyStateBindingSource, "IssueDte", True))
Me.txtDECaseNum.DataBindings.Add(New System.Windows.Forms.Binding("Text", Me.SpSelectLOMAbyStateBindingSource, "CaseNum", True))
Me.txtDECommNum.DataBindings.Add(New System.Windows.Forms.Binding("Text", Me.SpSelectLOMAbyStateBindingSource, "CommNum", True))
Catch ex As Exception
MessageBox.Show("Error loading LOMAs: " & ex.Message.ToString)
End Try
''Load PDF
If Me.dgDE.RowCount <> 0 Then
Dim i As Integer = Me.dgDE.CurrentRow.Index
Dim pathdePDF As String = Me.dgDE.Rows.Item(i).Cells(5).Value.ToString
LoaddePDF(pathdePDF)
End If
End Sub
The Public Sub that contains code to load the file and show frmdePDF:
Public Sub LoaddePDT(ByVal pathdePDF As String)
If System.IO.File.Exists(pathdePDF) Then
frmdePDF.pdfLOMC.LoadFile(pathdePDF)
frmdePDF.Show()
Else
MessageBox.Show("Image not available. Please check FEMA and CAMSIS.")
frmdePDF.Hide()
End If
End Sub
Other things I have tried
Creating a new instance of the form each time:
Public Sub LoadPDF_test(ByVal pathdePDF As String)
Dim openForms = Application.OpenForms.OfType(Of frmdePDF)()
While openForms.Any
openForms.First.Close()
End While
If System.IO.File.Exists(pathdePDF) Then
Dim newfrmdePDF As New frmdePDF
newfrmdePDF.pdfLOMC.LoadFile(pathdePDF)
newfrmdePDF.Show()
Else
MessageBox.Show("Image not available. Please check FEMA and CAMSIS.")
End If
End Sub
This code works on my machine 100%. It behaves the same way as the first load code on any other machine (throws the NullReferenceException).
Exception Text
See the end of this message for details on invoking
just-in-time (JIT) debugging instead of this dialog box.
************** Exception Text **************
System.NullReferenceException: Object reference not set to an instance of an object.
at SaveLOMC.frmHome.LoadPDF_test(String testPath) in C:\Data\Alycia\Development\LOMC\Projects\TFS_test\SaveLOMC\SaveLOMC\frmHome.vb:l ine 46
at SaveLOMC.frmHome.btnDENewLOMCState_Click(Object sender, EventArgs e) in C:\Data\Alycia\Development\LOMC\Projects\TFS_test\SaveLOMC\SaveLOMC\frmHome.vb:l ine 440
at System.Windows.Forms.ToolStripItem.RaiseEvent(Object key, EventArgs e)
at System.Windows.Forms.ToolStripMenuItem.OnClick(EventArgs e)
at System.Windows.Forms.ToolStripItem.HandleClick(EventArgs e)
at System.Windows.Forms.ToolStripItem.HandleMouseUp(MouseEventArgs e)
at System.Windows.Forms.ToolStripItem.FireEventInteractive(EventArgs e, ToolStripItemEventType met)
at System.Windows.Forms.ToolStripItem.FireEvent(EventArgs e, ToolStripItemEventType met)
at System.Windows.Forms.ToolStrip.OnMouseUp(MouseEventArgs mea)
at System.Windows.Forms.ToolStripDropDown.OnMouseUp(MouseEventArgs mea)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
at System.Windows.Forms.ToolStrip.WndProc(Message& m)
at System.Windows.Forms.ToolStripDropDown.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
I have tried stepping through the debugger on my local machine. But again, I can't recreate the error on it so the objects all have assigned values.
I know this question has been asked endlessly. I have read through all of these (plus MORE!):
What is a NullReferenceException, and how do I fix it?
"Object reference not set to an instance of an object?"
Object reference not set to an instance of an object. vb.net looking up a string
visual basic: object reference not set to an instance of an object
Visual Basic - Object reference not set to an instance of an object
VB.Net How to set an object reference to an instance of an object?
object reference not set to an instance of an object. vb.net for some but not all code
Object reference not set to an instance of an object.
specific error on :"Object reference not set to an instance of an object."
Object reference not set to an instance of an object
"Object reference not set to an instance of an object" message
object reference not set to an instance of an object error showing
Additional information: my local machine is 64 bit, the other machines are 32 bit. The associated .dll files for the Adobe component are 32 bit. My Target CPU in the Application Properties is x86.
Any advice is appreciated, I wouldn't ask this broad question if I hadn't exhausted my options.
Solution
There was nothing wrong with the form load event--I was trying to manually set the location/bounds of the form on load. Set the bounds to a non-existent screen (my computer has three screens--everyone else has 2). Learning experience?
I was following this: http://zerosandtheone.com/blogs/vb/archive/2009/11/20/vb-net-include-a-font-as-an-embedded-resource-in-your-application.aspx to allow my application to use a custom fonts in a labels. The problem with that is I can run the application on my computer (probably because I have this font installed), the problem appears when any other person run the compiled application on his computer; the following error from the exception catch appears: 53 File doesn't exists.
Where does this exception is located at?
I'm talking about the module I linked above:
'MATTHEW KLEINWAKS
'ZerosAndTheOne.com
'2009
'CUSTOM FONT LOADED DYNAMICALLY FROM A RESOURCE
Imports System.Drawing.Text
Imports System.Runtime.InteropServices
Module CustomFont
'PRIVATE FONT COLLECTION TO HOLD THE DYNAMIC FONT
Private _pfc As PrivateFontCollection = Nothing
Public ReadOnly Property GetInstance(ByVal Size As Single, _
ByVal style As FontStyle) As Font
Get
'IF THIS IS THE FIRST TIME GETTING AN INSTANCE
'LOAD THE FONT FROM RESOURCES
If _pfc Is Nothing Then LoadFont()
'RETURN A NEW FONT OBJECT BASED ON THE SIZE AND STYLE PASSED IN
Return New Font(_pfc.Families(0), Size, style)
End Get
End Property
Private Sub LoadFont()
Try
'INIT THE FONT COLLECTION
_pfc = New PrivateFontCollection
'LOAD MEMORY POINTER FOR FONT RESOURCE
Dim fontMemPointer As IntPtr = _
Marshal.AllocCoTaskMem( _
My.Resources.DIGITALDREAMNARROW.Length)
'COPY THE DATA TO THE MEMORY LOCATION
Marshal.Copy(My.Resources.DIGITALDREAMNARROW, _
0, fontMemPointer, _
My.Resources.DIGITALDREAMNARROW.Length)
'LOAD THE MEMORY FONT INTO THE PRIVATE FONT COLLECTION
_pfc.AddMemoryFont(fontMemPointer, _
My.Resources.DIGITALDREAMNARROW.Length)
'FREE UNSAFE MEMORY
Marshal.FreeCoTaskMem(fontMemPointer)
Catch ex As Exception
MessageBox.Show(& Err.Number & " " & Err.Description)
End Try
End Sub
End Module
precisely this:
Catch ex As Exception
MessageBox.Show(& Err.Number & " " & Err.Description)
End Try
Is showing the message box, containing the 53 File doesn't exists message.
I don't really know why does it happends, because it works on my computer without any problems... I would appreciate any help attempt!
Try using this code
''' <summary>Adds the specified font to the private font collection.</summary>
''' <param name="font">The font to be added.</param>
Public Sub AddFont(ByVal font As Byte())
If font Is Nothing Then Throw New ArgumentNullException("The font cannot be null.", "font")
If font.Length = 0 Then Throw New ArgumentException("The length of the font array cannot be 0.", "font")
Try
privateFonts.AddMemoryFont(Marshal.UnsafeAddrOfPinnedArrayElement(font, 0), font.Length)
Catch ex As Exception
'handle you exceptions here
End Try
End Sub
And add fonts to the collection this way
Private Sub LoadFont()
Try
'INIT THE FONT COLLECTION
privateFonts = New PrivateFontCollection
AddFont(My.Resources.DIGITALDREAMNARROW)
Catch
'
' the rest of your code
'
End Sub
Assuming you added the font resource as a file, it is going to be passed to the AddFont method as a byte array.
Needless to say, the AddFont method assumes you have an initialized PrivateFontCollection object called privateFonts which is accessible within the scope of the method.
Update
Since you're saying that my solution is not working, I've uploaded a sample project here. Download and see how to load and use private fonts from resources.
I'm working on a project for school in which a dll is loaded.
The dll that is loaded is a bridge between my program and the Twincat System Manager which forms the bridge between the computer and a PLC via the local network.
I need to read Variables trough this whole chain from the plc to my program.
This is the way I do this:
Public Function adsReadReal(ByVal Variabelenaam As String) As Single
Dim ds = New TwinCAT.Ads.AdsStream(4 * 8) ' new data stream
Dim br = New System.IO.BinaryReader(ds) 'new binary
Dim hVar = New Integer
Try
ConState(1)
tcclient = New TcAdsClient
ConState(2)
tcclient.Connect(Form1.amsAdress, 801) 'connects the tcclient to the PLC
hVar = tcclient.CreateVariableHandle(Variabelenaam) 'creats a handle for the variable
tcclient.Read(hVar, ds) 'read it
ConState(5)
Return br.ReadSingle() 'convert it from binary to readable for vb
Catch ex As Exception
ConState(0)
PrintEx(ex) 'print out the exception
finally
tcclient.Dispose() 'make the object stop being used to prevent a lingering connection
End Try
Return False
End Function
Now the program loads a dll called TwinCAT.ADS.dll at the start of the connection module. If the Twincat system manager is running the program ends normally, but when it is not it crashes and gives me this error:
System.DllNotFoundException was unhandled
Message="Kan DLL tcadsdll.dll niet laden: Kan opgegeven module niet vinden. (Uitzondering van HRESULT: 0x8007007E)"
Source="TwinCAT.Ads"
TypeName=""
StackTrace:
bij TwinCAT.Ads.Internal.TcAdsDllWrapper.TcAdsDll.AdsAmsUnRegisterRouterNotification()
bij TwinCAT.Ads.Internal.TcAdsDllWrapper.AmsUnRegisterRouterNotification(Boolean
throwAdsException)
bij TwinCAT.Ads.Internal.TcLocalSystem.Dispose(Boolean disposing)
bij TwinCAT.Ads.Internal.TcLocalSystem.Finalize()
which is roughly translated to:
Cannot load DLL tcadsdll.dll: Cannot find given module. (Exception at
HRESULT: 0x8007007E)
This is not a dll that I have imported, so it must be from the TwinCAT.ADS.dll
How can I prevent the program from throwing this error at me and instead close the program peacefully? I have tried to catch all the exceptions of every dll related operation possible.
Also the source is on Bitbucket. I will make it public on request.
Some links on the official but quite unhandy Beckhoff site:
http://infosys.beckhoff.com/espanol.php?content=../content/1034/tcquickstart/html/tcquickstart_samplevisualbasicnet.htm&id=10449
Edit:
Apparently using tcclient.dispose() causes the error since the finnaly statement was use instead of just after the try block
Edit: This currently catches the exception but it does not handle it.
Dim currentDomain As AppDomain = AppDomain.CurrentDomain
AddHandler currentDomain.UnhandledException, AddressOf MyHandler
Dim tick As Byte = 0
Sub MyHandler(sender As Object, args As UnhandledExceptionEventArgs)
Dim ex As Exception = DirectCast(args.ExceptionObject, Exception)
MsgBox("exception tick" & Str(tick))
tick = tick + 1
PrintEx(ex)
End Sub
Edit:
The exception isn't caught properly because in vs2008 a couple of errors occurs but the tick appears after I press F5 (continue)
When the program is run directly, I only see 1 Tick. Then windows gives an error.
Did you try an unhandled exception handler?
Dim currentDomain As AppDomain = AppDomain.CurrentDomain
AddHandler currentDomain.UnhandledException, AddressOf MyHandler
Sub MyHandler(sender As Object, args As UnhandledExceptionEventArgs)
Dim e As Exception = DirectCast(args.ExceptionObject, Exception)
Console.WriteLine("MyHandler caught : " + e.Message)
End Sub