《PicSi的實現細節》 第3節 窗口類CPicSiCreatorDlg的定義

       這一節是本系列文章中最重要的部分,因爲CPicsiCreatorDlg類是Main子窗口的實現類,它是PicSi的功能主體。有了第2節作爲基礎,相信大多數朋友對CPicSiCreatorDlg的主框架是不陌生的。因此,本節將重點闡述關鍵思路,而代碼的實現細節不在文中說明了。我會在文章的末尾將所涉及的代碼貼出,若理解過程中碰到什麼問題或者疑問,可隨時提出。
      CPicsiCreatorDlg與CAboutDlg一樣,都是CDialogImpl的派生類。因此它也通過Create方法來創建實例對象;同時,它也有自己的消息映射,能夠處理窗口消息。
   題外話:可能有的朋友覺得類名CPicsiDreatorDlg太長,對的,我也覺得有點長。不過,好的命名規範是需要儘量做到見名知義的,名稱長點沒關係,Ctrl + C/V,一點都不慢,還不易出錯。
      首先看CPicsiCreatorDlg的成員變量,窗口類的成員變量一般分爲兩類:控制成員變量和數據成員變量。建議將它們分成兩團定義,而不要交叉定義,這樣可使代碼更清晰一些。
      控制成員變量很好理解,就是窗口中控制(控件)在類中對應的變量。我們總是通過控制成員變量來對控制加以維護的。數據成員變量是算法所需的變量,如本例中,m_fileList是一個鏈表,它用來保存文件名列表,而m_strOutputPath即輸出路徑字符串。
      接下來就需要定義若干方法來響應窗口消息了。Windows編程的本質就是“以消息爲基礎,事件驅動之(Message based and Event driven)”。也就是說,任何一個Windows程序,它的整個生命週期說白了就是在不停地捕獲消息,不停地調用方法對消息進行響應。因此,窗口類有着非常明顯的特點,其主體一定是消息映射和響應方法。同時,每個類又可能含有一些成員變量以及一些私有成員方法,供消息的響應方法使用或調用。當然,它也可以擁有少量的公共方法,供父窗口調用。
      每個窗口類都應該響應WM_INITDIALOG消息,窗口在被初始化時,它將被拋出,用OnInitDialog方法響應它,OnInitDialog將實現窗口相關的初始化。此外,如果窗口尺寸是可調整的話,WM_SIZE消息一般也需被處理,定義OnSize方法來響應該消息。在OnSize方法的末尾,將bHandled置爲FALSE,表示WM_SIZE消息並不被當前窗口類獨佔,它還可以被其它窗口處理。而return 1表示允許操作系統自己再對WM_SIZE做進一步的處理,比如重繪窗口背景;如果return 0的話,操作系統是不會做進一步操作的,這對於調整窗口大小來說,可能會造成程序異常。當然,大多數消息的響應方法返回值都應該是0。
      AddFile方法是CPicsiCreatorDlg類唯一一個public方法,它的作用是將szFilePath所指向的文件名添加到m_fileList鏈表中,並且在Listview控制中顯示該文件的名稱、尺寸、創建時間等信息。AddFile方法在程序中僅僅被主窗口調用,參見MainDlg::OnDropFIles方法。
      接下來就是依次響應控制消息:
  • IDC_BTN_SETPATH - 用戶單擊Set按鈕,設置輸出路徑;
  • IDC_BTN_OPEN - 用戶單擊Open按鈕,打開輸出目錄;
  • IDC_BTN_CLEAR - 用戶單擊Clear按鈕,清空文件列表;
  • IDC_BTN_OK - 用戶單擊Open按鈕,開始生成內涵圖;
  • IDC_LIST_ORDINARY通知消息NM_DBLCLK - 用戶在Listview控制中雙擊鼠標左鍵,打開選中的文件;
  • IDC_LIST_ORDINARY通知消息NM_RCLICK - 用戶在Listview控制右擊鼠標,彈出右鍵菜單;
  • ID_POP1_OPEN - 用戶選中右鍵菜單項Open,打開選中的文件;
  • ID_POP1_DELETE - 用戶選中右鍵菜單項Delete,刪除選中的文件;
  • ID_POP1_UP - 用戶選中右鍵菜單項Up,將選中的文件往上移一位;
  • ID_POP1_DOWN - 用戶選中右鍵菜單項Down,將選中的文件往下移一位;
  • ID_POP1_TOP - 用戶選中右鍵菜單項Top,將選中的文件置頂;
  • ID_POP1_BOTTOM - 用戶選中右鍵菜單項Bottom,將選中的文件置底。
      簡要說明一下CPicsiCreatorDlg類中的私有方法:
  • get_appdata_path - 獲得PicSi配置文件在AppData目錄的全路徑,配置文件裏保存着輸出路徑(output path)。
  • read_output_path - 從PicSi配置文件中讀取輸出路徑並保存到m_strOutputPath成員變量中。
  • write_output_path - 將輸出路徑字符串m_strOutputPath寫入PicSi配置文件中。
  • IsValid - 當用戶單擊OK按鈕後,程序將首先檢查文件列表是否符合規則“至少兩個文件,首個文件必須是jpg文件”,只有再確認之後再正式生成內涵圖。IsVaild起到檢查文件列表是否符合規則的作用。
  • get_rar_exe_path - 獲得rar.exe文件的全路徑,rar.exe用於壓縮文件。
  • get_copy_bat_path - 獲得copy.bat文件的全路徑,copy.bat包含copy命令,拼接jpg和rar文件,製作內涵圖。
  • get_temporary_rar_path - 獲得臨時rar文件的路徑。
  • delete_temporary_rar - 刪除臨時rar文件。
  • build_rar_command_line - 裝配rar.exe命令。
  • build_copy_command_line - 裝配copy命令。
  • execute_subprocess - 執行子進程,傳入參數即命令行字符串。
  • shell_open_selected_file - 打開被選中的文件。
  • refresh_list_view - 刷新Listview。
CPicSiCreatorDlg窗口類的所有代碼如下所示:
// CPicsiCreatorDlg

class CPicsiCreatorDlg : public CDialogImpl<CPicsiCreatorDlg>
{
private:
	CButton m_btnOK;
	CButton m_btnClear;
	CStatic m_static;
	CEdit m_editPath;
	CButton m_btnSet;
	CButton m_btnOpen;
	CListViewCtrl m_list;

	ATL::CAtlList<WTL::CString> m_fileList;
	WTL::CString m_strOutputPath;

public:
	enum { IDD = IDD_DLG_CREATOR };

	void AddFile(LPCTSTR szFilePath) throw()
	{
		ATLASSERT(szFilePath != NULL);
		POSITION pos = m_fileList.GetHeadPosition();
		// check if alreay added
		while(pos != NULL) {
			WTL::CString strFilePath = m_fileList.GetAt(pos);
			if(::lstrcmpi(szFilePath, strFilePath) == 0) {
				WTL::CString strMsg = _T("You have already added file \"");
				strMsg += szFilePath;
				strMsg += _T("\"!");
				PS_MessageBox(strMsg, MB_ICONWARNING);
				return;
			} // end if
			m_fileList.GetNext(pos);
		} // end while
		int nCount = m_list.GetItemCount();
		WTL::CString strFilename;
		PS_GetFilename(szFilePath, strFilename);
		m_list.AddItem(nCount, 0, strFilename);
		// add size
		OFSTRUCT os;
		HANDLE hFile = (HANDLE)::OpenFile(::CT2A(szFilePath), &os, OF_READ);
		BY_HANDLE_FILE_INFORMATION fileinfo;
		::GetFileInformationByHandle(hFile, &fileinfo);
		TCHAR szSize[20];
		_stprintf_s(szSize, _T("%d KB"), fileinfo.nFileSizeLow / 1024);
		m_list.AddItem(nCount, 1, szSize);
		// add creation time
		SYSTEMTIME st;
		FileTimeToSystemTime(&fileinfo.ftCreationTime, &st);
		TCHAR szCreationTime[24];
		_stprintf_s(szCreationTime, _T("%d/%02d/%02d %02d:%02d"), st.wYear, st.wMonth, st.wDay, (st.wHour + 8)%24, st.wMinute);
		m_list.AddItem(nCount, 2, szCreationTime);
		// add file
		m_fileList.AddTail(szFilePath);
	}

	//message handler
	BEGIN_MSG_MAP(CPicsiCreatorDlg)
		MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
		MESSAGE_HANDLER(WM_SIZE, OnSize)
		COMMAND_ID_HANDLER(IDOK, OnOK)
		COMMAND_ID_HANDLER(IDCANCEL, OnCancel)
		MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
		COMMAND_ID_HANDLER(IDC_BTN_SETPATH, OnButtonSetpath)
		COMMAND_ID_HANDLER(IDC_BTN_OPEN, OnButtonOpen)
		COMMAND_ID_HANDLER(IDC_BTN_CLEAR, OnButtonClear)
		COMMAND_ID_HANDLER(IDC_BTN_OK, OnButtonOK)
		NOTIFY_HANDLER(IDC_LIST_ORDINARY, NM_DBLCLK, OnListDoubleClick)
		NOTIFY_HANDLER(IDC_LIST_ORDINARY, NM_RCLICK, OnListRightClick)
		COMMAND_ID_HANDLER(ID_POP1_OPEN, OnMenuOpen)
		COMMAND_ID_HANDLER(ID_POP1_DELETE, OnMenuDelete)
		COMMAND_ID_HANDLER(ID_POP1_UP, OnMenuUp)
		COMMAND_ID_HANDLER(ID_POP1_DOWN, OnMenuDown)
		COMMAND_ID_HANDLER(ID_POP1_TOP, OnMenuTop)
		COMMAND_ID_HANDLER(ID_POP1_BOTTOM, OnMenuBottom)
	END_MSG_MAP()

	LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
	{
		m_btnOK.Attach(GetDlgItem(IDC_BTN_OK));
		m_btnClear.Attach(GetDlgItem(IDC_BTN_CLEAR));
		m_static.Attach(GetDlgItem(IDC_STATIC));
		m_editPath.Attach(GetDlgItem(IDC_EDIT_PATH));
		m_btnSet.Attach(GetDlgItem(IDC_BTN_SETPATH));
		m_btnOpen.Attach(GetDlgItem(IDC_BTN_OPEN));
		m_list.Attach(GetDlgItem(IDC_LIST_ORDINARY));
		// add colums
		LVCOLUMN lvc = { 0 };
		lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
		lvc.fmt = LVCFMT_CENTER;
		lvc.pszText = _T("File Name");
		lvc.cx = 300;
		m_list.InsertColumn(0, &lvc);
		lvc.pszText = _T("File Size");
		lvc.cx = 80;
		m_list.InsertColumn(1, &lvc);
		lvc.pszText = _T("Creation Time");
		lvc.cx = 145;
		m_list.InsertColumn(2, &lvc);
		
		if( !read_output_path() || m_strOutputPath.GetLength() <= 0)
			m_strOutputPath.Empty();
		m_editPath.SetWindowText(m_strOutputPath);
		return TRUE;
	}
	// OnSize
	LRESULT OnSize(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
		if( wParam != SIZE_MINIMIZED ) {
			int nWidth = LOWORD(lParam);
			int nHeight = HIWORD(lParam);
			// change layout
			m_static.SetWindowPos(NULL, 4, 8, 88, 16, SWP_NOACTIVATE | SWP_NOZORDER);
			m_editPath.SetWindowPos(NULL, 92, 4, 228, 24, SWP_NOACTIVATE | SWP_NOZORDER);
			m_btnSet.SetWindowPos(NULL, 320, 4, 22, 24, SWP_NOACTIVATE | SWP_NOZORDER);
			m_btnOpen.SetWindowPos(NULL, 344, 4, 48, 24, SWP_NOACTIVATE | SWP_NOZORDER);
			m_btnOK.SetWindowPos(NULL, 420, 4, 48, 24, SWP_NOACTIVATE | SWP_NOZORDER);
			m_btnClear.SetWindowPos(NULL, 470, 4, 48, 24, SWP_NOACTIVATE | SWP_NOZORDER);
			m_list.SetWindowPos(NULL, 0, 32, nWidth, nHeight - 32, SWP_NOACTIVATE | SWP_NOZORDER);
		}
		bHandled = FALSE;
		return 1;
	}
	LRESULT OnOK(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
	{
		//EndDialog(wID);
		return 0;
	}
	LRESULT OnCancel(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
	{
		//EndDialog(wID);
		return 0;
	}
	LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
	{
		bHandled = FALSE;
		return 1;
	}
	LRESULT OnButtonSetpath(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
	{
		CFolderDialog dlg(NULL,_T("Set Output Directory"), BIF_NEWDIALOGSTYLE | BIF_EDITBOX | BIF_RETURNONLYFSDIRS);
		if(m_strOutputPath != _T(""))
			dlg.SetInitialFolder(m_strOutputPath, TRUE);
		if( dlg.DoModal() == IDOK ) {
			m_strOutputPath = dlg.GetFolderPath();
			m_editPath.SetWindowText(m_strOutputPath);
			if( !write_output_path() )
				PS_MessageBox(_T("Save output path failed!"), MB_ICONWARNING);
		}
		return 0;
	}
	LRESULT OnButtonOpen(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
	{
		::ShellExecute(NULL, _T("open"), NULL, NULL, m_strOutputPath, SW_NORMAL);
		return 0;
	}
	LRESULT OnButtonClear(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
	{
		m_list.DeleteAllItems();
		m_fileList.RemoveAll();
		return 1;
	}
	LRESULT OnButtonOK(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
	{
		if(m_strOutputPath.IsEmpty()) {
			PS_MessageBox(_T("Output cannot be empty, set output path first!"), MB_ICONWARNING);
			return 0;
		}
		if(!IsValid() ){
			PS_MessageBox(_T("At least two files and the first one must be a *.jpg file!"), MB_ICONERROR);
			return 0;
		}
		if( !delete_temporary_rar() ) {
			PS_MessageBox(_T("Clear temporary rar file failed!"), MB_ICONERROR);
			return 0;
		}
		WTL::CString strCommandLine;		
		if(!build_rar_command_line(strCommandLine)) {
			PS_MessageBox(_T("Create connotative jpg failed!"), MB_ICONERROR);
			return 0;
		}
		if(!execute_subprocess(strCommandLine.GetBuffer(128))) {
			PS_MessageBox(_T("Create connotative jpg failed!"), MB_ICONERROR);
			return 0;
		}
		if(!build_copy_command_line(strCommandLine)) {
			PS_MessageBox(_T("Create connotative jpg failed!"), MB_ICONERROR);
			delete_temporary_rar();
			return 0;
		}
		if(!execute_subprocess(strCommandLine.GetBuffer(128))) {
			delete_temporary_rar();
			return 0;
		}
		delete_temporary_rar();
		PS_MessageBox(_T("Create connotative jpg succeed!"), MB_ICONINFORMATION);		
		return 0;
	}
	LRESULT OnListDoubleClick(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandled*/)
	{
		shell_open_selected_file();
		return 0;
	}
	LRESULT OnListRightClick(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandled*/)
	{
		int nSelect = m_list.GetSelectedIndex();
		if(nSelect < 0)
			return 0;
		CMenu menu;
		menu.LoadMenu(IDR_MENU_POP);
		CMenuHandle oMenu = menu.GetSubMenu(0);
		if(nSelect == 0) {
			oMenu.EnableMenuItem(ID_POP1_UP, MF_BYCOMMAND | MF_GRAYED);
			oMenu.EnableMenuItem(ID_POP1_TOP, MF_BYCOMMAND | MF_GRAYED);
		}
		if(nSelect == m_list.GetItemCount() - 1) {
			oMenu.EnableMenuItem(ID_POP1_DOWN, MF_BYCOMMAND | MF_GRAYED);
			oMenu.EnableMenuItem(ID_POP1_BOTTOM, MF_BYCOMMAND | MF_GRAYED);
		}
		POINT pt;
		::GetCursorPos(&pt);
		oMenu.TrackPopupMenu(TPM_LEFTALIGN, pt.x, pt.y, m_hWnd);
		return 0;
	}
	LRESULT OnMenuOpen(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
	{
		shell_open_selected_file();
		return 0;
	}
	LRESULT OnMenuDelete(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
	{
		int nSelect = m_list.GetSelectedIndex();
		if(nSelect < 0)
			return 0;
		POSITION pos = m_fileList.GetHeadPosition();
		for(int i = 0; i < nSelect; i++)
			m_fileList.GetNext(pos);
		m_fileList.RemoveAt(pos);
		refresh_list_view();
		return 0;
	}
	LRESULT OnMenuUp(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
	{
		int nSelect = m_list.GetSelectedIndex();
		if(nSelect < 0)
			return 0;
		POSITION pos = m_fileList.GetHeadPosition();
		for(int i = 0; i < nSelect; i++)
			m_fileList.GetNext(pos);
		POSITION posPrev = pos;
		m_fileList.GetPrev(posPrev);
		m_fileList.SwapElements(pos, posPrev);
		refresh_list_view();
		return 0;
	}
	LRESULT OnMenuDown(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
	{
		int nSelect = m_list.GetSelectedIndex();
		if(nSelect < 0)
			return 0;
		POSITION pos = m_fileList.GetHeadPosition();
		for(int i = 0; i < nSelect; i++)
			m_fileList.GetNext(pos);
		POSITION posLatter = pos;
		m_fileList.GetNext(posLatter);
		m_fileList.SwapElements(pos, posLatter);
		refresh_list_view();
		return 0;
	}
	LRESULT OnMenuTop(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
	{
		int nSelect = m_list.GetSelectedIndex();
		if(nSelect < 0)
			return 0;
		POSITION pos = m_fileList.GetHeadPosition();
		for(int i = 0; i < nSelect; i++)
			m_fileList.GetNext(pos);
		m_fileList.MoveToHead(pos);
		refresh_list_view();
		return 0;
	}
	LRESULT OnMenuBottom(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
	{
		int nSelect = m_list.GetSelectedIndex();
		if(nSelect < 0)
			return 0;
		POSITION pos = m_fileList.GetHeadPosition();
		for(int i = 0; i < nSelect; i++)
			m_fileList.GetNext(pos);
		m_fileList.MoveToTail(pos);
		refresh_list_view();
		return 0;
	}

private:
	// get appdata path
	BOOL get_appdata_path(WTL::CString& strPath) throw()
	{
		if(!PS_GetAppDataDirectory(strPath))
			return FALSE;
		PS_PathAppendBackslash(strPath);
		strPath += _T("PicSi");
		if( !PS_IsDirectory(strPath) ) {
			if( ::CreateDirectory(strPath, NULL) == 0 )
				return FALSE;
		}
		strPath += _T("\\cfg");
		return TRUE;
	}
	// read output path
	BOOL read_output_path() throw()
	{
		CString strAppdataPath;
		if(!get_appdata_path(strAppdataPath))
			return FALSE;
		ATL::CComPtr<IStream> spStream;
		HRESULT hr = ::SHCreateStreamOnFile(strAppdataPath, STGM_READ | STGM_SHARE_DENY_WRITE, &spStream);
		if(FAILED(hr))
			return FALSE;
		ULONG nCount;
		hr = spStream->Read(m_strOutputPath.GetBufferSetLength(MAX_PATH), MAX_PATH, &nCount);
		m_strOutputPath.ReleaseBuffer();
		if(FAILED(hr))
			return FALSE;
		return TRUE;
	}
	// write output path
	BOOL write_output_path() throw()
	{
		CString strAppdataPath;
		if(!get_appdata_path(strAppdataPath))
			return FALSE;
		ATL::CComPtr<IStream> spStream;
		HRESULT hr = ::SHCreateStreamOnFile(strAppdataPath, STGM_WRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE, &spStream);
		if(FAILED(hr))
			return FALSE;
		ULONG nCount;
		hr = spStream->Write(m_strOutputPath, MAX_PATH, &nCount);
		if(FAILED(hr))
			return FALSE;
		return TRUE;
	}
	// check valid
	BOOL IsValid() throw()
	{
		int nCount = m_list.GetItemCount();
		if(nCount < 2)
			return FALSE;
		TCHAR szText[MAX_PATH];
		int nTotal = m_list.GetItemText(0, 0, szText, MAX_PATH);
		WTL::CString strPath = szText;
		strPath.MakeLower();
		int nPos = strPath.Find(_T(".jpg"));
		if(nPos < 0 || nPos < nTotal - 4)
			return FALSE;
		return TRUE;
	}
	// get rar exe path
	BOOL get_rar_exe_path(WTL::CString& strRarExePath) throw()
	{
		if(!PS_GetInstallationDirectory(strRarExePath))
			return FALSE;
		else {
			if(!PS_PathAppendBackslash(strRarExePath))
				return FALSE;
			strRarExePath += _T("Rar.exe");
		}
		return TRUE;
	}
	// get copy bat path
	BOOL get_copy_bat_path(WTL::CString& strCopyBatPath) throw()
	{
		if(!PS_GetInstallationDirectory(strCopyBatPath))
			return FALSE;
		else {
			if(!PS_PathAppendBackslash(strCopyBatPath))
				return FALSE;
			strCopyBatPath += _T("copy.bat");
		}
		return TRUE;
	}
	// get temporary rar path
	BOOL get_temporary_rar_path(WTL::CString& strPath) throw()
	{
		strPath = m_strOutputPath;
		if(!PS_PathAppendBackslash(strPath))
			return FALSE;
			strPath += _T("picsi_temporary.rar");
		return TRUE;
	}
	// delete temporary rar
	BOOL delete_temporary_rar() throw()
	{
		WTL::CString strRarPath;
		get_temporary_rar_path(strRarPath);
		if( ::DeleteFile(strRarPath) == 0  && ::GetLastError() != ERROR_FILE_NOT_FOUND)
			return FALSE;
		return TRUE;
	}
	// build command line
	BOOL build_rar_command_line(WTL::CString& strCmd) throw()
	{
		if( !get_rar_exe_path(strCmd) )
			return FALSE;
		PS_AddDoubleQuotationMarks(strCmd);
		strCmd += _T(" a -ep1 ");
		WTL::CString strRarPath;
		if( !get_temporary_rar_path(strRarPath) )
			return FALSE;
		PS_AddDoubleQuotationMarks(strRarPath);
		strCmd += strRarPath;
		// append source file name
		WTL::CString strTmp;
		POSITION pos = m_fileList.GetHeadPosition();
		m_fileList.GetNext(pos);
		while(pos != NULL) {
			strTmp = m_fileList.GetAt(pos);
			PS_AddDoubleQuotationMarks(strTmp);
			strCmd += _T(" ");
			strCmd += strTmp;
			m_fileList.GetNext(pos);
		}		
		return TRUE;
	}
	// build copy command line
	BOOL build_copy_command_line(WTL::CString& strCmd) throw()
	{
		if( !get_copy_bat_path(strCmd) )
			return FALSE;
		PS_AddDoubleQuotationMarks(strCmd);
		strCmd += _T(" ");
		// append jpg file
		WTL::CString strJpgPath = m_fileList.GetHead();
		PS_AddDoubleQuotationMarks(strJpgPath);
		strCmd += strJpgPath;
		strCmd += _T(" ");
		// append rar file
		WTL::CString strRarPath;
		if( !get_temporary_rar_path(strRarPath) )
			return FALSE;
		PS_AddDoubleQuotationMarks(strRarPath);
		strCmd += strRarPath;
		strCmd += _T(" ");
		// append result file
		WTL::CString strResultFile;
		TCHAR szFilename[MAX_PATH];
		m_list.GetItemText(0, 0, szFilename, MAX_PATH);
		PS_GetFilename(szFilename, strResultFile);
		PS_PathAppendBackslash(m_strOutputPath);
		strResultFile = m_strOutputPath + strResultFile;
		PS_AddDoubleQuotationMarks(strResultFile);
		strCmd += strResultFile;
		return TRUE;
	}
	// execute subprocess
	BOOL execute_subprocess(LPTSTR szCommandLine) throw()
	{
		ATLASSERT(szCommandLine != NULL);
		STARTUPINFO si = { 0 };
		si.cb = sizeof(si);
		PROCESS_INFORMATION pi = { 0 };
		if( !CreateProcess( NULL, szCommandLine,
							NULL, NULL, FALSE, CREATE_NO_WINDOW,
							NULL, NULL, &si, &pi ) ) {
			DWORD dwCode = ::GetLastError();
			return FALSE;
		}
		WaitForSingleObject( pi.hProcess, INFINITE );
		CloseHandle( pi.hProcess );
		CloseHandle( pi.hThread );
		return TRUE;
	}
	// shell open selected file
	void shell_open_selected_file() throw()
	{
		int nSelect = m_list.GetSelectedIndex();
		if(nSelect < 0)
			return;
		POSITION pos = m_fileList.GetHeadPosition();
		for(int i = 0; i < nSelect; ++i)
			m_fileList.GetNext(pos);
		::ShellExecute(NULL, _T("open"), m_fileList.GetAt(pos), NULL, NULL, SW_NORMAL);
	}
	// refresh list view
	void refresh_list_view() throw()
	{
		m_list.DeleteAllItems();
		POSITION pos = m_fileList.GetHeadPosition();
		WTL::CString strFilePath;
		int i = 0;
		while(pos != NULL) {
			strFilePath = m_fileList.GetAt(pos);
			WTL::CString strFilename;
			PS_GetFilename(strFilePath, strFilename);
			m_list.AddItem(i, 0, strFilename);
			// add size
			OFSTRUCT os;
			HANDLE hFile = (HANDLE)::OpenFile(::CT2A(strFilePath), &os, OF_READ);
			BY_HANDLE_FILE_INFORMATION fileinfo;
			::GetFileInformationByHandle(hFile, &fileinfo);
			TCHAR szSize[20];
			_stprintf_s(szSize, _T("%d KB"), fileinfo.nFileSizeLow / 1024);
			m_list.AddItem(i, 1, szSize);
			// add creation time
			SYSTEMTIME st;
			FileTimeToSystemTime(&fileinfo.ftCreationTime, &st);
			TCHAR szCreationTime[24];
			_stprintf_s(szCreationTime, _T("%d/%02d/%02d %02d:%02d"), st.wYear, st.wMonth, st.wDay, (st.wHour + 8) % 24, st.wMinute);
			m_list.AddItem(i, 2, szCreationTime);
			i++;
			m_fileList.GetNext(pos);
		}
	}
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章