Monday, December 29, 2003

Adobe Illustrator 10 SDK - Jpeg export of the page

How to actually do a Jpeg export.

After having found out which is the correct format name you could use this piece of code:


AIErr   error   = kNoErr;
AIActionParamValueRef valueParameterBlock = NULL;
ActionDialogStatus dialogStatus  = kDialogOff;
TCHAR   pszPath[255];
error = sAIActionManager->AINewActionParamValue(&valueParameterBlock);
ASSERT(!error );

error = sAIActionManager->AIActionSetString(valueParameterBlock, kAIExportDocumentNameKey, W2A(pszPath));

const char* szJPEGFileFormat = "JPEG file format";
error = sAIActionManager->AIActionSetString(valueParameterBlock, kAIExportDocumentFormatKey, szJPEGFileFormat);
error = sAIActionManager->AIActionSetString(valueParameterBlock, kAIExportDocumentExtensionKey, "jpg");

error = sAIActionManager->PlayActionEvent( kAIExportDocumentAction, dialogStatus, valueParameterBlock );



Adobe Illustrator 10 SDK beauties

How to find out which is the name of a particular file format.

You have to acquire the sAIFileFormat suite and then do something like this:


 if( sAIFileFormat )
  long count = 0;
  AIErr er = sAIFileFormat->CountFileFormats(&count);
  if( !er )
   for(long i = 0; i < count; i++)
    AIFileFormatHandle fh = NULL;
    er = sAIFileFormat->GetNthFileFormat(i, &fh);
    if( !er )
     char szName[255];

     ZeroMemory(&szName, 255);
     er = sAIFileFormat->GetFileFormatExtension(fh, szName);
     if( !er )
     if( strcmp(szName, "jpg") == 0 )
      char* szNames = NULL;

      er = sAIFileFormat->GetFileFormatName(fh, &szNames);
      if( !er )

in this case I was interested in the jpeg file format (extension jpg).


Friday, December 19, 2003

WTL Control - message reflection

If you have a wtl control (like a CListViewCtrl or a CTreeViewCtrl) and you want to handle notify messages into that class, you should have something like this in you message map:





LRESULT OnColumnClick(int idCtrl, LPNMHDR pNmh, BOOL& bHandled);


it is important that you didn't specify REFLECT_NOTIFICATIONS, otherwise messages will be sent to the wrong window.


Wednesday, December 17, 2003

WTL list control

I always had refresh problem with the list control, now I think I had the solution:

LRESULT CEMRecycleBinListCtrl::OnPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)


// we shouldn't use begin paint to obtain the HDC,

// otherwise we will loose the update region for the parent

WTL::CDC dc = GetDC();

WTL::CRgn rgn = CreateRectRgn(0,0,0,0);

if( GetUpdateRgn(rgn) != ERROR )


CRect headerRC;

CRect listRC;

WTL::CBrush hbrBkgnd = CreateSolidBrush(dc.GetBkColor());

CHeaderCtrl header = GetHeader();



ZeroMemory(&htInfo, sizeof(LVHITTESTINFO)); = 1; = headerRC.bottom + 1;

int idx = HitTest(&htInfo);

if( idx >= 0 )


CRect rc;

int count = GetCountPerPage();

if( GetItemRect(idx+count, &rc, LVIR_BOUNDS) )

{ = headerRC.bottom;

listRC.left = rc.left + 2;

listRC.bottom = rc.bottom;

listRC.right = rc.right;

WTL::CRgn headerRgn = CreateRectRgnIndirect(headerRC);

WTL::CRgn listRgn = CreateRectRgnIndirect(listRC);

rgn.CombineRgn(listRgn, RGN_DIFF);

rgn.CombineRgn(headerRgn, RGN_DIFF);



dc.FillRgn(rgn, hbrBkgnd);



// we should let the parent to draw himself

bHandled = FALSE;

return 0;

} // OnPaint


Monday, December 15, 2003

Atl COM Controls

When you are adding window support to a windowless control you have to remember to add

m_bWindowOnly = TRUE;

In the constructor if you want your CreateControlWindow virtual function to be called.


Friday, September 26, 2003

Property Sheets

I playing with WTL's PropertySheets and with my surprise I found out that if you embed only and ActiveX control or you subclass the only one item in the property page, on win XP you will have a very awful effect, the property sheet seems to be filled with the wrong, old dialog color.

To overcome this behavior you can insert a static control and make it invisible and the problem will vanish. If you already have other control on the dialog (like buttons, edit controls, etc.) you will not suffer from the problem.

Monday, September 22, 2003


CSS at the cubic power look here.

Wednesday, September 17, 2003

AI export to PDF

Illustrator is still hurting my nerves. I give up reading the documentation and I currently reading comments inside the include files. My current task is to produce a PDF on the document. Easy.

Looking in an include file it says that with the export action you can specify the pdf file format and also you can specifiy additional parameters for that action.
The mistake here is that you must not use the export action but the saveas action.

Another very obscure point (for me at least) is that for some of the options (enum options) you have to use the specific set method (setEnumerated) but this method requires a name in addition to the value. The name is a string value so it's not obvious that you have to use the same name used in the enum in the include file. Probably it derives from the automation model, I don't know. So, for example, in the include file there is:

typedef enum _MyOption
opt1 = 1,
} MyOption

Then in the setEnumerated method you have to use it like:

setEnumerated( "MyOption", opt1 );

Not very intuitive (because you have defines and const for everything else).

And listen, if you want to generate the pdf using you own preferences (pdf version, color settings, and so on), you have to tell him to use the custom set and then specify the options you want.

Last but not least, if AI keeps telling you that the save command is not available at this time, most probably means you have specified wrong parameters....

Good luck.

Tuesday, September 16, 2003

Visual Studio .NET editor

I daily read some blogs on the net and I found this one Wine Thirty about the VS.NET editor and I want to share with you my opinion on it.

What left me most suprised in the VS.NET editor is the build output window. It worked near perfection if VS6 why do they changed it? With VS6 you can compile the project, the output window is automatically opened to show you the build in progress, if you have a couple of errors you can simply click on the ESC key, correct the first mistake, then ALT+2 brings you back the output window were you can navigate with arrows, choose which error you want to correct and with the RETURN key you will jump directly to the line with the error and clicking on the ESC key close the output window. Now all of this works only partially with VS.NET. You have to make the output window a docking window with the autohide feature, but if you click ESC, sometimes that window goes away and sometimes not. It's frustrating.

It looks like the new editor has been designed to be used mostly with the mouse. But that's a thing a developer want to avoid in favor of writing speed.

Illustrator: Command locale

I haven't found a way to obtain the commands using the SDK interfaces (I'm talking about menu commands), so I come up with the following idea, I get the hwnd of the main window, ask for the menu handle and get info from it. Pretty simple.

You have to use the ADMWinHostSuite (that's not portable to the Mac side but there is an equivalent ADMMacHostSuite):

ADMWinHostSuite4* sADMWinHost = NULL;
error = sSPBasic->AcquireSuite(kADMWinHostSuite, kADMWinHostSuiteVersion4, (const void **)&sADMWinHost);

And then you can ask for the window:

HWND hwnd = (HWND)sADMWinHost->GetPlatformAppWindow();

Now you have all the things you need, if you call it in the plugin startup you may need to call getparent on that window to obtain the correct window holding the menu, anyway calling it from the plugin startup you will not be able to obtain the command in the correct locale because Illustrator use some sort of identifier in the menu that are translated to the correct values at runtime.

Friday, September 12, 2003

Windows Security Holes


“If nothing else. this [buffer overruns/security holes] just points to the fact that things need to be written in managed code everywhere (I don't care if its .NET or Java or whatever) and we need to get away from C/C++ as sloppy error-prone and dangerous languages. Efficiency is no longer the issue in this day and age of fast processors and much memory. Code safety and productivity is.” [Sam Gentile]

Long live the managed world!

Looks like we have to move on and learn c#

Illustrator Notifiers

I'm still fighting with Illustrator. Now it's time of events (or notifiers in Illustrator terms).

Adding a notifiers is pretty easy, just a call on the appropriate interface (ops ... suite) and you are done. You have some predefined events like kAIDocumentOpenedNotifier to catch events when a document has been opened by the user or kAIDocumentClosedNotifier to be notified when the document has been closed.

When you are processing the event, you can access to the document itself and ask for some of its properties (like GetDocumentFileSpecification), unfortunately in the close event seems like that GetDocumentModified is the only functions that can be called without errors. That's pretty bad.

Digging trough SDK examples I found that you can have other types of notifiers, basically every command have it's own notifiers before and after the command has been called, for example for the Close command you can have "AI Command Notifier: Before Close" and "AI Command Notifier: After Close", but to my great surprise the Close command must be written according to the UI locale, so I've installed Illustrator in Italian and the correct event is "AI Command Notifier: Before Chiudi". I hate it. Obviously is seems like there is no way to obtain the command string according to the locale, I'll end up obtaining the correct command string with plain win32 API, I think it'll be easier.

This event is fired before the document has been really closed, so you can do you own save, ask questions to user about the closing, etc. that's fine until I discovered that when you have documents opened and you quit the application, that event will not be fired but only the onClose for each document. That makes my plugin's life more difficult because it looks like I can't understand which document is about to be closed. At this time I give up reading the pdf documentation that seems not updated and I looked directly at *.h files in the SDK include directory and I found that there is an interface that let you browse the list of open documents. That's really helped me.

Back to coding for now, I let you know who will win the war.

Thursday, September 11, 2003

Illustrator Plugin.

I'm writing an adobe illustrator plugin, it is really a simple one that adds a custom menu in the File menu and allow you to open, close and save files to a custom repository.

Adding the menu and iteracting with it is straightforward, the SDK allow you to do whatever you want trough kind of interfaces.

Opening a file is another matter. Why they doesn't have an interface for such kind of actions? They only way to open a file is to use the action manager interface (AIActionManagerSuite) and use the PlayActionEvent using the "adobe_openDocument". Obviously it isn't described anywhere.

More later on others aspects.