05 January 2010

WinMo - Make Button

Assalamulaikum wbt..

Alhamdulliah masih lagi kite dpt bersua dlm tahun baru nie..Ok, xnak ckap byk sal greeting tahun baru org kapir nie, stret to the point. Seperti y dah dijanjikan ms post aku yg lepas, kali nie aku nk tnjuk how to make our very own control. One thing y mesti diingat adalah build control sndri y aku mksudkan adalah buat "component" dan bukannye User Control k. Kalu da sesape y agak x jelas ngn perbezaan dua bnde nie, leh tanya direct. Kalu nk bincang sal difference dua bnde nie, pnjag la plak, so out of the scope. Post lepas aku da terangkan kenapa perlunye wat control sendiri nie. Sebab utamanya adalah untuk dapatkan nice and good appealing UI dlm WinMo disebabkan default control y disediakan dlm .Net CF amat susah nk customize (nearly impossible la bro)..

"BUAT BUTTON SENDIRI
"

First, perlu di ingat semua control dlm .Net technologies asal nye dri 1 rectangle as the very basis starting point sepertimana asalnya protein adalah dripada asid amino. So, kite kne prepare 1 rectangle dlu and mksure gune overload utk set up property Left, Top, Height ngan Width. How and where to do it? haa, start dengan add class baru dlm project, n set kan die jadi public as well as inherit from Control as the base class. Control classes dlm .Net dh predefine sumer event handler like mouse down, mouse up, click, checked and etc.

protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
base.OnPaint(e);
}

After inherit dri class nie (bdak CS, bukak buku 113 blik ok) buat function Protected Override untuk OnPaint event. Some programmer may prefer OnRender event handler. Reason kenape gune OnPaint adalah event nie akn fire ms stiap mouse event berlaku, xkire la mouse down, click or preview. "base" adalah main control thread dlm form y kite gune. Part pling penting adalah ape nk isi kat dlm tue. Harus di ingat, ape y sgt kejam sal .Net nie adalah once kite dh override default function, kite kne responsible utk take care everything.

protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{

if (m_bmpOffscreen == null) //Bitmap for doublebuffering
{
m_bmpOffscreen = new Bitmap(ClientSize.Width, ClientSize.Height);
}

gxOff = Graphics.FromImage(m_bmpOffscreen);

base.OnPaint(e);
}

Declare 1 bitmap as a global variable (dlm kes aku = m_bmpOffscreen) sbb ia akn digunakan utk double buffering. Knpa double?? sbb untuk optimize system performance ms access thru GDI+ layer (.Net graphic engine ala ala OpenGL). Then declare gak 1 global variable type graphic (dlm kes aku = gxOff)..variable nie y akn reposible utk paint or draw control kite kat screen nnti. Variable type Graphic adalah bnde y responsible utk handle painting event sahaja. Dlm advanve situation, Graphic bleh di initialize dengan inherate dripada form painting event.

protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{

if (m_bmpOffscreen == null) //Bitmap for doublebuffering
{
m_bmpOffscreen = new Bitmap(ClientSize.Width, ClientSize.Height);
}

gxOff = Graphics.FromImage(m_bmpOffscreen);

if (bPushed)
{
gxOff.FillGradientRectangle(this.ClientRectangle, gradiantColorDefault[0], gradiantColorDefault[1], FillDirection.TopToBottom);
}
else
{
gxOff.FillGradientRectangle(this.ClientRectangle, gradiantColorPushed[0], gradiantColorPushed[1], FillDirection.TopToBottom);
}


base.OnPaint(e);
}

Next, kite perlu draw background color utk button kite. Caranye, gune gxOff td, n amik function fill gradient rectangle. Bagi parameter rectangle as a boundary (aku gune client rectangle), color ape nk gune and fill direction either top to bottom or left to right. By default, function nie xder pn dlm Graphic, korang kene include GDI+ API dlu (aku xinclude kat sini sbb byk sgt, termuntah plak korang nnti)..Ape fungdi bPushed?? Itu adalah simply boolean variable untuk aku indicate smada button tue tgah mouse down or mouse up. Ngn kate laen, mase button di tekan, draw kaler lain, ms xditekan, draw kaler laen plak.

protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{

if (m_bmpOffscreen == null) //Bitmap for doublebuffering
{
m_bmpOffscreen = new Bitmap(ClientSize.Width, ClientSize.Height);
}

gxOff = Graphics.FromImage(m_bmpOffscreen);

if (bPushed)
{
gxOff.FillGradientRectangle(this.ClientRectangle, gradiantColorDefault[0], gradiantColorDefault[1], FillDirection.TopToBottom);
}
else
{
gxOff.FillGradientRectangle(this.ClientRectangle, gradiantColorPushed[0], gradiantColorPushed[1], FillDirection.TopToBottom);
}

if (Text != "")
{
Font drawFont = new Font("Arial", 10, FontStyle.Regular);
SolidBrush drawBrush = new SolidBrush(Color.Black);
SizeF textSize = gxOff.MeasureString(Text, drawFont);
textRect = new Rectangle(((int)this.ClientRectangle.Width - (int)textSize.Width)/2,((int)this.ClientRectangle.Height - (int)textSize.Height)/2,this.Width,this.Height);
gxOff.DrawString(this.text, drawFont, drawBrush, textRect);
}

base.OnPaint(e);
}

After that, bese nye button ade text kan. So, skag kite akn draw string text kat screen plak sepertimana code kat atas nie. Ape y penting ialah kene specify Font dlu befora draw (dlm kes aku = drawFont) and also Brush color ape as a foreground color. Brush bleh accept beberapa overload, in case nk mcam2 kaler, tp make it simple, aku gune black jer. Function gxOff.MeasureString akan measure width and high bile string tue di draw kat screen berdasarkan Font y kite specify. Sbg contoh, font "Tahoma" ngn "Arial" maybe xsame even fontsize kedua-duanya adalah 10.

protected override void OnPaintBackground(PaintEventArgs e )
{
//Do nothing
}

Seperti y aku ckapkan td, once kite dh oeverride event, kite kene take over sumer bnde y berkaitan dengannya. Sbg contoh, kat atas nie aku override skali OnPaintBackground untuk mengelakkan image or graphic dri "flickering" since event nie akn fire whenever resize event rise up.

"LETAK EVENT HANDLER"

protected override void OnMouseDown(System.Windows.Forms.MouseEventArgs e)
{
bPushed = true;
this.Invalidate();
}

protected override void OnMouseUp(System.Windows.Forms.MouseEventArgs e)
{
bPushed = false;
this.Invalidate();
}

Last thing, letak event handler. Bnde nie depend coz sometimes aku purposely create control juz as a image viewer jer, xder nk click2. Da simplest way, gune cara y same iaitu override function y berkaitan since kite inherate dri base class y sama iaitu Control Classes. Cam code kat atas nie, override function Mouse Down ngn Mouse Up untuk change value bPushed td and automatically OnPaint event akan fire.

"WHATS NEXT"

Sekali lagi ucapkan - Welcome to Windows Mobile Development=)...haha..aniway, the nice thing bile develop dlm platform nie adalah aku byk blaja new programming skills y slama nie aku ignore jer. Contohnye penggunaan Override,Abstract Classes, Interface Classes n ofkos letak sendri event dan property2 kat control kite supaye org lain bleh access as simply as press Ctrl+Space bar..nice kan..selama nie kite tw tekan jer..tp skag nie, cmana nk wat sumer tue from scratch..

Any critics, suggestions and questions are welcome..

No comments:

Post a Comment

terima kasih.