2014-06-23

[Android] 將resource轉換成Bitmap (transforming drawable resource into Bitmap)

 private Bitmap decodeFile(int resId) {
     try {
         // decode image size
         BitmapFactory.Options o = new BitmapFactory.Options();
         o.inJustDecodeBounds = true;
         BitmapFactory.decodeResource(context.getResources(), resId, o);
         // Find the correct scale value. It should be the power of 2.
         final int REQUIRED_SIZE = 70;
         int width_tmp = o.outWidth, height_tmp = o.outHeight;
         int scale = 1;
         while (true) {
             if (width_tmp / 2 < REQUIRED_SIZE
                     || height_tmp / 2 < REQUIRED_SIZE)
                 break;
             width_tmp /= 2;
             height_tmp /= 2;
             scale++;
         }

         // decode with inSampleSize
         BitmapFactory.Options o2 = new BitmapFactory.Options();
         o2.inSampleSize = scale;
         return BitmapFactory.decodeResource(context.getResources(), resId, o2);
     } catch (Exception e) {
     }
     return null;
 }

2013-05-23

[MFC] 使用自訂的Cursor



1.將想要加入的Cursor(.cur檔)加入專案中
2.在類別下的MemberData中加入一個HCURSOR類別的成員(在此使用的名稱為 m_hNoDrop)

   protected:
      HCURSOR m_hNoDrop;

3.在類別建構子中加入以下指令

   m_hNoDrop = AfxGetApp()->LoadCursor( IDC_NODROP );

    註:IDC_NODROP為欲加入的cursor ID
4.在欲改變指標的區段加入

  SetCursor( m_hNoDrop  );

5.建立事件OnSetCursor:功能表中的View\MFC ClassWizard下,Object IDs選擇專案名稱,Messages選擇WM_SETCURSOR再選擇Add Function即可。

   BOOL Your_Project_Name::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) 
   {
      // TODO: Add your message handler code here and/or call default
      return true;
   }

註:1.須使該事件的回傳值為ture
     2.Your_Project_Name為您的專案名稱

[Qt]如何避免Qt所寫的dll被帶有參數的呼叫時造成的crash?

假設我們有一個由Qt所寫成的DLL, 當中有一個StartServer是這樣定義的:
extern "C"  MY_EXPORT  void  CALLBACK *StartServer(char* pcAddress, unsigned short uiPort, char* pcWorkingPath)
{
    if(g_pNewClass != NULL)
    {
        g_pNewClass->Start(pcAddress, uiPort, pcWorkingPath);
    }
    else
    {
        WriteDebug("g_pNewClass is NULL");
    }
    return g_pNewClass;
}
上述的CALLBACK很關鍵!!

2.而我們一般要呼叫dll的方式如下(以vc6為例):

 typedef void (CALLBACK* START)(char* , unsigned short , char* );
 START start = NULL;              
 start = (START)GetProcAddress(m_hMod, "StartServer");
 if(start == NULL)
 {
  //載入函數位置失敗
  TRACE("start not found");
 }
 else
 {
  start(m_pAddr, m_port,m_pWP);
 }


於是我們就會發現函數的位置無法取得,用Dependency Walker這套萬惡的工具一看DLL的內容才知道,
原來是Qt自己把函數的名字改掉了.

[名稱被改成了StartServer@12]



所以我們也要在GetProcAddress時將名字改成DLL內部所記載的:

start = (START)GetProcAddress(m_hMod, "StartServer@12");

如此一來就可以正確的傳值呼叫我們想要使用的函數啦!

[Qt]如何讓Qt建置的dll給其他語言使用

1.將 qtwinmigrate 安裝到Qt的目錄下


2.參照以下連結"windows下如何使用QT编写dll程序"進行設置


3.在dllMain前面加上敘述字MY_EXPORT以避免Qt把函數名稱改掉

#ifdef Q_WS_WIN
#define MY_EXPORT __declspec(dllexport)
#else
#define MY_EXPORT
#endif
extern "C" MY_EXPORT BOOL WINAPI DllMain( HINSTANCE hInstance, DWORD dwReason, LPVOID lpvReserved )
{
    ...
}


4.這樣就可以讓其他語言所撰寫的執行檔正常呼叫囉!


key words: QMfcApp, qtwinmigrate, dllMain, C++

2012-07-04

[Qt] QString, QByteArray與Char的互相轉換

第一種方式(比較難記):

QByteArray byteArray = "xxx";
QTextCodec *codec = QTextCodec::codecForName("KOI8-R");
QString string = codec->toUnicode( byteArray );

第二種方式:
QByteArray byte;
QString string(byte);
第二種方式是不是好記多了呢?:)
另外附上一些QString、QByteArray與char*的轉換方法
//char* -> QByteArray
char* str;
QByteArray byte(str);
//char* -> QString
char* str;
QString string(str);
//QByteArray -> char*
QByteArray byte;
char* str = byte.data();
//QString -> QByteArray 
QString string;
QByteArray byte = string.toAscii();

//QString -> char*
QString string;
char* str = qPrintable(string);


參考自此篇文章

2012-05-02

[Qt]如何利用QFtp的put()方法上傳檔案至ftp server


在Qt的說明文件中,已有QFtp的使用範例
但是該範例並沒有介紹put(),本文便會簡單的介紹put()的使用方法。

1.建立ftp通道
  使用以下指令便可以連結到想要的ftp server

   m_pftp = new QFtp(this);
   m_pftp->connectToHost("127.0.0.1");
   m_pftp->login("USER", "PASSWORD"); 

※"127.0.0.1"為ftp server的ip,當然也可以是domain name
※"USER"及"PASSWORD"分別為使用者的帳號和密碼

2.使用put方法上傳檔案
  在這邊我的做法是將欲上傳的檔案路徑都放在m_slUploadList這個QStringList變數中,再配合QFile與put()來上傳檔案。


   if(m_pftp->state() == QFtp::LoggedIn)
   {
        int iLoop = m_slUploadList.count();
        for(int index = 0; indexopen(QFile::ReadOnly);
           m_pftp->put(pFile, GetFileName(m_slUploadList[index]));
 }
   }

  其中

if(m_pftp->state() == QFtp::LoggedIn)


  這一行是在確定程式已經登入ftp中,不知為何若是將這個判斷是直接寫在 m_pftp->login("USER", "PASSWORD");這個指令之後,會造成這個if判斷為false,猜想應該是ftp需要一些登入的時間,所以如果一登入就進行判斷的話,會因為程式仍未登入ftp而判斷成false的情形。


  m_pftp->put(pFile, GetFileName(m_slUploadList[index]));


  因為m_slUploadList[index]裡面是存著路徑+檔名,所以需要另外一個函式來取出檔名,在這邊就野人獻曝順便提供一下GetFileName()的內容吧!

   QString GetFileName(QString NameWithPath)

   {

      int iLast = NameWithPath.lastIndexOf("/");

      QString strFileName;

      strFileName = NameWithPath.mid(iLast+1);

      return strFileName;

   }

2012-04-30

[Qt]關於QStringList的二三事


在QT中好用的字串陣列QStringList

這篇文章已經有介紹一些簡單的存取方式,
有興趣的可以前往該網頁觀看,
在這邊也會節錄一些常用的方法。

關於QStringList這個型別,
我們可以把他想成是一個Qt內建的字串陣列,
只是多了一些內建的函式可以使用而已。

加入字串到QStringList

我們可以使用"<<"運算子將字串加入QStringList中
ex:

 QStringList slFruitList;

 slFruitList << "apple" << "banana" << "cherry" ;

也可以使用insert方法將字串插入QStringList,被插隊的原始字串會自動往後移。
ex:
 slFruitList.insert(1, "guava");

 //原先的順序為apple, banana, cherry

 //新的順序為  apple, guava, banana, cherry

如果是要將字串加到QStringList的最後,則可以用append()這個函式。
ex:
 slFruitList.append("grape");

要加到最前面的話,則可以用prepend()。
ex:
 slFruitList.prepend("water");

從QStringList中取出字串

Qt提供了一個很簡單的方式,可以像使用陣列一樣來存取QStringList
ex:
 QString sTemp = slFruitList[0];

//將slFruitList中第一個字串指定給sTemp

但是如果你用的QStringList是宣告成指標的型式呢?很簡單,把星號和變數名稱先括起來就可以了!
ex:
 QStringList *slList = new QStringList;

 slList->append("a");

 slList->append("b");

 slList->append("c");



 QString sTemp = (*slList)[2]; // sTemp = c


2012-04-24

[Qt] 如何取得使用者設定資料夾(Application Data Folder)


由於windows有使用者帳號的觀念,
每個使用者的設定也不同,
因此如何獲得現在使用者的設定資料夾變成了一項各家語言一定會提供的服務。
而這個服務通常是使用變數的方式來解決的:
一般的windows操作或命令提示字元底下,
我們可以用%APPDATA%這個環境變數來直接取得Application Data這個資料夾的路徑。
例如:C:\Documents and Settings\xxx\Application Data
※xxx為目前的使用者名稱

在Qt內,我們則要借重QDir這個函式庫,才能取得使用者帳號的路徑了。
使用的方式很簡單:

1.

#include <QDir>
2.

QString strAppPath = QDir::homePath();
如此一來便可以使用strAppPath該字串來存取使用者帳號底下的目錄和檔案了(當然也包含了Application Data個資料夾囉~)。

Windows系統內建的常見環境變數


%ALLUSERSPROFILE%:All Users設定檔的資料夾位置。

%APPDATA%:目前使用者的Application Data資料夾位置。

%CD%:目前的工作資料夾。

%CLIENTNAME%:目前使用者的NETBIOS電腦名稱。

%CMDCMDLINE%:處理目前命令提示字元視窗命令的cmd.exe的完整路徑。

%CMDEXTVERSION%:目前Command Processor Extensions的版本。

%COMPUTERNAME%:電腦名稱。

%COMSPEC%::命令提示字元視窗的解譯程式路徑,通常與%CMDCMDLINE%相同。

%CommonProgramFiles%:Common Files資料夾的路徑。

%DATE%:目前的系統日期。

%ERRORLEVEL%:最近執行過的命令的錯誤碼;非零的值表示發生過的錯誤碼。

%HOMESHARE%:目前使用者共用資料夾的網路路徑。

%HomeDrive%:使用者目錄的磁碟機。

%HomePath%:使用者家目錄。

%LOGONSEVER%:目前使用者所登入的網路控制器名稱。

%NUMBER_OF_PROCESSORS%:電腦的處理器數量。

%OS%:作業系統名稱,其值固定為Windows_NT

%PATHEXT%:作業系統是為執行檔的副檔名。

%PROCESSOR_ARCHITECTURE%:處理器的架構名稱,例如x86。

%PROCESSOR_IDENTFIER%:說明處理器的文字(不一定會有此環境變數)。

%PROCESSOR_LEVEL%:處理器的model number。

%PROCESSOR_REVISION%:處理器的revision number。

%PROMPT%:目前解譯程式的命令提示字串。

%Path%:執行檔的搜尋路徑。

%ProgramFiles%:應用程式目錄,預設是C:\Program Files。

%RANDOM%:顯示0到32767之間的十進位整數亂數。

%SESSIONNAME%:連上終端伺服器的session names。

%SystemDirectory%:系統目錄,預設是C:\WINNT\System32或C:\WINDOWS\System32。

%SystemDrive%:系統磁碟機,預設是C:。

%SystemRoot%:系統根目錄,預設是C:\WINNT或C:\WINDOWS。

%TIME%:目前的系統時間。

%Temp%、%Tmp%:暫存檔目錄。

%USERPROFILE%:目前使用者的設定檔路徑。

%UserDomain%:包含使用者帳號的網域名稱,或者電腦名稱。

%UserName%:使用者帳號名稱。

%WinDir%:Windows目錄,預設是C:\WINNT或C:\WINDOWS。

轉載自此網頁

2012-04-10

[MFC] 改變Progress的顏色

使用以下語法即可改變Progress進度條的顏色:

    m_Pro1.SendMessage(PBM_SETBARCOLOR, 0, RGB(0, 0, 0));

其中:

     m_Por1為CProgressCtrl的名稱。
     RGB(0, 0, 0)改變裡面的數字可以讓ProgressBar變成不同的顏色,
     數值可以參考RGB配色表

 備註:
     CProgressCtrl的Member Function .SetBarColor無法在VC6中使用。

[MFC] 忽略esc與enter鍵,使其無法結束dialog

1.重載PreTranslateMessage事件
afx_msg BOOL PreTranslateMessage(MSG *pMsg);
2.在上述事件中,加入以下的code
BOOL CTestDlg::PreTranslateMessage(MSG* pMsg) 
{
   if(pMsg->message == WM_KEYDOWN)
   {
      switch(pMsg->wParam)
      {
         case VK_RETURN:
         case VK_ESCAPE:
              return true;
      }
   }
   return CDialog::PreTranslateMessage(pMsg);
}

如此即可避免程式執行中,因按下esc或enter而造成程式結束。

[Qt] 取得自己電腦的ip位置(ipv4)


先include下面兩個函式庫

#include <QHostInfo>
#include <QHostAddress>

然後在欲得到ip的程式碼區段加入以下的code

    QString ip;
    QHostInfo host = QHostInfo::fromName(QHostInfo::localHostName());
    foreach (QHostAddress address, host.addresses())
    ip = address.toString();

QString ip即為想得到的本機ip address

2012-04-09

[blog]如何在Blogger中顯示code區段

1.進入網誌後台設定頁面

2.選擇 '範本\修改HTML\繼續\'

3.將以下code加入至post區段中:

 .post pre {
  background: #F0F0F0 url(http://yourwebspace/Code_BG.gif) repeat-y scroll left top;
  border: 1px solid #CCCCCC;
  color: #333333;
  display: block;
  font-family: Courier New;
  font-size: 10pt;
  line-height: 120%;
  margin: 5px 0 0 20px;
  max-height: 200px;
  overflow: auto;
  padding: 10px 10px 10px 21px;
  width: 90%;
}

4.http://yourwebspace/即您的網路空間,這裡是指向程式碼區段左側的那條灰底圖。
5.之後只需在 source code前後加入<pre>和</pre>標籤即可!