Example #1
0
        /// <summary>
        /// フックプロシージャ
        /// </summary>
        /// <param name="nCode"></param>
        /// <param name="wParam"></param>
        /// <param name="lParam"></param>
        /// <returns></returns>
        private IntPtr HookProc(int nCode, IntPtr wParam, IntPtr lParam)
        {
            if (nCode == HCBT_ACTIVATE)
            {
                Commons.RECT rcForm   = new Commons.RECT(0, 0, 0, 0);
                Commons.RECT rcMsgBox = new Commons.RECT(0, 0, 0, 0);

                GetWindowRect(this.ownerWindow.Handle, out rcForm);
                GetWindowRect(wParam, out rcMsgBox);

                // センター位置を計算する。
                int x = (rcForm.Left + (rcForm.Right - rcForm.Left) / 2) - ((rcMsgBox.Right - rcMsgBox.Left) / 2);
                int y = (rcForm.Top + (rcForm.Bottom - rcForm.Top) / 2) - ((rcMsgBox.Bottom - rcMsgBox.Top) / 2);

                SetWindowPos(wParam, 0, x, y, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);

                IntPtr result = CallNextHookEx(this.hHook, nCode, wParam, lParam);

                // フックを解除する。
                UnhookWindowsHookEx(this.hHook);
                this.hHook = (IntPtr)0;

                return(result);
            }
            else
            {
                return(CallNextHookEx(this.hHook, nCode, wParam, lParam));
            }
        }
Example #2
0
        /// <summary>
        /// 文字列のインデックスに対応する表示座標を取得する(調整済み)
        /// FIXME: 無理矢理なので .NET Framework の実装によっては破綻する可能性あり
        /// </summary>
        /// <param name="textBoxRect">EM_GETRECT で取得した RECT 構造体</param>
        /// <param name="index">インデックス</param>
        /// <returns>調整済みの表示座標</returns>
        public Point GetFixedPositionFromCharIndex(Commons.RECT textBoxRect, int index)
        {
            Point pointOrig = this.GetPositionFromCharIndex(index);
            Point result    = new Point(pointOrig.X, pointOrig.Y);

            if (!this.Multiline)
            {
                result.Y += textBoxRect.Top;
            }

            return(result);
        }
Example #3
0
 private static extern bool GetWindowRect(IntPtr hWnd, out Commons.RECT lpRect);
Example #4
0
        /// <summary>
        /// 表示領域等を計算する(固定長のみ対応)
        /// FIXME: 文字末尾にタブがある場合の位置計算がおかしい
        /// </summary>
        /// <param name="graphics">Graphics</param>
        /// <param name="textBoxRect">テキストエリアの領域</param>
        /// <param name="baseFontSize">ベースとなるフォントサイズ</param>
        /// <returns>計算した領域情報</returns>
        private List <DrawDimension> CalcDrawDimensions(Graphics graphics, Commons.RECT textBoxRect, Size baseFontSize)
        {
            Size baseFontSizeHalf = TextRenderer.MeasureText(graphics, "A", this.displayFont, new Size(), this.textFormatFlags);

            string textBoxText     = this.Text;
            int    selectionStart  = this.SelectionStart;
            int    selectionLength = this.SelectionLength;

            // 描画対象の文字列インデックス範囲を得る
            int firstCharIndex = 0;
            int lastCharIndex  = textBoxText.Length;

            if (this.Multiline)
            {
                // 最初の位置を得る
                int firstVisibleLine = SendMessage(this.Handle, EM_GETFIRSTVISIBLELINE, 0, 0);
                if (0 <= firstVisibleLine)
                {
                    int firstIndex = this.GetFirstCharIndexFromLine(firstVisibleLine);
                    if (0 <= firstIndex)
                    {
                        firstCharIndex = firstIndex;
                    }
                }

                // 表示行数を得る
                int rows = this.ClientSize.Height / baseFontSize.Height;

                // 最後の位置を得る
                int lastIndex = this.GetFirstCharIndexFromLine(firstVisibleLine + rows);
                if (0 <= lastIndex)
                {
                    lastCharIndex = lastIndex;
                }
            }

            List <DrawDimension> drawDimensionList = new List <DrawDimension>();

            int columns  = 0;
            int prevLine = this.GetLineFromCharIndex(firstCharIndex);

            for (int chIndex = firstCharIndex; chIndex < lastCharIndex; ++chIndex)
            {
                if (chIndex < 0 || textBoxText.Length <= chIndex)
                {
                    break;
                }

                int currentLine = this.GetLineFromCharIndex(chIndex);

                string targetSChar = textBoxText.Substring(chIndex, 1);

                DrawDimension drawDimension = new DrawDimension(targetSChar);
                Point         point         = this.GetFixedPositionFromCharIndex(textBoxRect, chIndex);

                if (drawDimension.Type == DrawType.Emoji)
                {
                    drawDimension.Area = new Rectangle(point.X, point.Y, Commons.TEXT_ICON_WIDTH, Commons.TEXT_ICON_HEIGHT);
                    columns           += 2;
                }
                else if (drawDimension.Type == DrawType.ControlChar)
                {
                    drawDimension.Area = new Rectangle(point.X, point.Y, baseFontSizeHalf.Width, baseFontSizeHalf.Height);

                    if (drawDimension.OriginalChar == '\t')
                    {
                        int tabColumns = 8 - (columns % 8);

                        if (chIndex + 1 < textBoxText.Length)
                        {
                            Point pointNext = this.GetFixedPositionFromCharIndex(textBoxRect, chIndex + 1);
                            drawDimension.PaddingArea = new Rectangle(point.X + baseFontSizeHalf.Width, point.Y, pointNext.X - point.X - baseFontSizeHalf.Width, baseFontSizeHalf.Height);
                        }
                        else
                        {
                            int width = baseFontSizeHalf.Width * tabColumns - baseFontSizeHalf.Width;
                            drawDimension.PaddingArea = new Rectangle(point.X + baseFontSizeHalf.Width, point.Y, width, baseFontSizeHalf.Height);
                        }

                        columns += tabColumns;
                    }
                    else if (drawDimension.OriginalChar == '\n')
                    {
                        columns = 0;
                    }
                    else if (drawDimension.OriginalChar == '\r')
                    {
                        // 表示されないので columns には何もしない
                    }
                }
                else if (drawDimension.Type == DrawType.NormalChar)
                {
                    // NOTE: とりあえず固定長で考える
                    if (StringUtils.IsHalfSizeDisplay(targetSChar))
                    {
                        drawDimension.Area = new Rectangle(point.X, point.Y, baseFontSizeHalf.Width, baseFontSizeHalf.Height);
                        columns           += 1;
                    }
                    else
                    {
                        drawDimension.Area = new Rectangle(point.X, point.Y, baseFontSize.Width, baseFontSize.Height);
                        columns           += 2;
                    }
                }
                if (selectionStart <= chIndex && chIndex < selectionStart + selectionLength)
                {
                    drawDimension.Selection = true;

                    // 前行の文字末尾がタブの場合の処理
                    if (prevLine != currentLine && selectionStart <= chIndex - 1 && 0 < drawDimensionList.Count)
                    {
                        DrawDimension prevDrawDimension = drawDimensionList[drawDimensionList.Count - 1];
                        if (prevDrawDimension.OriginalChar == '\t')
                        {
                            Rectangle area = prevDrawDimension.Area;
                            prevDrawDimension.PaddingArea = new Rectangle(area.X + area.Width, area.Y, textBoxRect.Right - (area.X + area.Width), area.Height);
                        }
                    }
                }

                prevLine = currentLine;

                drawDimensionList.Add(drawDimension);
            }

            return(drawDimensionList);
        }
Example #5
0
 private static extern int SendMessage(IntPtr hWnd, int msg, int wParam, out Commons.RECT lParam);