Dailycode.info

Short solution for short problems

Remove send TO from the item menu

I have a SharePoint site that handles important documents with enhanced security. Users are allowed to view the documents, but no changes are allowed. So I decided to use Rights Management Services in cooperation with WSS security. Now I can even prevent users from saving and printing the word documents. But then SharePoint allowed a menu feature: "Send To"  which allowed the user to copy a document locally. This feature was not easy to remove. It's not possible using WSS security.

I tried a solution that proposed to add a empty javascript to the page or masterpage. This script would replace the AddSendSubMenu(m,ctx) script from the core.js in the WSS directory. But it didn't work. Then I found a solution on this site that worked for me. It involved changing the AddSendSubMenu javascript in the core.js file. One IISRESET was required. You could change the script or just empty the complete function, but I chose to add an IF to check for the document library name. Because it only applied for 1 particular document library.

Here is the change I made to the script:

function AddSendSubMenu(m,ctx){if(ctx.listName !="{3971CB40-C660-48BB-BF86-9FF3917A053A}"){
...script text
}

 

You can find the ID if the library in the content database, in the table Alllists or by clicking the settings link of the library and removing the url spacial characters.

You can find the core.js file here Drive :\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\LAYOUTS\1033


Microsoft tech days in Belgium

This year I will be attending the tech days again. It is happening on 10 (pre-conference) , 11 and 12 march. To view the schedule, click here. You can view the schedule per interest, Architet, Developer or IT professionals.

It has been 2 years since I was there. The program looks very interesting. I will also be attending a pre conference:

Pre-Conference: Deep-dive into development for Microsoft Office SharePoint Server 2007
SharePoint 2007 is built on ASP.NET 2.0. When it was released the current development tool was Visual Studio 2005. Since then many technologies and tools have been released that integrate with MOSS 2007, we can think about Visual Studio 2008, .NET 3.5, IIS7, etc. This pre-conference will give you the ground-layer and go further than the basic introduction training on MOSS, taking into account the use of latest technologies into SharePoint development. The day will be split into 5 separate sessions that will address the following topics:

  • SharePoint Architecture (Site Collections, Lists, Features, IIS Web Applications) using the tools under Visual Studio 2008
  • Managing data (Site Columns, Content types, Lists, etc)
  • Events
  • WCF
  • Internet facing Publishing sites and more.

Pre-requisites: Basic knowledge of MOSS2007 development

At the tech days after the pre-conference I will be attending mostly the developer sessions, also some of the architect sessions, but it will depend on the schedule of the different sessions.

Tech days


ASP.Net GridView: databinding a subobject

I have a gridview on my page. I want to show information in it that I retrieve from the database. After I get the data via webservices from the database, I map them with process layer object classes. The object classes from the process layer have following structure:

 
public class TESTStock
    {
        private string _guid;
 
        public string Guid
        {
            get { return _guid; }
            set { _guid = value; }
        }
       
 
        private TESTStockLocation _stockLocation;
 
        public TESTStockLocation StockLocation
        {
            get { return _ stockLocation; }
            set { this._ stockLocation = value; }
        }
    }

The subclass looks like this:


public class TESTStockLocation
    {
        private string _guid;
 
        public string Guid
        {
            get { return _guid; }
            set { _guid = value; }
        }
       
        private string _description;
 
        public string Description
        {
            get { return _ description; }
            set { _ description = value; }
        }
 
    }
 

If I want to show the information about the TestStockLocation (the subclass) in my gridview, I will have to use template columns:

<asp:TemplateField HeaderText="Stock location description">
  <ItemTemplate>
   <asp:Label ID="lblCRCID" runat="server"
    Text='<%# ((Namespace.TestStock)(Container.DataItem)).StockLocation.Description %>'>
   </asp:Label>
  </ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="Description" HeaderText="Stock descrioption" />
 

Notice that I used Namespace.TestStock, if the object class is in a different namespace, you will have to refer the namespace, even when you have a using clause of this namespace in your code behind.

Now when I databind a list of TestStock items, the description on the subitem teststocklocation will be shown in  template column.

  List<TestStock> mainstockItems = new List< TestStock >();
        Stock st = new Stock();
        mainstockItems = st.GetTestStock();
        this.GridView1.DataSource = mainstockItems;
        this.GridView1.Visible = true;
        this.GridView1.DataBind();

WIA vs DirectShow.Net

In the previous post I described how to take a picture using WIa. I looked a little further and discovered the DirectShow library. They have some good samples and just the code that I needed. It took a little more effort, not so much more by the way, but the result was promosing. The main difference is that the time to capture the image was greatly reduced. Also, once you setup the code of DirectShow, the implementation is relatively easy.

I copied a class called Capture.cs to my solution, made a reference to the DirectShow Library 2005 and then used following code to take a snapshot:

Cursor.Current = Cursors.WaitCursor;
 
 
// Release any previous buffer
if (m_ip != IntPtr.Zero)
{
Marshal.FreeCoTaskMem(m_ip);
      m_ip = IntPtr.Zero;
}
 
            // capture image
m_ip = cam.Click();
Bitmap b = new Bitmap(cam.Width, cam.Height, cam.Stride, 
PixelFormat.Format24bppRgb, m_ip);
pictureBox1.Height = b.Height;
pictureBox1.Width = b.Width;
// If the image is upsidedown
b.RotateFlip(RotateFlipType.RotateNoneFlipY);
pictureBox1.Image = b;
 
Cursor.Current = Cursors.Default;

In the default constructor I initialize the camera device and assign it to a second picturebox, so you get video streaming.

InitializeComponent();
this.ApplicationTitle = "Cigarette counter";
const int VIDEODEVICE = 0; 
// zero based index of video capture device to use
const int VIDEOWIDTH = 640; // Depends on video device caps
const int VIDEOHEIGHT = 480; // Depends on video device caps
const int VIDEOBITSPERPIXEL = 24; 
// BitsPerPixel values determined by device
 
cam = new Capture(VIDEODEVICE, VIDEOWIDTH, VIDEOHEIGHT, VIDEOBITSPERPIXEL, pictureBox2);
 

This works great, for now I decided to loose the WIA code and use the DirectShow library.

You can dowload the library and samples here.

I created a simple demo project using directshow, download this here.


Using WIA 2.0 to take picture

I have a webcam connected via USB to my pc. I needed to take a picture and do some calculations to it.

As I started to use the WIA library I noticed that it supported VB.Net better then c#. Some things where not possible in c#. I create an interface, ICamera and a class Camera that implemented this interface. The Camera is written in VB.Net because of limitations in c#.

For now the class exposes 1 function: TakePicture. This funtion takes a picture, returns an System.Drawing.Image and cleans up reasources. Here is the class that does the work:

Imports System.Drawing
Imports NSP.Win.Interfaces.IO
Imports WIA
Imports System.IO
...
 
Public Function TakePicture() As System.Drawing.Image Implements ICamera.TakePicture
 
        Dim returnImg As Image = Nothing
        Dim DefaultDevice As Device
        Dim Dialog1 As New WIA.CommonDialog
        DefaultDevice = Dialog1.ShowSelectDevice 'Does NOT show dialog. Merely retrieves device. 
        Dim total As Integer
        total = DefaultDevice.Items.Count
 
        Dim Item As WIA.Item = DefaultDevice.ExecuteCommand(WIA.CommandID.wiaCommandTakePicture)
        Dim Img As WIA.ImageFile = Item.Transfer 'because this item is an image. 
 
        'Dim Img As WIA.ImageFile = DefaultDevice.Items(total).Transfer() 'Whereas ShowTransfer() shows the progress bar. 
        If File.Exists("MyImage.Tif") Then
            File.Delete("MyImage.Tif")
        End If
        Img.SaveFile("MyImage.Tif")
        returnImg = Image.FromFile("MyImage.Tif")
 
 
        Dim x As Short
        ' Remove all items from the current device
        For Each WIAItm In DefaultDevice.Items
            ' Run through each item and remove
            For x = 1 To DefaultDevice.Items.Count
                Try
                    ' Remove the item
                    DefaultDevice.Items.Remove(x)
                    ' Exit the loop
                    Exit For
                Catch exp As Exception
                End Try
            Next
        Next
        Return returnImg
    End Function
End Class

 

I'm starting to investigate the properties of the WIA device, so I can set the brithgness, resolution etc and expose them via an interface. Maybe I will post this later on.

If you are wondering what different in c#, for example, less or practically no information, also, the dialog.showselectdevice cannot be addressed in c# without parameters, and it will always show the GUI.