Putting a CGImageRef on the clipboard - c++

I'm trying to copy a CGImageRef to the clipboard pasteboard. I found a function that claims it should do this by creating a destination from (zero sized), adding the image to the destination, finalizing, then PasteboardPutItemFlavor the ref into the clipboard.
However it doesn't work, so two questions:
Is this the correct way to go about this? (ie, is there just a small bug, or am I doing it wrong?)
What type should I make the destination? The source had it as TIFF, but word doesn't seem to know how to deal with that, I changed it to PICT, which at least gave me the "paste" option, but then said it was too big...
Code:
void copyCGImageRefToPasteboard(CGImageRef ref)
{
OSStatus err = noErr;
PasteboardRef theClipboard;
err = PasteboardCreate( kPasteboardClipboard, &theClipboard );
err = PasteboardClear( theClipboard );// 1
CFMutableDataRef url = CFDataCreateMutable(kCFAllocatorDefault, 0);
CFStringRef type = kUTTypePICT;
size_t count = 1;
CFDictionaryRef options = NULL;
CGImageDestinationRef dest = CGImageDestinationCreateWithData(url, type, count, options);
CGImageDestinationAddImage(dest, ref, NULL);
CGImageDestinationFinalize(dest);
err = PasteboardPutItemFlavor( theClipboard, (PasteboardItemID)1, type, url, 0 );
}

Enter "The Cupertino Tongue Twister" by James Dempsey
Peter put a PICT upon the pasteboard.
Deprecated PICT's a poor pasteboard type to pick.
For reference see: http://developer.apple.com/mac/library/documentation/cocoa/Conceptual/PasteboardGuide106/Articles/pbUpdating105.html
In short: it's deprecated to put PICT on the pasteboard.

Ok, I'm answering my own question here, but here's what I've found:
Apple wants you to use PDF for pasteboards. So if you swap out Pict with PDF, it pretty muc just works. However, MS Word (what I was testing with) only started to allow pasting of PDF in the newest version (Which I don't have).
So, that's the solution, use PDF, and require Word 2008.

Related

C++ How to use Range parameter with InlineShapes AddPicture() method

There is very limited documentation on using this method with C++. Most of the documentation is for VB. Please help me to 1) create a range object 2) use this range object with the AddPicture() method.
Here is the AddPicture definition for C++:
LPDISPATCH InlineShapes::AddPicture(LPCTSTR FileName, VARIANT* LinkToFile, VARIANT* SaveWithDocument, VARIANT* Range)
Below is working code that inserts an image into a word document. It inserts at top of doc because the range parameter(4th parameter, currently 'covOptional') is not specified. There is other code that sets up m_disp to interact with document of interest.
_Document objDoc;
COleVariant covOptional;
//instantiate the document object
objDoc.AttachDispatch(m_disp);
//adding image to doc
InlineShapes objInlineShapes(objDoc.GetInlineShapes())
objInlineShapes.AddPicture("C:\\QR.png", covOptional, covOptional, covOptional);
Here is more info on what I am trying to do incase there are alternative ways. I have a word document that I need to add a png image to. I see a couple ways of doing this: 1) hardcode range objects that specify the position in the document of the png to be inserted into 2) add anchor strings (ex. %pngLocation%) to the document. Find a way to return a range that represents this string's location. Use that range with the AddPicture() method.
I had to use a different msword library, but I got this to work with the following code.
#import "C:\Program Files (x86)\Microsoft Office\root\Office16\MSWORD.OLB" named_guids raw_native_types rename("ExitWindows", "WordExitWindows") rename("FindText", "WordFindText"), rename("VBE", "testVBE")
#include "path\debug\msword.tlh"
//setting up
Word::WindowPtr pWindow = w_app.GetActiveWindow();
Word::Range* pRange = pWindow->Selection->GetRange();
pRange->Start = 20;
pRange->End = 20;
VARIANT vTargetRange;
vTargetRange.vt = VT_DISPATCH;
vTargetRange.pdispVal = pRange;
I was able to use '&vTargetRange' as the range parameter in AddPicture().
Thank you to Castorix31.

MAPI, HrQueryAllRows: Filter messages on subject

I'm pretty much new to MAPI and haven't wrote much C++ Code.
Basically I want to read all emails in the inbox and filter them based on their subject text. So far I'm using the source code provided at the microsoft msdn website which basically reads all emails from the inbox. What I want now is to not get all emails but filter them on the subject, lets say: I want all emails in my Inbox with the subject title "test".
So far I figuered out that the following line of code retrieves all the mails:
hRes = HrQueryAllRows(lpContentsTable, (LPSPropTagArray) &sptCols, &sres, NULL, 0, &pRows);
The parameter &sres is from the type SRestriction.
I tried to implement a filter on 'test' in the subject:
sres.rt = RES_CONTENT;
sres.res.resContent.ulFuzzyLevel = FL_FULLSTRING;
sres.res.resContent.ulPropTag = PR_SUBJECT;
sres.res.resContent.lpProp = &SvcProps;
SvcProps.ulPropTag = PR_SUBJECT;
SvcProps.Value.lpszA = "test";
ScvProps is from the type SPropValue.
If i execute the application then I get 0 lines returned. If I change the String test to an empty String then I get all emails.
I'm assuming i'm using the "filter" option wrong, any ideas?
Edit: When I change the FuzzyLevel to:
sres.res.resContent.ulFuzzyLevel = FL_SUBSTRING;
then I can look for subjects that contain a single character but as soon as I add a second character I get 0 rows as result. I'm pretty sure this is just some c++ stuff that I don't understand that causes all this problems ...
I figured the problem out.
Replacing
sres.res.resContent.ulFuzzyLevel = FL_FULLSTRING;
sres.res.resContent.ulPropTag = PR_SUBJECT;
SvcProps.ulPropTag = PR_SUBJECT;
with
sres.res.resContent.ulFuzzyLevel = FL_SUBSTRING;
sres.res.resContent.ulPropTag = PR_SUBJECT_A;
SvcProps.ulPropTag = PR_SUBJECT_A;
fixed the problem.

Word automation with C++ Builder 5

I'm trying to control Word through a c++ builder 5 application. I would like to
open a ".dot" model file created with Word and modify it. In the ".dot" model file
there are some fields. For example, Title, LastName, FirstName, Address
and so on, and I would like to modify these fields putting text into them and then
saving file with a new name, for example "Warning.doc" leaving the ".dot" file
unaltered.
I can open the file, count the number of fields it contains, but then
when it comes to replacing each field with a string I don't know how to do because
I don't have a complete documentation on OleFunction and OlePropertyGet methods. I attach my source code to this message, can anybody help me to solve this problem please?
try
{
my_word = Variant::CreateObject("word.application");
}
catch (...)
{
Application->MessageBox("Unable to obtain Word automation object",
"Error:",MB_OK | MB_ICONERROR);
}
my_word.OlePropertySet("Visible", (Variant)true);
void __fastcall TForm1::Button2Click(TObject *Sender)
{
Variant this_doc;
Variant my_fields;
Variant test;
int k,field_count;
AnsiString test1;
AnsiString filename = "d:\\ProgrammaWord\\1-Avviso.dot";
my_docs = my_word.OlePropertyGet("Documents");
this_doc = my_docs.OleFunction("Open", filename);
my_fields = this_doc.OlePropertyGet("Fields");
field_count = my_fields.OlePropertyGet("Count");
for(k = 1; k <= field_count; k++)
{
test = my_fields.OleFunction("Item",(Variant)k);
test1 = test.OleFunction("Value"); //This instruction throws an exception
// "Value" is not a recognized parameter
// in this case
Memo1->Lines->Add(test1);
}
}
I never used word Ole but I used it for Outlook and Excel, I can't try it with word since I'm currently on OSX but you should try something similar as what I did.
The generic way of using Ole was to OleGetproperty() while you get the targeted field then OleSetProperty("action", ...).
for example when I wanted to change the color of the text in a particular cell of my excel document I used:
Variant _excel = Variant::CreateObject("Excel.Application");
Variant _workbook = _excel.OlePropertyGet("WorkBooks").OleFunction("Open", filename);
Variant _worksheet = _workbook.OlePropertyGet("WorkSheets", sheet);
_worksheet.OlePropertyGet("Cells", row, col).OlePropertyGet("Font").OlePropertySet("Color", color);
Here I instanciate an excel object, then I load a file into it (_workbook), then I select the _worksheet from the _workbook and I start my business.
Here comes the interesting part:
It concist of getting to a particular cell, getting the font object from it, and then setting the color of this font object.
Disclaimer: This is an example from my sources for excel, it's not directly related to your example, but maybe you can understand the principe with it. I can't try to figure out what you need because I have no windows right now.
Hope this can help you. Finding ressources for OLE can be fierce if you don't have the good patterns to look for.

If statement for cookie - WebMatrix/Razor

I have set a cookie that I want to use to populate a form, so that users don't need to keep filling out the same form (it's submitting an inquiry to owners of holiday villas).
I've got it working fine if the cookie is already set, but it errors out if there is no cookie set.
I'm guessing I'll need to use an "if" statement, but don't quite know how to write the code.
Here is the code that sets the cookie...
Response.Cookies["BookingEnquiry"]["ReqName"] = Request["BookingReqName"];
Response.Cookies["BookingEnquiry"]["ReqEmail"] = Request["BookingReqEmail"];
Response.Cookies["BookingEnquiry"]["ReqPhone"] = Request["BookingReqPhone"];
Response.Cookies["BookingEnquiry"]["NumAdults"] = Request["BookingNumAdults"];
Response.Cookies["BookingEnquiry"]["NumChildren"] = Request["BookingNumChildren"];
Response.Cookies["BookingEnquiry"]["ReqMessage"] = Request["BookingReqMessage"];
Response.Cookies["BookingEnquiry"].Expires = DateTime.Now.AddHours(4);
}
Here are the variables that collect info from the cookie...
var reqname = Request.Cookies["BookingEnquiry"]["ReqName"];
var reqemail = Request.Cookies["BookingEnquiry"]["ReqEmail"];
var reqphone = Request.Cookies["BookingEnquiry"]["ReqPhone"];
var numadults = Request.Cookies["BookingEnquiry"]["NumAdults"];
var numchildren = Request.Cookies["BookingEnquiry"]["NumChildren"];
var reqmessage = Request.Cookies["BookingEnquiry"]["ReqMessage"];
and here is a sample input from the form...
<label>Name</label>
<input type="text" name="BookingReqName" id="BookingReqName" placeholder="full nameā€¦" value="#reqname">
In WebMatrix C#.net, I think you are looking for something like this:
if(Request["BookingReqName"] != null)
{
Response.Cookies["BookingEnquiry"]["ReqName"] = Request["BookingReqName"];
}
else
{
Response.Cookies["BookingReqName"] = ""; //<--Whatever default value you want (I've used an empty string here, so you, at least, won't get a null reference error).
}
Or you can use the same code as a one liner (to not clutter up your code, however this will decrease readability, obv.).
if(Request["BookingReqName"] != null){Response.Cookies["BookingEnquiry"]["ReqName"] = Request["BookingReqName"];}else{Response.Cookies["BookingReqName"] = ""; //<--Whatever default value you want (I've used an empty string here, so you, at least, won't get a null reference error).}
You'll just have to do that for all of your lines requesting cookie values.
The point is, though, that anything can go in the "else" block that helps you handle what to do when the cookie values have been cleared/expired (which you must always expect). You could redirect to a page that requests information from the user to reset any "forgotten" configurations, or, if you want to persist the data no matter what, consider storing these values in a database, instead, as those values won't clear/expire.
One last thing, if this doesn't help:
If you find yourself wondering what value to store in the cookie (the default value you wish to specify), because you need to know, right then and there, what it was supposed to have remembered, then I am afraid it is time to reconsider how you have structured the flow of data.
Sorry, but I have done that, once upon a time, only with Session variables, and it wasn't pretty :)
If you need any help with the best way(s) to transfer data between web pages, check this very helpful, concise link from Mike Brind's website: http://www.mikesdotnetting.com/Article/192/Transferring-Data-Between-ASP.NET-Web-Pages
It should just be the following
if(Request.Cookies["BookingEnquiry"] == null)
{
return; // <- if BookingEnquiry is null we end this routine
}
// Normal code flow here...
or something similar

Regex to check if valid URL that ends in .jpg, .png, or .gif

I would like users to submit a URL that is valid but also is an image, ending with .jpg, .png, or .gif.
(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*\.(?:jpg|gif|png))(?:\?([^#]*))?(?:#(.*))?
That's a (slightly modified) version of the official URI parsing regexp from RFC 2396. It allows for #fragments and ?querystrings to appear after the filename, which may or may not be what you want. It also matches any valid domain, including localhost, which again might not be what you want, but it could be modified.
A more traditional regexp for this might look like the below.
^https?://(?:[a-z0-9\-]+\.)+[a-z]{2,6}(?:/[^/#?]+)+\.(?:jpg|gif|png)$
|-------- domain -----------|--- path ---|-- extension ---|
EDIT See my other comment, which although isn't answering the question as completely as this one, I feel it's probably a more useful in this case. However, I'm leaving this here for karma-whoring completeness reasons.
Actually.
Why are you checking the URL? That's no guarantee what you're going to get is an image, and no guarantee that the things you're rejecting aren't images. Try performing a HEAD request on it, and see what content-type it actually is.
In general, you're better off validating URLs using built-in library or framework functions, rather than rolling your own regular expressions to do this - see What is the best regular expression to check if a string is a valid URL for details.
If you are keen on doing this, though, check out this question:
Getting parts of a URL (Regex)
Then, once you're satisfied with the URL (by whatever means you used to validate it), you could either use a simple "endswith" type string operator to check the extension, or a simple regex like
(?i)\.(jpg|png|gif)$
(http(s?):)|([/|.|\w|\s])*\.(?:jpg|gif|png)
This will mach all images from this string:
background: rgb(255, 0, 0) url(../res/img/temp/634043/original/cc3d8715eed0c.jpg) repeat fixed left top; cursor: auto;
<div id="divbg" style="background-color:#ff0000"><img id="bg" src="../res/img/temp/634043/original/cc3d8715eed0c.jpg" width="100%" height="100%" /></div>
background-image: url(../res/img/temp/634043/original/cc3d8715eed0c.png);
background: rgb(255, 0, 0) url(http://google.com/res/../img/temp/634043/original/cc3 _d8715eed0c.jpg) repeat fixed left top; cursor: auto;
background: rgb(255, 0, 0) url(https://google.com/res/../img/temp/634043/original/cc3_d8715eed0c.jpg) repeat fixed left top; cursor: auto;
Test your regex here: https://regex101.com/r/l2Zt7S/1
(http(s?):)([/|.|\w|\s|-])*\.(?:jpg|gif|png) worked really well for me.
This will match URLs in the following forms:
https://farm4.staticflickr.com/3894/15008518202_c265dfa55f_h.jpg
http://farm4.staticflickr.com/3894/15008518202_c265dfa55f_h.jpg
https://farm4.staticflickr.com/3894/15008518202-c265dfa55f-h.jpg
https://farm4.staticflickr.com/3894/15008518202.c265dfa55f.h.jpg
https://farm4.staticflickr.com/3894/15008518202_c265dfa55f_h.gif
http://farm4.staticflickr.com/3894/15008518202_c265dfa55f_h.gif
https://farm4.staticflickr.com/3894/15008518202-c265dfa55f-h.gif
https://farm4.staticflickr.com/3894/15008518202.c265dfa55f.h.gif
https://farm4.staticflickr.com/3894/15008518202_c265dfa55f_h.png
http://farm4.staticflickr.com/3894/15008518202_c265dfa55f_h.png
https://farm4.staticflickr.com/3894/15008518202-c265dfa55f-h.png
https://farm4.staticflickr.com/3894/15008518202.c265dfa55f.h.png
Check this regular expression against the URLs here: http://regexr.com/3g1v7
Here's the basic idea in Perl. Salt to taste.
#!/usr/bin/perl
use LWP::UserAgent;
my $ua = LWP::UserAgent->new;
#ARGV = qw(http://www.example.com/logo.png);
my $response = $ua->head( $ARGV[0] );
my( $class, $type ) = split m|/|, lc $response->content_type;
print "It's an image!\n" if $class eq 'image';
If you need to inspect the URL, use a solid library for it rather than trying to handle all the odd situations yourself:
use URI;
my $uri = URI->new( $ARGV[0] );
my $last = ( $uri->path_segments )[-1];
my( $extension ) = $last =~ m/\.([^.]+)$/g;
print "My extension is $extension\n";
Good luck, :)
If you really want to be sure, grabbing the first kilobyte or two of the given URL should be sufficient to determine everything you need to know about the image.
Here's an example of how you can get that information, using Python, and here's an example of it being put to use, as a Django form field which allows you to easily validate an image's existence, filesize, dimensions and format, given its URL.
I am working in Javascript based library (React). The below regex is working for me for the URL with image extension.
[^\\s]+(.*?)\\.(jpg|jpeg|png|gif|JPG|JPEG|PNG|GIF)$
Working URL`s are:
https://images.pexels.com/photos/674010/pexels-photo-674010.jpeg
https://images.pexels.com/photos/674010/pexels-photo-674010.jpg
https://www.images.pexels.com/photos/674010/pexels-photo-674010.JPEG
http://www.images.pexels.com/photos/674010/pexels-photo-674010.JPEG
www.images.pexels.com/photos/674010/pexels-photo-674010.JPEG
images.pexels.com/photos/674010/pexels-photo-674010.JPEG
Got the solution from:
https://www.geeksforgeeks.org/how-to-validate-image-file-extension-using-regular-expression/
Use FastImage - it'll grab the minimum required data from the URL to determine if it's an image, what type of image and what size.
Addition to Dan's Answer.
If there is an IP address instead of domain.
Change regex a bit. (Temporary solution for valid IPv4 and IPv6)
^https?://(?:[a-z0-9\-]+\.)+[a-z0-9]{2,6}(?:/[^/#?]+)+\.(?:jpg|gif|png)$
However this can be improved, for IPv4 and IPv6 to validate subnet range(s).
^((http(s?)\:\/\/|~/|/)?([\w]+:\w+#)?([a-zA-Z]{1}([\w\-]+\.)+([\w]{2,5}))(:[\d]{1,5})?((/?\w+/)+|/?)(\w+\.(jpg|png|gif))
This expression will match all the image urls -
^(?:http(s)?:\/\/)?[\w.-]+(?:\.[\w\.-]+)+[\w\-\._~:/?#[\]#!\$&'\(\)\*\+,;=.]+(?:png|jpg|jpeg|gif|svg)+$
Examples -
Valid -
https://itelligencegroup.com/wp-content/usermedia/de_home_teaser-box_puzzle_in_the_sun.png
http://sweetytextmessages.com/wp-content/uploads/2016/11/9-Happy-Monday-images.jpg
example.com/de_home_teaser-box_puzzle_in_the_sun.png
www.example.com/de_home_teaser-box_puzzle_in_the_sun.png
https://www.greetingseveryday.com/wp-content/uploads/2016/08/Happy-Independence-Day-Greetings-Cards-Pictures-in-Urdu-Marathi-1.jpg
http://thuglifememe.com/wp-content/uploads/2017/12/Top-Happy-tuesday-quotes-1.jpg
https://1.bp.blogspot.com/-ejYG9pr06O4/Wlhn48nx9cI/AAAAAAAAC7s/gAVN3tEV3NYiNPuE-Qpr05TpqLiG79tEQCLcBGAs/s1600/Republic-Day-2017-Wallpapers.jpg
Invalid -
https://www.example.com
http://www.example.com
www.example.com
example.com
http://blog.example.com
http://www.example.com/product
http://www.example.com/products?id=1&page=2
http://www.example.com#up
http://255.255.255.255
255.255.255.255
http://invalid.com/perl.cgi?key= | http://web-site.com/cgi-bin/perl.cgi?key1=value1&key2
http://www.siteabcd.com:8008
Reference: See DecodeConfig section on the official go lang image lib docs here
I believe you could also use DecodeConfig to get the format of an image which you could then validate against const types like jpeg, png, jpg and gif ie
import (
"encoding/base64"
"fmt"
"image"
"log"
"strings"
"net/http"
// Package image/jpeg is not used explicitly in the code below,
// but is imported for its initialization side-effect, which allows
// image.Decode to understand JPEG formatted images. Uncomment these
// two lines to also understand GIF and PNG images:
// _ "image/gif"
// _ "image/png"
_ "image/jpeg"
)
func main() {
resp, err := http.Get("http://i.imgur.com/Peq1U1u.jpg")
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
data, _, err := image.Decode(resp.Body)
if err != nil {
log.Fatal(err)
}
reader := base64.NewDecoder(base64.StdEncoding, strings.NewReader(data))
config, format, err := image.DecodeConfig(reader)
if err != nil {
log.Fatal(err)
}
fmt.Println("Width:", config.Width, "Height:", config.Height, "Format:", format)
}
format here is a string that states the file format eg jpg, png etc
Just providing a better solution. You can just validate the uri and check the format then:
public class IsImageUriValid
{
private readonly string[] _supportedImageFormats =
{
".jpg",
".gif",
".png"
};
public bool IsValid(string uri)
{
var isUriWellFormed = Uri.IsWellFormedUriString(uri, UriKind.Absolute);
return isUriWellFormed && IsSupportedFormat(uri);
}
private bool IsSupportedFormat(string uri) => _supportedImageFormats.Any(supportedImageExtension => uri.EndsWith(supportedImageExtension));
}
const url = "https://www.laoz.com/image.png";
const acceptedImage = [".png", ".jpg", ".gif"];
const extension = url.substring(url.lastIndexOf("."));
const isValidImage = acceptedImage.find((m) => m === extension) != null;
console.log("isValidImage", isValidImage);
console.log("extension", extension);