C# – Viết chương trình đóng mở ổ CD với MCI

Trong ví dụ trước ta đã làm một ví dụ về chương trình Media Player sử dụng các lệnh MCI. Ngoài các chức năng đó, MCI có thể dùng để điều khiển ổ đĩa mở hoặc đóng lại. Cách thực hiện cũng tương tự, chỉ cần một dòng lệnh. Vì thế để cho chương trình không quá đơn điệu ta sẽ thể thêm một số chức năng phụ vào, cụ thể như sau:


Auto Hide (tự động ẩn)

Always On top (luôn nổi cửa sổ trên cùng)

Auto Startup (tự khởi động chương trình khi đăng nhập vào Windows)

I)      Thiết kế

Trước tiên bạn hãy thiết kế giao diện tương tự như trên, đặt thuộc tính FormBorderStyle là None để giấu đi thanh tiêu đề.

Tạo một ContextMenuStrip như trên đặt thuộc tính CheckOnClick là true cho các item cần thiết

và chọn nó trong thuộc tính ContextMenuStrip của một NotifyIcon bạn sẽ thêm vào.

Trong form chính, hãy viết đoạn code sau vào đầu lớp để sử dụng được hàm mciSendString:

[DllImport(“winmm.dll”)]

private static extern long mciSendString(string strCommand,

StringBuilder strReturn, int iReturnLength, IntPtr hwndCallback);

1)      Thiết lập vị trí chương trình khi khởi động

Để chương trình lúc khởi động sẽ nằm ở vị trí góc phải bên dưới của màn hình, ta thêm đoạn mã sau vào sự kiện Form Load :

Point p = new Point(Screen.PrimaryScreen.Bounds.Right – this.Width,

Screen.PrimaryScreen.Bounds.Bottom – this.Height-30);

this.Location = p;

Đoạn mã trên sẽ lấy vị trí bên phải của màn hình chính (lớp Screen có thể trả về tất cả màn hình mà hệ thống của bạn hiện có) trừ đi chiều rộng của form để tính ra vị trí Left, tương tự với Top nhưng sẽ trừ đi 30 để cửa sổ sẽ nằm bên trên taskbar.

Bởi vì số 30 (ước lượng cho chiều cao của taskbar) chỉ là tương đối, nó có thể không giúp chương trình nằm đúng vị trí một cách chính xác trên màn hình nếu như bạn thay đổi taskbar chiều cao taskbar. Nếu muốn tính được chiều cao thật sự của taskbar, trong các ngôn ngữ lập trình trước như VB6 hoặc VC++6 bạn phải sử dụng các hàm thư viện API để lấy thông tin của taskbar như hàm SystemParametersInfo. Trong C# dĩ nhiên bạn có thể dùng cách này, nhưng bạn có thể làm nó đơn giản hơn bằng cách sau:

int taskBarHeight = Screen.PrimaryScreen.Bounds.Bottom – Screen.PrimaryScreen.WorkingArea.Bottom;

Như bạn có thể thấy, câu lệnh trên chỉ đơn giản lấy vị trí dưới cùng của toàn bộ màn hình(bao gồm cả thanh taskbar) trừ đi vị trí dưới cùng của phần màn hình làm việc(không bao gồm taskbar).

Bây giờ bạn có thể chèn thêm và thế biến taskBarHeight thay cho số 30 trong đoạn mã phía trên.

Tuy nhiên đến đây, có thể bạn sẽ nhận thấy một sự dư thừa và máy móc không cần thiết. Trên thực tế không ai làm như cách trên cả. Cuối cùng đoạn mã của ta chỉ còn như sau:

Point p = new Point(Screen.PrimaryScreen.WorkingArea.Right – this.Width,

Screen.PrimaryScreen.WorkingArea.Bottom- this.Height);

this.Location = p;

(* Đoạn mã chỉ áp dụng cho trường hợp taskbar nằm ở phía dưới màn hình, tuy nhiên bạn có thể áp dụng một số phép tính để xác định vị trí của taskbar).

2)      Mở và đóng ổ CD

Vấn đề đơn giản đầu tiên chúng ta đã giải quyết xong, tiếp theo chúng ta sẽ vào phần chính của chương trình. Và nếu từng đọc qua cách sử dụng MCI qua bài viết trước thì bạn có thể đoán rằng những gì bạn sắp đọc cũng không quá khó hiểu:

private void btnOpenClose_Click(object sender, EventArgs e)

{

Cursor.Current = Cursors.WaitCursor;

if (btnOpenClose.Text == “&Mở”)

{

mciSendString(“set cdaudio door open”, null, 0, IntPtr.Zero);

btnOpenClose.Text = “&Đóng”;

}

else

{

mciSendString(“set cdaudio door closed”, null, 0, IntPtr.Zero);

btnOpenClose.Text = “&Mở”;

}

}

Vì việc mở/đóng CD có thể mất một khoảng thời gian chờ nên ta sẽ đặt con trỏ chuột sang trạng thái chờ cho đến khi hoàn tất tác vụ:

Cursor.Current = Cursors.WaitCursor;

3)      Tự động ẩn:

Mô tả: Khi con trỏ chuột không nằm trên cửa sổ trong một khoảng thời gian nào đó, chương trình sẽ tự động di chuyển sang phải cho đến khi ra ngoài màn hình.

Chúng ta sẽ dùng Timer cho việc này, giả sử bạn muốn chương trình chờ 2 giây trước khi bắt đầu di chuyển, hãy gán Interval của Timer là 2000, khi tiến hành di chuyển ta sẽ giảm Interval của Timer xuống với tốc độ phù hợp. Các đoạn mã sau đây khá đơn giản nên tôi sẽ không giải thích, tùy vào ý định bạn có thể thay đổi cho phù hợp:

private void timer1_Tick(object sender, EventArgs e)

{

if (timer1.Interval > 100)

timer1.Interval = 100;

if (this.Left < Screen.PrimaryScreen.Bounds.Width)

this.Left += 5;

else

timer1.Enabled = false;

}

private void Form1_MouseEnter(object sender, EventArgs e)

{

this.Left = Screen.PrimaryScreen.Bounds.Width – this.Width;

timer1.Enabled = false;

}

private void Form1_MouseLeave(object sender, EventArgs e)

{

if (autoHideToolStripMenuItem.Checked)

timer1.Enabled = true;

}

Có một vấn đề nhỏ phát sinh khi bạn di chuyển chuột vào/ra các control của Form, ví dụ như khi bạn để chuột trên một Button hay bạn di chuyển chuột khỏi Button mà không qua Form (hoặc với tốc độ quá nhanh).  Bạn có thể giải quyết vấn đề này bằng cách viết các lệnh tương tự cho sự kiện MouseEnter và MouseLeft của các control. Cách đơn giản bạn ghi thêm vào trong sự kiện Form Load như sau:

foreach (Control ctl in this.Controls)

{

ctl.MouseEnter += new System.EventHandler(this.Form1_MouseEnter);

ctl.MouseLeave+= new System.EventHandler(this.Form1_MouseLeave);

}

Bởi vì Form của tôi không chứa các container khác (như Panel, GroupBox) nên vòng foreach sẽ lần lượt lặp qua tất cả các control. Nếu chương trình của bạn có chứa các container, hãy viết ra hàm riêng và sử dụng đệ qui cho mỗi control lặp qua.

-Tận dụng cả 3 nút chuột để sử dụng NotifyIcon.

private void notifyIcon1_MouseClick(object sender, MouseEventArgs e)

{

if (e.Button == MouseButtons.Left)

{

this.Left = Screen.PrimaryScreen.Bounds.Right- this.Width;

this.Activate();

timer1.Enabled = true;

timer1.Interval = 2000;

}

else if (e.Button == MouseButtons.Middle)

{

btnOpenClose_Click(null, null);

}

}

4)      Tự khởi động khi đăng nhập hệ thống :

Phương pháp:

Cách đơn giản, thông thường nhất và cũng “hợp pháp” để đăng kí chương trình tự khởi động là tạo khóa trong registry. Có nhiều khóa bạn có thể lựa chọn, nhưng vì 3 tiêu chí trên bạn được khuyến cáo nên chọn khóa sau:

HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run

Vì đây là kiến thức cơ bản về Windows nên tôi sẽ không giải thích kĩ, chủ yếu là phần viết mã bạn có thể tìm được câu trả lời trong đó nếu như còn thắc mắc.

Ta sẽ viết lệnh cho một ToolStripMenuItem giả sử có cái tên khá dài là autoStartupToolStripMenuItem. Nhiệm vụ của bạn là khi menuItem này được chọn thì chương trình sẽ ghi một String Value vào khóa trên với tên tùy chọn và giá trị là đường dẫn đến chương trình, khi bỏ chọn thì String Value này sẽ bị xóa đi như chưa từng xuất hiện.

Để thao tác được với Registry bạn cần thêm namespace Microsoft.Win32 vào. Về cách sử dụng các và thao tác với Registry tôi có thể sẽ trình bày trong những bài sau.

private void autoStartupToolStripMenuItem_Click(object sender, EventArgs e)

{

if (autoStartupToolStripMenuItem.Checked)

{

Registry.SetValue(@”HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run”,

Application.ProductName, Application.ExecutablePath);

}

else

{

try

{

RegistryKey regKey= Registry.CurrentUser.OpenSubKey(@”Software\Microsoft\Windows\CurrentVersion\Run”, true);

regKey.DeleteValue(Application.ProductName);

regKey.Close();

}

catch { }

}

}

–  Application.ProductName: tên của sản phẩm, trùng với tên của dự án khi bạn tạo, bạn có thể thay đổi nó trong Assembly Information. (Ở đây bạn nên sử dụng tên cho giá trị sẽ ghi là ProductName, để tiện thay thế và dễ nhớ)

Application.ExecutablePath: trả về đường dẫn đến tập tin thực thi của chương trình.

Bước tiếp theo bạn cần thực hiện là khi khởi động, chương trình sẽ kiểm tra xem giá trị registry trên đã tồn tại chưa và đánh dấu chọn vào menuItem này nếu giá trị này tồn tại. Bạn có thể sử dụng cách này để lưu các thiết lập của chương trình vào regedit như các chương trình khác thường làm. Thêm vào sự kiện Form Load:

bool autoStartup=Registry.GetValue(

@”HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run”, Application.ProductName,null)!=null;

autoStartupToolStripMenuItem.Checked = autoStartup;

II)  Phần kết

Có vẻ đây là một bài khá dài so với những gì mà kết quả của nó có thể làm được. Tuy nhiên một số điều có thể giúp ích cho bạn từ những gì tôi trình bày. Như những bài trước, chương trình trên chưa thực sự hoàn thành, bạn hãy kết thúc 10% còn lại nếu bạn không cảm thấy nó quá đơn giản.

http://yinyang-it.tk

14/6/2009

Advertisements

2 thoughts on “C# – Viết chương trình đóng mở ổ CD với MCI

Trả lời

Mời bạn điền thông tin vào ô dưới đây hoặc kích vào một biểu tượng để đăng nhập:

WordPress.com Logo

Bạn đang bình luận bằng tài khoản WordPress.com Đăng xuất / Thay đổi )

Twitter picture

Bạn đang bình luận bằng tài khoản Twitter Đăng xuất / Thay đổi )

Facebook photo

Bạn đang bình luận bằng tài khoản Facebook Đăng xuất / Thay đổi )

Google+ photo

Bạn đang bình luận bằng tài khoản Google+ Đăng xuất / Thay đổi )

Connecting to %s