Tuesday, July 06, 2004
Food
Friday, July 02, 2004
Indesign SDK - plugin ID
Thursday, July 01, 2004
Indesign SDK - Front Document
When you want to obtain a pointer to the current front document (the one the user is editing) you could use
InterfacePtrbut when you are inside an action component it may not work, instead you should usedoc(Utils ()->GetFrontDocument(), UseDefaultIID());
InterfacePtrwhere ac is the IActiveContext* passed in the DoAction.doc(ac->GetContextDocument(), UseDefaultIID());
Thursday, June 24, 2004
Source code mismatch during debugging
When you are debugging an application, if the source executed by the debugger is different than the actual source code (i.e. the code executed is not the code showed in the source code) and you are sure the pdb is absolutely right for that dll/exe, it means one of these 2 things:
1. your source code is not up to date;
2. you may have non-dos line ending mixed in the file.
I did have this problem in the past days with code I've written pretty much from scratch, it turned up to be case number 2. Probably I copy-pasted a small portion from a mac code. A full conversion to DOS endings of the source file solved the problem. I was plagued by it since two weeks ago, but only in two files, that I didn't change very much in the last days, so I let the problem remain, but today I decided I had to solve the problem because there weren't any reasonable explanation of this weird problem. Fortunately I had the idea of checking the line endings of the file and that solved my problems.
Thursday, June 17, 2004
Indesign SDK - Query story metadata
How to query for story's metadata?
Simple, assuming storyRef is the UIDRef of the story:
UtilsinCopyWorkFlowUtils;
InterfacePtrmodel(storyRef, IID_ITEXTMODEL);
ASSERT(model);
InterfacePtriMetaData(inCopyWorkFlowUtils->QueryTextMetaDataBoss(model, kTrue));
if (iMetaData) {
InterfacePtrmdAcc(iMetaData, UseDefaultIID());
if (mdAcc) {
InterfacePtrmdPaths(mdAcc->Enumerate(0));
if (mdPaths) {
// iterate thru all paths
while (mdPaths->HasMorePaths()) {
PMString nspace, path;
// get the next path (by namespace and path)
mdPaths->GetNextPath(nspace, path);
PMString value;
MetaDataFeatures metaDataFeatures;
// inspect the node
if (mdAcc->Get(nspace, path, value, metaDataFeatures))
{
}
}
}
}
}
Monday, June 14, 2004
Wednesday, June 09, 2004
Indesign menus
It took me a while to figure it out how to add a submenu in the main File menu and position it whereever I want. The solution came from a Ken Sadahiro answer to a forum post, which point out to a Q & A session (login ASN web account required) on user interface.
I tried to do something similar, but the culprit is the 0 as the actionID for the sub-menu and the use of the delimiter ":" when adding the submenu.
Tuesday, June 08, 2004
NEP
I used to work for Tera until March 2003, recently I discovered a guy, Derek Lakin, who worked for NEP.
Nep (or I should say Nep's "this is" project) is a fantastic project that delivers all the regional news trough one big site, I was in charge of the part of the project that allow to transfer editorial content (pics and stories) from the editorial system to Nep's CMS.
Tuesday, June 01, 2004
Indesign SDK - custom draw palette
Indesign doesn't use windows to put together many panels into a palette or to draw the tab of a palette. It uses GDI (or the equivalent on the Mac) to draw everything on screen. IControlView is the interface for a "control", you can navigate the controls tree trough IWidgetParent interface (and GetParent method) and IPanelControlData or IPaletteControlData.
Suppose you have a panel that is subclassed by you, you can ask for the IPaletteControlData, this way:
IPaletteControlData* ppcd = nil;
InterfacePtr<IWidgetParent> parent(
this, UseDefaultIID());if( parent ) {ppcd =
static_cast<IPaletteControlData*>(parent->QueryParentFor(IID_IPALETTECONTROLDATA));}
InterfacePtr<IPaletteControlData> pcd(ppcd);
ASSERT(pcd);
Now you can use GetSectionCount and GetSection to retrieve the interface for the wanted control, the first one is the tab, the other is the entire panel. Suppose you want to enumerate the tabs in the palette, you need the PanelControlData for the tabs so:
InterfacePtr<IControlView> tabAreaView(pcd->GetSection(0), UseDefaultIID());
ASSERT(tabAreaView);
InterfacePtr<IPanelControlData> tabAreaCD(tabAreaView, UseDefaultIID());
ASSERT(tabAreaCD);
for(int32 idx = 0; idx < tabAreaCD->Length(); idx++) {
InterfacePtr<IControlView> tabWidget(tabAreaCD->GetWidget(idx), UseDefaultIID());
}
And there you can draw whatever you want on the tab.
Wednesday, May 26, 2004
Indesign strikes back
This is related to incopy but I think indesign will behave the same because the plugins are cross-application ('till a certain point. i.e. you use specific custom functions).
The problem is another interface leak. The culprit is IWidgetUtils->QueryRelatedWidget, the documentation doesn't say anything particular about it but it looks to me that this method is returning an interface with the reference counter incremented.
I tried to look at the adobe samples but it is never used so I cannot say if I'm doing it wrong or the documentation (both help files and include files) is wrong. Anyway using the static_cast trick explained before solved my problem.
Pay attention to those leaks as soon as you got it, or you will have hard days finding the guilty.
InDesign newbiee problems
I was having an interface leak with InDesign, such leak caused all sort of others leaks that they had the potential to drive me to look at others places, fortunately I've got quite a lot experience with COM interface leaks.
After all the suspecting function was this one:
IPMUnknown* getPanelView(){
InterfacePtr parent(this, UseDefaultIID());
if( parent ) {
InterfacePtr parentPanel(parent->GetParent(), UseDefaultIID());
if( parentPanel )
return parentPanel->QueryParentFor(IID_ICONTROLVIEW);
}
return nil;
} // getPanelView In particular I was using such function with an InterfacePtr like this:
InterfacePtr<IControlView> panel(getPanelView(), UseDefaultIID());
However if you look at the include file for IWidgetParent, you will find that QueryParentFor will return a reference incremented ptr to interface this means I will leak a reference to that interface. InterfacePtr have a constructor that doesn't call AddRef on the interface and it's the one that didn't do the QueryInterface. So the correct InterfacePtr is:
InterfacePtr<IControlView> panel(getPanelView());
But getPanelView must return an IControlView* or we should cast it here, I prefer the first solution, so I'll have:
IControlView* getPanelView(){
InterfacePtr parent(this, UseDefaultIID());
if( parent ) {
InterfacePtr parentPanel(parent->GetParent(), UseDefaultIID());
if( parentPanel )
return static_cast<IControlView*>(parentPanel->QueryParentFor(IID_ICONTROLVIEW));
}
return nil;
} // getPanelView Moral of the story: read carefully documentation *and* include files before using any complex sdk.
Friday, May 21, 2004
incredible video
A friend of mine sent me a link to this really funny video I can't understand what they say but it is really really funny.
http://www.hugi.is/hahradi/bigboxes.php?box_id=51208&f_id=1000Indesign UI
If you are developing a dynamic palette in which you want to host a custom panel, you must be sure that the WidgetID that you will set for the panel must not clash with any of the IDs defined elsewhere.
If they clash you will have some really strange behaviour, for example I aggregated a simple interface to the panel (interface that will give me access to panel's options) but when I assign a conflicting widgetID everyone seems to work except the aggregated interface was not created at all.
I'm not that smart....it took me a couple of days to figure it out.
Monday, May 03, 2004
PNG in Windows IE
http://homepage.ntlworld.com/bobosola/index.htm
How to solve the PNG transparency problem with Ie 5.5 and 6.
Thursday, April 22, 2004
INTERNAL COMPILER ERROR vc7.1
I was porting some code from vc6 to vc7.1 and I got stuck in:
c:\build\main\.......\inc.h(27) : fatal error C1001: INTERNAL COMPILER ERROR
(compiler file 'msc1.cpp', line 2701)
Please choose the Technical Support command on the Visual C++
Help menu, or open the Technical Support help file for more information
Looking trough newsgroups microsoft.public.dotnet.languages.vc gave me a good hint:
"I spoke with Microsoft incident support for my MSDN licence and the fix is:
#if _MFC_VER < 0x0700
class CString;
#endif
CString is not a class in MFC anymore. It is a template in ATL so forward
declarations are invalid."
So I searched for CString forward declarations and I solved - quickly - my problem.
Tuesday, April 20, 2004
PInvoke.net
from www.pinvoke.net:
PINVOKE.NET attempts to address the difficulty of calling Win32 or other unmanaged APIs in managed code (languages such as C# and VB .NET). Manually defining and using PInvoke signatures (also known as Declare statements in VB .NET) is an error-prone process that can introduce extremely subtle bugs. The rules are complex, and if you make a mistake, you’ll probably corrupt memory.
Tuesday, April 13, 2004
randomness
Very interesting thoughts on random numbers. link: http://weblogs.asp.net/oldnewthing/archive/2004/04/12/111596.aspx
Monday, March 22, 2004
Thursday, March 04, 2004
Tuesday, March 02, 2004
How to enable sound on a Virtual PC running Linux
1. Log into Red Hat Linux.
2. Start a terminal session, click the ‘Red Hat’, System Tools, then Terminal.
3. Type su and press Enter.
4. Enter the root password and press Enter.
5. Type cd /sbin and press Enter
6. Type ./sndconfig and press Enter.
7. Introduction: Press Enter.
8. Probe Results: Press Enter.
9. Card Type: Select Sound Blaster 16 and press Enter.
10. Card Settings:
a. I/O Port: Select 0x220 and press Tab.
b. IRQ: Select 5 and press Tab.
c. DMA 1: Select 1 and press Tab.
d. DMA 2: Select 5 and press Tab.
e. MPU I/O: Select 0x330 and press Tab.
f. Press Enter
11. Sound Card Test: Press Enter
NOTE Sound volume may be very low, adjust speakers accordingly.
12. Test Result: Press Enter if sound was heard, if not, Tab to select No and press Enter.
NOTE If no sound was heard, the most likely cause is lack of volume
13. File Exists: press Enter to overwrite the existing config file.
14. Type exit and press Enter to exit the root console.
15. Type exit and press Enter to exit the standard console.