Andri Yadi

A geeky technopreneur, trying to do something big with his startup
  • WSS 3.0 SP2 on Windows Server 2008 R2 - “Open with Windows Explorer” Failed

    So you’ve installed Windows SharePoint Server (WSS) 3.0 SP2 on Windows Server 2008 R2 successfully. You’ve created a web application and a site collection using a template, let’s say a Team Site. And you’ve managed get it run.

    First, let me explain my WSS environment:

    • WSS 3.0 SP2
    • Windows Server 2008 R2. Yes, it’s 64-bit edition, it’s the only option
    • SQL Server 2008 Standard Edition SP1
    • Internet Explorer 8 for viewing WSS site

    Now, if you have a Document Library inside that just created site, open it. It will look like this:

    image

    One of neat features of WSS 3.0 (and MOSS 2007) is the ability to browse, open, create, delete file and folder in the Document Library using Windows Explorer as if it were a shared network drive. This article explains the detail and how to do it: http://office.microsoft.com/en-us/sharepointtechnology/HA100929191033.aspx?pid=CH100649441033, and this video: ttp://www.youtube.com/watch?v=ywsdnYfHATs

    So, you click Actions menumenu in that Document library, and click Open with Windows Explorer, as shown below. See what happen?

    Screen shot 2010-01-04 at 3.56.52 AM

    If your environment is like mine, you will probably encounter this error: “Your client does not support opening this list with Windows Explorer.”, as shown below.

    image

    That error never happened when I install WSS 3.0 on Windows Server 2008 (not R2). How to solve it?

    Some refer to this http://support.microsoft.com/kb/923906. It’s no good as it’s for solving Internet Explorer 6 issue. Others refer to this http://www.microsoft.com/downloads/details.aspx?familyid=17C36612-632E-4C04-9382-987622ED1D64&displaylang=en. It’s also no good since it’s for Windows XP/Vista.

    Enabling WebDAV Client Service

    If you haven’t know yet, “Open with Windows Explorer” feature is implemented using WebDAV protocol, so it relies on a WebDAV client service (i.e. WebClient). By default, that service is not installed on Windows Server 2008 and Windows Server 2008 R2. Many blogs talk about this, such as: http://ari.provoke.co.nz/archive/2009/02/02/enabling-open-with-windows-explorer-in-windows-server-2008.aspx.

    Basically, you need to install the “Desktop Experience” feature. This can be done by navigating to Server Manager > Features > Add Feature > Desktop Experience (requires reboot). Then, make sure WebClient service is Started. You can set Startup Type to Automatic. More step by step guidance is here.

    image

    It’s Not Enough, More Steps

    Turns out it’s not enough. For Windows Server 2008 R2, you need to perform additional steps:

    1. Open IIS Manager, navigate to your WSS site (WSS web application). In my example, the WSS site is PM Central. Then, double click to Modules.

    image

    You’ll see modules list like this. Do you notice there is WebDAVModule?

    image

    2. Remove WebDAVModule, by right clicking to it and click Remove.

    Now, refresh your Document Library (off course from Internet Explorer). Try “Open with Windows Explorer” again. Voilà, here come the great Windows Explorer displaying the content of Document Library.

    image 

    I don’t know why this error happens. Whether it’s a bug or miss configuration, I don’t know. The fact you should know, although WSS uses WebDAV for implementing the browsing with Windows Explorer feature, it doesn’t need WebDAV support on IIS to be enabled. Seems like it has its own WebDAV implementation. In our case, somehow WebDAV on IIS cannot be co-existence with WSS WebDAV.

    Map Network Drive

    As a bonus, now you can map the Document Library to a drive.

    1. From Windows Explorer, press Alt key to show menu bar.

    2. Click Tools, then Map network drive, you’ll get:

    image

    3. Select Drive letter. For Folder, type something like this: http://[hostname]:[port]/[sitename]/[libraryname], where:

    • hostname: you know what it is
    • port: the port where WSS site is deployed
    • sitename: optional
    • libraryname: Document Library name

    And, you’ll have Document Library mapped to local drive.

    image

    That’s it. Enjoy.

    Share this post: | | | |
  • “System.BadImageFormatException: Could not load file or assembly” on IIS 7

    Pernah ngalamin error kuning kayak gini waktu deploy web app di IIS 7?

    “System.BadImageFormatException: Could not load file or assembly 'SharpMap' or one of its dependencies. An attempt was made to load a program with an incorrect format.”

    image

    FYI, my dev environment:

    • Windows 7 Ultimate 64-bit (did I mention I do coding on MacBook Pro :P ?)
    • IIS 7.0
    • SQL Server Express 2008

    Pada contoh error message di atas, ada masalah dengan assembly SharpMap. Langsung menyalahkan assembly SharpMap (yang sebenarnya, paket yang gw download masih hasil build dari trunk, not really final yet).

    Langsung pergi ke MSDN untuk cari apa dan penyebab exception System.BadImageFormatException. Not helping much, but one thing I notice that exception should be related to platform, x86 or x64. After googling and binging, either on SharpMap portal at codeplex or anywhere, not helping much. I suspect it’s not directly related to the SharpMap assembly itself. Its should be related to configuration.

    Iseng-iseng buka konfigurasi IIS 7.0. Tidak menemukan sesuatu yang terkait pada property pages untuk men-setting web app yang bersangkutan. Lalu coba masuk ke Application pool, klik kanan pada DefaultAppPool (gw pakai DefaultAppPool aja, malas bikin baru, toh app yang pakai cuman satu). Dan menemukan setting “Enable 32-Bit Applications”. Ahh…it should be it.

    image

    Then, I set “Enable 32-Bit Applications” to True. Viola…it works. So, looks like SharpMap assembly I have, it targeted to 32-bit platform.

    That’s all, hope this post will help somebody out there.

    Share this post: | | | |
    Posted Nov 03 2009, 04:04 PM by andriyadi with no comments
    Filed under:
  • AJAX Control Toolkit: AsyncFileUpload

    Wow…long time no blogging. As always, busy busy busy… Di tengah kesibukan mengerjakan proyek dadakan di negeri tetangga dengan deadline yang super cepat, nyempatin diri lihat-lihat AJAX Control Toolkit (ACT), siapa tahu ada control baru. Ternyata memang ada. The latest release is Sept 30, 2009. There are two new controls:

    • SeaDragon - This version of Seadragon allows you to display an image, and to zoom in and out of that image using mouse button keys without resizing the window.
    • AsyncFileUpload - This new control enables you to perform file uploads without doing a postback. The control displays a throbber image during upload and raises client and server events when the upload is complete. This control was contributed by Steven Lindsay.

    Let’s focus to AsyncFileUpload. While other open framework and platform have release this kind of control years ago, for example ICEFaces (for JSF) with its <ice:inputFile> control, ACT took quite sometime to release the same control. But, it’s better late than never, isn’t it?

    So, let’s try AsyncFileUpload.

    1. Download ACT binary here

    2. Extract the downloaded zip file. You’ll find among other things are: AjaxControlToolkit.dll and AjaxControlToolkit.pdb

    3. Copy those two files to Bin folder of ASP.NET Website project

    4. To ease the usage, don’t forget to add these lines in web.config:

    <pages>
        <controls>                
            <add namespace="AjaxControlToolkit" assembly="AjaxControlToolkit" 
                 tagPrefix="ajaxToolkit"/>
        </controls>
    </pages>

    5. Now, create a new ASP.NET page (or you can use existing page). Name it whatever you want. Add this tag:

    <ajaxToolkit:AsyncFileUpload runat="server" ID="AsyncFileUpload1" Width="400px" 
    UploaderStyle="Modern" UploadingBackColor="#CCFFFF" />

    then right click to the page and View in Browser. You’ll get:

    image

    Not bad huh? Change the UploaderStyle to Traditional, you’ll get the old input file.

    If you try to click Select File button, browse and select the file, looks like the control will upload the file, but don’t know where the file goes. Why? because you don’t specify the destination yet.

    Server-side Event

    This control has two server-side events:

    • UploadedComplete - Fired on the server side when the file successfully uploaded
    • UploadedFileError - Fired on the server side when the uploaded file is corrupted

    If the file has been successfully uploaded to server, it’s your responsibility to move/save as to wherever you want. You can use UploadedComplete  event to do that.

    Change the tag to:

    <ajaxToolkit:AsyncFileUpload runat="server" ID="AsyncFileUpload1" Width="400px" 
    UploaderStyle="Modern" UploadingBackColor="#CCFFFF" 
    OnUploadedComplete="AsyncFileUpload1_UploadedComplete"/>

    Then in aspx code behind, write this event handler:

    protected void AsyncFileUpload1_UploadedComplete(object sender, 
                   AjaxControlToolkit.AsyncFileUploadEventArgs e)
    {
         if (AsyncFileUpload1.HasFile)
         {
             AsyncFileUpload1.SaveAs(Server.MapPath("~/Uploads/" + 
             Path.GetFileName(e.filename)));
         }
    }

    That code will save as the uploaded file to Upload folder under the root application folder.

    By default setting, ASP.NET can handle file upload until 4096 KB (4 MB). You can specify more by change the setting in web.config. Find <system.web> and put something like this <httpRuntime maxRequestLength="102400"/> to allow file upload until 100 MB. Please be aware that change to this setting opens the possibility for denial of service attacks caused by users posting large files to the server. Use it at your own risk.

    Client-side Event

    To add interactivity, you can handle client-side events. They are:

  • ClientUploadComplete - the client-side event after the file successfully uploaded
  • ClientUploadError - the client-side event if the file uploading failed
  • ClientUploadStarted - the client-side event on the file uploading started

    Let’s change the ASPX code to:

  •    1: <script type="text/javascript">
       2:     function uploadError(sender, args) {
       3:         $get('labelUploadMsg').innerText = args.get_fileName() + " " + 
       4:                                            args.get_errorMessage() + " ";
       5:         $get('labelUploadMsg').style.color = 'red';
       6:     }
       7:  
       8:     function uploadComplete(sender, args) {
       9:         var contentType = args.get_contentType();
      10:         var text = args.get_length() + " bytes";
      11:         if (contentType.length > 0) {
      12:             text += ", '" + contentType + "'";
      13:         }
      14:  
      15:         $get('labelUploadMsg').innerText = text;
      16:         $get('labelUploadMsg').style.color = 'black';
      17:     }
      18:  
      19:     function uploadStarted(sender, args) {
      20:         $get('labelUploadMsg').innerText = "Upload is started";
      21:         $get('labelUploadMsg').style.color = 'black';
      22:     }
      23:  
      24: </script>
       1: <ajaxToolkit:AsyncFileUpload OnClientUploadError="uploadError" 
       2:     OnClientUploadComplete="uploadComplete" 
       3:     OnClientUploadStarted="uploadStarted"
       4:     runat="server" ID="AsyncFileUpload1" Width="400px" 
       5:     UploaderStyle="Modern" UploadingBackColor="#CCFFFF"
       6:     ThrobberID="activity" 
       7:     OnUploadedComplete="AsyncFileUpload1_UploadedComplete" />
       8: <img src="../../App_Global/Images/Skin/activity.gif" runat="server" 
       9:      id="activity" alt="Uploading..."/><br />
      10: <div>
      11:     <span id="labelUploadMsg"></span>
      12: </div>

    What I do above is:

    • Add javascript functions to handle client-side events
    • Add throbber image and set ThrobberID. Throbber image is animation image that will be displayed during file upload. You can use any GIF images.
    • Add span tag to display messages during upload.

    Let’s View In Browser:

    image

    If upload is completed successfully:

    image

    If it’s failed:

    image

    That error is caused by too large file size.

    Cool huh?

    If you see JS functions that handle client-side events, there’s a parameter called args. It’s an object that has these methods:

    • get_fileName()
    • get_path()
    • get_length()
    • get_contentType()
    • get_errorMessage()

    I’m sure you know what they are used for.

    Conclusion

    It’s a nice and helpful control. I’ve been waiting for this control years ago. Most of controls/lib (like JQuery uploadify) use Flash to handle async upload, it doesn’t. Don’t expect too much yet. It doesn’t support upload progress (byte by byte) notification yet.

    That’s it. Enjoy.

    Share this post: | | | |
  • 090909

    What will happen today, Sept 09, 2009 or 090909?

    • Some people believe that it has something to with the end of time and also Satan number. 999 is the upside-down number of “The Beast” Satan number, 666.
    • September 9, 2009, is the 252nd day of the year, 252 adds to 9, and 09-09-09 = 27.
    • 09-09-09 is also the last of the single-digits dates for quite a while - 92 years to be precise.
    • The day itself falls on a Wednesday and both Wednesday & September have 9 letters.

    Why 09/09/09 is so special, read it here: http://www.livescience.com/culture/090909-2009-date-nines.html

    One thing for sure, an Apple’s event will take place at the Yerba Buena Center for the Arts in San Francisco at 10 a.m. Pacific Time. The invitation, pictured below, features a classic iPod ad silhouette and reads "It's only rock and roll, but we like it.". The expected announcement? The new iPod lineup, at the very least, with iTunes a possibility and a tablet unlikely, at best.

    image

     

    What are you gonna  do at 090909 09:09:09? Looks like I’m still sleeping, since I’m about to hit the sack right now :)

    Share this post: | | | |
    Posted Sep 09 2009, 08:33 AM by andriyadi with no comments
    Filed under: ,
  • ADO.NET Data Services Cheat Sheet

    Memangnya cuman game yang punya cheat sheet. ADO.NET Data Services juga punya.

    image

    Mudah-mudahan gak repost.

    Thanks to Robert Maclean for creating a data services "cheat sheet".  You can get it here: http://www.sadev.co.za/content/adonet-data-services-cheat-sheet

    Direct Download

    Share this post: | | | |
  • OBA – Excel & ADO.NET Data Services

    Ah…long time no blogging. Busy..busy..busy.. :)

    Today I’ll post my demo that I’ve presented on an event entitled “Light Up Your Office”, on July 07, 2009 (a day before Indonesia Presidential Election), at Microsoft Indonesia. This all-day event delivered OBA/VSTO-related topics. I delivered a topic entitled “Optimizing OBA Spreadsheet Productivity with Excel and VSTO”.

    In Office Business Application (OBA), working with data from Microsoft Office application, directly to database or via XML Web Services is a common thing. Inspired by this blog post, I created a simpler sample using C# (original sample uses VB.NET). This sample demonstrates how we can develop a simple Office Business Application that is based on Microsoft Excel and work with ADO.NET Data Services.

    ADO.NET Data Services or codenamed Astoria, has become a hot topic lately. It is a framework to enable creation and consumption of data services for the web. Pak Risman talked a lot about that stuffs, e.g: here.

    Our OBA will look like this:

    Picture 1

    Excel displays a list of unshipped orders (marked by empty shipped date). If we click a cell of a row inside the list, the order detail will be displayed on action pane on the right. Using action pane, we can set the ship date and save it. The ship date then will be saved to order table.

    Architecture of the demo:

    090707011000 - OBA Excel

    The sample uses Northwind database (“bing” it to download). Let’s get started…

    We’ll create three projects:

    • Northwind.Excel: an Excel Workbook project, our Excel-based OBA.
    • Northwind.Model: a Class Library project to store our Entity Data Model
    • Northwind.Svc: a Web Application project to store our ADO.NET Data Service

    1. Create Entity Data Model

    This sample uses ADO.NET Entity Framework to work with database. So, we need to create ADO.NET Entity Data Model (EDM) that will be used by ADO.NET Data Services to expose the data.

    Let’s create a Class Library project and name it Northwind.Model. To create an EDM, simply add new item from Northwind.Model project and select ADO.NET Entity Data Model. Name it Northwind.edmx. You’ll find a wizard to import model from Northwind database. Select Order, Order_Detail, Product, and Shipper table to be imported. Use Northwind.Model as model classes namespace. When you finish, you should have this models:

    Picture 2

    Build Nothwind.Model project

    2. Create ADO.NET Data Service

    Now, let’s create a Web Application project and name it Northwind.Svc. From this project, Add Reference to Northwind.Model project (I don’t have to explain how, do I?). Then Add New Item, select ADO.NET Data Service template, name it NorthwindServices.svc. Change the generated code so it will look like this.

    using System;
    using System.Collections.Generic;
    using System.Data.Services;
    using System.Linq;
    using System.ServiceModel.Web;
    using System.Web;
     
    namespace Northwind.Svc
    {
        public class NorthwindServices : DataService< Northwind.Model.NorthwindEntities >
        {
            // This method is called only once to initialize service-wide policies.
            public static void InitializeService(IDataServiceConfiguration config)
            {
                // TODO: set rules to indicate which entity sets and service operations are visible, updatable, etc.
                // Examples:
                // config.SetEntitySetAccessRule("MyEntityset", EntitySetRights.AllRead);
                // config.SetServiceOperationAccessRule("MyServiceOperation", ServiceOperationRights.All);
     
                config.SetEntitySetAccessRule("*", EntitySetRights.All);
            }
        }
    }

    Note:
    Northwind.Model.NorthwindEntities is a class generated when we generate EDM. Northwind.Model is the namespace we use to group EDM classes.

    Now, right click to NorthwindServices.svc and View in Browsers. Browser will display something like this:

    <?xml version="1.0" encoding="utf-8" standalone="yes" ?> 
    - <service xml:base=http://localhost:1344/NorthwindServices.svc/ 
    xmlns:atom=http://www.w3.org/2005/Atom 
    xmlns:app=http://www.w3.org/2007/app 
    xmlns="http://www.w3.org/2007/app">
    - <workspace>
      <atom:title>Default</atom:title> 
    - <collection href="Order_Details">
      <atom:title>Order_Details</atom:title> 
      </collection>
    - <collection href="Orders">
      <atom:title>Orders</atom:title> 
      </collection>
    - <collection href="Products">
      <atom:title>Products</atom:title> 
      </collection>
    - <collection href="Shippers">
      <atom:title>Shippers</atom:title> 
      </collection>
      </workspace>
      </service>

    You can try to type this URL on browser address field: (port 1344 can be varying)
    http://localhost:1344/NorthwindServices.svc/Orders?$top=10&$orderby=OrderDate
    And browser will display:

    Picture 3

    Right click to that page and View Source, you’ll get XML content that contains actual Order data and structure. It contains 10 <entry> elements (means 10 records of Order data), sorted by OrderDate property.

    You can refer to ADO.NET Data Services to learn more about how to query the data using REST-like URI.

    3. Create Excel Workbook project

    So far we’ve created data model and data service that will be consumed by Excel application. Let’s create a Excel 2007 Workbook project and name it Northwind.Excel. You’ll be asked to create a new Excel document, just accept the default.

    As the final result depicts on the first picture, a list of unshipped order will be displayed on Excel worksheet. We need somehow to be able to bind the data (retrieved from ADO.NET Data Service) to Excel worksheet cells. There are some alternatives for binding purpose. One of it is to use the combination of Excel’s ListObject, BindingSource, and BindingList. This combination supports list change notification to be communicated to the user interface.

    ListObject is Excel’s control that allow us to bind data without having to traverse the Excel object model. It support simple binding from DataTable or IQueryable (returned from LINQ query), also from BindingSource.

    3.1.  Add Service Reference

    Let’s first to add service reference to our ADO.NET Data Service created on point 2. Since ADO.NET Data Service is basically based on WCF, adding reference to the service is the same as general WCF Service. Right click to Northiwind.Excel project, click Add Service Reference. Type service address (e.g. http://localhost:1344/NorthwindServices.svc, port 1344 can be varying) and use Namespace NorthwindSvc.

    This action will generate classes those are associated with EDM classes on the server. All generated classes will be resided inside Northwind.Excel.NorthwindSvc namespace.

    3.2. Order partial class

    To support change notification, we need to partial Order class and implement INotifyPropertyChanged interface. Write Order partial class within Northwind.Excel.NorthwindSvc namespace (note: NorthwindSvc is the Namespace we specify when adding service reference). It will look like this:

    using System;
    using System.ComponentModel;
     
    namespace Northwind.Excel.NorthwindSvc
    {
        public partial class Order: INotifyPropertyChanged
        {
     
            #region INotifyPropertyChanged Members
     
            public event PropertyChangedEventHandler PropertyChanged;
     
            #endregion
     
            private void FirePropertyChanged(String propertyName)
            {
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                }
            }
     
            partial void OnShippedDateChanged()
            {
                FirePropertyChanged("ShippedDate");
            }
     
            partial void OnOrderDateChanged()
            {
                FirePropertyChanged("OrderDate");
            }
     
            partial void OnFreightChanged()
            {
                FirePropertyChanged("Freight");
            }
     
            partial void OnOrderIDChanged()
            {
                FirePropertyChanged("OrderID");
            }
     
            partial void OnRequiredDateChanged()
            {
                FirePropertyChanged("RequiredDate");
            }
     
            partial void OnShipAddressChanged()
            {
                FirePropertyChanged("ShipAddress");
            }
     
            partial void OnShipCityChanged()
            {
                FirePropertyChanged("ShipCity");
            }
     
            partial void OnShipCountryChanged()
            {
                FirePropertyChanged("ShipCountry");
            }
     
            partial void OnShipNameChanged()
            {
                FirePropertyChanged("ShipName");
            }
            
            partial void OnShipPostalCodeChanged()
            {
                FirePropertyChanged("ShipPostalCode");
            }
     
            partial void OnShipRegionChanged()
            {
                FirePropertyChanged("ShipRegion");
            }
        }
     
        public partial class Product
        {
            public override string ToString()
            {
                return ProductName;
            }
        }
    }

    Please note that we also add Product partial class to override ToString() method.

    3.3. Create BindingList<Order>

    We need to create a subclass of BindingList to hold Order collection. Create a class and name it NorthwindOrderList.cs. Write this code:

    using System;
    using System.Linq;
    using System.ComponentModel;
    using Northwind.Excel.NorthwindSvc;
    using System.Data.Services.Client;
     
    namespace Northwind.Excel
    {
        public class NorthwindOrderList: BindingList<Order>
        {
            private NorthwindSvc.NorthwindEntities DataServiceContext;
            private bool hasChanged;
            private bool isSaving;
     
            public bool HasChanged { get { return hasChanged; } }
     
            public NorthwindOrderList()
            {
                DataServiceContext = new NorthwindEntities(
                    new Uri("http://localhost:1344/NorthwindServices.svc/"));
                this.DataServiceContext.MergeOption = MergeOption.OverwriteChanges;
            }
     
            protected override void OnListChanged(ListChangedEventArgs e)
            {
                if (!isSaving)
                {
                    if (e.ListChangedType == ListChangedType.ItemChanged)
                    {
                        DataServiceContext.UpdateObject(this[e.NewIndex]);
                        hasChanged = true;
                    }
                    base.OnListChanged(e);
                }
            }
     
            public int LoadOrders()
            {
                this.Clear();
     
                this.RaiseListChangedEvents = false;
     
                var orders = from o in DataServiceContext.Orders
                             where o.ShippedDate == null
                             orderby o.OrderDate descending
                             select o;
     
                foreach (var o in orders) { this.Add(o); }
     
                this.RaiseListChangedEvents = true;
                this.OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, 0));
     
                return this.Count;
            }
     
            public void LoadOrderDetails(Order o)
            {
                if (o != null)
                {
                    if (o.Shippers == null)
                    {
                        DataServiceContext.LoadProperty(o, "Shippers");
                    }
     
                    if (o.Order_Details == null || o.Order_Details.Count == 0)
                    {
                        DataServiceContext.LoadProperty(o, "Order_Details");
     
                        foreach (var od in o.Order_Details)
                        {
                            od.Orders = o;
                            if (od.Products == null)
                            {
                                DataServiceContext.LoadProperty(od, "Products");
                            }
                        }
                    }
                }
            }
     
            public bool SaveChanges()
            {
                bool saved = false;
                try
                {
                    isSaving = true;
                    DataServiceContext.SaveChanges();
                    hasChanged = false;
                    saved = true;
                    isSaving = false;
                }
                catch
                {
                    isSaving = false;
                }
     
                return saved;
     
            }
        }
    }

    In this class, we define three public methods:

    • LoadOrder(): to explicitly load order data from service and add to BindingList collection
    • LoadOrderDetails: to explicitly load Order_Details, Shipper, and Product object
    • SaveChanges: to explicitly save changes to ADO.NET Data Service.

    Note:

    3.4. Add New Data Source

    To be able to add ListObject to Excel Worksheet, we can use Data Source. Simply Add New Data Source from Data menu of Visual Studio. On Data Source Configuration wizard, choose Object. Then select NorthwindOrderList as the object to bind to.

    Picture 4

    After finishing the wizard, we’ll have NorthwindOrderList data source on Data Sources window. Drag that data source to a cell of Excel worksheet Sheet1, and we’ll have a ListObject. By default, the name the ListObject is northwindOrderListListObject. You can change it as you need. A BindingSource named northwindOrderListBindingSource will be generated automatically.

    Picture 5

    3.5. Write code in Sheet1.cs

    Right click to Sheet1 above and View Code. Write some code inside Sheet1_Startup method, that will look like this:

       1:  private void Sheet1_Startup(object sender, System.EventArgs e)
       2:          {
       3:              this.northwindOrderListBindingSource.DataSource = Globals.ThisWorkbook.OrderList;
       4:              this.northwindOrderListListObject.SetDataBinding(this.northwindOrderListBindingSource, "",
       5:                                            "OrderID",
       6:                                            "ShippedDate",
       7:                                            "Freight",
       8:                                            "ShipName",
       9:                                            "ShipAddress",
      10:                                            "ShipCity",
      11:                                            "ShipRegion",
      12:                                            "ShipPostalCode",
      13:                                            "ShipCountry");
      14:   
      15:              Globals.ThisWorkbook.LoadOrders();
      16:   
      17:              northwindOrderListListObject.Range.Columns.AutoFit();
      18:   
      19:              for (int i = 1; i < northwindOrderListListObject.DataBodyRange.Row; i++)
      20:              {
      21:                  ((Microsoft.Office.Interop.Excel.Range)northwindOrderListListObject.DataBodyRange.Cells[i, 2]).NumberFormat = "dd/mm/yyyy";
      22:              }
      23:          }

    At line 4 of above code, we use SetDataBinding of ListObject to set what columns/properties to be bound. You’ll notice that we call Globals.ThisWorkbook.LoadOrders() method that is not yet available. We’ll create it soon.

    3.6. Write code in ThisWorkbook.cs

    It’s time to write LoadOrder method and other code in ThisWorkbook.cs, so it will have this code:

            private NorthwindOrderList orderList;
            public NorthwindOrderList OrderList
            {
                get
                {
                    if (orderList == null)
                    {
                        orderList = new NorthwindOrderList();
                    }
                    return orderList;
                }
            }
     
            private OrderActionsPane oActionPane;
     
            private void ThisWorkbook_Startup(object sender, System.EventArgs e)
            {
                oActionPane = new OrderActionsPane();
                this.ActionsPane.Controls.Add(oActionPane);
            }
     
            public int LoadOrders()
            {
                return orderList.LoadOrders();
            }

    3.7. Create ActionPane

    Add new item and chose Action Pane control. Name the control as OrderActionPane.cs. Add some controls so it will look like this.

    Picture 6

    View code and write this code:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using Office = Microsoft.Office.Core;
    using Northwind.Excel.NorthwindSvc;
     
    namespace Northwind.Excel
    {
        partial class OrderActionsPane : UserControl
        {
            public OrderActionsPane()
            {
                InitializeComponent();
            }
     
            public void DisplayOrderDetails(Order o)
            {
                if (o != null)
                {
                    Globals.ThisWorkbook.OrderList.LoadOrderDetails(o);
                    order_DetailsBindingSource.DataSource = o.Order_Details;
                    
                }
            }
     
            private void OrderActionsPane_Load(object sender, EventArgs e)
            {
                Globals.Sheet1.northwindOrderListBindingSource.PositionChanged += new EventHandler(northwindOrderListBindingSource_PositionChanged);
            }
     
            void northwindOrderListBindingSource_PositionChanged(object sender, EventArgs e)
            {
                BindingSource bs = (BindingSource)sender;
                if (bs != null)
                {
                    if (bs.Position > -1)
                    {
                        DisplayOrderDetails((Order)bs.Current);
                    }
                }
            }
     
            private void button1_Click(object sender, EventArgs e)
            {
                try
                {
                    int count = Globals.ThisWorkbook.OrderList.LoadOrders();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
     
            private void button2_Click(object sender, EventArgs e)
            {
                try
                {
                    Globals.ThisWorkbook.OrderList.SaveChanges();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
     
            private void dateTimePicker1_ValueChanged(object sender, EventArgs e)
            {
                Order o = (Order)Globals.Sheet1.northwindOrderListBindingSource.Current;
                if (o != null)
                {
                    o.ShippedDate = dateTimePicker1.Value;
                }
            }
     
            
        }
    }

    Notes:

    • OrderActionsPane_Load is form load event handler
    • button1_Click and button2_Click are buttons click event handler. You can use more intuitive name
    • dateTimePicker1_ValueChanged is DatePicker value changed event handler

    The complete source code and the presentation slide can be found at: http://dycode.com/files/folders/other_talks/entry200.aspx

    The photo taken during my speaking.

    _MG_5579-r

    This concludes how we can create a simple Excel-based OBA that work with ADO.NET Data Service. Write comment if you have any problems related to this sample. Enjoy.

    Share this post: | | | |
    Posted Jul 16 2009, 04:45 AM by andriyadi with 1 comment(s)
    Filed under: , ,
  • Office Development in Visual Studio 2010

    Here are some samples that demonstrate Office 2007 development projects using Visual Studio 2010 Beta 1

    Outlook Form Region RSS Reader Sample Demonstrates how to use Microsoft Office Outlook 2007 form regions to display the full content of articles from an RSS feed.
    Excel Master Detail Data Sample Demonstrates how to retrieve data from a relational database or XML file and use that data in Excel.
    Excel Document Protection Techniques Sample Demonstrates various techniques you can use to protect structural components of a worksheet to help to prevent users from accidentally deleting controls or otherwise changing important parts of your solution document.
    UI Manager Sample Demonstrates how to create a Ribbon customization, a custom task pane, and a custom form region for Outlook 2007 by implementing extensibility interfaces in an add-in. Each instance of the Ribbon, task pane, and form region can correctly communicate with each other.
    SharePoint 2007 Sequential Workflow Sample When a document is uploaded the workflow is automatically started and a task is immediately created. The workflow then goes into a wait state until the task is updated. If the task is marked completed the workflow then completes.

    Just grab the code at: http://code.msdn.microsoft.com/OfficeDevFuture

    Off course you need VS 2010 Beta 1 to open the solution.

    Share this post: | | | |
    Posted May 20 2009, 08:15 AM by andriyadi with 2 comment(s)
    Filed under:
  • The Baby is Two Years Old Now

    He was conceived about three years ago. On May 9, 2007, exactly two years ago, he was born into this world, delivered by originally six fathers, no mom. We named him DyCode, a nickname of a full name, Dycode Cominfotech Development. He was born with almost nothing, from scratch, with only faith and determination of his fathers.

    Memang nggak mudah membesarkan bayi jika nggak punya cukup uang. Bayi apapun itu. Ketika bayi itu adalah sebuah perusahaan, nggak sedikit orang tuanya yang memilih menyerah dan meninggalkannya ketika kondisi keuangan mulai parah. Ditambah ketika pekerjaan-pekerjaan sulit didapat, makin menghancurkan kemampuan dan niat untuk tetap mengurusnya.

    Tidak terkecuali DyCode. Masa-masa awal kelahirannya, cukup membawa penderitaan bagi orang tuanya. Orangtuanya harus rela nggak gajian sama sekali, nggak bisa beredar, hidup seadanya dari sisa-sisa tabungan masa lalu, dan mengencangkan ikat pinggang. Ditambah para orangtuanya nggak punya banyak modal uang dan aset tetap ketika melahirkannya, hanya modal konsep, niat, keberanian, dan keteguhan hati.

    Walaupun pada awal kelahiran DyCode, sudah banyak pekerjaan bagi orangtuanya, tapi itu nggak membuat kondisi menjadi lebih baik. Pekerjaan-pekerjaan yang disebut proyek itu nggak seketika mendatangkan uang. Harus menunggu 2-3 bulan untuk bisa mencairkan uang. Dan ketika uang itu cair, langsung habis untuk membayar kewajiban-kewajiban yang tertunda di bulan-bulan sebelumnya. Kondisi tsb berlangsung terus menerus sampai hampir setahun.

    Akibatnya, nggak semua orangtua DyCode bertahan. Satu persatu meninggalkannya, sampai akhirnya tinggal 3 bapak yang mengurus DyCode. Kami nggak menyalahkan orangtua lainnya yang memilih jalan lain, mereka berhak untuk melakukan itu. Kondisi saat itu memang sucks. Hampir tidak ada harapan.

    Setelah kurang lebih setahun, kondisi mulai membaik. Pekerjaan semakin banyak dan nilainya bisa semakin tinggi seiring peningkatan kualitas dan image DyCode. Cash flow bisa lebih lancar, kegiatan gali lubang tutup lubang (kayak lagu bang Roma aja :P) bertendensi mulai berkurang. Semua berkat kesabaran dan kerja keras founders yang tersisa, dan tentu didukung oleh DyCoders yang tetap loyal, keep dynamic, work hard, dan outstanding results.

    Selayaknya bayi berumur 2 tahun, saat ini DyCode sudah memiliki gigi, bisa berjalan dan mulai berdiri tegak di tengah persaingan bisnis IT di tanah air, khususnya software development. Dalam 2 tahun, DyCode sudah mengalami peningkatan 100% dari sisi resources, 100% dalam hal revenue, 200% pada peningkatan aset tetap. Sudah me-launch satu produk ke publik, dan saat ini sedang dibentuk new business division (more story about this later). Not good enough for a business, but we are still and keep on trying and trying.

    Today, 090509, is his two years birthday. Happy birthday our baby DyCode…This is a cake for you.
    IMG_5113

    And this is the party for you (more story about this later).
    IMG_5314

    Grow up fast my son, be a nice boy… Selamat menempuh tahun ketiga dalam hidupmu.

    Share this post: | | | |
    Posted May 09 2009, 09:05 PM by andriyadi with 8 comment(s)
    Filed under:
  • Indonesia Celebrates It

    9 April 2009 adalah hari bersejarah. Indonesia merayakan sesuatu yang luar biasa. Pada hari itu seluruh rakyat Indonesia, well...mungkin tidak seluruhnya tapi sebagian besar, berbondong-bondong menuju ke suatu tempat yang sama, kemanakah mereka? Mungkinkah bangsa Indonesia sedang merayakan Ulang Tahun seorang anak manusia sekaligus putra Indonesia? Mungkin saja, tapi yang pasti, pada hari itu Indonesia sedang merayakan sebuah pesta demokrasi, Pemilihan Umum Legislatif 2009. Suatu hari dimana rakyat Indonesia menggunakan hak pilihnya untuk memilih partai politik dan calon wakil rakyat, dan calon DPD.

    27 tahun lalu, tepatnya hari Jumat dini hari, lahir seorang Homo Sapiens di negeri Nusantara ini. Kicking, Crying, and Screaming ketika ia menembus alam dunia fana ini. Mungkin awalnya ia menangis dan bertanya, "why I have to be born to this world". Tapi selama 27 tahun hidupnya, tak sedikitpun ia menyesal, malah bersyukur. From his perspective, many great things he've done. Walaupun semuanya masih belum cukup, but still..ia bersyukur.

    He is Andri Yadi, a geeky technopreneur that trying to do something big with his startup and his life. Datang dari keluarga dengan ekonomi menengah dan dari kampung antah beranta (yang cukup lama dilupakan oleh negeri kita tercinta, sampai akhirnya menjadi Provinsi sendiri), tidak membuatnya merasa kecil hati dan patah semangat. Hampir selalu memperoleh peringkat pertama (dan hanya 2 kali peringkat kedua) sejak SD sampai SMA, dan ditutup dengan pencapaian Cumlaude sewaktu kuliah di sebuah kampus ternama, adalah pencapaian yang berharga dalam hidupnya. Walaupun lapangan pekerjaan terbuka lebar, ia memilih menjadi pengusaha sesaat setelah lulus. Walaupun awalnya berdarah-darah, but still he enjoys his life as an entrepreneur.

    Memilih antara hidup sebagai karyawan di perusahaan ternama dengan gaji besar, atau memulai usaha dari nol dengan awal yang berdarah-darah, tentunya sebagian besar orang akan memilih pilihan pertama. Tapi tidak baginya. Pernah hidup pas-pasan dan hilang dari peredaran di masa awal pendirian perusahaannya, tidak membuat semangatnya surut untuk tetap melanjutkan hidup sebagai pengusaha. To him, money (and all kind of rewards) is a consequence, not an objective. Hidup sebagai entrepreneur membuat seseorang menjadi lebih matang, tolerir, sabar, dan berkemampuan untuk problem solving yang lebih baik. Entrepreneurship is one of the hardest yet most rewarding personal journeys we can take.

    Salah satu pencapaian penting di umur 26 tahun adalah Microsoft MVP award, yang diterima pada bulan Juli 2008. Di-recognize dan diberikan award sebagai Microsoft MVP untuk teknologi VSTO, satu-satunya di Indonesia kala itu (dan sampai hari ini), adalah suatu kebanggaan yang luar biasa. Lihat cerita selengkapnya di sini.

    Jika kebayakan orang bersuka ria di hari ulang tahunnya, bagi Andri, ulang tahun kali ini lebih membawa kesedihan. Kenapa? Karena baginya, begitu banyak yang masih harus dilakukan, tapi semakin sedikit jatah umur yang ada. Lihat saja entrepreneur-entrepreneur besar dunia, yang sudah bisa dibilang berhasil di usia rata-rata 24-25 tahun. Di usianya sekarang, Andri merasa masih belum terlalu terarah dalam berkarya, masih banyak distraction dalam jalannya. But still, he's thankful for all achievements he had so far. Hopefully, he will find that true path in the near time. Mudah2an dalam waktu dekat, akan ada sesuatu yang "wow" darinya. Tunggu saja.

    Di ulang tahunnya yang ke-27 ini, Andri ingin berterima kasih kepada Tuhan untuk 27 tahun hidup yang luar biasa, mudah2an masih ada tahun-tahun mendatang baginya untuk tetap berkarya. Terima kasih kepada Bapak dan Ibu, sepasang orang tua yang luar biasa hebatnya, yang telah memberi kelahiran, memberi kasih sayang dan pelajaran hidup. Terima kasih juga kepada semua teman-teman yang telah menambahkan makna dalam kehidupan.

    Terima kasih yang luar biasa dan amat dalam atas semua ucapan, harapan, dan doa dari teman-teman di Facebook. Mohon maaf jika tidak bisa dibalas satu persatu. Untuk makan-makan, mudah2an kita bisa schedule-kan satu persatu :)





    Thanks to Facebook for a great wall :)

    And special thanks to someone special for this delicious cake and other presents. I love you.


    Terima kasih Indonesia, yang telah ikut merayakan Ulang Tahun kali ini.

     

    Share this post: | | | |
  • My First English ScreenCast: About Excel, Virtual Earth, VSTO, and WPF

    It’s a must-watch screencast if you’d like to know about the possibility of creating something useful using technologies: Excel, Virtual Earth, VSTO, and WPF.

    Yes, you read the post’s title right. Several days ago I made my first screen cast in English. I’ve already did some screencasts (here and here), but this is the first audible one in English. Before you judge it, I have to admit that my English is terrible, it is more Indonesia-English (Inglish). However, if you’re Indonesian and geeky enough, I’m sure you’ll understand the content. This screencast is just for fun, no sponsors that endorse me to do it. Anyway, any endorsements are welcome :)

    Here it is, have a nice watching..

    It’s a long screencast (49 minutes), so you better prepare a cup of coffee (or some cigarettes, if you’re smoker) before you watch it.

    If somehow you cannot watch it in this page, you can download the video file directly from this Link. If the video or link are unavailable on April 12, 2009, then screencast.com (where I host the file) is in maintenance.

    Let me explain the content. If you attended MSDN Day at Microsoft Indonesia on March 25, 2009 ago, you’ve seen the demo. In this long screencast, I talked about Excel, Virtual Earth, VSTO, and WPF in one demo. It’s all about:

    1. Binding SQL Server table data (sales data) to Excel’s ListObject using LINQ to SQL
    2. Customizing Excel Ribbon
    3. Adding and configuring chart to Excel’s Worksheet programmatically
    4. Accessing Virtual Earth (VE) from WPF user control
    5. Embedding WPF User Control to Excel’s Action Pane using ElementHost control
    6. Programmatically adding pushpins to Virtual Earth (based on sales persons location data)
    7. Displaying VE pushpins’ InfoBox (detail) programmatically when user click Excel ListObject rows by handling ListObject’s SelectedIndexChanged event

    The completed solution of the demo can be downloaded at: http://dycode.com/files/folders/msdnday/entry190.aspx

    Virtual Earth WPF Control
    For the demo, I use WPF user control that’s originally posted here: http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/2008/10/03/10813.aspx

    For my demo purpose, I did some modification to:

    • Allow to display pushpin's InfoBox programmatically by calling ShowPushPinInfoBox() method. That method is added to PushPin class.
    • Allow to change Map mode to 3D. We add MapMode dependency property to VirtualEarth user control.
    • Add DetailsPushPinClicked event to VirtualEarth control. That event will be triggered when user click "Show Details" link located inside pushpin's InfoBox. The technique show how we can link JavaScript event with WPF.

    The modified control can be downloaded at: http://dycode.com/files/folders/codesamples/entry192.aspx

    That’s it. Have a nice watching and exploring.

    Links in this post:

    Share this post: | | | |
  • Windows 7 Build 7068 Successfully Installed

    [Updated] Yesterday (March 31, 2009), after 18 hours of downloading 3.23 gigs, finally I had Windows 7 Build 7068 x64 disk image. After burning the disk image, and ready to install it. Instead of doing fresh installation, I choose upgrade. After more or less 2 hours of upgrading my system, I finally had latest Windows 7 build. Well, actually it’s not latest build, since I just did searching and finding people talking about Windows 7 build 7072…that’s s**k.

    Anyway, this is my screen capture of Windows 7 build 7068 installed on my baby.

    image

    Few notes:

    1. Upgrading from Windows 7 beta build 7000 is successful

    Upgrading take more/less 2 hours. No error/warning messages during upgrading. It goes as smooth as Monica Belluci lips.

    Why I did upgrading instead of fresh installation you may ask. Well, I don’t wanna spend 10 hours that I usually spend to setup and configure all programs and environment for me to do my daily work. I can confirm that it’s safe to upgrade. All your settings and data are safe.

    2. All previous programs are running well

    Except:

    a. MacDrive 7.2.6
    if you have MacBook/MacBook Pro and use MacDrive to access Mac partition from Windows, you probably will have issue. After first time login, you probably will encounter MacDrive failed to start due to “File System Driver Did Not Start” error. To resolve the issue, use MacDrive 7.2.5 instead. So, uninstall MacDrive 7.2.6 and make sure to stay connected to internet so it will deactivate your serial no. Then install MacDrive 7.2.5 and activate using the same serial no. It works for me.

    By default, MacDrive cannot be installed on Windows 7 since the creator won’t support Windows 7 until its final release (RTM). So, you need to do a little hacking. Refer to this link: http://forums.macrumors.com/archive/index.php/t-632996.html or http://www.insanelymac.com/forum/index.php?showtopic=142438&st=60

    b. Windows Media Player
    WMP runs well except it does not retain previous library.

    c. Internet Explorer 8
    It also runs well. My concern is it has two icons on the taskbar. So, you need to remove one on the middle, not on the most left. Looks like it causes by the difference of Internet Explorer’s version. In this build, the include Internet Explorer 8 RTM. I can confirm that by openning http://geeks.netindonesia.net/ page and there is no “need to upgrade” message appears :)

    Beside all of those, Windows 7 runs well on my system…so far.

    Some fixes/improvements I notice and I thank for:

    1. LINQ to SQL Classes Designer of Visual Studio 2008

    I’d rather use Bahasa to explain this since many friends experience this. Di Windows 7 build 7000, ketika membuka file dbml (LINQ to SQL Classes), seperti biasa akan tampil tampilan designer. Anehnya, jika salah satu gambar model diklik maka segera dia akan hilang tanpa sebab. Coba designernya ditutup dan dibuka lagi, same result. Masalah tersebut dialami oleh banyak (bahkan mungkin semua) orang yang menggunakan build 7000.

    Fortunately, masalah itu gak terjadi lagi di build 7068.

    image

    2. No Blue Screen, so far

    Blue Screen on build 7000 has become a routine :) I usually encounter blue screen in many circumstances, such as: when I build my Visual Studio 2008 project/solution, when I close VS 2008, etc. Using build 7068, I do open and close VS 2008 several time, and still no blue screen. Thanks God.

    3. Nice login/shutting down screen

    logonandshutdownscreen1 

    4. Windows Experience Index

    Using build 7000, I only got 2.3 of Windows Experience Index due to lower score of primary hard disk that is only 2.3. Using build 7068, finally my system got what it deserves, 5.3.

    image

    What else? Hmmm… I think that’s all for now.

    So, to all Windows 7 (not patient and wanna be tester) users, I recommend you to upgrade to the latest build. I won’t tell where you can download disk image since it’s not released formally by Microsoft yet. You better start searching or waiting formal release from Microsoft.

    That’s all. Enjoy…

    Share this post: | | | |
  • Catatan Belajar Sore Ini

    March 31, 2009

    Button_FunViewController.h

    #import <UIKit/UIKit.h>

    @interface Button_FunViewController : UIViewController {
        IBOutlet UILabel *statusText;
    }

    @property (retain, nonatomic) UILabel *statusText;

    - (IBAction)buttonPressed:(id)sender;

    @end



    Button_FunViewController.m

    #import "Button_FunViewController.h"

    @implementation Button_FunViewController
    @synthesize statusText;

    -(IBAction)buttonPressed:(id)sender
    {
        NSString *title = [sender titleForState:UIControlStateNormal];
        NSString *newText = [[NSString alloc] initWithFormat:
                             @"%@ button pressed.", title];
        statusText.text = newText;
        [newText release];
    }

    -(BOOL)shouldAutorotateInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{
        return (interfaceOrientation == UIInterfaceOrientationPortrait);
    }

    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];    
    }

    - (void)dealloc {
        [statusText release];
        [super dealloc];
    }

    @end



    Ada yang tahu itu bahasa apa dan code di atas ngapain? Kalau ada, berarti sudah ada yang lebih dulu menguasai. And to whoever he/she is: "Master, I beg you to teach me!!. You Kung fu is very good."

    More post (about this) to come.


    Share this post: | | | |
    Posted Mar 31 2009, 04:46 PM by andriyadi with 5 comment(s)
    Filed under:
  • ScreenCast of IE 8 JSON Native Support

    This is very belated posting. This was a screen cast that was captured when I delivered a talk about Internet Explorer 8 for Developer on MSDN Day, Nov 29, 2008. I know it was a long time ago, just had time to convert and publish the screen cast :)

    This is my first screen cast that uses my voice as audio. Enjoy...

    The sample code used in this screencast can be downloaded at: http://dycode.com/files/folders/msdnday/entry174.aspx

    Share this post: | | | |
  • What is The Weirdest Thing You Do Using Excel?

    Another event, another presentation and demo, but still about VSTO. Yesterday, I delivered a talk about VSTO on an event entitled "Weekend with MUGI Seminar" at University of Pasundan (UNPAD), on March 15, 2009. This time, I opened my presentation with a question "What is the Weirdest Thing You Do using Microsoft Excel?". Unfortunately, no audiences answered the question. I expected somebody will raise hand and mention something wild/weird that he/she do using Excel or Office product.

    To show the audience the uncommon thing that can be done using Excel, I did a demo to simulate pendulum motion. Before I talk about the demo, let's squeeze some brains to understand how the simulation can be made.

    The illustration of pendulum motion:


    To be able to simulate the motion, all you need to have is the motion equation. More specifically, you need to know how amplitude (theta) change with time. Let's see how we can get the equation.
    Force diagram of simple gravity pendulum is


    Some mathematical derivations:
     


    Under the initial conditions θ(0) = θ0 and dθ/dt(0) = 0, the solution of differential equation is



    And the period is



    By knowing initial theta (θ0) and string/rod length (l), I can simulate the motion. Here's the screenshot:

    At the left side, we have the simulation. At the middle, there're some input fields. And at the right side, there's a chart plotting the theta against the time. As we see, the chart is sinusoidal means the motion is Simple Harmonic Motion.

    The crowd applause when the pendulum start to swing...

    The main part of code is:

                    double thetaT = theta0;
               
                do {
                    t += dt;

                    thetaT = theta * Math.Cos(t * Math.Sqrt(9.8/(stringLength/100)));

                    pendulumY = stringLength * Math.Cos(thetaT);
                    pendulumX = stringLength * Math.Sin(thetaT);

                    pendulum.Top = platformBelow +
                                   Convert.ToSingle(pendulumY);
                    pendulum.Left = referenceLeft +
                                    Convert.ToSingle(pendulumX) - (pendulum.Width / 2);

                    System.Windows.Forms.Application.DoEvents();

                } while (true);


    Where:
    • theta0: initial theta
    • thetaT: theta at a time t
    • stringLenght: String/Rod length
    • platformBelow: the position (from the top of the screen) of platform where string/rod hangs
    • referenceLeft: the position (from the left of the screen) of reference/equilibrium line
    That looping will go forever, so you need to create code to stop it.

    To get the full source code, just grab the code and presentation slide at: http://dycode.com/files/folders/mugi/entry189.aspx

    And here're some photos during the event:






    That's it. Enjoy.



    Share this post: | | | |
  • Enabling Apache and PHP on Leopard

    Gak seperti biasanya, kali ini gw akan bahas sesuatu yang tidak "berbau" Windows, .NET, and other Microsoft products. Bukan berarti gw Microsoft MVP "murtad" :) Gw tetap cinta .NET, and still write .NET code for living. Kebetulan aja gw lagi explore suatu teknologi di atas platform yang lain. Lagian, sayang banget nih MacBook Pro kalo gak dipakai buat coding on Mac :)

    Sebenarnya ini berawal dari kebutuhan training untuk implementasi produk Microsoft juga, yaitu Windows Live Services. Bos Naren ngajak gw sama-sama ngisi HOL dan training implementasi Windows Live Service on top of PHP. Karena saat menulis posting ini, gw sedang "berada" di Mac OS 10.5.6 (Leopard) dan sedang ingin meng-enable Apache dan PHP, jadilah gw bahas bagaimana meng-enable Apache dan PHP di Leopard.

    Di dalam Leopard, khususnya Leopard 10.5.6, sebenarnya sudah terinstall Apache 2.2.9 dan PHP 5.2.5. Hanya by default, keduanya tidak di-enabled.

    Berikut langkah-langkah untuk meng-enable keduanya:
    1. Buka aplikasi TextWrangler. Jika belum terinstal, download gratis dari http://www.barebones.com/products/textwrangler. Gw pakai TextWrangler 2.3. Dari menu File --> Open, dan navigate ke  Macintosh HD:private:etc:apache2:httpd.conf. Open file tersebut.
    2. Lalu editor akan menampilkan isi file httpd.conf. Jika diperhatikan, icon pencil pada toolbar masih tersilang yang berarti bahwa file tersebut sedang di-lock. Click icon tersebut, lalu ada pertanyaan apakah akan di-unlock. Click Unlock dan file siap di-edit. Ada baiknya Anda membuat backup just in case mau back to factory setting :)
    3. Scroll down ke baris 115, sampai Anda menemukan tampilan seperti ini.
    4. Uncomment baris 115 tersebut dengan cara membuat tanda pagar (#) untuk meng-enable PHP 5.
    5. Save file tersebut. Karena file ini di-own oleh "root", ketika mencoba menyimpan file akan muncul dialog untuk memasukkan password.
    6. Nah, sekarang saatnya men-start Apache Web Server. Buka System Preferences --> Sharing. Lalu centang checkbox Web Sharing (jika belum).

    7. Untuk memastikan PHP benar-benar sudah aktif, buatlah code simple yang basi' kayak gini:
      <?php phpinfo(); ?>

      Simpan code tersebut pada file dengan nama, misalnya: phpinfo.php. Simpan file tersebut di folder Macintosh HD:Library:WebServer:Documents. Lalu buka browser dan ketikkan alamat: http://localhost/phpinfo.php. Alhasil:
    Dengan langkah-langkah di atas sebenarnya kita pakai konfigurasi PHP yang default. Kalau mau enable PHP extensions, dll, perlu utak-atik php.ini. Untuk itu, perlu extra steps berikut.
    1. Buka Terminal (dari Application:Utilities), change directory (cd) ke etc, dengan mengetik: cd /etc
    2. Buat salinan file php.ini.default menjadi php.ini, dengan cara mengetik: sudo cp php.ini.default php.ini. Masukkan password root Anda
    3. Ya sudah...utak-atiklah file php.ini tersebut.
    Udah, gitu aja. Selamat coding PHP di Leopard :)

    Share this post: | | | |
More Posts Next page »