Anyone met the same thing? Our plugin for Adobe AI has a custom cursor. It's a PNG file together with an XML description, and the PNG and XML are declared in a .r REZ file. sUser->SetCursor(resID, iResourceManager); is used to set the cursor. And it can work on AI CS6, but after installing the 16.0.3 update package, there was no custom cursor, but only the default black arrow instead. I know this update makes some changes to the cursor since it supports high definition screen resolution, but the AI cursors can resize with no details missing. What can I do to add our cursor resources?
I just dealt with this problem yesterday. The AIResourceManagerHandle
appeared to be valid, but the call to sAIUser->SetCursor()
returned a CANT
error no matter what I tried. The cursor PNGI
ID was correct, XML_
hot spot ID was correct, etc. I even tried making a variety of higher resolution PNGs for a cursor and that didn't help either. There's even a newer version of the SDK, but I ran a diff on it and the only changes were some unrelated comments.
I just worked around it by using platform code for Mac, and stuck with Illustrator code for Windows. We already had a cursor class, which made it much easier (you may want to make one if you don't have one already). It ended up looking something like this:
class Cursor
{
public:
Cursor(const int cursorID_);
virtual ~Cursor();
virtual void enable();
private:
int __cursorID;
#if defined(MAC_ENV)
NSCursor* __cursorMac;
#endif
};
bool getResourceData(
const long type_,
const int id_,
char*& data__,
int& size__
) const
{
static const int oneMeg = 1048576;
data__ = NULL;
size__ = 0;
AIDataFilter* aidf = NULL;
AIErr error = sAIDataFilter->NewResourceDataFilter(
yourPluginRef,
type_,
id_,
"",
&aidf
);
if(error != kNoErr || !aidf)
return false;
// This is the max size to read when going in to ReadDataFilter(),
// and the actual size read when coming out.
size_t tmpSize = oneMeg;
data__ = new char[ oneMeg ];
error = sAIDataFilter->ReadDataFilter(aidf, data__, &tmpSize);
AIErr ulError = kNoErr;
while(aidf && ulError == kNoErr)
{
ulError = sAIDataFilter->UnlinkDataFilter(aidf, &aidf);
}
if(error != kNoErr)
{
delete[] data__;
return false;
}
size__ = tmpSize;
return true;
}
Cursor::Cursor(const int cursorID_)
{
this->__cursorID = cursorID_;
#if defined(MAC_ENV)
this->__cursorMac = nil;
char* pngData = NULL;
int pngDataSize = 0;
if(!getResourceData('PNGI', this->__cursorID, pngData, pngDataSize))
return;
NSPoint hs = NSMakePoint(0.0, 0.0);
char* xmlData = NULL;
int xmlDataSize = 0;
if(getResourceData('XML_', this->__cursorID, xmlData, xmlDataSize))
{
std::string xmlStr(xmlData, xmlDataSize);
// Parse xmlStr however you prefer. If you have an XML parser, rock on.
// Otherwise, the XML is so simple that an sscanf() call should work.
delete[] xmlData;
xmlData = NULL;
}
NSData* pngNSD = [[NSData alloc] initWithBytes:pngData length:pngDataSize];
delete[] pngData;
pngData = NULL;
NSImage* pngNSI = [[NSImage alloc] initWithData:pngNSD];
[pngNSD release];
pngNSD = nil;
this->__cursorMac = [[NSCursor alloc] initWithImage:pngNSI hotSpot:hs];
[pngNSI release];
pngNSI = nil;
#endif
}
Cursor::~Cursor()
{
#if defined(MAC_ENV)
if(this->__cursorMac)
{
[this->__cursorMac release];
this->__cursorMac = nil;
}
#endif
}
void Cursor::enable()
{
#if defined(MAC_ENV)
if(this->__cursorMac)
{
[this->__cursorMac set];
}
#elif defined(WIN_ENV)
sAIUser->SetCursor(this->__cursorID, yourCursorRsrcMgr);
#endif
}
Depending on how your project is configured, you may need to set your source files to be compiled as Objective-C++ and/or #import <AppKit/AppKit.h>
somewhere.