Friday, August 22, 2014

Windows Mobile Development .NET CE techiniques

Windows Mobile (.NET CE) development techniques: 
As a recent shifting into Windows Mobile CE Development I wanted to share Widow CE development techniques which I have struggled to be done.
I would feel new comer in the new Windows Mobile Development could have multi-specialty stuff with not too much struggle.
1)   Drag , Drop & Move in Window CE

For explanation I have taken picture box and defined the Mouse events as listed

    // pbVehCycle
            //
            this.pbVehCycle.Image = ((System.Drawing.Image)(resources.GetObject("pbVehCycle.Image")));
            this.pbVehCycle.Location = new System.Drawing.Point(120, 3);
            this.pbVehCycle.Name = "pbVehCycle";
            this.pbVehCycle.Size = new System.Drawing.Size(32, 32);
            this.pbVehCycle.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
            this.pbVehCycle.MouseMove += new System.Windows.Forms.MouseEventHandler(this.pbVeh1_MouseMove);
            this.pbVehCycle.MouseDown += new System.Windows.Forms.MouseEventHandler(this.pbVeh1_MouseDown);
            this.pbVehCycle.MouseUp += new System.Windows.Forms.MouseEventHandler(this.pbVeh1_MouseUp);

The code written in events is as below(the below code is to drag & drop the picture box and simultaneously recreate the picture box with same image at the same position) =>

Point  vehOrgPos; //global declaration for recreation of picturebox
private void pbVeh1_MouseDown(object sender, MouseEventArgs e)
        {
            var staticVeh = (PictureBox)sender;
            vehOrgPos = new Point(staticVeh.Location.X, staticVeh.Location.Y);
            if (e.Button == System.Windows.Forms.MouseButtons.Left)
            {
                MouseDownLocation = new Point(e.X, e.Y);
            }
        }

        private void pbVeh1_MouseMove(object sender, MouseEventArgs e)
        {
            var staticVeh = (PictureBox)sender;
            if (e.Button == System.Windows.Forms.MouseButtons.Left)
            {
                staticVeh.Left = e.X + staticVeh.Left - MouseDownLocation.X;
                staticVeh.Top = e.Y + staticVeh.Top - MouseDownLocation.Y;
            }
        }

//In the below method I am recreating the new picturebox with same image at same position   
  
  private void pbVeh1_MouseUp(object sender, MouseEventArgs e)
        {

            var staticVeh = (PictureBox)sender;
            string DraggedImageName = staticVeh.Name;
            if (e.Button == System.Windows.Forms.MouseButtons.Left)
            {
                if (staticVeh.Top > 35)
                {

                    staticVeh.MouseDown -= new MouseEventHandler(pbVeh1_MouseDown);
                    staticVeh.MouseMove -= new MouseEventHandler(pbVeh1_MouseMove);
                    staticVeh.MouseUp -= new MouseEventHandler(pbVeh1_MouseUp);
                    staticVeh.MouseDown += new MouseEventHandler(pbDyn_MouseDown);
                    staticVeh.MouseMove += new MouseEventHandler(pbDyn_MouseMove);
                    staticVeh.MouseUp += new MouseEventHandler(pbDyn_MouseUp);


                    Random rndom = new Random();
                    rndom.Next(1, 10000);
                    staticVeh.Name = staticVeh.Name + "new_" + rndom.Next(1, 10000);

                    PictureBox revertOrginalPB = new PictureBox
                    {
                        Name = "new_" + rndom.Next(1, 10000),
                        Size = new Size(34, 33),
                        Location = vehOrgPos,
                        SizeMode = PictureBoxSizeMode.StretchImage
                    };
                    revertOrginalPB.Image = staticVeh.Image;
                    revertOrginalPB.MouseDown += new MouseEventHandler(pbVeh1_MouseDown);
                    revertOrginalPB.MouseMove += new MouseEventHandler(pbVeh1_MouseMove);
                    revertOrginalPB.MouseUp += new MouseEventHandler(pbVeh1_MouseUp);


                    this.pnlCollisionLayout.Controls.Add(revertOrginalPB);
                    pictureBoxList.Add(staticVeh);
                    revertOrginalPB.Invalidate();
                }
                else
                {
                    staticVeh.Location = vehOrgPos;
                }

            }
        }
Screen shot (below provided) to understand what am I doing….

I have dragged the picture box from top right at this point I have stored the vehicle position in the global variable declared then after dragging Mouse up event fires where I have recreated the picture box with the same image & events at the recorded vehicle position.
In this way you can drag as many times. Just test it very smooth movement has been adopted.
2)   Saving the Portion of the Screen as Image onclick of Save button


After dragging & moving I want to save the specific region as pointed above then how? 
I had this requirement, this should be saved & sync to server. For this I come up some smarted technique , I though why can’t I save the screen shot by cutting down it to the portion I want as an Image, and I could able to implement it as below..
        //Used for saving image
        enum RasterOperation : uint { SRC_COPY = 0x00CC0020 }
        [DllImport("coredll.dll")]
        static extern int BitBlt(IntPtr hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr  hdcSrc, int nXSrc, int nYSrc, RasterOperation rasterOperation);
        [DllImport("coredll.dll")]
        public static extern IntPtr GetDC(IntPtr hwnd);
        [DllImport("coredll.dll")]
        public static extern int ReleaseDC(IntPtr hwnd, IntPtr hdc);

  /// <summary>
        /// to save image finalized after drag,drop drawinglines
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
   private void btnSave_Click (object sender, EventArgs e)
        {
            Bitmap capture = new Bitmap(300, 300);

            // The code below takes the screenshot and
            // saves it in "capture" bitmap.
            Rectangle bounds = Screen.PrimaryScreen.Bounds;
            IntPtr hdc = GetDC(IntPtr.Zero);
            Bitmap bitmap = new Bitmap(bounds.Width, bounds.Height, PixelFormat.Format16bppRgb565);
            using (Graphics graphics = Graphics.FromImage(bitmap))
            {

                IntPtr dstHdc = graphics.GetHdc();
                BitBlt(dstHdc, 0, 0, bounds.Width, bounds.Height, hdc, 0, 67,
                RasterOperation.SRC_COPY);
                graphics.ReleaseHdc(dstHdc);
            }
            bitmap.Save("collision.jpg", ImageFormat.Jpeg);
            ReleaseDC(IntPtr.Zero, hdc);
            // Example use:    
            Bitmap source = new Bitmap("collision.jpg");
            Rectangle section = new Rectangle(0, 0, bounds.Width, 220);

            Bitmap CroppedImage = CropImage(source, section);
            CroppedImage.Save("collision_image.jpg", ImageFormat.Jpeg);
            if (File.Exists("collision.jpg"))
                File.Delete("collision.jpg");
        }


3)   Line Drawings on Panel
Define the 3 event handler to panel first and the code & screen is below
ð  Make sure that you have dragged Panel & defined 3 event handlers as below

this.pnlCollisionLayout.MouseMove += new System.Windows.Forms.MouseEventHandler(this.panel1_MouseMove);
this.pnlCollisionLayout.MouseDown += new  System.Windows.Forms.MouseEventHandler(this.panel1_MouseDown);
 this.pnlCollisionLayout.MouseUp += new System.Windows.Forms.MouseEventHandler(this.panel1_MouseUp);

& Now see the code in the events
#region Panel Line Drawings
        Pen newPen = new Pen(Color.Black, 3);//global declaration
        Graphics gr = null; Point startLine;//global declaration

        private void panel1_MouseMove(object sender, MouseEventArgs e)
        {
                       
                    graphic.DrawLine(newPen, e.X, e.Y, e.X, e.Y);          
        }

        private void panel1_MouseDown(object sender, MouseEventArgs e)
        {

                   gr = this.pnlCollisionLayout.CreateGraphics();
                    gr.DrawLine(newPen, e.X, e.Y, e.X, e.Y);
                    startLine = new Point(e.X, e.Y);

        }

        private void panel1_MouseMove (object sender, MouseEventArgs e)
        {

                    gr.DrawLine(newPen, startLine.X, startLine.Y, e.X, e.Y);
                    startLine.X = e.X;
                    startLine.Y = e.Y;

        }
        #endregion
4) Widening Window CE ScrollBar for Smooth Movement
Below SetVerticalScrollbarWidth() is used to acehive it
/// <summary>
        /// For Setting Vertical Scroll Bar Width when to Scroll down perfectly when records in DataGrid are  more
        /// </summary>
        public static void SetVerticalScrollbarWidth(Control c, int w)
        {
            try
            {
                var lGridVerticScrollBar = GetNonPublicFieldByReflection<VScrollBar>(c, "m_sbVert");
                lGridVerticScrollBar.Width = w;
            }
            catch(Exception ex)
            {
                Utilities.LogException(ex, "Error while Setting Grid Scroll Bar Width - SetVerticalScrollbarWidth,ViolationCodes");
            }
        }
        /// <summary>
        /// Function is used to set Verical Scroll Bar Width - Used By SetVerticalScrollbarWidth()
        /// </summary>
        public static T GetNonPublicFieldByReflection<T>(object o, string name)
        {
            if (o != null)
            {
                Type lType = o.GetType();
                if (lType != null)
                {
                    var lFieldInfo = lType.GetField(name, BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.Instance);
                    if (lFieldInfo != null)
                    {
                        var lFieldValue = lFieldInfo.GetValue(o);
                        if (lFieldValue != null)
                        {
                            return (T)lFieldValue;
                        }
                    }
                }
            }
            throw new InvalidCastException("Error in GetNonPublicFieldByReflection for " + o.ToString());

        }
  
5) Show & Hide KeyBoard Windows Mobile

        //Pop up of Keyboard with the parameter 'code'=1 as popout and 0 as hidden
        [DllImport("coredll.dll", EntryPoint = "SipShowIM")]
        public static extern bool SipShowIMP(int code);


6) Get Windows Mobile Device ID (IMEI No.) Through the Following Class

public class DeviceId

    {

        //static string deviceId = null;

        private static Int32 FILE_DEVICE_HAL = 0x00000101;
        private static Int32 FILE_ANY_ACCESS = 0x0;
        private static Int32 METHOD_BUFFERED = 0x0;
        //private Button button1;

        private static Int32 IOCTL_HAL_GET_DEVICEID =
       ((FILE_DEVICE_HAL) << 16) | ((FILE_ANY_ACCESS) << 14)
        | ((21) << 2) | (METHOD_BUFFERED);

        [DllImport("coredll.dll")]
        private static extern bool KernelIoControl(Int32 IoControlCode, IntPtr
          InputBuffer, Int32 InputBufferSize, byte[] OutputBuffer, Int32
          OutputBufferSize, ref Int32 BytesReturned);


        public static string GetDeviceID()
        {
            byte[] OutputBuffer = new byte[256];
            Int32 OutputBufferSize, BytesReturned;
            OutputBufferSize = OutputBuffer.Length;
            BytesReturned = 0;

            // Call KernelIoControl passing the previously defined
            // IOCTL_HAL_GET_DEVICEID parameter
            // We don’t need to pass any input buffers to this call
            // so InputBuffer and InputBufferSize are set to their null
            // values
            bool retVal = KernelIoControl(IOCTL_HAL_GET_DEVICEID,
                   IntPtr.Zero,
                   0,
                   OutputBuffer,
                   OutputBufferSize,
                   ref BytesReturned);

            // If the request failed, exit the method now
            if (retVal == false)
            {
                return null;
            }

            // Examine the OutputBuffer byte array to find the start of the
            // Preset ID and Platform ID, as well as the size of the
            // PlatformID.
            // PresetIDOffset – The number of bytes the preset ID is offset
            //                  from the beginning of the structure
            // PlatformIDOffset - The number of bytes the platform ID is
            //                    offset from the beginning of the structure
            // PlatformIDSize - The number of bytes used to store the
            //                  platform ID
            // Use BitConverter.ToInt32() to convert from byte[] to int
            Int32 PresetIDOffset = BitConverter.ToInt32(OutputBuffer, 4);
            Int32 PlatformIDOffset = BitConverter.ToInt32(OutputBuffer, 0xc);
            Int32 PlatformIDSize = BitConverter.ToInt32(OutputBuffer, 0x10);

            // Convert the Preset ID segments into a string so they can be
            // displayed easily.
            StringBuilder sb = new StringBuilder();
            sb.Append(String.Format("{0:X8}-{1:X4}-{2:X4}-{3:X4}-",
                 BitConverter.ToInt32(OutputBuffer, PresetIDOffset),
                 BitConverter.ToInt16(OutputBuffer, PresetIDOffset + 4),
                 BitConverter.ToInt16(OutputBuffer, PresetIDOffset + 6),
                 BitConverter.ToInt16(OutputBuffer, PresetIDOffset + 8)));

            // Break the Platform ID down into 2-digit hexadecimal numbers
            // and append them to the Preset ID. This will result in a
            // string-formatted Device ID
            for (int i = PlatformIDOffset;
                 i < PlatformIDOffset + PlatformIDSize;
                 i++)
            {
                sb.Append(String.Format("{0:X2}", OutputBuffer[i]));
            }

            // return the Device ID string
            return sb.ToString();
            //return ShortDeviceId;
         }

    }
 

Usage :  string DeviceSerial = DeviceId.GetDeviceID(); // get the device ID   

7) Enable & Disable Touch, Solving of Double Click Issue
 The Detail about this already explained in this post click here
 

There are still many logics in .NET CE I would share as soon as I have a time to write.
Hope you have benefitted.

No comments: