<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Karl Heinz Kremer&#039;s Ramblings &#187; Programming</title>
	<atom:link href="http://www.khk.net/wordpress/category/programming/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.khk.net/wordpress</link>
	<description>Stuff, stuff and more stuff</description>
	<lastBuildDate>Sun, 25 Sep 2011 18:38:40 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=</generator>
		<item>
		<title>Reading PDF Form Fields with VBA</title>
		<link>http://www.khk.net/wordpress/2010/09/23/reading-pdf-form-fields-with-vba/</link>
		<comments>http://www.khk.net/wordpress/2010/09/23/reading-pdf-form-fields-with-vba/#comments</comments>
		<pubDate>Thu, 23 Sep 2010 14:04:12 +0000</pubDate>
		<dc:creator>khk</dc:creator>
				<category><![CDATA[Acrobat]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[PDF]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Adobe Acrobat]]></category>
		<category><![CDATA[Form]]></category>
		<category><![CDATA[JSO]]></category>
		<category><![CDATA[vba]]></category>

		<guid isPermaLink="false">http://www.khk.net/wordpress/?p=651</guid>
		<description><![CDATA[I&#8217;ve written about VBA and Acrobat JavaScript before, and I&#8217;ve also mentioned that you can combine VBA and JavaScript to access PDF form fields, but I still owe a sample for that. I had to answer another question today about how to exactly do that, so I whipped up a quick sample program that demonstrates [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: left; margin-right: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.khk.net%2Fwordpress%2F2010%2F09%2F23%2Freading-pdf-form-fields-with-vba%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.khk.net%2Fwordpress%2F2010%2F09%2F23%2Freading-pdf-form-fields-with-vba%2F&amp;source=khkremer&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>I&#8217;ve written about VBA and Acrobat JavaScript <a href="http://www.khk.net/wordpress/2009/03/11/acrobat-javascript-and-vb-walk-into-a-bar/">before</a>, and I&#8217;ve also mentioned that you can combine VBA and JavaScript to access PDF form fields, but I still owe a sample for that. I had to answer another question today about how to exactly do that, so I whipped up a quick sample program that demonstrates the use of the JavaScript Object (JSO) to read and write AcroForm fields.</p>
<p>We start the same way as in my <a href="http://www.khk.net/wordpress/2009/03/04/adobe-acrobat-and-vba-an-introduction/">old VBA sample</a> to create a VBA program that references the Acrobat TLB and to add a button to a document. When we now use the following script as the button handler, we can work with form fields:</p>
<p><pre><pre>Private Sub CommandButton1_Click()
&nbsp;&nbsp;&nbsp;&nbsp;Dim AcroApp As Acrobat.CAcroApp
&nbsp;&nbsp;&nbsp;&nbsp;Dim theForm As Acrobat.CAcroPDDoc
&nbsp;&nbsp;&nbsp;&nbsp;Dim jso As Object
&nbsp;&nbsp;&nbsp;&nbsp;Dim text1, text2 As String
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;Set AcroApp = CreateObject(&quot;AcroExch.App&quot;)
&nbsp;&nbsp;&nbsp;&nbsp;Set theForm = CreateObject(&quot;AcroExch.PDDoc&quot;)
&nbsp;&nbsp;&nbsp;&nbsp;theForm.Open (&quot;C:\temp\sampleForm.pdf&quot;)
&nbsp;&nbsp;&nbsp;&nbsp;Set jso = theForm.GetJSObject
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&#039; get the information from the form fields Text1 and Text2
&nbsp;&nbsp;&nbsp;&nbsp;text1 = jso.getField(&quot;Text1&quot;).Value
&nbsp;&nbsp;&nbsp;&nbsp;text2 = jso.getField(&quot;Text2&quot;).Value
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;MsgBox &quot;Values read from PDF: &quot; &amp; text1 &amp; &quot; &quot; &amp; text2

&nbsp;&nbsp;&nbsp;&nbsp;&#039; set a text field
&nbsp;&nbsp;&nbsp;&nbsp;Dim field2 As Object
&nbsp;&nbsp;&nbsp;&nbsp;Set field2 = jso.getField(&quot;Text2&quot;)
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;field2.Value = 13&nbsp;&nbsp; &#039; assign the number 13 to the fields value
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&#039; get the information from the form fields Text1 and Text2
&nbsp;&nbsp;&nbsp;&nbsp;text1 = jso.getField(&quot;Text1&quot;).Value
&nbsp;&nbsp;&nbsp;&nbsp;text2 = jso.getField(&quot;Text2&quot;).Value
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;MsgBox &quot;Values read from PDF: &quot; &amp; text1 &amp; &quot; &quot; &amp; text2

&nbsp;&nbsp;&nbsp;&nbsp;theForm.Close
&nbsp;&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp;&nbsp;AcroApp.Exit
&nbsp;&nbsp;&nbsp;&nbsp;Set AcroApp = Nothing
&nbsp;&nbsp;&nbsp;&nbsp;Set theForm = Nothing
&nbsp;&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp;&nbsp;MsgBox &quot;Done&quot;
End Sub
</pre></pre></p>
<p>This program requires a PDF file with text fields called &#8220;Text1&#8243; and &#8220;Text2&#8243; to be stored as C:\temp\sampleForm.pdf. With the explanation in the previous two blog posts, it should not be hard to understand what&#8217;s going on here. The only new command introduced is the getField() function, which returns a form field. The form field object has a property &#8220;value&#8221; which contains the actual value that&#8217;s assigned to the field. Give it a try and let me know how it works for you. The updated form field is not saved (because the document does not get saved) &#8211; I&#8217;ll leave that up to the reader to figure out.</p>
<p>Also, this program will not work with XFA forms (the ones you create in Designer). For those, you need to use the XFA DOM to access the form data. For anybody interested in XFA forms, the <a href="http://help.adobe.com/en_US/livecycle/es/lcdesigner_scripting_reference.pdf">LifeCycle Designer ES Scripting Reference</a> is a must read. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.khk.net/wordpress/2010/09/23/reading-pdf-form-fields-with-vba/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Best Way to Learn Acrobat Scripting</title>
		<link>http://www.khk.net/wordpress/2010/08/18/best-way-to-learn-acrobat-scripting/</link>
		<comments>http://www.khk.net/wordpress/2010/08/18/best-way-to-learn-acrobat-scripting/#comments</comments>
		<pubDate>Wed, 18 Aug 2010 15:25:04 +0000</pubDate>
		<dc:creator>khk</dc:creator>
				<category><![CDATA[Acrobat]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[PDF]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[adobe pdf]]></category>
		<category><![CDATA[pdfscripting.com]]></category>
		<category><![CDATA[scripting]]></category>

		<guid isPermaLink="false">http://www.khk.net/wordpress/?p=638</guid>
		<description><![CDATA[Every now and then I come across the question &#8220;What is the best way to learn scripting for Adobe Acrobat? Are there any books or other resources averrable?&#8221;. After doing some research, I think I finally found the best resource for beginners and for seasoned Acrobat JavaScript programmers that need a quick tip or a [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: left; margin-right: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.khk.net%2Fwordpress%2F2010%2F08%2F18%2Fbest-way-to-learn-acrobat-scripting%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.khk.net%2Fwordpress%2F2010%2F08%2F18%2Fbest-way-to-learn-acrobat-scripting%2F&amp;source=khkremer&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>Every now and then I come across the question &#8220;What is the best way to learn scripting for Adobe Acrobat? Are there any books or other resources averrable?&#8221;. After doing some research, I think I finally found the best resource for beginners and for seasoned Acrobat JavaScript programmers that need a quick tip or a recipe to copy&amp;paste into a project:</p>
<p><a href="http://www.pdfscripting.com/">PDFScripting.com</a></p>
<p>The site offers content for both paying members and the general public. If you are new to scripting, and you don&#8217;t want to spend the money for a membership (yet), take a look at the free content at ﻿<a href="http://www.pdfscripting.com/public/department40.cfm">http://www.pdfscripting.com/public/department40.cfm</a> &#8211; it walks you through creating your first AcroForm script, but also offers a number of videos that explain more complicated concepts. For the really good stuff however, you have to pay.</p>
<p>Ever wondered how to hook up a PDF form with an Excel spread sheet? Wonder no more! The article series &#8220;<a href="http://www.pdfscripting.com/members/department48.cfm">Acrobat, PDF and Excel Spreadsheets</a>&#8221; teaches you more than you ever wanted to know about that subject.</p>
<p>You may remember my post about <a href="http://www.khk.net/wordpress/2009/05/31/more-interactive-dynamic-stamps-in-seven-easy-steps/">dynamic stamps in Acrobat</a>. The PDFScripting.com site has a lot more information about dynamic forms and provides a number of <a href="http://www.pdfscripting.com/public/images/Video/PDFStampsGoneWild.cfm">very interesting samples</a> (video link).</p>
<p>There is a ton more information available for both AcroForm and LiveCycle Designer scripting. This information comes in form of articles, videos, a copy&amp;paste script library and downloadable sample files that illustrate a subject.</p>
<p>To get familiar with the web site, Thom Parker has recorded a video tour that helps to navigate the site, but also gives a pretty good overview about what&#8217;s available both for free and for paying members at &#8220;﻿<a href="http://www.pdfscripting.com/public/images/video/PDFSTour.cfm">Take a tour of the PDFScripting.com website!</a>&#8221; (video link).</p>
<p>So, no need to ask me for a good Acrobat scripting resource anymore, just go to PDFScripting.com and sign up for a year &#8211; it&#8217;s well worth the membership fee (and as Thom says in his tour video, no surprise at the end of the year, the membership does not automatically renew).</p>
]]></content:encoded>
			<wfw:commentRss>http://www.khk.net/wordpress/2010/08/18/best-way-to-learn-acrobat-scripting/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Is Your Acrobat Plug-in Still Using ADM?</title>
		<link>http://www.khk.net/wordpress/2010/04/23/is-your-acrobat-plug-in-still-using-adm/</link>
		<comments>http://www.khk.net/wordpress/2010/04/23/is-your-acrobat-plug-in-still-using-adm/#comments</comments>
		<pubDate>Fri, 23 Apr 2010 16:33:08 +0000</pubDate>
		<dc:creator>khk</dc:creator>
				<category><![CDATA[Acrobat]]></category>
		<category><![CDATA[mac]]></category>
		<category><![CDATA[PDF]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[adm]]></category>
		<category><![CDATA[adobe pdf]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[plug-in]]></category>
		<category><![CDATA[wxwidgets]]></category>

		<guid isPermaLink="false">http://www.khk.net/wordpress/?p=617</guid>
		<description><![CDATA[For a few years now Adobe has been telling 3rd party developers that the ADM (Adobe Dialog Manager) will be discontinued, and that existing plug-ins may have to be ported to something else. If I remember correctly, this started with Acrobat 7 or 8, but back then it was a soft threat &#8211; everything still [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: left; margin-right: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.khk.net%2Fwordpress%2F2010%2F04%2F23%2Fis-your-acrobat-plug-in-still-using-adm%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.khk.net%2Fwordpress%2F2010%2F04%2F23%2Fis-your-acrobat-plug-in-still-using-adm%2F&amp;source=khkremer&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>For a few years now Adobe has been telling 3rd party developers that the ADM (Adobe Dialog Manager) will be discontinued, and that existing plug-ins may have to be ported to something else. If I remember correctly, this started with Acrobat 7 or 8, but back then it was a soft threat &#8211; everything still worked, and there wasn&#8217;t much incentive to start porting plug-ins. However, with the release of the <a href="http://www.adobe.com/devnet/acrobat">Acrobat 9 SDK</a> the ADM related header files were gone, but ADM based plug-ins were still working (at least some of them). </p>
<p>The removal of the header files does send a strong signal, but what was an even stronger signal for me was that one of the ADM based plug-in I was working on was no longer working correctly on some versions of Windows. </p>
<p>As far as Adobe is concerned, ADM is no longer supported &#8211; that means there won&#8217;t be any bug fixes for it, but the plug-in has to work with Acrobat 9 on any Windows system that&#8217;s supported by Acrobat 9. So, what is a developer to do in such a situation?</p>
<p>Adobe does not give us much guidance in what to chose as a replacement for ADM. The most obvious choice is to stick with the native UI framework that comes with the operating system, but the advantage of ADM was that one could write UI code that would run in both Windows and Mac plug-ins. One of the sample plug-ins &#8211; wxPlugin &#8211; that comes with the Acrobat SDK is based on <a href="http://wxwidgets.org/">wxWidgets</a>. To me that was a pretty strong hint that wxWidgets would be a good choice&#8230;</p>
<p>However, even though the Mac version of the SDK does come with the wxPlugin code and even contains a XCode project file, it does not compile. After some work, trying to come up with a combination of wxWidget configuration options and wxPlugin project settings, I was able to create an Acrobat plug-in that worked. </p>
<p>In order to &#8220;fix&#8221; the Mac&#8217;s version of the wxPlugin I first had to compile wxWidgets. Use the following configure command line to create the static wxWidget libraries that can be linked with the project:</p>
<p><pre><code>configure CC=gcc-4.0 CXX=g++-4.0 LD=g++-4.0 --enable-universal_binary \
--disable-shared --with-macosx-sdk=/Developer/SDKs/MacOSX10.4u.sdk \
--with-mmacosx-version-min=10.4 --enable-debug</code></pre></p>
<p>Just install the libraries and include files according to the <a href="http://livedocs.adobe.com/acrobat_sdk/9.1/Acrobat9_1_HTMLHelp/API_References/Acr obat_API_Reference/Samples/CodeSamples/sample-descriptions.html">instructions provided by Adobe</a>. </p>
<p>A closer inspection of the plug-in code then revealed that the part that actually did anything was commented out for the Mac with <code>#ifndef MAC_PLATFORM</code> statements, so I removed those and the last thing to do was to remove the reference to the <code>libexpat</code> library &#8211; it is provided by the operating system and does not have to be provided by wxWidgets.</p>
<p>With a working environment on the Mac, wxWidgets is a viable alternative for ADM for either new Acrobat plug-ins, or existing plug-ins that need to be modified to make them compatible with the current version of Acrobat. </p>
<p>If your Acrobat plug-ins are still using ADM, now would be a good time to think about what to do about that&#8230; If you need any help, <a href="mailto:khk+b1GvaE@khk.net">let me know</a>. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.khk.net/wordpress/2010/04/23/is-your-acrobat-plug-in-still-using-adm/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Developing Acrobat JavaScript on a MacBook</title>
		<link>http://www.khk.net/wordpress/2010/03/23/javascript-console/</link>
		<comments>http://www.khk.net/wordpress/2010/03/23/javascript-console/#comments</comments>
		<pubDate>Tue, 23 Mar 2010 17:58:20 +0000</pubDate>
		<dc:creator>khk</dc:creator>
				<category><![CDATA[Acrobat]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[mac]]></category>
		<category><![CDATA[PDF]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[adobe pdf]]></category>
		<category><![CDATA[development]]></category>

		<guid isPermaLink="false">http://www.khk.net/wordpress/?p=624</guid>
		<description><![CDATA[Acrobat&#8217;s JavaScript is a great tool to extend the application, or to automate reoccurring tasks. There are several ways a JavaScript can be added to the application or a document (e.g. folder level scripts, validation scripts, event handling scripts, &#8230;), but regardless of how a script is written, chances are that the developer wants to [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: left; margin-right: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.khk.net%2Fwordpress%2F2010%2F03%2F23%2Fjavascript-console%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.khk.net%2Fwordpress%2F2010%2F03%2F23%2Fjavascript-console%2F&amp;source=khkremer&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>Acrobat&#8217;s JavaScript is a great tool to extend the application, or to automate reoccurring tasks. There are several ways a JavaScript can be added to the application or a document (e.g. folder level scripts, validation scripts, event handling scripts, &#8230;), but regardless of how a script is written, chances are that the developer wants to test parts of the script in Acrobat&#8217;s Javascript console. This console window can be shown by either using the &#8220;Advanced>Document Processing>JavaScript Debugger&#8230;&#8221; menu item or Ctrl-J on Windows or Cmd-J on a Mac:</p>
<div style="text-align:center;"><img src="http://www.khk.net/wordpress/wp-content/uploads/2010/03/BlogPicsJS_Menu.png" alt="JS_Menu.png" border="0" width="400" /></div>
<p>After the console or debugger window comes up, the user can then enter Javascript and execute it&#8230; </p>
<div style="text-align:center;"><img src="http://www.khk.net/wordpress/wp-content/uploads/2010/03/BlogPicsJS_Debugger.png" alt="JS_Debugger.png" border="0" width="500" /></div>
<p>&#8230; that is, as long as a full keyboard with a numeric keypad is used. In Adobe&#8217;s documentation, we find the following <a href="http://livedocs.adobe.com/acrobat_sdk/9.1/Acrobat9_1_HTMLHelp/JS_Dev_Tools.72.4.html">instructions to execute Javascript typed into the console window</a>:</p>
<p>
The JavaScript console allows you to evaluate single or multiple lines of code. There are three ways to evaluate JavaScript code while using the interactive console:</p>
<ul>
<li>To evaluate a portion of a line of code, highlight the portion and press either the Enter key on the numeric keypad or press Ctrl + Enter.</li>
<li>To evaluate a single line of code, make sure the cursor is positioned on that line and press either the Enter key on the numeric keypad or press Ctrl + Enter.</li>
<li>To evaluate multiple lines of code, highlight those lines and press either the Enter key on the numeric keypad or press Ctrl + Enter.</li>
</ul>
<p>That works fine as long as you have access to the numeric keypad, but on a MacBook or a MacBook Pro without that keypad. No key combination involving fn, ctrl, cmd or option with the Return or Enter key will result in the Javascript getting executed. </p>
<p>The virtual keyboard to the rescue: Mac OS comes with a handy keyboard viewer that allows us to send the correct key code to the application. To bring up the keyboard viewer, bring up the Mac OS System Preferences first and select the &#8220;Keyboard&#8221; category:</p>
<div style="text-align:center;"><img src="http://www.khk.net/wordpress/wp-content/uploads/2010/03/BlogPicsKeyboardViewer_1.png" alt="KeyboardViewer_1.png" border="0" width="500" /></div>
<p>Make sure that the option &#8220;Show Keyboard &#038; Character Viewer in menu bar&#8221; is selected. Once this is done, you can access the keyboard viewer from the menu bar:</p>
<div style="text-align:center;"><img src="http://www.khk.net/wordpress/wp-content/uploads/2010/03/BlogPicsKeyboardViewer_2.png" alt="KeyboardViewer_2.png" border="0" width="244" height="118" /></div>
<p>Now comes the tricky part: Write some Javascript in the console window and place the cursor on the line you want to execute or select the snippet of the Javascript that should be executed. In the following example I&#8217;m using code from <a href="http://livedocs.adobe.com/acrobat_sdk/9.1/Acrobat9_1_HTMLHelp/JS_API_AcroJS.88.151.html">Adobe&#8217;s Javascript API documentation</a>:</p>
<p><pre><pre>
&nbsp;&nbsp;var menuItems = app.listMenuItems()
&nbsp;&nbsp;for( var i in menuItems)
&nbsp;&nbsp;&nbsp;&nbsp;console.println(menuItems[i] + &quot;\n&quot;)
</pre></pre></p>
<p>With the console prepped, bring up the keyboard viewer and start pushing keys &#8211; real keys that is: Hold down the &#8220;fn&#8221; and the &#8220;control&#8221; key, then move the mouse pointer to the &#8220;Enter&#8221; key on the keyboard viewer and click it&#8230;</p>
<div style="text-align:center;"><img src="http://www.khk.net/wordpress/wp-content/uploads/2010/03/BlogPicsJS_Debugger_6.png" alt="JS_Debugger_6.png" border="0" width="500" /></div>
<p>&#8230; and voila, the script gets executed:</p>
<div style="text-align:center;"><img src="http://www.khk.net/wordpress/wp-content/uploads/2010/03/BlogPicsJS_Debugger_7.png" alt="JS_Debugger_7.png" border="0" width="500"/></div>
<p>This is not the most straight forward method, but at least it&#8217;s possible to use the Javascript console to execute code when using a MacBook. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.khk.net/wordpress/2010/03/23/javascript-console/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Acrobat Plug-Ins</title>
		<link>http://www.khk.net/wordpress/2009/04/14/acrobat-plug-ins/</link>
		<comments>http://www.khk.net/wordpress/2009/04/14/acrobat-plug-ins/#comments</comments>
		<pubDate>Wed, 15 Apr 2009 00:40:12 +0000</pubDate>
		<dc:creator>khk</dc:creator>
				<category><![CDATA[Acrobat]]></category>
		<category><![CDATA[PDF]]></category>
		<category><![CDATA[Photos]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[acrobat plug-in]]></category>
		<category><![CDATA[adobe]]></category>
		<category><![CDATA[plug-in]]></category>

		<guid isPermaLink="false">http://khk.net/wordpress/?p=326</guid>
		<description><![CDATA[If you&#8217;ve seen my resume &#8211; or talked to me lately, you know that I create Acrobat plug-ins for a living. When people hear that, they usually think something like &#8220;Don&#8217;t forget to pick up the dry cleaning&#8221; or &#8220;I need to bring my cat to the vet for the rabies shot&#8221;&#8230; Yes, I understand, [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: left; margin-right: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.khk.net%2Fwordpress%2F2009%2F04%2F14%2Facrobat-plug-ins%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.khk.net%2Fwordpress%2F2009%2F04%2F14%2Facrobat-plug-ins%2F&amp;source=khkremer&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>If you&#8217;ve seen my <a href="http://khk.net/wordpress/resume/">resume</a> &#8211; or talked to me lately, you know that I create Acrobat plug-ins for a living. When people hear that, they usually think something like &#8220;Don&#8217;t forget to pick up the dry cleaning&#8221; or &#8220;I need to bring my cat to the vet for the rabies shot&#8221;&#8230; Yes, I understand, this may not be the most exciting topic, but probably only because you don&#8217;t know enough about what these &#8220;plug-ins&#8221; are, so let me explain.</p>
<p><a title="View 'Conservatory-038' on Flickr.com" href="http://www.flickr.com/photos/68335338@N00/3440056708"></p>
<div style="text-align:center;"><img class="flickr" src="http://farm4.static.flickr.com/3584/3440056708_32cec4e199.jpg" alt="Conservatory-038" /></div>
<p></a></p>
<p><a title="View 'Conservatory-038' on Flickr.com" href="http://www.flickr.com/photos/68335338@N00/3440056708"></a></p>
<p>Â </p>
<p>Adobe Acrobat is a very powerful tool, more powerful that most users actually realize. I wont go into any details about how powerful exactly &#8211; at least not today. Lets just say that it has something for everybody. However, you may need something in addition to what Adobe provides, something that still is in the general area of PDF. Adobe may not have considered your needs because either the target market for &#8220;your&#8221; feature is too small, or to far out there&#8230; Or you are so far ahead of everybody else that they have not even thought about that feature yet.</p>
<p>Adobe did however do a very interesting thing: They created an interface that allows 3rd party developers to create solutions based on Adobe Acrobat &#8211; using plug-ins. It is a very powerful interface, and hence not something that you can pick up in an afternoon. There are several thousand pages of API documentation that one needs to understand before a plug-in should be written.</p>
<p>A plug-in is &#8211; from a technical point of view &#8211; a module or library that gets loaded dynamically at runtime. Acrobat will scan it&#8217;s plug-ins directory and will load any modules it finds. Once loaded, such a plug-in can extend Acrobat by e.g. adding menu items, toolbuttons, or event handlers (e.g. a function that gets executed whenever a documents gets loaded).</p>
<p><a title="View 'Conservatory-013' on Flickr.com" href="http://www.flickr.com/photos/68335338@N00/3439227641"></p>
<div style="text-align:center;"><img class="flickr" src="http://farm4.static.flickr.com/3577/3439227641_2f7148f1cf.jpg" alt="Conservatory-013" /></div>
<p></a></p>
<p><a title="View 'Conservatory-013' on Flickr.com" href="http://www.flickr.com/photos/68335338@N00/3439227641"></a></p>
<p>Â </p>
<p>Interestingly enough, the plug-ins directory of a fresh Adobe Acrobat installation is not empty&#8230; A lot of Acrobat&#8217;s functionality is actually implemented as plug-ins. You can verify that on a Windows system by temporarily disabling all plug-ins by holding down the Shift key when bringing up Acrobat. That will load the application without any plug-ins. When you compare the toolbar or the menu bar with a fully loaded application, you&#8217;ll see what portion of the Acrobat core functionality is actually implemented in plug-ins.</p>
<p>The plug-in interface has different abstraction levels (COS, PDE, AV, &#8230;). If there is enough interest, I will provide information about how to navigate that API, and how to structure a plug-in.</p>
<p>The Acrobat SDK is available for free from Adobe&#8217;s <a href="http://www.adobe.com/devnet/acrobat/">Acrobat Development Center</a>.</p>
<p>Here are a few examples of commercially available plug-ins that I&#8217;ve used:</p>
<ul>
<li><em>Enfocus PitStop Professional:</em><br />
This is a preflight tool.</li>
<li><em>Quite Imposing Plus:</em><br />
The best PDF based imposition tool that I am aware of.</li>
<li><em>Enfocus Browser:</em><br />
Allows to review and change the internal structure of a PDF file.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.khk.net/wordpress/2009/04/14/acrobat-plug-ins/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Splitting PDF Pages</title>
		<link>http://www.khk.net/wordpress/2009/03/30/splitting-pdf-pages/</link>
		<comments>http://www.khk.net/wordpress/2009/03/30/splitting-pdf-pages/#comments</comments>
		<pubDate>Tue, 31 Mar 2009 02:23:49 +0000</pubDate>
		<dc:creator>khk</dc:creator>
				<category><![CDATA[Acrobat]]></category>
		<category><![CDATA[PDF]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Scanned pages]]></category>

		<guid isPermaLink="false">http://khk.net/wordpress/?p=306</guid>
		<description><![CDATA[No, this is not about my patent pending idea of a sheet splitter that turns duplex documents into simplex documents&#8230; This post is about a problem that comes up every now and then: When you scan a book or a magazine, chances are that you end up with two physical pages on your scanned image, [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: left; margin-right: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.khk.net%2Fwordpress%2F2009%2F03%2F30%2Fsplitting-pdf-pages%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.khk.net%2Fwordpress%2F2009%2F03%2F30%2Fsplitting-pdf-pages%2F&amp;source=khkremer&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>No, this is not about my patent pending idea of a sheet splitter that turns  duplex documents into simplex documents&#8230; This post is about a problem that comes up every now and then: When you scan a book or a magazine, chances are that you end up with two physical pages on your scanned image, and your document looks something like this:</p>
<div style="text-align: center;"><img src="http://khk.net/wordpress/wp-content/uploads/2009/03/joinedpages.png" border="0" alt="JoinedPages.png" width="200" /></div>
<p>Pages one and two are on the same scan, three and four are, and five and six and so on.</p>
<p>How can we split such a combined page into it&#8217;s two parts?</p>
<p>There are of course different solutions to this problem, some more complicated than others, some producing better results than others.</p>
<p>The most straight forward approach would be to write an Acrobat plug-in or a standalone application (e.g. using the iText library) that takes the source page, determines what needs to be copied to the new page that should represent the left half of the original page, and then just copy those page elements. With a scanned source document, this would potentially mean that the scanned image needs to be cropped and placed on the target page. Sounds complicated, and it is complicated. Is there an easier way to accomplish the same results?</p>
<p>[More after the jump]</p>
<p><span id="more-306"></span>If we have access the Acrobat, we can use JavaScript to mimic the behavior of the just described application. With Acrobat&#8217;s JavaScript, we do of course not have access to the page content elements, so we need to find a different way to end up with the same results.</p>
<p>JavaScript gives us access to the crop box of a PDF page (if you don&#8217;t know what that is, read up on page boxes in the <a href="http://www.adobe.com/devnet/pdf/pdf_reference.html">PDF Reference</a>), this means we can find out how big a page is, but also set the crop box to configure which part of the page should be displayed in the viewer, or should get printed.</p>
<p>So, if our combined page is 11&#215;17&#8243;, and we want to extract two 8 1/2&#215;11&#8243; pages, we first need to &#8220;select&#8221; the left half of the page, and then the right half of the same page.</p>
<p>Here is the script that will do just that:<br />
<a title="SplitPages.js" href="http://khk.net/wordpress/wp-content/uploads/2009/03/splitpages.js">SplitPages.js</a></p>
<p>Copy that file to the Acrobat JavaScript directory &#8211; for Acrobat 9 on a Windows machine that would be<br />
<pre>c:\Program Files\Adobe\Acrobat 9.0\Acrobat\JavaScript</pre><br />
Now let&#8217;s take a look at the different parts of the script:<br />
<pre><code>ProcessDocument = app.trustedFunction(function()
{
// create a new document
app.beginPriv();
var newDoc = app.newDoc();
app.endPriv();</code></pre><br />
This snippet shows that we are declaring a trusted function. This is necessary because we need to execute the app.newDoc() method, which requires (since Acrobat 7) a privileged context. The first thing we do in this script is to create that new document &#8211; the call is wrapped with the beginPriv() and endPriv() calls. When creating a new document in JavaScript, the document is no only created, Acrobat will also add a page to that document. We don&#8217;t need that page, but every PDF document that is getting displayed in Acrobat, needs at least one PDF page. We will deal with that extra page later.</p>
<p><pre><pre>
var i = 0;
while (i &lt; this.numPages)
{
&nbsp;&nbsp;newDoc.insertPages( {
&nbsp;&nbsp;nPage: newDoc.numPages-1,
&nbsp;&nbsp;cPath: this.path,
&nbsp;&nbsp;nStart: i
});
newDoc.insertPages( {
&nbsp;&nbsp;nPage: newDoc.numPages-1,
&nbsp;&nbsp;cPath: this.path,
&nbsp;&nbsp;nStart: i
});
// we did this twice so that we can then split each copy of the page into a left
// and right half.
i++;
}
</pre></pre></p>
<p>In these few lines we copy every page from the source document (this.path, which is the path to the active document) to our newly created document &#8211; and we are doing that twice. This is necessary because we need to crop out the left half of the page for the first page, and the right half of the page for the second page. After this loop, we will have twice as many pages in our new document than we have in our source document.</p>
<p><pre><pre>
if (newDoc.numPages &gt; 1)
{
&nbsp;&nbsp;newDoc.deletePages(0);&nbsp;&nbsp;// this gets rid of the page that was created with the newDoc call.
}
</pre></pre></p>
<p>Now that we have all the pages in our new document, we no longer need the blank page we got when we created the document. So, we delete it.</p>
<p><pre><code>// at this point we have a documnent with every page from the source document
// copied twice</code></pre></p>
<p><code> </code></p>
<p><pre><pre> for (i=0; i&lt;newDoc.numPages; i++)
{
&nbsp;&nbsp;// determine the crop box of the page
&nbsp;&nbsp;var cropRect = newDoc.getPageBox(&quot;Crop&quot;, i);
&nbsp;&nbsp;var halfWidth = (cropRect[2]-cropRect[0])/2;
</pre></pre><br />
We loop over all pages in our new document (that is twice the number of pages in the original document). And for every page we get the crop box. We also calculate a value that we will need later: The half of the width of that page. That is the location where the page will get split.</p>
<p><pre><code>var cropLeft = new Array();
cropLeft[0] = cropRect[0];
cropLeft[1] = cropRect[1];
cropLeft[2] = cropRect[0] + halfWidth;
cropLeft[3] = cropRect[3];</code></pre></p>
<p>The previous few lines create a new Array. A page box is represented as an array of four values. We can now assign the partially modified values to the new page box. As you can see, three of the four values just are copies of the original crop box. Array element 2 however gets modified. It is the original X value for the lower left point of the crop box, and we add half of our page width to that number. This means, the new right edge of the modified page box is now at the halfway point between the two sides.</p>
<p><pre><code>var cropRight = new Array();
cropRight[0] = cropRect[2] - halfWidth;
cropRight[1] = cropRect[1];
cropRight[2] = cropRect[2];
cropRight[3] = cropRect[3];</code></pre><br />
We do something similar for the new crop box for the right side of the page.</p>
<p><pre><code>if (i%2 == 0)
{
&nbsp;&nbsp;newDoc.setPageBoxes( {
&nbsp;&nbsp;cBox: &quot;Crop&quot;,
&nbsp;&nbsp;nStart: i,
&nbsp;&nbsp;rBox: cropLeft
});
}
else
{
&nbsp;&nbsp;newDoc.setPageBoxes( {
&nbsp;&nbsp;cBox: &quot;Crop&quot;,
&nbsp;&nbsp;nStart: i,
&nbsp;&nbsp;rBox: cropRight
});
}
}
}
)</code></pre></p>
<p>This is a bit tricky&#8230; Acrobat starts to count pages with page 0. The first page in the document is on the left half of our first sheet. All of a sudden, our first page is actually an even page number (0), and not like in &#8220;normal&#8221; books an odd number (1). This means that for all even numbers we need to crop the left half, and for all odd numbers we need to crop the right half.</p>
<p>We test for &#8220;evenness&#8221; by performing the modulo operation on our page number. If the result is 0, we know we have an even number, so we can use the left side crop box. If the operation returns 1, we are dealing with an odd page number, and we will use the ride side crop box.</p>
<p>The new crop box gets applied with the doc.setPageBoxes() method.</p>
<p><pre><code>// add the menu item
app.addMenuItem({
&nbsp;&nbsp;cName: &quot;splitPagesJS&quot;,&nbsp;&nbsp;&nbsp;&nbsp; // this is the internal name used for this menu item
&nbsp;&nbsp;cUser: &quot;Split Pages&quot;,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // this is the label that is used to display the menu item
&nbsp;&nbsp;cParent: &quot;Document&quot;,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// this is the parent menu. The file menu would use &quot;File&quot;
&nbsp;&nbsp;cExec: &quot;ProcessDocument()&quot;,&nbsp;&nbsp;// this is the JavaScript code to execute when this menu item is selected
&nbsp;&nbsp;cEnable: &quot;event.rc = (event.target != null);&quot;,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // when should this menu item be active?
&nbsp;&nbsp;nPos: 0
});</code></pre></p>
<p><code> </code></p>
<p>Almost done&#8230; We&#8217;ve implemented the functionality to split the pages, now we just need a mechanism to actually start our little program. I&#8217;ve chosen to create a menu item under the &#8220;Document&#8221; menu. That menu item is only available (not grayed out), if we have an active document.</p>
<p>Disclaimer: Of course, there is no such thing as a sheet splitter, and therefore there is no patent application. It&#8217;s a joke.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.khk.net/wordpress/2009/03/30/splitting-pdf-pages/feed/</wfw:commentRss>
		<slash:comments>23</slash:comments>
		</item>
		<item>
		<title>Digging Deep into History &#8211; My First Tweet</title>
		<link>http://www.khk.net/wordpress/2009/03/28/digging-deep-into-history-my-first-tweet/</link>
		<comments>http://www.khk.net/wordpress/2009/03/28/digging-deep-into-history-my-first-tweet/#comments</comments>
		<pubDate>Sat, 28 Mar 2009 12:33:30 +0000</pubDate>
		<dc:creator>khk</dc:creator>
				<category><![CDATA[Misc]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Social Media]]></category>
		<category><![CDATA[Twitter]]></category>

		<guid isPermaLink="false">http://khk.net/wordpress/?p=293</guid>
		<description><![CDATA[I&#8217;ve been using Twitter more over the last few weeks &#8211; this is pretty obvious when you take a look at the graph from TwitterCounter.com: Once I started to tweet more, my follower count went up. While playing around with different Twitter tools, I came across MyTweet16.com, which allows you to display the first 16 [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: left; margin-right: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.khk.net%2Fwordpress%2F2009%2F03%2F28%2Fdigging-deep-into-history-my-first-tweet%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.khk.net%2Fwordpress%2F2009%2F03%2F28%2Fdigging-deep-into-history-my-first-tweet%2F&amp;source=khkremer&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>I&#8217;ve been using Twitter more over the last few weeks &#8211; this is pretty obvious when you take a <a href="http://twittercounter.com/khkremer/all">look at the graph from TwitterCounter.com</a>:</p>
<div style="text-align:center;"><a href="http://twittercounter.com/khkremer/all"><img src="http://khk.net/wordpress/wp-content/uploads/2009/03/twittercounter.png" border="0" alt="TwitterCounter.png" width="400"  /></a></div>
<p>Once I started to tweet more, my follower count went up.</p>
<p>While playing around with different Twitter tools, I came across <a href="http://www.mytweet16.com/user/khkremer">MyTweet16.com</a>, which allows you to display the first 16 tweets of any Twitter user. I of course was curious about what I had to say when I first signed up for my account.</p>
<p>What I found was pretty interesting: For my very first tweet, I did not use any of the &#8220;normal&#8221; ways to use Twitter: It was not the web interface or any of the established Twitter clients &#8211; instead, I used a program that I wrote myself. I completely forgot about that. Who else can say that they tweeted first with something they created (besides Biz Stone and Jack Dorsey, the founders of Twitter)?</p>
<p>I used the book <a href="http://www.amazon.com/gp/product/1590599365?ie=UTF8&amp;tag=spechtshomepa-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=1590599365">Creating Mashups with Adobe Flex and AIR (Friends of Ed Abobe Learning Library)</a><img style="border:none !important; margin:0px !important;" src="http://www.assoc-amazon.com/e/ir?t=spechtshomepa-20&amp;l=as2&amp;o=1&amp;a=1590599365" border="0" alt="" width="1" height="1" /> to get some exposure to Flex, and the first few examples in the book are about using the Twitter API. </p>
<p>So, without any further ado, here is my first tweet (copy&amp;pasted from <a href="http://www.mytweet16.com/user/khkremer">MyTweet16.com</a>:<br />
<pre>Playing with Flex for the first time (that&#039;s how I twittered this). 12:33 PM Jun 3rd 2008</pre><br />
I actually singed up for Twitter just to use these examples.</p>
<p>Please <a href="http://www.twitter.com/khkremer">follow me on Twitter</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.khk.net/wordpress/2009/03/28/digging-deep-into-history-my-first-tweet/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Acrobat, JavaScript and VB walk into a bar&#8230;</title>
		<link>http://www.khk.net/wordpress/2009/03/11/acrobat-javascript-and-vb-walk-into-a-bar/</link>
		<comments>http://www.khk.net/wordpress/2009/03/11/acrobat-javascript-and-vb-walk-into-a-bar/#comments</comments>
		<pubDate>Thu, 12 Mar 2009 00:37:36 +0000</pubDate>
		<dc:creator>khk</dc:creator>
				<category><![CDATA[Acrobat]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[PDF]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Acrobat SDK]]></category>
		<category><![CDATA[Adobe Acrobat]]></category>
		<category><![CDATA[VB]]></category>

		<guid isPermaLink="false">http://khk.net/wordpress/?p=256</guid>
		<description><![CDATA[OK, let&#8217;s just forget about that old joke and concentrate on how to combine all three into something that is quite useful. As I&#8217;ve described in one of my previous posting, it is quite easy to automate Acrobat from VB or VBA. So how does JavaScript fit into this picture? As you may know, Acrobat [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: left; margin-right: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.khk.net%2Fwordpress%2F2009%2F03%2F11%2Facrobat-javascript-and-vb-walk-into-a-bar%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.khk.net%2Fwordpress%2F2009%2F03%2F11%2Facrobat-javascript-and-vb-walk-into-a-bar%2F&amp;source=khkremer&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>OK, let&#8217;s just forget about that old joke and concentrate on how to combine all three into something that is quite useful.</p>
<p>As I&#8217;ve described in one of my <a href="http://khk.net/wordpress/2009/03/04/adobe-acrobat-and-vba-an-introduction/">previous posting</a>, it is quite easy to automate Acrobat from VB or VBA. So how does JavaScript fit into this picture? As you may know, Acrobat comes with a very powerful JavaScript engine that provides access to a lot of functionality &#8211; more functions actually than what you have access to from your VB program. So, if you want to access some of these features, but you are stuck with VB, how can you do that?</p>
<p>Adobe provides a VB/JavaScript bridge with Acrobat &#8211; the JSObject, and the <a href="http://livedocs.adobe.com/acrobat_sdk/9/Acrobat9_HTMLHelp/IAC_DevApp_OLE_Support.100.13.html">Acrobat SDK describes how to use that feature</a>.</p>
<p>There is quite a bit of good information in the documentation. When you access the online documentation, expand the tree to &#8220;Acrobat Interapplication Communication > Developing Applications Using Interapplication Communication > Using OLE > Using the JSObject interface&#8221;.</p>
<p><H3>JavaScript</H3></p>
<p>In this example, I want to illustrate how you can create a folder level JavaScript function, instantiate the JSObject, and then call the custom function and display the result in VB. My plan was to use the <a href="http://khk.net/wordpress/2009/03/11/counting-bookmarks/">JavaScript code from my last posting</a>, but I found one small problem in the way I wrote the code (it works fine as a standalone JavaScript program, but we cannot use it in the VB context), so here is it&#8217;s replacement:</p>
<p><pre><pre>
function CountBookmarks(bkm, nLevel)
{
&nbsp;&nbsp;&nbsp;&nbsp;var count = 0;
&nbsp;&nbsp;&nbsp;&nbsp;if (bkm.children != null)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;count = bkm.children.length;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (var i = 0; i &lt; bkm.children.length; i++)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; count += CountBookmarks(bkm.children[i], nLevel + 1);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;return count;
}

function CountAllBookmarks()
{
&nbsp;&nbsp;&nbsp;&nbsp;console.clear(); console.show();
&nbsp;&nbsp;&nbsp;&nbsp;var n = CountBookmarks(this.bookmarkRoot, 0);
&nbsp;&nbsp;&nbsp;&nbsp;console.println(&quot;Number of bookmarks found: &quot; + n);

&nbsp;&nbsp;&nbsp;&nbsp;return n;
}

// add the menu item
app.addMenuItem({
&nbsp;&nbsp;&nbsp;&nbsp; cName: &quot;countBookmarks&quot;,
&nbsp;&nbsp;&nbsp;&nbsp; cUser: &quot;Count Bookmarks&quot;,
&nbsp;&nbsp;&nbsp;&nbsp; cParent: &quot;Document&quot;,
&nbsp;&nbsp;&nbsp;&nbsp; cExec: &quot;CountAllBookmarks();&quot;,
&nbsp;&nbsp;&nbsp;&nbsp; cEnable: &quot;event.rc = (event.target != null);&quot;
});

</pre></pre> </p>
<p>Save this JavaScript program as a folder level JavaScript file and make sure that it works.</p>
<p>So, why can&#8217;t we just implement the whole algorithm with the JSObject? The problem is with how VB handles objects that are actually JavaScript objects &#8211; in this case the root bookmark object. I cannot figure out how to access it&#8217;s &#8220;children&#8221; property through the JSObject. That&#8217;s the reason why I&#8217;m &#8220;cheating&#8221; by calling our custom JavaScript function &#8211; being able to do that is pretty cool IMHO.</p>
<p><H3>The VB Part</H3></p>
<p>We start out just like with any other VB program, by declaring some objects, initializing them and then it gets interesting&#8230;</p>
<p>Here is some sample code that shows how to initialize the JSObject, and how to call our own JavaScript function.  </p>
<p>Create a button on an Excel spreadsheet again, and put the following code into the button handler callback (just like before). </p>
<p><pre><pre>
Dim gApp As Acrobat.CAcroApp
Dim gPDDoc As Acrobat.CAcroPDDoc
Dim jso As Object

Sub Button1_Click()
&nbsp;&nbsp;&nbsp;&nbsp;Set gApp = CreateObject(&quot;AcroExch.App&quot;)
&nbsp;&nbsp;&nbsp;&nbsp;Set gPDDoc = CreateObject(&quot;AcroExch.PDDoc&quot;)
&nbsp;&nbsp;&nbsp;&nbsp;If gPDDoc.Open(&quot;c:\temp\test.pdf&quot;) Then
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set jso = gPDDoc.GetJSObject
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MsgBox (jso.CountAllBookmarks())
&nbsp;&nbsp;&nbsp;&nbsp;End If
End Sub
</pre></pre></p>
<p>Now just make sure that you have a file c:\temp\test.pdf that has some bookmarks in it. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.khk.net/wordpress/2009/03/11/acrobat-javascript-and-vb-walk-into-a-bar/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Counting Bookmarks</title>
		<link>http://www.khk.net/wordpress/2009/03/11/counting-bookmarks/</link>
		<comments>http://www.khk.net/wordpress/2009/03/11/counting-bookmarks/#comments</comments>
		<pubDate>Thu, 12 Mar 2009 00:17:42 +0000</pubDate>
		<dc:creator>khk</dc:creator>
				<category><![CDATA[Acrobat]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[PDF]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Adobe Acrobat]]></category>

		<guid isPermaLink="false">http://khk.net/wordpress/?p=251</guid>
		<description><![CDATA[Let&#8217;s assume you have a PDF document, and you want to know how many bookmarks you have in that document, how would you approach that? The JavaScript API has methods to traverse the bookmark tree. Here is a short program that &#8211; once installed in Acrobat&#8217;s JavaScript folder &#8211; will add a menu item &#8220;Count [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: left; margin-right: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.khk.net%2Fwordpress%2F2009%2F03%2F11%2Fcounting-bookmarks%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.khk.net%2Fwordpress%2F2009%2F03%2F11%2Fcounting-bookmarks%2F&amp;source=khkremer&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>Let&#8217;s assume you have a PDF document, and you want to know how many bookmarks you have in that document, how would you approach that? </p>
<p>The JavaScript API has methods to traverse the bookmark tree. Here is a short program that &#8211; once installed in Acrobat&#8217;s JavaScript folder &#8211; will add a menu item &#8220;Count Bookmarks&#8221; to the &#8220;Document&#8221; menu, and when executed will print the number of bookmarks encountered in the JavaScript console.</p>
<p><pre><pre>
function CountBookmarks(bkm, nLevel)
{
&nbsp;&nbsp;&nbsp;&nbsp;var count = 0;
&nbsp;&nbsp;&nbsp;&nbsp;if (bkm.children != null)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;count = bkm.children.length;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (var i = 0; i &lt; bkm.children.length; i++)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; count += CountBookmarks(bkm.children[i], nLevel + 1);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;return count;
}

function DoIt()
{
&nbsp;&nbsp;&nbsp;&nbsp;console.clear(); console.show();
&nbsp;&nbsp;&nbsp;&nbsp;var n = CountBookmarks(this.bookmarkRoot, 0);
&nbsp;&nbsp;&nbsp;&nbsp;console.println(&quot;Number of bookmarks found: &quot; + n);
}

// add the menu item
app.addMenuItem({
&nbsp;&nbsp;&nbsp;&nbsp; cName: &quot;countBookmarks&quot;,
&nbsp;&nbsp;&nbsp;&nbsp; cUser: &quot;Count Bookmarks&quot;,
&nbsp;&nbsp;&nbsp;&nbsp; cParent: &quot;Document&quot;,
&nbsp;&nbsp;&nbsp;&nbsp; cExec: &quot;DoIt();&quot;,
&nbsp;&nbsp;&nbsp;&nbsp; cEnable: &quot;event.rc = (event.target != null);&quot;
});

</pre></pre></p>
<p>Save this program in a file in e.g. C:\Program Files\Adobe\Acrobat 9.0\Acrobat\Javascripts (for Acrobat 9) and restart Acrobat. You should now find a new menu item in the Document menu. Load a file with bookmarks in it, and execute the menu item. </p>
<p>I have not implemented the privileged execution context that is required to make this work in all instances, so you  have to go into your JavaScript preferences in Acrobat and check the setting for &#8220;Enable menu items JavaScript execution privileges&#8221;:</p>
<div style="text-align:center;"><img src="http://khk.net/wordpress/wp-content/uploads/2009/03/preferencesjavascript.png" alt="PreferencesJavaScript.png" border="0" width="300" /></div>
]]></content:encoded>
			<wfw:commentRss>http://www.khk.net/wordpress/2009/03/11/counting-bookmarks/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

