Windows Clipboard, Store Image Using MS Forms Data Object - VBA - windows

I want to put an image on the Windows clipboard using VBA. I currently do this for text essentially as described here using the DataObject in the MS Forms 2.0 Library.
I want to do the same thing using an image file, putting the image on the clipboard instead of text.
My working code used for text is below, I have tried using the image file path as the variable but just stores the text. Also tried "SetImage" as a method but throws error as below.
Dim DataObj As MSForms.DataObject
Set DataObj = New MSForms.DataObject
DataObj.SetText str1 <--------------- works for string variable
DataObj.SetImage strImageFilePath <----------- Error Method not available
DataObj.PutInClipboard

Related

Adobe Reader cannot read fonts from my project?

I am generating the PDF using iTextPdf version 5 and am using Calibri font inside that PDF. I have loaded that font from the src/resource/fonts folder as I am working with Boot. All is working fine as I can view that PDF in my project and download also except that when I am trying to open the PDF using Adobe Reader, than the page is showing something like that-
I have opened that PDF using Google Chrome, WPS office and other PDF Reader and that PDF is working perfectly fine but I can't seem to understand what is wrong when I am trying to view the PDF using Adobe. I have also attached the screenshot of PDF in WPS office below -
Here is the code that I have loaded the font in my PDF -
static URL calibriFont = UserProfileController.class.getResource("/static/fonts/Calibri Regular.ttf");
static Font namefont = FontFactory.getFont(calibriFont.toString(), 20, Font.BOLD, new BaseColor(139, 0, 0));
FontFactory.register(calibriFont.toString());
Here is the PDF File link shared below -
Sample PDF
In short
Additional data was added to the PDF after initial generation, introducing a cross reference error. Take the first 1019493 bytes of the file to get the original working file.
My first guess would be another program postprocessing the PDF incorrectly but as it turned out the iText objects were closed incorrectly resulting in that error.
In detail
The final version of the PDF you shared is not generated by iText, at least not by correct iText usage.
The file has a size of 1021972 bytes. The initial 1019493 bytes constitute a valid PDF.
The extra 2479 bytes extend the PDF providing some updated old object, some new objects, and a full cross reference table. And in this cross reference table the offset entry for the first new object 33 is incorrect, it should be 0001019493 (the first byte added after the original contents, i.e. the start of the first new object) but it is 0001018667 (the start of the cross reference table of the original PDF).
Thus, a PDF processor will incorrectly find the original cross references when looking for the new object 33.
As the object 33 happens to contain the FontDescriptor of the font Calibri in the updated object 1, an attempt to parse this font fails. This font is referenced from all document pages.
As a results, Adobe Reader stops drawing each page as soon as it comes across an instruction using that font.
Some other PDF viewers repair that error under the hood and, therefore, show you what you want to see.
The actual cause
In a comment you write
The error was coming due to PdfWriter instance object was closed before document.
Indeed, you are not expected to close the PdfWriter at all, and in particular not before the Document.
When requesting a PdfWriter using PdfWriter.getInstance for a Document, a PdfDocument instance is created and registered as listener of the Document; then a PdfWriter is created and registered as listener of the PdfDocument.
To finalize the PDF generation you are expected to close the Document. This will call its listeners' respective close methods, i.e. PdfDocument.close, which will finish some last objects, write them, and then call its own listener's close method, i.e. PdfWriter.close, which will write the cross references.
In your code you first explicitly called PdfWriter.close (which wrote the first cross reference table) and then Document.close (which caused PdfDocument to write some objects and then trigger PdfWriter.close again to write the second cross references). This incorrect sequence also resulted in an incorrect cross reference offset.
I have found the solution of my problem as what I was doing that, I have closed PdfWriter instance before the document. When I closed that instance after the document, it was working fine.

itext7 PdfButtonFormField setImage method does not work on a signed pdf

I am using itext7 java library as shown below to add PdfButtonFormField to an existing pdf :
String src = "sample.pdf";
String dest = "acro_sample_empty_fields.pdf";
PdfDocument pdf = new PdfDocument(new PdfReader(src), new PdfWriter(dest));
PdfAcroForm form = PdfAcroForm.getAcroForm(pdf, true);
PdfButtonFormField button = PdfFormField.createPushButton(pdf, new Rectangle(Integer.parseInt(control.xCord), Integer.parseInt(control.yCord),Integer.parseInt(control.width), Integer.parseInt(control.height)), control.name, control.value);
form.addField(button, page);
String resource = "sample.png";
button.setImage(resource);
After this i use the following code to fill the form like below :
String src = "1540982441_313554925_acro_sample_empty_fields_signedFinal.pdf";
String dest = "acro_sample_filled_fields.pdf";
PdfReader reader = new PdfReader(src);
File output = new File(dest);
OutputStream outputStream = new FileOutputStream(output);
PdfDocument document = new PdfDocument(reader,
new PdfWriter(outputStream),
new StampingProperties().useAppendMode());
PdfAcroForm form = PdfAcroForm.getAcroForm(document, true);
Map<String, PdfFormField> fields = form.getFormFields();
String resource = "sample_test.png";
((PdfButtonFormField)fields.get(control.name)).setImage(resource);
Everything works fine for a normal pdf. But if i digitally sign the created pdf and then try to fill it. then the image is not set properly.
For a normal pdf the image on the push button is changed as expected. But on the digitally signed pdf the image is not set.
I have tried looking for this on google but no luck yet. Any help will be appreciated. Thanks in advance.
I tested the code in this answer with the signed but unfilled PDF you shared. As you didn't share a sample image, though, I used one of my own.
A more precise observation
You say
Everything works fine for a normal pdf. But if i digitally sign the created pdf and then try to fill it. then the image is not set properly. For a normal pdf the image on the push button is changed as expected. But on the digitally signed pdf the image is not set.
This is not entirely true, the image is set but not all PDF viewers show it.
In detail: If you set the image in the signed PDF using your code, Adobe Reader indeed shows merely a grey box
but other PDF viewers, e.g. Foxit or Chrome's built-in viewer, do show the replacement image
Thus, the image is set for the digitally signed PDF, too. The actual problem is that Adobe Reader does not display it!
The cause
After some analysis and having followed some red herrings, the cause of the problem appears to be that if Adobe Reader displays a PDF with a changed AcroForm button appearance and
the PDF is not signed, then Adobe Reader simply uses the updated appearance stream; but if
the PDF is signed, then Adobe Reader tries to ignore the updated appearance stream and construct a new appearance from appearance characteristics information.
(Other PDF viewers, though, appear to always use the updated appearance stream.)
iText does create an appearance characteristics dictionary for the button (so Adobe Reader assumes it can ignore the updated appearance and can construct an new one based on this dictionary) but unfortunately does not add some button specific information to it, neither when constructing the button nor when changing the button. This in particular concerns the following two entries:
I
stream
(Optional; push-button fields only; shall be an indirect reference) A form XObject defining the widget annotation’s normal icon, which shall be displayed when it is not interacting with the user.
TP
integer
(Optional; push-button fields only) A code indicating where to position the text of the widget annotation’s caption relative to its icon:
0 No icon; caption only
1 No caption; icon only
2 Caption below the icon
3 Caption above the icon
4 Caption to the right of the icon
5 Caption to the left of the icon
6 Caption overlaid directly on the icon
Default value: 0.
(ISO 32000-2, Table 192 — Entries in an appearance characteristics dictionary)
As iText does not supply the TP value, the Default value kicks in and Adobe Reader creates a button appearance with "No icon; caption only". As no caption is defined, the result is a grey box.
A work-around
The most simple work-around is to remove the whole appearance characteristics dictionary during image update, i.e. replace
((PdfButtonFormField)fields.get(control.name)).setImage(resource);
by
PdfButtonFormField button = (PdfButtonFormField)fields.get(control.name);
button.setImage(resource);
if (button.getPdfObject().containsKey(PdfName.MK)) {
button.setModified();
button.getPdfObject().remove(PdfName.MK);
}
(SetButtonImage helper method setLikeGautamAnandImproved)
Now Adobe Reader does not find any appearance characteristics and, therefore, cannot ignore the updated appearance stream.
A fix
Alternatively we can add the missing appearance characteristics entries, e.g. like this:
PdfButtonFormField button = (PdfButtonFormField)fields.get(control.name);
button.setImage(resource);
PdfWidgetAnnotation widget = button.getWidgets().get(0);
PdfDictionary characteristics = widget.getAppearanceCharacteristics();
if (characteristics != null) {
characteristics.setModified();
characteristics.put(PdfName.I, widget.getNormalAppearanceObject());
characteristics.put(PdfName.TP, new PdfNumber(1));
}
(SetButtonImage helper method setLikeGautamAnandImproved2)
The result looks slightly different, though:
As you see, there is a small frame around the image. Most likely you can make it vanish by setting other characteristics accordingly.

PDFDocument(data: myPdfDoc.dataRepresentation()) does not reproduce original PDF

I encounter a weird bug using PDFKit's PDFDocument.
I have an app with a PDFView and the user can drag & drop a PDF on it.
On this event, I save the data representation (NSData) in my core-data structure
myCoreDataObject.pdfdata = myPDFView.dataRepresentation()
Later, the user can select the core data object to display the PDF, which calls
myPDFView.setDocument(PDFDocument(data: myCoreDataObject.pdfdata))
The PDF is correctly displayed in the PDFView BUT when the user selects text in it, copy-pastes it in another editor, the selection is made of empty(blank) characters ! Which was not the case with the original dragged-and-dropped PDF.
So my question is: WHY this code:
PDFDocument(data: myPdfDoc.dataRepresentation())
does not return the exact same PDF ?
IMPORTANT NOTE: this only happens with OCR'd PDF that have been through ABBY FineReader OCR.
Additional information: the "modification" in the PDF only appears when the binary data goes through core data. I ran a test by directly calling
PDFDocument(data: PDFDocument(url: myUrl).dataRepresentation())
, and the PDF works as expected.

Load Picture to Microsoft Access 2010 Ribbon from Table

I'm working with Access 2010's new ribbon feature, and I'm trying to figure out the simplest way to load an image to the ribbon from a table. I know that I could do this by using a GDI API function, but from what I can see the code looks convoluted and appears to utilize extra dlls that I would just as well avoid calling if I don't need to. I also know that I could create a control on a form, load the image to the form, and then load the image from the form to the ribbon image variable. While using the form is doable, it seems sloppy. Eventually, I will resort to one of the two preceding methods if I have to, but it just seems like there should be some simple way to load an image from a table directly into an image variable for the ribbon.
One thing to note is that I'm willing to use whatever image format is easiest. These icon files are very small and so I'm not concerned about file size and I also don't care whether or not they are capable of transparency. So if there's a method that only works with bitmap file types that is fine with me.
Here's the code I have for the button in the ribbon XML:
<button id="CCTrans" label="Credit Card Trans." getImage="GetMnuIcn" onAction="=OpenCCTrans()" />
And here's the code I have for retrieving the image:
Sub GetMnuIcn(control As IRibbonControl, ByRef Image)
Set Image = DLookup("Img", "LtblImg", "Lbl=""" & control.ID & """")
End Sub
I've tried storing the image both as an OLE Object and as an attachment. Either way, when I try to retrieve it, it gives me the error "Type Mismatch". For simplicity, I've been storing it as a bitmap, but I also tried .gif and .png in my first attempts.
Note: Apparently the ribbon icons are IPictureDisp objects. If I can just figure out how to load an image from a table into one of those object types, I should be able to use it for the ribbon.
Also, there's a lot of good information on Microsoft's website, but I haven't been able to piece it together into a solution yet. Here's a link: http://msdn.microsoft.com/en-us/library/bb187398.aspx
Well after tedious days of trying to find a better solution, I'm forced to pick between what I feel are various mediocre approaches. I really wanted to just load it directly into a variable, but the only method for doing that requires references to a bunch of dlls and has code that is pretty complicated. To avoid any extra dependencies and to keep my code simpler, I decided to go the route of assigning the table containing the attached images to a form, opening that form in hidden mode and then assigning the picture variables from the form.
For some reason the code that I saw elsewhere that loaded the pictures on demand via this method caused my program to crash and so I had to load the pictures into variables when the program opened and then have the menu bar set the icons from those variables when the menu is selected.
My code is as follows:
Dim Icn(15) As IPictureDisp, IcnLbl(15) As String
Function SetMnuIcn()
Dim Img As Recordset, i As Byte
DoCmd.OpenForm "frmImg", acNormal, , , acFormReadOnly, acHidden
Set Img = Forms!frmImg.Recordset
While Not Img.EOF
i = i + 1
Set Icn(i) = Forms!frmImg!Img.PictureDisp
IcnLbl(i) = Img!Lbl
Img.MoveNext
Wend
DoCmd.Close acForm, "frmImg", acSaveNo
End Function
Sub GetMnuIcn(control As IRibbonControl, ByRef Image)
Set Image = Icn(GetAryLoc(IcnLbl, control.ID, 15))
End Sub
Function GetAryLoc(varValues As Variant, varMatch As Variant, NumOfValues As Integer) As Integer
Dim i As Integer
For i = 1 To NumOfValues
If varValues(i) = varMatch Then GetAryLoc = i
Next
End Function
Note: To ensure that the icons have been loaded prior to when they are needed, I specified SetMnuIcn to run on ribbon load:
<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui" onLoad="=SetMnuIcn()">

How to get a C# Image over to Monotouch

I am connecting from monotouch through wcf to my windows c# host and wish to stream an image back to monotouch so I can display this.
My image is held in an System.Drawing.Image object which is not available in monotouch (it uses UIImage).
I was hoping to convert the Image on the host to a string like so:
Image im = Image.FromFile(path);
MemoryStream ms = new MemoryStream();
im.Save(ms, im.RawFormat);
byte[] array = ms.ToArray();
return Convert.ToBase64String(array);
And then using the opposite within MonoTouch to get my Image back again:
byte[] array = Convert.FromBase64String(imageString);
Image image = Image.FromStream(new MemoryStream(array));
return image;
This works fine in a 'pure' .net environment but monotouch doesn't recognise the Image object so it fails on that end.
How can I convert the byte[] back into a UIImage?
I tried things like this:
UIImage img = (UIImage)UIImage.FromObject(bytes);
to no avail...
Any help much appreciated!
Instead of passing im.RawFormat, try using one of:
ImageFormat.Bmp
ImageFormat.Png
Depending on which format your images usually are. These are in System.Drawing.Imaging, see here.
This might cause trouble for other client applications, I would recommend having the client send something to determine what format the server returns.

Resources