有需求或技術問題可以隨時跟我連絡 (MSN上線時)

2009年8月20日 星期四

螢幕結取與鍵盤HOOK 程式修正

剛剛測試了一下程式,發現記憶體越吃越兇...

於是修正一下程式

打開Source Code Form1.cs 修正底下(粗體字部分 請新增即可)

private void timer_Capture_Tick(object sender, EventArgs e)
{
    Bitmap bmpScreenshot = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
    Graphics gfxScreenshot = Graphics.FromImage(bmpScreenshot);
    gfxScreenshot = Graphics.FromImage(bmpScreenshot);  
    gfxScreenshot.CopyFromScreen(Screen.PrimaryScreen.Bounds.X, Screen.PrimaryScreen.Bounds.Y, 0, 0, Screen.PrimaryScreen.Bounds.Size, CopyPixelOperation.SourceCopy);  
    string FileName = Path.Combine(textBox_FolderName.Text,string.Format(@"{0}.jpg", DateTime.Now.Ticks.ToString()));
    bmpScreenshot.Save(FileName, System.Drawing.Imaging.ImageFormat.Png);
    bmpScreenshot.Dispose();
    gfxScreenshot.Dispose();
}
private void timer_checkESC_Tick(object sender, EventArgs e)
{
    Application.DoEvents();
    GC.Collect();
    if (StopFlg)
        EndProcess();
}

不想修改者,這裡直接下再使用...

程式[MD5 : baac548d02f802c73640f5feda7a53a6]



鍵盤 Hook的應用

上篇文章提到Keyboard Hook,一般都會以為只能用在一些Hack程式(鍵盤側錄...),但是有很多程式是需要這個Keyboard Hook的支援,特別是那些失去Focus時候的應用程式,無法用KeyDown Event捕捉使用者的訊息,所以想要透過鍵盤的操控(快速鍵)達到"開始" ”停止" “擷取"……都可以透過這個方式達到目的.

底下是我寫的一個範例:

用途:全螢幕擷取程式,使用者可以設定圖檔存放處,擷取頻率...

當使用這按下[開始],程式最小化開始進行擷取,一直當使用者按下[Esc]就立即停止擷取,並將程式帶至桌面前景...

2009-8-20 下午 01-35-25

2009-8-20 下午 01-42-18

重要程式片段:

private void button_Start_Click(object sender, EventArgs e) 

     if (m_HookHandle == 0) 
         { 
             using (Process curProcess = Process.GetCurrentProcess()) 
             using (ProcessModule curModule = curProcess.MainModule) 
             { 
                 m_KbdHookProc = new HookProc(Form1.KeyboardHookProc); 
                 m_HookHandle = SetWindowsHookEx(WH_KEYBOARD_LL, m_KbdHookProc, GetModuleHandle(curModule.ModuleName), 0); 
             } 
             if (m_HookHandle == 0) 
             { 
                 MessageBox.Show("呼叫 SetWindowsHookEx 失敗!"); 
                 return; 
             } 
             StartProcess(); 
         } 
}

private static int KeyboardHookProc(int nCode, IntPtr wParam, IntPtr lParam) 

        // 當按鍵按下及鬆開時都會觸發此函式,這裡只處理鍵盤按下的情形。 
        bool isPressed = (lParam.ToInt32() & 0x80000000) == 0; 
        if (nCode < 0 || !isPressed) 
        { 
            return CallNextHookEx(m_HookHandle, nCode, wParam, lParam); 
        }

        // 取得欲攔截之按鍵狀態 
        KeyStateInfo escKey = KeyboardInfo.GetKeyState(Keys.Escape); 
        if (escKey.IsPressed) 
        { 
            System.Diagnostics.Debug.WriteLine("ESC Pressed!"); 
            bool ret = UnhookWindowsHookEx(m_HookHandle); 
            if (ret == false) 
            { 
                MessageBox.Show("呼叫 UnhookWindowsHookEx 失敗!"); 
                return 0; 
            } 
            m_HookHandle = 0; 
            StopFlg = true; 
            return 0; 
        } 
        return CallNextHookEx(m_HookHandle, nCode, wParam, lParam); 
  }

程式 [MD5 : 3bf4c56247725d8437605e17189626ef]

 

Source Code [MD5 : 6301e4c7e651ffa46959259adbd21447]



2009年8月18日 星期二

鍵盤 Keyboard Hook

一個簡單的鍵盤Hook程式...

基本上都是Win32API兜出來的...

SetWindowsHookEx() , UnhookWindowsHookEx() , CallNextHookEx() , GetCurrentThreadId() ,GetModuleHandle()

目前只針對 Ctrl , Alt , Shift , F8 進行觸發後紀錄...

有興趣的人可以自行修改,底下有Source Code

2009-8-18 下午 10-22-23

2009-8-18 下午 10-22-42

Source Code ( MD5 : 7c32ae81d92a624111c655ea2a2bc196 )



C# 3.0 物件初始化的新方式 (Object Initializer)

看範例

定義Person類別

public class Person
{
    public string Name;
    public int Age;
    public int Height;
    public int Weight;
    public string Country;
    public string PhoneNo;

    //預設建構式 
    public Person() { }

    //建構式(1)
    public Person(string name)
    {
        this.Name = name;  
    }

    //建構式(2)
    public Person(string name, int age)
    {
        this.Name = name;
        this.Age= age; 
    }
}

C#2.0 初始化物件方式

//使用預設建構式初始化
Person Tony= new Person();
Tony.Name= "Tony";
Tony.Country = "Chinese";

//使用建構式(1)
Person Tony = new Person("Tony"); 

//使用建構式(2)
Person Tony = new Person("Tony ", 23);

C#3.0 初始化物件一個新方式(舊的也是沿用)

Person Mary = new Person

    Name= "Tony";
    Age= "23";
    Height=177;
    Weight=78;
    Country = "Chinese";
    PhoneNo= "07-3333333";
};

優點:

(1)程式的精簡
(2)提供類似建構式指定參數方式初始化物件
(3)可以任意呼叫所有公開的欄位或屬性,不需要刻意建立多個建構式

至於方不方便,見仁見智吧...

另外泛型也新增了類似的方式

C# 2.0之泛型語法建立之LIST
    List<string> models = new List<string>();
    models.Add("Kevin");
    models.Add("Mary");
    models.Add("Clare");
    models.Add("Joe");
    models.Add("Mark");

C# 3.0之集合初始化(Collection Initializer)建立之List集合
    List<string> Models= new List<string> { "Kevin", "Mary", "Clare", "Joe", "Mark" };




簡易MD5驗證程式

因為部落格中開始會有一些自己寫的程式或檔案可以提供下載並使用MD5驗證機制,所以就寫了一支簡單的MD5驗證程式提供使用...

使用介紹:

 2009-8-18 上午 10-31-39 2009-8-18 上午 10-32-09 2009-8-18 上午 10-32-312009-8-18 上午 10-38-372009-8-18 上午 10-41-26

程式: [MD5 : c3130b3057182ad2b4be4626cb16fd18]

 

Source Code : [MD5 : 52613fc671c60e086ca05a1cc14b4792]



2009年8月17日 星期一

Indexer(索引器) in C#

透過索引器機制,能夠讓你像陣列一樣的爲物件編寫索引值,這是屬性提供的一個有效率的方式來管理類別的實體資料,看以下範例

(1)建立Telephone Class

public class Telephnoe
{
    private string[] _telephone = new string[3];

    public string this[int index]
    {
        get
        {
            if(index >=0 || index < _telephone.Length)
             {
                 return _telephone[index];
             }
             return string.Empty;
         }
         set
         {
             if (index >= 0 || index < _telephone.Length)
             {
                 _telephone[index] = value;
             }
         }
     }
}

 

(2)建立Person Class

public class Person  
{  
      public string Name { get; set; }  
      public Telephone Telephones = new Telephone();  
}

使用範例:

// 宣告 Person 類別物件變數 Person  
Person myPerson = new Person();  
// 設定一般 Name 屬性,無法帶入參數  
person.Name = "王小明";  
// 設定可代入參數的 Telephones 屬性  
person.Telephones[0] = "07-3333333";  
person.Telephones[1] = "0960666333";  
// 讀取一般性 Name 屬性 
Console.WriteLine(person.Name); 
// 設定可代入參數的 Telephones 屬性 
Console.WriteLine(person.Telephones[0]); 
Console.WriteLine(person.Telephones[1]);

輸出結果:

王小明  
電話:07-3333333 
電話:0960666333



網站可下載檔案開始提供MD5檢查碼

爾後網站中可以下載的檔案,我都會提供MD5 Code,提供網友自行檢查檔案的正確性

提供一份保障...

2009-8-17 上午 11-42-29



2009年8月16日 星期日

MP3 Tag 修改程式

想必各位一定都有聽MP3的習慣,但是有時候MP3 Player所顯示的資訊是錯誤的,或者是亂碼,怎麼辦???

這時候你就會需要MP3 Tag修改軟體.

MP3的 TAG大概是這樣組成的

MP3 TagBody (檔案的最後128 Bytes為TAG) 編碼方式 :
(0—2)      3 bytes ==> "TAG"三個字,如果不是"TAG",則為MPEG File
(3—32)     30 bytes ==> 標題 (Title)
(33—62)   30 bytes ==> 演唱/奏者,藝術家 (Artist)
(63—92)   30 bytes ==> 專輯名稱 (Album)
(93—96)   4bytes   ==> 發行年份 (PubYear)
(97—126) 30 bytes ==> 註釋/附加/備註信息 (Comment)
(127)       1 byte  ==> 音樂型態 (Music Type)

ID3v1 ID3v11

根據上面的編碼原則,寫的一個Parser Class

2009-8-16 下午 09-27-45

MP3TagParser Class

 

應用程式畫面

2009-8-16 下午 09-28-46

Source Code



Int / String to Enum in C#

enum myEnum {…………}

From a string:

myEnum foo = (myEnum)Enum.Parse(typeof(myEnum), yourString);

From an int:

myEnum foo = (myEnum)yourInt;