Getting the Screen Coordinates of a Cell in a DataGridView

16. September 2009 05:23 by Mrojas in General  //  Tags:   //   Comments (0)

Well, this is actually quite easy.

To get the X and Y of a Cell you just need to do something like:

grid.CurrentCell.ContentBounds.Location

or for the selected cell use:

grid.SelectedCells[0].ContentBounds.Location

 

And to convert that to screen coordinates do:

grid.PointToScreen(grid.CurrentCell.ContentBounds.Location)

 

mmm Well I found that

grid.GetCellDisplayRectangle(columnIndex, rowIndex, false) is a better alternative, because it will give you the Rectangle for the whole Cell

Where is my DXCore

19. August 2009 05:06 by Mrojas in General  //  Tags: , , , ,   //   Comments (0)

I’m an enthusiastic user of DXCore and I have been working on some extensions of my own. But I could not find the DXCore or DevExpress menu.

Well there is a hack for that.

Please invoke the Registry editor, add the "HideMenu" DWORD value to the following Registry key, and set its Value to 0:
HKEY_LOCAL_MACHINE\SOFTWARE\Developer Express\CodeRush for VS\9.1
This should make the "DevExpress" menu visible.

Look at the post for more details and keep enjoying DXCore.

C# PInvoke out or ref??

17. August 2009 09:40 by Mrojas in General  //  Tags: , , , ,   //   Comments (0)

If I have a PInvoke call like the following:

[DllImport("Advapi32.dll", CharSet=CharSet.Auto)]
static extern Boolean FileEncryptionStatus(String filename, 
   out UInt32 status);

What is the difference between

 

[DllImport("Advapi32.dll", CharSet=CharSet.Auto)] static extern Boolean FileEncryptionStatus(String filename, out UInt32 status);

and

[DllImport("Advapi32.dll", CharSet=CharSet.Auto)] static extern Boolean FileEncryptionStatus(String filename, ref UInt32 status);

Well, as long as I have tested it, they exactly the same. From the MSDN you can even read

“I could have selected the ref keyword here as well, and in fact both result in the same machine code at run time. The out keyword is simply a specialization of a by-ref parameter that indicates to the C# compiler that the data being passed is only being passed out of the called function. In contrast, with the ref keyword the compiler assumes that data may flow both in and out of the called function.”

“When marshaling pointers through P/Invoke, ref and out are only used with value types in managed code. You can tell a parameter is a value type when its CLR type is defined using the struct keyword. Out and ref are used to marshal pointers to these data types”

So what should you use? Well using the out keyword for PInvoke will just add some information or documentation to your method, but because these functions are implemented in C or C++ they might treat an out parameter as an IN parameter so I really prefere to use ref when I’m calling functions with PInvoke.

Migration from .NET Framework 1.1

13. August 2009 18:07 by Mrojas in General  //  Tags: , , , , , ,   //   Comments (0)

.NET has been around for quite a while. According Wikipedia it has been around since on 3 April 2003
So now there exist applications developed for .NET Framework 1.0 or 1.1 and people
need to migrate them to Framework 2.0 or Framework 3.5.

It is the general impression that there is not a direct path to 3.5.
As Zain Naboulsi explains in his blog you can go from 1.1 to 2.0 then from 2.0 to 3.5.
And From 2.0 to 3.5 the migration is a no-brainer because, both, 3.0 and 3.5 are based on 2.0.

A good reference also is the post of Peter Laudati on migration from 1.1 to 2.0.
Note: Peter’s post seem to have a broken link to the microsoft document about breaking changes in 2.0.
The correct link is this.

A more recent post by The Moth provides more links to breaking changes documents:

- Design time Breaking Changes in .NET Framework 2.0
- Runtime Breaking Changes in .NET Framework 2.0
- Microsoft .NET Framework 1.1 and 2.0 Compatibility
- Compatibility Testing Scenarios

Going from 1.1 to 2.0 or 3.5 can be just as simple as opening the solution in VS and compile
or it can take a lot of effort. Web Projects then to be more difficult due to several changes in ASP.NET.

So good luck.

Tools?

Well there a lot of static analyisis tools we have used
(some internal, some from Third Parties. I particulary like Understand and NDepend)

No more System.Data.OracleClient

7. August 2009 06:15 by Mrojas in General, Oracle, Database  //  Tags: , , , , ,   //   Comments (0)

 Microsoft announced that they won’t support the System.Data.OracleClient anymore :(

 

The message says that it will still be available in .NET 4.0 but “deprecated” and that it wont impact existing applicatoions.

 

So what are my options?

Well you have to go to a third party. Not now but eventually.

 

Oracle Data Provider for .NET (ODP.NET) (Oracle states that ODP.NET is Free)

DataDirect ADO.NET Provider for Oracle

dotConnect for Oracle

 

Migration to ODP.NET

Installation

Microsoft OracleClient to ODP.NET Application Migration: Code Migration

Oracle provide general instructions. In summary you need to:

  1. Add the references to Oracle.DataAccess
  2. Change namespaces: System.Data.OracleClient by  Oracle.DataAccess.Client; and maybe add “using Oracle.DataAccess.Types”
  3. Update the connection String (most attributes are the same). Change Integrated Security by  "User Id=/", change “Server” attribute to “Data Source” and remove Unicode
  4. The following is anoying but you have to add after all OracleCommands something like OracleCommand1.BindByName = true;

Deployment

  • Oracle Universal Installer (either in normal installation or Silent Install)
  • XCopy (I like this :) ) just remember to download the ODAC xcopy version

Extended WebBrowser Control Series: NewWindow3

Recently an user of the ExtendedBrowser v2 commented that he needed access to the NewWindow3 event.

The NewWindow3 event is raised when a new window is to be created. It extends NewWindow2 with additional information about the new window. 

Syntax

Private Sub object_NewWindow3( _
	ByRef ppDisp As Object, _
	ByRef Cancel As Boolean, _
	ByVal dwFlags As Long, _
	ByVal bstrUrlContext As String, _
	ByVal bstrUrl As String)

Parameters

object Object expression that resolves to the objects in the Applies To list. ppDisp Object expression that, optionally, receives a new, hidden WebBrowser or InternetExplorer object with no URL loaded. Cancel A Boolean value that determines whether the current navigation should be canceled. true Cancel the navigation. false Do not cancel the navigation. dwFlags The flags from the NWMFenumeration that pertain to the new window.

typedef enum NWMF 
{     
    NWMF_UNLOADING = 0x00000001,
     NWMF_USERINITED = 0x00000002,
     NWMF_FIRST = 0x00000004,
     NWMF_OVERRIDEKEY = 0x00000008,
     NWMF_SHOWHELP = 0x00000010,
     NWMF_HTMLDIALOG = 0x00000020,
    NWMF_FROMDIALOGCHILD = 0x00000040,
     NWMF_USERREQUESTED = 0x00000080,
     NWMF_USERALLOWED = 0x00000100,
     NWMF_FORCEWINDOW = 0x00010000,
     NWMF_FORCETAB = 0x00020000,
     NWMF_SUGGESTWINDOW = 0x00040000,
     NWMF_SUGGESTTAB = 0x00080000,
     NWMF_INACTIVETAB = 0x00100000
} NWMF;

bstrUrlContext The URL of the page that is opening the new window. bstrUrlThe URL that is opened in the new window.

Please notice:

Note   The NewWindow3 event is only fired when a new instance of Internet Explorer is about to be created. Calling showModalDialog or showModelessDialog does not trigger an event because they are not new instances of Internet Explorer. They are implemented as MSHTML host windows, which allows them to render and display HTML content but not hyperlinks between documents.

You can download from here

DOWNLOAD CODE HERE v3_1

ExtendedBrowserExampleVBNET.zip (92.56 kb)

CapsLock, NumLock in C# and VB.NET

10. July 2009 12:49 by Mrojas in General  //  Tags: , , , , ,   //   Comments (0)

I was looking for a “.net” way of detecting the CapsLock state, but almost all the references pointed to pinvoke code like:

<DllImport("user32.dll")> _
Public Shared Function GetKeyState(VirtKey As Integer) As Integer
End Sub

And I finally found two ways:

1) You can call methods from the System.Console class:

You can use the System.Console.CapsLock property and if you want the NumLock state use: System.Console.NumberLock

or

2) You can call make an instance of Microsoft.VisualBasic.Devices.Keyboard. (For this if you are in C# you need to add a reference to Microsoft.VisualBasic.dll)

For example:

Microsoft.VisualBasic.Devices.Keyboard key = new Microsoft.VisualBasic.Devices.Keyboard();

and use properties like:

key.CapsLock

key.NumLock

key.ScrollLock

key.ShiftKeyDown

key.CtrlKeyDown

key.AltKeyDown

Printing RichTextBox contents in C#

10. July 2009 05:54 by Mrojas in General  //  Tags: , , , ,   //   Comments (0)

This post discusses and provides the implementation of a helper class to add support
for printing the formatted contents of a richtextbox control.

The print model in .NET is a little different than one used in VB6.

For example see: http://support.microsoft.com/kb/146022

Public Sub PrintRTF(RTF As RichTextBox, LeftMarginWidth As Long, _
   TopMarginHeight, RightMarginWidth, BottomMarginHeight)
   Dim LeftOffset As Long, TopOffset As Long
   Dim LeftMargin As Long, TopMargin As Long
   Dim RightMargin As Long, BottomMargin As Long
   Dim fr As FormatRange
   Dim rcDrawTo As Rect
   Dim rcPage As Rect
   Dim TextLength As Long
   Dim NextCharPosition As Long
   Dim r As Long

   ' Start a print job to get a valid Printer.hDC
   Printer.Print Space(1)
   Printer.ScaleMode = vbTwips

   ' Get the offsett to the printable area on the page in twips
   LeftOffset = Printer.ScaleX(GetDeviceCaps(Printer.hdc, _
      PHYSICALOFFSETX), vbPixels, vbTwips)
   TopOffset = Printer.ScaleY(GetDeviceCaps(Printer.hdc, _
      PHYSICALOFFSETY), vbPixels, vbTwips)

   ' Calculate the Left, Top, Right, and Bottom margins
   LeftMargin = LeftMarginWidth - LeftOffset
   TopMargin = TopMarginHeight - TopOffset
   RightMargin = (Printer.Width - RightMarginWidth) - LeftOffset
   BottomMargin = (Printer.Height - BottomMarginHeight) - TopOffset

   ' Set printable area rect
   rcPage.Left = 0
   rcPage.Top = 0
   rcPage.Right = Printer.ScaleWidth
   rcPage.Bottom = Printer.ScaleHeight

   ' Set rect in which to print (relative to printable area)
   rcDrawTo.Left = LeftMargin
   rcDrawTo.Top = TopMargin
   rcDrawTo.Right = RightMargin
   rcDrawTo.Bottom = BottomMargin

   ' Set up the print instructions
   fr.hdc = Printer.hdc   ' Use the same DC for measuring and rendering
   fr.hdcTarget = Printer.hdc  ' Point at printer hDC
   fr.rc = rcDrawTo            ' Indicate the area on page to draw to
   fr.rcPage = rcPage          ' Indicate entire size of page
   fr.chrg.cpMin = 0           ' Indicate start of text through
   fr.chrg.cpMax = -1          ' end of the text

   ' Get length of text in RTF
   TextLength = Len(RTF.Text)

   ' Loop printing each page until done
   Do
      ' Print the page by sending EM_FORMATRANGE message
      NextCharPosition = SendMessage(RTF.hWnd, EM_FORMATRANGE, True, fr)
      If NextCharPosition >= TextLength Then Exit Do  'If done then exit
      fr.chrg.cpMin = NextCharPosition ' Starting position for next page
      Printer.NewPage                  ' Move on to next page
      Printer.Print Space(1) ' Re-initialize hDC
      fr.hdc = Printer.hdc
      fr.hdcTarget = Printer.hdc
   Loop

   ' Commit the print job
   Printer.EndDoc

   ' Allow the RTF to free up memory
   r = SendMessage(RTF.hWnd, EM_FORMATRANGE, False, ByVal CLng(0))
End Sub

The VBCompanion provides excellent helpers that provide a lot fo the VB6 Printer object functionality, so you dont have to change any of your actual code, but in some cases, you might just want to remove that code, specially for very specific things like printing a RichTextBox.

So here I’m providing a .NET simplified helper that allows you to print the contents of a RichTextBox control. This helper is just based on the code published by Martin Muller in http://msdn.microsoft.com/en-us/library/ms996492.aspx. It provides an extension method for VS 2008 user so all you have to do is call RichTextBox.Print.

The implementation is simple. The RichTextBoxPrintHelper creates or receives an instance of a PrintDocument object, and event handlers are added to it for the BeginPrint, PrintPage and EndPrint events.

    private int m_nFirstCharOnPage;

    private void printDocument_BeginPrint(object sender, System.Drawing.Printing.PrintEventArgs e)
    {
        // Start at the beginning of the text
        m_nFirstCharOnPage = 0;
    }

    private void printDocument_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
    {
        // To print the boundaries of the current page margins
        // uncomment the next line:
        //e.Graphics.DrawRectangle(System.Drawing.Pens.Blue, e.MarginBounds);

        // make the RichTextBoxEx calculate and render as much text as will
        // fit on the page and remember the last character printed for the
        // beginning of the next page
        m_nFirstCharOnPage = FormatRange(false,
            e,
            m_nFirstCharOnPage,
            control.TextLength);

        // check if there are more pages to print
        if (m_nFirstCharOnPage < control.TextLength)
            e.HasMorePages = true;
        else
            e.HasMorePages = false;
    }

    private void printDocument_EndPrint(object sender, System.Drawing.Printing.PrintEventArgs e)
    {
        // Clean up cached information
        FormatRangeDone();
    }
The FormatRange method is called. This method will use the fill out some structures 
with page information and use the RichTextBox handle to send messages that will render
the control contents to the Printer’s HDC.
 
 /// <summary>
    /// Calculate or render the contents of our RichTextBox for printing
    /// </summary>
    /// <param name="measureOnly">If true, only the calculation is performed,
    /// otherwise the text is rendered as well</param>
    /// <param name="e">The PrintPageEventArgs object from the
    /// PrintPage event</param>
    /// <param name="charFrom">Index of first character to be printed</param>
    /// <param name="charTo">Index of last character to be printed</param>
    /// <returns>(Index of last character that fitted on the
    /// page) + 1</returns>
    public int FormatRange(bool measureOnly, PrintPageEventArgs e,
        int charFrom, int charTo)
    {
        // Specify which characters to print
        STRUCT_CHARRANGE cr;
        cr.cpMin = charFrom;
        cr.cpMax = charTo;

        // Specify the area inside page margins
        STRUCT_RECT rc;
        rc.top = HundredthInchToTwips(e.MarginBounds.Top);
        rc.bottom = HundredthInchToTwips(e.MarginBounds.Bottom);
        rc.left = HundredthInchToTwips(e.MarginBounds.Left);
        rc.right = HundredthInchToTwips(e.MarginBounds.Right);

        // Specify the page area
        STRUCT_RECT rcPage;
        rcPage.top = HundredthInchToTwips(e.PageBounds.Top);
        rcPage.bottom = HundredthInchToTwips(e.PageBounds.Bottom);
        rcPage.left = HundredthInchToTwips(e.PageBounds.Left);
        rcPage.right = HundredthInchToTwips(e.PageBounds.Right);

        // Get device context of output device
        IntPtr hdc = e.Graphics.GetHdc();

        // Fill in the FORMATRANGE struct
        STRUCT_FORMATRANGE fr;
        fr.chrg = cr;
        fr.hdc = hdc;
        fr.hdcTarget = hdc;
        fr.rc = rc;
        fr.rcPage = rcPage;

        // Non-Zero wParam means render, Zero means measure
        Int32 wParam = (measureOnly ? 0 : 1);

        // Allocate memory for the FORMATRANGE struct and
        // copy the contents of our struct to this memory
        IntPtr lParam = Marshal.AllocCoTaskMem(Marshal.SizeOf(fr));
        Marshal.StructureToPtr(fr, lParam, false);

        // Send the actual Win32 message
        int res = SendMessage(control.Handle, EM_FORMATRANGE, wParam, lParam);

        // Free allocated memory
        Marshal.FreeCoTaskMem(lParam);

        // and release the device context
        e.Graphics.ReleaseHdc(hdc);

        return res;
    }
 

Using the RichTextBox is even more simple. You add a richtextbox to a form and call the Print method:

image

        private void printToolStripMenuItem_Click(object sender, EventArgs e)
        {
            richTextBox1.Print();
        }

I’m attaching the source code for the helper an this sample application so you can use this.

DOWNLOAD SOURCE CODE

ColdFusion 8 and JRockIt

15. June 2009 18:41 by Mrojas in General  //  Tags: , , , , , , ,   //   Comments (0)

JRockIt is an interesting Java Virtual Machine. I really admire the technology used in it. Well following Mike’s post about Memory Leaks in Coldfusion http://www.schierberl.com/cfblog/index.cfm/2006/10/12/ColdFusion_memoryLeak_profiler I was trying to configure the JRockit JVM to do some profiling on an important application.

But alas. Time just flies and things have change a lot since Mike wrote that post. So this is basically an update:

1) JRockit must be downloaded from: http://www.oracle.com/technology/software/products/jrockit/index.html You must accept the license and also have an OTN Account (this is a free process). Download the right version for your platform. I tried the x86 version on my 64 bit server and it didn;t work, so use the version that fits better to your platform. However there is no 64 bit client version of Memory Leak and all the other nice client tools. But dont worry. Download both version 64 and 32 bits versions. You will use the 64 version for your server and the 32 bit version for monitoring.

2) Stop coldfusion server

3) Modify the jvm.config file. In my case it was in: C:\ColdFusion8\runtime\bin\jvm.config

comment out old java.home and add a new line like:
java.home=C:/Program Files/Java/jrmc-3.1.0-1.6.0/jre

In the java.args setting, remove parameter –Xbatch (dont know why, it just didnt work)

add a parameter like:
-Xmanagement:ssl=false,authenticate=false,autodiscovery=true

*In my case I also had to disable security in C:\Program files\Java\jrmc-3.1.0-1.6.0\jre\management\management.properties with a line like:

com.sun.management.jmxremote.authenticate=false

4) Re start coldfusion

DDE in .NET

10. June 2009 04:51 by Mrojas in General  //  Tags: , , , , , ,   //   Comments (0)

Someone recently made me remind an old technology called DDE.

“Dynamic Data Exchange (DDE) is a technology for communication between multiple applications under Microsoft Windows or OS/2

 

“The primary function of DDE is to allow Windows applications to share data. For example, a cell in Microsoft Excel could be linked to a value in another application and when the value changed, it would be automatically updated in the Excel spreadsheet. The data communication was established by a simple, three-segment model. Each program was known to DDE by its "application" name. Each application could further organize information by groups known as "topic" and each topic could serve up individual pieces of data as an "item". For example, if a user wanted to pull a value from Microsoft Excel which was contained in a spreadsheet called "Sheet1" in the cell in the first row and first column, the application would be "Excel", the topic "Sheet1" and the item "r1c1".

Note: In DDE, the application, topic and item are not case-sensitive.”

 

So in VB6 you can have something like:

 

Private Sub Form_Load()
Text1.LinkMode = 0
Text1.LinkTopic = "Excel|Sheet1"
Text1.LinkItem = "R1C1"
Text1.LinkMode = 1
End Sub

 

 

How can you do that in .NET. Is it possible in C#? Well I started looking around and found several forums explaining about all the API calls and I was just about to write my own solution when I found NDDE. This project hosted in CodePlex “provides a convenient and easy way to integrate .NET applications with legacy applications that use Dynamic Data Exchange (DDE)” :)

 

So this is a  nice example of how to do the previous lines in C#:

        //This class provides the infraestructure for DDE comunication
        NDde.Client.DdeClient ddeClient_TextBox1 = null;

        private void Form1_Load(object sender, EventArgs e)
        {
            //I initialize the DDEClient object. Application is Excel and Topic is Sheet1. I'm using the 
            //the TextBox as the syncronization object
            ddeClient_TextBox1 = new NDde.Client.DdeClient("Excel", "Sheet1", textBox1);
            //Connect to the DDE Server
            ddeClient_TextBox1.Connect();
            //Start the Advise Loop
            ddeClient_TextBox1.StartAdvise("R1C1", 1, true, 60000);
            //Setup the Advise Method
            ddeClient_TextBox1.Advise += new EventHandler<NDde.Client.DdeAdviseEventArgs>(ddeClient_TextBox1_Advise);
            //Setup a method to Poke the Server for TextBox cahnges
            textBox1.TextChanged += new EventHandler(textBox1_TextChanged);

        }
        
        void textBox1_TextChanged(object sender, EventArgs e)
        {
            //Syncronous Poking the server
            ddeClient_TextBox1.Poke("R1C1", textBox1.Text + "\0", 4000);
        }

        const string DDE_postFix = "\r\n\0";
        void ddeClient_TextBox1_Advise(object sender, NDde.Client.DdeAdviseEventArgs e)
        {
            //Advise only if needed
            if (e.Text.Length >=DDE_postFix.Length && textBox1.Text + DDE_postFix != e.Text)
                textBox1.Text = e.Text.Substring(0,e.Text.Length-3);
        }
NOTE: Remember that you need to download NDDE and add a reference to this library

This is very good library, you can also set up a lot of Async calls to even improve performance. I have even thought of making an extender as the ToolTip control to add LinkTopic, LinkMode and LinkItem properties for Winforms controls or provide extensions methods to make all the syntax easier, but that is for a future post. Good Luck.