예제 #1
0
 public static extern bool GetGUIThreadInfo(uint idThread, ref GUITHREADINFO lpgui);
예제 #2
0
        private void RefreshFakeWnd()
        {
            if (_refreshing)
            {
                return;
            }

            if (!User32.IsWindow(_fakeWindowHandle))
            {
                return;
            }

            _refreshing = true;
            var  ptSrc    = new POINT(0, 0);
            var  ptWinPos = new POINT(this.Left, this.Top);
            byte biAlpha  = 0xFF;
            var  stBlend  = new BLENDFUNCTION(BlendOp.AC_SRC_OVER, 0, biAlpha, BlendOp.AC_SRC_ALPHA);

            IntPtr hDC = User32.GetDC(_fakeWindowHandle);

            if (hDC == IntPtr.Zero)
            {
                _refreshing = false;
                Debug.Assert(false, "GetDC failed.");
                return;
            }

            IntPtr hdcMemory = Gdi32.CreateCompatibleDC(hDC);

            int nBytesPerLine = ((this.GetWidth() * 32 + 31) & (~31)) >> 3;

            var stBmpInfoHeader = new BITMAPINFOHEADER();

            stBmpInfoHeader.Init();
            stBmpInfoHeader.biWidth       = this.GetWidth();
            stBmpInfoHeader.biHeight      = this.GetHeight();
            stBmpInfoHeader.biPlanes      = 1;
            stBmpInfoHeader.biBitCount    = 32;
            stBmpInfoHeader.biCompression = CompressionType.BI_RGB;
            stBmpInfoHeader.biClrUsed     = 0;
            stBmpInfoHeader.biSizeImage   = (uint)(nBytesPerLine * base.Height);

            IntPtr pvBits  = IntPtr.Zero;
            IntPtr hbmpMem = Gdi32.CreateDIBSection(hDC, ref stBmpInfoHeader
                                                    , DIBColorTableIdentifier.DIB_RGB_COLORS, out pvBits, IntPtr.Zero, 0);

            Debug.Assert(hbmpMem != IntPtr.Zero, "CreateDIBSection failed.");

            if (hbmpMem != null)
            {
                var hbmpOld = Gdi32.SelectObject(hdcMemory, hbmpMem);

                var graphic = Graphics.FromHdcInternal(hdcMemory);

                graphic.DrawImage(this.BackgroundImage, 0, 0, GetWidth(), GetHeight());

                foreach (Control ctrl in this.Controls)
                {
                    if (!ctrl.Visible)
                    {
                        continue;
                    }

                    using (var bmp = new Bitmap(ctrl.Width, ctrl.Height))
                    {
                        var rect = new Rectangle(0, 0, ctrl.Width, ctrl.Height);
                        ctrl.DrawToBitmap(bmp, rect);

                        graphic.DrawImage(bmp, ctrl.Left, ctrl.Top, ctrl.Width, ctrl.Height);
                    }
                }

                GUITHREADINFO stGuiThreadInfo = new GUITHREADINFO();
                stGuiThreadInfo.Init();
                if (User32.GetGUIThreadInfo(Kernel32.GetCurrentThreadId(), ref stGuiThreadInfo))
                {
                    if (User32.IsWindow(stGuiThreadInfo.hwndCaret))
                    {
                        int   height  = stGuiThreadInfo.rcCaret.Bottom - stGuiThreadInfo.rcCaret.Top;
                        POINT ptCaret = new POINT(stGuiThreadInfo.rcCaret.Left, stGuiThreadInfo.rcCaret.Top);

                        User32.ClientToScreen(stGuiThreadInfo.hwndCaret, ref ptCaret);
                        User32.ScreenToClient(this.Handle, ref ptCaret);

                        graphic.DrawLine(new Pen(new SolidBrush(Color.Black)), ptCaret.X, ptCaret.Y, ptCaret.X, ptCaret.Y + height);
                    }
                }

                var szWin = new SIZE(this.GetWidth(), this.GetHeight());
                User32.UpdateLayeredWindow(_fakeWindowHandle, hDC, ref ptWinPos, ref szWin, hdcMemory, ref ptSrc, 0, ref stBlend, UpdateLayerWindowParameter.ULW_ALPHA);

                graphic.Dispose();
                Gdi32.SelectObject(hbmpMem, hbmpOld);
                Gdi32.DeleteObject(hbmpMem);
            }

            Gdi32.DeleteDC(hdcMemory);
            Gdi32.DeleteDC(hDC);

            _refreshing = false;
        }