Sean's Note: 6月 2012

2012年6月27日 星期三

[USB2.0] PNY Key Attache 16GB

PNY Key Attache 極致纖薄Q版鑰匙造型隨身碟16GB
PNY Key Attache 16GB













最近在 Y 購物上買了這款便宜的隨身碟 NT.259,拿到後

馬上格式化成 NTFS 16K,再用 CrystalDiskMark 3.0.1 跑效能測試,

發現讀的速度還不錯 23MB/s,不過寫也太爛了,只有 4.7MB/S,

感覺是平均市售隨身碟的一半速度...

果然還是一分錢一分貨阿!

不過這也不一定準,

實際存 2~3 G 的檔案時跑到 100M~20M 左右還不錯,

但存幾百M但檔案都很小又多時,速度還會掉到幾十 K...

評測結果

2012年6月26日 星期二

不要將 vector 做為參數傳遞至 DLL

最近用了 STL 的 vector 當作 DLL 裡的函式參數,讓 EXE 建立的 vector 給 DLL 做事,

結果發現一直莫名其妙的 Crash,原來 EXE 和 DLL 會有各自的記憶體存放靜態成員,

而大部分的 STL 物件類別都使用靜態成員資料(Static Data Member),所以就會造成 


Access Violation, Data Lost 甚至於 Crash。


參考資料:
http://www.cnblogs.com/mysunnyday/archive/2011/08/23/2150279.html
http://support.microsoft.com/default.aspx?scid=KB;en-us;q172396

2012年6月20日 星期三

[MFC] 將使用者設定儲存到 Key 裡

通常一個較好的使用者介面,會在程式關閉時,將使用者的狀態紀錄到系統裡,

等下次使用者開啟軟體時,再將狀態讀出,顯示使用者關閉前的狀態,

而我們可以透過幾個 Windows API 做到這樣的功能。

CWinApp::GetProfileInt
CWinApp::GetProfileString
CWinApp::WriteProfileInt
CWinApp::WriteProfileString

原本這些 API 會將狀態寫到 C:\Windows\XXX.INI 裡,也從這裡讀,

但在 MSDN 上已說這不是個好的方式,建議存放到 Registry Key 裡。


透過 SetRegistryKey(LPCTSTR lpszRegistryKey) 可以指定存放到 Registry Key 而非 INI 檔。


存放的路徑如下:
HKEY_CURRENT_USER\Software\<company name>\<application name>\<section name>\<value name>.


其實 SetRegistryKey 就是把 CWinAp::m_pszProfileName 成員變數設成你所設定的值,

否則預設是 XXX.INI。


注意: 如果是用 Win32 API 的 WriteProfileString 寫到的則是 C:\Windows\win.ini 裡。



2012年6月16日 星期六

[C/C++] public/protected/private 繼承

class A
{
      public:
      void print() {printf ("print() From class A\n");};
      protected:
      void print2() {printf ("print2() From class A\n");};
      private:
      void print3() {printf ("print3() From class A\n");};
      
};

class PublicB : public A
{
      public:
      int print() {printf ("print() From class B\n"); print2();};  // Redefine
      /* 注意: protected 的 print2() 雖被繼承下來, 但不為外人所用 */
      /* 注意: private 的 print3() 並沒有被繼承下來 */
};

class ProtectedB : protected A
{
      public:
      /* 注意: public 的 print() 雖被繼承下來, 但此時已變為 protected */
      /* 注意: protected 的 print2() 雖被繼承下來, 但不為外人所用 */
      /* 注意: private 的 print3() 並沒有被繼承下來 */
};

class PrivateB : private A
{
      public:
      void myPrint() {print(); print2();};      
      /* 注意: public 的 print() 雖被繼承下來, 但此時已變為 private */
      /* 注意: protected 的 print2() 雖被繼承下來, 但此時已變為 private */
      /* 注意: private 的 print3() 並沒有被繼承下來 */
};

int main()
{
    A clsA;
    clsA.print();
    //clsA.print2(); // Compiler Error! print2() is protected.
    
    PublicB clsB_pub;
    clsB_pub.print();
    //clsB_pub.print2(); // Compiler Error! print2() is protected.
    
    ProtectedB clsB_pro;
    //clsB_pro.print(); // Compiler Error! print() is protected.
    //clsB_pro.print2(); // Compiler Error! print2() is protected.
    
    PrivateB clsB_pri;
    clsB_pri.myPrint();

    system("pause");
}
  1. 首先,繼承的概念是,只有 public 和 protected 的成員函式或變數會被繼承下來,除了建構式 (Constructor)、解構式 (Constructor) 和 Copy Constructor 除外,還有 private 也不會。
    • public: 所有人都能使用。
    • protected: 只有自己和兒子 (Derived Class) 可以使用,外人不能使用。
    • private: 只有自己可以使用, 兒子 (Derived Class) 和外人皆不能使用。
  2. 倘若 B 以 public 方式繼承了 A,則存取修飾字 (Access Specifier) 保持相同,規則同 1。
  3. 倘若 B 以 protected 方式繼承了 A,則 A 的 public 和 protected 成員被以 protected 方式繼承,所以範例中的 Line:48, 49 則發生編譯錯誤,因為  protected 成員不為外人所用。
  4. 倘若 B 以 private 方式繼承了 A,  則 A 的 public 和 protected 成員被以  private 方式繼承 ,僅自身可使用 Line:31。

2012年6月8日 星期五

在 Google Blogger 中使用 SyntaxHighlighter 3.0.83

有時候想貼出美美的程式碼,卻不知道怎麼用,

在網路上發現了 SyntaxHighlighter 這個工具,支援 C、C++、Python、HTML、CSS 等等。

教學文章:
http://sharedderrick.blogspot.tw/2010/10/google-blogger-syntaxhighlighter-3083.html

不過並沒有提供 Objective-C 的支援,好在有熱心人士寫了一份放在 GitHub 上:

https://github.com/scottdensmore/ObjectiveCSyntaxHighlighter

Windows 7 電腦每天會在特定時間無預期的從睡眠狀態中喚醒

發現電腦休眠後,常常還是莫名的被喚醒。

後來才發現是 Media Center 在作怪。

http://support.microsoft.com/kb/979878/zh-tw

2012年6月7日 星期四

class 中的 const 成員函式

const 函式主要定義為不能改變 class 中的變數。
此外,const  物件 只能引用 const 函式。


class A
{
private:
      int number;
public:
      A(int value){number=value;};
      void const_f(void) const {/*number=1;*/}; // 不能對成員變數賦值
      void nonconst_f(void){number=1;};
};

int main()
{
    const A a(1);
    a.const_f();
    a.nonconst_f(); // 編譯錯誤: const 物件只能引用 const 函式
    return 0;  
}

2012年6月5日 星期二

把視窗移到最前面

試過了 BringToTop() 和 SetWindowsPos() 都沒什麼用。

SwitchToThisWindow() 有用,但不是想要的效果。

SetForegroundWindow() 有用,但不是每次都成功,

失敗時程式就會在工作列上閃阿閃的 (註 1)。

最後參考了這篇的第二段 code ,終於實現了需要的功能:
http://www.codeproject.com/Tips/76427/How-to-bring-window-to-top-with-SetForegroundWindo

最主要是 AttachThreadInput() 讓 SetForegroundWindow() 幾乎都能成功。


註 1: 利用 SPI_SETFOREGROUNDFLASHCOUNT 可以控制要閃的次數。
SystemParametersInfo( SPI_SETFOREGROUNDFLASHCOUNT, 0, 5, SPIF_SENDWININICHANGE | SPIF_UPDATEINIFILE);