tag:blogger.com,1999:blog-85024026197001957002024-03-08T12:10:39.273+01:00Nenad About Programming...Stories about professional programming.Nenad Dobrilovichttp://www.blogger.com/profile/17675085565409829708noreply@blogger.comBlogger20125tag:blogger.com,1999:blog-8502402619700195700.post-24156876304977159732012-07-20T14:38:00.002+02:002012-07-20T14:57:29.071+02:00Under or over-engineering?Whenever you see classes called controler, provider, decider, manager, presenter, etc. which reassembles to some managerial job, you know that it isn't truly object oriented. It is actually procedural way of thinking, just packed in classes.<br />
<br />
I just saw a class called ColorDecider, which has one public method, two private ones and no state at all. The only job of this class is to decide which color should be chosen based on the state of some other object. It is actually a replacement for a switch or dictionary in that object. It does the same job, but it looks smarter. Not for me.<br />
<br />
But it has an interface, because it is nice thing to have. There are no other classes which implement this interface, because there can be only one way of presenting data in the system in one time, and it is defined by requirements. This behavior will be changed only if requirements change one day. So, why it needs a whole class?Nenad Dobrilovichttp://www.blogger.com/profile/17675085565409829708noreply@blogger.com0tag:blogger.com,1999:blog-8502402619700195700.post-88259702208696912732012-07-17T16:00:00.004+02:002023-05-11T16:14:31.585+02:00A Cross-Thread Exception in DevExpress XPOA cross-thread exception will happen every time you want to access a Session from different threads at the same time.<br />
<br />
With the latest changes, DexExpress' Session introduced a Thread Watch object. His sole purpose is to check <span style="font-family: inherit;">which thread tries to access a Session when it is about to charge it state from empty or to either </span><span style="font-family: inherit;">GetObjectsNonReenterant or CommitTransactionNonReenterant </span><span style="font-family: inherit;">state</span>. If it is the different than the previous one, it will throw an InvalidOperationException exception.<br />
<br />
Once the thread leaves the Session, Thread Watch will clear its state, so new thread can access it again.<br />
<br />
Basically, it means that you have to use a single thread throughout the lifecycle of the Session object. You could, however, use more than one thread, as along as you use them sequentially, one after another. But, I believe that it would, if it isn't already natural for your application, bring more troubles than benefits.<br />
<br />
There is an option left to turn off this explicitly checks, by setting DevExpress.Xpo.Helpers.SessionStateStack.SuppressCrossThreadFailuresDetection to True, but it not advisable since it will just hide the real source of the problem.Nenad Dobrilovichttp://www.blogger.com/profile/17675085565409829708noreply@blogger.com0tag:blogger.com,1999:blog-8502402619700195700.post-27019396131304860352012-01-31T17:11:00.000+01:002012-01-31T17:24:12.692+01:00Teamplifier<a href="http://teamplifier.com/" target="_blank">Teamplifier</a> is small, off-side, project done in a free time by two members team in Belgrade. But, if I didn't tell you, you would never guess it was the case as it looks like a product of much bigger and expensive team. Although it is in beta phase and some of planned features are still missing, you can already feel the main idea behind it: small and lightweight web based project management tool aimed for small teams, freelancers and entrepreneurs.<br />
<br />
<br />
It is extremely easy, in only few steps, to kick-start a project. Each project consists of more tasks in different stages. By advancing tasks you keep a track of a project progress, until it ends naturally. Beside projects itself, you have to define users and groups, each with its own settings. And that's all. No complicated rules, workflows and meaningless features. That is exactly what is expected from the ultimate project management tool for small organizations, to be there to help in turbulent and dynamic environments, but not distract processes by imposing its own rules and regulations.<br />
<br />
And the best feature of all: it is completely free.Nenad Dobrilovichttp://www.blogger.com/profile/17675085565409829708noreply@blogger.com0tag:blogger.com,1999:blog-8502402619700195700.post-1945050772075185882010-05-31T15:42:00.001+02:002011-10-24T14:30:01.328+02:00PST Data Structure View Tool<a href="http://pstviewtool.codeplex.com/">PST Data Structure View Tool</a>: "PST Data Structure View Tool (PSTViewTool) is a tool supporting the PST file format documentation effort. It allows the user to browse the internal structures of a PST file."<br />
<br />
More about structure of a PST file: <a href="http://msdn.microsoft.com/en-us/library/ff385210(office.12).aspx">Outlook Personal Folders File Format (.pst) Structure Specification</a>Nenad Dobrilovichttp://www.blogger.com/profile/17675085565409829708noreply@blogger.com1tag:blogger.com,1999:blog-8502402619700195700.post-51657161573111210742010-01-22T16:44:00.000+01:002011-10-24T14:29:48.260+02:00Use embedded IE in FHP to show Office documentsYou can use embedded Internet Explorer control, hosted by FHP, to show Office documents. But, by default, IE will open them as read-only, even if they are local files. If you are using SharePoint server, you can notice that it opens Office documents as read/write in that case.<br />
So, in order to resolve this behavior so that IE opens documents that are in the Internet or Local intranet security zones with read/write permissions, you must add the following registry key: <br />
<br />
• For Office XP<br />
<span style="font-family: "Courier New", Courier, monospace;">HKEY_CURRENT_USER\Software\Microsoft\Office\10.0\Common\Internet\</span><span style="font-family: "Courier New", Courier, monospace;">OpenDocumentsReadWriteWhileBrowsing = 1</span><br />
<br />
• For Office 2003<br />
<span style="font-family: "Courier New", Courier, monospace;">HKEY_CURRENT_USER\Software\Microsoft\Office\11.0\Common\Internet\OpenDocumentsReadWriteWhileBrowsing = 1</span><br />
<br />
• For the 2007 Office system<br />
<span style="font-family: "Courier New", Courier, monospace;">HKEY_CURRENT_USER\Software\Microsoft\Office\12.0\Common\Internet\OpenDocumentsReadWriteWhileBrowsing = 1</span>Nenad Dobrilovichttp://www.blogger.com/profile/17675085565409829708noreply@blogger.com0tag:blogger.com,1999:blog-8502402619700195700.post-45836386822581619932009-12-11T15:47:00.000+01:002011-10-24T14:28:42.093+02:00PIA for Office 2007 and VSTO 3.0 Improvements- Richer support for Outlook Object Model; twice larger, with 85 classes included.<br />
- Performance improvements. Introduced new Table object for faster accessing items and properties and PropertyAccessor for faster property access.<br />
- Richer security model and in some cases simpler appliance. Application object within add-in is trusted as safe by default.<br />
- New forms regions which can be added in Explorer and Inspector to show more properties of displayed item.<br />
- New ribbons can be added.<br />
- Some of context menus are allowed to change.<br />
- Access to Outlook Rules.Nenad Dobrilovichttp://www.blogger.com/profile/17675085565409829708noreply@blogger.com0tag:blogger.com,1999:blog-8502402619700195700.post-59518461309851824412009-12-03T13:36:00.000+01:002011-10-24T14:27:54.396+02:00Security and FHPUser control which is embedded in Folder Home Page must be registered as COM object and marked as Safe for Scripting. This is done automatically by Visual Studio during debugging but must be set manually in installer if you want installed application to work properly.<br />
<br />
Outlook 2007 has strengthened security model from 2003 version - it will not allow custom FHP for non-default PST file. If you have additional PST file, beside default one you have to allow it by setting this key in the registry to 1:<br />
<br />
<code>HKCU\Software\Microsoft\Office\12.0\Outlook\Security\NonDefaultStoreScript</code>Nenad Dobrilovichttp://www.blogger.com/profile/17675085565409829708noreply@blogger.com0tag:blogger.com,1999:blog-8502402619700195700.post-8488657690795776422009-11-18T13:05:00.002+01:002011-10-24T14:26:46.554+02:00Hosted control in FHPUsually Outlook loads all add-ins in their application domains, to isolate them from Outlook and from each other. In that way, unstable add-in will be prevented to influence on Outlook or the other add-ins. If some add-in hung, Outlook will not load it next time it starts.<br />
<br />
But, control hosted in custom FHP work in the same application domain as Outlook, which can be risky because any instability in add-in can endanger the whole Outlook. FHP is an acronym for Folder Home Page - an HTML page that may be displayed when user clicks on the folder icon to represent its content. That page may include any other user control, which is a usual way for a developers to embed a new control in Outlook.Nenad Dobrilovichttp://www.blogger.com/profile/17675085565409829708noreply@blogger.com0tag:blogger.com,1999:blog-8502402619700195700.post-63995669683305612952009-04-22T17:29:00.003+02:002011-10-24T14:25:50.066+02:00New Explorers and InspectorsThere is no way to change look and feel of the Explorer window which displays current folder in the Outlook. But, Inspector which displays the content of the opened item for some item type can be changed. More accurate, the default one can be prevented to show, and any other Windows form can be displayed instead of.<br />
There is a supported way to make some new form for displaying item or to change existing one. But this can’t be done programmatically. Furthermore, user can always change form again by changing Outlook properties.<br />
You can make brand new Message class which is bounded to Outlook item, but there is no way to introduce brand new Outlook item. It is possible only to add a new one which is inherited from existing one, for example: IPM.Note.MyNote from IPM.Note.<br />
New item can be displayed by a custom form as well.Nenad Dobrilovichttp://www.blogger.com/profile/17675085565409829708noreply@blogger.com0tag:blogger.com,1999:blog-8502402619700195700.post-81750752574053460132009-04-03T13:44:00.002+02:002011-10-24T14:24:52.732+02:00ItemRemove Event in Outlook 2003There is a problem with ItemRemove event on Items collection of a folder in Outlook 2003: it does not return item removed, so the only option to find out which item has been removed is to count items before and after delete.<br />
The individual item objects have a BeforeDelete event, but it's usable only if you're willing to use a wrapper class to instantiate an instance for every open or selected item.<br />
Problem is not in Outlook Object Model, it is on the MAPI level, TABLE_CHANGED <br />
event is fired rather than TABLE_ROW_DELETED. <br />
This was fixed in Outlook 2007.Nenad Dobrilovichttp://www.blogger.com/profile/17675085565409829708noreply@blogger.com0tag:blogger.com,1999:blog-8502402619700195700.post-42066650149325309582009-04-01T17:07:00.003+02:002011-10-24T14:24:25.067+02:00ItemAdd EventThere is one event that is fired when a new item is arrived in the folder. It's a folder event. But, there is a problem with that event: ItemAdd may not fire if many items arrive in the folder at once.<br />
A workaround would be to process the Item that ItemAdd passes as an argument and mark that item as processed (you can use Mileage property for that purpose). Then process any other unmarked items in the folder.Nenad Dobrilovichttp://www.blogger.com/profile/17675085565409829708noreply@blogger.com0tag:blogger.com,1999:blog-8502402619700195700.post-57205400331665198142009-03-27T11:48:00.003+01:002011-10-24T14:24:00.087+02:00Mutithreading and Outlook ProgrammingOutlook Object Model is run in a STA COM server. Single-Threaded Apartment COM server will execute all calls on its main (and single) thread. If a client running on another thread wants to call an object in a single threaded apartment, the two threads need to be forcibly synchronized. It is known as 'marshaling'.<br />
That means that you don't gain any performance when using multithreading. All the calls are going to run on the same thread anyway and you incur the overhead hit. There's not really an advantage to multithreading Outlook Object Model.<br />
You can learn more about COM programming <a href="http://msdn.microsoft.com/en-us/library/ms809311.aspx">here</a> and <a href="http://www.microsoft.com/com/default.mspx">here</a>.Nenad Dobrilovichttp://www.blogger.com/profile/17675085565409829708noreply@blogger.com0tag:blogger.com,1999:blog-8502402619700195700.post-52405124683928772272009-03-25T16:17:00.003+01:002011-10-24T14:23:28.044+02:00Activate and Close EventsWhen an Activate or Close event occurs (on Explorer and Inspector objects), it doesn't tell you which inspector or explorer is activate or closed. Even worse, the CurrentExplorer or CurrentInspector references are the previous instance, not the newly activated instance.<br />
Solution is as follows: when a NewExplorer or NewInspector event comes in (from the Explorers and Inspectors collections, respectively), create a wrapper object. This wrapper holds a reference to the explorer or inspector object to which you register for Activate and Close events. In your add-in you should keep a collection of the wrapper objects and register for Activate and Close events with your wrapper object which forwards the underlying explorer or inspector events. Now when an event comes in, you know which explorer or inspector it is because it is identified by the wrapper object.Nenad Dobrilovichttp://www.blogger.com/profile/17675085565409829708noreply@blogger.com0tag:blogger.com,1999:blog-8502402619700195700.post-29017087446120270652009-03-23T14:22:00.002+01:002011-10-24T14:22:51.253+02:00Event HandlersWhen adding event handlers to any Outlook object, such as the Explorers and Inspectors collections or the Explorer and Inspector objects, you have to retain a reference to those items in your add-in. The reason for this is because the objects presented to the add-in by Outlook are not the actual objects, but rather interface objects providing limited access to the actual underlying objects. When the object goes out of scope it is discarded. Every time you get a reference, it's a new interface object so you never actually see the same object twice. Thus if you do not save a reference, your event handlers are discarded and garbage collected. Thus they don't throw events or at least not for long.Nenad Dobrilovichttp://www.blogger.com/profile/17675085565409829708noreply@blogger.com0tag:blogger.com,1999:blog-8502402619700195700.post-24450453872408851052009-02-02T15:48:00.002+01:002011-10-24T14:22:04.914+02:00VSTO is COM objectVisual Studio Tools for Office (VSTO) add-ins are COM objects.<br />
Almost every object that is used in Outlook is a COM object (inspectors, explorers, etc). They won't be discarded as long as any kind of reference is held on them. That means that when you are finished with these objects you must release your references to them. But you must also release the object from COM using Marshal.ReleaseComObject().<br />
In many cases unless you do use Marshal.ReleaseComObject() you don't know when the objects are actually released and as a result you can get memory leaks.<br />
You do have to be careful as to when you call Marshal.ReleaseComObject() because it releases all references to an object, including copies and different instances of the object. For example call Marshal.ReleaseComObject() on an Inspector passed to a class or method and not only that copy but the original object are released and attempts to use the object result in an invalid RCW error.<br />
Only call Marshal.ReleaseComObject() when you are completely finished with an object and any copies/instances of the object.<br />
Another reason to call Marshal.ReleaseComObject() is the default 256 RPC channel limit to Exchange. If you end up with that many or more current objects instantiated, for example in a loop, then you will get errors back when trying to instantiate any additional objects. That applies even to implicit objects internally instantiated due to dot operators. Setting the instances to null often isn't enough to release RPC channels due to the indeterminate nature of when the GC runs. In those cases often the only way to complete a loop is to explicitly call to Marshal.ReleaseComObject() and then to GC.Collect().Nenad Dobrilovichttp://www.blogger.com/profile/17675085565409829708noreply@blogger.com0tag:blogger.com,1999:blog-8502402619700195700.post-32164013352262864852008-11-20T23:06:00.002+01:002011-10-24T14:17:10.966+02:00Navigation Pane in OutlookThere are no way to influence on a look and feel of the navigation pane in Outlook 2003 and 2007. It is possible only to add a new shortcut in the shortcuts pane. Outlook documentations doesn't recommend adding new functionalities in Outlook navigation pane in any case.Nenad Dobrilovichttp://www.blogger.com/profile/17675085565409829708noreply@blogger.com0tag:blogger.com,1999:blog-8502402619700195700.post-391259411017898232008-11-10T15:39:00.002+01:002011-10-24T14:15:36.068+02:00Transfer Old Solutions to New Visual StudioIf you have developed applications in Visual Studio 2005 for Office 2003 and you are willing to make a transfer to new versions of Visual Studio and Office it wouldn't be a problem at all.<br />
First be sure to have installed PIA for Office 2007 and VSTO 3.0 on a new machine. Than just open an old project in Visual Studio 2008 an it will automatically convert older VS 2005 solution and project files and additionaly will update all references to work on Office 2007.Nenad Dobrilovichttp://www.blogger.com/profile/17675085565409829708noreply@blogger.com0tag:blogger.com,1999:blog-8502402619700195700.post-62607501652756801582008-11-07T14:16:00.000+01:002011-10-24T14:14:38.566+02:00Add-In for Outlook 2003 and 2007MSDN Documentation states that: ‘There is no supported way to use VSTO to create add-in that that works on both Outlook 2003 and 2007.’<br />
But actually it is possible to make add-in for Outlook 2003 which works on Outlook 2007 because VSTO 3.0 runtime can detect that add-in is made for previous version of Outlook and can set environment for it.<br />
However, backward compatibility is not possible.<br />
Additional difficulty is that Outlook 2003 and 2007 can’t work on the same machine, which makes development and testing a little bit harder than usual.Nenad Dobrilovichttp://www.blogger.com/profile/17675085565409829708noreply@blogger.com0tag:blogger.com,1999:blog-8502402619700195700.post-86747648214273099452008-10-24T15:43:00.006+02:002011-10-24T14:13:21.150+02:00Office Programming ModelsBeside VSTO (<a href="http://msdn.microsoft.com/en-us/office/aa905533.aspx">Visual Studio for Office</a>) and PIA (<a href="http://msdn.microsoft.com/en-us/library/aax7sdch.aspx">Primary Interop Assemblies</a>) for Office 2003/2007, there are two additional older technologies to program against MAPI stores:<br />
<ol>
<li>Extended MAPI (Messaging Application Program Interface) is set of functions that can be used to create MAPI enabled applications. Extended MAPI (or MAPI 1.0) allows complete control over the messaging system on the client computer, creation and management of messages, management of the client mailbox, service providers, and so forth. Extended MAPI is programming using C or C++.</li>
<li>CDO (Collaboration Data Objects) is a COM wrapper of the MAPI library and can be called from any development language that supports automation. CDO implements most but not all MAPI functionality.</li>
</ol>
Both of them provide a way to read and write more properties for MAPI store and items than PIA and to accomplish more tasks that using VSTO so sometimes they are the only way to do something. But VSTO 3.0 and PIA for Office 2007 provides more options to make custom MAPI items and stores so there is less need for using additional technologies.Nenad Dobrilovichttp://www.blogger.com/profile/17675085565409829708noreply@blogger.com0tag:blogger.com,1999:blog-8502402619700195700.post-28872426187699321542008-10-14T13:59:00.003+02:002011-10-24T14:09:51.937+02:00Proof Of Concept Outlook Add-InThree months ago, I got a task to make Proof Of Concept Outlook Add-In for an internal project in my company.<br />
<div>
<br />
<div>
As I have some experience in using Office platform, specifically Outlook, I thought that I shouldn't have any problem in programming against Office platform.</div>
<div>
<br /></div>
<div>
Microsoft has put a lot of effors in making Office easy to learn and use as a programming platform and in some extent they manage to make it so. But, if you need to do something in a way which is not meant by API creators you'll get a lot of problems, so I had them a lot.</div>
<div>
<br /></div>
<div>
To make a long story short, these were my targets at the begining:</div>
<div>
<br /></div>
<div>
<ol style="margin-top: 0in;" type="1">
<li class="MsoNormal">Make an add-in for Outlook (versions 2003 and 2007). Support look & feel of Outlook. List all items in a folder structure. Support preview of items for common types and in an addition, changing and saving items where it is possible.</li>
<li class="MsoNormal">Use Visual Studio Tools for Office (VSTO) to create add-in. Alternative is to use COM development targeting Office platform (no indentified advantages over VSTO).</li>
</ol>
</div>
<div>
In the following posts, I will try to describe all problems that I had and what I did to solve them in a single aim: not to forget them.</div>
</div>Nenad Dobrilovichttp://www.blogger.com/profile/17675085565409829708noreply@blogger.com0