DCSIMG
Question from .Net Tapuz forum: Drawing with a mouse/Stylus in Windows Forms 2.0 (not using GDI+) - Justin myJustin = new Justin( Expriences.Current );

Question from .Net Tapuz forum: Drawing with a mouse/Stylus in Windows Forms 2.0 (not using GDI+)

איך אפשר להשתמש בעכבר או בעט סטיילוס (במחשבי Tablet) כדי לצייר ב-Windows Forms?

ציור על המסך באמצעות עזרים חיצוניים (עכבר במקרה של מחשבים שולחניים או ציור באמצעות לחיצות על המסך במקרה של Tablet Pc) הוא מנת חלקם של מחשבי Tablet.

יש DLL דוט-נטי בשם Microsoft.Ink.DLL שבא עם ההתקנה של Tablet PC SDK.
כחלק מה-DLL המסתורי הזה, מגיעים כמה מחלקות מעניינות מאוד שמאפשרות לנו "לצייר על פקדים".

נוריד את ה-SDK מכאן - http://www.microsoft.com/downloads/details.aspx?FamilyId=B46D4B83-A821-40BC-AA85-C9EE3D6E9699&displaylang=en.

נפתח פרוייקט WinForms חדש.

כדי להשתמש ב-DLL נוסיף Refference חדש לפרוייקט ל - Microsoft Tablet PC API.

עכשיו, נוסיף לטופס שלנו Panel רגיל לחלוטין שעליו החלטתי שנצייר.

נשתמש ב-Microsoft.Ink.InkOverlay.
InkOverlay הוא בדיוק כמו שהוא נשמע - מאפשר ציור מעל פקד גרפי מסויים.
ניצור מופע של InkOverlay ברמת הטופס, נקבע שהוא עובד על ה-Panel שלנו ובנוסף לדאוג לבצע Dispose שלו בסגירת הטופס כדי להימנע מזליגות זכרון.

 

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Text;

using System.Windows.Forms;

 

using Microsoft.Ink;

 

namespace WinTesting

{

    public partial class Form15 : Form

    {

        public Form15()

        {

            InitializeComponent();

        }

 

        private InkOverlay panelOverlay;

        private void Form15_Load(object sender, EventArgs e)

        {

            panelOverlay = new InkOverlay(this.panel1);

            panelOverlay.Enabled = true;

        }

 

        private void Form15_FormClosing(object sender, FormClosingEventArgs e)

        {

            panelOverlay.Dispose();

        }

    }

}

מאוד פשוט יחסית, איתחלנו מופע של המחלקה שמכוון על ה-Panel וכל השאר זה מסביב (להתחיל את ה-InkOverlay, להיפטר ממנו, להוסיף Using).

בואו נראה את הטופס שלנו אחרי שציירתי עליו עם העכבר:

(אכן מסמך אנושי מזעזע)

אם נניח לרגע את כשרון הציור המינימלי שהפגנתי כאן, תסכימו איתי שהתמונה הזו קצת מכוערת - הכל בצבע שחור, העובי של הקווים אחיד והסוג של הקווים הוא קו מוצק.

נכיר מחלקה נוספת בשם DrawingAttributes. המחלקה הזו מכילה סט של מאפיינים (גם באנגלית: Properties) שקובעים את "העט" איתו אנו מציירים.
על InkOverlay יושב מאפיין בשם DefaultDrawingAttributes מסוג DrawingAttributes שדרכו נקבע את העט איתו אנו מציירים.

נרצה לשנות כמה פרטים מעניינים של העט שלנו דרך ה-GUI: הרוחב שלו, ה-Transperncy, צבע המברוש והאם הציור הוא Anti-Aliased.

קבענו את הערכים ברירת המחדל בתוך הפקדים השונים שלנו.

נחבר עכשיו את האירועים שלהם לשינויים של ה-Drawing Attributes.

        private void cbxAntiAlias_CheckedChanged(object sender, EventArgs e)

        {

            panelOverlay.DefaultDrawingAttributes.AntiAliased = cbxAntiAlias.Checked;

        }

 

        private void numWidth_ValueChanged(object sender, EventArgs e)

        {

            panelOverlay.DefaultDrawingAttributes.Width = float.Parse(numWidth.Value.ToString());

        }

 

        private void numTransperncy_ValueChanged(object sender, EventArgs e)

        {

            panelOverlay.DefaultDrawingAttributes.Transparency = byte.Parse(numTransperncy.Value.ToString());

        }

התחברנו לאירועים השונים של התערבות משתמש ב-GUI (לחיצה על ה-CheckBox או שינוי ערך ב-NumericUpDown) ושנינו את הערך הרלוונטי שלהם ב-DrawingAttributes לערך הנוכחי בפקד.

נוסיף גם טיפול בשינוי צבע באמצעות ה-ColorDialog שהוא דיאלוג שמאפשר למשתמש לבחור צבע מתוך הדיאלוג הסטנדרטי של חלונות.

        private void btnSetColor_Click(object sender, EventArgs e)

        {

            using (ColorDialog dlg = new ColorDialog())

            {

                if (dlg.ShowDialog() == DialogResult.OK)

                    panelOverlay.DefaultDrawingAttributes.Color = dlg.Color;

            }

        }

פתחנו דיאלוג חדש ואם נבחר צבע - נשנה את הצבע של ה-DrawingAttributes לצבע שנבחר.

(כן, זה בהחלט מסוג הדברים שנהוג לראות את הילדה בת ה-3 של ליאור מציירת)

 

נראה דבר אחד אחרון - יצירת פונקציונליות Undo ללוח הציור שלנו.

בשביל כפתור ה-Undo נצטרך להבין מהי מחלקת ה-Stroke.
כל קו כזה שציירנו (כל משיכה של המכחול באנאלוגיה) מייצר מופע של מחלקה בשם Stroke שמתווספת לאוסף Stroke הקיים על ה-InkOverlay. האוסף הזה הוא קצת יותר מאוסף בנאלי של Stroke. אלא הוא מחלקה בשם Ink שיושבת על InkOverlay ומאפשרת לנו למחוק, להוסיף ולגשת לאוסף ה-Stroke בציור שלנו.

נצייר במשיכת מכחול ראשונה (בלי שנרים את העכבר) את המספר 1.
ובמשיכת מכחול שנייה נצייר את המספר 2.

כעת באוסף ה-InkOverlay.Ink.Strokes שלנו יש שני Strokes.

נכתוב קוד שמוציא מהאוסף את ה-Stroke האחרון שנוסף, מוחק אותו ומורה על ציור מחדש של הפנאל.

        private void btnUndo_Click(object sender, EventArgs e)

        {

            Stroke strokeToDelete = panelOverlay.Ink.Strokes[panelOverlay.Ink.Strokes.Count - 1];

            panelOverlay.Ink.DeleteStroke(strokeToDelete);

            panel1.Invalidate();

        }

ובאמת בלחיצה על ה-Undo נקבל שיש Stroke אחד פחות על המסך.

למעשה ה-Strokes נותנות לנו מה שמוכר בתוכנות ציור מודרניות כ-Layers.

 

ניתן להוריד את קוד המקור שעבדנו עליו כאן - http://www.JustinAngel.Net/Files/WinformsPainting.zip.

Published Sunday, June 03, 2007 2:01 PM by Justin-Josef Angel [MVP]

Comments

No Comments