示例#1
0
        public void Disconnect()
        {
            // Cancel read thread
            m_cancelTokenSource?.Cancel();

            // There may not be any received messages and it may be blocked by Read.
            // Therefore, send FramebufferUpdate so that the client sends a message.
            m_client?.WriteFramebufferUpdateRequest();

            // Wait for completion or timeout (5 second).
            m_readTask?.Wait(5 * 1000);

            // Disconnect
            m_client?.DisconnectVnc();

            // Execute to draw this control black.
            // Without this, the screen will not be updated and the VNC image will remain.
            NativeMethods.InvalidateRect(m_handle, (IntPtr)0, false);
        }
示例#2
0
        protected override void OnPaint(PaintEventArgs e)
        {
            if (DesignMode)
            {
                e.Graphics.DrawRectangle(Pens.DarkGray, 0, 0, this.Width - 1, this.Height - 1);
            }
            else
            {
                if (m_client != null && m_client.Connected)
                {
                    if (m_last.Enable)
                    {
                        m_client.WritePointerEvent(m_last.Mask, (UInt16)m_last.X, (UInt16)m_last.Y);
                        m_lastPointerSendDt = DateTime.Now;
                        m_last.Enable       = false;
                    }

                    // NearestNeighbor is the fastest.
                    e.Graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;

                    // At the time of connection, the background black is left, so erase it
                    if (!m_prevConnected)
                    {
                        m_prevConnected = true;
                        e.Graphics.Clear(this.BackColor);
                    }

                    // Lock to access below.
                    // - m_client.InternalCanvas
                    // - m_encodeList
                    lock (m_client.CanvasLock)
                    {
                        BitmapConverter.ToBitmap(m_client.InternalCanvas, (Bitmap)m_image);

                        // When the size changes, redraw it all.
                        // Or if the focus is lost, redraw it all.
                        if (m_prevSize.Width != this.Width || m_prevSize.Height != this.Height || m_needsRedraw)
                        {
                            m_prevSize.Width  = this.Width;
                            m_prevSize.Height = this.Height;
                            m_needsRedraw     = false;

                            // I could not draw correctly if the size was not an integer ratio.
                            // Therefore, find the integer ratio that the denominator becomes 10 or less.
                            m_xZoom = new Fraction(this.Width, m_client.ServerInitBody.FramebufferWidth, 10);
                            m_yZoom = new Fraction(this.Height, m_client.ServerInitBody.FramebufferHeight, 10);

                            int width  = (int)(m_client.ServerInitBody.FramebufferWidth * m_xZoom.Numerator / m_xZoom.Denominator);
                            int height = (int)(m_client.ServerInitBody.FramebufferHeight * m_yZoom.Numerator / m_yZoom.Denominator);

                            // Redraw  all
                            e.Graphics.DrawImage(m_image, 0, 0, width, height);
                        }
                        // If the size is the same, draw only the difference.
                        else
                        {
                            foreach (var list in m_encodeList)
                            {
                                foreach (var v in list)
                                {
                                    // To draw correctly, I calculate drawing source rectangle and drawing destination rectangle.
                                    // ex.
                                    //   Framebuffer = 640x480
                                    //   Control     = 320x240
                                    //   Source Rectangle(x,y,w,h) =  (101, 101, 10, 10)
                                    //                             => (100, 100, 12, 12) (Convert to be divisible)
                                    //   Dest   Rectangle(x,y,w,h) => (50,   50,  5,  5)
                                    int newX   = (int)(v.X / m_xZoom.Denominator) * m_xZoom.Denominator;
                                    int newY   = (int)(v.Y / m_yZoom.Denominator) * m_yZoom.Denominator;
                                    int newW   = (int)(Math.Ceiling((double)(v.Width + v.X - newX) / m_xZoom.Denominator) * m_xZoom.Denominator);
                                    int newH   = (int)(Math.Ceiling((double)(v.Height + v.Y - newY) / m_yZoom.Denominator) * m_yZoom.Denominator);
                                    int xpos   = newX * m_xZoom.Numerator / m_xZoom.Denominator;
                                    int ypos   = newY * m_yZoom.Numerator / m_yZoom.Denominator;
                                    int width  = newW * m_xZoom.Numerator / m_xZoom.Denominator;
                                    int height = newH * m_yZoom.Numerator / m_yZoom.Denominator;
                                    e.Graphics.DrawImage(m_image, new Rectangle(xpos, ypos, width, height), newX, newY, newW, newH, GraphicsUnit.Pixel);
                                }
                            }
                            m_encodeList.Clear();
                        }
                    }
                    m_client.WriteFramebufferUpdateRequest();
                }
                else
                {
                    m_prevConnected = false;
                    e.Graphics.FillRectangle(Brushes.Black, 0, 0, this.Width, this.Height);
                }
            }
        }